diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c0e460f --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +editor/ +lighting/ +prefs/ +gui/ +*.dso +Classic* \ No newline at end of file diff --git a/README.md b/README.md index 253eb39..11c2b19 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,52 @@ -# SkillSector -Skill Sector is a game mode for learning skills needed in other Tribes 2 game modes +# SkillSector - The Sector that gives you Skills +## Description +SkillSector is a game mode for Tribes 2 for building skills you will need to play other game modes. A few fun toys are also thrown in. + +# Mode plan +Building on the concepts seen in the [Training Grounds](https://github.com/jakraska/Tribes-2-Training-Grounds/) game mode by [jakraska](https://github.com/jakraska), SkillSector hopes to achieve the following features for the following modes.\ +#### Movement and shooting + - [ ] Flying aim training, multiple difficulty levels + - [ ] Human duel arena(s) + - [ ] Robot duel arena(s) +#### Flag handling + - [ ] Flag toss practice + - [ ] Baseball machine flag catch practice (CTF, TR2) + - [ ] Human flag practice (CTF, TR2) +#### Toys + - [ ] Grav cycle racing + - [ ] Ski racing + +# Modes +## Flying aim training +### Beginner difficulty +Static targets. Shots will only count when the player is... + - In the air + - Travelling at a minimum velocity + +Different weapons will have different scores based on their 'ease' of hitting a static target.\ +Static targets will be both on the ground and in the air.\ +Hitting a static target with splash damage will count, but won't grant much score compared to a direct hit. + +### Moderate difficulty +Moving targets. Splash damage does not count. Same rules as previous. + +### Advanced difficulty +Fast moving targets. Same rules as previous. + +## Human duel arena(s) +Humans should be able to schedule a duel between themselves. I like the way that TG did it. + +## Robot duel arena(s) +Humans should be able to select from various difficulty robots for dueling. + +## Flag toss/catch practice +Flag tossing and flag catching require a fair bit of practice. Doing so manually or between players + +#### auxiliary todo list / odds and ends + - noIndividualDamage could be set for the roof's power stations, making it possible to annoy other players by disabling FloatingBank's inventory station(s) + + +# map ideas +# twin towers 9/11 map is a good meme + +# flying aim training thinking \ No newline at end of file diff --git a/missions/NewbiesNexus.mis b/missions/NewbiesNexus.mis new file mode 100644 index 0000000..98866ed --- /dev/null +++ b/missions/NewbiesNexus.mis @@ -0,0 +1,620 @@ +// MissionTypes = SkillSector + +//--- MISSION QUOTE BEGIN --- +// Forget Ymir, remember ur mom +// -- Jarek Redmoon, Ur-Shaman of the Starwolf, 3941 CE +//--- MISSION QUOTE END --- + +//--- MISSION STRING BEGIN --- +//[Hunters TeamHunters]WOLOLO +//NO I HAVE NOT WRITTEN THIS SHIT YET +//--- MISSION STRING END --- + +//--- OBJECT WRITE BEGIN --- +new SimGroup(MissionGroup) { + + Team_Hunters_timeLimit = "25"; + powerCount = "0"; + cdTrack = "5"; + musicTrack = "ice"; + Hunters_timeLimit = "25"; + + new MissionArea(MissionArea) { + area = "-1008 -1032 2144 2080"; + flightCeiling = "2000"; + flightCeilingRange = "50"; + + locked = "true"; + }; + new Sun() { + position = "-1024 -1024 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.600000 0.600000 0.620000 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/snowdet1"; + terrainFile = "Scarabrae_nef.ter"; + squareSize = "8"; + + position = "-1024 -1024 0"; + visibleDistance = "1200"; + hazeDistance = "250"; + locked = "true"; + }; + new NavigationGraph(NavGraph) { + conjoinAngleDev = "55"; + cullDensity = "0.3"; + customArea = "0 0 0 0"; + + position = "0 0 0 1"; + YDimOverSize = "0"; + conjoinBowlDev = "20"; + rotation = "0 0 0 0"; + coverage = "0"; + scale = "1 1 1"; + GraphFile = "Scarabrae_nef.nav"; + XDimOverSize = "0"; + locked = "true"; + }; + new Sky(Sky) { + position = "-904 -1136 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 = "1000"; + useSkyTextures = "1"; + renderBottomTexture = "0"; + SkySolidColor = "0.365000 0.390000 0.420000 0.000000"; + fogDistance = "800"; + fogColor = "0.600000 0.600000 0.600000 1.000000"; + fogVolume1 = "0 0 0"; + fogVolume2 = "0 0 0"; + 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 0 0"; + high_fogVolume2 = "-1 0 0"; + high_fogVolume3 = "-1 0 0"; + + cloudSpeed0 = "0.000000 0.000000"; + locked = "true"; + }; + new SimGroup(ObserverDropPoints) { + + powerCount = "0"; + + new Camera() { + position = "-20.1378 130.534 175.57"; + rotation = "0 0 -1 95.2935"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + new Camera() { + position = "-98.5621 203.831 198.799"; + rotation = "0.0328029 -0.0599317 0.997663 122.726"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + new Camera() { + position = "-17.4677 159.05 77.7879"; + rotation = "0 0 1 195.952"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + new Camera() { + position = "163.16 -235.163 216.951"; + rotation = "0.305024 0.0666097 -0.950012 25.8909"; + scale = "1 1 1"; + dataBlock = "Observer"; + lockCount = "0"; + homingCount = "0"; + + locked = "true"; + }; + }; + new SimGroup(Teams) { + + powerCount = "0"; + + new SimGroup(Team1) { + + powerCount = "0"; + + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-0.966477 -50.0832 112.711"; + rotation = "0 0 -1 84.7978"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "100"; + sphereWeight = "100"; + indoorWeight = "0"; + outdoorWeight = "120"; + + locked = "true"; + }; + new SpawnSphere() { + position = "-34.2901 125.288 201.689"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "300"; + sphereWeight = "100"; + indoorWeight = "0"; + outdoorWeight = "100"; + + locked = "true"; + }; + }; + }; + new SimGroup(Team2) { + + powerCount = "0"; + + new SimGroup(spawnspheres) { + + powerCount = "0"; + + new SpawnSphere() { + position = "-87.5583 365.17 126.118"; + rotation = "0 0 1 57.8687"; + scale = "1 1 1"; + dataBlock = "SpawnSphereMarker"; + lockCount = "0"; + homingCount = "0"; + radius = "120"; + sphereWeight = "100"; + indoorWeight = "0"; + outdoorWeight = "100"; + + locked = "true"; + }; + }; + }; + new SimGroup(Team0) { + + powerCount = "0"; + + new SimGroup(DefaultInventoryStations) { + + powerCount = "1"; + + new InteriorInstance() { + position = "-264.726 -197.424 226.091"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "stowr1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "false"; + }; + new StaticShape() { + position = "31.9146 91.7929 -97.0133"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "GeneratorLarge"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + Target = "33"; + locked = "false"; + }; + new InteriorInstance() { + position = "223.424 372.998 217.978"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "stowr1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "false"; + }; + new StaticShape() { + position = "223.429 374.166 208.98"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + Trigger = "39503"; + Target = "34"; + locked = "false"; + }; + new StaticShape() { + position = "157.765 -195.042 204.45"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + Trigger = "39505"; + Target = "35"; + locked = "false"; + }; + new InteriorInstance() { + position = "157.83 -196.214 213.451"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "stowr1.dif"; + showTerrainInside = "0"; + + team = "0"; + locked = "false"; + }; + new StaticShape() { + position = "-264.666 -196.208 217.09"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + team = "0"; + Trigger = "39508"; + Target = "36"; + locked = "false"; + }; + new ScriptObject(ObserverHUDWeaponList) { + class = "ObserverHUDWeaponList"; + + DamageTypeName12 = "Explosion"; + DamageType87 = "Other"; + DamageTypeName3 = "Chaingun"; + DamageType72 = "Other"; + DamageType86 = "Other"; + DamageType96 = "Other"; + DamageType55 = "Other"; + DamageType7 = "ELF"; + DamageType66 = "Other"; + DamageType88 = "Other"; + DamageType48 = "Other"; + DamageTypeName16 = "DepTurret"; + DamageType3 = "Chaingun"; + DamageType5 = "Grenade"; + DamageType14 = "Ground"; + DamageType31 = "SatchelCharge"; + DamageTypeName13 = "Impact"; + DamageType70 = "Other"; + DamageType59 = "Other"; + DamageType85 = "Other"; + DamageType58 = "Other"; + team = "0"; + DamageTypeName14 = "Ground"; + DamageType64 = "Other"; + DamageType89 = "Other"; + DamageType44 = "Other"; + DamageType33 = "Other"; + DamageType18 = "Turret"; + DamageType22 = "DepTurret"; + DamageType77 = "Other"; + DamageType71 = "Other"; + DamageTypeName22 = "TankMortar"; + DamageTypeName6 = "Laser"; + DamageTypeName5 = "Grenade"; + DamageType39 = "Other"; + DamageType65 = "Other"; + DamageType23 = "Turret"; + DamageType1 = "Blaster"; + DamageType28 = "BomberBombs"; + DamageType16 = "Turret"; + DamageType62 = "Other"; + DamageType30 = "TankMortar"; + DamageType81 = "Other"; + DamageTypeName17 = "Ground"; + DamageType10 = "ShockLance"; + DamageType49 = "Other"; + DamageTypeName1 = "Blaster"; + DamageType68 = "Other"; + DamageType67 = "Other"; + DamageType41 = "Other"; + MaxDamageType = "24"; + DamageType63 = "Other"; + DamageType73 = "Other"; + DamageType29 = "TankChaingun"; + DamageType52 = "Other"; + DamageType2 = "Plasma"; + DamageTypeName21 = "TankChaingun"; + DamageType78 = "Other"; + DamageType21 = "DepTurret"; + DamageTypeName2 = "Plasma"; + DamageTypeName4 = "Disc"; + DamageType37 = "Other"; + DamageType24 = "Other"; + DamageType84 = "Other"; + DamageTypeName23 = "SatchelCharge"; + DamageType43 = "Other"; + DamageType79 = "Other"; + DamageType9 = "Missile"; + DamageType6 = "Laser"; + DamageType25 = "Ground"; + DamageType94 = "Other"; + DamageType97 = "Other"; + DamageType17 = "Turret"; + DamageType54 = "Other"; + DamageTypeName7 = "ELF"; + DamageType75 = "Other"; + DamageTypeName10 = "ShockLance"; + DamageType76 = "Other"; + mod = "base"; + DamageType99 = "Suicide"; + DamageType15 = "Turret"; + DamageType57 = "Other"; + DamageType40 = "Other"; + DamageTypeName19 = "BellyTurret"; + DamageType74 = "Other"; + DamageType35 = "Other"; + DamageType53 = "Other"; + DamageType11 = "Mine"; + DamageType92 = "Other"; + DamageTypeName18 = "ShrikeBlaster"; + DamageType13 = "Impact"; + DamageType83 = "Other"; + DamageType38 = "Other"; + DamageType51 = "Other"; + DamageTypeName20 = "BomberBombs"; + DamageType93 = "Other"; + DamageTypeName24 = "Other"; + DamageType12 = "Explosion"; + DamageTypeName11 = "Mine"; + DamageTypeName9 = "Missile"; + DamageType56 = "Other"; + DamageType61 = "Other"; + DamageType20 = "Turret"; + DamageType98 = "Other"; + DamageType27 = "BellyTurret"; + DamageType4 = "Disc"; + DamageType0 = "Other"; + DamageType69 = "Other"; + DamageType32 = "Turret"; + DamageType45 = "Other"; + DamageType60 = "Other"; + DamageType82 = "Other"; + DamageType26 = "ShrikeBlaster"; + DamageType46 = "Other"; + DamageTypeName15 = "Turret"; + DamageType8 = "Mortar"; + DamageType47 = "Other"; + DamageType95 = "Other"; + DamageType42 = "Other"; + DamageType34 = "Other"; + DamageType19 = "Turret"; + DamageTypeName8 = "Mortar"; + DamageType36 = "Other"; + DamageType80 = "Other"; + DamageType90 = "Other"; + DamageType91 = "Other"; + DamageType50 = "Other"; + }; + }; + }; + }; + new SimGroup(Ambiance) { + + powerCount = "0"; + + new Precipitation(Precipitation) { + position = "-72.3863 217.965 161.798"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "Sand"; + 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 = "3"; + maxNumDrops = "500"; + maxRadius = "200"; + + locked = "false"; + }; + new AudioEmitter() { + position = "-72.3863 217.965 161.798"; + 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 = "false"; + }; + }; + new FileObject() { + }; + new FileObject() { + }; + new SimGroup(Bank) { + + powerCount = "2"; + + new InteriorInstance(FlyingBase) { + position = "-158.549 134.258 226.011"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + interiorFile = "dbase4.dif"; + showTerrainInside = "0"; + }; + new StaticShape() { + position = "-159.078 135.457 290.453"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "SolarPanel"; + lockCount = "0"; + homingCount = "0"; + + Target = "37"; + }; + new StaticShape() { + position = "-158.234 132.947 290.416"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + dataBlock = "SolarPanel"; + lockCount = "0"; + homingCount = "0"; + + Target = "38"; + }; + new StaticShape(MainInventory) { + position = "-158.549 153.858 241.953"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + dataBlock = "StationInventory"; + lockCount = "0"; + homingCount = "0"; + + damageTimeMS = "247515"; + inUse = "Down"; + Trigger = "39520"; + lastDamagedBy = "5025"; + Target = "39"; + lastDamagedByTeam = "1"; + notReady = "1"; + }; + new PhysicalZone(TractorBeamFront) { + position = "-142.042 106.838 82.3519"; + rotation = "1 0 0 0"; + scale = "1 1 1"; + velocityMod = "1"; + gravityMod = "-3"; + appliedForce = "0 0 0"; + polyhedron = "0.0000000 0.0000000 0.0000000 10.0000000 0.0000000 0.0000000 -0.0000000 -40.0000000 -0.0000000 -0.0000000 -0.0000000 160.0000000"; + }; + }; + new SimGroup(AimTrain) { + + powerCount = "0"; + + new SimGroup(AimTrainLow) { + + powerCount = "0"; + + new TSStatic(LeftPlaceholder) { + position = "-572.337 40.4128 232.884"; + rotation = "0 0 -1 20"; + scale = "1 1 1"; + shapeName = "statue_hmale.dts"; + + placeholder = "1"; + }; + new TSStatic(MidPlaceholder) { + position = "-590.737 101.598 252.119"; + rotation = "0 0 1 90"; + scale = "1 1 1"; + shapeName = "statue_lfemale.dts"; + + placeholder = "1"; + }; + new TSStatic(MidBase) { + position = "-590.737 101.598 251.319"; + rotation = "1 0 0 0"; + scale = "0.25 0.25 0.25"; + shapeName = "statue_base.dts"; + }; + new TSStatic(RightPlaceholder) { + position = "-584.067 184.117 243.119"; + rotation = "0 0 1 180"; + scale = "1 1 1"; + shapeName = "statue_lfemale.dts"; + + placeholder = "1"; + }; + new TSStatic(FarBase) { + position = "-723.379 103.636 250.839"; + rotation = "1 0 0 0"; + scale = "0.25 0.25 0.25"; + shapeName = "statue_base.dts"; + }; + new TSStatic(FarPlaceholder) { + position = "-723.379 103.636 251.639"; + rotation = "0 0 1 90"; + scale = "1 1 1"; + shapeName = "statue_lfemale.dts"; + + placeholder = "1"; + }; + new StaticShape(BankTeleport) { + position = "-539.94 114.928 212.877"; + rotation = "0 -1 0 9.99997"; + scale = "1 1 1"; + dataBlock = "MPBTeleporter"; + lockCount = "0"; + homingCount = "0"; + + damageTimeMS = "9247167"; + lastDamagedBy = "39473"; + Target = "40"; + lastDamagedByTeam = "1"; + }; + }; + }; +}; +//--- OBJECT WRITE END --- diff --git a/scripts/SkillSectorAimTrainer.cs b/scripts/SkillSectorAimTrainer.cs new file mode 100644 index 0000000..9446f09 --- /dev/null +++ b/scripts/SkillSectorAimTrainer.cs @@ -0,0 +1,61 @@ +datablock PlayerData(DermDummy) : LightMaleBiodermArmor { + canObserve = false; + groundImpactMinSpeed = 0.01; + minImpactSpeed = 5; + speedDamageScale = 0.004; +}; + +function resetDummyPosition(%this) { + %this.setTransform(%this.original_transform); + %this.setvelocity("0 0 0"); +} + +function DermDummy::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) { + if (%sourceObject == 0) { + return; + } + echo("Damage object received: " @ %targetObject @ " from " @ %sourceObject); + cancel(%targetObject.resetter); // Avoid double resets + // 750 allows for the original splash damage to decay + // 500 results in a double reset because the dummy is hit by the original explosion twice + %targetObject.resetter = schedule(750, 0, "resetDummyPosition", %targetObject); +} + +// function TSStatic::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType) { +// echo("Damage object received: " @ %targetObject.name); +// } + +// function TSStatic::damage(%this, %sourceObject, %position, %amount, %damageType) { +// echo("wtf is this then: " @ %this @ " tgt " @ %sourceObject); +// } + + +function findAndReplacePlaceholders() { + // Replace placeholders in the aim training system + %trash = new SimSet(); + for (%i = 0; %i < AimTrainLow.getCount(); %i += 1) { + if (AimTrainLow.getObject(%i).placeholder) { + %obj = AimTrainLow.getObject(%i); + echo("Replace : " @ %obj.getName()); + %trans = %obj.getTransform(); + %replace = new Player() { + datablock = "DermDummy"; + }; + AimTrainLow.add(%replace); + %replace.setName(%obj.getName()); + %replace.setTransform(%trans); + %replace.original_transform = %trans; + %trash.add(%obj); + } + } + while (%trash.getCount() > 0) { + %obj = %trash.getObject(0); + %obj.delete(); + } + %trash.delete(); +} + +// Don't replace placeholder entities in development mode +if ($DEVMODE == 0) { + findAndReplacePlaceholders(); +} \ No newline at end of file diff --git a/scripts/SkillSectorGame.cs b/scripts/SkillSectorGame.cs new file mode 100644 index 0000000..6ed3ba2 --- /dev/null +++ b/scripts/SkillSectorGame.cs @@ -0,0 +1,34 @@ +// SkillSector game has a README.md, read that instead. + +// author: loop +// date: 10/2025 +// url: https://github.com/tribes2/SkillSector + +// Allows you to modify AimTrain placeholder entities. +// Don't leave it on or AimTrain will be a bunch of statues that do nothing. +$DEVMODE = 1; + +// thanks DarkTiger (you can prob list them all via datablockGroup.getCount(); and iterate them all and do echo %obj.getName();) +function dumpDatablockNames() { + for (%i = 0; %i < datablockgroup.getCount(); %i += 1) { + echo("Datablock " @ %i @ " named " @ datablockgroup.getObject(%i).getName()); + } +} + +// DEVMODE reload/test function +function ssrl() { + exec("scripts/SkillSectorGame.cs"); + findAndReplacePlaceholders(); +} + +function dc() { + disconnect(); +} + +if ($DEVMODE) { + moveMap.bind(keyboard, "f5", disconnect); +} + +// Load the various modes, datablocks and functions. +exec("scripts/SkillSectorTeleporter.cs"); +exec("scripts/SkillSectorAimTrainer.cs"); \ No newline at end of file diff --git a/scripts/SkillSectorTeleporter.cs b/scripts/SkillSectorTeleporter.cs new file mode 100644 index 0000000..3523069 --- /dev/null +++ b/scripts/SkillSectorTeleporter.cs @@ -0,0 +1,216 @@ +// stolen from classic +datablock StaticShapeData(BankTeleporter): 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) +//datablock ParticleEmitterData(MPBTeleportEmitter) + +function BankTeleporter::onCollision(%data, %obj, %collider) { + // Teleporters are generally one way in Skill Sector + // Teleporter entities are linked to 'spawn point' objects + if (%obj.disabled) { + messageClient(%collider.client, 'MsgStationDenied', '\c2Teleporter is recharging please stand by. ~wfx/powered/nexus_deny.wav'); + return; + } + %collider.setVelocity("0 0 0"); + %collider.disableMove = true; + %collider.startFade(1000, 0, true); + %collider.playAudio($ActivateThread, StationVehicleAcitvateSound); + %obj.disabled = 1; + %obj.setThreadDir($ActivateThread, 1); + %obj.playThread($ActivateThread, "activate"); + + %data.sparkEmitter(%obj); + %data.schedule(2000, "teleportout", %obj, %collider); + %data.schedule(4000, "teleportingDone", %obj, %collider); +} + +// function BankTeleporter::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).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 BankTeleporter::teleportOut(%data, %obj, %player) { + if(isObject(%obj.destination)) { + %player.setTransform(%obj.MPB.spawnPos[%index] @ " " @ getWords(%obj.MPB.getTransform(), 3, 6)); + } else { + %player.teleporting = 0; + } else { + messageClient(%player.client, 'MsgTeleFailed', 'No Valid teleporting positions.'); + %player.teleporting = 0; + } + %data.schedule(1000, "teleportIn", %player); +} + +function BankTeleporter::teleportIn(%data, %player) { + %data.sparkEmitter(%player); // z0dd - ZOD, 4/24/02. teleport sparkles + %player.startFade(1000, 0, false ); + %player.playAudio($PlaySound, StationVehicleDeactivateSound); +} + +function BankTeleporter::reEnable(%data, %obj) { + %obj.disabled = 0; +} + +function BankTeleporter::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 BankTeleporter::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; +}