diff --git a/.gitignore b/.gitignore index 40031bf9..832e50d6 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,9 @@ dist .DS_Store .tshy + +# GameData folder with actual .vl2 files (unextracted) in it. Some scripts like +# `extract-assets` and `generate-manifest` look at this to extract or build the +# list of files. Once someone builds this, it's not really necessary for other +# developers to have this folder. +GameData diff --git a/README.md b/README.md index 47292b3b..f30b33f3 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,8 @@ Click inside the map preview area to capture the mouse. | Space | Up | | Shift | Down | | Esc | Release mouse | +| △ Scroll/mouse wheel up | Increase speed | +| ▽ Scroll/mouse wheel down | Decrease speed | ## Development diff --git a/app/InteriorInstance.tsx b/app/InteriorInstance.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/app/Sky.tsx b/app/Sky.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/app/TerrainBlock.tsx b/app/TerrainBlock.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/app/WaterBlock.tsx b/app/WaterBlock.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/app/page.tsx b/app/page.tsx index 1a797326..51f450e9 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,738 +1,53 @@ "use client"; -import { useEffect, useRef, useState } from "react"; -import * as THREE from "three"; -import { - getActualResourcePath, - getResourceList, - getSource, -} from "@/src/manifest"; -import { parseTerrainBuffer } from "@/src/terrain"; -import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader"; -import { getTerrainFile, iterObjects, parseMissionScript } from "@/src/mission"; +import { useState, useEffect } from "react"; +import { useSearchParams, useRouter } from "next/navigation"; +import { Canvas } from "@react-three/fiber"; +import { EffectComposer, N8AO } from "@react-three/postprocessing"; +import { Mission } from "@/src/components/Mission"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { ObserverControls } from "@/src/components/ObserverControls"; +import { InspectorControls } from "@/src/components/InspectorControls"; +import { SettingsProvider } from "@/src/components/SettingsProvider"; +import { ObserverCamera } from "@/src/components/ObserverCamera"; -const BASE_URL = "/t2-mapper"; -const RESOURCE_ROOT_URL = `${BASE_URL}/base/`; - -function getUrlForPath(resourcePath: string, fallbackUrl?: string) { - resourcePath = getActualResourcePath(resourcePath); - let sourcePath: string; - try { - sourcePath = getSource(resourcePath); - } catch (err) { - if (fallbackUrl) { - return fallbackUrl; - } else { - throw err; - } - } - if (!sourcePath) { - return `${RESOURCE_ROOT_URL}${resourcePath}`; - } else { - return `${RESOURCE_ROOT_URL}@vl2/${sourcePath}/${resourcePath}`; - } -} - -function interiorToUrl(name: string) { - const difUrl = getUrlForPath(`interiors/${name}`); - return difUrl.replace(/\.dif$/i, ".gltf"); -} - -function terrainTextureToUrl(name: string) { - name = name.replace(/^terrain\./, ""); - return getUrlForPath(`textures/terrain/${name}.png`, `${BASE_URL}/black.png`); -} - -function interiorTextureToUrl(name: string) { - name = name.replace(/\.\d+$/, ""); - return getUrlForPath(`textures/${name}.png`); -} - -function textureToUrl(name: string) { - try { - return getUrlForPath(`textures/${name}.png`); - } catch (err) { - return `${BASE_URL}/black.png`; - } -} - -async function loadDetailMapList(name: string) { - const url = getUrlForPath(`textures/${name}`); - const res = await fetch(url); - const text = await res.text(); - return text - .split(/(?:\r\n|\n|\r)/) - .map((line) => `textures/${line.trim().replace(/\.png$/i, "")}.png`); -} - -function uint16ToFloat32(src: Uint16Array) { - const out = new Float32Array(src.length); - for (let i = 0; i < src.length; i++) { - out[i] = src[i] / 65535; - } - return out; -} - -async function loadMission(name: string) { - const res = await fetch(getUrlForPath(`missions/${name}.mis`)); - const missionScript = await res.text(); - return parseMissionScript(missionScript); -} - -async function loadTerrain(fileName: string) { - const res = await fetch(getUrlForPath(`terrains/${fileName}`)); - const terrainBuffer = await res.arrayBuffer(); - return parseTerrainBuffer(terrainBuffer); -} - -function resizeRendererToDisplaySize(renderer) { - const canvas = renderer.domElement; - const width = canvas.clientWidth; - const height = canvas.clientHeight; - const needResize = canvas.width !== width || canvas.height !== height; - if (needResize) { - renderer.setSize(width, height, false); - } - return needResize; -} - -const excludeMissions = new Set([ - "SkiFree", - "SkiFree_Daily", - "SkiFree_Randomizer", -]); - -const missions = getResourceList() - .map((resourcePath) => resourcePath.match(/^missions\/(.+)\.mis$/)) - .filter(Boolean) - .map((match) => match[1]) - .filter((name) => !excludeMissions.has(name)); +// three.js has its own loaders for textures and models, but we need to load other +// stuff too, e.g. missions, terrains, and more. This client is used for those. +const queryClient = new QueryClient(); export default function HomePage() { - const canvasRef = useRef(null); - const [missionName, setMissionName] = useState("TWL2_WoodyMyrk"); - const [fogEnabled, setFogEnabled] = useState(true); - const threeContext = useRef>({}); + const searchParams = useSearchParams(); + const router = useRouter(); + // Initialize state from query params + const [missionName, setMissionName] = useState( + searchParams.get("mission") || "TWL2_WoodyMyrk" + ); + + // Update query params when state changes useEffect(() => { - const canvas = canvasRef.current; - const renderer = new THREE.WebGLRenderer({ - canvas, - antialias: true, - }); - - const textureLoader = new THREE.TextureLoader(); - const gltfLoader = new GLTFLoader(); - - const scene = new THREE.Scene(); - const camera = new THREE.PerspectiveCamera( - 75, - canvas.clientWidth / canvas.clientHeight, - 0.1, - 2000 - ); - - function setupColor(tex, repeat = [1, 1]) { - tex.wrapS = tex.wrapT = THREE.RepeatWrapping; // Still need this for tiling to work - tex.colorSpace = THREE.SRGBColorSpace; - tex.repeat.set(...repeat); - tex.anisotropy = renderer.capabilities.getMaxAnisotropy?.() ?? 16; - tex.generateMipmaps = true; - tex.minFilter = THREE.LinearMipmapLinearFilter; - tex.magFilter = THREE.LinearFilter; - return tex; - } - - function setupMask(data) { - const tex = new THREE.DataTexture( - data, - 256, - 256, - THREE.RedFormat, // 1 channel - THREE.UnsignedByteType // 8-bit - ); - - // Masks should stay linear - tex.colorSpace = THREE.NoColorSpace; - - // Set tiling / sampling. For NPOT sizes, disable mips or use power-of-two. - tex.wrapS = tex.wrapT = THREE.RepeatWrapping; - tex.generateMipmaps = false; // if width/height are not powers of two - tex.minFilter = THREE.LinearFilter; // avoid mips if generateMipmaps=false - tex.magFilter = THREE.LinearFilter; - - tex.needsUpdate = true; - - return tex; - } - - const skyColor = "rgba(209, 237, 255, 1)"; - const groundColor = "rgba(186, 200, 181, 1)"; - const intensity = 2; - const light = new THREE.HemisphereLight(skyColor, groundColor, intensity); - scene.add(light); - - // Free-look camera setup - camera.position.set(0, 100, 512); - - const keys = { - w: false, a: false, s: false, d: false, - shift: false, space: false - }; - - const onKeyDown = (e) => { - if (e.code === "KeyW") keys.w = true; - if (e.code === "KeyA") keys.a = true; - if (e.code === "KeyS") keys.s = true; - if (e.code === "KeyD") keys.d = true; - if (e.code === "ShiftLeft" || e.code === "ShiftRight") keys.shift = true; - if (e.code === "Space") keys.space = true; - }; - - const onKeyUp = (e) => { - if (e.code === "KeyW") keys.w = false; - if (e.code === "KeyA") keys.a = false; - if (e.code === "KeyS") keys.s = false; - if (e.code === "KeyD") keys.d = false; - if (e.code === "ShiftLeft" || e.code === "ShiftRight") keys.shift = false; - if (e.code === "Space") keys.space = false; - }; - - document.addEventListener("keydown", onKeyDown); - document.addEventListener("keyup", onKeyUp); - - // Mouse look controls - let isPointerLocked = false; - const euler = new THREE.Euler(0, 0, 0, 'YXZ'); - const PI_2 = Math.PI / 2; - - const onMouseMove = (e) => { - if (!isPointerLocked) return; - - const movementX = e.movementX || 0; - const movementY = e.movementY || 0; - - euler.setFromQuaternion(camera.quaternion); - euler.y -= movementX * 0.002; - euler.x -= movementY * 0.002; - euler.x = Math.max(-PI_2, Math.min(PI_2, euler.x)); - camera.quaternion.setFromEuler(euler); - }; - - const onPointerLockChange = () => { - isPointerLocked = document.pointerLockElement === canvas; - }; - - const onCanvasClick = () => { - if (!isPointerLocked) { - canvas.requestPointerLock(); - } - }; - - canvas.addEventListener('click', onCanvasClick); - document.addEventListener('pointerlockchange', onPointerLockChange); - document.addEventListener('mousemove', onMouseMove); - - let moveSpeed = 2; - - const onWheel = (e: WheelEvent) => { - e.preventDefault(); - - // Adjust speed based on wheel direction - const delta = e.deltaY > 0 ? .75 : 1.25; - moveSpeed = Math.max(0.025, Math.min(4, moveSpeed * delta)); - - // Log the new speed for user feedback - console.log(`Movement speed: ${moveSpeed.toFixed(3)}`); - }; - - canvas.addEventListener('wheel', onWheel, { passive: false }); - - const animate = (t) => { - // Free-look movement - const forward = new THREE.Vector3(); - camera.getWorldDirection(forward); - - const right = new THREE.Vector3(); - right.crossVectors(forward, camera.up).normalize(); - - let move = new THREE.Vector3(); - if (keys.w) move.add(forward); - if (keys.s) move.sub(forward); - if (keys.a) move.sub(right); - if (keys.d) move.add(right); - if (keys.space) move.add(camera.up); - if (keys.shift) move.sub(camera.up); - - if (move.lengthSq() > 0) { - move.normalize().multiplyScalar(moveSpeed); - camera.position.add(move); - } - - if (resizeRendererToDisplaySize(renderer)) { - const canvas = renderer.domElement; - camera.aspect = canvas.clientWidth / canvas.clientHeight; - camera.updateProjectionMatrix(); - } - - renderer.render(scene, camera); - }; - renderer.setAnimationLoop(animate); - - threeContext.current = { - scene, - renderer, - camera, - setupColor, - setupMask, - textureLoader, - gltfLoader, - }; - - return () => { - document.removeEventListener("keydown", onKeyDown); - document.removeEventListener("keyup", onKeyUp); - document.removeEventListener('pointerlockchange', onPointerLockChange); - document.removeEventListener('mousemove', onMouseMove); - canvas.removeEventListener('click', onCanvasClick); - canvas.removeEventListener('wheel', onWheel); - renderer.setAnimationLoop(null); - renderer.dispose(); - }; - }, []); - - useEffect(() => { - const { - scene, - camera, - setupColor, - setupMask, - textureLoader, - gltfLoader, - } = threeContext.current; - - let cancel = false; - let root: THREE.Group; - - async function loadMap() { - const mission = await loadMission(missionName); - const terrainFile = getTerrainFile(mission); - const terrain = await loadTerrain(terrainFile); - - const layerCount = terrain.textureNames.length; - - const baseTextures = terrain.textureNames.map((name) => { - return setupColor(textureLoader.load(terrainTextureToUrl(name))); - }); - - const alphaTextures = terrain.alphaMaps.map((data) => setupMask(data)); - - const planeSize = 2048; - const geom = new THREE.PlaneGeometry(planeSize, planeSize, 256, 256); - geom.rotateX(-Math.PI / 2); - geom.rotateY(-Math.PI / 2); - - // Find TerrainBlock properties for empty squares - let emptySquares: number[] | null = null; - for (const obj of iterObjects(mission.objects)) { - if (obj.className === "TerrainBlock") { - const emptySquaresStr = obj.properties.find((p: any) => p.target.name === "emptySquares")?.value; - if (emptySquaresStr) { - emptySquares = emptySquaresStr.split(" ").map((s: string) => parseInt(s)) - } - break; - } - } - - const f32HeightMap = uint16ToFloat32(terrain.heightMap); - - // Create a visibility mask for empty squares - let visibilityMask: THREE.DataTexture | null = null; - if (emptySquares) { - const terrainSize = 256; - - // Create a mask texture (1 = visible, 0 = invisible) - const maskData = new Uint8Array(terrainSize * terrainSize); - maskData.fill(255); // Start with everything visible - - for (const squareId of emptySquares) { - // The squareId encodes position and count: - // Bits 0-7: X position (starting position) - // Bits 8-15: Y position - // Bits 16+: Count (number of consecutive horizontal squares) - const x = (squareId & 0xFF); - const y = (squareId >> 8) & 0xFF; - const count = (squareId >> 16); - - for (let i = 0; i < count; i++) { - const px = x + i; - const py = y; - const index = py * terrainSize + px; - if (index >= 0 && index < maskData.length) { - maskData[index] = 0; - } - } - } - - visibilityMask = new THREE.DataTexture( - maskData, - terrainSize, - terrainSize, - THREE.RedFormat, - THREE.UnsignedByteType - ); - visibilityMask.colorSpace = THREE.NoColorSpace; - visibilityMask.wrapS = visibilityMask.wrapT = THREE.ClampToEdgeWrapping; - visibilityMask.magFilter = THREE.NearestFilter; - visibilityMask.minFilter = THREE.NearestFilter; - visibilityMask.needsUpdate = true; - } - - const heightMap = new THREE.DataTexture( - f32HeightMap, - 256, - 256, - THREE.RedFormat, - THREE.FloatType - ); - heightMap.colorSpace = THREE.NoColorSpace; - heightMap.generateMipmaps = false; - heightMap.needsUpdate = true; - - // Start with a standard material; assign map to trigger USE_MAP/vMapUv - const mat = new THREE.MeshStandardMaterial({ - // map: base0, - displacementMap: heightMap, - map: heightMap, - displacementScale: 2048, - depthWrite: true, - // displacementBias: -128, - }); - - // Inject our 4-layer blend before lighting - mat.onBeforeCompile = (shader) => { - // uniforms for 4 albedo maps + 3 alpha masks - baseTextures.forEach((tex, i) => { - shader.uniforms[`albedo${i}`] = { value: tex }; - }); - alphaTextures.forEach((tex, i) => { - if (i > 0) { - shader.uniforms[`mask${i}`] = { value: tex }; - } - }); - - // Add visibility mask uniform if we have empty squares - if (visibilityMask) { - shader.uniforms.visibilityMask = { value: visibilityMask }; - } - - // Add per-texture tiling uniforms - baseTextures.forEach((tex, i) => { - shader.uniforms[`tiling${i}`] = { - value: Math.min( - 512, - { 0: 16, 1: 16, 2: 32, 3: 32, 4: 32, 5: 32 }[i] - ), - }; - }); - - // Declare our uniforms at the top of the fragment shader - shader.fragmentShader = - ` -uniform sampler2D albedo0; -uniform sampler2D albedo1; -uniform sampler2D albedo2; -uniform sampler2D albedo3; -uniform sampler2D albedo4; -uniform sampler2D albedo5; -uniform sampler2D mask1; -uniform sampler2D mask2; -uniform sampler2D mask3; -uniform sampler2D mask4; -uniform sampler2D mask5; -uniform float tiling0; -uniform float tiling1; -uniform float tiling2; -uniform float tiling3; -uniform float tiling4; -uniform float tiling5; -${visibilityMask ? 'uniform sampler2D visibilityMask;' : ''} -` + shader.fragmentShader; - - if (visibilityMask) { - const clippingPlaceholder = '#include '; - shader.fragmentShader = shader.fragmentShader.replace( - clippingPlaceholder, - `${clippingPlaceholder} - // Early discard for invisible areas (before fog/lighting) - float visibility = texture2D(visibilityMask, vMapUv).r; - if (visibility < 0.5) { - discard; - } - ` - ); - } - - // Replace the default map sampling block with our layered blend. - // We rely on vMapUv provided by USE_MAP. - shader.fragmentShader = shader.fragmentShader.replace( - "#include ", - ` - // Sample base albedo layers (sRGB textures auto-decoded to linear) - vec2 baseUv = vMapUv; - vec3 c0 = texture2D(albedo0, baseUv * vec2(tiling0)).rgb; - ${ - layerCount > 1 - ? `vec3 c1 = texture2D(albedo1, baseUv * vec2(tiling1)).rgb;` - : "" - } - ${ - layerCount > 2 - ? `vec3 c2 = texture2D(albedo2, baseUv * vec2(tiling2)).rgb;` - : "" - } - ${ - layerCount > 3 - ? `vec3 c3 = texture2D(albedo3, baseUv * vec2(tiling3)).rgb;` - : "" - } - ${ - layerCount > 4 - ? `vec3 c4 = texture2D(albedo4, baseUv * vec2(tiling4)).rgb;` - : "" - } - ${ - layerCount > 5 - ? `vec3 c5 = texture2D(albedo5, baseUv * vec2(tiling5)).rgb;` - : "" - } - - // Sample linear masks (use R channel) - float a1 = texture2D(mask1, baseUv).r; - ${layerCount > 1 ? `float a2 = texture2D(mask2, baseUv).r;` : ""} - ${layerCount > 2 ? `float a3 = texture2D(mask3, baseUv).r;` : ""} - ${layerCount > 3 ? `float a4 = texture2D(mask4, baseUv).r;` : ""} - ${layerCount > 4 ? `float a5 = texture2D(mask5, baseUv).r;` : ""} - - // Bottom-up compositing: each mask tells how much the higher layer replaces lower - ${layerCount > 1 ? `vec3 blended = mix(c0, c1, clamp(a1, 0.0, 1.0));` : ""} - ${layerCount > 2 ? `blended = mix(blended, c2, clamp(a2, 0.0, 1.0));` : ""} - ${layerCount > 3 ? `blended = mix(blended, c3, clamp(a3, 0.0, 1.0));` : ""} - ${layerCount > 4 ? `blended = mix(blended, c4, clamp(a4, 0.0, 1.0));` : ""} - ${layerCount > 5 ? `blended = mix(blended, c5, clamp(a5, 0.0, 1.0));` : ""} - - // Assign to diffuseColor before lighting - diffuseColor.rgb = ${layerCount > 1 ? "blended" : "c0"}; -` - ); - }; - - root = new THREE.Group(); - - const terrainMesh = new THREE.Mesh(geom, mat); - root.add(terrainMesh); - - for (const obj of iterObjects(mission.objects)) { - const getProperty = (name) => { - const property = obj.properties.find((p) => p.target.name === name); - // console.log({ name, property }); - return property; - }; - - const getPosition = () => { - const position = getProperty("position")?.value ?? "0 0 0"; - const [x, z, y] = position.split(" ").map((s) => parseFloat(s)); - return [x, y, z]; - }; - - const getScale = () => { - const scale = getProperty("scale")?.value ?? "1 1 1"; - const [scaleX, scaleZ, scaleY] = scale - .split(" ") - .map((s) => parseFloat(s)); - return [scaleX, scaleY, scaleZ]; - }; - - const getRotation = (isInterior = false) => { - const rotation = getProperty("rotation")?.value ?? "1 0 0 0"; - const [ax, az, ay, angle] = rotation - .split(" ") - .map((s) => parseFloat(s)); - - if (isInterior) { - // For interiors: Apply coordinate system transformation - // 1. Convert rotation axis from source coords (ax, az, ay) to Three.js coords - // 2. Apply -90 Y rotation to align coordinate systems - const sourceRotation = new THREE.Quaternion().setFromAxisAngle( - new THREE.Vector3(az, ay, ax), - -angle * (Math.PI / 180) - ); - const coordSystemFix = new THREE.Quaternion().setFromAxisAngle( - new THREE.Vector3(0, 1, 0), - Math.PI / 2 - ); - return coordSystemFix.multiply(sourceRotation); - } else { - // For other objects (terrain, etc) - return new THREE.Quaternion().setFromAxisAngle( - new THREE.Vector3(ax, ay, -az), - angle * (Math.PI / 180) - ); - } - }; - - switch (obj.className) { - case "TerrainBlock": { - const [x, y, z] = getPosition(); - camera.position.set(x - 512, y + 256, z - 512); - const [scaleX, scaleY, scaleZ] = getScale(); - const q = getRotation(); - terrainMesh.position.set(x, y, z); - terrainMesh.scale.set(scaleX, scaleY, scaleZ); - terrainMesh.quaternion.copy(q); - break; - } - case "Sky": { - const materialList = getProperty("materialList")?.value; - if (materialList) { - const detailMapList = await loadDetailMapList(materialList); - const skyLoader = new THREE.CubeTextureLoader(); - const fallbackUrl = `${BASE_URL}/black.png`; - const texture = skyLoader.load([ - getUrlForPath(detailMapList[1], fallbackUrl), // +x - getUrlForPath(detailMapList[3], fallbackUrl), // -x - getUrlForPath(detailMapList[4], fallbackUrl), // +y - getUrlForPath(detailMapList[5], fallbackUrl), // -y - getUrlForPath(detailMapList[0], fallbackUrl), // +z - getUrlForPath(detailMapList[2], fallbackUrl), // -z - ]); - scene.background = texture; - } - const fogDistance = getProperty("fogDistance")?.value; - const fogColor = getProperty("fogColor")?.value; - if (fogDistance && fogColor) { - const distance = parseFloat(fogDistance); - const [r, g, b] = fogColor.split(" ").map((s) => parseFloat(s)); - const color = new THREE.Color().setRGB(r, g, b); - const fog = new THREE.Fog(color, 0, distance * 2); - if (fogEnabled) { - scene.fog = fog; - } else { - scene._fog = fog; - } - } - break; - } - case "InteriorInstance": { - const [z, y, x] = getPosition(); - const [scaleX, scaleY, scaleZ] = getScale(); - const q = getRotation(true); - const interiorFile = getProperty("interiorFile").value; - gltfLoader.load(interiorToUrl(interiorFile), (gltf) => { - gltf.scene.traverse((o) => { - if (o.material?.name) { - const name = o.material.name; - try { - const tex = textureLoader.load(interiorTextureToUrl(name)); - o.material.map = setupColor(tex); - } catch (err) { - console.error(err); - } - o.material.needsUpdate = true; - } - }); - const interior = gltf.scene; - interior.position.set(x - 1024, y, z - 1024); - interior.scale.set(-scaleX, scaleY, -scaleZ); - interior.quaternion.copy(q); - root.add(interior); - }); - break; - } - case "WaterBlock": { - const [z, y, x] = getPosition(); - const [scaleZ, scaleY, scaleX] = getScale(); - const q = getRotation(true); - - const surfaceTexture = - getProperty("surfaceTexture")?.value ?? "liquidTiles/BlueWater"; - - const geometry = new THREE.BoxGeometry(scaleZ, scaleY, scaleX); - const material = new THREE.MeshStandardMaterial({ - map: setupColor( - textureLoader.load(textureToUrl(surfaceTexture)), - [8, 8] - ), - // transparent: true, - opacity: 0.8, - }); - const water = new THREE.Mesh(geometry, material); - - water.position.set( - x - 1024 + scaleX / 2, - y + scaleY / 2, - z - 1024 + scaleZ / 2 - ); - water.quaternion.copy(q); - - root.add(water); - break; - } - } - } - - if (cancel) { - return; - } - - scene.add(root); - } - - loadMap(); - - return () => { - cancel = true; - root.removeFromParent(); - }; - }, [missionName]); - - useEffect(() => { - const { scene } = threeContext.current; - if (fogEnabled) { - scene.fog = scene._fog ?? null; - scene._fog = null; - scene.needsUpdate = true; - } else { - scene._fog = scene.fog; - scene.fog = null; - scene.needsUpdate = true; - } - }, [fogEnabled]); + const params = new URLSearchParams(); + params.set("mission", missionName); + router.replace(`?${params.toString()}`, { scroll: false }); + }, [missionName, router]); return ( -
- -
- -
- { - setFogEnabled(event.target.checked); - }} + +
+ + + + + + + + + + - -
-
-
+ + + ); } diff --git a/app/style.css b/app/style.css index b2badbf9..d5d0e6f4 100644 --- a/app/style.css +++ b/app/style.css @@ -2,6 +2,7 @@ html, body { margin: 0; padding: 0; + background: black; } html { @@ -10,8 +11,7 @@ html { font-size: 100%; } -#canvas { - display: block; +main { width: 100vw; height: 100vh; } @@ -19,7 +19,7 @@ html { #controls { display: flex; align-items: center; - gap: 10px; + gap: 20px; position: fixed; top: 0; left: 0; @@ -35,3 +35,13 @@ html { align-items: center; gap: 6px; } + +.Field { + display: flex; + align-items: center; + gap: 6px; +} + +#speedInput { + max-width: 80px; +} diff --git a/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.hmale.png b/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.hmale.png deleted file mode 100644 index 83fb1171..00000000 Binary files a/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.hmale.png and /dev/null differ diff --git a/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.lmale.png b/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.lmale.png deleted file mode 100644 index 223ed891..00000000 Binary files a/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.lmale.png and /dev/null differ diff --git a/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.mmale.png b/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.mmale.png deleted file mode 100644 index 2fd53489..00000000 Binary files a/docs/base/@vl2/StormJason.vl2/textures/skins/StormJason.mmale.png and /dev/null differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2flag.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2flag.glb new file mode 100644 index 00000000..985c7c36 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2flag.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2heavy_male.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2heavy_male.glb new file mode 100644 index 00000000..917708b5 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2heavy_male.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_female.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_female.glb new file mode 100644 index 00000000..f160e59e Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_female.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_male.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_male.glb new file mode 100644 index 00000000..b8bb0d13 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_male.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_female.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_female.glb new file mode 100644 index 00000000..132cf332 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_female.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_male.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_male.glb new file mode 100644 index 00000000..68886c98 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_male.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_chaingun.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_chaingun.glb new file mode 100644 index 00000000..dd6f827e Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_chaingun.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_disc.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_disc.glb new file mode 100644 index 00000000..29cbd885 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_disc.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_grenade_launcher.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_grenade_launcher.glb new file mode 100644 index 00000000..c1b38d3d Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_grenade_launcher.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_mortar.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_mortar.glb new file mode 100644 index 00000000..38e23f5d Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_mortar.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_shocklance.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_shocklance.glb new file mode 100644 index 00000000..57ad1169 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_shocklance.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_1.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_1.glb new file mode 100644 index 00000000..fc79856b Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_1.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_2.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_2.glb new file mode 100644 index 00000000..723d3fa9 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_2.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_3.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_3.glb new file mode 100644 index 00000000..2cd782bd Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_3.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_4.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_4.glb new file mode 100644 index 00000000..311182f7 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_4.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_back.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_back.glb new file mode 100644 index 00000000..7fd0dbe4 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_back.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_panel.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_panel.glb new file mode 100644 index 00000000..d89b73e3 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_panel.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_side.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_side.glb new file mode 100644 index 00000000..cd997e1a Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_side.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_top.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_top.glb new file mode 100644 index 00000000..a1aead39 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/goal_top.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_back.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_back.glb new file mode 100644 index 00000000..2956a553 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_back.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_side.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_side.glb new file mode 100644 index 00000000..a6853551 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_side.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_top.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_top.glb new file mode 100644 index 00000000..bb0f0ab4 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_top.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/golden_pole.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/golden_pole.glb new file mode 100644 index 00000000..6d54ddb2 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/golden_pole.glb differ diff --git a/docs/base/@vl2/TR2final105-client.vl2/shapes/silver_pole.glb b/docs/base/@vl2/TR2final105-client.vl2/shapes/silver_pole.glb new file mode 100644 index 00000000..6462a4f5 Binary files /dev/null and b/docs/base/@vl2/TR2final105-client.vl2/shapes/silver_pole.glb differ diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2BonusCategories.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2BonusCategories.cs deleted file mode 100644 index ca26473e..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2BonusCategories.cs +++ /dev/null @@ -1,468 +0,0 @@ -// BonusCategories - -// You can create CBonuses that arbitrarily combine any number of -// these categories. Pretty cool. -// Prefixes - tests a player's orientation relative to an object -// Noun - tests two players' heights and one player's speed -// Qualifier - tests an object's horizontal speed, vertical speed, and hangtime -// Description - very specific category for flag passes -// - -exec("scripts/TR2Prefixes.cs"); -exec("scripts/TR2Nouns.cs"); -exec("scripts/TR2Qualifiers.cs"); -exec("scripts/TR2Descriptions.cs"); -exec("scripts/TR2WeaponBonuses.cs"); - -function BonusCategory::performEffects(%this, %component, %obj) -{ - // DEBUG! Don't play dummy sounds - if (%component.sound $= "blah.wav") - return; - - serverPlay2d(%component.sound); - - // Particle effects -} - -function BonusCategory::createCategoryData(%this, %p0, %p1, %p2, %p3, %p4) -{ - // Add some dynamic info to the data before returning it. Save the parameter - // values for calculating variance. - %categoryData = %this.data.get(%p0, %p1, %p2, %p3, %p4); - %categoryData.numParameters = %this.dimensionality; - - for (%i=0; %i<%categoryData.numParameters; %i++) - %categoryData.parameter[%i] = %p[%i]; - - return %categoryData; -} - -// Nouns -new ScriptObject(Noun) -{ - class = Noun; - superclass = BonusCategory; - dimensionality = 3; - passerSpeedLevels = 4; - grabberSpeedLevels = 4; - grabberHeightLevels = 4; - passerSpeedThreshold[0] = 10; - passerSpeedThreshold[1] = 35; - passerSpeedThreshold[2] = 57; - passerSpeedThreshold[3] = 85; - grabberSpeedThreshold[0] = 10; - grabberSpeedThreshold[1] = 35; - grabberSpeedThreshold[2] = 57; - grabberSpeedThreshold[3] = 85; - grabberHeightThreshold[0] = 5; - grabberHeightThreshold[1] = 30; - grabberHeightThreshold[2] = 90; - grabberHeightThreshold[3] = 230; - soundDelay = 0; -}; - -// Nouns play in 3D -function Noun::performEffects(%this, %component, %obj) -{ - // DEBUG! Don't play dummy sounds - if (%component.sound $= "blah.wav") - return; - - serverPlay2d(%component.sound);//, %obj.getPosition()); -} - -function Noun::evaluateold(%this, %grabber, %flag) -{ - %passerSpeed = VectorLen(%flag.dropperVelocity); - %grabberSpeed = %grabber.getSpeed(); - %grabberHeight = %grabber.getHeight(); - - // Don't award a Noun bonus if the flag is on a goal - if (%flag.onGoal) - return; - - // Might be able to abstract these loops somehow - // Passer speed - for(%i=%this.passerSpeedLevels - 1; %i>0; %i--) - if (%passerSpeed >= %this.passerSpeedThreshold[%i]) - break; - - // Grabber speed - for(%j=%this.grabberSpeedLevels - 1; %j>0; %j--) - if (%grabberSpeed >= %this.grabberSpeedThreshold[%j]) - break; - - // Grabber height - for(%k=%this.grabberHeightLevels - 1; %k>0; %k--) - if (%grabberHeight >= %this.grabberHeightThreshold[%k]) - break; - - //echo("NOUN: passSpeed = " @ %passerSpeed @ " grabSpeed = " @ %grabberSpeed @ " grabHeight = " @ %grabberHeight); - //echo("NOUN: " SPC %i SPC %j SPC %k); - return %this.createCategoryData(%i, %j, %k); -} - -function Noun::evaluate(%this, %player1, %player2, %flag) -{ - if (%flag !$= "") - { - // Don't award a Noun bonus if the flag is on a goal - if (%flag.onGoal) - return %this.createCategoryData(0, 0, 0); - - // If the flag thinks it is airborn, yet it's not moving... - if (%flag.getHeight() > 7 && %flag.getSpeed() < 3) - return %this.createCategoryData(0, 0, 0); - - // Use a special Noun for water pickups - if (%flag.inLiquid) - return $WaterNoun; - - %player1Speed = VectorLen(%flag.dropperVelocity); - } - else - %player1Speed = %player1.getSpeed(); - - %player2Speed = %player2.getSpeed(); - %player2Height = %player2.getHeight(); - - // Might be able to abstract these loops somehow - // Passer speed - for(%i=%this.passerSpeedLevels - 1; %i>0; %i--) - if (%player1Speed >= %this.passerSpeedThreshold[%i]) - break; - - // Grabber speed - for(%j=%this.grabberSpeedLevels - 1; %j>0; %j--) - if (%player2Speed >= %this.grabberSpeedThreshold[%j]) - break; - - // Grabber height - for(%k=%this.grabberHeightLevels - 1; %k>0; %k--) - if (%player2Height >= %this.grabberHeightThreshold[%k]) - break; - - //echo("NOUN: passSpeed = " @ %passerSpeed @ " grabSpeed = " @ %grabberSpeed @ " grabHeight = " @ %grabberHeight); - //echo("NOUN: " SPC %i SPC %j SPC %k); - return %this.createCategoryData(%i, %j, %k); -} - -// Qualifiers -new ScriptObject(Qualifier) -{ - class = Qualifier; - superclass = BonusCategory; - dimensionality = 3; - horizontalFlagSpeedLevels = 2; - verticalFlagSpeedLevels = 3; - hangTimeLevels = 4; - horizontalFlagSpeedThreshold[0] = 10; - horizontalFlagSpeedThreshold[1] = 40; - verticalFlagSpeedThreshold[0] = 4; - verticalFlagSpeedThreshold[1] = 20; - verticalFlagSpeedThreshold[2] = 40; - hangTimeThreshold[0] = 500; - hangTimeThreshold[1] = 1200; - hangTimeThreshold[2] = 2500; - hangTimeThreshold[3] = 5000; - soundDelay = 0; -}; - -function Qualifier::evaluate(%this, %dropper, %grabber, %flag) -{ - %flagSpeed = %flag.getSpeed(); - if (%flag.inLiquid || %dropper $= "" || %flag.getSpeed() < 5) - return; - - %dropperSpeed = VectorLen(%flag.dropperVelocity); - - // Lock these down a bit - if (%grabber.getSpeed() < 13 && %dropperSpeed < 8) - return; - - //if (getSimTime() - %flag.dropTime <= 500) - // return; - - if (%flag.getHeight() < 7) - return; - - %flagVel = %flag.getVelocity(); - %horizontalFlagSpeed = VectorLen(setWord(%flagVel, 2, 0)); - %verticalFlagSpeed = mAbs(getWord(%flagVel, 2)); - - // Test to see if the pass was good enough...it must have a sufficient - // horizontal speed, and failing that, it must either be midair or have - // a sufficient downward speed. - if (%horizontalFlagSpeed < %this.horizontalFlagSpeedThreshold[0]) - if (%flag.getHeight() < 10) - if (%verticalFlagSpeed < %this.verticalFlagSpeedThreshold[0]) - return ""; - - - // Horizontal flag speed - for(%i=%this.horizontalFlagSpeedLevels - 1; %i>0; %i--) - if (%horizontalFlagSpeed >= %this.horizontalFlagSpeedThreshold[%i]) - break; - - // Vertical flag speed - for(%j=%this.verticalFlagSpeedLevels - 1; %j>0; %j--) - if (%verticalFlagSpeed >= %this.verticalFlagSpeedThreshold[%j]) - break; - - // Hangtime - %hangtime = getSimTime() - %flag.dropTime; - for(%k=%this.hangTimeLevels - 1; %k>0; %k--) - if (%hangTime >= %this.hangTimeThreshold[%k]) - break; - - //echo("QUALIFIER: horSpeed = " @ %horizontalFlagSpeed @ " verSpeed = " @ %verticalFlagSpeed @ " hang = " @ %hangtime); - //echo("QUALIFIER: " @ %i SPC %j SPC %k); - - return %this.createCategoryData(%i, %j, %k); -} - -// Descriptions -new ScriptObject(Description) -{ - class = Description; - superclass = BonusCategory; - dimensionality = 3; - soundDelay = 1000; -}; - -function Description::evaluate(%this, %dropper, %grabber, %flag) -{ - %flagVel = %flag.getVelocity(); - - // Return default description if the flag was dropped because the flag - // carrier died. - if (%dropper $= "" || %dropper.client.plyrDiedHoldingFlag - || %flag.inLiquid) - return $DefaultDescription; - - if (%grabber.getHeight() < 5 || %flag.getSpeed() < 5 || %flag.getHeight() < 5) - return $DefaultDescription; - - // Make sure the pass was good enough to warrant a full bonus description. - // If it wasn't a high pass with decent speed, check the hangtime; if there - // wasn't lots of hangtime, don't give this bonus - if (%flag.getHeight() < 30 || %flag.getSpeed() < 15) - if (getSimTime() - %flag.dropTime <= 1000) - return $DefaultDescription; - - %dropperSpeed = VectorLen(%flag.dropperVelocity); - // Don't give this bonus if they're both just standing/hovering around - if (%grabber.getSpeed() < 17 && %dropperSpeed < 12) - return $DefaultDescription; - - - // Determine passer's dominant direction (horizontal or vertical) at the - // time the flag was dropped. - %passerVertical = getWord(%flag.dropperVelocity, 2); - %passerHorizontal = VectorLen(setWord(%flag.dropperVelocity, 2, 0)); - %passerDir = 0; // Horizontal dominance - if ( mAbs(%passerVertical) >= %passerHorizontal) - { - // Now decide if the passer was travelling mostly up or mostly down - if (%passerVertical >= 0) - %passerDir = 1; // Upward dominance - else - %passerDir = 2; // Downward dominance - } - - //echo("DESCRIPTION: ver = " @ %passerVertical @ " hor = " @ %passerHorizontal); - - // Based on the dominant direction, use either the xy-plane or the xz-plane - // for comparisons. - if (%passerDir == 0) - { - // Horizontal: use xy-plane - %dropperOrientationN = setWord(VectorNormalize(%flag.dropperOrientation), 2, 0); - %dropperVelocityN = setWord(VectorNormalize(%flag.dropperVelocity), 2, 0); - } else { - // Vertical: use xz-plane - %dropperOrientationN = setWord(VectorNormalize(%flag.dropperOrientation), 1, 0); - %dropperVelocityN = setWord(VectorNormalize(%flag.dropperVelocity), 1, 0); - } - - // Determine passer's dominant orientation relative to velocity at the time - // the flag was dropped (forward pass, backward pass, or perpendicular pass). - %passDirectionDot = VectorDot(%dropperOrientationN, %dropperVelocityN); - %passDir = 0; // Forward pass - //echo("DESCRIPTION: passDirDot = " @ %passDirectionDot); - if (%passDirectionDot <= -0.42) - %passDir = 1; // Backward pass - else if (%passDirectionDot >= -0.29 && %passDirectionDot <= 0.29) - %passDir = 2; // Perpendicular pass - - // Do the same for the flag's dominant direction. - %flagVertical = mAbs(getWord(%flagVel, 2)); - %flagHorizontal = VectorLen(setWord(%flagVel, 2, 0)); - %flagDir = (%flagHorizontal >= %flagVertical) ? 0 : 1; - %grabberVel = %grabber.getVelocity(); - - if (%flagDir == 0) - { - %flagVelocityN = setWord(VectorNormalize(%flagVel), 2, 0); - %grabberVelN = setWord(VectorNormalize(%grabberVel), 2, 0); - } - else - { - %flagVelocityN = setWord(VectorNormalize(%flagVel), 1, 0); - %grabberVelN = setWord(VectorNormalize(%grabberVel), 1, 0); - } - - // Determine the flag's velocity relative to the grabber's velocity at the time - // the flag is grabbed, ie. now (into pass, with pass, perpendicular to pass). - %flagDirectionDot = VectorDot(%dropperOrientationN, %grabberVelN); - %flagDir = 0; // Default to travelling into the pass - //echo("DESCRIPTION: flagDirDot = " @ %flagDirectionDot); - if (%flagDirectionDot >= 0.7) - %flagDir = 1; // Travelling with the pass - else if (%flagDirectionDot >= -0.21 && %flagDirectionDot <= 0.21) - %flagDir = 2; // Travelling perpendicular to the pass - - //echo("DESCRIPTION:" - // @ " passerDir = " @ %passerDir - // @ " passDir = " @ %passDir - // @ " flagDir = " @ %flagDir); - - return %this.createCategoryData(%passerDir, %passDir, %flagDir); -} - -// Prefixs - -new ScriptObject(Prefix) -{ - class = Prefix; - superclass = BonusCategory; - dimensionality = 1; - grabberOrientationLevels = 3; - grabberOrientationThreshold[0] = -0.1; - grabberOrientationThreshold[1] = -0.5; - grabberOrientationThreshold[2] = -0.85; - soundDelay = 0; -}; - -function Prefix::evaluate(%this, %dropper, %grabber, %flag) -{ - // Determine if the grabber caught the flag backwards. Derive a - // relative position vector and calculate the dot product. - %flagPos = %flag.getPosition(); - %grabberPos = %grabber.getPosition(); - %grabberEye = %grabber.getEyeVector(); - - // If the flag is sliding around near the ground, only expect the grabber to - // be horizontally backwards...otherwise, he must be backwards in all dimensions. - if (%flag.getHeight() < 10 && getWord(%flag.getVelocity(), 2) < 17) - %flagPos = setWord(%flagPos, 2, getWord(%grabberPos, 2)); - - %relativePos = VectorNormalize(VectorSub(%flagPos, %grabberPos)); - %relativeDot = VectorDot(%relativePos, %grabberEye); - //echo("PREFIX TEST: reldot = " @ %relativeDot); - - // Should probably put this into a loop - if (%relativeDot <= %this.grabberOrientationThreshold[2]) - %grabberDir = 2; - else if (%relativeDot <= %this.grabberOrientationThreshold[1]) - %grabberDir = 1; - else if (%relativeDot <= %this.grabberOrientationThreshold[0]) - %grabberDir = 0; - else - return ""; - - //echo("Prefix: " @ %grabberDir); - return %this.createCategoryData(%grabberDir); -} - -// Weapon speed (speed of victim) -new ScriptObject(SpeedBonus) -{ - class = SpeedBonus; - superclass = BonusCategory; - dimensionality = 1; - SpeedLevels = 3; - SpeedThreshold[0] = 20; - SpeedThreshold[1] = 65; - SpeedThreshold[2] = 100; - soundDelay = 0; -}; - -function SpeedBonus::evaluate(%this, %notUsed, %victim) -{ - // A little trick to allow evaluation for either parameter - if (%victim $= "") - %victim = %notUsed; - - %victimSpeed = %victim.getSpeed(); - - if (%victimSpeed < %this.SpeedThreshold[0]) - return; - - // Victim speed - for(%i=%this.SpeedLevels - 1; %i>0; %i--) - if (%victimSpeed >= %this.SpeedThreshold[%i]) - break; - - //echo("SB: " SPC %i SPC "speed =" SPC %victimSpeed); - return %this.createCategoryData(%i); -} - -// Weapon height (height of victim) -new ScriptObject(HeightBonus) -{ - class = HeightBonus; - superclass = BonusCategory; - dimensionality = 1; - heightLevels = 3; - HeightThreshold[0] = 15; - HeightThreshold[1] = 40; - HeightThreshold[2] = 85; -}; - - -function HeightBonus::evaluate(%this, %notUsed, %victim) -{ - // A little trick to allow evaluation for either parameter - if (%victim $= "") - %victim = %notUsed; - - %victimHeight = %victim.getHeight(); - - if (%victimHeight < %this.HeightThreshold[0]) - return; - - // Victim height - for(%i=%this.HeightLevels - 1; %i>0; %i--) - if (%victimHeight >= %this.HeightThreshold[%i]) - break; - - //echo("HB: " SPC %i); - return %this.createCategoryData(%i); -} - -// Weapon type -new ScriptObject(WeaponTypeBonus) -{ - class = WeaponTypeBonus; - superclass = BonusCategory; - dimensionality = 1; -}; - - -function WeaponTypeBonus::evaluate(%this, %shooter, %victim, %damageType) -{ - // Determine shooter weapon type here - switch(%damageType) - { - case $DamageType::Disc: %i = 0; - case $DamageType::Grenade: %i = 1; - case $DamageType::Bullet: %i = 2; - } - - //echo("WTB: " SPC %i); - return %this.createCategoryData(%i); -} - - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2BonusSounds.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2BonusSounds.cs deleted file mode 100644 index aa243dff..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2BonusSounds.cs +++ /dev/null @@ -1,1083 +0,0 @@ - -// Misc. -datablock AudioProfile(CrowdClapSound) -{ - volume = 1.0; - filename = "fx/misc/crowd-clap.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdDisappointment1Sound) -{ - volume = 1.0; - filename = "fx/misc/missed.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdCheer1Sound) -{ - volume = 1.0; - filename = "fx/misc/cheer.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdFlairSound) -{ - volume = 1.0; - filename = "fx/misc/flair.wav"; - description = Audio2D; -}; - -// Bonus sound profiles - -// Assorted -datablock AudioProfile(MarioSound) -{ - volume = 1.0; - filename = "fx/bonuses/mario-6notes.wav"; - description = Audio2D; -}; - -datablock AudioProfile(GameStartSound) -{ - volume = 1.0; - filename = "fx/misc/gamestart.wav"; - description = Audio2D; -}; - -datablock AudioProfile(GadgetSound) -{ - volume = 1.0; - filename = "fx/bonuses/gadget3.wav"; - description = Audio2D; -}; - -datablock AudioProfile(EvilLaughSound) -{ - volume = 1.0; - filename = "fx/bonuses/evillaugh.wav"; - description = AudioBigExplosion3D; -}; - -datablock AudioProfile(RoleChangeSound) -{ - volume = 1.0; - filename = "fx/misc/rolechange.wav"; - description = AudioExplosion3D; -}; - -//datablock AudioProfile(InterceptionFriendlySound) -//{ -// volume = 1.0; -// filename = "fx/misc/nexus_cap"; -// description = Audio2D; -//}; - -//datablock AudioProfile(InterceptionEnemySound) -//{ -// volume = 1.0; -// filename = "fx/misc/flag_taken.wav"; -// description = Audio2D; -//}; - -datablock AudioProfile(CarScreechSound) -{ - volume = 1.0; - filename = "fx/misc/carscreech.wav"; - description = AudioBigExplosion3D; -}; - -datablock AudioProfile(SlapshotSound) -{ - volume = 1.0; - filename = "fx/misc/slapshot.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CoinSound) -{ - volume = 1.0; - filename = "fx/misc/coin.wav"; - description = AudioBigExplosion3D; -}; - -datablock AudioProfile(MA1Sound) -{ - volume = 1.0; - filename = "fx/misc/MA1.wav"; - description = Audio2D; -}; - -datablock AudioProfile(MA2Sound) -{ - volume = 1.0; - filename = "fx/misc/MA2.wav"; - description = Audio2D; -}; - -datablock AudioProfile(MA3Sound) -{ - volume = 1.0; - filename = "fx/misc/MA3.wav"; - description = Audio2D; -}; - - -datablock AudioProfile(MonsterSound) -{ - volume = 1.0; - filename = "fx/Bonuses/TRex.wav"; - description = AudioBigExplosion3D; -}; - -datablock AudioProfile(CrowdLoop1Sound) -{ - volume = 1.0; - filename = "fx/misc/crowd.wav"; - description = AudioLooping2D; -}; - -datablock AudioProfile(CrowdLoop2Sound) -{ - volume = 1.0; - filename = "fx/misc/crowd2.wav"; - description = AudioLooping2D; -}; - -datablock AudioProfile(CrowdLoop3Sound) -{ - volume = 1.0; - filename = "fx/misc/crowd3.wav"; - description = AudioLooping2D; -}; - -datablock AudioProfile(CrowdTransition1aSound) -{ - volume = 1.0; - filename = "fx/misc/crowdtransition1a.wav"; - description = Audio2D; -}; -datablock AudioProfile(CrowdTransition1bSound) -{ - volume = 1.0; - filename = "fx/misc/crowdtransition1b.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdTransition2aSound) -{ - volume = 1.0; - filename = "fx/misc/crowdtransition2a.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdTransition2bSound) -{ - volume = 1.0; - filename = "fx/misc/crowdtransition2b.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdTransition3aSound) -{ - volume = 1.0; - filename = "fx/misc/crowdtransition3a.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdTransition3bSound) -{ - volume = 1.0; - filename = "fx/misc/crowdtransition3b.wav"; - description = Audio2D; -}; - -datablock AudioProfile(CrowdFadeSound) -{ - volume = 1.0; - filename = "fx/misc/crowdfade.wav"; - description = Audio2D; -}; - -$TR2::CrowdLoopTransitionUp[0] = CrowdTransition1aSound; -$TR2::CrowdLoop[0] = CrowdLoop1Sound; -$TR2::CrowdLoopTransitionDown[0] = CrowdTransition1bSound; -$TR2::CrowdLoopTransitionUp[1] = CrowdTransition2aSound; -$TR2::CrowdLoop[1] = CrowdLoop2Sound; -$TR2::CrowdLoopTransitionDown[1] = CrowdTransition2bSound; -$TR2::CrowdLoopTransitionUp[2] = CrowdTransition3aSound; -$TR2::CrowdLoop[2] = CrowdLoop3Sound; -$TR2::CrowdLoopTransitionDown[2] = CrowdTransition3bSound; -$TR2::NumCrowdLevels = 3; - - -// Creativity -datablock AudioProfile(Creativity1Sound) -{ - volume = 1.0; - filename = "fx/bonuses/qseq1.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Creativity2Sound) -{ - volume = 1.0; - filename = "fx/bonuses/qseq2.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Creativity3Sound) -{ - volume = 1.0; - filename = "fx/bonuses/qseq3.wav"; - description = Audio2D; -}; - - -// Nouns -datablock AudioProfile(NounDogSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/dog.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounHorseSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/horse.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounWolfSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/wolf.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounInsect1Sound) -{ - volume = 1.0; - filename = "fx/bonuses/insect1.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounInsect2Sound) -{ - volume = 1.0; - filename = "fx/bonuses/insect2.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounAstronautSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/astronaut.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounAtmosphereSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/atmosphere.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBalloonSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/balloon.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBatSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/bats.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBeeSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/beeswarm.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBirdOfPreySound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/birdofprey.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBlimpSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/blimp.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBluejaySound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/bluejay.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBudgieSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/budgie.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounButterlySound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/butterfly.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCamelSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/camel.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCaptainSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/captain.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCatSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/cat.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCheetahSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/cheetah.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounChickadeeSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/chickadee.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCloudSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/cloud.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounColonelSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/colonel.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCondorSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/condor.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCougarSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/cougar.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCowSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/cow.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCoyoteSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/coyote.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounDonkeySound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/donkey.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounDoveSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/dove.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounDragonflySound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/dragonfly.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounFishSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/fish.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounFlamingoSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/flamingo.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounFlySound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/fly.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounGeneralSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/general.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounGoldfinchSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/goldfinch.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounGrasshopperSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/grasshopper.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounHornetSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/hornet.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounHelicopterSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/helicopter.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounHurricaneSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/hurricane.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounIguanaSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/iguana.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounJaguarSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/jaguar.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounJetSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/airplane.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounLlamaSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/llama.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounMajorSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/major.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounMoonSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/moon.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounCrowSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/crow.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounMosquitoSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/msquito.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounOstrichSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/ostrich.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounOwlSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/Owl.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounOzoneSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/ozone.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounParakeetSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/parakeet.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounParrotSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/parrot.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounPelicanSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/pelican.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounPuppySound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/puppy.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounSharkSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/shark.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounSnakeSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/snake.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounSwallowSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/Swallow.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounTigerSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/tiger.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounTornadoSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/tornado.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounTurtleSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/turtle.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounWarnippleSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/warnipple.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounWaspSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/wasp.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounZebraSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/zebra.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounZeppellinSound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/zeppellin.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounSpecial1Sound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/Special1.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounSpecial2Sound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/Special2.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounSpecial3Sound) -{ - volume = 1.0; - filename = "fx/bonuses/Nouns/Special3.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounGrowlSound) -{ - volume = 1.0; - filename = "fx/environment/growl4.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounWindSound) -{ - volume = 1.0; - filename = "fx/environment/moaningwind1.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBird1Sound) -{ - volume = 1.0; - filename = "fx/environment/bird_echo1.wav"; - description = Audio2D; -}; - -datablock AudioProfile(NounBird2Sound) -{ - volume = 1.0; - filename = "fx/environment/bird_echo5.wav"; - description = Audio2D; -}; - - - - -// Qualifiers -datablock AudioProfile(Qualifier100Sound) -{ - volume = 1.0; - filename = "fx/bonuses/low-level1-sharp.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier010Sound) -{ - volume = 1.0; - filename = "fx/bonuses/low-level2-spitting.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier110Sound) -{ - volume = 1.0; - filename = "fx/bonuses/low-level3-whipped.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier020Sound) -{ - volume = 1.0; - filename = "fx/bonuses/low-level4-popping.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier120Sound) -{ - volume = 1.0; - filename = "fx/bonuses/low-level5-bursting.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier001Sound) -{ - volume = 1.0; - filename = "fx/bonuses/med-level1-modest.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier101Sound) -{ - volume = 1.0; - filename = "fx/bonuses/med-level2-ripped.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier011Sound) -{ - volume = 1.0; - filename = "fx/bonuses/med-level3-shining.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier111Sound) -{ - volume = 1.0; - filename = "fx/bonuses/med-level4-slick.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier021Sound) -{ - volume = 1.0; - filename = "fx/bonuses/med-level5-sprinkling"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier121Sound) -{ - volume = 1.0; - filename = "fx/bonuses/med-level6-brilliant.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier002Sound) -{ - volume = 1.0; - filename = "fx/bonuses/high-level1-frozen.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier102Sound) -{ - volume = 1.0; - filename = "fx/bonuses/high-level2-shooting.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier012Sound) -{ - volume = 1.0; - filename = "fx/bonuses/high-level3-dangling.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier112Sound) -{ - volume = 1.0; - filename = "fx/bonuses/high-level4-blazing.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier022Sound) -{ - volume = 1.0; - filename = "fx/bonuses/high-level5-raining.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier122Sound) -{ - volume = 1.0; - filename = "fx/bonuses/high-level6-falling.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier003Sound) -{ - volume = 1.0; - filename = "fx/bonuses/wow-level1-suspended.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier103Sound) -{ - volume = 1.0; - filename = "fx/bonuses/wow-level2-skeeting.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier013Sound) -{ - volume = 1.0; - filename = "fx/bonuses/wow-level3-hanging.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier113Sound) -{ - volume = 1.0; - filename = "fx/bonuses/wow-level4-arcing.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier023Sound) -{ - volume = 1.0; - filename = "fx/bonuses/wow-level5-pouring.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Qualifier123Sound) -{ - volume = 1.0; - filename = "fx/bonuses/wow-level6-elite.wav"; - description = Audio2D; -}; - - -// Descriptions -datablock AudioProfile(Description000Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_straipass1_bullet.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description001Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_straipass2_heist.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description002Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_straipass3_smackshot.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description010Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_passback1_jab.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description011Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_passback2_backbreaker.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description012Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_passback3_leetlob.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description020Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_perppass1_peeler.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description021Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_perppass2_blender.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description022Sound) -{ - volume = 1.0; - filename = "fx/bonuses/horz_perppass3_glasssmash.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description100Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_straipass1_ascension.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description101Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_straipass2_elevator.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description102Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_straipass3_rainbow.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description110Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_passback1_bomb.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description111Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_passback2_deliverance.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description112Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_passback3_crank.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description120Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_perppass1_fling.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description121Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_perppass2_quark.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description122Sound) -{ - volume = 1.0; - filename = "fx/bonuses/upward_perppass3_juggletoss.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description200Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_straipass1_yoyo.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description201Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_straipass2_skydive.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description202Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_straipass3_jolt.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description210Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_passback1_prayer.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description211Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_passback2_moyoyo.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description212Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_passback3_rocket.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description220Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_perppass1_blast.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description221Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_perppass2_deepdish.wav"; - description = Audio2D; -}; - -datablock AudioProfile(Description222Sound) -{ - volume = 1.0; - filename = "fx/bonuses/down_perppass3_bunnybump.wav"; - description = Audio2D; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Bonuses.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Bonuses.cs deleted file mode 100644 index d334fa5e..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Bonuses.cs +++ /dev/null @@ -1,464 +0,0 @@ -// TR2 Bonuses -// This file execs the entire bonus infrastructure, and also contains all the -// evaluate() and award() functions for bonuses. -exec("scripts/TR2BonusSounds.cs"); -exec("scripts/TR2BonusCategories.cs"); -exec("scripts/TR2OtherBonuses.cs"); - -$TR2::teamColor[1] = ""; // Gold -$TR2::teamColor[2] = ""; // Silver - -function initializeBonuses() -{ - // Flag bonus - if (!isObject(FlagBonus)) - { - new ScriptObject(FlagBonus) - { - class = FlagBonus; - superclass = Bonus; - history = FlagBonusHistory; - }; - FlagBonus.addCategory(Prefix, $PrefixList); - FlagBonus.addCategory(Noun, $NounList); - FlagBonus.addCategory(Qualifier, $QualifierList); - FlagBonus.addCategory(Description, $DescriptionList); - //MissionCleanup.add(FlagBonus); - } - - // Weapon kill bonus - if (!isObject(WeaponBonus)) - { - new ScriptObject(WeaponBonus) - { - class = WeaponBonus; - superclass = Bonus; - instant = true; - history = ""; - }; - WeaponBonus.addCategory(HeightBonus, $WeaponHeightBonusList); - WeaponBonus.addCategory(SpeedBonus, $WeaponSpeedBonusList); - WeaponBonus.addCategory(WeaponTypeBonus, $WeaponTypeBonusList); - //MissionCleanup.add(WeaponBonus); - } - - // Go-go Gadget Bonus - if (!isObject(G4Bonus)) - { - new ScriptObject(G4Bonus) - { - class = G4Bonus; - superclass = Bonus; - history = ""; - }; - G4Bonus.addCategory(Noun, $NounList); - //MissionCleanup.add(G4Bonus); - } - - // Midair Bonus - if (!isObject(MidairBonus)) - { - new ScriptObject(MidairBonus) - { - class = MidairBonus; - superclass = Bonus; - history = ""; - }; - //MissionCleanup.add(MidairBonus); - } - - // Collision Bonus - if (!isObject(CollisionBonus)) - { - new ScriptObject(CollisionBonus) - { - class = CollisionBonus; - superclass = Bonus; - history = ""; - }; - //MissionCleanup.add(CollisionBonus); - } - - // Creativity Bonus - if (!isObject(CreativityBonus)) - { - new ScriptObject(CreativityBonus) - { - class = CreativityBonus; - superclass = Bonus; - instant = true; - lastVariance = 0; - lastVarianceLevel = 0; - varianceLevels = 4; - varianceThreshold[0] = 0; - varianceThreshold[1] = 17; - varianceThreshold[2] = 34; - varianceThreshold[3] = 51; - varianceValue[0] = 0; - varianceValue[1] = 25; - varianceValue[2] = 50; - varianceValue[3] = 75; - varianceSound[0] = ""; - varianceSound[1] = Creativity1Sound; - varianceSound[2] = Creativity2Sound; - varianceSound[3] = Creativity3Sound; - history = ""; - }; - //MissionCleanup.add(CreativityBonus); - } -} - -function Bonus::addCategory(%this, %newCategory, %data) -{ - if (%this.numCategories $= "") - %this.numCategories = 0; - - // A category can be used in multiple bonuses - %this.category[%this.numCategories] = %newCategory; - %this.category[%this.numCategories].data = %data; - %this.numCategories++; -} - -function Bonus::evaluate(%this, %obj1, %obj2, %obj3, %obj4, %obj5) -{ - // This is added to the bonus history and eventually deleted - %newBonusData = new ScriptObject() - { - class = BonusData; - }; - MissionCleanup.add(%newBonusData); - %newBonusData.initialize(%this); - - // Construct the bonus by iterating through categories - for (%i=0; %i<%this.numCategories; %i++) - { - %newCategoryData = %this.category[%i].evaluate(%obj1, %obj2, %obj3, %obj4); - if (%newCategoryData > 0) - { - %newBonusData.addCategoryData(%newCategoryData, %i); - - // Perform audiovisual effects - %delay = %this.category[%i].soundDelay; - %this.category[%i].schedule(%delay, "performEffects", %newCategoryData, %obj2); - } - } - - // Award the bonus - if (%newBonusData.getValue() != 0) - %this.award(%newBonusData, %obj1, %obj2, %obj3); - else - %newBonusData.delete(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////// -// BonusData -// This class stores an instance of a dynamically constructed bonus. -function BonusData::initialize(%this, %bonus) -{ - %this.bonus = %bonus; - %this.time = GetSimTime(); - - %this.maxCategoryDatas = %bonus.numCategories; - for (%i=0; %i < %this.numCategoryDatas; %i++) - %this.categoryData[%i] = ""; - - %this.totalValue = 0; -} - -function BonusData::addCategoryData(%this, %newCategoryData, %index) -{ - // This little trick allows a BonusData instance to mirror its - // Bonus type...it allows a BonusData to have empty component - // slots. Empty slots are needed so that successive Bonuses "line up" - // for calculating variance. There's likely a better way to do this. - %this.categoryData[%index] = %newCategoryData; - %this.totalValue += %newCategoryData.value; -} - -function BonusData::getString(%this) -{ - %str = %this.categoryData[0].text; - - for (%i=1; %i < %this.maxCategoryDatas; %i++) - if (%this.categoryData[%i] !$= "") - %str = %str SPC %this.categoryData[%i].text; - - return %str; -} - -function BonusData::getValue(%this) -{ - return %this.totalValue; -} - -//////////////////////////////////////////////////////////////////////////////// -// Bonus history and variance -new ScriptObject(FlagBonusHistory) -{ - class = FlagBonusHistory; - superclass = BonusHistory; - bonusType = FlagBonus; - numBonuses = 0; - variance = 0; -}; - -function BonusHistory::initialize(%this) -{ - for (%i=0; %i<%this.numBonuses; %i++) - %this.bonus[%i].delete(); - - %this.numBonuses = 0; - %this.variance = 0; -} - -function BonusHistory::add(%this, %newBonus) -{ - %this.bonus[%this.numBonuses] = %newBonus; - %this.numBonuses++; - - // Calculate the new variance - return %this.calculateIncrementalVariance(); -} - - // An incremental way of calculating the creativity within a bonus -// history as new bonuses are added (incremental approach used for efficiency) -function BonusHistory::calculateIncrementalVariance(%this) -{ - if (%this.numBonuses <= 1) - return 0; - - %i = %this.numBonuses - 1; - for(%j=0; %j<%this.bonus[%i].maxCategoryDatas; %j++) - { - %categoryData = %this.bonus[%i].categoryData[%j]; - // Don't count empty component slots - if(%categoryData !$= "") - for(%k=0; %k<%categoryData.numParameters; %k++) - %this.variance += mAbs(%categoryData.parameter[%k] - - %this.bonus[%i-1].categoryData[%j].parameter[%k]); - } - - return %this.variance; -} - - -// An instantaneous way of calculating the creativity within a bonus -// history (inefficient and not intended to be used; for informational -// and debugging purposes only) -function BonusHistory::calculateVariance(%this) -{ - if (%this.numBonuses <= 1) - return 0; - - %this.variance = 0; - - for(%i=1; %i<%this.numBonuses; %i++) - for(%j=0; %j<%this.bonus[%i].maxCategoryDatas; %j++) - { - %categoryData = %this.bonus[%i].categoryData[%j]; - if (%categoryData !$= "") - for(%k=0; %k<%categoryData.numParameters; %k++) - %this.variance += abs(%categoryData.parameter[%k] - - %this.bonus[%i-1].categoryData[%j].parameter[%k]); - } - - return %this.variance; -} - -function BonusHistory::getVariance(%this) -{ - return %this.variance; -} - -function BonusHistory::getRecentRecipient(%this, %index) -{ - if (%index $= "") - %index = 0; - - return %this.bonus[%this.numBonuses-1-%index].recipient; -} - -function Bonus::award(%this, %bonusData, %player1, %player2, %action, %suffix, %extraval, %sound) -{ - // Handle instant bonuses (previously handled via subclassing) - if (%this.instant) - return %this.awardInstantBonus(%bonusData, %player1, %player2, %action, %suffix, %extraval, %sound); - - if (%bonusData !$= "") - %val = %bonusData.getValue(); - else - %val = 0; - - if (%extraval !$= "") - %val += %extraval; - - if (%val < 0) - %val = 0; - - // Send message to bonus display mechanism - if (%val > 0) - Game.updateCurrentBonusAmount(%val, %player1.team); - - if (%bonusData !$= "") - %text = %bonusData.getString(); - - if (%suffix !$= "") - %text = %text SPC %suffix; - - if (%player1.team != %player2.team) - %actionColor = ""; - else - %actionColor = ""; - - %player1Color = $TR2::teamColor[%player1.team]; - %player2Color = $TR2::teamColor[%player2.team]; - - %summary = %player1Color @ getTaggedString(%player1.client.name) - SPC %actionColor @ %action - SPC %player2Color @ getTaggedString(%player2.client.name); - - messageAll('MsgTR2Event', "", %summary, %text, %val); - - if (%this.history !$= "") - // Add to BonusHistory and calculate variance - %this.history.add(%bonusData); - else if (%bonusData !$= "") - // Otherwise just get rid of it - %bonusData.delete(); -} - -function Bonus::awardInstantBonus(%this, %bonusData, %player1, %player2, %action, %suffix, %extraVal, %sound) -{ - if (%bonusData !$= "") - %val = %bonusData.getValue(); - else - %val = 0; - - if (%extraVal !$= "") - %val += %extraVal; - - if (%val < 0) - %val = 0; - - if (%player2 !$= "") - %summary = getTaggedString(%player1.client.name) SPC %action SPC - getTaggedString(%player2.client.name); - //else if (%player1 !$= "") - // %summary = getTaggedString(%player1.client.name); - - // Send message to bonus display mechanism - %scoringTeam = %player1.client.team; - $teamScore[%scoringTeam] += %val; - messageAll('MsgTR2SetScore', "", %scoringTeam, $teamScore[%scoringTeam]); - - if (%bonusData !$= "") - %text = %bonusData.getString() SPC %suffix; - else - %text = %suffix; - - %scoringTeam = %player1.team; - %otherTeam = (%scoringTeam == 1) ? 2 : 1; - - //messageAll('MsgTR2Event', "", %summary, %text, %val); - messageTeam(%scoringTeam, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")"); - messageTeam(%otherTeam, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")"); - messageTeam(0, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")"); - - if (%sound !$= "") - serverPlay2D(%sound); - - if (%this.history !$= "") - // Add to BonusHistory and calculate variance - %this.history.add(%bonusData); - else if (%bonusData !$= "") - // Otherwise just get rid of it - %bonusData.delete(); -} - - -function FlagBonus::award(%this, %bonusData, %dropper, %grabber, %flag) -{ - // Hmm, should update this to use Parent:: - - // Calculate bonus value - %val = %bonusData.getValue(); - - // Sneaky workaround so that some bonuses still display even though - // they're worth nothing - if (%val < 0) - %val = 0; - - if (%val >= 20) - ServerPlay2D(CrowdCheerSound); - - if (!%flag.atHome && !%flag.onGoal && !%flag.dropperKilled) - { - if (%flag.dropper.team == %grabber.team) - { - %actionColor = ""; - %ppoints = mCeil(%val / 2); - %rpoints = mFloor(%val / 2); - %grabber.client.score += %rpoints; - %grabber.client.receivingScore += %rpoints; - %flag.dropper.client.score += %ppoints; - %flag.dropper.client.passingScore += %ppoints; - } else { - %actionColor = ""; - %grabber.client.score += %val; - %grabber.client.interceptingScore += %val; - %this.history.initialize(); - - // If grabber was a goalie, count this as a save - if (%grabber.client.currentRole $= Goalie) - %grabber.client.saves++; - } - - if (%flag.dropper.client !$= "") - { - %dropperColor = $TR2::teamColor[%dropper.team]; - %grabberColor = $TR2::teamColor[%grabber.team]; - %summary = %dropperColor @ getTaggedString(%dropper.client.name) - SPC %actionColor @ "to" - SPC %grabberColor @ getTaggedString(%grabber.client.name); - } - } else { - // Handle regular flag pickups - %summary = $TR2::teamColor[%grabber.team] @ getTaggedString(%grabber.client.name); - %this.history.initialize(); - } - - // Add to BonusHistory and calculate variance - %bonusData.recipient = %grabber; - %this.history.add(%bonusData); - - // Use variance to calculate creativity - %variance = %this.history.getVariance(); - CreativityBonus.evaluate(%variance, %grabber); - - // Send message to bonus display mechanism - // - Game.updateCurrentBonusAmount(%val, %grabber.team); - messageAll('MsgTR2Event', "", %summary, %bonusData.getString(), %val); -} - -function WeaponBonus::award(%this, %bonusData, %shooter, %victim) -{ - %shooter.client.fcHits++; - if (%bonusData.getValue() >= 5) - ServerPlay2D(MonsterSound); - Parent::award(%this, %bonusData, %shooter, %victim, "immobilized", "Hit \c2(" @ getTaggedString(%shooter.client.name) @ ")"); -} - -function G4Bonus::award(%this, %bonusData, %plAttacker, %plVictim, %damageType, %damageLoc, %val) -{ - Parent::award(%this, %bonusData, %plAttacker, %plVictim, "G4'd", - "Bionic Grab", %val); -} - -function CollisionBonus::award(%this, %bonusData, %plPasser, %plReceiver, %action, %desc, %val) -{ - Parent::award(%this, %bonusData, %plPasser, %plReceiver, %action, %desc, %val); -} - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Descriptions.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Descriptions.cs deleted file mode 100644 index 1b6614e5..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Descriptions.cs +++ /dev/null @@ -1,248 +0,0 @@ - -//////////////////////////////////////////////////////////////////////////////// -// Special DescriptionDatas -$DefaultDescription = new ScriptObject() { - text = "Grab"; - value = 0; - sound = "blah.wav"; - class = DescriptionData; - numParameters = 0; -}; - -$G4Description = new ScriptObject() { - text = "Go-go Gadget Grab"; - value = 5; - sound = "blah.wav"; - class = DescriptionData; - numParameters = 0; -}; - - -// DescriptionData components -// [Passer direction, pass direction, flag direction] - -$DescriptionList = new ScriptObject() { - class = DescriptionList; -}; - -function DescriptionList::get(%this, %a, %b, %c) -{ - return $DescriptionList[%a, %b, %c]; -} - -//////////////////////////////////////////////////////////////////////////////// -// Horizontal dominance (straight pass) -$DescriptionList[0,0,0] = new ScriptObject() { - text = "Bullet"; - value = 5; - sound = Description000Sound; - class = DescriptionData; -}; - - -$DescriptionList[0,0,1] = new ScriptObject() { - text = "Heist"; - value = 7; - sound = Description001Sound; - class = DescriptionData; -}; - -$DescriptionList[0,0,2] = new ScriptObject() { - text = "Smack Shot"; - value = 9; - sound = Description002Sound; - class = DescriptionData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Horizontal dominance (pass back) -$DescriptionList[0,1,0] = new ScriptObject() { - text = "Jab"; - value = 9; - sound = Description010Sound; - class = DescriptionData; -}; - - -$DescriptionList[0,1,1] = new ScriptObject() { - text = "Back Breaker"; - value = 11; - sound = Description011Sound; - class = DescriptionData; -}; - - -$DescriptionList[0,1,2] = new ScriptObject() { - text = "Leet Lob"; - value = 12; - sound = Description012Sound; - class = DescriptionData; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Horizontal dominance (perpendicular pass) -$DescriptionList[0,2,0] = new ScriptObject() { - text = "Peeler"; - value = 22; - sound = Description020Sound; - class = DescriptionData; -}; - -$DescriptionList[0,2,1] = new ScriptObject() { - text = "Blender"; - value = 25; - sound = Description021Sound; - class = DescriptionData; -}; - -$DescriptionList[0,2,2] = new ScriptObject() { - text = "Glass Smash"; - value = 28; - sound = Description022Sound; - class = DescriptionData; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Upward dominance (straight pass) -$DescriptionList[1,0,0] = new ScriptObject() { - text = "Ascension"; - value = 7; - sound = Description100Sound; - class = DescriptionData; -}; - -$DescriptionList[1,0,1] = new ScriptObject() { - text = "Elevator"; - value = 9; - sound = Description101Sound; - class = DescriptionData; -}; - - -$DescriptionList[1,0,2] = new ScriptObject() { - text = "Rainbow"; - value = 7; - sound = Description102Sound; - class = DescriptionData; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Upward dominance (pass back) -$DescriptionList[1,1,0] = new ScriptObject() { - text = "Bomb"; - value = 9; - sound = Description110Sound; - class = DescriptionData; -}; - -$DescriptionList[1,1,1] = new ScriptObject() { - text = "Deliverance"; - value = 11; - sound = Description111Sound; - class = DescriptionData; -}; - -$DescriptionList[1,1,2] = new ScriptObject() { - text = "Crank"; - value = 12; - sound = Description112Sound; - class = DescriptionData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Upward dominance (pass perpendicular) -$DescriptionList[1,2,0] = new ScriptObject() { - text = "Fling"; - value = 18; - sound = Description120Sound; - class = DescriptionData; -}; - -$DescriptionList[1,2,1] = new ScriptObject() { - text = "Quark"; - value = 20; - sound = Description121Sound; - class = DescriptionData; -}; - -$DescriptionList[1,2,2] = new ScriptObject() { - text = "Juggle Toss"; - value = 22; - sound = Description122Sound; - class = DescriptionData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Downward dominance (straight pass) -$DescriptionList[2,0,0] = new ScriptObject() { - text = "Yo-yo"; - value = 7; - sound = Description200Sound; - class = DescriptionData; -}; - -$DescriptionList[2,0,1] = new ScriptObject() { - text = "Skydive"; - value = 9; - sound = Description201Sound; - class = DescriptionData; -}; - - -$DescriptionList[2,0,2] = new ScriptObject() { - text = "Jolt"; - value = 11; - sound = Description202Sound; - class = DescriptionData; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Downward dominance (pass back) -$DescriptionList[2,1,0] = new ScriptObject() { - text = "Prayer"; - value = 10; - sound = Description210Sound; - class = DescriptionData; -}; - -$DescriptionList[2,1,1] = new ScriptObject() { - text = "Mo-yo-yo"; - value = 12; - sound = Description211Sound; - class = DescriptionData; -}; - -$DescriptionList[2,1,2] = new ScriptObject() { - text = "Rocket"; - value = 14; - sound = Description212Sound; - class = DescriptionData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Downward dominance (pass perpendicular) -$DescriptionList[2,2,0] = new ScriptObject() { - text = "Blast"; - value = 20; - sound = Description220Sound; - class = DescriptionData; -}; - -$DescriptionList[2,2,1] = new ScriptObject() { - text = "Deep Dish"; - value = 23; - sound = Description221Sound; - class = DescriptionData; -}; - -$DescriptionList[2,2,2] = new ScriptObject() { - text = "Bunny Bump"; - value = 25; - sound = Description222Sound; - class = DescriptionData; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Game.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Game.cs deleted file mode 100644 index 42c066e4..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Game.cs +++ /dev/null @@ -1,3204 +0,0 @@ -// DisplayName = Team Rabbit 2 - -//--- GAME RULES BEGIN --- -//Get the flag and throw it into the other team's goal -//You can only hold onto the flag for 15 seconds -//Passing the flag increases the size of the Jackpot -//Scoring a goal awards the Jackpot to your team! -//When your health reaches zero, you are knocked down -//Replenish your ammo by pressing your suicide button -//--- GAME RULES END --- - - - -// Team Rabbit 2 -// Created by Codality, Inc. -// www.codality.com -// ------------------------------- -// Michael "KineticPoet" Johnston - Designer, Lead Programmer, Maps -// Dan "daunt" Kolta - Physics design, Maps -// Scott "FSB-AO" Estabrook - Programmer -// John "CObbler" Carter - Bonus sound effects -// Buddy "sLaM" Pritchard - Sound effects -// Gregg "illy" Fellows - 3D models and skins -// Alan "Nefilim" Schwertel; - Maps -// Kenneth "SONOFMAN" Cook - Sky art - - -exec("scripts/TR2Packages.cs"); -exec("scripts/TR2Particles.cs"); -exec("scripts/TR2Physics.cs"); -exec("scripts/TR2Items.cs"); -exec("scripts/TR2Bonuses.cs"); -exec("scripts/TR2ObserverQueue.cs"); -exec("scripts/TR2Roles.cs"); - -$TR2::ThrownObject = "TR2Flag.dts"; -//$TR2::ThrownObject = "bioderm_light.dts"; // Derm tossing -//$TR2::ThrownObject = "TR2ball.dts"; // Ball - -$TR2::DisableDeath = true; -$TR2::EnableRoles = true; -$TR2::EnableCrowd = true; -$TR2::DelayAfterKnockdown = 1800; -$TR2::MinimumKnockdownDelay = 2300; -$TR2::MaximumKnockdownDelay = 7000; -$TR2::MinSpeedForFlagSmoke = 9; -$TR2::HotPotatoTime = 14000; -$TR2::selfPassTimeout = 6500; -$TR2::CrazyFlagLifetime = 15000; -$TR2::FlagUpdateTime = 70; -$TR2::PracticeMode = false; -$TR2::GoalRespawnDelay = 4; -$TR2::TimeSlice = 2000; -$TR2::PointsPerTimeSlice = 1; -$TR2::MinimumJackpot = 40; -$TR2::MaximumJackpot = 250; -$TR2::dynamicUpdateFrequency = 1000; -$TR2::GoalieInvincibilityTime = 5000; -$TR2::FriendlyKnockdownPenalty = 15; -$TR2::MaxFlagChargeTime = 3000; -$TR2::KnockdownTimeSlice = 500; -$TR2::FlagSmokeTimeSlice = 200; -$TR2::datablockRoleChangeDelay = 400; -$TR2::DelayBetweenTeamChanges = 1000; -$TR2::OneTimerGoalBonus = 50; -$TR2::CorpseTimeoutValue = 2000; - -$TR2::ObsZoomScale[0] = 1; -$TR2::ObsZoomScale[1] = 2; -$TR2::ObsZoomScale[2] = 4; -$TR2::ObsZoomScale[3] = 6; -$TR2::NumObsZoomLevels = 4; - -$TR2::CrowdLevelDistance[0] = 800; -$TR2::CrowdLevelDistance[1] = 400; -$TR2::CrowdLevelDistance[2] = 210; - -$DamageType::TouchedOwnGoal = 200; -$DamageType::Grid = 201; -$DamageType::RespawnAfterScoring = 202; -$DamageType::HotPotato = 203; -$DamageType::OOB = 204; - -$InvincibleTime = 3; -$TR2::validatingQueue = true; - -$TR2::JoinMotd = "Team Rabbit 2 (build 095)\n" @ - "Created by Codality, Inc.\nhttp://www.codality.com"; - - -function TR2Game::sendMotd(%game, %client) -{ - bottomPrint(%client, $TR2::JoinMotd, 5, 3); - %client.sentTR2Motd = true; -} - -function TR2Game::spawnPlayer( %game, %client, %respawn ) -{ - if( !isObject(%client) || %client.team <= 0 ) - return 0; - - %client.lastSpawnPoint = %game.pickPlayerSpawn( %client, false ); - %client.suicidePickRespawnTime = getSimTime() + 20000; - %game.createPlayer( %client, %client.lastSpawnPoint, %respawn ); - - if(!$MatchStarted && !$CountdownStarted) // server has not started anything yet - { - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - %client.setControlObject( %client.camera ); - if( $Host::TournamentMode ) - { - %client.observerMode = "pregame"; - %client.notReady = true; - centerprint( %client, "\nPress FIRE when ready.", 0, 3 ); - checkTourneyMatchStart(); - } - %client.camera.mode = "pre-game"; - //schedule(1000, 0, "commandToClient", %client, 'setHudMode', 'Observer'); - schedule(1000, 0, "commandToClient", %client, 'displayHuds'); - } - else if(!$MatchStarted && $CountdownStarted) // server has started the countdown - { - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - %client.setControlObject( %client.camera ); - if( $Host::TournamentMode ) - { - %client.observerMode = "pregame"; - } - %client.camera.mode = "pre-game"; - //schedule(1000, 0, "commandToClient", %client, 'setHudMode', 'Observer'); - schedule(1000, 0, "commandToClient", %client, 'displayHuds'); - } - else - { - %client.camera.setFlyMode(); - %client.setControlObject( %client.player ); - commandToClient(%client, 'setHudMode', 'Standard'); // the game has already started - } -} - - -function TR2Game::initGameVars(%game) -{ - if (%game.oldCorpseTimeout $= "") - %game.oldCorpseTimeout = $CorpseTimeoutValue; - - $CorpseTimeoutValue = $TR2::CorpseTimeoutValue; - %game.TR2FlagSmoke = 0; - %game.addFlagTrail = ""; - %game.currentBonus = 0; - %game.updateCurrentBonusAmount(0, -1); - - %game.FLAG_RETURN_DELAY = 12 * 1000; //12 seconds - %game.fadeTimeMS = 2000; - %game.crowdLevel = -1; - %game.crowdLevelSlot = 0; - - %game.resetPlayerRoles(); -} - -function TR2Game::onClientLeaveGame(%game, %client) -{ - //remove them from the team rank arrays - %game.removeFromTeamRankArray(%client); - // First set to outer role (just to be safe) - %game.assignOuterMostRole(%client); - - // Then release client's role - %game.releaseRole(%client); - - if( isObject(%client.player)) - %client.player.scriptKill(0); - - if( %client.team > 0 ) // hes on a team... - { - %nextCl = getClientFromQueue(); - if( %nextCl != -1 ) - { - %game.assignClientTeam(%nextCl); - %game.spawnPlayer(%nextCl); - } - } - // just in case... - removeFromQueue(%client); - - //cancel a scheduled call... - cancel(%client.respawnTimer); - %client.respawnTimer = ""; - - logEcho(%client.nameBase@" (cl "@%client@") dropped"); -} - - // END package TR2Game - -//-------------------------------------------------------------------------- -// 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 TR2Game::AIInit() -{ -} - -function TR2Game::getTeamSkin(%game, %team) -{ - // TR2 experiment - switch (%team) - { - case 1: return 'TR2-1'; - case 2: return 'TR2-2'; - } - - if(isDemo() || $host::tournamentMode) - { - return $teamSkin[%team]; - } - - else - { - //error("TR2Game::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 TR2Game::getTeamName(%game, %team) -{ - if ( isDemo() || $host::tournamentMode) - return $TeamName[%team]; - - //error("TR2Game::getTeamName"); - if(!$host::useCustomSkins) - { - %terrain = MissionGroup.musicTrack; - //error("Terrain type is: " SPC %terrain); - 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 $= "") - { - //error("No team Name ============================="); - %name = $teamName[%team]; - } - } - else - %name = $TeamName[%team]; - - //error("%name = " SPC getTaggedString(%name)); - return %name; -} - -//-------------------------------------------------------------------------- -function TR2Game::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; - $teamScoreJackpot[%i] = 0; - $teamScoreCreativity[%i] = 0; - $teamScorePossession[%i] = 0; - } - - // AO: if there are more players on a team than open TR2 spots, we just switched from another game mode - // first 12 in the clientgroup get to play, rest spec. - %count = ClientGroup.getCount(); - %playing = 0; - for( %i = 0; %i < %count; %i++ ) - { - %cl = ClientGroup.getObject(%i); - if( %cl.team > 0 ) - %playing++; - } - - if( %playing > 12 ) - { - %idx = 0; - for( %j = 0; %j < %count; %j++ ) - { - %cl = ClientGroup.getObject(%i); - if( %idx < 12 ) - { - if( %cl.team != 0 ) - %idx++; - else - addToQueue(%cl); - } - else - { - if( %cl.team != 0 ) - %game.forceObserver(%cl, "teamsMaxed"); - else - addToQueue(%cl); - } - } - } - - - // KP: Reset accumulated score - $accumulatedScore = 0; - - // remove - MissionGroup.clearFlagWaypoints(); - - //reset some globals, just in case... - $dontScoreTimer[1] = false; - $dontScoreTimer[2] = false; - - // KP: Over-ride the sensor settings to remove alpha transparency - // 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 -1"); - setSensorGroupColor(%i, ~%team, "255 0 0 -1"); - setSensorGroupColor(%i, 1, "255 255 255 -1"); - - // setup the team targets (alwyas friendly and visible to same team) - setTargetAlwaysVisMask(%i, %team); - setTargetFriendlyMask(%i, %team); - } - setSensorGroupAlwaysVisMask(1, 0xffffffff); - setSensorGroupFriendlyMask(1, 0xffffffff); - setSensorGroupAlwaysVisMask(2, 0xffffffff); - setSensorGroupFriendlyMask(2, 0xffffffff); - - // Init TR2 bonuses - initializeBonuses(); - - // Set gravity - setGravity($TR2::Gravity); - - // Locate goals - - for (%i=1; %i<=2; %i++) - { - %group = nameToID("MissionGroup/Teams/team" @ %i @ "/Goal" @ %i); - %count = %group.getCount(); - - for (%j=0; %j<%count; %j++) - { - %obj = %group.getObject(%j); - if (%obj.dataBlock $= "Goal") - { - $teamGoal[%i] = %obj; - $teamGoalPosition[%i] = $teamGoal[%i].getPosition(); - break; - } - } - } - - %sphereGroup = nameToID("MissionGroup/Sphere"); - %count = %sphereGroup.getCount(); - - for (%j=0; %j<%count; %j++) - { - %obj = %sphereGroup.getObject(%j); - if (%obj.interiorFile $= "sphere.dif") - { - $TR2::TheSphere = %obj; - break; - } - } - - // Make sure everyone's spawnBuilding flag is set - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl $= "" || %cl.player $= "") - continue; - - %cl.inSpawnBuilding = true; - } - - %bounds = MissionArea.area; - %boundsWest = firstWord(%bounds); - %boundsNorth = getWord(%bounds, 1); - // Hack to get a permanent dynamic object for playAudio() - //$AudioObject = new Player() - //{ - // datablock = TR2LightMaleHumanArmor; - //}; - - // Game threads - %game.dynamicUpdateThread = %game.schedule(0, "dynamicUpdate"); -} - -function TR2Game::startMatch(%game) -{ - //serverPlay2D(GameStartSound); - return Parent::startMatch(%game); -} - -function TR2Game::dynamicUpdate(%game) -{ - //echo("DYNAMIC: Start update"); - // Keep checking for flag and flag carrier oob because T2's enter/leave - // mission callbacks aren't reliable - //%game.keepFlagInBounds(true); - - // Only start the flag return timer if the flag is moving slowly - if ($TheFlag.getSpeed() < 8 && $TheFlag.carrier $= "") - { - if (($FlagReturnTimer[$TheFlag] $= "" || $FlagReturnTimer[$TheFlag] <= 0) && !$TheFlag.onGoal && !$TheFlag.isHome) - $FlagReturnTimer[$TheFlag] = Game.schedule(Game.FLAG_RETURN_DELAY - Game.fadeTimeMS, "flagReturnFade", $TheFlag); - } - - // Little trick to alternate between queue validation and role validation with - // each dynamic update tick - if ($TR2::validatingQueue) - validateQueue(); - else - %game.validateRoles(); - - $TR2::validatingQueue = !$TR2::validatingQueue; - - if ($TR2::enableRoles) - %game.updateRoles(); - - if ($TR2::EnableCrowd) - %game.evaluateCrowdLevel(); - - %game.dynamicUpdateThread = %game.schedule($TR2::dynamicUpdateFrequency, "dynamicUpdate"); - //echo("DYNAMIC: End update"); -} - -function TR2Game::keepFlagInBounds(%game, %firstTime) -{ - if (%firstTime && ($TheFlag.isOutOfBounds() || $TheFlag.carrier.OutOfBounds)) - // Double-check, just in case we caught a gridjump - %game.oobCheckThread = %game.schedule(500, "keepFlagInBounds", false); - else - { - cancel(%game.oobCheckThread); - if ($TheFlag.carrier.OutOfBounds) - $TheFlag.carrier.scriptKill($DamageType::suicide); - - if ($TheFlag.isOutOfBounds()) - { - cancel($FlagReturnTimer[$TheFlag]); - %game.flagReturn($TheFlag); - } - } -} - -function TR2Game::endMission(%game) -{ - if ($DefaultGravity !$= "") - setGravity($DefaultGravity); - - $CorpseTimeoutValue = %game.oldCorpseTimeout; - - cancel(%game.roleUpdateThread); - - // Try setting everyone's inSpawnBuilding flag to avoid weird death messages - // between missions - //%count = ClientGroup.getCount(); - //for (%i = 0; %i < %count; %i++) - //{ - // %cl = ClientGroup.getObject(%i); - // if (%cl $= "" || %cl.player $= "") - // continue; - - // %cl.inSpawnBuilding = true; - //} - %game.forceTeamRespawn(1); - %game.forceTeamRespawn(2); - - // End dynamic updates - cancel(%game.dynamicUpdateThread); - cancel(%game.addFlagTrail); - cancel(%game.pointsPerTimeSliceThread); - cancel(%game.roleValidationThread); - - %game.stopCrowd(); - - Parent::endMission(%game); -} - -function TR2Game::playerTouchFlag(%game, %player, %flag) -{ - //echo("playerTouchFlag() (client = " @ %player.client @ ")"); - %client = %player.client; - - if (%player.getState() $= "Dead") - return; - - %grabTime = getSimTime(); - %flagVel = %flag.getVelocity(); - %flagSpeed = %flag.getSpeed(); - - if (Game.goalJustScored || %client.OutOfBounds) - return; - - if (%flag.isOutOfBounds() || %player.inSpawnBuilding) - { - Game.flagReturn(%flag); - return; - } - - // TR2: Try to fix the infamous flag re-catch bug - //if (%player == %flag.dropper && %grabTime - %flag.dropTime <= 200) - //{ - // echo(" RE-CATCH BUG DETECTED!"); - //%flag.setVelocity(%flag.throwVelocity); - //return; - //} - - // TR2: don't allow players to re-grab - if (!$TR2::PracticeMode) - if (%player == %flag.dropper && (%grabTime - %flag.dropTime) <= $TR2::selfPassTimeout) // && %flag.oneTimer == 0) - { - messageClient(%client, 'MsgTR2SelfPass', '\c1You can\'t pass to yourself!'); - return; - } - - - if (%flag.carrier $= "") - { - // TR2: Check for one-timer catches, hee - //if (getSimTime() - %flag.oneTimer < 1500 && %flagSpeed > 3) - //{ - // %newVel = VectorAdd(%player.getVelocity(), VectorScale(%flagVel, 10)); - // %player.setVelocity(%newVel); - // echo(" ONE-TIMER ====== " @ %flagVel); - //} - - - // TR2: Temporary invulnerability for goalies - if (%player.client.currentRole $= Goalie) - { - %player.setInvincible(true); - %player.schedule($TR2::GoalieInvincibilityTime, "setInvincible", false); - } - - - // Carrier health update - cancel(%game.updateCarrierHealth); - game.UpdateCarrierHealth(%player); - - %chasingTeam = (%player.client.team == 1) ? 2 : 1; - - %client = %player.client; - %player.holdingFlag = %flag; //%player has this flag - %flag.carrier = %player; //this %flag is carried by %player - - %player.mountImage(TR2FlagImage, $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] = ""; - } - - %flag.hide(true); - %flag.startFade(0, 0, false); - %flag.isHome = false; - %flag.onGoal = false; - %flag.dropperKilled = false; - //if(%flag.stand) - // %flag.stand.getDataBlock().onFlagTaken(%flag.stand);//animate, if exterior stand - - $flagStatus[%flag.team] = %client.nameBase; - %teamName = %game.getTeamName(%flag.team); - setTargetSensorGroup(%flag.target, %player.team); - //~wfx/misc/flag_snatch.wav - //~wfx/misc/flag_taken.wav - if (!%player.flagThrowStart) - { - messageTeamExcept(%client, 'MsgTR2FlagTaken', '\c2Teammate %1 took the flag.~wfx/misc/Flagfriend.wav', %client.name, %teamName, %flag.team, %client.nameBase); - messageTeam(%chasingTeam, 'MsgTR2FlagTaken', '\c2%1 took the flag!~wfx/misc/Flagenemy.wav',%client.name, 0, %flag.team, %client.nameBase); - messageClient(%client, 'MsgTR2FlagTaken', '\c2You took the flag.~wfx/misc/Flagself.wav', %client.name, %teamName, %flag.team, %client.nameBase); - - if (%flag.dropper $= "") - messageTeam(0, 'MsgTR2FlagTaken', '\c4%1 took the flag.~wfx/misc/Flagself.wav', %client.name, %teamName, %flag.team, %client.nameBase); - else if (%flag.dropper.team != %player.team) - messageTeam(0, 'MsgTR2FlagTaken', '\c2%1 intercepted the flag!~wfx/misc/Flagenemy.wav', %client.name, %teamName, %flag.team, %client.nameBase); - else - messageTeam(0, 'MsgTR2FlagTaken', '\c3%1 caught the flag.~wfx/misc/Flagfriend.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); - - // TR2: Schedule new hot potato - if (%game.hotPotatoThread !$= "") - cancel(%game.hotPotatoThread); - if (!$TR2::PracticeMode) - { - %game.hotPotatoThread = %game.schedule($TR2::hotPotatoTime, "hotPotato", %player, true); - - // Schedule points-per-second - %game.pointsPerTimeSliceThread = %game.schedule($TR2::timeSlice, "awardPointsPerTimeSlice"); - } - - //%flag.oneTimer = 0; - - // Set observers to flag carrier - for( %i = 0; %i " @ VectorLen(%vel)); - - // Try updating its transform to force a client update - $TheFlag.setTransform($TheFlag.getTransform()); - $updateFlagThread = %game.schedule($TR2::FlagUpdateTime, "updateFlagTransform"); -} - -function TR2Game::playerDroppedFlag(%game, %player) -{ - //echo("playerDroppedFlag() (client = " @ %player.client @ ")"); - %client = %player.client; - %flag = %player.holdingFlag; - - // Cancel points per time slice - cancel(%game.pointsPerTimeSliceThread); - - %game.playerLostFlagTarget(%player); - - %player.holdingFlag = ""; //player isn't holding a flag anymore - %flag.carrier = ""; //flag isn't held anymore - $flagStatus[%flag.team] = ""; - setTargetSensorGroup(%flag.target, 3); - - // Carrier health update - cancel(%game.updateCarrierHealthThread); - messageAll('MsgTR2CarrierHealth', "", 0); - - %player.unMountImage($FlagSlot); - %flag.hide(false); //Does the throwItem function handle this? - - // TR2: Give the flag some extra oomph - //%flagVel = %flag.getVelocity(); - //%playerVel = %player.getVelocity(); - //%playerRot = %player.getEyeVector(); - //%playerVelxy = setWord(%playerVel, 2, 0); - //%playerVelxz = setWord(%playerVel, 1, 0); - //%playerVelyz = setWord(%playerVel, 0, 0); - //%playerRotxy = setWord(%playerRot, 2, 0); - //%playerRotxz = setWord(%playerRot, 1, 0); - //%playerRotyz = setWord(%playerRot, 0, 0); - //%dotxy = VectorDot(VectorNormalize(%playerVelxy), VectorNormalize(%playerRotxy)); - //%dotxz = VectorDot(VectorNormalize(%playerVelxz), VectorNormalize(%playerRotxz)); - //%dotyz = VectorDot(VectorNormalize(%playerVelyz), VectorNormalize(%playerRotyz)); - //echo(" *********VEL dot ROT (xy) = " @ %dotxy); - //echo(" *********VEL dot ROT (xz) = " @ %dotxz); - //echo(" *********VEL dot ROT (yz) = " @ %dotyz); - //%testDirection = VectorDot(VectorNormalize(%playerVel), VectorNormalize(%playerRot)); - //%playerVel = VectorScale(%playerVel, 80); - //%playerRot = VectorScale(%playerRot, 975); - //%flag.setTransform(VectorAdd(VectorNormalize(%playerRot), %player.getPosition())); - - //%newVel = VectorAdd(%newVel, %playerRot); - - // Don't apply the velocity impulse if the player is facing one direction - // but travelling in the other - //if (%testDirection > -0.85) - // %newVel = VectorAdd(%playerVel, %newVel); - - // apply the impulse to the flag object - //%flag.applyImpulse(%flag.getPosition(), %newVel); - //%player.getWorldBoxCenter() - %flag.dropper = %player; - %flag.dropperVelocity = %player.getVelocity(); - %flag.dropperOrientation = %player.getEyeVector(); - %flag.dropperHeight = %player.getHeight(); - %flag.dropperPosition = %player.getPosition(); - %flag.dropTime = getSimTime(); - - // Argh, remember actual name to prevent self-pass exploit - %flag.dropperName = %player.client.name; - - //%flag.setCollisionTimeout(%player); - - %teamName = %game.getTeamName(%flag.team); - %chasingTeam = (%player.client.team == 1) ? 2 : 1; - //~wfx/misc/flag_drop.wav - messageTeamExcept(%client, 'MsgTR2FlagDropped', '\c2Teammate %1 dropped the flag.~wfx/misc/flagflap.wav', %client.name, %teamName, %flag.team); - messageTeam(%chasingTeam, 'MsgTR2FlagDropped', '\c2The flag has been dropped by %1!~wfx/misc/flagflap.wav', %client.name, 0, %flag.team); - messageTeam(0, 'MsgTR2FlagDropped', '\c2%1 dropped the flag.~wfx/misc/flagflap.wav', %client.name, %teamName, %flag.team); - if(!%player.client.outOfBounds) - messageClient(%client, 'MsgTR2FlagDropped', '\c2You dropped the flag.~wfx/misc/flagflap.wav', 0, %teamName, %flag.team); - logEcho(%client.nameBase@" (pl "@%player@"/cl "@%client@") dropped team "@%flag.team@" flag"); - - // TR2: Cancel hot potato thread - cancel(%game.hotPotatoThread); - - - //if( %flag.getSpeed() <= $TR2::MinSpeedForFlagSmoke && $FlagReturnTimer[%flag] <= 0) - // $FlagReturnTimer[%flag] = %game.schedule(%game.FLAG_RETURN_DELAY - %game.fadeTimeMS, "flagReturnFade", %flag); - - - // Set observers - for( %i = 0; %i $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.~wfx/misc/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; - - $accumulatedScore = 0; -} - -function TR2Game::onClientDamaged(%game, %clVictim, %clAttacker, %damageType, %implement, %damageLoc) -{ - if (%game.goalJustScored) - return; - - //if(%clVictim.headshot && %damageType == $DamageType::Laser && %clVictim.team != %clAttacker.team) - //{ - - //} - - // Try to give a free self-inflicted wound when invincible - if (%clVictim.player.invincible && %clVictim == %clAttacker) - { - %clVictim.player.invincible = false; - return; - } - - //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; - } - - if (!%clVictim.player.invincible) - G4Bonus.evaluate(%clAttacker.player, %clVictim.player, $TheFlag, %damageType, %damageLoc); - //$DamageBonus.evaluate(%clAttacker, %clVictim, %damageType, %damageLoc); - -} - -//////////////////////////////////////////////////////////////////////////////////////// -//function TR2Game::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 TR2Game::updateCurrentBonusAmount(%this, %bonus, %team) -{ - %this.currentBonus += %bonus; - if (%this.currentBonus > $TR2::MaximumJackpot) - %this.currentBonus = $TR2::MaximumJackpot; - - // Don't color the Jackpot until it's big enough - if (%this.currentBonus < $TR2::MinimumJackpot) - %team = -1; - - %this.setBonus(%this.currentBonus, %team); - //for( %i = 0; %i < ClientGroup.getCount(); %i++ ) - //{ - // %cl = ClientGroup.getObject(%i); - // %flag = %cl.team == %team ? 1 : 0; - // messageClient(%cl, 'MsgTR2UpdateBonus', "", %this.currentBonus, %flag); - //} -} - -function TR2Game::setBonus(%game, %bonus, %team) -{ - if( %bonus $= "0" || %team == -1 ) - messageAll('MsgTR2Bonus', "", %bonus, $TR2::NeutralColor); - else - { - messageAllExcept(-1, %team, 'MsgTR2Bonus', "", %bonus, $TR2::RedColor); - messageTeam(%team, 'MsgTR2Bonus', "", %bonus, $TR2::GreenColor); - } -} - -function TR2Game::giveInstantBonus(%this, %team, %amount) -{ - $teamScore[%team] += %amount; - messageAll('MsgTR2SetScore', "", %team, $teamScore[%team]); -} - -function TR2Game::recalcScore(%game, %cl) -{ - -} - -function TR2Game::updateKillScores(%game, %clVictim, %clKiller, %damageType, %implement) -{ - -} - - -function TR2Game::testCarrierKill(%game, %victimID, %killerID) -{ - %flag = %victimID.plyrDiedHoldingFlag; - return ((%flag !$= "") && (%flag.team == %killerID.team)); -} - - - -function TR2Game::resetDontScoreTimer(%game, %team) -{ - $dontScoreTimer[%team] = false; -} - -function TR2Game::checkScoreLimit(%game, %team) -{ - -} - -function TR2Game::clientMissionDropReady(%game, %client) -{ - // TR2 specific anti-non-vchat-wav-spam-thing... - if( getTaggedString(%client.voiceTag) $= "" ) - { - removeTaggedString(%client.voiceTag); - - %raceGender = %client.race SPC %client.sex; - switch$ ( %raceGender ) - { - case "Human Male": - %voice = "Male1"; - case "Human Female": - %voice = "Fem1"; - case "Bioderm": - %voice = "Derm1"; - default: - %voice = "Male1"; - } - %client.voiceTag = addTaggedString(%voice); - } - - %game.sendMotd(%client); - //error(%client @ " - " @ %client.nameBase @ " - Team: " @ %client.team @ " - Last: " @ %client.lastTeam); - if( %client.team <= 0 || %client.team $= "" ) - addToQueue(%client); - if( %client.tr2SpecMode $= "" ) - %client.tr2SpecMode = true; - if( %client.specOnly $= "" ) - %client.specOnly = false; - messageClient(%client, 'MsgClientReady',"", %game.class); - %game.resetScore(%client); - - %score1 = $Teams[1].score != 0 ? $Teams[1].score : 0; - %score2 = $Teams[2].score != 0 ? $Teams[2].score : 0; - - if( $TheFlag.isHome ) - { - %flagLoc = "Center"; - %carrierHealth = 0; - } - else if( $TheFlag.onGoal ) - { - %flagLoc = "On goal"; - %carrierHealth = 0; - } - else if( $TheFlag.carrier !$= "" ) - { - %flagLoc = $TheFlag.carrier.client.name; - %maxDamage = $TheFlag.carrier.getDatablock().maxDamage; - %health = ((%maxDamage - $TheFlag.carrier.getDamageLevel()) / %maxDamage) * 200; - %carrierHealth = mFloor(%health/10) * 5; - } - else - { - %flagLoc = "Dropped"; - %carrierHealth = 0; - } - - - %client.inSpawnBuilding = true; - - messageClient(%client, 'MsgTR2ObjInit', "", %game.getTeamName(1), %game.getTeamName(2), %score1, %score2, %flagLoc, %carrierHealth, %game.currentBonus ); - messageClient(%client, 'MsgMissionDropInfo', '\c0You are in mission %1 (%2).', $MissionDisplayName, $MissionTypeDisplayName, $ServerName ); - - //synchronize the clock HUD - messageClient(%client, 'MsgSystemClock', "", 0, 0); - - %game.sendClientTeamList( %client ); - %game.setupClientHuds( %client ); - - %client.camera.setFlyMode(); - - %observer = false; - if( !$Host::TournamentMode ) - { - if( %client.camera.mode $= "observerFly" || %client.camera.mode $= "justJoined" || - %client.camera.mode $= "followFlag" || %client.camera.mode $= "observerFollow" ) - { - %observer = true; - %client.observerStartTime = getSimTime(); - commandToClient(%client, 'setHudMode', 'Observer'); - %client.setControlObject( %client.camera ); - } - - if( (%client.team <= 0 || %client.team $= "") && getActiveCount() < (6 * 2) ) - { - %observer = false; - %game.assignClientTeam(%client, 0); - %game.spawnPlayer(%client, 0); - } - - if( %observer ) - { - if( %client.tr2SpecMode == 1 ) - { - if( $TheFlag.carrier $= "" ) - Game.observeObject(%client, $TheFlag, 2); - else - Game.observeObject(%client, $TheFlag.carrier.client, 1); - } - else - %client.camera.getDataBlock().setMode( %client.camera, "ObserverFly" ); - } - } - else - { - // set all players into obs mode. setting the control object will handle further procedures... - if( %client.tr2SpecMode == 1 ) - { - if( $TheFlag.carrier $= "" ) - Game.observeObject(%client, $TheFlag, 2); - else - Game.observeObject(%client, $TheFlag.carrier.client, 1); - } - else - %client.camera.getDataBlock().setMode( %client.camera, "ObserverFly" ); - %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 && %client.lastTeam != 0 && %client.lastTeam !$= "" ) - 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("TR2: Client" SPC %client SPC "is ready."); - - if ( isDemo() ) - { - if ( %client.demoJustJoined ) - { - %client.demoJustJoined = false; - centerPrint( %client, "Welcome to the Tribes 2 Demo." NL "You have been assigned the name \"" @ %client.nameBase @ "\"." NL "Press FIRE to join the game.", 0, 3 ); - } - } -} -function TR2Game::resetScore(%game, %client) -{ - %client.kills = 0; - %client.deaths = 0; - %client.suicides = 0; - %client.score = 0; - %client.midairDiscs = 0; - %client.kidneyThiefSteals = 0; - %client.goals = 0; - %client.assists = 0; - %client.saves = 0; - %client.hareHelpers = 0; - %client.receivingScore = 0; - %client.passingScore = 0; - %client.interceptingScore = 0; - %client.fcHits = 0; - - // Set outermost role - %game.assignOutermostRole(%client); - - for (%i=o; %i<$TR2::numRoles; %i++) - { - %role = $TR2::role[%i]; - %client.roleChangeTicks[%role] = 0; - } - // etc... -} - -function TR2Game::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; - - %client = %player.client; - %flag = %player.holdingFlag; - %flag.setVelocity("0 0 0"); - %flag.setTransform(%player.getWorldBoxCenter()); - %flag.setCollisionTimeout(%player); - - %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"); - - // apply the impulse to the flag object - %flag.applyImpulse(%player.getWorldBoxCenter(), %vec); - - //don't forget to send the message - messageClient(%player.client, 'MsgTR2FlagDropped', '\c1You have left the mission area and lost the flag.~wfx/misc/flag_drop.wav', 0, 0, %player.holdingFlag.team); - logEcho(%player.client.nameBase@" (pl "@%player@"/cl "@%player.client@") lost flag (out of bounds)"); -} - -function TR2Game::dropFlag(%game, %player) -{ - if(%player.holdingFlag > 0) - { - if (!%player.client.outOfBounds) - %player.throwObject(%player.holdingFlag); - else - %game.boundaryLoseFlag(%player); - } -} - -function TR2Game::applyConcussion(%game, %player) -{ - %game.dropFlag( %player ); -} - - -function TR2Game::testKill(%game, %victimID, %killerID) -{ - return ((%killerID !=0) && (%victimID.team != %killerID.team)); -} - -function TR2Game::equip(%game, %player) -{ - %cl = %player.client; - for(%i =0; %i<$InventoryHudCount; %i++) - %cl.setInventoryHudItem($InventoryHudData[%i, itemDataName], 0, 1); - %cl.clearBackpackIcon(); - - //%player.setArmor("Light"); - %player.setInventory(RepairKit,1); - %player.setInventory(TR2Disc,1); - %player.setInventory(TR2GrenadeLauncher,1); - %player.setInventory(TR2Chaingun, 1); - %player.weaponCount = 3; - - if (%cl.restockAmmo) - { - %player.setInventory(TR2ChaingunAmmo, 100); - %player.setInventory(TR2DiscAmmo, 15); - %player.setInventory(TR2GrenadeLauncherAmmo, 10); - %player.setInventory(Beacon, 3); - %player.setInventory(TR2Grenade,5); - } - else - %game.restockRememberedAmmo(%cl); - - %player.setInventory(TR2EnergyPack, 1); - - %targetingLaser = (%player.team == 1) ? TR2GoldTargetingLaser : TR2SilverTargetingLaser; - %player.setInventory(%targetingLaser, 1); - - %player.use("TR2Disc"); -} - -function TR2Game::playerSpawned(%game, %player) -{ - if( %player.client.respawnTimer) - cancel(%player.client.respawnTimer); - - %player.client.observerStartTime = ""; - %game.equip(%player); - - %player.client.spawnTime = getSimTime(); -} - -function TR2Game::rememberAmmo(%game, %client) -{ - %pl = %client.player; - %client.lastChaingunAmmo = %pl.invTR2ChaingunAmmo; - %client.lastDiscAmmo = %pl.invTR2DiscAmmo; - %client.lastGrenadeLauncherAmmo = %pl.invTR2GrenadeLauncherAmmo; - %client.lastGrenades = %pl.invTR2Grenade; - %client.lastBeacons = %pl.invBeacon; - - // Remember role items - for (%i=0; %i<$TR2::roleNumExtraItems[%client.currentRole]; %i++) - %client.lastRoleItemCount[%i] = %pl.extraRoleItemCount[%i]; -} - -function TR2Game::restockRememberedAmmo(%game, %client) -{ - %player = %client.player; - %player.setInventory(TR2ChaingunAmmo, %client.lastChaingunAmmo); - %player.setInventory(TR2DiscAmmo, %client.lastDiscAmmo); - %player.setInventory(TR2GrenadeLauncherAmmo, %client.lastGrenadeLauncherAmmo); - %player.setInventory(TR2Grenade,%client.lastGrenades); - %player.setInventory(Beacon, %client.lastBeacons); - - %game.equipRoleWeapons(%player.client); -} - -function TR2Game::penalty(%game, %player, %text, %amount) -{ - $teamScore[%player.team] -= %amount; - messageAll('MsgTR2SetScore', "", %player.team, $teamScore[%player.team]); - messageAll('MsgTR2Penalty', "\c3-" @ %amount SPC "\c1PENALTY: " @ %text @ " \c0(" @ getTaggedString(%player.client.name) @ ")~wfx/misc/whistle.wav"); -} - -function TR2Game::onClientKilled(%game, %clVictim, %clKiller, %damageType, %implement, %damageLocation) -{ - //echo ("CLIENT KILLED (" @ %clVictim @ ")"); - %plVictim = %clVictim.player; - %plKiller = %clKiller.player; - %clVictim.plyrPointOfDeath = %plVictim.position; - %clVictim.plyrDiedHoldingFlag = %plVictim.holdingFlag; - %clVictim.waitRespawn = 1; - - 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', ""); - - // TR2: Get rid of suicide delay - if (%damageType == $DamageType::suicide) - %respawnDelay = 2; - else - %respawnDelay = 2; - - // TR2: Teamkill penalty - if (%plVictim != %plKiller && %plVictim.team == %plKiller.team) - { - if (%plKiller.gogoKill) - %plKiller.gogoKill = false; - else - %game.schedule(1000, "penalty", %plKiller, "Friendly knockdown", $TR2::FriendlyKnockdownPenalty); - } - // TR2: Handle flag carrier kills - // Bonus evaluation - if (%plVictim == $TheFlag.carrier) - { - $TheFlag.dropperKilled = true; - - // Reset the bonus pot - //Game.currentBonus = 0; - //Game.updateCurrentBonusAmount(0, -1); - - if(%plVictim.team != %plKiller.team && %clKiller != 0) - WeaponBonus.evaluate(%plKiller, %plVictim, %damageType); - } - - %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.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); - //} - - //%clVictim.inSpawnBuilding = false; - - if (!$TR2::DisableDeath) - %plVictim.inSpawnBuilding = true; - - if (%damageType == $DamageType::Suicide) - { - %clVictim.player.delayRoleChangeTime = 0; - %game.assignOutermostRole(%clVictim); - %clVictim.lastDeathSuicide = true; - %clVictim.suicideRespawnTime = getSimTime() + 1000; - %clVictim.forceRespawn = true; - %clVictim.inSpawnBuilding = true; - //%game.trySetRole(%plVictim, Offense); - } - - else if (%damageType == $DamageType::Lava) - { - %clVictim.forceRespawn = true; - %clVictim.inSpawnBuilding = true; - } - - // TR2: disable death - else if ($TR2::DisableDeath && !%clVictim.forceRespawn) - { - %clVictim.plyrTransformAtDeath = %plVictim.getTransform(); - %clVictim.knockedDown = true; - %clVictim.knockDownTime = getSimTime(); - %game.rememberAmmo(%clVictim); - - // Track body thread - // Delay this slightly so that the body's speed is guaranteed - // to be greater than 0 - %game.schedule($TR2::KnockdownTimeSlice, "trackKnockDown", %plVictim); - } - - //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; - - // TR2: Force generic message for suicide-by-weapon - if ($TR2::DisableDeath && %clVictim == %clKiller) - %damageType = $DamageType::suicide; - - %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 - // TR2: Only throw all items if death is enabled - //if (!$TR2::DisableDeath || %clVictim.forceRespawn) - //{ - // for(%index = 0 ; %index < 8; %index++) - // { - // %image = %plVictim.getMountedImage(%index); - // if(%image) - // { - // if(%index == $FlagSlot) - // %plVictim.throwObject(%plVictim.holdingFlag); - // else - // %plVictim.throw(%image.item); - // } - // } - //} - // TR2: Otherwise just throw the flag if applicable - //else - if(%plVictim == $TheFlag.carrier) - %plVictim.throwObject(%plVictim.holdingFlag); - - // 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); - %obsx = getWord($TR2_playerObserveParameters, 0); - %obsy = getWord($TR2_playerObserveParameters, 1); - %obsz = getWord($TR2_playerObserveParameters, 2); - %clVictim.camera.setOrbitMode(%plVictim, %plVictim.getTransform(), %obsx, %obsy, %obsz); - //%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; -} - -function TR2Game::trackKnockDown(%this, %player) -{ - %client = %player.client; - %speed = %player.getSpeed(); - %time = getSimTime(); - - //echo(" (" @ %client @ ") Knockdown tracking"); - - if (%speed <= 0.1 && !%player.inCannon) - { - cancel(%client.knockDownThread); - - // Wait a bit longer - %client.suicideRespawnTime = %time + $TR2::delayAfterKnockdown; - - // Ensure the wait was at least a certain length of time - if (%client.suicideRespawnTime - %client.knockDownTime < $TR2::MinimumKnockdownDelay) - %client.suicideRespawnTime = %time + $TR2::MinimumKnockdownDelay; - - // Make the player spawn at his corpse's resting location - %client.plyrTransformAtDeath = %player.getTransform(); - - // Hmm...hack this to delete the corpse when the player presses the - // trigger (used in TR2Game::onObserverTrigger() - %client.playerToDelete = %player; - } - else if (%time - %client.knockDownTime > $TR2::MaximumKnockdownDelay) - { - cancel(%client.knockDownThread); - %this.forceRespawn(%client); - } - else - { - %client.suicideRespawnTime = %time + $TR2::knockdownTimeSlice; - %client.knockDownThread = %this.schedule($TR2::knockdownTimeSlice, "trackKnockDown", %player); - } -} - -function TR2Game::displayDeathMessages(%game, %clVictim, %clKiller, %damageType, %implement) -{ - %victimGender = (%clVictim.sex $= "Male" ? 'him' : 'her'); - %victimPoss = (%clVictim.sex $= "Male" ? 'his' : 'her'); - %killerGender = (%clKiller.sex $= "Male" ? 'him' : 'her'); - %killerPoss = (%clKiller.sex $= "Male" ? 'his' : 'her'); - %victimName = %clVictim.name; - %killerName = %clKiller.name; - //error("DamageType = " @ %damageType @ ", implement = " @ %implement @ ", implement class = " @ %implement.getClassName() @ ", is controlled = " @ %implement.getControllingClient()); - - if(%damageType == $DamageType::TouchedOwnGoal) - { - messageAll('msgTouchedOwnGoal', '\c0%1 respawns for touching %3 own goal.', %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by own goal."); - } - else if(%damageType == $DamageType::Grid) - { - %message = $TR2::DisableDeath ? - '\c0%1 was knocked down by the Grid.' : - '\c0%1 was killed by the Grid.'; - messageAll('msgGrid', %message, %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by Grid."); - } - else if(%damageType == $DamageType::OOB) - { - %message = '\c0%1 was thrown outside the Grid.'; - messageAll('msgGrid', %message, %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed for OOB."); - } - else if(%damageType == $DamageType::respawnAfterScoring) - { - //messageClient(%clVictim, 'msgRespawnAfterScoring', '\c0Your team scored! Forcing respawn...', %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") forced to respawn."); - } - else if(%damageType == $DamageType::Suicide) - { - %message = $TR2::DisableDeath ? - '\c1%1 knocks %2self out.' : - '\c1%1 is respawning...'; - messageAll('msgSuicide', %message, %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") is respawning."); - } - else if(%damageType == $DamageType::HotPotato) - { - // Could display a newbie message here - messageAll('msgHotPotato', '\c1%1 held onto the flag for too long!', %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType); - logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") killed by hot potato."); - } - else if(%damageType == $DamageType::G4) - { - } - else if ($TR2::DisableDeath && %damageType != $DamageType::Ground && %damageType != $DamageType::Lava - && %clVictim.team != %clKiller.team) - - { - messageAll('msgTR2Knockdown', '\c0%4 knocks down %1.', %victimName, %victimGender, %victimPoss, %killerName, %killerGender, %killerPoss, %damageType); - //logEcho(%clVictim.nameBase@" (pl "@%clVictim.player@"/cl "@%clVictim@") knocked down by " @c%clKiller.nameBase); - } - else - DefaultGame::displayDeathMessages(%game, %clVictim, %clKiller, %damageType, %implement); -} - -function TR2Game::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; - - if (%client $= "" || %client <= 0) - { - error("Invalid client sent to createPlayer()"); - 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); - - %armorType = $TR2::roleArmor[%client.currentRole]; - if (%armorType $= "") - %armorType = $DefaultPlayerArmor; - - // copied from player.cs - if (%client.race $= "Bioderm") - // No Bioderms. - %armor = "TR2" @ %armorType @ "Male" @ "Human" @ Armor; - else - %armor = "TR2" @ %armorType @ %client.sex @ %client.race @ Armor; - - %client.armor = %armor; - - // TR2 - %client.enableZones = false; - - %player = new Player() { - //dataBlock = $DefaultPlayerArmor; - //scale = "2 2 2"; - // TR2 - dataBlock = %armor; - }; - - if (%player == 0) - { - error("Unable to create new player in createPlayer()"); - return; - } - - %client.enableZones = true; - - if(%respawn) - { - %player.setInvincible(true); - //%player.setCloaked(true); - %player.setInvincibleMode($InvincibleTime,0.02); - //%player.respawnCloakThread = %player.schedule($InvincibleTime * 1000, "setRespawnCloakOff"); - %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; - %client.plyrDiedHoldingFlag = false; - - // TR2 - if (%client.knockedDown) - %client.restockAmmo = false; - else - %client.restockAmmo = true; - - %client.knockedDown = false; - %client.playerToDelete = ""; - %client.forceRespawn = false; - %player.inCannon = false; - - - - // 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 TR2Game::enableZones(%this, %client) -{ - %client.enableZones = true; -} - -function TR2Game::forceRespawn(%this, %client) -{ - %player = %client.getControlObject(); - %client.suicideRespawnTime = 0; - %client.knockedDown = false; - %client.inSpawnBuilding = true; - %client.forceRespawn = true; - if (%player.mode $= "playerDeath") - %this.ObserverOnTrigger(%player, %player, 1, 1); - else - %player.scriptKill($DamageType::RespawnAfterScoring); -} - -function TR2Game::forceTeamRespawn(%this, %team) -{ - // If DisableDeath is active, temporarily ignore it - //%disableDeath = $TR2::DisableDeath; - - //$TR2::DisableDeath = false; - for(%i = 0; %i < ClientGroup.getCount(); %i ++) - { - %client = ClientGroup.getObject(%i); - if (%client.team == %team) - Game.forceRespawn(%client); - } -} - -function TR2Game::pickPlayerSpawn(%game, %client, %respawn) -{ - if (%client.knockedDown && !%client.forceRespawn) - return %client.plyrTransformAtDeath; - else - return Parent::pickPlayerSpawn(%game, %client, %respawn); -} - -datablock AudioProfile(GridjumpSound) -{ - volume = 1.0; - filename = "fx/misc/gridjump.wav"; - description = AudioClose3d; - preload = true; -}; - -function TR2Game::leaveMissionArea(%game, %playerData, %player) -{ - if (%player.client.outOfBounds) - { - %player.client.forceRespawn = true; - return; - } - - if (%player.client.inSpawnBuilding) - return; - //%player.client.inSpawnBuilding = false; - - // Cancel the delayed oob check in case this is a second gridjump - //cancel(%player.checkOOBthread); - //%player.checkOOBthread = ""; - - if (%player.client.forceRespawn) - return; - - %alreadyDead = (%player.getState() $= "Dead"); - - %oldVel = %player.getVelocity(); - %player.client.outOfBounds = true; - -// //messageClient(%player.client, 'LeaveMissionArea', '\c1You left the mission area.~wfx/misc/warning_beep.wav'); - - %player.bounceOffGrid(85); - - // Gridjump effect - %newEmitter = new ParticleEmissionDummy(GridjumpEffect) { - position = %player.getTransform(); - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "defaultEmissionDummy"; - emitter = "GridjumpEmitter"; - velocity = "1"; - }; - //echo("EMITTER = " @ %newEmitter); - %newEmitter.schedule(%newEmitter.emitter.lifetimeMS, "delete"); - - %player.playAudio(0, GridjumpSound); - - if (!%alreadyDead) - { - %player.setDamageFlash(0.75); - %player.applyDamage(0.12); - if(%player.getState() $= "Dead") - Game.onClientKilled(%player.client, 0, $DamageType::Grid); - } - - // If the player is going too fast, blow him up - //if (%player.getSpeed() > $TR2_MaximumGridSpeed) - //{ - // %player.client.forceRespawn = true; - // if(!%alreadyDead) - // { - // cancel(%player.checkOOBthread); - // %player.applyDamage(1); - // //%player.blowup(); - // Game.onClientKilled(%player.client, 0, $DamageType::Grid); - // } - - // return; - //} - - // Double-check that the player didn't squeeze out - if (!%player.client.forceRespawn) - %player.checkOOBthread = %game.schedule(1000, "doubleCheckOOB", %player); -} - -function TR2Game::doubleCheckOOB(%this, %player) -{ - if (%player.client.outOfBounds && !%player.client.forceRespawn) - { - %player.client.forceRespawn = true; - if (%player.getState() !$= "Dead") - { - %player.applyDamage(1); - %player.client.inSpawnBuilding = true; - //%player.blowup(); - Game.onClientKilled(%player.client, 0, $DamageType::OOB); - } - } -} - -function TR2Game::enterMissionArea(%game, %playerData, %player) -{ -// if(%player.getState() $= "Dead") -// return; - - %player.client.outOfBounds = false; - - // TR2: Should probably find a better place for this - if (!%player.client.forceRespawn) - %player.client.inSpawnBuilding = false; - //messageClient(%player.client, 'EnterMissionArea', '\c1You are back in the mission area.'); -} - - -//---------------------------------------------------------------------------- -// TR2Flag: -//---------------------------------------------------------------------------- -datablock ShapeBaseImageData(TR2FlagImage) -{ - shapeFile = $TR2::ThrownObject; - item = Flag; - mountPoint = 2; - offset = "0 0 0.1"; - - lightType = "PulsingLight"; - lightColor = "0.9 0.0 0.0 1.0"; - lightTime = "500"; - lightRadius = "18"; -}; - -// 1: red -// 2: blue -// 4: yellow -// 8: green -datablock ItemData(TR2Flag1) -{ - // Observer stuff - cameraDefaultFov = 90; - cameraMaxDist = 20; - cameraMaxFov = 120; - cameraMinDist = 5; - cameraMinFov = 5; - canControl = false; - canObserve = true; - - className = TR2Flag; - - shapefile = $TR2::ThrownObject; - mass = $TR2_FlagMass; - density = $TR2_FlagDensity; - elasticity = $TR2_FlagElasticity; - friction = $TR2_FlagFriction; - drag = 0.08;//0.2; // - maxdrag = 0.25;//0.4; - rotate = true; - - // These don't seem to have any effect - //pickupRadius = 10; - - isInvincible = true; - pickUpName = "a flag"; - computeCRC = true; - - lightType = "PulsingLight"; - lightColor = "0.9 0.2 0.2 1.0"; - lightTime = "250"; - lightRadius = "18"; - - category = "Objectives"; - cmdCategory = "Objectives"; - cmdIcon = CMDFlagIcon; - cmdMiniIconName = "commander/MiniIcons/com_flag_grey"; - targetTypeTag = 'Flag'; - - hudImageNameFriendly[1] = "commander/MiniIcons/TR2com_flag_grey"; - hudIMageNameEnemy[1] = "commander/MiniIcons/TR2com_flag_grey"; - hudRenderModulated[1] = true; - hudRenderAlways[1] = true; - hudRenderCenter[1] = true; - hudRenderDistance[1] = true; - hudRenderName[1] = false; - -// catagory = "Objectives"; -// shapefile = "flag.dts"; -// mass = 55; -// elasticity = 0.2; -// friction = 0.6; -// pickupRadius = 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'; -}; - -datablock ItemData(TR2Flag2) : TR2Flag1 -{ - lightColor = "0.1 0.1 0.9 1.0"; - className = TR2FlagFake; - lightTime = "100"; - lightRadius = "5"; -}; - -datablock ItemData(TR2Flag4) : TR2Flag2 -{ - lightColor = "0.9 0.9 0.1 1.0"; -}; - -datablock ItemData(TR2Flag8) : TR2Flag2 -{ - lightColor = "0.1 0.9 0.1 1.0"; -}; - -// Used as an Audio object -datablock ItemData(TR2FlagTiny) : TR2Flag2 -{ - lightColor = "0.1 0.9 0.1 1.0"; - scale = "0.0001 0.0001 0.0001"; -}; - -function TR2Flag::onRemove(%data, %obj) -{ - // dont want target removed... -} - -function AddTR2FlagSmoke(%obj) -{ - // Sneak in an oob check - // TO-DO: Create a general post-throw flag thread - if (%obj.isOutOfBounds()) - if (%obj.getSpeed() < $TR2_MaximumGridSpeed) - %obj.bounceOffGrid(3); - else - Game.flagReturn(%obj, %obj.dropper); - - %scale = VectorLen(%obj.getVelocity()); - - if( %scale >= $TR2::MinSpeedForFlagSmoke || (%obj.getHeight() > 7 && !%obj.isHome && !%obj.onGoal) ) - { - %delay = 100 - %scale; - %x = getWord(%obj.position, 0); - %y = getWord(%obj.position, 1); - %z = getWord(%obj.position, 2) + 1.4; - - if( Game.TR2FlagSmoke < 20 ) - Game.TR2FlagSmoke++; - else - Game.TR2FlagSmoke = 0; - - if( isObject(Game.dropSmoke[Game.TR2FlagSmoke]) ) - { - Game.dropSmoke[Game.TR2FlagSmoke].delete(); - Game.dropSmoke[Game.TR2FlagSmoke] = ""; - } - - Game.dropSmoke[Game.TR2FlagSmoke] = new ParticleEmissionDummy() - { - //position = getWord(%client.player.position, 0) SPC getWord(%client.player.position, 1) SPC getWord(%client.player.position, 2) + 3; - position = %x SPC %y SPC %z; - rotation = "0 0 0 0"; - scale = "1 1 1"; - dataBlock = defaultEmissionDummy; - emitter = TR2FlagEmitter; - velocity = "1"; - }; - MissionCleanup.add(Game.dropSmoke[Game.TR2FlagSmoke]); - - Game.dropSmoke[Game.TR2FlagSmoke].schedule(1000, "delete"); - - Game.addFlagTrail = schedule($TR2::FlagSmokeTimeSlice, 0, "AddTR2FlagSmoke", %obj); - } - else - Game.TR2FlagSmoke = 0; -} - -function aodebug() -{ - for( %i = 0; %i <= 20; %i++ ) - { - %status = isObject(Game.dropSmoke[%i]) ? "exists" : "does NOT exist"; - echo( "*** Flag smoke " @ %i @ " " @ %status ); - } -} - -function TR2Flag::onThrow(%data,%obj,%src) -{ - Game.playerDroppedFlag(%src); - AddTR2FlagSmoke(%obj); -} - -function TR2Flag::onCollision(%data,%obj,%col) -{ - if (%col.getDataBlock().className $= Armor) - { - if (%col.isMounted()) - return; - - cancel(Game.addFlagTrail); - - // a player hit the flag - Game.playerTouchFlag(%col, %obj); - } - else if (%obj.onGoal || %obj.getSpeed() <= 0.1) - return; - - else if (%col.getDataBlock().className $= Goal) - { - Game.goalCollision(%obj, %col); - } - else if (%col.getDataBlock().className $= GoalPost || - %col.getDataBlock().className $= GoalCrossbar) - { - // Play some noise. =) - serverPlay2D(CrowdDisappointment1Sound); - } - -} - -function TR2Flag::objectiveInit(%this, %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(), TR2Game::getTeamSkin(TR2Game, %flag.team)); - - // TR2: Make it red to everyone - setTargetSensorGroup(%flag.getTarget(), 3); - - setTargetAlwaysVisMask(%flag.getTarget(), 0x7); - setTargetRenderMask(%flag.getTarget(), getTargetRenderMask(%flag.getTarget()) | 0x2); - %flag.scopeWhenSensorVisible(true); - $flagStatus[%flag.team] = ""; - - // set the nametag on the target - //setTargetName(%flag.getTarget(), TR2Game::getTeamName(TR2Game, %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, TR2Game::getTeamName( TR2Game, %flag.team), "", "", 'Base', %flag.team, 0); - //setTargetAlwaysVisMask(%target, 0xffffffff); - - //store the flag in an array - $TeamFlag[%flag.team] = %flag; - - // KP: Make our lives easier - $TheFlag = %flag; - $TheFlag.oneTimer = 0; - //setTargetRenderMask($TheFlag, getTargetRenderMask($TheFlag) | 0x4); - - $AIRabbitFlag = %flag; - - // TR2 - %flag.lastKTS = 0; - %flag.dropper = ""; - %flag.dropTime = 0; - %flag.lastMario = 0; - %flag.oneTimerCount = 0; - %flag.oneTimer = 0; -} - -function TR2Flag::resetOneTimerCount(%flag) -{ - %flag.oneTimerCount = 0; -} - -function TR2Flag1::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); - } - %obj.inLiquid = true; - //$FlagReturnTimer[%obj] = Game.schedule(Game.FLAG_RETURN_DELAY - Game.fadeTimeMS + 2000, "flagReturnFade", %obj); - - - // Reset the drop time (for hangtime calculations) - %obj.dropTime = getSimTime(); -} - -function TR2Flag1::onLeaveLiquid(%data, %obj, %type) -{ - %obj.inLiquid = false; - //cancel($FlagReturnTimer[%obj]); -} - -function TR2Game::emitFlags(%game, %position, %count, %player, %ttl) // %obj = whatever object is being used as a focus for the flag spew - // %count = number of flags to spew -{ - if( %position $= "" ) - { - error("No position passed!"); - return 0; - } - if( %count <= 0 ) - { - error("Number of flags to spew must be greater than 0!"); - return 0; - } - - %flagArr[0] = TR2Flag8; - %flagArr[1] = TR2Flag2; - %flagArr[2] = TR2Flag4; - - while( %count > 0 ) - { - %index = mFloor(getRandom() * 3); - // throwDummyFlag(location, Datablock); - throwDummyFlag(%position, %flagArr[%index], %player, %ttl); - %count--; - } -} - -function throwDummyFlag(%position, %datablock, %player, %ttl) -{ - %client = %player.client; - - // create a flag and throw it - %droppedflag = new Item() { - position = %position; - rotation = "0 0 1 " @ (getRandom() * 360); - scale = "1 1 1"; - dataBlock = %datablock; - collideable = "0"; - static = "0"; - rotate = "1"; - team = "0"; - isFake = 1; - }; - MissionCleanup.add(%droppedflag); - - %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); - %vec = VectorScale(%vec, 1000 + (getRandom() * 300)); - - // Add player's velocity - if (%player !$= "") - { - %droppedflag.setCollisionTimeout(%player); - %vec = vectorAdd(%vec, %player.getVelocity()); - } - - %droppedflag.applyImpulse(%pos, %vec); - - %deleteTime = (%ttl $= "") ? $TR2::CrazyFlagLifetime : %ttl; - %droppedFlag.die = schedule(%deleteTime, 0, "removeFlag", %droppedflag); -} - -function removeFlag(%flag) -{ - %flag.startFade(600, 0, true); - %flag.schedule(601, "delete"); -} - -function TR2FlagFake::onCollision(%data,%obj,%col) -{ - if (%obj.dying) - return; - - cancel(%obj.die); - %obj.startFade(400, 0, true); - %obj.dying = true; - %obj.schedule(401, "delete"); - - // Message player and award bonus point here - messageClient(%col.client, 'MsgTR2CrazyFlag', '\c2Crazy flag! (+3)'); - serverPlay3D(CoinSound, %col.getPosition()); - Game.giveInstantBonus(%col.client.team, 3); -} - -function TR2Game::goalCollision(%this, %obj, %colObj) -{ - if (%obj != $TheFlag) - return; - - if (Game.currentBonus < $TR2::MinimumJackpot && !$TR2::PracticeMode) - { - messageAll('MsgTR2JackpotMinimum', "\c3NO GOAL: Jackpot must be at least " - @ $TR2::MinimumJackpot @".~wfx/misc/red_alert_short.wav"); - return; - } - - // Check goalie crease - %throwDist = VectorLen(VectorSub(%obj.dropperPosition, %colobj.getPosition())); - if (%throwDist < $TR2::roleDistanceFromGoal[Goalie] - 14) - { - messageAll('MsgTR2GoalieCrease', "\c3NO GOAL: Throw was inside the goalie crease." - @".~wfx/misc/red_alert_short.wav"); - return; - } - - if (!$TheFlag.onGoal) - { - // Award points - %scoringTeam = (%colObj.team == 1) ? 2 : 1; - - $teamScore[%scoringTeam] += Game.currentBonus; - $teamScoreJackpot[%scoringTeam] += Game.currentBonus; - Game.currentBonus = 0; - Game.updateCurrentBonusAmount(0, -1); - messageAll('MsgTR2SetScore', "", %scoringTeam, $teamScore[%scoringTeam]); - - - // Respawn the flag on top of the goal - %newFlagPosition = %colobj.position; - %newz = getWord(%newFlagPosition, 2) + 80; - %newFlagPosition = setWord(%newFlagPosition, 2, %newz); - %obj.setVelocity("0 0 0"); - %obj.setTransform(%newFlagPosition @ "0 0 0"); - %obj.onGoal = true; - cancel($FlagReturnTimer[%obj]); - - // Allow some time for taunting - if (!$TR2::PracticeMode) - { - //%obj.hide(true); - Game.goalJustScored = true; - %this.schedule($TR2::goalRespawnDelay*1000, "resetTheField", %scoringTeam); - } - - // Inform players - %this.schedule(750, "afterGoal", %scoringTeam); - - %scoreMessage = $TR2::PracticeMode ? - '\c3Goal! (Practice Mode enabled)~wfx/misc/goal.wav' : - '\c3Your team scored!~wfx/misc/goal.wav'; - - %otherMessage = $TR2::PracticeMode ? - '\c3Goal! (Practice Mode enabled)~wfx/misc/goal.wav' : - '\c3You allowed the other team to score.~wfx/misc/goal.wav'; - - %obsMessage = '\c3Goal!~wfx/misc/goal.wav'; - - messageTeam(%colObj.team, 'msgTR2TeamScored', %otherMessage); - messageTeam(%scoringTeam, 'msgTR2TeamScored', %scoreMessage); - messageTeam(0, 'msgTR2TeamScore', %obsMessage); - - messageTeam(%colObj.team, 'MsgTR2FlagStatus', "", "On your goal"); - messageTeam(%scoringTeam, 'MsgTR2FlagStatus', "", "On their goal"); - messageTeam(0, 'MsgTR2FlagStatus', "", "On goal"); - - // Schedule some delayed messages (only if they didn't score on themselves) - if (%obj.dropper.team == %scoringTeam) - { - %goalScorer = %obj.dropper; - if ($TheFlag.oneTimer) - { - $teamScore[%scoringTeam] += $TR2::OneTimerGoalBonus; - messageAll('MsgTR2SetScore', "", %scoringTeam, $teamScore[%scoringTeam]); - %message ="\c1 One-timer goal (+" - @ $TR2::OneTimerGoalBonus @ ") scored by \c3" - @ getTaggedString(%goalScorer.client.name) @ "~wfx/misc/target_waypoint.wav"; - } - else - %message ="\c1 Goal scored by \c3" - @ getTaggedString(%goalScorer.client.name) @ "~wfx/misc/target_waypoint.wav"; - - - schedule(4000, 0, "messageAll", 'MsgTR2GoalScorer', %message); - %goalScorer.client.goals++; - - %firstAssist = FlagBonusHistory.getRecentRecipient(1); - %secondAssist = FlagBonusHistory.getRecentRecipient(2); - - if (%firstAssist !$= "" && %firstAssist.client.name !$= "" && %firstAssist != %goalScorer && %firstAssist.team == %goalScorer.team) - { - schedule(5000, 0, "messageAll", 'MsgTR2GoalAssist', "\c1 Assisted by \c3" - @ getTaggedString(%firstAssist.client.name) @ "~wfx/misc/target_waypoint.wav"); - %firstAssist.client.assists++; - } - - if (%secondAssist !$= "" && %secondAssist.client.name !$= "" && %secondAssist != %firstAssist && %secondAssist != %goalScorer && %secondAssist.team == %goalScorer.team) - { - schedule(6000, 0, "messageAll", 'MsgTR2GoalScorer', "\c1 Assisted by \c3" - @ getTaggedString(%secondAssist.client.name) @ "~wfx/misc/target_waypoint.wav"); - %secondAssist.client.assists++; - } - } - Game.flagReset(%obj); - } -} - -function TR2Game::afterGoal(%this, %scoringTeam) -{ - serverPlay2d(CrowdCheer1Sound); - - if (!$TR2::PracticeMode) - messageAll('MsgTR2RespawnWarning', "Forcing respawn in " - @ $TR2::goalRespawnDelay @ " seconds."); - - %this.schedule(1000, "afterGoal1", %scoringTeam); -} - -function TR2Game::afterGoal1(%this, %scoringTeam) -{ - serverPlay2d(CrowdFlairSound); -} - -function TR2Game::resetTheField(%this, %team) -{ - Game.goalJustScored = false; - messageAll('MsgTR2ForcedRespawn', "Respawning..."); - - // Force both teams to respawn - Game.forceTeamRespawn(%team); - //$TheFlag.hide(false); -} - -function TR2Game::sendGameVoteMenu( %game, %client, %key ) -{ - if( (($Host::TournamentMode && !MatchStarted) || !$Host::TournamentMode) && !$TR2::SpecLock && %client.queueSlot !$= "" && %client.queueSlot <= ((6 * 2) - getActiveCount()) ) - { - messageClient( %client, 'MsgVoteItem', "", %key, 'tr2JoinGame', 'Join the game', 'Join the game' ); - } - - if( %client.isAdmin && $TheFlag.carrier $= "" && (getSimTime() - $TheFlag.dropTime) >= 30000 ) - { - messageClient( %client, 'MsgVoteItem', "", %key, 'tr2ForceFlagReturn', 'Force the flag to return', 'Force the flag to return' ); - } - - DefaultGame::sendGameVoteMenu( %game, %client, %key ); - - if( %client.isAdmin ) - { - //if ( $TR2::DisableDeath ) - // messageClient( %client, 'MsgVoteItem', "", %key, 'ToggleDisableDeath', 'Enable Death', 'Enable Death' ); - //else - // messageClient( %client, 'MsgVoteItem', "", %key, 'ToggleDisableDeath', 'Disable Death', 'Disable Death' ); - - if ( $TR2::PracticeMode ) - messageClient( %client, 'MsgVoteItem', "", %key, 'TogglePracticeMode', 'Disable Practice Mode', 'Disable Practice Mode' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'TogglePracticeMode', 'Enable Practice Mode', 'Enable Practice Mode' ); - - if ( $TR2::EnableRoles ) - messageClient( %client, 'MsgVoteItem', "", %key, 'ToggleRoles', 'Disable Player Roles', 'Disable Player Roles' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'ToggleRoles', 'Enable Player Roles', 'Enable Player Roles' ); - - if ( $TR2::EnableCrowd ) - messageClient( %client, 'MsgVoteItem', "", %key, 'ToggleCrowd', 'Disable Crowd', 'Disable Crowd' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'ToggleCrowd', 'Enable Crowd', 'Enable Crowd' ); - if( $TR2::SpecLock ) - messageClient( %client, 'MsgVoteItem', "", %key, 'toggleSpecLock', 'Unlock Spectators', 'Unlock Spectators' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'toggleSpecLock', 'Lock Spectators', 'Lock Spectators' ); - - } - if( %client.team == 0 ) - { - if( %client.queueSlot !$= "" ) - messageClient( %client, 'MsgVoteItem', "", %key, 'getQueuePos', 'Get your queue status', 'Get your queue status' ); - - if( !%client.specOnly) - messageClient( %client, 'MsgVoteItem', "", %key, 'toggleSpecOnly', 'Lock myself as a spectator', 'Lock myself as a spectator' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'toggleSpecOnly', 'Enter the queue to join the game.', 'Enter the queue to join the game.' ); - - if( !%client.tr2SpecMode ) - messageClient( %client, 'MsgVoteItem', "", %key, 'toggleSpecMode', 'Lock onto Flag/Carrier', 'Lock onto Flag/Carrier' ); - else - messageClient( %client, 'MsgVoteItem', "", %key, 'toggleSpecMode', 'Free-flight Observer Mode', 'Free-flight Observer Mode' ); - } -} - -function TR2Game::clientChangeTeam(%game, %client, %team, %fromObs) -{ - %time = getSimTime(); - if (%time - %client.lastTeamChangeTime <= $TR2::delayBetweenTeamChanges) - return; - - %client.lastTeamChangeTime = %time; - - // Get rid of the corpse after changing teams - %client.forceRespawn = true; - %client.inSpawnBuilding = true; - - // First set to outer role (just to be safe) - %game.assignOuterMostRole(%client); - - // Then release client's role - %game.releaseRole(%client); - - - if( %fromObs ) - removeFromQueue(%client); - - return Parent::clientChangeTeam(%game, %client, %team, %fromObs); -} - -function TR2Game::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', "", 'TEAMSCOREJackpotCreativityPossession' ); - for ( %team = 1; %team - 1 < %game.numTeams; %team++ ) - { - if ( $TeamScore[%team] $= "" ) - { - %score = 0; - %jscore = 0; - %cscore = 0; - %pscore = 0; - } - else - { - %score = $TeamScore[%team]; - %jscore = $TeamScoreJackpot[%team]; - %cscore = $TeamScoreCreativity[%team]; - %pscore = $TeamScorePossession[%team]; - } - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3 %4 %5', %game.getTeamName(%team), %score, %jscore, %cscore, %pscore ); - } - - // Player scores: - messageClient( %client, 'MsgDebriefAddLine', "", '\nPLAYERTEAMGOALSASSISTSSAVESPASSRECVINTCFC-HITS' ); - 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.passingScore + %cl.receivingScore + %cl.interceptingScore; - %kills = %cl.kills $= "" ? 0 : %cl.kills; - messageClient( %client, 'MsgDebriefAddLine', "", ' %1 %2 %3 %4 %5 %6 %7 %8 %9', %cl.name, %game.getTeamName(%cl.team), %cl.goals, %cl.assists, %cl.saves, %cl.passingScore, %cl.receivingScore, %cl.interceptingScore, %cl.fcHits ); - - %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 TR2Game::updateScoreHud(%game, %client, %tag) -{ - 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 && !isDemo() && %game.class $= "CTFGame") - { - %team1ClientScore = "--------------"; - } - else if( %index == $teamRank[1, count]+1 && $teamRank[1, count] != 0 && !isDemo() && %game.class $= "CTFGame") - { - %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 && !isDemo() && %game.class $= "CTFGame") - { - %team2ClientScore = "--------------"; - } - else if( %index == $teamRank[2, count]+1 && $teamRank[2, count] != 0 && !isDemo() && %game.class $= "CTFGame") - { - %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 ); - } - //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) - { - if ( %numColumns == 2 ) - messageClient(%client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', - %col1Client.name, %col1ClientScore, %col2Client.name, %col2ClientScore, %col1Style, %col2Style ); - else - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%3%1%2', - %col1Client.name, %col1ClientScore, %col1Style ); - } - //else for observers, create an anchor around the player name so they can be observed - else - { - if ( %numColumns == 2 ) - messageClient(%client, 'SetLineHud', "", %tag, %index, '\t%5%1%2\t%6%3%4', - %col1Client.name, %col1ClientScore, %col2Client.name, %col2ClientScore, %col1Style, %col2Style, %col1Client, %col2Client ); - else - messageClient( %client, 'SetLineHud', "", %tag, %index, '\t%3%1%2', - %col1Client.name, %col1ClientScore, %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 TR2Game::selectSpawnMarker(%game, %team) -{ - if (%team <= 0) - return; - - %teamDropsGroup = "MissionCleanup/TeamDrops" @ %team; - - %group = nameToID(%teamDropsGroup); - if (%group != -1) - { - %count = %group.getCount(); - if (%count > 0) - { - for (%try =0; %try < 5; %try++) - { - %done = false; - %markerIndex = mFloor(getRandom() * %count); - %markerAttempts = 0; - while (%markerAttempts < %count) - { - %marker = %group.getObject(%markerIndex); - - // If nobody's at this spawn, use it - if (%marker > 0 && !%game.teammateNear(%team, %marker.getPosition())) - { - //echo("SPAWN FOUND for team " @ %team @ " (" @ %try @ " tries)"); - return %marker.getTransform(); - } - - // Otherwise, cycle through looking for the next available slot - %markerIndex++; - - // Handle circular increment - if (%markerIndex >= %count) - %markerIndex = 0; - - %markerAttempts++; - } - } - echo("**SPAWN ERROR: spawn not found."); - } - else - error("No spawn markers found in " @ %teamDropsGroup); - } - else - error(%teamDropsGroup @ " not found in selectSpawnMarker()."); - - return -1; -} - -function TR2Game::teammateNear(%game, %team, %position) -{ - %count = ClientGroup.getCount(); - - // Only check x,y (this means we can't have one spawn directly over another, - // but oh well...quick and dirty) - %position = setWord(%position, 2, 0); - - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl $= "" || %cl.player == 0 || %cl.player $= "") - continue; - - if (%cl.team == %team) - { - %plyrPos = %cl.player.getPosition(); - %plyrPos = setWord(%plyrPos, 2, 0); - %diff = VectorLen(VectorSub(%position, %plyrPos)); - if (%diff <= 1) - return true; - } - } - - return false; -} - -function TR2Game::pickTeamSpawn(%game, %team) -{ - // Oh-so simple - return %game.selectSpawnMarker(%team); -} - -function TR2Game::onClientEnterObserverMode( %game, %client ) -{ - clearBottomPrint(%client); -} - -function ServerPlayAudio(%slot, %profile) -{ - $TR2::audioSlot[%slot] = alxPlay(%profile, 0, 0, 0); -} - -function ServerStopAudio(%slot) -{ - alxStop($TR2::audioSlot[%slot]); -} - -function TR2Game::increaseCrowdLevel(%game) -{ - if (%game.crowdLevel+1 == $TR2::numCrowdLevels) - return; - - %game.crowdTransition(%game.crowdLevel+1); -} - -function TR2Game::decreaseCrowdLevel(%game) -{ - if (%game.crowdLevel == -1) - return; - - if (%game.crowdLevel == 0) - %game.stopCrowd(); - else - %game.crowdTransition(%game.crowdLevel-1); -} - -function TR2Game::stopCrowd(%game) -{ - //if (%game.crowdLevel == -1) - // return; - - ServerPlay2d($TR2::crowdLoopTransitionDown[%game.crowdLevel]); - //schedule(50, 0, "ServerStopAudio", %game.crowdLevel); - - // Stop all levels immediately - ServerStopAudio(0); - ServerStopAudio(1); - ServerStopAudio(2); - %game.crowdLevel = -1; -} - -function TR2Game::crowdTransition(%game, %level) -{ - if (%level == %game.crowdLevel) - return; - - //%newSlot = (%game.crowdLevelSlot == 2) ? 3 : 2; - - ServerPlay2d($TR2::crowdLoopTransitionUp[%level]); - schedule(4000, 0, "ServerPlay2d", $TR2::crowdLoopTransitionDown[%game.crowdLevel]); - - schedule(1200, 0, "ServerPlay2d", CrowdFadeSound); - schedule(3200, 0, "ServerPlay2d", CrowdFadeSound); - - schedule(4100, 0, "ServerStopAudio", %game.crowdLevel); - schedule(2850, 0, "ServerPlayAudio", %level, $TR2::CrowdLoop[%level]); - - %game.crowdLevel = %level; - //%game.crowdLevelSlot = %newSlot; -} - -function TR2Game::evaluateCrowdLevel(%game) -{ - if (%game.currentBonus < $TR2::minimumJackpot) - { - %game.stopCrowd(); - return; - } - - if ($TheFlag.carrier $= "") - { - %obj = $TheFlag; - %distance1 = VectorLen(VectorSub(%obj.getPosition(), $teamgoal[1].getPosition())); - %distance2 = VectorLen(VectorSub(%obj.getPosition(), $teamgoal[2].getPosition())); - %dist = (%distance1 > %distance2) ? %distance2 : %distance1; - } - else - { - %obj = $TheFlag.carrier; - %otherTeam = ($TheFlag.carrier.team == 1) ? 2 : 1; - %dist = VectorLen(VectorSub(%obj.getPosition(), $teamgoal[%otherTeam].getPosition())); - } - - for (%i=0; %i<$TR2::NumCrowdLevels; %i++) - { - if (%dist < $TR2::CrowdLevelDistance[%i]) - %newLevel = %i; - } - - if (%newLevel $= "") - { - %game.decreaseCrowdLevel(); - return; - } - else if (%newLevel == %game.crowdLevel) - return; - - if (%newLevel > %game.crowdLevel) - %game.increaseCrowdLevel(); - else - %game.decreaseCrowdLevel(); -} - -// Fun stuff! -function TR2Game::startSphere(%game) -{ - //%game.preSphereGravity = getGravity(); - setGravity(0); - %count = ClientGroup.getCount(); - - %position = $TR2::TheSphere.getPosition(); - %radius = 75; - - // Prevent all damage - %game.goalJustScored = true; - - if ($TheFlag.carrier !$= "") - $TheFlag.carrier.throwObject($TheFlag); - - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl $= "" || %cl.player == 0 || %cl.player $= "") - continue; - - - %addx = mFloor(getRandom() * %radius); - %addy = mFloor(getRandom() * %radius); - %addy = mFloor(getRandom() * %radius); - - %newx = getWord(%position, 0) + %addx; - %newy = getWord(%position, 1) + %addy; - %newz = getWord(%position, 2) + %addz; - %newPosition = %newx SPC %newy SPC %newz; - %cl.inSpawnBuilding = true; - - %cl.plyrTransformAtDeath = %newPosition; - %cl.player.setTransform(%newPosition); - } - - %game.emitFlags(%position, 40, "", 60000); -} - -function TR2Game::endSphere(%game) -{ - Game.goalJustScored = false; - setGravity($TR2::Gravity); - %game.forceTeamRespawn(1); - %game.forceTeamRespawn(2); -} - - - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Items.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Items.cs deleted file mode 100644 index 9baedf4b..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Items.cs +++ /dev/null @@ -1,429 +0,0 @@ -exec("scripts/weapons/TR2disc.cs"); -exec("scripts/weapons/TR2grenadeLauncher.cs"); -exec("scripts/weapons/TR2chaingun.cs"); -exec("scripts/weapons/TR2grenade.cs"); -exec("scripts/weapons/TR2targetingLaser.cs"); -exec("scripts/packs/TR2energypack.cs"); -exec("scripts/weapons/TR2shocklance.cs"); -exec("scripts/weapons/TR2mortar.cs"); - -datablock StaticShapeData(TR2DeployedBeacon) : StaticShapeDamageProfile -{ - shapeFile = "beacon.dts"; - explosion = DeployablesExplosion; - maxDamage = 0.45; - disabledLevel = 0.45; - destroyedLevel = 0.45; - targetNameTag = 'beacon'; - - deployedObject = true; - - dynamicType = $TypeMasks::SensorObjectType; - - debrisShapeName = "debris_generic_small.dts"; - debris = SmallShapeDebris; -}; - -datablock ItemData(RedNexus) -{ - catagory = "Objectives"; - shapefile = "nexus_effect.dts"; - mass = 10; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - icon = "CMDNexusIcon"; - targetTypeTag = 'Nexus'; - - computeCRC = false; -}; - -datablock ItemData(YellowNexus) -{ - catagory = "Objectives"; - shapefile = "nexus_effect.dts"; - mass = 10; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - icon = "CMDNexusIcon"; - targetTypeTag = 'Nexus'; - - computeCRC = false; -}; - -function serverCmdStartFlagThrowCount(%client, %data) -{ - %client.player.flagThrowStart = getSimTime(); -} - -function serverCmdEndFlagThrowCount(%client, %data) -{ - if(%client.player.flagThrowStart == 0) - return; - - %time = getSimTime(); - %result = %time - %client.player.flagThrowStart; - if( %result >= $TR2::MaxFlagChargeTime ) - { - %client.player.flagThrowStart = 0; - return; - } - - // throwStrength will be how many seconds the key was held - %throwStrength = (getSimTime() - %client.player.flagThrowStart) / 1000; - // trim the time to fit between 0.2 and 1.2 - if(%throwStrength > 1.2) - %throwStrength = 1.2; - else if(%throwStrength < 0.2) - %throwStrength = 0.2; - - %client.player.flagThrowStrength = %throwStrength; - - %client.player.flagThrowStart = 0; -} - -datablock AudioProfile(LauncherSound) -{ - volume = 1.0; - filename = "fx/misc/launcher.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock StaticShapeData(Launcher) -{ - catagory = "Objectives"; - className = "Launcher"; - isInvincible = true; - needsNoPower = true; - shapeFile = "stackable3m.dts"; - soundEffect = LauncherSound; - scale = "1 1 0.14"; -}; - -function Launcher::onCollision(%this, %obj, %col) -{ - //echo("LAUNCHER: " @ %col); - %newVel = %col.getVelocity(); - %normVel = VectorNormalize(%newVel); - %speed = %col.getSpeed(); - - // If the player walks on it, boost him upward - if (%speed < 30) - { - %newVel = %normVel; - %newVel = VectorScale(%newVel, 10); - %newVel = setWord(%newVel, 2, 72); - } - // If he has decent speed, give him a static boost - else if (%speed < 100) - { - %newVel = %normVel; - %newVel = VectorScale(%newVel, 100); - // Otherwise, give him a slightly scaled boost - } else - %newVel = VectorScale(%newVel, 1.05); - //%newVel = setWord(%newVel, 2, getWord(%newVel, 2) * -1); - //%col.applyImpulse(%col.getWorldBoxCenter(), VectorScale(%newVel, 200)); - %col.setVelocity(%newVel); - %obj.playAudio(0, %this.soundEffect); -} - -datablock TriggerData(cannonTrigger) -{ - tickPeriodMS = 1000; -}; - -datablock TriggerData(goalZoneTrigger) -{ - tickPeriodMS = 1000; -}; - -datablock TriggerData(defenseZoneTrigger) -{ - tickPeriodMS = 1000; -}; - -datablock AudioProfile(CannonShotSound) -{ - volume = 1.0; - filename = "fx/misc/cannonshot.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock AudioProfile(CannonStartSound) -{ - volume = 1.0; - filename = "fx/misc/cannonstart.wav"; - description = AudioClose3d; - preload = true; -}; - -function cannonTrigger::onEnterTrigger(%this, %trigger, %obj) -{ - if (%obj.getState $= "Dead") - return; - - %client = %obj.client; - %obj.playAudio(0, CannonStartSound); - %obj.inCannon = true; - %obj.setInvincible(true); - %client.cannonThread = %this.schedule(500, "ShootCannon", %trigger, %obj); -} - -function cannonTrigger::onLeaveTrigger(%this, %trigger, %obj) -{ - %client = %obj.client; - %obj.setInvincible(false); - cancel(%client.cannonThread); -} - -function cannonTrigger::onTickTrigger(%this, %trigger) -{ -} - -function cannonTrigger::shootCannon(%this, %trigger, %obj) -{ - %obj.applyImpulse(%obj.getWorldBoxCenter(), "0 0 20000"); - %obj.setInvincible(false); - %obj.inCannon = false; - - %newEmitter = new ParticleEmissionDummy(CannonEffect) { - position = %trigger.position; - rotation = %trigger.rotation; - scale = "1 1 1"; - dataBlock = "defaultEmissionDummy"; - emitter = "CannonEmitter"; - velocity = "1"; - }; - - %obj.playAudio(0, CannonShotSound); - %newEmitter.schedule(%newEmitter.emitter.lifetimeMS, "delete"); -} - -function goalZoneTrigger::onEnterTrigger(%this, %trigger, %obj) -{ - if (!$TR2::EnableRoles || %trigger.team != %obj.team) - return; - - if (!%obj.client.enableZones) - return; - - - Game.trySetRole(%obj, Goalie); -} - -function goalZoneTrigger::onLeaveTrigger(%this, %trigger, %obj) -{ - if (!$TR2::EnableRoles) - return; - - if (!%obj.client.enableZones) - return; - - if (!Game.trySetRole(%obj, Defense)) - Game.trySetRole(%obj, Offense); -} - -function defenseZoneTrigger::onEnterTrigger(%this, %trigger, %obj) -{ - if (!$TR2::EnableRoles || %trigger.team != %obj.team) - return; - - if (!%obj.client.enableZones) - return; - - - Game.trySetRole(%obj, Defense); -} - -function defenseZoneTrigger::onLeaveTrigger(%this, %trigger, %obj) -{ - if (!$TR2::EnableRoles) - return; - - if (!%obj.client.enableZones) - return; - - if (!Game.trySetRole(%obj, Offense)) - error("TR2 role change error: couldn't change to Offense"); -} - -datablock StaticShapeData(Goal) -{ - className = "Goal"; - catagory = "Objectives"; - shapefile = "goal_panel.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(GoalPost) -{ - className = "GoalPost"; - catagory = "Objectives"; - shapefile = "goal_side.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(GoalCrossbar) -{ - className = "GoalCrossbar"; - catagory = "Objectives"; - shapefile = "goal_top.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(GoalBack) -{ - className = "GoalBack"; - catagory = "Objectives"; - shapefile = "goal_back.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(GoldGoalPost) -{ - className = "GoalPost"; - catagory = "Objectives"; - shapefile = "gold_goal_side.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(GoldGoalCrossbar) -{ - className = "GoalCrossbar"; - catagory = "Objectives"; - shapefile = "gold_goal_top.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(GoldGoalBack) -{ - className = "GoalBack"; - catagory = "Objectives"; - shapefile = "gold_goal_back.dts"; - isInvincible = true; - needsNoPower = true; -}; - - -datablock StaticShapeData(GoldPole) -{ - className = "GoldPole"; - catagory = "Objectives"; - shapefile = "golden_pole.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(SilverPole) -{ - className = "SilverPole"; - catagory = "Objectives"; - shapefile = "silver_pole.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(Billboard1) -{ - className = "Billboard"; - catagory = "Misc"; - shapefile = "billboard_1.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(Billboard2) -{ - className = "Billboard"; - catagory = "Misc"; - shapefile = "billboard_2.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(Billboard3) -{ - className = "Billboard"; - catagory = "Misc"; - shapefile = "billboard_3.dts"; - isInvincible = true; - needsNoPower = true; -}; - -datablock StaticShapeData(Billboard4) -{ - className = "Billboard"; - catagory = "Misc"; - shapefile = "billboard_4.dts"; - isInvincible = true; - needsNoPower = true; -}; - - -function GoalCrossbar::onCollision(%this, %obj, %col) -{ - return; - if (%col.getClassName() !$= "Player") - return; - - if (getWord(%col.getPosition(), 2) > getWord(%obj.getPosition(), 2)) - { - // Ooo...the quick 1-2 punch to defeat a potential exploit - %this.nudgeObject(%obj, %col, 10); - %obj.schedule(100, "nudgeObject", %obj, %col, -70); - } -} - -function GoalCrossbar::nudgeObject(%this, %obj, %col, %vertNudge) -{ - %center = $TheFlag.originalPosition; - - // Determine if the object is on the front or back part of the crossbar - %colDist = VectorDist(%col.getPosition(), %center); - %goalDist = VectorDist(%obj.getPosition(), %center); - %nudgeDir = (%goalDist > %colDist) ? 1 : -1; - - // Nudge the player towards the center of the map - %nudgeVec = VectorNormalize($TheFlag.originalPosition); - %nudgeVec = VectorScale(%nudgeVec, %nudgeDir); - %nudgeVec = VectorScale(%nudgeVec, 40); - %nudgeVec = setWord(%nudgeVec, 2, %vertNudge); - - %col.setVelocity(%nudgeVec); -} - -datablock ForceFieldBareData(TR2defaultForceFieldBare) -{ - fadeMS = 1000; - baseTranslucency = 0.80; - powerOffTranslucency = 0.0; - teamPermiable = true; - otherPermiable = true; - color = "0.0 0.55 0.99"; - powerOffColor = "0.0 0.0 0.0"; - targetNameTag = 'Force Field'; - targetTypeTag = 'ForceField'; - - texture[0] = "skins/forcef1"; - texture[1] = "skins/forcef2"; - texture[2] = "skins/forcef3"; - texture[3] = "skins/forcef4"; - texture[4] = "skins/forcef5"; - - framesPerSec = 10; - numFrames = 5; - scrollSpeed = 15; - umapping = 1.0; - vmapping = 0.15; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Nouns.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Nouns.cs deleted file mode 100644 index 6413f0ba..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Nouns.cs +++ /dev/null @@ -1,494 +0,0 @@ - - -datablock AudioProfile(TR2TestNounDataSound) -{ - volume = 2.0; - filename = "fx/bonuses/test-NounData-wildcat.wav"; - description = AudioBIGExplosion3d; - preload = true; -}; - -// NounData components -// [Passer speed, grabber speed, grabber height] - -$NounList = new ScriptObject() { - class = NounList; -}; - -function NounList::get(%this, %a, %b, %c) -{ - return $NounList[%a, %b, %c]; -} - -$WaterNoun = new ScriptObject() { - text = "Shark's"; - value = 2; - sound = NounSharkSound; - emitter = "Optional"; - class = NounData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Ground passes -$NounList[0,0,0] = new ScriptObject() { - text = "Llama's"; - value = -1; - sound = NounLlamaSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[1,0,0] = new ScriptObject() { - text = "Turtle's"; - value = 1; - sound = NounTurtleSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[2,0,0] = new ScriptObject() { - text = "Snake's"; - value = 2; - sound = NounSnakeSound; - class = NounData; -}; - -$NounList[3,0,0] = new ScriptObject() { - text = "Iguana's"; - value = 3; - sound = NounIguanaSound; - class = NounData; -}; - -$NounList[0,1,0] = new ScriptObject() { - text = "Puppy's"; - value = 2; - sound = NounPuppySound; - class = NounData; -}; - -$NounList[1,1,0] = new ScriptObject() { - text = "Dog's"; - value = 3; - sound = NounDogSound; - class = NounData; -}; - -$NounList[2,1,0] = new ScriptObject() { - text = "Coyote's"; - value = 4; - sound = NounCoyoteSound; - class = NounData; -}; - -$NounList[3,1,0] = new ScriptObject() { - text = "Wolf's"; - value = 4; - sound = NounWolfSound; - class = NounData; -}; - -$NounList[0,2,0] = new ScriptObject() { - text = "Donkey's"; - value = 2; - sound = NounDonkeySound; - class = NounData; -}; - -$NounList[1,2,0] = new ScriptObject() { - text = "Cow's"; - value = 3; - sound = NounCowSound; - class = NounData; -}; - -$NounList[2,2,0] = new ScriptObject() { - text = "Zebra's"; - value = 3; - sound = NounZebraSound; - class = NounData; -}; - -$NounList[3,2,0] = new ScriptObject() { - text = "Horse's"; - value = 4; - sound = NounHorseSound; - class = NounData; -}; - -$NounList[0,3,0] = new ScriptObject() { - text = "Tiger's"; - value = 3; - sound = NounTigerSound; - class = NounData; -}; - -$NounList[1,3,0] = new ScriptObject() { - text = "Jaguar's"; - value = 4; - sound = NounJaguarSound; - class = NounData; -}; - -$NounList[2,3,0] = new ScriptObject() { - text = "Cougar's"; - value = 5; - sound = NounCougarSound; - class = NounData; -}; - -$NounList[3,3,0] = new ScriptObject() { - text = "Cheetah's"; - value = 6; - sound = NounCheetahSound; - class = NounData; -}; - -/////////////////////////////////////////////////////////////////////////////// -// Low passes -$NounList[0,0,1] = new ScriptObject() { - text = "Helicopter's"; - value = 2; - sound = NounHelicopterSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[1,0,1] = new ScriptObject() { - text = "Grasshopper's"; - value = 3; - sound = NounGrasshopperSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[2,0,1] = new ScriptObject() { - text = "Crow's"; - value = 3; - sound = NounCrowSound; - class = NounData; -}; - -$NounList[3,0,1] = new ScriptObject() { - text = "Bee's"; - value = 4; - sound = NounBeeSound; - class = NounData; -}; - -$NounList[0,1,1] = new ScriptObject() { - text = "Dragonfly's"; - value = 3; - sound = NounDragonflySound; - class = NounData; -}; - -$NounList[1,1,1] = new ScriptObject() { - text = "Mosquito's"; - value = 4; - sound = NounMosquitoSound; - class = NounData; -}; - -$NounList[2,1,1] = new ScriptObject() { - text = "Fly's"; - value = 4; - sound = NounFlySound; - class = NounData; -}; - -$NounList[3,1,1] = new ScriptObject() { - text = "Parakeet's"; - value = 5; - sound = NounParakeetSound; - class = NounData; -}; - -$NounList[0,2,1] = new ScriptObject() { - text = "Budgie's"; - value = 3; - sound = NounBudgieSound; - class = NounData; -}; - -$NounList[1,2,1] = new ScriptObject() { - text = "Ostrich's"; - value = 4; - sound = NounOstrichSound; - class = NounData; -}; - -$NounList[2,2,1] = new ScriptObject() { - text = "Wasp's"; - value = 4; - sound = NounWaspSound; - class = NounData; -}; - -$NounList[3,2,1] = new ScriptObject() { - text = "Hornet's"; - value = 5; - sound = NounHornetSound; - class = NounData; -}; - -$NounList[0,3,1] = new ScriptObject() { - text = "Bat's"; - value = 4; - sound = NounBatSound; - class = NounData; -}; - -$NounList[1,3,1] = new ScriptObject() { - text = "Chickadee's"; - value = 5; - sound = NounChickadeeSound; - class = NounData; -}; - -$NounList[2,3,1] = new ScriptObject() { - text = "Warnipple's"; - value = 10; - sound = NounWarnippleSound; - class = NounData; -}; - -$NounList[3,3,1] = new ScriptObject() { - text = "Special's"; - value = 12; - sound = NounSpecial1Sound; - class = NounData; -}; - - -//////////////////////////////////////////////////////////////////////////////// -// Medium-high passes -$NounList[0,0,2] = new ScriptObject() { - text = "Captain's"; - value = 4; - sound = NounCaptainSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[1,0,2] = new ScriptObject() { - text = "Major's"; - value = 5; - sound = NounMajorSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[2,0,2] = new ScriptObject() { - text = "Colonel's"; - value = 6; - sound = NounColonelSound; - class = NounData; -}; - -$NounList[3,0,2] = new ScriptObject() { - text = "General's"; - value = 7; - sound = NounGeneralSound; - class = NounData; -}; - -$NounList[0,1,2] = new ScriptObject() { - text = "Hurricane's"; - value = 5; - sound = NounHurricaneSound; - class = NounData; -}; - -$NounList[1,1,2] = new ScriptObject() { - text = "Tornado's"; - value = 6; - sound = NounHurricaneSound; - class = NounData; -}; - -$NounList[2,1,2] = new ScriptObject() { - text = "Dove's"; - value = 6; - sound = NounDoveSound; - class = NounData; -}; - -$NounList[3,1,2] = new ScriptObject() { - text = "Flamingo's"; - value = 7; - sound = NounFlamingoSound; - class = NounData; -}; - -$NounList[0,2,2] = new ScriptObject() { - text = "Goldfinch's"; - value = 6; - sound = NounGoldfinchSound; - class = NounData; -}; - -$NounList[1,2,2] = new ScriptObject() { - text = "Owl's"; - value = 6; - sound = NounOwlSound; - class = NounData; -}; - -$NounList[2,2,2] = new ScriptObject() { - text = "Pelican's"; - value = 7; - sound = NounPelicanSound; - class = NounData; -}; - -$NounList[3,2,2] = new ScriptObject() { - text = "Jet's"; - value = 8; - sound = NounJetSound; - class = NounData; -}; - -$NounList[0,3,2] = new ScriptObject() { - text = "Bluejay's"; - value = 7; - sound = NounBluejaySound; - class = NounData; -}; - -$NounList[1,3,2] = new ScriptObject() { - text = "Swallow's"; - value = 7; - sound = NounSwallowSound; - class = NounData; -}; - -$NounList[2,3,2] = new ScriptObject() { - text = "Joop's"; - value = 14; - sound = NounSpecial2Sound; - class = NounData; -}; - -$NounList[3,3,2] = new ScriptObject() { - text = "Bluenose's"; - value = 16; - sound = NounSpecial3Sound; - class = NounData; -}; - -/////////////////////////////////////////////////////////////////////////////// -// High passes -$NounList[0,0,3] = new ScriptObject() { - text = "Astronaut's"; - value = 8; - sound = NounAstronautSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[1,0,3] = new ScriptObject() { - text = "Cloud's"; - value = 9; - sound = NounCloudSound; - emitter = "Optional"; - class = NounData; -}; - -$NounList[2,0,3] = new ScriptObject() { - text = "Atmosphere's"; - value = 10; - sound = NounAtmosphereSound; - class = NounData; -}; - -$NounList[3,0,3] = new ScriptObject() { - text = "Moon's"; - value = 10; - sound = NounMoonSound; - class = NounData; -}; - -$NounList[0,1,3] = new ScriptObject() { - text = "Ozone's"; - value = 9; - sound = NounOzoneSound; - class = NounData; -}; - -$NounList[1,1,3] = new ScriptObject() { - text = "Balloon's"; - value = 10; - sound = NounBalloonSound; - class = NounData; -}; - -$NounList[2,1,3] = new ScriptObject() { - text = "Blimp's"; - value = 11; - sound = NounBlimpSound; - class = NounData; -}; - -$NounList[3,1,3] = new ScriptObject() { - text = "Zeppellin's"; - value = 12; - sound = NounZeppellinSound; - class = NounData; -}; - -$NounList[0,2,3] = new ScriptObject() { - text = "Condor's"; - value = 11; - sound = NounCondorSound; - class = NounData; -}; - -$NounList[1,2,3] = new ScriptObject() { - text = "Eagle's"; - value = 12; - sound = NounBirdOfPreySound; - class = NounData; -}; - -$NounList[2,2,3] = new ScriptObject() { - text = "Hawk's"; - value = 13; - sound = NounBirdOfPreySound; - class = NounData; -}; - -$NounList[3,2,3] = new ScriptObject() { - text = "Orlando's"; - value = 18; - sound = NounSpecial1Sound; - class = NounData; -}; - -$NounList[0,3,3] = new ScriptObject() { - text = "Falcon's"; - value = 12; - sound = NounBirdOfPreySound; - class = NounData; -}; - -$NounList[1,3,3] = new ScriptObject() { - text = "Jack's"; - value = 16; - sound = NounSpecial2Sound; - class = NounData; -}; - -$NounList[2,3,3] = new ScriptObject() { - text = "Daunt's"; - value = 20; - sound = NounSpecial3Sound; - class = NounData; -}; - -$NounList[3,3,3] = new ScriptObject() { - text = "Natural's"; - value = 22; - sound = NounSpecial1Sound; - class = NounData; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2ObserverQueue.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2ObserverQueue.cs deleted file mode 100644 index 8634915b..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2ObserverQueue.cs +++ /dev/null @@ -1,639 +0,0 @@ -// updated ObserverQueue - -// Create queue container... -if( !isObject("ObserverQueue") ) -{ - new SimGroup("ObserverQueue"); - //ObserverQueue.setPersistent(1); // whats this do..? -} - -function validateQueue() -{ - if( !$TR2::SpecLock && !$Host::TournamentMode ) - { - %active = GetActiveCount(); - %count = 12 - %active; - for( %i = 0; %i < %count && ObserverQueue.getCount() > 0; %i++ ) - { - %cl = getClientFromQueue(); - if( isObject(%cl) ) - { - Game.assignClientTeam(%cl, $MatchStarted); - Game.spawnPlayer(%cl, $MatchStarted); - reindexQueue(); - } - } - } -} - - -function getActiveCount() -{ - %count = 0; - for( %i = 0; %i < ClientGroup.getCount(); %i++) - { - %cl = ClientGroup.getObject(%i); - if( %cl.team > 0 ) - %count++; - } - return %count; -} - -function addToQueue(%client) -{ - if( %client.team > 0 ) - return 0; - if( !isObject(%client) ) - return 0; - %unique = 1; - %count = ObserverQueue.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %node = ObserverQueue.getObject(%i); - if( %node.id == %client ) - { - %unique = 0; - } - } - reindexQueue(); - if( %unique == 1 ) - { - %node = new ScriptObject() - { - id = %client.getId(); - name = %client.nameBase; - }; - ObserverQueue.add(%node); - ObserverQueue.pushToBack(%node); - } - %client.allowedToJoinTeam = 1; - reindexQueue(); - messageQueue(); - return %unique; // 0 = client already added to queue, 1 = client successfully added -} - -function removeFromQueue(%client) -{ -// if( !isObject(%client) ) -// return 0; - // we shouldn't have duplicates in the queue, but why take a chance.. - %idx = 0; - %count = ObserverQueue.getCount(); - - - for( %i = 0; %i < %count; %i++ ) - { - %node = ObserverQueue.getObject(%i); - if( %node.id == %client.getId() ) - { - ObserverQueue.pushToBack(%node); - %node.delete(); - break; - } - } - reindexQueue(); - messageQueue(); -// schedule(100, 0, "reindexQueue"); -// schedule(101, 0, "messageQueue"); - return %idx; // 0 if client not found to remove -} - -function messageQueue() -{ - %total = reindexQueue(); - %count = ObserverQueue.getCount(); - for( %i = 0; %i < %count; %i++ ) - { - %cl = ObserverQueue.getObject(%i).id; - if( !%cl.specOnly ) - { - if( %cl.queueSlot == 1 ) - messageClient(%cl, 'MsgTR2QueuePos', '\c0You are currently \c1NEXT\c0 of \c1%2\c0 in the Observer Queue.~wfx/misc/bounty_objrem2.wav', %cl.queueSlot, %total); - else - messageClient(%cl, 'MsgTR2QueuePos', '\c0You are currently \c1%1\c0 of \c1%2\c0 in the Observer Queue.', %cl.queueSlot, %total); - } - } -} - -function messageQueueClient(%client) -{ - if( %client.team != 0 ) - { - messageClient(%client, 'MsgNotObserver', '\c0You are not currently in observer mode.~wfx/powered/station_denied.wav'); - return; - } - if( %client.specOnly ) - { - messageClient(%client, 'MsgSpecOnly', '\c0You are currently in individual spectator only mode.~wfx/powered/station_denied.wav'); - return; - } - - %total = reindexQueue(); - %pos = %client.queueSlot; - - if( %pos $= "" ) - return; - - if( %pos == 1 ) - messageClient(%client, 'MsgTR2QueuePos', '\c0You are currently \c1NEXT\c0 of \c1%2\c0 in the Observer Queue.!~wfx/misc/bounty_objrem2.wav', %pos, %total); - else - messageClient(%client, 'MsgTR2QueuePos', '\c0You are currently \c1%1\c0 of \c1%2\c0 in the Observer Queue.', %pos, %total); -} - -function reindexQueue() -{ - // reassigns client 'slots' in the queue - // returns the current number of assigned 'slots' - // only people who are actively in the queue (not spec locked) are counted. - - %slot = 0; - //%count = ObserverQueue.getCount(); - for( %i = 0; %i < ObserverQueue.getCount(); %i++ ) - { - %node = ObserverQueue.getObject(%i); - %client = %node.id; - if( !isObject(%client) ) - { - error("Client " @ %client @ " does not exist!! Removing from queue."); - if( isObject(%node) ) - { - ObserverQueue.pushToBack(%node); - %node.delete(); - } - } - else - { - if( %node.id.team > 0 ) - { - ObserverQueue.pushToBack(%node); - %node.delete(); - } - else if( !%client.specOnly ) - { - %slot++; - %client.queueSlot = %slot; - } - else - { - %client.queueSlot = ""; - } - } - } - return %slot; -} - -function getClientFromQueue() -{ - reindexQueue(); - %count = ObserverQueue.getCount(); - %client = -1; - for( %i = 0; %i < %count; %i++ ) - { - %cl = ObserverQueue.getObject(%i).id; - if( %cl.queueSlot == 1 ) - { - %client = %cl; - break; - } - } - return %client; -} - -function TR2Game::forceObserver(%game, %client, %reason) -{ - //make sure we have a valid client... - if (%client <= 0 || %client.team == 0) - return; - - // TR2 - // First set to outer role (just to be safe) - %game.assignOuterMostRole(%client); - - // Then release client's role - %game.releaseRole(%client); - - // Get rid of the corpse after the force - %client.forceRespawn = true; - %client.inSpawnBuilding = true; - - // first kill this player - if(%client.player) - %client.player.scriptKill(0); - - // TR2: Fix observer timeouts; for some reason %client.player is already 0 - // in that case, so scriptKill() won't get called - if (%client.playerToDelete !$= "") - { - %client.enableZones = false; - %client.playerToDelete.delete(); - } - - if( %client.respawnTimer ) - cancel(%client.respawnTimer); - - %client.respawnTimer = ""; - - // remove them from the team rank array - %game.removeFromTeamRankArray(%client); - - // place them in observer mode - %client.lastObserverSpawn = -1; - %client.observerStartTime = getSimTime(); - %adminForce = 0; - - switch$ ( %reason ) - { - case "playerChoose": - messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); - echo(%client.nameBase@" (cl "@%client@") entered observer mode"); - %client.lastTeam = %client.team; - %client.specOnly = true; // this guy wants to sit out... - - case "AdminForce": - messageClient(%client, 'MsgClientJoinTeam', '\c2You have been forced into observer mode by the admin.', %client.name, %game.getTeamName(0), %client, 0 ); - echo(%client.nameBase@" (cl "@%client@") was forced into observer mode by admin"); - %client.lastTeam = %client.team; - %adminForce = 1; - - if($Host::TournamentMode) - { - if(!$matchStarted) - { - if(%client.camera.Mode $= "pickingTeam") - { - commandToClient( %client, 'processPickTeam'); - clearBottomPrint( %client ); - } - else - { - clearCenterPrint(%client); - %client.notReady = true; - } - } - } - - case "spawnTimeout": - messageClient(%client, 'MsgClientJoinTeam', '\c2You have been placed in observer mode due to delay in respawning.', %client.name, %game.getTeamName(0), %client, 0 ); - echo(%client.nameBase@" (cl "@%client@") was placed in observer mode due to spawn delay"); - // save the team the player was on - only if this was a delay in respawning - %client.lastTeam = %client.team; - %client.specOnly = true; // why force an afk player back into the game? - - case "specLockEnabled": - messageClient(%client, 'MsgClientJoinTeam', '\c2Spectator lock is enabled. You were automatically forced to observer.', %client.name, %game.getTeamName(0), %client, 0 ); - %client.lastTeam = %client.team; - - case "teamsMaxed": - messageClient(%client, 'MsgClientJoinTeam', '\c2Teams are at capacity. You were automatically forced to observer.', %client.name, %game.getTeamName(0), %client, 0 ); - %client.lastTeam = %client.team; - - case "gameForce": - messageClient(%client, 'MsgClientJoinTeam', '\c2You have become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); - %client.lastTeam = %client.team; - } - - // switch client to team 0 (observer) - %client.team = 0; - %client.player.team = 0; - setTargetSensorGroup( %client.target, %client.team ); - %client.setSensorGroup( %client.team ); - - // set their control to the obs. cam - %client.setControlObject( %client.camera ); - commandToClient(%client, 'setHudMode', 'Observer'); - - // display the hud - //displayObserverHud(%client, 0); - updateObserverFlyHud(%client); - - - // message everyone about this event - if( !%adminForce ) - messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2%1 has become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); - else - messageAllExcept(%client, -1, 'MsgClientJoinTeam', '\c2The admin has forced %1 to become an observer.', %client.name, %game.getTeamName(0), %client, 0 ); - - updateCanListenState( %client ); - - // call the onEvent for this game type - %game.onClientEnterObserverMode(%client); //Bounty uses this to remove this client from others' hit lists - - if( !%client.tr2SpecMode ) - { - %client.camera.getDataBlock().setMode( %client.camera, "observerFly" ); - } - else - { - if( $TheFlag.carrier.client !$= "" ) - %game.observeObject(%client, $TheFlag.carrier.client, 1); - else - %game.observeObject(%client, $TheFlag, 2); - } - -// Queuing... - if( %reason !$= "specLockEnabled" && %reason !$= "teamsMaxed" && !$Host::TournamentMode ) - { - %vacant = ((6 * 2) - getActiveCount()); - %nextCl = getClientFromQueue(); - - if( isObject(%nextCl) && %vacant > 0 && %nextCl.queueSlot <= %vacant ) - { - %game.assignClientTeam(%nextCl, $MatchStarted ); - %game.spawnPlayer(%nextCl, $MatchStarted); - } - } - addToQueue(%client); - %client.allowedToJoinTeam = 1; -} - -function TR2Game::clientJoinTeam( %game, %client, %team, %fromObs ) -{ - //%game.assignClientTeam(%client, $MatchStarted); - if( (12 - getActiveCount()) > 0 || $Host::TournamentMode ) - { - %client.allowedToJoinTeam = 1; - - //first, remove the client from the team rank array - //the player will be added to the new team array as soon as he respawns... - %game.removeFromTeamRankArray(%client); - - %pl = %client.player; - if(isObject(%pl)) - { - if(%pl.isMounted()) - %pl.getDataBlock().doDismount(%pl); - %pl.scriptKill(0); - } - - // reset the client's targets and tasks only - clientResetTargets(%client, true); - - // give this client a new handle to disassociate ownership of deployed objects - if( %team $= "" && (%team > 0 && %team <= %game.numTeams)) - { - if( %client.team == 1 ) - %client.team = 2; - else - %client.team = 1; - } - else - %client.team = %team; - - // Set the client's skin: - if (!%client.isAIControlled()) - setTargetSkin( %client.target, %game.getTeamSkin(%client.team) ); - setTargetSensorGroup( %client.target, %client.team ); - %client.setSensorGroup( %client.team ); - - // Spawn the player: - %game.spawnPlayer(%client, $MatchStarted); - - if(%fromObs $= "" || !%fromObs) - { - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 switched to team %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); - messageClient( %client, 'MsgClientJoinTeam', '\c1You switched to team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); - } - else - { - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined team %2.', %client.name, %game.getTeamName(%client.team), %client, %team ); - messageClient( %client, 'MsgClientJoinTeam', '\c1You joined team %2.', $client.name, %game.getTeamName(%client.team), %client, %client.team ); - } - - updateCanListenState( %client ); - - // MES - switch objective hud lines when client switches teams - messageClient(%client, 'MsgCheckTeamLines', "", %client.team); - logEcho(%client.nameBase@" (cl "@%client@") switched to team "@%client.team); - - - removeFromQueue(%client); - } - else - { - //error("Forced to observer: " @%client.nameBase @ " via JoinTeam"); - %game.forceObserver(%client, "gameForce"); - } -} -// if( %client.allowedToJoinTeam == 1 ) -// { -// DefaultGame::clientJoinTeam( %game, %client, %team, %respawn ); -// removeFromQueue(%client); -// } -// else -// { -// %game.forceObserver(%client, "gameForce"); -// } - - -function TR2Game::assignClientTeam(%game, %client, %respawn ) -{ - if( %client.team > 0 ) - return; - %size[0] = 0; - %size[1] = 0; - %size[2] = 0; - %leastTeam = 0; - for( %i = 0; %i < ClientGroup.getCount(); %i++ ) - { - %cl = ClientGroup.getObject(%i); - if( %cl != %client ) - %size[%cl.team]++; - } - %playing = %size[1] + %size[2]; - - if( %playing < (6 << 1) ) // HEH HEH - { - %game.removeFromTeamRankArray(%client); - %leastTeam = (%size[1] <= %size[2]) ? 1 : 2; - removeFromQueue(%client); - - %client.lastTeam = %client.team; - %client.team = %leastTeam; - - - // Assign the team skin: - if ( %client.isAIControlled() ) - { - if ( %leastTeam & 1 ) - { - %client.skin = addTaggedString( "basebot" ); - setTargetSkin( %client.target, 'basebot' ); - } - else - { - %client.skin = addTaggedString( "basebbot" ); - setTargetSkin( %client.target, 'basebbot' ); - } - } - else - setTargetSkin( %client.target, %game.getTeamSkin(%client.team) ); - - messageAllExcept( %client, -1, 'MsgClientJoinTeam', '\c1%1 joined %2.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); - messageClient( %client, 'MsgClientJoinTeam', '\c1You joined the %2 team.', %client.name, %game.getTeamName(%client.team), %client, %client.team ); - - updateCanListenState( %client ); - - clearBottomPrint(%client); // clear out the observer hud... - - echo(%client.nameBase@" (cl "@%client@") joined team "@%client.team); - //error("Assigned: " @%client.nameBase @ " to team: " @ %team @ " via AssignTeam"); - } - else - { - //error("Forced to observer: " @%client.nameBase @ " via AssignTeam"); - %game.forceObserver(%client, "teamsMaxed"); - } - // hes been checked for team join ability.. - %client.allowedToJoinTeam = 1; -} - -function TR2Game::ObserverOnTrigger(%game, %data, %obj, %trigger, %state) -{ - //trigger types: 0:fire 1:altTrigger 2:jump 3:jet 4:throw - if (!$missionRunning) - { - return false; - } - - %client = %obj.getControllingClient(); - - if (!isObject(%client)) - { - return false; - } - - // Knockdowns - // Moved up since players in the game should have a little priority over observers - // save a little execution time and effort : - if (%obj.mode $= "playerDeath") - { - if(!%client.waitRespawn && getSimTime() > %client.suicideRespawnTime) - { - commandToClient(%client, 'setHudMode', 'Standard'); - if (%client.playerToDelete !$= "") - { - %client.enableZones = false; - %client.playerToDelete.delete(); - } - - // Use current flymode rotation - %transform = %client.camera.getTransform(); - %oldTrans = %client.plyrTransformAtDeath; - %oldPos = getWord(%oldTrans, 0) SPC getWord(%oldTrans, 1) SPC getWord(%oldTrans, 2); - %newRot = getWord(%transform, 3) SPC getWord(%transform, 4) SPC getWord(%transform, 5) SPC getWord(%transform, 6); - %client.plyrTransformAtDeath = %oldPos SPC %newRot; - - Game.spawnPlayer( %client, true ); - %client.camera.setFlyMode(); - %client.setControlObject(%client.player); - } - return false; - } - - // Observer zoom - if( %obj.mode $= "followFlag" || %obj.mode $= "observerFollow" ) - { - if( %trigger == 3 ) - { - %client.obsZoomLevel++; - if (%client.obsZoomLevel >= $TR2::numObsZoomLevels) - %client.obsZoomLevel = 0; - - // Move the camera - %game.observeObject(%client, %client.observeTarget, %client.observeType); - - //%pos = %client.camera.getPosition(); - //%rot = %client.camera - return false; - } - else - return false; - } - - if( %obj.mode $= "observerFly" ) - { - // unfortunately, it seems that sometimes the "observer speed up" thing doesn't always happen... - if (%trigger == 0) - { - clearBottomPrint(%client); - return false; - } - //press JET - else if (%trigger == 3) - { - %markerObj = Game.pickObserverSpawn(%client, true); - %transform = %markerObj.getTransform(); - %obj.setTransform(%transform); - %obj.setFlyMode(); - clearBottomPrint(%client); - return false; - } - //press JUMP - else if (%trigger == 2) - { - clearBottomPrint(%client); - return false; - } - } - - if( %obj.mode $= "pre-game" ) - { - return true; // use default action - } - - if( %obj.mode $= "justJoined" ) - { - if( !$TR2::SpecLock && !$Host::TournamentMode ) - { - if( %client.team <= 0 ) - { - if( getActiveCount() < ($TR2::DefaultTeamSize * 2) ) - { - %game.assignClientTeam(%client, 0); - %game.spawnPlayer(%client, 0); - } - else - { - %game.forceObserver(%client, "teamsMaxed"); - } - } - else if( %client.team >= 1 ) - { - %game.spawnPlayer(%client, 0); - } - - if( isObject(%client.player) ) // player was successfully created... - { - if(!$MatchStarted && !$CountdownStarted) - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - else if(!$MatchStarted && $CountdownStarted) - %client.camera.getDataBlock().setMode( %client.camera, "pre-game", %client.player ); - else - { - %client.camera.setFlyMode(); - commandToClient(%client, 'setHudMode', 'Standard'); - %client.setControlObject( %client.player ); - } - } - } - else - { - // kind of weak, but tourney mode *is* a form of spec lock :/ - %game.forceObserver(%client, "specLockEnabled"); - } - return false; - } - - // Queue - if( %trigger == 0 ) - { - if( %obj.mode !$= "playerDeath" ) - { - return false; - } - } - return true; -} - - - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2OtherBonuses.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2OtherBonuses.cs deleted file mode 100644 index 14d66a3e..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2OtherBonuses.cs +++ /dev/null @@ -1,234 +0,0 @@ -// Simple bonuses - -$TR2::midairLevel[0] = 10; -$TR2::midairLevel[1] = 25; - - -function FlagBonus::evaluate(%this, %passer, %receiver, %flag) -{ - if ($TheFlag.specialPass $= "" && !%flag.onGoal) - Parent::evaluate(%this, %passer, %receiver, %flag); - - $TheFlag.specialPass = ""; -} - -//function WeaponBonus::evaluate(%this, %shooter, %victim, %damageType) -//{ -//} - -//////////////////////////////////////////////////////////////////////////////// -// Damage bonus - - -function G4Bonus::evaluate(%this, %plAttacker, %plVictim, %flag, %damageType, %damageLoc) -{ - if (%plVictim !$= %flag.carrier && %plAttacker !$= %flag.carrier) - return; - - if (%plAttacker $= "" || %plVictim $= "" || %flag.carrier $= "") - return; - - // Lock this down a bit - if (%plVictim.getSpeed() < 3) - return; - - %clAttacker = %plAttacker.client; - %clVictim = %plVictim.client; - %victimHeight = %plVictim.getHeight(); - - if (%clVictim != %clAttacker && - %damageType == $DamageType::Disc && - %victimHeight > 13) - { - if (%plVictim.isAboveSomething(25)) - return; - - // MA effect - %newEmitter = new ParticleEmissionDummy(MidairDiscEffect) { - position = %plVictim.getTransform(); - rotation = "1 0 0 0"; - scale = "0.1 0.1 0.1"; - dataBlock = "defaultEmissionDummy"; - emitter = "MidairDiscEmitter"; - velocity = "1"; - }; - %newEmitter.schedule(%newEmitter.emitter.lifetimeMS, "delete"); - - if (%plVictim == %flag.carrier) - { - //Game.playerDroppedFlag(%flag.carrier); - $TheFlag.specialPass = "MA"; - %plVictim.throwObject(%plVictim.holdingFlag); - - if (%plVictim.team == %plAttacker.team) - { - // G4 - TR2Flag::onCollision("",%flag,%plAttacker); - //%plVictim.forceRespawn = true; - %plAttacker.gogoKill = true; - %plVictim.setDamageFlash(0.75); - %plVictim.applyDamage(1); - //%plVictim.blowup(); - //Game.onClientKilled(%clVictim, 0, $DamageType::G4); - serverPlay2D(GadgetSound); - } else { - // Crazy flags here - %numFlags = mFloor(%victimHeight / 7); - if (%numFlags > 40) - %numFlags = 40; - - Game.emitFlags(%plVictim.getWorldBoxCenter(), mFloor(%victimHeight / 5), %plVictim); - - if (%numFlags >= 30) - ServerPlay2D(MA3Sound); - else if (%numFlags >= 13) - ServerPlay2D(MA2Sound); - else if (%numFlags >= 3) - ServerPlay2D(MA1Sound); - - messageAll('msgTR2MA', '%1 MA\'s %2.', %clAttacker.name, %clVictim.name); - return; - } - } - // Otherwise, Rabid Rabbit - else { - ServerPlay3D(MonsterSound, %plAttacker.getPosition()); - %plVictim.setDamageFlash(0.75); - %plVictim.applyDamage(1); - } - } - else return; - - Parent::evaluate(%this, %plAttacker, %plVictim, "", %damageType, %damageLoc, 5); -} - -function MABonus::evaluate(%this, %clAttacker, %clVictim, %damageType, %damageLoc) -{ - // MA detection - %plAttacker = %clAttacker.Player; - %plVictim = %clVictim.Player; - %victimHeight = %plVictim.getHeight(); - if (%clVictim != %clAttacker && - %damageType == $DamageType::Disc && - %victimHeight > 10) - { - // MA effect - %newEmitter = new ParticleEmissionDummy(MidairDiscEffect) { - position = %player.getTransform(); - rotation = "1 0 0 0"; - scale = "1 1 1"; - dataBlock = "defaultEmissionDummy"; - emitter = "MidairDiscEmitter"; - velocity = "1"; - }; - %newEmitter.schedule(%newEmitter.emitter.lifetimeMS, "delete"); - - if (%plVictim == $TheFlag.carrier && %plVictim.team != %plAttacker.team) - { - Game.playerDroppedFlag($TheFlag.carrier); - - // Crazy flags here - game.emitFlags(%plVictim, 10); - } - else if (%plAttacker == $TheFlag.carrier) - { - // Rabid Rabbit here - %plVictim.setDamageFlash(0.75); - %plVictim.applyDamage(1); - %plVictim.blowup(); - } - } -} - -function CollisionBonus::evaluate(%this, %obj, %col) -{ - %client = %obj.client; - if ($TheFlag.carrier.client == %client) - { - // Kidney Thief Steal - if (%client.team != %col.team) - { - if (getSimTime() - $TheFlag.lastKTS >= 3 * 1000) - { - $TheFlag.specialPass = "KTS"; - Game.playerDroppedFlag($TheFlag.carrier); - TR2Flag::onCollision("",$TheFlag,%col); - $TheFlag.lastKTS = getSimTime(); - %action = "ROBBED"; - %desc = "Kidney Thief Steal"; - %val = 5; - serverPlay3D(EvilLaughSound, %col.getPosition()); - } else return; - // Mario Grab - } else { - %carrierPos = %obj.getPosition(); - %collidedPos = %col.getPosition(); - %carrierz = getWord(%carrierPos, 2); - %collidez = getWord(%collidedPos, 2); - - // Inverse - //if (%carrierz > %collidez && %carrierz - %collidez > 2.5) - //{ - //%flagVel = $TheFlag.carrier.getVelocity(); - //Game.playerDroppedFlag($TheFlag.carrier); - //%flagx = firstWord(%flagVel) * 4; - //%flagy = getWord(%flagVel, 1) * 4; - //%flagz = getWord(%flagVel, 2); - //%flagz = %flagz + 1500; - //$TheFlag.applyImpulse($TheFlag.getPosition(), %flagx SPC %flagy SPC %flagz); - //} else - // Standard - if (%carrierz < %collidez && %collidez - %carrierz > 2.8 - && getSimTime() - $TheFlag.lastMario >= 4 * 1000) - { - $TheFlag.specialPass = "Mario"; - $TheFlag.lastMario = getSimTime(); - Game.playerDroppedFlag($TheFlag.carrier); - TR2Flag::onCollision("",$TheFlag,%col); - %action = "TROUNCED"; - %desc = "Plumber Butt"; - %val = 4; - serverPlay2D(MarioSound); - } else return; - } - } - else return; - - %this.award("", %col, %obj, %action, %desc, %val); -} - -function CreativityBonus::evaluate(%this, %variance, %player) -{ - if (%variance < %this.lastVariance) - { - %this.lastVariance = 0; - %this.lastVarianceLevel = 0; - return; - } - - if (%variance == %this.lastVariance) - return; - - %this.lastVariance = %variance; - - for(%i=%this.varianceLevels - 1; %i>0; %i--) - if (%variance >= %this.varianceThreshold[%i]) - break; - - if (%i < %this.lastVarianceLevel) - { - %this.lastVarianceLevel = 0; - return; - } - - if (%i == %this.lastVarianceLevel) - return; - - %this.lastVarianceLevel = %i; - - $teamScoreCreativity[%player.team] += %this.varianceValue[%i]; - - // Ugly..hmm - %this.schedule(1500, "award", "", %player, "", "", - "Level" SPC %i SPC "Creativity Bonus", %this.varianceValue[%i], %this.varianceSound[%i]); -} diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Packages.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Packages.cs deleted file mode 100644 index 828e827d..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Packages.cs +++ /dev/null @@ -1,1030 +0,0 @@ -package TR2Game { - -function Player::scriptKill(%player, %damageType) -{ - if (%damageType == $DamageType::suicide || - %damageType == $DamageType::RespawnAfterScoring || - %damageType == 0) - { - %player.client.forceRespawn = true; - %player.client.inSpawnBuilding = true; - %player.knockedDown = false; - } - - Parent::scriptKill(%player, %damageType); -} - -function Player::isAboveSomething(%player, %searchrange) -{ - // Borrow some deployment code to determine whether the player is - // above something. - %mask = $TypeMasks::InteriorObjectType | $TypeMasks::StaticShapeObjectType | $TypeMasks::ForceFieldObjectType; - %eyeVec = "0 0 -1";//%player.getEyeVector(); - %eyeTrans = %player.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 - return containerRayCast(%eyePos, %eyeEnd, %mask, 0); -} - -function ShapeBase::hasAmmo( %this, %weapon ) -{ - switch$ ( %weapon ) - { - // TR2 - case TR2Disc: - return( %this.getInventory( TR2DiscAmmo ) > 0 ); - case TR2GrenadeLauncher: - return( %this.getInventory( TR2GrenadeLauncherAmmo ) > 0 ); - case TR2Chaingun: - return( %this.getInventory( TR2ChaingunAmmo ) > 0); - case TR2Mortar: - return( %this.getInventory( TR2MortarAmmo ) > 0 ); - case TR2Shocklance: - return( true ); - case TR2GoldTargetingLaser: - return( false ); - case TR2SilverTargetingLaser: - return( false ); - default: - return Parent::hasAmmo(%this, %weapon); - } -} - -function ShapeBase::clearInventory(%this) -{ - // TR2 - %this.setInventory(TR2Disc,0); - %this.setInventory(TR2GrenadeLauncher,0); - %this.setInventory(TR2Chaingun,0); - %this.setInventory(TR2Mortar,0); - %this.setInventory(TR2Shocklance,0); - %this.setInventory(TR2GoldTargetingLaser,0); - %this.setInventory(TR2SilverTargetingLaser,0); - %this.setInventory(TR2DiscAmmo,0); - %this.setInventory(TR2GrenadeLauncherAmmo,0); - %this.setInventory(TR2MortarAmmo, 0); - %this.setInventory(TR2ChaingunAmmo,0); - %this.setInventory(TR2Grenade,0); - - Parent::clearInventory(%this); -} - -function serverCmdUse(%client,%data) -{ - if( %data $= Disc ) - %client.getControlObject().use(TR2Disc); - else if( %data $= GrenadeLauncher ) - %client.getControlObject().use(TR2GrenadeLauncher); - else if( %data $= Chaingun ) - %client.getControlObject().use(TR2Chaingun); - else if( %data $= Shocklance ) - %client.getControlObject().use(TR2Shocklance); - else if( %data $= Grenade ) - %client.getControlObject().use(TR2Grenade); - else if( %data $= Mortar ) - %client.getControlObject().use(TR2Mortar); - else if( %data $= TargetingLaser ) - %client.getControlObject().use((%client.team == 1) ? TR2GoldTargetingLaser : TR2SilverTargetingLaser); - // etc... - else - %client.getControlObject().use(%data); -} - -function serverCmdStartNewVote(%client, %typeName, %arg1, %arg2, %arg3, %arg4, %playerVote) -{ - parent::serverCmdStartNewVote(%client, %typeName, %arg1, %arg2, %arg3, %arg4, %playerVote); - - //if( %typeName $= "ToggleDisableDeath" && %client.isAdmin ) - // ToggleDisableDeath(%client); - - if ( %typeName $= "TogglePracticeMode" && %client.isAdmin ) - TogglePracticeMode(%client); - - if( %typeName $= "ToggleRoles" && %client.isAdmin ) - TogglePlayerRoles(%client); - - if( %typeName $= "ToggleCrowd" && %client.isAdmin ) - ToggleCrowd(%client); - - if( %typeName $= "getQueuePos" ) - { - messageQueueClient(%client); - } - if( %typeName $= "toggleSpecLock" && %client.isAdmin ) - { - toggleSpectatorLock(%client); - } - - if( %typeName $= "toggleSpecOnly" ) - toggleSpecOnly(%client); - - if( %typeName $= "toggleSpecMode" ) - toggleSpectatorMode(%client); - - if( %typeName $= "tr2JoinGame" ) - { - reindexQueue(); - if( !$TR2::SpecLock && %client.queueSlot !$= "" && %client.queueSlot <= ((6 * 2) - getActiveCount()) ) - { - Game.assignClientTeam(%client); - Game.spawnPlayer(%client, $MatchStarted); - } - } - if( %typeName $= "tr2ForceFlagReturn" ) - { - if( %client.isAdmin && $TheFlag.carrier $= "" && (getSimTime() - $TheFlag.dropTime) >= 30000 ) - { - messageAll('MsgAdminForce', '\c0%1 forced the flag to return to the stand.', %client.name); - Game.flagReturn($TheFlag, 0); - } - } -} - -function toggleSpectatorMode(%client) -{ - if( %client.team <= 0 ) - { - %client.tr2SpecMode = !%client.tr2SpecMode; - if( %client.tr2SpecMode ) - { - %target = $TheFlag.carrier $= "" ? $TheFlag : $TheFlag.carrier.client; - %type = $TheFlag.carrier $= "" ? 2 : 1; - Game.observeObject(%client, %target, %type); - } - else - { - if( %client.camera.mode !$= "observerFly" ) - %client.camera.getDataBlock().setMode(%client.camera, "observerFly"); - } - } -} - -function toggleSpectatorLock(%client) -{ - $TR2::SpecLock = !$TR2::SpecLock; - %status = $TR2::SpecLock ? "locked spectators in observer mode." : "enabled the spectator queue."; - messageAll('MsgAdminForce', '\c0%1 %2.', %client.name, %status); -} - -function toggleSpecOnly(%client) -{ - %time = getSimTime() - %client.specOnlyTime; - if( %time > 10000 ) - { - %client.specOnly = !%client.specOnly; - %status = %client.specOnly ? "You have locked yourself as a spectator." : "You have entered the queue."; - messageClient(%client, 'MsgAdminForce', '\c2%1', %status); - reindexQueue(); - messageQueueClient(%client); - %client.specOnlyTime = getSimTime(); - - %vacant = ((6 * 2) - getActiveCount()); - if( !%client.specOnly && %vacant > 0 && %client.queueSlot <= %vacant ) - { - Game.assignClientTeam(%client, 0); - Game.spawnPlayer(%client, 0); - } - } - else - messageClient(%client, 'MsgTR2Wait', '\c0You must wait %1 seconds before using this option again!~wfx/powered/station_denied.wav', mFloor((10000 - %time)/1000) ); -} - -function TogglePlayerRoles(%client) -{ - $TR2::EnableRoles = !$TR2::EnableRoles; - %status = $TR2::EnableRoles ? "enabled player roles." : "disabled player roles."; - messageAll('MsgAdminForce', '\c2%1 %2', %client.name, %status); -} - -function ToggleCrowd(%client) -{ - if ($TR2::EnableCrowd) - Game.stopCrowd(); - - $TR2::EnableCrowd = !$TR2::EnableCrowd; - %status = $TR2::EnableCrowd ? "enabled the crowd." : "disabled the crowd"; - messageAll('MsgAdminForce', '\c2%1 %2', %client.name, %status); -} - -function ToggleDisableDeath(%client) -{ - $TR2::DisableDeath = !$TR2::DisableDeath; - %status = $TR2::DisableDeath ? "disabled Death." : "enabled Death."; - messageAll('MsgAdminForce', '\c2%1 %2', %client.name, %status); - - // Reset all players' knockdown status - for(%i = 0; %i < ClientGroup.getCount(); %i ++) - { - %cl = ClientGroup.getObject(%i); - %cl.knockedDown = false; - cancel(%cl.knockdownThread); - } -} - -function TogglePracticeMode(%client) -{ - $TR2::PracticeMode = !$TR2::PracticeMode; - %status = $TR2::PracticeMode ? "enabled Practice Mode." : "disabled Practice Mode."; - messageAll('MsgAdminForce', '\c2%1 %2', %client.name, %status); -} - -function Flag::shouldApplyImpulse(%data, %obj) -{ - // TR2: Get rid of flag discing - return false; -} - -function TR2ShockLanceImage::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 ) - { - // TR2: Don't allow friendly lances - if (%obj.team == %hitobj.team) - return; - - %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; - } - } - - %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); - - } -} - - -function Armor::onCollision(%this,%obj,%col,%forceVehicleNode) -{ - // Don't allow corpse looting - %dataBlock = %col.getDataBlock(); - %className = %dataBlock.className; - if (%className $= "Armor") - if (%col.getState() $= "Dead") - return; - - Parent::onCollision(%this, %obj, %col, %forceVehicleNode); - - if (%obj.getState() $= "Dead") - return; - - %obj.delayRoleChangeTime = getSimTime(); - - %dataBlock = %col.getDataBlock(); - %className = %dataBlock.className; - %client = %obj.client; - if (%className $= "Armor") - { - if (%col.getState() $= "Dead" || %obj.invincible) - return; - - CollisionBonus.evaluate(%obj, %col); - } -} - -function Armor::onDisabled(%this, %obj, %state) -{ - Game.assignOutermostRole(%obj.client); - if (!$TR2::DisableDeath || %obj.client.forceRespawn) - Parent::onDisabled(%this, %obj, %state); -} - -function Armor::damageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC) -{ - //echo("Armor::damageObject() (targetClient = " @ getTaggedString(%targetObject.client.name) @ ")"); - //echo("Armor::damageObject() (sourceClient = " @ getTaggedString(%sourceObject.client.name) @ ")"); - //echo("Armor::damageObject() (sourceObj = " @ %sourceObject @ ")"); - - if (Game.goalJustScored) - return; - - //if (%sourceObject == 0) - //{ - //%targetObject.schedule(2, "setDataBlock", TR2HeavyMaleHumanArmor); - %targetObject.delayRoleChangeTime = getSimTime(); - //} - return Parent::DamageObject(%data, %targetObject, %sourceObject, %position, %amount, %damageType, %momVec, %mineSC); -} - -function ShapeBase::getHeight(%this) -{ - %z = getWord(%this.getPosition(), 2); - return (%z - getTerrainHeight(%this.getPosition())); -} - -function ShapeBase::getSpeed(%this) -{ - return (VectorLen(%this.getVelocity())); -} - -function ShapeBase::isOutOfBounds(%this) -{ - %shapePos = %this.getPosition(); - %shapex = firstWord(%shapePos); - %shapey = getWord(%shapePos, 1); - %bounds = MissionArea.area; - %boundsWest = firstWord(%bounds); - %boundsNorth = getWord(%bounds, 1); - %boundsEast = %boundsWest + getWord(%bounds, 2); - %boundsSouth = %boundsNorth + getWord(%bounds, 3); - - return (%shapex < %boundsWest || %shapex > %boundsEast || - %shapey < %boundsNorth || %shapey > %boundsSouth); -} - -function ShapeBase::bounceOffGrid(%this, %bounceForce) -{ - if (%bounceForce $= "") - %bounceForce = 85; - - %oldVel = %this.getVelocity(); - %this.setVelocity("0 0 0"); - - %vecx = firstWord(%oldVel); - %vecy = getWord(%oldVel, 1); - %vecz = getWord(%oldVel, 2); - - %shapePos = %this.getPosition(); - %shapex = firstWord(%shapePos); - %shapey = getWord(%shapePos, 1); - %bounds = MissionArea.area; - %boundsWest = firstWord(%bounds); - %boundsNorth = getWord(%bounds, 1); - %boundsEast = %boundsWest + getWord(%bounds, 2); - %boundsSouth = %boundsNorth + getWord(%bounds, 3); - - // Two cases: 1) object is at E or W side; 2) object is at N or S side - if((%shapex <= %boundsWest) || (%shapex >= %boundsEast)) - %vecx = -%vecx; - else - %vecy = -%vecy; - - %vec = %vecx SPC %vecy SPC %vecz; - - // normalize the vector, scale it - //%vecNorm = VectorNormalize(%vec); - //%vec = VectorScale(%vecNorm, 100 * %bounceForce); - - // If the object's speed was pretty slow, give it a boost - %oldSpeed = VectorLen(%oldVel); - if (%oldSpeed < $TR2_MinimumGridBoost) - { - %vec = VectorNormalize(%vec); - %vec = VectorScale(%vec, $TR2_MinimumGridBoost); - } - else - %vec = VectorScale(%vec, $TR2_GridVelocityScale); - - // apply the impulse to the flag object - //%this.applyImpulse(%this.getWorldBoxCenter(), %vec); - %this.setVelocity(%vec); -} - -function Observer::setMode(%data, %obj, %mode, %targetObj) -{ - if(%mode $= "") - return; - - %client = %obj.getControllingClient(); - - %obsVector = $TR2_playerObserveParameters; - - if (%client > 0 && %client.obsZoomLevel !$= "") - %zoomLevel = %client.obsZoomLevel; - else - %zoomLevel = 0; - %obsVector = VectorScale(%obsVector, $TR2::ObsZoomScale[%zoomLevel]); - - %obsx = getWord(%obsVector, 0); - %obsy = getWord(%obsVector, 1); - %obsz = getWord(%obsVector, 2); - - switch$ (%mode) { - case "justJoined": - commandToClient(%client, 'setHudMode', 'Observer'); - %markerObj = Game.pickObserverSpawn(%client, true); - %transform = %markerObj.getTransform(); - %obj.setTransform(%transform); - %obj.setFlyMode(); - - case "followFlag": - // Follow the dropped flag (hopefully) - %position = %targetObj.getPosition(); - %newTransform = %position SPC %client.lastObsRot; - %obj.setOrbitMode(%targetObj, %newTransform, %obsx, %obsy, %obsz); - //%obj.setOrbitMode(%targetObj, %targetObj.getTransform(), %obsx, %obsy, %obsz); - %obj.mode = %mode; - - - case "pre-game": - commandToClient(%client, 'setHudMode', 'Observer'); - %obj.setOrbitMode( %targetObj, %targetObj.getTransform(), %obsx, %obsy, %obsz); - - case "observerFollow": - // Observer attached to a moving object (assume player for now...) - %position = %targetObj.getPosition(); - %transform = %position SPC %client.lastObsRot; - - //%obj.setOrbitMode(%targetObj, %newTransform, %obsx, %obsy, %obsz); - //%transform = %targetObj.getTransform(); - - if( !%targetObj.isMounted() ) - %obj.setOrbitMode(%targetObj, %transform, %obsx, %obsy, %obsz); - 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 "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 "observerTimeout": - commandToClient(%client, 'setHudMode', 'Observer'); - %markerObj = Game.pickObserverSpawn(%client, true); - %transform = %markerObj.getTransform(); - %obj.setTransform(%transform); - %obj.setFlyMode(); - } - %obj.mode = %mode; -} - -function ShapeBaseImageData::onFire(%data, %obj, %slot) -{ - //if (Game.goalJustScored) - // return; - - %data.lightStart = getSimTime(); - - // TR2: No need for cloak logic - //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 ); - // } - // } - //} - - // TR2: Delay the disabling of invincibility to allow one free disc jump - if( %obj.client > 0 ) - { - %obj.setInvincibleMode(0 ,0.00); - %obj.schedule(200, "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; - } - if(%data.projectileSpread) - { - %vector = %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, %vector); - - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %vector; - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - vehicleObject = %vehicle; - }; - } - else - { - %p = new (%data.projectileType)() { - dataBlock = %data.projectile; - initialDirection = %obj.getMuzzleVector(%slot); - initialPosition = %obj.getMuzzlePoint(%slot); - sourceObject = %obj; - sourceSlot = %slot; - vehicleObject = %vehicle; - }; - // echo("blah"); - } - - 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); - return %p; -} - -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.passingScore + %cl.receivingScore; - Game.teamCount[%team]++; - } -} - -// Ugly, non-gametype specific code to deal with tourney mode :/ -function serverCmdClientPickedTeam( %client, %option ) -{ - if( Game.class $= "TR2Game" && %client.lastTeam <= 0 ) - { - Game.forceObserver( %client, "playerChoose" ); - return; - } - - 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; - } - // End z0dd - ZOD - // ------------------------------------------------------------------------------------ - 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 ) -{ - if( Game.class $= "TR2Game" ) - { - if( %client.lastTeam > 0 ) - schedule( 0, 0, "commandToClient", %client, 'pickTeamMenu', Game.getTeamName(1), Game.getTeamName(2)); - } - else - { - %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 Beacon::onUse(%data, %obj) -{ - // look for 3 meters along player's viewpoint for interior or terrain - // TR2: increased - //%searchRange = 3.0; - %searchRange = 5.2; - %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); - 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() $= TR2DeployedBeacon) - 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, TargetBeacon] >= $TeamDeployableMax[TargetBeacon]) - //{ - // 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; - - // TR2: T1-style beacon stop - %playerSpeed = %obj.getSpeed(); - if (%obj.isJetting) - %obj.setVelocity("0 0 " @ %playerSpeed * $TR2_beaconStopScale); - else - %obj.setVelocity("0 0 0"); - if (%playerSpeed > 17) - serverPlay3D(CarScreechSound, %obj.getPosition()); - - %obj.decInventory(%data, 1); - %depBeac = new BeaconObject() { - dataBlock = "DeployedBeacon"; - position = VectorAdd(%terrPt, VectorScale(%terrNrm, 0.05)); - rotation = %rotation; - }; - //$TeamDeployedCount[%obj.team, TargetBeacon]++; - - // TR2: Auto-delete beacon - %depBeac.startFade(2 * 1000, 0, true); - %depBeac.schedule(3 * 1000, "delete"); - - - %depBeac.playThread($AmbientThread, "ambient"); - %depBeac.team = %obj.team; - %depBeac.sourceObject = %obj; - - // give it a team target - %depBeac.setTarget(%depBeac.team); - MissionCleanup.add(%depBeac); -} - -function ShapeBase::throwObject(%this,%obj) -{ - //if the object is being thrown by a corpse, use a random vector - if (%this.getState() $= "Dead" && %obj.getDataBlock().getName() !$= "TR2Flag1" ) - { - %vec = (-1.0 + getRandom() * 2.0) SPC (-1.0 + getRandom() * 2.0) SPC getRandom(); - %vec = vectorScale(%vec, 10); - } - - // else Initial vel based on the dir the player is looking - else - { - %eye = %this.getEyeVector(); - %vec = vectorScale(%eye, 20); - } - - // Add player's velocity - %vec = vectorAdd(%vec, %this.getVelocity()); - %pos = getBoxCenter(%this.getWorldBox()); - - // Add a vertical component to give the item a better arc - %dot = vectorDot("0 0 1",%eye); - if (%dot < 0) - %dot = -%dot; - - - - //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() $= "TR2Flag1") - { - // Add the throw strength, which ranges from 0.2 - 1.2 - // Make it range from 0 - 1 - //%addedStrength = %this.flagThrowStrength/1.25 - 0.2; - %addedStrength = %this.flagThrowStrength - 0.2; - %addedStrength *= $TR2_FlagThrowScale; - - %vec = vectorAdd(%vec,vectorScale("0 0 " @ $TR2_UpwardFlagThrust,1 - %dot)); - %flagVel = %this.getVelocity(); - %playerRot = %this.getEyeVector(); - %testDirection = VectorDot(VectorNormalize(%playerVel), VectorNormalize(%playerRot)); - //%flagVel = VectorScale(%flagVel, 50); - %playerVel = VectorNormalize(%this.getVelocity()); - if (%obj.oneTimer) - { - %playerVel = VectorScale(%playerVel, $TR2_PlayerVelocityAddedToFlagThrust / 1.3); - %addedStrength *= 1.1; - //%obj.oneTimer = 0; - } - else - %playerVel = VectorScale(%playerVel, $TR2_PlayerVelocityAddedToFlagThrust); - %playerRot = VectorScale(%playerRot, $TR2_ForwardFlagThrust * %addedStrength); - //%pos = VectorAdd(VectorNormalize(%playerRot), %this.getPosition()); - - %vec = VectorAdd(%vec, %playerVel); - %vec = VectorAdd(%vec, %playerRot); - - - // Don't apply the velocity impulse if the player is facing one direction - // but travelling in the other - //if (%testDirection > -0.85) - %newVel = VectorAdd(%playerVel, %newVel); - - // apply the impulse to the flag object - //%flag.applyImpulse(%flag.getPosition(), %newVel); - %vec = vectorScale(%vec, $TR2_GeneralFlagBoost); - //%vec = %newVel; - //echo("applying flag impulse: " @ %vec); - - // Remember the throw velocity in case T2's flag re-catch bug rears - // its ugly head, and we need to re-boost it - //%obj.throwVelocity = %vec; - - // Try adjust the flag to start further away from the player in order to - // bypass T2's re-catch bug - %extend = VectorScale(VectorNormalize(%this.getEyeVector()), 2); - %pos = VectorAdd(%extend, %pos); - - %this.throwStrength = 0; - } - - %obj.setTransform(%pos); - %obj.applyImpulse(%pos,%vec); - %obj.setCollisionTimeout(%this); - %data = %obj.getDatablock(); - %data.onThrow(%obj,%this); - - //call the AI hook - //AIThrowObject(%obj); -} - -// classic hoses this up. -// using the grenade throw from 24834 -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); - - %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 4", 1 - %dot)); - - // add player's velocity - %vec = vectorAdd(%vec, vectorScale(%obj.getVelocity(), 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; - } -} - -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Particles.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Particles.cs deleted file mode 100644 index 00730a3d..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Particles.cs +++ /dev/null @@ -1,202 +0,0 @@ -datablock ParticleData(TR2FlagParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = 0.3; - inheritedVelFactor = 0.8; - constantAcceleration = 0.3; - lifetimeMS = 5000; - lifetimeVarianceMS = 50; - textureName = "special/Smoke/bigSmoke"; // special/Smoke/bigSmoke special/droplet - colors[0] = "0.5 0.25 0 1"; - colors[1] = "0 0.25 0.5 1"; - sizes[0] = 0.80; - sizes[1] = 0.60; -}; - -datablock ParticleEmitterData(TR2FlagEmitter) -{ - ejectionPeriodMS = 75; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 5; - phiReferenceVel = 0; - phiVariance = 360; - lifetimeMS = 5000; - overrideAdvances = false; - particles = "TR2FlagParticle"; -}; - -datablock ParticleData(GridjumpParticle) -{ - dragCoefficient = 0; - gravityCoefficient = -0.017094; - inheritedVelFactor = 0.0176125; - constantAcceleration = -1.1129; - lifetimeMS = 258; - lifetimeVarianceMS = 60; - useInvAlpha = 1; - spinRandomMin = -200; - spinRandomMax = 200; - textureName = "special/Smoke/smoke_001"; - colors[0] = "0.000000 0.877165 0.000000 1.000000"; - colors[1] = "0.181102 0.981102 0.181102 1.000000"; - colors[2] = "0.000000 0.800000 0.000000 0.000000"; - colors[3] = "1.000000 1.000000 1.000000 1.000000"; - sizes[0] = 0.991882; - sizes[1] = 2.99091; - sizes[2] = 4.98993; - sizes[3] = 1; - times[0] = 0; - times[1] = 0.2; - times[2] = 1; - times[3] = 2; -}; - -datablock ParticleEmitterData(GridjumpEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 100.25; - velocityVariance = 0.25; - ejectionOffset = 0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = 0; - orientParticles= 0; - orientToNormal = 0; - orientOnVelocity = 1; - particles = "GridjumpParticle"; - lifetimeMS = 1000; -}; - -datablock ParticleData(MidairDiscParticle) -{ - dragCoefficient = 0; - gravityCoefficient = -0.017094; - inheritedVelFactor = 0.0176125; - constantAcceleration = -1.1129; - lifetimeMS = 2258; - lifetimeVarianceMS = 604; - useInvAlpha = 1; - spinRandomMin = -200; - spinRandomMax = 200; - textureName = "special/Smoke/smoke_001"; - colors[0] = "0.000000 0.077165 0.700000 1.000000"; - colors[1] = "0.181102 0.181102 0.781102 1.000000"; - colors[2] = "0.000000 0.000000 0.600000 0.000000"; - colors[3] = "1.000000 1.000000 1.000000 1.000000"; - sizes[0] = 0.991882; - sizes[1] = 2.99091; - sizes[2] = 4.98993; - sizes[3] = 1; - times[0] = 0; - times[1] = 0.2; - times[2] = 1; - times[3] = 2; -}; - -datablock ParticleEmitterData(MidairDiscEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 10.25; - velocityVariance = 0.25; - ejectionOffset = 0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = 0; - orientParticles= 0; - orientToNormal = 0; - orientOnVelocity = 1; - lifetimeMS = 1000; - particles = "MidairDiscParticle"; -}; - -datablock ParticleData(CannonParticle) -{ - dragCoefficient = 0; - gravityCoefficient = -0.017094; - inheritedVelFactor = 0.0176125; - constantAcceleration = -1.1129; - lifetimeMS = 258; - lifetimeVarianceMS = 60; - useInvAlpha = 1; - spinRandomMin = -200; - spinRandomMax = 200; - textureName = "special/Smoke/smoke_001"; - colors[0] = "0.000000 0.0 0.000000 1.000000"; - colors[1] = "0.181102 0.181102 0.181102 1.000000"; - colors[2] = "0.8000000 0.800000 0.800000 0.000000"; - colors[3] = "1.000000 1.000000 1.000000 1.000000"; - sizes[0] = 2.991882; - sizes[1] = 4.99091; - sizes[2] = 6.98993; - sizes[3] = 1; - times[0] = 0; - times[1] = 0.2; - times[2] = 1; - times[3] = 2; -}; - -datablock ParticleEmitterData(CannonEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 20.25; - velocityVariance = 0.5; - ejectionOffset = 0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = 0; - orientParticles= 0; - orientToNormal = 0; - orientOnVelocity = 1; - particles = "CannonParticle"; - lifetimeMS = 2500; -}; - -datablock ParticleData( RoleChangeParticle ) -{ - dragCoefficient = 0; - gravityCoefficient = -1.0; - inheritedVelFactor = 0.2; - constantAcceleration = -1.4; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 10.5; - sizes[1] = 30.2; - sizes[2] = 30.2; - times[0] = 0.0; - times[1] = 0.15; - times[2] = 0.2; -}; - -datablock ParticleEmitterData( RoleChangeEmitter ) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 10; - velocityVariance = 0.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 800; - particles = "RoleChangeParticle"; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Penalties.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Penalties.cs deleted file mode 100644 index cbf4bd01..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Penalties.cs +++ /dev/null @@ -1,7 +0,0 @@ -// Penalties - -new ScriptObject(TeamkillPenalty) -{ -}; - - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Physics.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Physics.cs deleted file mode 100644 index c556b61f..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Physics.cs +++ /dev/null @@ -1,653 +0,0 @@ -// Flag physics -$TR2_UpwardFlagThrust = 23; -$TR2_ForwardFlagThrust = 42.3; -$TR2_GeneralFlagBoost = 22.4; -$TR2_PlayerVelocityAddedToFlagThrust = 32; -$TR2_FlagFriction = 0.7;//0.7;//1.3; -$TR2_FlagMass = 30; -$TR2_FlagDensity = 0.25; -$TR2_FlagElasticity = 0.1;//0.2; - -// This controls the range of possible strengths -$TR2_FlagThrowScale = 3.0; - -$TR2::Gravity = -43;//-41; - -// Misc -$TR2_BeaconStopScale = 0.7; - -// Grid -$TR2_MinimumGridBoost = 80; -$TR2_GridVelocityScale = 1.15; -$TR2_MaximumGridSpeed = 310; - -// Player camera -$TR2_player3rdPersonDistance = 7; -$TR2_playerObserveParameters = "1.0 18.0 18.0"; - -// Player physics (light armor only) -$TR2_playerNoFrictionOnSki = true; -$TR2_playerMass = 130; -$TR2_playerDrag = 0.003;//0.2; // -$TR2_playerMaxdrag = 0.005;//0.4; -$TR2_playerDensity = 1.2;//10; -$TR2_playerRechargeRate = 0.251;//0.256; -$TR2_playerJetForce = 7030;//4000;//26.21 * 90; -$TR2_playerUnderwaterJetForce = 5800;//26.21 * 90 * 1.75; -$TR2_playerUnderwaterVertJetFactor = 1.0;//1.5; -$TR2_playerJetEnergyDrain = 0.81;//0.8; -$TR2_playerUnderwaterJetEnergyDrain = 0.5;//0.6; -$TR2_playerMinJetEnergy = 5;//1; -$TR2_playerMaxJetHorizontalPercentage = 0.8;//0.8; -$TR2_playerRunForce = 12500;//12400;//4500;//55.20 * 90; -$TR2_playerMaxForwardSpeed = 25;//16;//15; -$TR2_playerMaxBackwardSpeed = 23;//16;//13; -$TR2_playerMaxSideSpeed = 23;//16;//13; -$TR2_playerMaxUnderwaterForwardSpeed = 16; -$TR2_playerMaxUnderwaterBackwardSpeed = 15; -$TR2_playerMaxUnderwaterSideSpeed = 15; -$TR2_playerJumpForce = 1800;//8.3 * 90; -$TR2_playerRecoverDelay = 0;//9; -$TR2_playerRecoverRunForceScale = 2;//1.2; -$TR2_playerMinImpactSpeed = 75;//45; -$TR2_playerSpeedDamageScale = 0.001;//0.004; -$TR2_playerBoundingBox = "2.4 2.1 4.6";//"3 3 4.0";//"1.2 1.2 2.3"; -$TR2_playerRunSurfaceAngle = 90;//70; -$TR2_playerJumpSurfaceAngle = 90;//80; -$TR2_playerMinJumpSpeed = 600; -$TR2_playerMaxJumpSpeed = 700;//30; -$TR2_playerHorizMaxSpeed = 10000; -$TR2_playerHorizResistSpeed = 10000;//200;//445;//33 * 1.15; -$TR2_playerHorizResistFactor = 0.0;//0.15;//0.35; -$TR2_playerMaxJetForwardSpeed = 50;//57;//42;//30 * 1.5; -$TR2_playerUpMaxSpeed = 10000;//80; -$TR2_playerUpResistSpeed = 38;//200;//150;//25; -$TR2_playerUpResistFactor = 0.05;//0.15;//0.55;//0.30; - -// Unused -$TR2_ForwardHandGrenadeThrust = 0; - -$StaticTSObjects[$NumStaticTSObjects] = "PlayerArmors TR2LightMaleHumanArmorImage TR2light_male.dts"; -$NumStaticTSObjects++; -$StaticTSObjects[$NumStaticTSObjects] = "PlayerArmors TR2LightFemaleHumanArmorImage TR2light_female.dts"; -$NumStaticTSObjects++; - -exec("scripts/TR2light_male.cs"); -exec("scripts/TR2light_female.cs"); -exec("scripts/TR2medium_male.cs"); -exec("scripts/TR2medium_female.cs"); -exec("scripts/TR2heavy_male.cs"); - -datablock AudioProfile(TR2SkiAllSoftSound) -{ - filename = "fx/armor/TR2ski_soft.wav"; - description = AudioClose3d; - preload = true; -}; - -datablock PlayerData(TR2LightMaleHumanArmor) : LightPlayerDamageProfile -{ - // KP: Use this to turn ski friction on and off - noFrictionOnSki = $TR2_playerNoFrictionOnSki; - - emap = true; - //offset = $TR2_playerOffset; - - className = Armor; - shapeFile = "TR2light_male.dts"; - cameraMaxDist = $TR2_player3rdPersonDistance; - computeCRC = false; - - canObserve = true; - cmdCategory = "Clients"; - cmdIcon = CMDPlayerIcon; - cmdMiniIconName = "commander/MiniIcons/TR2com_player_grey"; - //targetTypeTag = 'Flag'; - - hudImageNameFriendly[0] = "gui/TR2hud_playertriangle"; - hudImageNameEnemy[0] = "gui/TR2hud_playertriangle_enemy"; - hudRenderModulated[0] = true; - hudRenderAlways[0] = true; - hudRenderCenter[0] = false; - - hudImageNameFriendly[1] = "commander/MiniIcons/TR2com_flag_grey"; - hudImageNameEnemy[1] = "commander/MiniIcons/TR2com_flag_grey"; - hudRenderModulated[1] = true; - hudRenderAlways[1] = true; - hudRenderCenter[1] = true; - hudRenderDistance[1] = true; - - hudImageNameFriendly[2] = "commander/MiniIcons/TR2com_flag_grey"; - hudImageNameEnemy[2] = "commander/MiniIcons/TR2com_flag_grey"; - hudRenderModulated[2] = true; - hudRenderAlways[2] = true; - hudRenderCenter[2] = true; - hudRenderDistance[2] = true; - - cameraDefaultFov = 97.0; - cameraMinFov = 5.0; - cameraMaxFov = 120.0; - - debrisShapeName = "debris_player.dts"; - debris = playerDebris; - - aiAvoidThis = true; - - minLookAngle = -1.5;//-1.5; - maxLookAngle = 1.5;//1.5; - maxFreelookAngle = 3.5;//3.0; - - // KP: Mass affects all forces...very important - mass = $TR2_playerMass;//90; - - // KP: Drag affects movement through liquids - drag = $TR2_playerDrag; - maxdrag = $TR2_playerMaxDrag; - - // KP: Density affects water buoyancy...water skiing is back! - density = $TR2_playerDensity;//10; - - maxDamage = 0.62; - maxEnergy = 60;//60; - repairRate = 0.0033; - energyPerDamagePoint = 70.0; // shield energy required to block one point of damage - - // KP: How fast your jets will charge - rechargeRate = $TR2_playerRechargeRate; - - // KP: The force of your jets (critically important) - jetForce = $TR2_playerJetForce; - - underwaterJetForce = $TR2_playerUnderwaterJetForce; - underwaterVertJetFactor = $TR2_playerUnderwaterVertJetFactor; - - // KP: How quickly your energy drains - jetEnergyDrain = $TR2_playerJetEnergyDrain; - - underwaterJetEnergyDrain = $TR2_playerUnderwaterJetEnergyDrain; - - // KP: Minimum amount of energy you need in order to jet - minJetEnergy = $TR2_playerminJetEnergy; - - // KP: Percentage of jets applied to strafing - maxJetHorizontalPercentage = $TR2_playerMaxJetHorizontalPercentage; - - // KP: This seems to affect the speed at which you can come to a stop, but if - // it's too low, you slide all around the terrain. - runForce = $TR2_playerRunForce; - - runEnergyDrain = 0; - minRunEnergy = 0; - - // KP: These are your walking speeds - maxForwardSpeed = $TR2_playerMaxForwardSpeed; - maxBackwardSpeed = $TR2_playerMaxBackwardSpeed; - maxSideSpeed = $TR2_playerMaxSideSpeed; - - maxUnderwaterForwardSpeed = $TR2_playerMaxUnderwaterForwardSpeed; - maxUnderwaterBackwardSpeed = $TR2_playerMaxUnderwaterBackwardSpeed; - maxUnderwaterSideSpeed = $TR2_playerMaxUnderwaterSideSpeed; - - // KP: Your jump force - jumpForce = $TR2_playerJumpForce; - - jumpEnergyDrain = 0; - minJumpEnergy = 0; - jumpDelay = 0; - - // KP: Not 100% sure what this is...looking at Torque, it seems to affect - // your momentum when you land heavily on terrain - recoverDelay = $TR2_playerRecoverDelay; - recoverRunForceScale = $TR2_playerRecoverRunForceScale; - - // KP: This controls the damage that you take on impact (most important for - // inserting another degree of skill into skiing) - minImpactSpeed = $TR2_playerMinImpactSpeed; - speedDamageScale = $TR2_playerSpeedDamageScale; - - jetSound = ArmorJetSound; - wetJetSound = ArmorJetSound; - jetEmitter = HumanArmorJetEmitter; - jetEffect = HumanArmorJetEffect; - - boundingBox = $TR2_playerBoundingBox; - pickupRadius = 1.5;//0.75; - - // damage location details - boxNormalHeadPercentage = 0.83; - boxNormalTorsoPercentage = 0.49; - boxHeadLeftPercentage = 0; - boxHeadRightPercentage = 1; - boxHeadBackPercentage = 0; - boxHeadFrontPercentage = 1; - - //Foot Prints - decalData = LightMaleFootprint; - decalOffset = 0.25; - - footPuffEmitter = LightPuffEmitter; - footPuffNumParts = 15; - footPuffRadius = 0.25; - - dustEmitter = LiftoffDustEmitter; - - splash = PlayerSplash; - splashVelocity = 4.0; - splashAngle = 67.0; - splashFreqMod = 300.0; - splashVelEpsilon = 0.60; - bubbleEmitTime = 0.4; - splashEmitter[0] = PlayerFoamDropletsEmitter; - splashEmitter[1] = PlayerFoamEmitter; - splashEmitter[2] = PlayerBubbleEmitter; - mediumSplashSoundVelocity = 10.0; - hardSplashSoundVelocity = 20.0; - exitSplashSoundVelocity = 5.0; - - // Controls over slope of runnable/jumpable surfaces - // KP: This seems to control your "stickiness" to surfaces. Can affect the - // fluidity of skiing when friction is enabled. Best used in - // conjunction with runForce. - runSurfaceAngle = $TR2_playerRunSurfaceAngle; - jumpSurfaceAngle = $TR2_playerJumpSurfaceAngle; - - // KP: These don't seem to have an obvious effect, but might be useful - minJumpSpeed = $TR2_playerMinJumpSpeed; - maxJumpSpeed = $TR2_playerMaxJumpSpeed; - - // KP: Max speed settings including resistance. High resistSpeed seems to - // result in faster movement. resistFactor determines the magnitude of - // the resistance. - horizMaxSpeed = $TR2_playerHorizMaxSpeed; - horizResistSpeed = $TR2_playerHorizResistSpeed; - horizResistFactor = $TR2_playerHorizResistFactor; - - // KP: Limits how much your jets can affect your forward speed...very useful - // for balancing how much your speed can be increased by jets as opposed to - // pure skiing - maxJetForwardSpeed = $TR2_playerMaxJetForwardSpeed; - - // KP: Same as horizontal counterparts. Should be set so that players can't - // go too high. Must be careful not to make it feel too "floaty" - upMaxSpeed = $TR2_playerUpMaxSpeed; - upResistSpeed = $TR2_playerUpResistSpeed; - upResistFactor = $TR2_playerUpResistFactor; - - // heat inc'ers and dec'ers - heatDecayPerSec = 1.0 / 4.0; // takes 4 seconds to clear heat sig. - heatIncreasePerSec = 1.0 / 3.0; // takes 3.0 seconds of constant jet to get full heat sig. - - footstepSplashHeight = 0.35; - //Footstep Sounds - LFootSoftSound = LFootLightSoftSound; - RFootSoftSound = RFootLightSoftSound; - LFootHardSound = LFootLightHardSound; - RFootHardSound = RFootLightHardSound; - LFootMetalSound = LFootLightMetalSound; - RFootMetalSound = RFootLightMetalSound; - LFootSnowSound = LFootLightSnowSound; - RFootSnowSound = RFootLightSnowSound; - LFootShallowSound = LFootLightShallowSplashSound; - RFootShallowSound = RFootLightShallowSplashSound; - LFootWadingSound = LFootLightWadingSound; - RFootWadingSound = RFootLightWadingSound; - LFootUnderwaterSound = LFootLightUnderwaterSound; - RFootUnderwaterSound = RFootLightUnderwaterSound; - LFootBubblesSound = LFootLightBubblesSound; - RFootBubblesSound = RFootLightBubblesSound; - movingBubblesSound = ArmorMoveBubblesSound; - waterBreathSound = WaterBreathMaleSound; - - impactSoftSound = ImpactLightSoftSound; - impactHardSound = ImpactLightHardSound; - impactMetalSound = ImpactLightMetalSound; - impactSnowSound = ImpactLightSnowSound; - - skiSoftSound = "";//TR2SkiAllSoftSound; - skiHardSound = "";//SkiAllHardSound; - skiMetalSound = SkiAllMetalSound; - skiSnowSound = SkiAllSnowSound; - - impactWaterEasy = ImpactLightWaterEasySound; - impactWaterMedium = ImpactLightWaterMediumSound; - impactWaterHard = ImpactLightWaterHardSound; - - // KP: Removed the annoying shaking upon impact - groundImpactMinSpeed = 30.0;//10.0; - groundImpactShakeFreq = "4.0 4.0 4.0"; - groundImpactShakeAmp = "0.1 0.1 0.1";//"1.0 1.0 1.0"; - groundImpactShakeDuration = 0.05;//0.8; - groundImpactShakeFalloff = 2.0;//10.0; - - exitingWater = ExitingWaterLightSound; - - maxWeapons = 3; // Max number of different weapons the player can have - maxGrenades = 1; // Max number of different grenades the player can have - maxMines = 1; // Max number of different mines the player can have - - // Inventory restrictions - max[RepairKit] = 1; - max[Mine] = 3; - max[Grenade] = 5; - max[Blaster] = 1; - max[Plasma] = 1; - max[PlasmaAmmo] = 20; - max[Disc] = 1; - max[DiscAmmo] = 15; - max[SniperRifle] = 1; - max[GrenadeLauncher] = 1; - max[GrenadeLauncherAmmo]= 10; - max[Mortar] = 0; - max[MortarAmmo] = 0; - max[MissileLauncher] = 0; - max[MissileLauncherAmmo]= 0; - max[Chaingun] = 1; - max[ChaingunAmmo] = 100; - max[RepairGun] = 1; - max[CloakingPack] = 1; - max[SensorJammerPack] = 1; - max[EnergyPack] = 1; - max[RepairPack] = 1; - max[ShieldPack] = 1; - max[AmmoPack] = 1; - max[SatchelCharge] = 1; - max[MortarBarrelPack] = 0; - max[MissileBarrelPack] = 0; - max[AABarrelPack] = 0; - max[PlasmaBarrelPack] = 0; - max[ELFBarrelPack] = 0; - max[InventoryDeployable]= 0; - max[MotionSensorDeployable] = 1; - max[PulseSensorDeployable] = 1; - max[TurretOutdoorDeployable] = 0; - max[TurretIndoorDeployable] = 0; - max[FlashGrenade] = 5; - max[ConcussionGrenade] = 5; - max[FlareGrenade] = 5; - max[TargetingLaser] = 1; - max[ELFGun] = 1; - max[ShockLance] = 1; - max[CameraGrenade] = 2; - max[Beacon] = 3; - - // TR2 - max[TR2Disc] = 1; - max[TR2GrenadeLauncher] = 1; - max[TR2Chaingun] = 1; - max[TR2GoldTargetingLaser] = 1; - max[TR2SilverTargetingLaser] = 1; - max[TR2Grenade] = 5; - max[TR2DiscAmmo] = 15; - max[TR2GrenadeLauncherAmmo] = 10; - max[TR2ChaingunAmmo] = 100; - max[TR2EnergyPack] = 1; - - observeParameters = "1.0 12.0 12.0";//$TR2_playerObserveParameters;//"1.0 32.0 32.0";//"0.5 4.5 4.5"; - - shieldEffectScale = "0.7 0.7 1.0"; -}; - -datablock PlayerData(TR2LightFemaleHumanArmor) : TR2LightMaleHumanArmor -{ - shapeFile = "TR2light_female.dts"; - waterBreathSound = WaterBreathFemaleSound; - jetEffect = HumanMediumArmorJetEffect; -}; - -datablock ItemData(TR2DummyArmor)// : TR2LightMaleHumanArmor -{ - shapeFile = "statue_lmale.dts"; -}; - -datablock PlayerData(TR2MediumMaleHumanArmor) : TR2LightMaleHumanArmor -{ - emap = true; - - className = Armor; - shapeFile = "TR2medium_male.dts"; - maxDamage = 1.55;//1.1; - - jetSound = ArmorJetSound; - wetJetSound = ArmorWetJetSound; - - jetEmitter = HumanArmorJetEmitter; - jetEffect = HumanMediumArmorJetEffect; - - boundingBox = "2.9 2.3 5.2"; - boxHeadFrontPercentage = 1; - - //Foot Prints - decalData = MediumMaleFootprint; - decalOffset = 0.35; - - footPuffEmitter = LightPuffEmitter; - footPuffNumParts = 15; - footPuffRadius = 0.25; - - dustEmitter = LiftoffDustEmitter; - - splash = PlayerSplash; - splashVelocity = 4.0; - splashAngle = 67.0; - splashFreqMod = 300.0; - splashVelEpsilon = 0.60; - bubbleEmitTime = 0.4; - splashEmitter[0] = PlayerFoamDropletsEmitter; - splashEmitter[1] = PlayerFoamEmitter; - splashEmitter[2] = PlayerBubbleEmitter; - mediumSplashSoundVelocity = 10.0; - hardSplashSoundVelocity = 20.0; - exitSplashSoundVelocity = 5.0; - - footstepSplashHeight = 0.35; - //Footstep Sounds - LFootSoftSound = LFootMediumSoftSound; - RFootSoftSound = RFootMediumSoftSound; - LFootHardSound = LFootMediumHardSound; - RFootHardSound = RFootMediumHardSound; - LFootMetalSound = LFootMediumMetalSound; - RFootMetalSound = RFootMediumMetalSound; - LFootSnowSound = LFootMediumSnowSound; - RFootSnowSound = RFootMediumSnowSound; - LFootShallowSound = LFootMediumShallowSplashSound; - RFootShallowSound = RFootMediumShallowSplashSound; - LFootWadingSound = LFootMediumWadingSound; - RFootWadingSound = RFootMediumWadingSound; - LFootUnderwaterSound = LFootMediumUnderwaterSound; - RFootUnderwaterSound = RFootMediumUnderwaterSound; - LFootBubblesSound = LFootMediumBubblesSound; - RFootBubblesSound = RFootMediumBubblesSound; - movingBubblesSound = ArmorMoveBubblesSound; - waterBreathSound = WaterBreathMaleSound; - - impactSoftSound = ImpactMediumSoftSound; - impactHardSound = ImpactMediumHardSound; - impactMetalSound = ImpactMediumMetalSound; - impactSnowSound = ImpactMediumSnowSound; - - impactWaterEasy = ImpactMediumWaterEasySound; - impactWaterMedium = ImpactMediumWaterMediumSound; - impactWaterHard = ImpactMediumWaterHardSound; - - exitingWater = ExitingWaterMediumSound; - - maxWeapons = 4; // Max number of different weapons the player can have - maxGrenades = 1; // Max number of different grenades the player can have - maxMines = 1; // Max number of different mines the player can have - - // Inventory restrictions - max[RepairKit] = 1; - max[Mine] = 3; - max[Grenade] = 6; - max[Blaster] = 1; - max[Plasma] = 1; - max[PlasmaAmmo] = 40; - max[Disc] = 1; - max[DiscAmmo] = 15; - max[SniperRifle] = 0; - max[GrenadeLauncher] = 1; - max[GrenadeLauncherAmmo]= 12; - max[Mortar] = 0; - max[MortarAmmo] = 0; - max[MissileLauncher] = 1; - max[MissileLauncherAmmo]= 4; - max[Chaingun] = 1; - max[ChaingunAmmo] = 150; - max[RepairGun] = 1; - max[CloakingPack] = 0; - max[SensorJammerPack] = 1; - max[EnergyPack] = 1; - max[RepairPack] = 1; - max[ShieldPack] = 1; - max[AmmoPack] = 1; - max[SatchelCharge] = 1; - max[MortarBarrelPack] = 1; - max[MissileBarrelPack] = 1; - max[AABarrelPack] = 1; - max[PlasmaBarrelPack] = 1; - max[ELFBarrelPack] = 1; - max[InventoryDeployable]= 1; - max[MotionSensorDeployable] = 1; - max[PulseSensorDeployable] = 1; - max[TurretOutdoorDeployable] = 1; - max[TurretIndoorDeployable] = 1; - max[FlashGrenade] = 6; - max[ConcussionGrenade] = 6; - max[FlareGrenade] = 6; - max[TargetingLaser] = 1; - max[ELFGun] = 1; - max[ShockLance] = 1; - max[CameraGrenade] = 3; - max[Beacon] = 3; - - max[TR2Shocklance] = 1; - - shieldEffectScale = "0.7 0.7 1.0"; -}; - -datablock PlayerData(TR2MediumFemaleHumanArmor) : TR2MediumMaleHumanArmor -{ - shapeFile = "TR2medium_female.dts"; -}; - - -datablock PlayerData(TR2HeavyMaleHumanArmor) : TR2LightMaleHumanArmor -{ - emap = true; - - mass = 245; - jetForce = 14000; - jumpForce = 3500; - runForce = 22000; - - className = Armor; - shapeFile = "TR2heavy_male.dts"; - cameraMaxDist = 14; - - boundingBox = "6.2 6.2 9.0"; - maxDamage = 6.0;//1.32; - - // Give lots of energy to goalies - maxEnergy = 120;//60; - maxJetHorizontalPercentage = 1.0; - - //Foot Prints - decalData = HeavyMaleFootprint; - decalOffset = 0.4; - - footPuffEmitter = LightPuffEmitter; - footPuffNumParts = 15; - footPuffRadius = 0.25; - - dustEmitter = LiftoffDustEmitter; - - //Footstep Sounds - LFootSoftSound = LFootHeavySoftSound; - RFootSoftSound = RFootHeavySoftSound; - LFootHardSound = LFootHeavyHardSound; - RFootHardSound = RFootHeavyHardSound; - LFootMetalSound = LFootHeavyMetalSound; - RFootMetalSound = RFootHeavyMetalSound; - LFootSnowSound = LFootHeavySnowSound; - RFootSnowSound = RFootHeavySnowSound; - LFootShallowSound = LFootHeavyShallowSplashSound; - RFootShallowSound = RFootHeavyShallowSplashSound; - LFootWadingSound = LFootHeavyWadingSound; - RFootWadingSound = RFootHeavyWadingSound; - LFootUnderwaterSound = LFootHeavyUnderwaterSound; - RFootUnderwaterSound = RFootHeavyUnderwaterSound; - LFootBubblesSound = LFootHeavyBubblesSound; - RFootBubblesSound = RFootHeavyBubblesSound; - movingBubblesSound = ArmorMoveBubblesSound; - waterBreathSound = WaterBreathMaleSound; - - impactSoftSound = ImpactHeavySoftSound; - impactHardSound = ImpactHeavyHardSound; - impactMetalSound = ImpactHeavyMetalSound; - impactSnowSound = ImpactHeavySnowSound; - - impactWaterEasy = ImpactHeavyWaterEasySound; - impactWaterMedium = ImpactHeavyWaterMediumSound; - impactWaterHard = ImpactHeavyWaterHardSound; - - - maxWeapons = 5; // Max number of different weapons the player can have - maxGrenades = 1; // Max number of different grenades the player can have - maxMines = 1; // Max number of different mines the player can have - - // Inventory restrictions - max[RepairKit] = 1; - max[Mine] = 3; - max[Grenade] = 8; - max[Blaster] = 1; - max[Plasma] = 1; - max[PlasmaAmmo] = 50; - max[Disc] = 1; - max[DiscAmmo] = 15; - max[SniperRifle] = 0; - max[GrenadeLauncher] = 1; - max[GrenadeLauncherAmmo]= 15; - max[Mortar] = 1; - max[MortarAmmo] = 10; - max[MissileLauncher] = 1; - max[MissileLauncherAmmo]= 8; - max[Chaingun] = 1; - max[ChaingunAmmo] = 200; - max[RepairGun] = 1; - max[CloakingPack] = 0; - max[SensorJammerPack] = 1; - max[EnergyPack] = 1; - max[RepairPack] = 1; - max[ShieldPack] = 1; - max[AmmoPack] = 1; - max[SatchelCharge] = 1; - max[MortarBarrelPack] = 1; - max[MissileBarrelPack] = 1; - max[AABarrelPack] = 1; - max[PlasmaBarrelPack] = 1; - max[ELFBarrelPack] = 1; - max[InventoryDeployable]= 1; - max[MotionSensorDeployable] = 1; - max[PulseSensorDeployable] = 1; - max[TurretOutdoorDeployable] = 1; - max[TurretIndoorDeployable] = 1; - max[FlashGrenade] = 8; - max[ConcussionGrenade] = 8; - max[FlareGrenade] = 8; - max[TargetingLaser] = 1; - max[ELFGun] = 1; - max[ShockLance] = 1; - max[CameraGrenade] = 3; - max[Beacon] = 3; - - max[TR2Mortar] = 1; - max[TR2MortarAmmo] = 99; - max[TR2Shocklance] = 1; - - shieldEffectScale = "0.7 0.7 1.0"; -}; - -datablock PlayerData(TR2HeavyFemaleHumanArmor) : TR2HeavyMaleHumanArmor -{ - className = Armor; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Prefixes.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Prefixes.cs deleted file mode 100644 index 6fe6490c..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Prefixes.cs +++ /dev/null @@ -1,44 +0,0 @@ - -//datablock AudioProfile(TR2TestPrefixSound) -//{ -// filename = "fx/bonuses/test-Prefix-brilliance.wav"; -// description = AudioBIGExplosion3d; -// preload = true; -//}; - -$PrefixList = new ScriptObject() { - class = PrefixList; -}; - -function PrefixList::get(%this, %a) -{ - return $PrefixList[%a]; -} - -// Somewhat backwards -$PrefixList[0] = new ScriptObject() { - text = "Angled"; - value = 2; - sound = "blah.wav"; - emitter = "Optional"; - class = PrefixData; -}; - -// Nearly backwards -$PrefixList[1] = new ScriptObject() { - text = "Twisted"; - value = 5; - sound = "blah.wav"; - emitter = "Optional"; - class = PrefixData; -}; - -// Completely backwards -$PrefixList[2] = new ScriptObject() { - text = "Deranged"; - value = 8; - sound = "blah.wav"; - emitter = "Optional"; - class = PrefixData; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Qualifiers.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Qualifiers.cs deleted file mode 100644 index 15eebbc3..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Qualifiers.cs +++ /dev/null @@ -1,221 +0,0 @@ - - -//datablock AudioProfile(TR2TestQualifierDataSound) -//{ -// filename = "fx/bonuses/test-QualifierData-brilliance.wav"; -// description = AudioBIGExplosion3d; -// preload = true; -//}; - -// QualifierData components -// [Horizontal flag speed, Vertical flag speed, hangtime] - -$QualifierList = new ScriptObject() { - class = QualifierList; -}; - -function QualifierList::get(%this, %a, %b, %c) -{ - return $QualifierList[%a, %b, %c]; -} - -//////////////////////////////////////////////////////////////////////////////// -// No/low hangtime -$QualifierList[0,0,0] = ""; -//new ScriptObject() { -// text = "Dull"; -// value = 5; -// sound = "blah.wav"; -// emitter = "Optional"; -// class = QualifierData; -//}; - -$QualifierList[1,0,0] = new ScriptObject() { - text = "Sharp"; - value = 1; - sound = Qualifier100Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,1,0] = new ScriptObject() { - text = "Spitting"; - value = 1; - sound = Qualifier010Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,1,0] = new ScriptObject() { - text = "Whipped"; - value = 2; - sound = Qualifier110Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,2,0] = new ScriptObject() { - text = "Popping"; - value = 2; - sound = Qualifier020Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,2,0] = new ScriptObject() { - text = "Bursting"; - value = 3; - sound = Qualifier120Sound; - emitter = "Optional"; - class = QualifierData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Medium hangtime -$QualifierList[0,0,1] = new ScriptObject() { - text = "Modest"; - value = 3; - sound = Qualifier001Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,0,1] = new ScriptObject() { - text = "Ripped"; - value = 4; - sound = Qualifier101Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,1,1] = new ScriptObject() { - text = "Shining"; - value = 4; - sound = Qualifier011Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,1,1] = new ScriptObject() { - text = "Slick"; - value = 5; - sound = Qualifier111Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,2,1] = new ScriptObject() { - text = "Sprinkling"; - value = 5; - sound = Qualifier021Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,2,1] = new ScriptObject() { - text = "Brilliant"; - value = 6; - sound = Qualifier121Sound; - emitter = "Optional"; - class = QualifierData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// High hangtime -$QualifierList[0,0,2] = new ScriptObject() { - text = "Frozen"; - value = 7; - sound = Qualifier002Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,0,2] = new ScriptObject() { - text = "Shooting"; - value = 8; - sound = Qualifier102Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,1,2] = new ScriptObject() { - text = "Dangling"; - value = 9; - sound = Qualifier012Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,1,2] = new ScriptObject() { - text = "Blazing"; - value = 10; - sound = Qualifier112Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,2,2] = new ScriptObject() { - text = "Raining"; - value = 11; - sound = Qualifier022Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,2,2] = new ScriptObject() { - text = "Falling"; - value = 12; - sound = Qualifier122Sound; - emitter = "Optional"; - class = QualifierData; -}; - -//////////////////////////////////////////////////////////////////////////////// -// Wow hangtime -$QualifierList[0,0,3] = new ScriptObject() { - text = "Suspended"; - value = 13; - sound = Qualifier003Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,0,3] = new ScriptObject() { - text = "Skeeting"; - value = 14; - sound = Qualifier103Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,1,3] = new ScriptObject() { - text = "Hanging"; - value = 15; - sound = Qualifier013Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,1,3] = new ScriptObject() { - text = "Arcing"; - value = 16; - sound = Qualifier113Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[0,2,3] = new ScriptObject() { - text = "Pouring"; - value = 17; - sound = Qualifier023Sound; - emitter = "Optional"; - class = QualifierData; -}; - -$QualifierList[1,2,3] = new ScriptObject() { - text = "Elite"; - value = 18; - sound = Qualifier123Sound; - emitter = "Optional"; - class = QualifierData; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Roles.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Roles.cs deleted file mode 100644 index 7c6a2a49..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2Roles.cs +++ /dev/null @@ -1,317 +0,0 @@ -// Roles -$TR2::role[0] = Goalie; -$TR2::role[1] = Defense; -$TR2::role[2] = Offense; -$TR2::numRoles = 3; - -// For some reason the above "strings" convert to all lowercase -$TR2::roleText[Goalie] = "Goalie"; -$TR2::roleText[Defense] = "Defense"; -$TR2::roleText[Offense] = "Offense"; - -$TR2::roleMax[Goalie] = 1; -$TR2::roleMax[Defense] = 2; -$TR2::roleMax[Offense] = 10; - -$TR2::roleArmor[Goalie] = Heavy; -$TR2::roleArmor[Defense] = Medium; -$TR2::roleArmor[Offense] = Light; - -// Roles are automated via concentric circles around goals -$TR2::roleDistanceFromGoal[Goalie] = 70; -$TR2::roleDistanceFromGoal[Defense] = 350; -$TR2::roleDistanceFromGoal[Offense] = 10000; - -// Number of ticks needed before changing to this role -$TR2::roleTicksNeeded[Goalie] = 0; -$TR2::roleTicksNeeded[Defense] = 0; -$TR2::roleTicksNeeded[Offense] = 0; - -// Extra items for roles -$TR2::roleExtraItem[Goalie0] = TR2Shocklance; -$TR2::roleExtraItemCount[Goalie0] = 1; -$TR2::roleExtraItem[Goalie1] = TR2Mortar; -$TR2::roleExtraItemCount[Goalie1] = 1; -$TR2::roleExtraItem[Goalie2] = TR2MortarAmmo; -$TR2::roleExtraItemCount[Goalie2] = 99; -$TR2::roleNumExtraItems[Goalie] = 3; - -$TR2::roleExtraItem[Defense0] = TR2Shocklance; -$TR2::roleExtraItemCount[Defense0] = 1; -$TR2::roleNumExtraItems[Defense] = 1; - -$TR2::roleNumExtraItems[Offense] = 0; - -function debugPrintRoles() -{ - echo("**********************************ROLE PRINT"); -} - -function TR2Game::resetPlayerRoles(%game) -{ - %count = ClientGroup.getCount(); - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - %game.releaseRole(%cl); - } - - for (%i=0; %i<$TR2::numRoles; %i++) - %game.initRole($TR2::Role[%i]); -} - -function TR2Game::initRole(%game, %role) -{ - $numPlayers[%role @ 1] = 0; - $numPlayers[%role @ 2] = 0; -} - -function TR2Game::validateRoles(%game) -{ - // Recalculate role counts - %count = ClientGroup.getCount(); - for (%i = 0; %i<$TR2::numRoles; %i++) - { - %role = $TR2::role[%i]; - %newCount[1] = 0; - %newCount[2] = 0; - - for (%j = 0; %j<%count; %j++) - { - %cl = ClientGroup.getObject(%j); - if (%cl.currentRole $= %role) - %newCount[%cl.team]++; - } - $numPlayers[%role @ 1] = %newCount[1]; - $numPlayers[%role @ 2] = %newCount[2]; - } - - // Make sure that all players are in the armor they're supposed to be in - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (!isObject(%cl) || !isObject(%cl.player)) - continue; - - // If somehow the player is active, but has no role, set the outer role - if (%cl.currentRole $= "") - %game.assignOutermostRole(%cl); - - // If for some reason that wasn't possible, skip this player - if (%cl.currentRole $= "") - continue; - - %player = %cl.player; - %armor = "TR2" @ $TR2::roleArmor[%cl.currentRole] @ %cl.sex @ HumanArmor; - - // Swap armors if necessary - if (%player.getDataBlock().getName() !$= %armor) - { - // Don't allow an armor change if the player recently did something that requires - // datablock access, such as impacting the terrain. There is a T2 UE bug related - // to concurrent datablock access. - %time = getSimTime(); - if (%time - %player.delayRoleChangeTime <= $TR2::datablockRoleChangeDelay) - return false; - %damagePct = %player.getDamagePercent(); - %energyPct = %player.getEnergyPercent(); - %player.setDataBlock(%armor); - %player.setDamageLevel(%damagePct * %player.getDataBlock().maxDamage); - %player.setEnergyLevel(%energyPct * %player.getDataBlock().maxEnergy); - } - } -} - -function TR2Game::trySetRole(%game, %player, %role) -{ - // Check concentric circles - if (!isObject(%player)) - return false; - - // Don't allow an armor change if the player recently did something that requires - // datablock access, such as impacting the terrain. There is a T2 UE bug related - // to concurrent datablock access. - %time = getSimTime(); - if (%time - %player.delayRoleChangeTime <= $TR2::datablockRoleChangeDelay) - return false; - - %position = %player.getPosition(); - %distanceToGoal = VectorLen(VectorSub(%position, $teamGoalPosition[%player.team])); - - if (%distanceToGoal > $TR2::roleDistanceFromGoal[%role]) - { - %player.client.roleChangeTicks[%role] = 0; - return false; - } - - // See if a change is even necessary - if (%player.client.currentRole $= %role) - { - return true; - } - - // Make sure a spot is available - if ($numPlayers[%role @ %player.team] >= $TR2::roleMax[%role]) - { - //echo("****ROLES: No slots left for " @ %role); - return false; - } - // Make sure enough time has been spent in this zone - if (%player.client.roleChangeTicks[%role] < $TR2::roleTicksNeeded[%role]) - { - %player.client.roleChangeTicks[%role]++; - return false; - } - - %team = %player.team; - - - // Change roles - // First release the old role, if applicable - if (%player.client.currentRole !$= "") - { - //echo("TEAM " @ %player.team @ " ROLE CHANGE: " - // @ %player.client.currentRole - // @ "(" @ $numPlayers[%player.client.currentRole @ %team] @ ") " - // @ " to " - // @ %role - // @ "(" @ $numPlayers[%role @ %team] @ ")" - //); - $numPlayers[%player.client.currentRole @ %team]--; - - // Debug the decrement - if ($numPlayers[%player.client.currentRole @ %team] < 0) - { - echo("**ROLE CHANGE ERROR: negative role count"); - $numPlayers[%player.client.currentRole @ %team] = 0; - } - } - - // Now switch to the new role - $numPlayers[%role @ %team]++; - %newArmor = "TR2" @ $TR2::roleArmor[%role] @ %player.client.sex @ HumanArmor; - %player.client.roleChangeTicks[%role] = 0; - %player.setInvincible(false); - - // Swap armors if necessary - if (%player.getDataBlock().getName() !$= %newArmor) - { - %damagePct = %player.getDamagePercent(); - %energyPct = %player.getEnergyPercent(); - //echo(" ROLE: " @ %damagePct @ " damage"); - //echo(" ROLE: " @ %energyPct @ " energy"); - //echo(" ROLE: pre-armorSwitchSched = " @ %player.armorSwitchSchedule); - %player.setDataBlock(%newArmor); - //echo(" ROLE: post-armorSwitchSched = " @ %player.armorSwitchSchedule); - %player.setDamageLevel(%damagePct * %player.getDataBlock().maxDamage); - %player.setEnergyLevel(%energyPct * %player.getDataBlock().maxEnergy); - } - %player.client.currentRole = %role; - - // Equipment changes - %game.equipRoleWeapons(%player.client); - - messageClient(%player.client, 'TR2ArmorChange', "\c3ROLE CHANGE: \c4" @ $TR2::roleText[%role] @ "."); - serverPlay3D(RoleChangeSound, %player.getPosition()); - // Particle effect too? - //%newEmitter = new ParticleEmissionDummy(RoleChangeEffect) { - //position = %player.getTransform(); - //rotation = "1 0 0 0"; - //scale = "1 1 1"; - //dataBlock = "defaultEmissionDummy"; - //emitter = "RoleChangeEmitter"; - //velocity = "1"; - //}; - //%newEmitter.schedule(800, "delete"); - - return true; -} - -function TR2Game::updateRoles(%game) -{ - %count = ClientGroup.getCount(); - - for (%i = 0; %i < %count; %i++) - { - %cl = ClientGroup.getObject(%i); - if (%cl $= "" || %cl.player == 0 || %cl.player $= "") - continue; - - %done = false; - for (%j = 0; %j < $TR2::numRoles && !%done; %j++) - { - if (%game.trySetRole(%cl.player, $TR2::role[%j])) - %done = true; - } - } -} - -function TR2Game::equipRoleWeapons(%game, %client) -{ - %player = %client.player; - - // Get rid of existing extra weapon - for (%i=0; %i<%client.extraRoleItems; %i++) - { - %item = %client.extraRoleItem[%i]; - - // If the player is using the item we're about to take away, equip - // the disc launcher - %equippedWeapon = %player.getMountedImage($WeaponSlot).item; - if (%equippedWeapon $= %item) - %player.use(TR2Disc); - - %player.setInventory(%item, 0); - } - - // Clear HUD - %client.setWeaponsHudItem(TR2Shocklance, 0, 0); - %client.setWeaponsHudItem(TR2Mortar, 0, 0); - - // Equip role items - %client.extraRoleItems = $TR2::roleNumExtraItems[%client.currentRole]; - for (%i=0; %i<%client.extraRoleItems; %i++) - { - %item = $TR2::roleExtraItem[%client.currentRole @ %i]; - %roleItemAmount = $TR2::roleExtraItemCount[%client.currentRole @ %i]; - - // Hmm, this actually works, but it remembers that you - // lose your mortar ammo after a role switch. Get rid of it - // for now since there's unlimited mortar ammo anyway. - //if (%client.restockAmmo || %roleItemAmount == 1) - %itemAmount = %roleItemAmount; - //else - // %itemAmount = %client.lastRoleItemCount[%i]; - %player.setInventory(%item, %itemAmount); - %client.extraRoleItem[%i] = %item; - %client.extraRoleItemCount[%i] = %itemAmount; - - // Re-equip, if necessary - if (%item $= %equippedWeapon) - %player.use(%item); - } - //echo(" ROLE: weapons equipped."); -} - -function TR2Game::releaseRole(%game, %client) -{ - if (%client.currentRole $= "") - return; - - //echo(" ROLE: client " @ %client @ " released " @ %client.currentRole); - - $numPlayers[%client.currentRole @ %client.team]--; - %client.currentRole = ""; -} - -function TR2Game::assignOutermostRole(%game, %client) -{ - //$role[%client.currentRole @ %client.team @ %i] = ""; - //$numPlayers[%client.currentRole @ %client.team]--; - //%client.currentRole = $TR2::role[$TR2::numRoles-1]; - //echo(" ROLE: assigning outermost"); - %outerRole = $TR2::role[$TR2::numRoles-1]; - if (%client.player > 0 && %client.currentRole !$= %outerRole) - %game.trySetRole(%client.player, %outerRole); -} - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2WeaponBonuses.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2WeaponBonuses.cs deleted file mode 100644 index 2eeceb67..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2WeaponBonuses.cs +++ /dev/null @@ -1,104 +0,0 @@ -// Weapon bonuses - - -// Weapon speed -$WeaponSpeedBonusList = new ScriptObject() { - class = WeaponSpeedBonusList; -}; - -function WeaponSpeedBonusList::get(%this, %a) -{ - return $WeaponSpeedBonusList[%a]; -} - -$WeaponSpeedBonusList[0] = new ScriptObject() { - text = "Kilo"; - value = 1; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -$WeaponSpeedBonusList[1] = new ScriptObject() { - text = "Mega"; - value = 3; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -$WeaponSpeedBonusList[2] = new ScriptObject() { - text = "Giga"; - value = 5; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -// Weapon height -$WeaponHeightBonusList = new ScriptObject() { - class = WeaponHeightBonusList; -}; - -function WeaponHeightBonusList::get(%this, %a) -{ - return $WeaponHeightBonusList[%a]; -} - -$WeaponHeightBonusList[0] = new ScriptObject() { - text = "Hovering"; - value = 1; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -$WeaponHeightBonusList[1] = new ScriptObject() { - text = "Towering"; - value = 3; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -$WeaponHeightBonusList[3] = new ScriptObject() { - text = "Nose-Bleeding"; - value = 5; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -// Weapon type -$WeaponTypeBonusList = new ScriptObject() { - class = WeaponTypeBonusList; -}; - -function WeaponTypeBonusList::get(%this, %a) -{ - return $WeaponTypeBonusList[%a]; -} - -$WeaponTypeBonusList[0] = new ScriptObject() { - text = "Disc"; - value = 3; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -$WeaponTypeBonusList[1] = new ScriptObject() { - text = "Grenade"; - value = 1; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; - -$WeaponTypeBonusList[2] = new ScriptObject() { - text = "Chain"; - value = 2; - sound = "blah.wav"; - emitter = "Optional"; - class = BonusComponent; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2heavy_male.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2heavy_male.cs deleted file mode 100644 index 0711e8b2..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2heavy_male.cs +++ /dev/null @@ -1,41 +0,0 @@ -datablock TSShapeConstructor(TR2HeavyMaleDts) -{ - baseShape = "TR2heavy_male.dts"; - sequence0 = "TR2heavy_male_root.dsq root"; - sequence1 = "TR2heavy_male_forward.dsq run"; - sequence2 = "TR2heavy_male_back.dsq back"; - sequence3 = "TR2heavy_male_side.dsq side"; - sequence4 = "heavy_male_lookde.dsq look"; - sequence5 = "heavy_male_head.dsq head"; - sequence6 = "TR2heavy_male_fall.dsq fall"; - sequence7 = "TR2heavy_male_jet.dsq jet"; - sequence8 = "TR2heavy_male_land.dsq land"; - sequence9 = "TR2heavy_male_jump.dsq jump"; - sequence10 = "heavy_male_recoilde.dsq light_recoil"; - sequence11 = "heavy_male_idlepda.dsq pda"; - sequence12 = "heavy_male_headside.dsq headside"; - sequence13 = "heavy_male_lookms.dsq lookms"; - sequence14 = "TR2heavy_male_diehead.dsq death1"; - sequence15 = "TR2heavy_male_diechest.dsq death2"; - sequence16 = "TR2heavy_male_dieback.dsq death3"; - sequence17 = "TR2heavy_male_diesidelf.dsq death4"; - sequence18 = "TR2heavy_male_diesidert.dsq death5"; - sequence19 = "TR2heavy_male_dieforward.dsq death6"; // heavy_male_dieleglf - sequence20 = "TR2heavy_male_diechest.dsq death7"; // heavy_male_dielegrt - sequence21 = "TR2heavy_male_dieslump.dsq death8"; - sequence22 = "TR2heavy_male_dieforward.dsq death9"; // heavy_male_dieknees - sequence23 = "TR2heavy_male_dieforward.dsq death10"; - sequence24 = "TR2heavy_male_diespin.dsq death11"; - sequence25 = "TR2heavy_male_celsalute.dsq cel1"; - sequence26 = "TR2heavy_male_celwave.dsq cel2"; - sequence27 = "TR2heavy_male_tauntbest.dsq cel3"; - sequence28 = "TR2heavy_male_tauntimp.dsq cel4"; - sequence29 = "TR2heavy_male_celdance.dsq cel5"; - sequence30 = "TR2heavy_male_celflex.dsq cel6"; - sequence31 = "TR2heavy_male_celtaunt.dsq cel7"; - sequence32 = "TR2heavy_male_celjump.dsq cel8"; - sequence33 = "TR2heavy_male_ski.dsq ski"; - sequence34 = "TR2heavy_male_standjump.dsq standjump"; - sequence35 = "heavy_male_looknw.dsq looknw"; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2light_female.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2light_female.cs deleted file mode 100644 index 2d4025e3..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2light_female.cs +++ /dev/null @@ -1,43 +0,0 @@ -datablock TSShapeConstructor(TR2LightFemaleDts) -{ - baseShape = "TR2light_female.dts"; - sequence0 = "TR2light_female_root.dsq root"; - sequence1 = "TR2light_female_forward.dsq run"; - sequence2 = "TR2light_female_back.dsq back"; - sequence3 = "TR2light_female_side.dsq side"; - sequence4 = "light_female_lookde.dsq look"; - sequence5 = "light_female_head.dsq head"; - sequence6 = "light_female_headside.dsq headside"; - sequence7 = "TR2light_female_fall.dsq fall"; - sequence8 = "TR2light_female_jet.dsq jet"; - sequence9 = "TR2light_female_land.dsq land"; - sequence10 = "TR2light_female_jump.dsq jump"; - sequence11 = "light_female_recoilde.dsq light_recoil"; - sequence12 = "light_female_scoutroot.dsq scoutroot"; - sequence13 = "light_female_looksn.dsq looksn"; - sequence14 = "light_female_lookms.dsq lookms"; - sequence15 = "light_female_sitting.dsq sitting"; - sequence16 = "light_female_idlepda.dsq pda"; - sequence17 = "TR2light_female_diehead.dsq death1"; - sequence18 = "TR2light_female_diechest.dsq death2"; - sequence19 = "TR2light_female_dieback.dsq death3"; - sequence20 = "TR2light_female_diesidelf.dsq death4"; - sequence21 = "TR2light_female_diesidert.dsq death5"; - sequence22 = "TR2light_female_dieleglf.dsq death6"; - sequence23 = "TR2light_female_dielegrt.dsq death7"; - sequence24 = "TR2light_female_dieslump.dsq death8"; - sequence25 = "TR2light_female_dieknees.dsq death9"; - sequence26 = "TR2light_female_dieforward.dsq death10"; - sequence27 = "TR2light_female_diespin.dsq death11"; - sequence28 = "TR2light_female_celsalute.dsq cel1"; - sequence29 = "TR2light_female_celwave.dsq cel2"; - sequence30 = "TR2light_female_tauntbest.dsq cel3"; - sequence31 = "TR2light_female_tauntimp.dsq cel4"; - sequence32 = "TR2light_female_celdance.dsq cel5"; - sequence33 = "TR2light_female_tauntkiss.dsq cel6"; - sequence34 = "TR2light_female_tauntbutt.dsq cel7"; - sequence35 = "TR2light_female_celbow.dsq cel8"; - sequence36 = "TR2light_female_ski.dsq ski"; - sequence37 = "TR2light_female_standjump.dsq standjump"; - sequence38 = "light_female_looknw.dsq looknw"; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2light_male.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2light_male.cs deleted file mode 100644 index 8d9073f1..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2light_male.cs +++ /dev/null @@ -1,43 +0,0 @@ -datablock TSShapeConstructor(TR2lightMaleDts) -{ - baseShape = "TR2light_male.dts"; - sequence0 = "TR2light_male_root.dsq root"; - sequence1 = "TR2light_male_forward.dsq run"; - sequence2 = "TR2light_male_back.dsq back"; - sequence3 = "TR2light_male_side.dsq side"; - sequence4 = "light_male_lookde.dsq look"; - sequence5 = "light_male_head.dsq head"; - sequence6 = "TR2light_male_fall.dsq fall"; - sequence7 = "TR2light_male_jet.dsq jet"; - sequence8 = "TR2light_male_land.dsq land"; - sequence9 = "TR2light_male_jump.dsq jump"; - sequence10 = "light_male_diehead.dsq death1"; - sequence11 = "light_male_diechest.dsq death2"; - sequence12 = "light_male_dieback.dsq death3"; - sequence13 = "light_male_diesidelf.dsq death4"; - sequence14 = "light_male_diesidert.dsq death5"; - sequence15 = "light_male_dieleglf.dsq death6"; - sequence16 = "light_male_dielegrt.dsq death7"; - sequence17 = "light_male_dieslump.dsq death8"; - sequence18 = "light_male_dieknees.dsq death9"; - sequence19 = "light_male_dieforward.dsq death10"; - sequence20 = "light_male_diespin.dsq death11"; - sequence21 = "light_male_idlepda.dsq pda"; - sequence22 = "light_male_looksn.dsq looksn"; - sequence23 = "light_male_lookms.dsq lookms"; - sequence24 = "light_male_scoutroot.dsq scoutroot"; - sequence25 = "light_male_headside.dsq headside"; - sequence26 = "light_male_recoilde.dsq light_recoil"; - sequence27 = "light_male_sitting.dsq sitting"; - sequence28 = "light_male_celsalute.dsq cel1"; - sequence29 = "light_male_celwave.dsq cel2"; - sequence30 = "light_male_tauntbest.dsq cel3"; - sequence31 = "light_male_tauntimp.dsq cel4"; - sequence32 = "light_male_celdisco.dsq cel5"; - sequence33 = "light_male_celflex.dsq cel6"; - sequence34 = "light_male_celtaunt.dsq cel7"; - sequence35 = "light_male_celrocky.dsq cel8"; - sequence36 = "TR2light_male_ski.dsq ski"; - sequence37 = "light_male_standjump.dsq standjump"; - sequence38 = "light_male_looknw.dsq looknw"; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2medium_female.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2medium_female.cs deleted file mode 100644 index 2a49761f..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2medium_female.cs +++ /dev/null @@ -1,42 +0,0 @@ -datablock TSShapeConstructor(TR2MediumFemaleDts) -{ - baseShape = "TR2medium_female.dts"; - sequence0 = "TR2medium_female_root.dsq root"; - sequence1 = "TR2medium_female_forward.dsq run"; - sequence2 = "TR2medium_female_back.dsq back"; - sequence3 = "TR2medium_female_side.dsq side"; - sequence4 = "medium_female_lookde.dsq look"; - sequence5 = "medium_female_head.dsq head"; - sequence6 = "medium_female_headside.dsq headside"; - sequence7 = "TR2medium_female_fall.dsq fall"; - sequence8 = "TR2medium_female_jet.dsq jet"; - sequence9 = "TR2medium_female_land.dsq land"; - sequence10 = "TR2medium_female_jump.dsq jump"; - sequence11 = "medium_female_recoilde.dsq light_recoil"; - sequence12 = "medium_female_looksn.dsq looksn"; - sequence13 = "medium_female_lookms.dsq lookms"; - sequence14 = "medium_female_sitting.dsq sitting"; - sequence15 = "medium_female_idlepda.dsq pda"; - sequence16 = "TR2medium_female_diehead.dsq death1"; - sequence17 = "TR2medium_female_diechest.dsq death2"; - sequence18 = "TR2medium_female_dieback.dsq death3"; - sequence19 = "TR2medium_female_diesidelf.dsq death4"; - sequence20 = "TR2medium_female_diesidert.dsq death5"; - sequence21 = "TR2medium_female_dieleglf.dsq death6"; - sequence22 = "TR2medium_female_dielegrt.dsq death7"; - sequence23 = "TR2medium_female_dieslump.dsq death8"; - sequence24 = "TR2medium_female_dieknees.dsq death9"; - sequence25 = "TR2medium_female_dieforward.dsq death10"; - sequence26 = "TR2medium_female_diespin.dsq death11"; - sequence27 = "TR2medium_female_celsalute.dsq cel1"; - sequence28 = "TR2medium_female_celwave.dsq cel2"; - sequence29 = "TR2medium_female_tauntbest.dsq cel3"; - sequence30 = "TR2medium_female_tauntimp.dsq cel4"; - sequence31 = "TR2medium_female_celdisco.dsq cel5"; - sequence32 = "TR2medium_female_tauntkiss.dsq cel6"; - sequence33 = "TR2medium_female_tauntbutt.dsq cel7"; - sequence34 = "TR2medium_female_celbow.dsq cel8"; - sequence35 = "TR2medium_female_ski.dsq ski"; - sequence36 = "TR2medium_female_standjump.dsq standjump"; - sequence37 = "medium_female_looknw.dsq looknw"; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2medium_male.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2medium_male.cs deleted file mode 100644 index 7b18da4f..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/TR2medium_male.cs +++ /dev/null @@ -1,43 +0,0 @@ - -datablock TSShapeConstructor(TR2MediumMaleDts) -{ - baseShape = "TR2medium_male.dts"; - sequence0 = "TR2medium_male_root.dsq root"; - sequence1 = "TR2medium_male_forward.dsq run"; - sequence2 = "TR2medium_male_back.dsq back"; - sequence3 = "TR2medium_male_side.dsq side"; - sequence4 = "medium_male_lookde.dsq look"; - sequence5 = "medium_male_head.dsq head"; - sequence6 = "TR2medium_male_fall.dsq fall"; - sequence7 = "TR2medium_male_jet.dsq jet"; - sequence8 = "TR2medium_male_land.dsq land"; - sequence9 = "TR2medium_male_jump.dsq jump"; - sequence10 = "medium_male_recoilde.dsq light_recoil"; - sequence11 = "medium_male_headside.dsq headside"; - sequence12 = "medium_male_looksn.dsq looksn"; - sequence13 = "medium_male_lookms.dsq lookms"; - sequence14 = "TR2medium_male_sitting.dsq sitting"; - sequence15 = "TR2medium_male_diehead.dsq death1"; - sequence16 = "TR2medium_male_diechest.dsq death2"; - sequence17 = "TR2medium_male_dieback.dsq death3"; - sequence18 = "TR2medium_male_diesidelf.dsq death4"; - sequence19 = "TR2medium_male_diesidert.dsq death5"; - sequence20 = "TR2medium_male_dieleglf.dsq death6"; - sequence21 = "TR2medium_male_diechest.dsq death7"; // medium_male_dielegrt - sequence22 = "TR2medium_male_dieback.dsq death8"; - sequence23 = "TR2medium_male_dieknees.dsq death9"; - sequence24 = "TR2medium_male_dieforward.dsq death10"; - sequence25 = "TR2medium_male_diespin.dsq death11"; - sequence26 = "medium_male_idlepda.dsq pda"; - sequence27 = "TR2medium_male_celsalute.dsq cel1"; - sequence28 = "TR2medium_male_celwave.dsq cel2"; - sequence29 = "TR2medium_male_tauntbest.dsq cel3"; - sequence30 = "TR2medium_male_tauntimp.dsq cel4"; - sequence31 = "TR2medium_male_celdance.dsq cel5"; - sequence32 = "TR2medium_male_celflex.dsq cel6"; - sequence33 = "TR2medium_male_celtaunt.dsq cel7"; - sequence34 = "TR2medium_male_celrocky.dsq cel8"; - sequence35 = "TR2medium_male_ski.dsq ski"; - sequence36 = "TR2medium_male_standjump.dsq standjump"; - sequence37 = "medium_male_looknw.dsq looknw"; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/packs/TR2energypack.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/packs/TR2energypack.cs deleted file mode 100644 index 02975480..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/packs/TR2energypack.cs +++ /dev/null @@ -1,75 +0,0 @@ -// ------------------------------------------------------------------ -// ENERGY PACK -// can be used by any armor type -// does not have to be activated -// increases the user's energy recharge rate - -datablock ShapeBaseImageData(TR2EnergyPackImage) -{ - shapeFile = "pack_upgrade_energy.dts"; - item = TR2EnergyPack; - mountPoint = 1; - offset = "0 0 0"; - rechargeRateBoost = 0.11;//0.15; - - stateName[0] = "default"; - stateSequence[0] = "activation"; -}; - -datablock ItemData(TR2EnergyPack) -{ - className = Pack; - catagory = "Packs"; - shapeFile = "pack_upgrade_energy.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - rotate = true; - image = "TR2EnergyPackImage"; - pickUpName = "an energy pack"; - - computeCRC = false; - -}; - -function TR2EnergyPackImage::onMount(%data, %obj, %node) -{ - %obj.setRechargeRate(%obj.getRechargeRate() + %data.rechargeRateBoost); - %obj.hasEnergyPack = true; // set for sniper check -} - -function TR2EnergyPackImage::onUnmount(%data, %obj, %node) -{ - %obj.setRechargeRate(%obj.getRechargeRate() - %data.rechargeRateBoost); - %obj.hasEnergyPack = ""; -} - -// KP: Tried adding these, but putting state transitions in -// the above datablock causes a UE. =( -function TR2EnergyPackImage::onActivate(%data, %obj, %slot) -{ - if (%obj.holdingFlag > 0) - { - %obj.flagThrowStrength = 1.5; - %obj.throwObject(%obj.holdingFlag); - } - //messageClient(%obj.client, 'MsgShieldPackOn', '\c2Shield pack on.'); - //%obj.isShielded = true; - //if ( !isDemo() ) - // commandToClient( %obj.client, 'setShieldIconOn' ); -} - -function TR2EnergyPackImage::onDeactivate(%data, %obj, %slot) -{ - //messageClient(%obj.client, 'MsgShieldPackOff', '\c2Shield pack off.'); - //%obj.setImageTrigger(%slot,false); - //%obj.isShielded = ""; - //if ( !isDemo() ) - // commandToClient( %obj.client, 'setShieldIconOff' ); -} - -function TR2EnergyPack::onPickup(%this, %obj, %shape, %amount) -{ - // created to prevent console errors -} diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2chaingun.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2chaingun.cs deleted file mode 100644 index 79f6b43a..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2chaingun.cs +++ /dev/null @@ -1,676 +0,0 @@ -//-------------------------------------- -// TR2Chaingun -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(TR2ChaingunSwitchEffect) -{ - effectname = "weapons/TR2Chaingun_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2ChaingunFireEffect) -{ - effectname = "weapons/TR2Chaingun_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2ChaingunSpinUpEffect) -{ - effectname = "weapons/TR2Chaingun_spinup"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2ChaingunSpinDownEffect) -{ - effectname = "weapons/TR2Chaingun_spindown"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2ChaingunDryFire) -{ - effectname = "weapons/TR2Chaingun_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(TR2ChaingunSwitchSound) -{ - filename = "fx/weapons/chaingun_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2ChaingunSwitchEffect; -}; - -datablock AudioProfile(TR2ChaingunFireSound) -{ - filename = "fx/weapons/chaingun_fire.wav"; - description = AudioDefaultLooping3d; - preload = true; - effect = TR2ChaingunFireEffect; -}; - -datablock AudioProfile(TR2ChaingunProjectile) -{ - filename = "fx/weapons/chaingun_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(TR2ChaingunImpact) -{ - filename = "fx/weapons/chaingun_impact.WAV"; - description = AudioClosest3d; - preload = true; -}; - -datablock AudioProfile(TR2ChaingunSpinDownSound) -{ - filename = "fx/weapons/chaingun_spindown.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2ChaingunSpinDownEffect; -}; - -datablock AudioProfile(TR2ChaingunSpinUpSound) -{ - filename = "fx/weapons/chaingun_spinup.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2ChaingunSpinUpEffect; -}; - -datablock AudioProfile(TR2ChaingunDryFireSound) -{ - filename = "fx/weapons/chaingun_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = TR2ChaingunDryFire; -}; - -datablock AudioProfile(ShrikeBlasterProjectileSound) -{ - filename = "fx/vehicles/shrike_blaster_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- - -datablock ParticleData( TR2ChaingunSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -1.4; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.05; - sizes[1] = 0.2; - sizes[2] = 0.2; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( TR2ChaingunSplashEmitter ) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "TR2ChaingunSplashParticle"; -}; - - -datablock SplashData(TR2ChaingunSplash) -{ - numSegments = 10; - ejectionFreq = 10; - ejectionAngle = 20; - ringLifetime = 0.4; - lifetimeMS = 400; - velocity = 3.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = TR2ChaingunSplashEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Particle Effects -//-------------------------------------- -datablock ParticleData(TR2ChaingunFireParticle) -{ - dragCoefficient = 2.75; - gravityCoefficient = 0.1; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 550; - lifetimeVarianceMS = 0; - textureName = "particleTest"; - colors[0] = "0.46 0.36 0.26 1.0"; - colors[1] = "0.46 0.36 0.26 0.0"; - sizes[0] = 0.25; - sizes[1] = 0.20; -}; - -datablock ParticleEmitterData(TR2ChaingunFireEmitter) -{ - ejectionPeriodMS = 6; - periodVarianceMS = 0; - ejectionVelocity = 10; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 12; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvance = true; - particles = "TR2ChaingunFireParticle"; -}; - -//-------------------------------------------------------------------------- -// Explosions -//-------------------------------------- -datablock ParticleData(TR2ChaingunExplosionParticle1) -{ - dragCoefficient = 0.65; - gravityCoefficient = 0.3; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 150; - textureName = "particleTest"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 0.0"; - sizes[0] = 0.0625; - sizes[1] = 0.2; -}; - -datablock ParticleEmitterData(TR2ChaingunExplosionEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 0.75; - velocityVariance = 0.25; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "TR2ChaingunExplosionParticle1"; -}; - - - - -datablock ParticleData(TR2ChaingunImpactSmokeParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.2; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1000; - lifetimeVarianceMS = 200; - useInvAlpha = true; - spinRandomMin = -90.0; - spinRandomMax = 90.0; - textureName = "particleTest"; - colors[0] = "0.7 0.7 0.7 0.0"; - colors[1] = "0.7 0.7 0.7 0.4"; - colors[2] = "0.7 0.7 0.7 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2ChaingunImpactSmoke) -{ - ejectionPeriodMS = 8; - periodVarianceMS = 1; - ejectionVelocity = 1.0; - velocityVariance = 0.5; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 35; - overrideAdvances = false; - particles = "TR2ChaingunImpactSmokeParticle"; - lifetimeMS = 50; -}; - - -datablock ParticleData(TR2ChaingunSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/spark00"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 1.0"; - colors[2] = "1.0 0.36 0.26 0.0"; - sizes[0] = 0.6; - sizes[1] = 0.2; - sizes[2] = 0.05; - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(TR2ChaingunSparkEmitter) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 4; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "TR2ChaingunSparks"; -}; - - -datablock ExplosionData(TR2ChaingunExplosion) -{ - soundProfile = TR2ChaingunImpact; - - emitter[0] = TR2ChaingunImpactSmoke; - emitter[1] = TR2ChaingunSparkEmitter; - - faceViewer = false; -}; - - -datablock ShockwaveData(ScoutTR2ChaingunHit) -{ - width = 0.5; - numSegments = 13; - numVertSegments = 1; - velocity = 0.5; - acceleration = 2.0; - lifetimeMS = 900; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = false; - orientToNormal = true; - - texture[0] = "special/shockwave5"; - texture[1] = "special/gradient"; - texWrap = 3.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.3 1.0 0.5"; - colors[2] = "0.0 0.0 1.0 0.0"; -}; - -datablock ParticleData(ScoutTR2ChaingunExplosionParticle1) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent4"; - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.3 1.0 1.0"; - colors[2] = "0.0 0.0 1.0 0.0"; - sizes[0] = 0.25; - sizes[1] = 0.5; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(ScoutTR2ChaingunExplosionEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - ejectionVelocity = 2; - velocityVariance = 1.5; - ejectionOffset = 0.0; - thetaMin = 80; - thetaMax = 90; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "ScoutTR2ChaingunExplosionParticle1"; -}; - -datablock ExplosionData(ScoutTR2ChaingunExplosion) -{ - soundProfile = blasterExpSound; - shockwave = ScoutTR2ChaingunHit; - emitter[0] = ScoutTR2ChaingunExplosionEmitter; -}; - - -//-------------------------------------------------------------------------- -// Particle effects -//-------------------------------------- - - -datablock DebrisData( TR2ShellDebris ) -{ - shapeName = "weapon_chaingun_ammocasing.dts"; - - lifetime = 3.0; - - minSpinSpeed = 300.0; - maxSpinSpeed = 400.0; - - elasticity = 0.5; - friction = 0.2; - - numBounces = 3; - - fade = true; - staticOnMaxBounce = true; - snapOnMaxBounce = true; -}; - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock DecalData(TR2ChaingunDecal1) -{ - sizeX = 0.05; - sizeY = 0.05; - textureName = "special/bullethole1"; -}; -datablock DecalData(TR2ChaingunDecal2) : TR2ChaingunDecal1 -{ - textureName = "special/bullethole2"; -}; - -datablock DecalData(TR2ChaingunDecal3) : TR2ChaingunDecal1 -{ - textureName = "special/bullethole3"; -}; -datablock DecalData(TR2ChaingunDecal4) : TR2ChaingunDecal1 -{ - textureName = "special/bullethole4"; -}; -datablock DecalData(TR2ChaingunDecal5) : TR2ChaingunDecal1 -{ - textureName = "special/bullethole5"; -}; -datablock DecalData(TR2ChaingunDecal6) : TR2ChaingunDecal1 -{ - textureName = "special/bullethole6"; -}; - - -datablock TracerProjectileData(TR2ChaingunBullet) -{ - doDynamicClientHits = true; - - directDamage = 0.065; - directDamageType = $DamageType::Bullet; - explosion = "TR2ChaingunExplosion"; - splash = TR2ChaingunSplash; - - kickBackStrength = 0.0; - sound = TR2ChaingunProjectile; - - dryVelocity = 750.0; - wetVelocity = 280.0; - velInheritFactor = 1.0; - fizzleTimeMS = 3000; - lifetimeMS = 3000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - tracerLength = 30.0;//15.0; - tracerAlpha = false; - tracerMinPixels = 6; - tracerColor = 211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; - //211.0/255.0 @ " " @ 215.0/255.0 @ " " @ 120.0/255.0 @ " 0.75"; - tracerTex[0] = "special/tracer00"; - tracerTex[1] = "special/tracercross"; - tracerWidth = 0.20;//0.10; - crossSize = 0.20; - crossViewAng = 0.990; - renderCross = true; - - decalData[0] = TR2ChaingunDecal1; - decalData[1] = TR2ChaingunDecal2; - decalData[2] = TR2ChaingunDecal3; - decalData[3] = TR2ChaingunDecal4; - decalData[4] = TR2ChaingunDecal5; - decalData[5] = TR2ChaingunDecal6; -}; - -//-------------------------------------------------------------------------- -// Scout Projectile -//-------------------------------------- -datablock TracerProjectileData(ScoutTR2ChaingunBullet) -{ - doDynamicClientHits = true; - - directDamage = 0.125; - explosion = "ScoutTR2ChaingunExplosion"; - splash = TR2ChaingunSplash; - - directDamageType = $DamageType::ShrikeBlaster; - kickBackStrength = 0.0; - - sound = ShrikeBlasterProjectileSound; - - dryVelocity = 400.0; - wetVelocity = 100.0; - velInheritFactor = 1.0; - fizzleTimeMS = 1000; - lifetimeMS = 1000; - explodeOnDeath = false; - reflectOnWaterImpactAngle = 0.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 3000; - - tracerLength = 45.0; - tracerAlpha = false; - tracerMinPixels = 6; - tracerColor = "1.0 1.0 1.0 1.0"; - tracerTex[0] = "special/shrikeBolt"; - tracerTex[1] = "special/shrikeBoltCross"; - tracerWidth = 0.55; - crossSize = 0.99; - crossViewAng = 0.990; - renderCross = true; - -}; - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(TR2ChaingunAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_chaingun.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some chaingun ammo"; - - computeCRC = false; - -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ShapeBaseImageData(TR2ChaingunImage) -{ - className = WeaponImage; - shapeFile = "TR2weapon_chaingun.dts"; - item = TR2Chaingun; - ammo = TR2ChaingunAmmo; - projectile = TR2ChaingunBullet; - projectileType = TracerProjectile; - emap = true; - - casing = TR2ShellDebris; - shellExitDir = "1.0 0.3 1.0"; - shellExitOffset = "0.15 -0.56 -0.1"; - shellExitVariance = 18.0; - shellVelocity = 4.0; - - projectileSpread = 5.5 / 1000.0; - - //-------------------------------------- - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = TR2ChaingunSwitchSound; - stateAllowImageChange[0] = false; - // - stateTimeoutValue[0] = 0.5; - stateTransitionOnTimeout[0] = "Ready"; - stateTransitionOnNoAmmo[0] = "NoAmmo"; - - //-------------------------------------- - stateName[1] = "Ready"; - stateSpinThread[1] = Stop; - // - stateTransitionOnTriggerDown[1] = "Spinup"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - //-------------------------------------- - stateName[2] = "NoAmmo"; - stateTransitionOnAmmo[2] = "Ready"; - stateSpinThread[2] = Stop; - stateTransitionOnTriggerDown[2] = "DryFire"; - - //-------------------------------------- - stateName[3] = "Spinup"; - stateSpinThread[3] = SpinUp; - stateSound[3] = TR2ChaingunSpinupSound; - // - stateTimeoutValue[3] = 0.5; - stateWaitForTimeout[3] = false; - stateTransitionOnTimeout[3] = "Fire"; - stateTransitionOnTriggerUp[3] = "Spindown"; - - //-------------------------------------- - stateName[4] = "Fire"; - stateSequence[4] = "Fire"; - stateSequenceRandomFlash[4] = true; - stateSpinThread[4] = FullSpeed; - stateSound[4] = TR2ChaingunFireSound; - //stateRecoil[4] = LightRecoil; - stateAllowImageChange[4] = false; - stateScript[4] = "onFire"; - stateFire[4] = true; - stateEjectShell[4] = true; - // - stateTimeoutValue[4] = 0.15; - stateTransitionOnTimeout[4] = "Fire"; - stateTransitionOnTriggerUp[4] = "Spindown"; - stateTransitionOnNoAmmo[4] = "EmptySpindown"; - - //-------------------------------------- - stateName[5] = "Spindown"; - stateSound[5] = TR2ChaingunSpinDownSound; - stateSpinThread[5] = SpinDown; - // - stateTimeoutValue[5] = 0.4;//1.0; - stateWaitForTimeout[5] = false;//true; - stateTransitionOnTimeout[5] = "Ready"; - stateTransitionOnTriggerDown[5] = "Spinup"; - - //-------------------------------------- - stateName[6] = "EmptySpindown"; - stateSound[6] = TR2ChaingunSpinDownSound; - stateSpinThread[6] = SpinDown; - // - stateTimeoutValue[6] = 0.5; - stateTransitionOnTimeout[6] = "NoAmmo"; - - //-------------------------------------- - stateName[7] = "DryFire"; - stateSound[7] = TR2ChaingunDryFireSound; - stateTimeoutValue[7] = 0.5; - stateTransitionOnTimeout[7] = "NoAmmo"; -}; - -datablock ItemData(TR2Chaingun) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "TR2weapon_chaingun.dts"; - image = TR2ChaingunImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a chaingun"; - - computeCRC = true; - emap = true; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2disc.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2disc.cs deleted file mode 100644 index 06a8e03f..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2disc.cs +++ /dev/null @@ -1,484 +0,0 @@ -//-------------------------------------- -// TR2Disc launcher -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(TR2DiscFireEffect) -{ - effectname = "weapons/Tspinfusor_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2DiscSwitchEffect) -{ - effectname = "weapons/spinfusor_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2DiscDryFireEffect) -{ - effectname = "weapons/spinfusor_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2DiscIdleEffect) -{ - effectname = "weapons/spinfusor_idle"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2DiscReloadEffect) -{ - effectname = "weapons/spinfusor_reload"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2DiscExpEffect) -{ - effectname = "explosions/grenade_explode"; - minDistance = 5; - maxDistance = 20; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(TR2DiscSwitchSound) -{ - filename = "fx/weapons/blaster_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2DiscSwitchEffect; -}; - -datablock AudioProfile(TR2DiscLoopSound) -{ - filename = "fx/weapons/spinfusor_idle.wav"; - description = ClosestLooping3d; - effect = TR2DiscIdleEffect; -}; - - -datablock AudioProfile(TR2DiscFireSound) -{ - filename = "fx/weapons/TR2spinfusor_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = TR2DiscFireEffect; -}; - -datablock AudioProfile(TR2DiscReloadSound) -{ - filename = "fx/weapons/spinfusor_reload.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2DiscReloadEffect; -}; - -datablock AudioProfile(TR2DiscExpSound) -{ - filename = "fx/weapons/spinfusor_impact.wav"; - description = AudioExplosion3d; - preload = true; - effect = TR2DiscExpEffect; -}; - -datablock AudioProfile(underwaterTR2DiscExpSound) -{ - filename = "fx/weapons/spinfusor_impact_UW.wav"; - description = AudioExplosion3d; - preload = true; - effect = TR2DiscExpEffect; -}; - -datablock AudioProfile(TR2DiscProjectileSound) -{ - filename = "fx/weapons/spinfusor_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(TR2DiscDryFireSound) -{ - filename = "fx/weapons/spinfusor_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = TR2DiscDryFireEffect; -}; - -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------- -datablock ParticleData(TR2DiscExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 2000; - lifetimeVarianceMS = 750; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 1.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.3; - times[2] = 1.0; -}; -datablock ParticleEmitterData(TR2DiscExplosionBubbleEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 3.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "TR2DiscExplosionBubbleParticle"; -}; - -datablock ExplosionData(UnderwaterTR2DiscExplosion) -{ - explosionShape = "Disc_explosion.dts"; - soundProfile = underwaterTR2DiscExpSound; - - faceViewer = true; - - sizes[0] = "1.3 1.3 1.3"; - sizes[1] = "0.75 0.75 0.75"; - sizes[2] = "0.4 0.4 0.4"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - emitter[0] = "TR2DiscExplosionBubbleEmitter"; - - shakeCamera = false;//true; - camShakeFreq = "10.0 11.0 10.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 10.0; -}; - -datablock ExplosionData(TR2DiscExplosion) -{ - explosionShape = "Disc_explosion.dts"; - soundProfile = TR2DiscExpSound; - - faceViewer = true; - explosionScale = "2.0 2.0 2.0";//"1 1 1"; - - shakeCamera = false;//true; - camShakeFreq = "10.0 11.0 10.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 10.0; - - sizes[0] = "2.5 2.5 2.5";//"1.0 1.0 1.0"; - sizes[1] = "2.5 2.5 2.5";//"1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- -datablock ParticleData(TR2DiscMist) -{ - dragCoefficient = 2.0; - gravityCoefficient = -0.05; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 400; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2DiscMistEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 3.0; - velocityVariance = 2.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "TR2DiscMist"; -}; - -datablock ParticleData( TR2DiscSplashParticle2 ) -{ - - dragCoeffiecient = 0.4; - gravityCoefficient = -0.03; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 600; - lifetimeVarianceMS = 300; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 1.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( TR2DiscSplashEmitter2 ) -{ - ejectionPeriodMS = 25; - ejectionOffset = 0.2; - periodVarianceMS = 0; - ejectionVelocity = 2.25; - velocityVariance = 0.50; - thetaMin = 0.0; - thetaMax = 30.0; - lifetimeMS = 250; - - particles = "TR2DiscSplashParticle2"; -}; - - -datablock ParticleData( TR2DiscSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.2; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( TR2DiscSplashEmitter ) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 60; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "TR2DiscSplashParticle"; -}; - - -datablock SplashData(TR2DiscSplash) -{ - numSegments = 15; - ejectionFreq = 0.0001; - ejectionAngle = 45; - ringLifetime = 0.5; - lifetimeMS = 400; - velocity = 5.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = TR2DiscSplashEmitter; - emitter[1] = TR2DiscMistEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock LinearProjectileData(TR2DiscProjectile) -{ - projectileShapeName = "Disc.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 0.5;//0.35;//0.50; - damageRadius = 15;//11;//7.5; - radiusDamageType = $DamageType::Disc; - kickBackStrength = 6100;//1750; - - sound = TR2DiscProjectileSound; - explosion = "TR2DiscExplosion"; - underwaterExplosion = "UnderwaterTR2DiscExplosion"; - splash = TR2DiscSplash; - - dryVelocity = 130;//90; - wetVelocity = 120; - velInheritFactor = 0.7; - fizzleTimeMS = 5000; - lifetimeMS = 5000; - explodeOnDeath = true; - reflectOnWaterImpactAngle = 30.0;//15.0; - explodeOnWaterImpact = false; - deflectionOnWaterImpact = 0.0; - fizzleUnderwaterMS = 5000; - - activateDelayMS = 100; - - hasLight = true; - lightRadius = 6.0; - lightColor = "0.175 0.175 1.0"; -}; - - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(TR2DiscAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_disc.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some spinfusor discs"; - computeCRC = false; -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- - -datablock ShapeBaseImageData(TR2DiscImage) -{ - className = WeaponImage; - shapeFile = "TR2weapon_disc.dts"; - item = TR2Disc; - ammo = TR2DiscAmmo; - offset = "0 -0.5 0"; - emap = true; - - projectileSpread = 0.0 / 1000.0; - - projectile = TR2DiscProjectile; - projectileType = LinearProjectile; - - // State Data - stateName[0] = "Preactivate"; - stateTransitionOnLoaded[0] = "Activate"; - stateTransitionOnNoAmmo[0] = "NoAmmo"; - - stateName[1] = "Activate"; - stateTransitionOnTimeout[1] = "Ready"; - stateTimeoutValue[1] = 0.5; - stateSequence[1] = "Activated"; - stateSound[1] = TR2DiscSwitchSound; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - stateSequence[2] = "TR2DiscSpin"; - stateSound[2] = TR2DiscLoopSound; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 1.25; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - stateSound[3] = TR2DiscFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 0.5; // 0.25 load, 0.25 spinup - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = TR2DiscReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = TR2DiscDryFireSound; - stateTimeoutValue[6] = 1.0; - stateTransitionOnTimeout[6] = "NoAmmo"; -}; - -datablock ItemData(TR2Disc) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "TR2weapon_disc.dts"; - image = TR2DiscImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a spinfusor"; - computeCRC = true; - emap = true; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2grenade.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2grenade.cs deleted file mode 100644 index dab9b6d3..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2grenade.cs +++ /dev/null @@ -1,380 +0,0 @@ -// ------------------------------------------------------------------------ -// grenade (thrown by hand) script -// ------------------------------------------------------------------------ -datablock EffectProfile(TR2GrenadeThrowEffect) -{ - effectname = "weapons/grenade_throw"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2GrenadeSwitchEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(TR2GrenadeThrowSound) -{ - filename = "fx/weapons/throw_grenade.wav"; - description = AudioClose3D; - preload = true; - effect = GrenadeThrowEffect; -}; - -datablock AudioProfile(TR2GrenadeSwitchSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3D; - preload = true; - effect = GrenadeSwitchEffect; -}; - -//************************************************************************** -// Hand Grenade underwater fx -//************************************************************************** - - -//-------------------------------------------------------------------------- -// Underwater Hand Grenade Particle effects -//-------------------------------------------------------------------------- -datablock ParticleData(TR2HandGrenadeExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 2000; - lifetimeVarianceMS = 750; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.75; - sizes[1] = 0.75; - sizes[2] = 0.75; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; -datablock ParticleEmitterData(TR2HandGrenadeExplosionBubbleEmitter) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 2.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "TR2HandGrenadeExplosionBubbleParticle"; -}; - -datablock ParticleData(UnderwaterTR2HandGrenadeExplosionSmoke) -{ - dragCoeffiecient = 105.0; - gravityCoefficient = -0.0; // rises slowly - inheritedVelFactor = 0.025; - - constantAcceleration = -1.0; - - lifetimeMS = 1250; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "0.4 0.4 1.0 1.0"; - colors[1] = "0.4 0.4 1.0 0.5"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 3.0; - sizes[2] = 5.0; - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterTR2HandGrenadeExplosionSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - - ejectionVelocity = 5.25; - velocityVariance = 0.25; - - thetaMin = 0.0; - thetaMax = 180.0; - - lifetimeMS = 250; - - particles = "UnderwaterTR2HandGrenadeExplosionSmoke"; -}; - - - -datablock ParticleData(UnderwaterTR2HandGrenadeSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/droplet"; - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.6 1.0 1.0"; - colors[2] = "0.6 0.6 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.25; - sizes[2] = 0.25; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterTR2HandGrenadeSparkEmitter) -{ - ejectionPeriodMS = 3; - periodVarianceMS = 0; - ejectionVelocity = 10; - velocityVariance = 6.75; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "UnderwaterTR2HandGrenadeSparks"; -}; - - - -datablock ExplosionData(UnderwaterTR2HandGrenadeSubExplosion1) -{ - offset = 1.0; - emitter[0] = UnderwaterTR2HandGrenadeExplosionSmokeEmitter; - emitter[1] = UnderwaterTR2HandGrenadeSparkEmitter; -}; - -datablock ExplosionData(UnderwaterTR2HandGrenadeSubExplosion2) -{ - offset = 1.0; - emitter[0] = UnderwaterTR2HandGrenadeExplosionSmokeEmitter; - emitter[1] = UnderwaterTR2HandGrenadeSparkEmitter; -}; - -datablock ExplosionData(UnderwaterTR2HandGrenadeExplosion) -{ - soundProfile = TR2GrenadeExplosionSound; - - emitter[0] = UnderwaterTR2HandGrenadeExplosionSmokeEmitter; - emitter[1] = UnderwaterTR2HandGrenadeSparkEmitter; - emitter[2] = TR2HandGrenadeExplosionBubbleEmitter; - - subExplosion[0] = UnderwaterTR2HandGrenadeSubExplosion1; - subExplosion[1] = UnderwaterTR2HandGrenadeSubExplosion2; - - shakeCamera = true; - camShakeFreq = "12.0 13.0 11.0"; - camShakeAmp = "35.0 35.0 35.0"; - camShakeDuration = 1.0; - camShakeRadius = 15.0; -}; - -//************************************************************************** -// Hand Grenade effects -//************************************************************************** - -//-------------------------------------------------------------------------- -// Grenade Particle effects -//-------------------------------------------------------------------------- - -datablock ParticleData(TR2HandGrenadeExplosionSmoke) -{ - dragCoeffiecient = 105.0; - gravityCoefficient = -0.0; // rises slowly - inheritedVelFactor = 0.025; - - constantAcceleration = -0.80; - - lifetimeMS = 1250; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "1.0 0.7 0.0 1.0"; - colors[1] = "0.2 0.2 0.2 1.0"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 4.0;//1.0; - sizes[1] = 12.0;//3.0; - sizes[2] = 20.0;//5.0; - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(TR2HandGrenadeExplosionSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - - ejectionVelocity = 10.25; - velocityVariance = 0.25; - - thetaMin = 0.0; - thetaMax = 180.0; - - lifetimeMS = 250; - - particles = "TR2HandGrenadeExplosionSmoke"; -}; - - - -datablock ParticleData(TR2HandGrenadeSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/bigSpark"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 1.0"; - colors[2] = "1.0 0.36 0.26 0.0"; - sizes[0] = 3.0;//0.5; - sizes[1] = 1.5;//0.25; - sizes[2] = 1.0;//0.25; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(TR2HandGrenadeSparkEmitter) -{ - ejectionPeriodMS = 3; - periodVarianceMS = 0; - ejectionVelocity = 24;//18; - velocityVariance = 6.75; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 180; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "TR2HandGrenadeSparks"; -}; - - - - -//---------------------------------------------------- -// Explosion -//---------------------------------------------------- - -datablock ExplosionData(TR2HandGrenadeSubExplosion1) -{ - offset = 2.0; - emitter[0] = TR2HandGrenadeExplosionSmokeEmitter; - emitter[1] = TR2HandGrenadeSparkEmitter; -}; - -datablock ExplosionData(TR2HandGrenadeSubExplosion2) -{ - offset = 2.0; - emitter[0] = TR2HandGrenadeExplosionSmokeEmitter; - emitter[1] = TR2HandGrenadeSparkEmitter; -}; - -datablock ExplosionData(TR2HandGrenadeExplosion) -{ - soundProfile = TR2GrenadeExplosionSound; - - emitter[0] = TR2HandGrenadeExplosionSmokeEmitter; - emitter[1] = TR2HandGrenadeSparkEmitter; - - subExplosion[0] = TR2HandGrenadeSubExplosion1; - subExplosion[1] = TR2HandGrenadeSubExplosion2; - - shakeCamera = true; - camShakeFreq = "12.0 13.0 11.0"; - camShakeAmp = "35.0 35.0 35.0"; - camShakeDuration = 1.0; - camShakeRadius = 15.0; -}; - - - - -datablock ItemData(TR2GrenadeThrown) -{ - className = Weapon; - shapeFile = "grenade.dts"; - mass = 0.35;//0.7; - elasticity = 0.2; - friction = 1; - pickupRadius = 2; - maxDamage = 0.5; - explosion = TR2HandGrenadeExplosion; - underwaterExplosion = UnderwaterTR2HandGrenadeExplosion; - indirectDamage = 0.4; - damageRadius = 22.0;//10.0; - radiusDamageType = $DamageType::Grenade; - kickBackStrength = 8000;//2000; - - computeCRC = false; - -}; - -datablock ItemData(TR2Grenade) -{ - className = HandInventory; - catagory = "Handheld"; - shapeFile = "grenade.dts"; - mass = 0.35;//0.7; - elasticity = 0.2; - friction = 1; - pickupRadius = 2; - thrownItem = TR2GrenadeThrown; - pickUpName = "some grenades"; - isGrenade = true; - - computeCRC = false; - -}; - -function TR2GrenadeThrown::onThrow(%this, %gren) -{ - //AIGrenadeThrow(%gren); - %gren.detThread = schedule(2000, %gren, "detonateGrenade", %gren); -} - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2grenadeLauncher.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2grenadeLauncher.cs deleted file mode 100644 index ecf47ab6..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2grenadeLauncher.cs +++ /dev/null @@ -1,788 +0,0 @@ -//-------------------------------------- -// TR2Grenade launcher -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(TR2GrenadeSwitchEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2GrenadeFireEffect) -{ - effectname = "weapons/grenadelauncher_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2GrenadeDryFireEffect) -{ - effectname = "weapons/grenadelauncher_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2GrenadeReloadEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2GrenadeExplosionEffect) -{ - effectname = "explosions/grenade_explode"; - minDistance = 10; - maxDistance = 35; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(TR2GrenadeSwitchSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2GrenadeSwitchEffect; -}; - -datablock AudioProfile(TR2GrenadeFireSound) -{ - filename = "fx/weapons/grenadelauncher_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = TR2GrenadeFireEffect; -}; - -datablock AudioProfile(TR2GrenadeProjectileSound) -{ - filename = "fx/weapons/grenadelauncher_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(TR2GrenadeReloadSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2GrenadeReloadEffect; -}; - -datablock AudioProfile(TR2GrenadeExplosionSound) -{ - filename = "fx/weapons/grenade_explode.wav"; - description = AudioExplosion3d; - preload = true; - effect = TR2GrenadeExplosionEffect; -}; - -datablock AudioProfile(UnderwaterTR2GrenadeExplosionSound) -{ - filename = "fx/weapons/grenade_explode_UW.wav"; - description = AudioExplosion3d; - preload = true; - effect = TR2GrenadeExplosionEffect; -}; - -datablock AudioProfile(TR2GrenadeDryFireSound) -{ - filename = "fx/weapons/grenadelauncher_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = TR2GrenadeDryFireEffect; -}; - -//---------------------------------------------------------------------------- -// Underwater fx -//---------------------------------------------------------------------------- -datablock ParticleData(TR2GrenadeExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 1.0; - sizes[1] = 1.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; -datablock ParticleEmitterData(TR2GrenadeExplosionBubbleEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 3.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "TR2GrenadeExplosionBubbleParticle"; -}; - -datablock ParticleData(UnderwaterTR2GrenadeDust) -{ - dragCoefficient = 1.0; - gravityCoefficient = -0.01; - inheritedVelFactor = 0.0; - constantAcceleration = -1.1; - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - useInvAlpha = false; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.6 0.6 1.0 0.5"; - colors[1] = "0.6 0.6 1.0 0.5"; - colors[2] = "0.6 0.6 1.0 0.0"; - sizes[0] = 3.0; - sizes[1] = 3.0; - sizes[2] = 3.0; - times[0] = 0.0; - times[1] = 0.7; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(UnderwaterTR2GrenadeDustEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 0; - ejectionVelocity = 15.0; - velocityVariance = 0.0; - ejectionOffset = 0.0; - thetaMin = 70; - thetaMax = 70; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "UnderwaterTR2GrenadeDust"; -}; - - -datablock ParticleData(UnderwaterTR2GrenadeExplosionSmoke) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.25; // rises slowly - inheritedVelFactor = 0.025; - constantAcceleration = -1.1; - - lifetimeMS = 1250; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - colors[0] = "0.1 0.1 1.0 1.0"; - colors[1] = "0.4 0.4 1.0 1.0"; - colors[2] = "0.4 0.4 1.0 0.0"; - sizes[0] = 2.0; - sizes[1] = 6.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterTR2GExplosionSmokeEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 0; - - ejectionVelocity = 6.25; - velocityVariance = 0.25; - - thetaMin = 0.0; - thetaMax = 90.0; - - lifetimeMS = 250; - - particles = "UnderwaterTR2GrenadeExplosionSmoke"; -}; - - - -datablock ParticleData(UnderwaterTR2GrenadeSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/underwaterSpark"; - colors[0] = "0.6 0.6 1.0 1.0"; - colors[1] = "0.6 0.6 1.0 1.0"; - colors[2] = "0.6 0.6 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.75; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(UnderwaterTR2GrenadeSparksEmitter) -{ - ejectionPeriodMS = 2; - periodVarianceMS = 0; - ejectionVelocity = 12; - velocityVariance = 6.75; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "UnderwaterTR2GrenadeSparks"; -}; - -datablock ExplosionData(UnderwaterTR2GrenadeExplosion) -{ - soundProfile = UnderwaterTR2GrenadeExplosionSound; - - faceViewer = true; - explosionScale = "0.8 0.8 0.8"; - - emitter[0] = UnderwaterTR2GrenadeDustEmitter; - emitter[1] = UnderwaterTR2GExplosionSmokeEmitter; - emitter[2] = UnderwaterTR2GrenadeSparksEmitter; - emitter[3] = TR2GrenadeExplosionBubbleEmitter; - - shakeCamera = true; - camShakeFreq = "10.0 6.0 9.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 20.0; -}; - - -//---------------------------------------------------------------------------- -// Bubbles -//---------------------------------------------------------------------------- -datablock ParticleData(TR2GrenadeBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.4"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2GrenadeBubbleEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 0.1; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "TR2GrenadeBubbleParticle"; -}; - -//---------------------------------------------------------------------------- -// Debris -//---------------------------------------------------------------------------- - -datablock ParticleData( TR2GDebrisSmokeParticle ) -{ - dragCoeffiecient = 1.0; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - - textureName = "particleTest"; - - useInvAlpha = true; - - spinRandomMin = -60.0; - spinRandomMax = 60.0; - - colors[0] = "0.4 0.4 0.4 1.0"; - colors[1] = "0.3 0.3 0.3 0.5"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 0.0; - sizes[1] = 1.0; - sizes[2] = 1.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( TR2GDebrisSmokeEmitter ) -{ - ejectionPeriodMS = 7; - periodVarianceMS = 1; - - ejectionVelocity = 1.0; // A little oomph at the back end - velocityVariance = 0.2; - - thetaMin = 0.0; - thetaMax = 40.0; - - particles = "TR2GDebrisSmokeParticle"; -}; - - -datablock DebrisData( TR2GrenadeDebris ) -{ - emitters[0] = TR2GDebrisSmokeEmitter; - - explodeOnMaxBounce = true; - - elasticity = 0.4; - friction = 0.2; - - lifetime = 0.3; - lifetimeVariance = 0.02; - - numBounces = 1; -}; - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- - -datablock ParticleData( TR2GrenadeSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -1.4; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.05; - sizes[1] = 0.2; - sizes[2] = 0.2; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( TR2GrenadeSplashEmitter ) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 4; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "BlasterSplashParticle"; -}; - - -datablock SplashData(TR2GrenadeSplash) -{ - numSegments = 15; - ejectionFreq = 15; - ejectionAngle = 40; - ringLifetime = 0.35; - lifetimeMS = 300; - velocity = 3.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = BlasterSplashEmitter; - - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 1.0"; - colors[3] = "0.7 0.8 1.0 1.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//-------------------------------------------------------------------------- -// Particle effects -//-------------------------------------- -datablock ParticleData(TR2GrenadeSmokeParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = -0.2; // rises slowly - inheritedVelFactor = 0.00; - - lifetimeMS = 700; // lasts 2 second - lifetimeVarianceMS = 150; // ...more or less - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -30.0; - spinRandomMax = 30.0; - - // TR2: white - colors[0] = "1.0 1.0 1.0 1.0"; - colors[1] = "0.95 0.95 0.95 1.0"; - colors[2] = "0.9 0.9 0.9 0.0"; - - sizes[0] = 0.7;//0.25; - sizes[1] = 2.4;//1.0; - sizes[2] = 7.0;//3.0; - - times[0] = 0.0; - times[1] = 0.2; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2GrenadeSmokeEmitter) -{ - ejectionPeriodMS = 15; - periodVarianceMS = 5; - - ejectionVelocity = 1.25; - velocityVariance = 0.50; - - thetaMin = 0.0; - thetaMax = 90.0; - - particles = "TR2GrenadeSmokeParticle"; -}; - - -datablock ParticleData(TR2GrenadeDust) -{ - dragCoefficient = 1.0; - gravityCoefficient = -0.01; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1000; - lifetimeVarianceMS = 100; - useInvAlpha = true; - spinRandomMin = -90.0; - spinRandomMax = 500.0; - textureName = "particleTest"; - colors[0] = "0.3 0.3 0.3 0.5"; - colors[1] = "0.3 0.3 0.3 0.5"; - colors[2] = "0.3 0.3 0.3 0.0"; - sizes[0] = 7.0;//3.2; - sizes[1] = 10.0;//4.6; - sizes[2] = 11.0;//5.0; - times[0] = 0.0; - times[1] = 0.7; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2GrenadeDustEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 15.0; - velocityVariance = 0.0; - ejectionOffset = 0.0; - thetaMin = 85; - thetaMax = 85; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - lifetimeMS = 250; - particles = "TR2GrenadeDust"; -}; - - -datablock ParticleData(TR2GrenadeExplosionSmoke) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.5; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 1250; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -200.0; - spinRandomMax = 200.0; - - textureName = "special/Smoke/smoke_001"; - - // TR2: Red/orange - colors[0] = "0.9 0.7 0.7 1.0"; - colors[1] = "0.8 0.4 0.2 1.0"; - colors[2] = "0.6 0.2 0.1 0.0"; - sizes[0] = 6.0;//2.0; - sizes[1] = 18.0;//6.0; - sizes[2] = 6.0;//2.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2GExplosionSmokeEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - - ejectionVelocity = 6.25; - velocityVariance = 0.25; - - thetaMin = 0.0; - thetaMax = 90.0; - - lifetimeMS = 250; - - particles = "TR2GrenadeExplosionSmoke"; -}; - - - -datablock ParticleData(TR2GrenadeSparks) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/bigspark"; - colors[0] = "0.56 0.36 0.26 1.0"; - colors[1] = "0.56 0.36 0.26 1.0"; - colors[2] = "1.0 0.36 0.26 0.0"; - sizes[0] = 9.0;//0.5; - sizes[1] = 9.0;//0.5; - sizes[2] = 12.0;//0.75; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(TR2GrenadeSparksEmitter) -{ - ejectionPeriodMS = 2; - periodVarianceMS = 0; - ejectionVelocity = 12; - velocityVariance = 6.75; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "TR2GrenadeSparks"; -}; - - - - -//---------------------------------------------------- -// Explosion -//---------------------------------------------------- -datablock ExplosionData(TR2GrenadeExplosion) -{ - soundProfile = TR2GrenadeExplosionSound; - - faceViewer = true; - explosionScale = "3.0 3.0 3.0";//"0.8 0.8 0.8"; - - debris = TR2GrenadeDebris; - debrisThetaMin = 10; - debrisThetaMax = 50; - debrisNum = 8; - debrisVelocity = 52.0;//26.0; - debrisVelocityVariance = 14.0;//7.0; - - emitter[0] = TR2GrenadeDustEmitter; - emitter[1] = TR2GExplosionSmokeEmitter; - emitter[2] = TR2GrenadeSparksEmitter; - - shakeCamera = true; - camShakeFreq = "10.0 6.0 9.0"; - camShakeAmp = "20.0 20.0 20.0"; - camShakeDuration = 0.5; - camShakeRadius = 20.0; -}; - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock GrenadeProjectileData(BasicTR2Grenade) -{ - projectileShapeName = "grenade_projectile.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 0.40; - damageRadius = 27;//20.0; - radiusDamageType = $DamageType::Grenade; - kickBackStrength = 7200;//1500; - bubbleEmitTime = 1.0; - - sound = TR2GrenadeProjectileSound; - explosion = "TR2GrenadeExplosion"; - underwaterExplosion = "UnderwaterTR2GrenadeExplosion"; - velInheritFactor = 0.62;//0.7;//0.5; - splash = TR2GrenadeSplash; - - baseEmitter = TR2GrenadeSmokeEmitter; - bubbleEmitter = TR2GrenadeBubbleEmitter; - - grenadeElasticity = 0.15;//0.25;//0.35; - grenadeFriction = 0.09;//0.2;//0.2; - armingDelayMS = 1000; - muzzleVelocity = 165;//78;//47.00; - drag = 0.09;//0.15;//0.1; - gravityMod = 2.75; -}; - - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(TR2GrenadeLauncherAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_grenade.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some grenade launcher ammo"; - - computeCRC = false; - emap = true; -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ItemData(TR2GrenadeLauncher) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "TR2weapon_grenade_launcher.dts"; - image = TR2GrenadeLauncherImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a grenade launcher"; - - computeCRC = true; - -}; - -datablock ShapeBaseImageData(TR2GrenadeLauncherImage) -{ - className = WeaponImage; - shapeFile = "TR2weapon_grenade_launcher.dts"; - item = TR2GrenadeLauncher; - ammo = TR2GrenadeLauncherAmmo; - offset = "0 0 0"; - emap = true; - - projectile = BasicTR2Grenade; - projectileType = GrenadeProjectile; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = TR2GrenadeSwitchSound; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.4; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - stateSound[3] = TR2GrenadeFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 0.5; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = TR2GrenadeReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = TR2GrenadeDryFireSound; - stateTimeoutValue[6] = 1.5; - stateTransitionOnTimeout[6] = "NoAmmo"; -}; diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2mortar.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2mortar.cs deleted file mode 100644 index 022283cc..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2mortar.cs +++ /dev/null @@ -1,799 +0,0 @@ -//-------------------------------------- -// Mortar -//-------------------------------------- - -//-------------------------------------------------------------------------- -// Force-Feedback Effects -//-------------------------------------- -datablock EffectProfile(TR2MortarSwitchEffect) -{ - effectname = "weapons/mortar_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2MortarFireEffect) -{ - effectname = "weapons/mortar_fire"; - minDistance = 2.5; - maxDistance = 5.0; -}; - -datablock EffectProfile(TR2MortarReloadEffect) -{ - effectname = "weapons/mortar_reload"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2MortarDryFireEffect) -{ - effectname = "weapons/mortar_dryfire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2MortarExplosionEffect) -{ - effectname = "explosions/explosion.xpl03"; - minDistance = 30; - maxDistance = 65; -}; - -//-------------------------------------------------------------------------- -// Sounds -//-------------------------------------- -datablock AudioProfile(TR2MortarSwitchSound) -{ - filename = "fx/weapons/mortar_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2MortarSwitchEffect; -}; - -datablock AudioProfile(TR2MortarReloadSound) -{ - filename = "fx/weapons/mortar_reload.wav"; - description = AudioClosest3d; - preload = true; - effect = TR2MortarReloadEffect; -}; - -// DELETE IF NOT NEEDED -//datablock AudioProfile(TR2MortarIdleSound) -//{ -// filename = "fx/weapons/weapon.mortarIdle.wav"; -// description = ClosestLooping3d; -// preload = true; -//}; - -datablock AudioProfile(TR2MortarFireSound) -{ - filename = "fx/weapons/mortar_fire.wav"; - description = AudioDefault3d; - preload = true; - effect = TR2MortarFireEffect; -}; - -datablock AudioProfile(TR2MortarProjectileSound) -{ - filename = "fx/weapons/mortar_projectile.wav"; - description = ProjectileLooping3d; - preload = true; -}; - -datablock AudioProfile(TR2MortarExplosionSound) -{ - filename = "fx/weapons/mortar_explode.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = TR2MortarExplosionEffect; -}; - -datablock AudioProfile(UnderwaterTR2MortarExplosionSound) -{ - filename = "fx/weapons/mortar_explode_UW.wav"; - description = AudioBIGExplosion3d; - preload = true; - effect = TR2MortarExplosionEffect; -}; - -datablock AudioProfile(TR2MortarDryFireSound) -{ - filename = "fx/weapons/mortar_dryfire.wav"; - description = AudioClose3d; - preload = true; - effect = TR2MortarDryFireEffect; -}; - -//---------------------------------------------------------------------------- -// Bubbles -//---------------------------------------------------------------------------- -datablock ParticleData(TR2MortarBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.4"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.8; - sizes[1] = 0.8; - sizes[2] = 0.8; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2MortarBubbleEmitter) -{ - ejectionPeriodMS = 9; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 0.1; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "TR2MortarBubbleParticle"; -}; - -//-------------------------------------------------------------------------- -// Splash -//-------------------------------------------------------------------------- -datablock ParticleData( TR2MortarSplashParticle ) -{ - dragCoefficient = 1; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -1.4; - lifetimeMS = 300; - lifetimeVarianceMS = 0; - textureName = "special/droplet"; - colors[0] = "0.7 0.8 1.0 1.0"; - colors[1] = "0.7 0.8 1.0 0.5"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 0.05; - sizes[1] = 0.2; - sizes[2] = 0.2; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( TR2MortarSplashEmitter ) -{ - ejectionPeriodMS = 4; - periodVarianceMS = 0; - ejectionVelocity = 3; - velocityVariance = 1.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 50; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "TR2MortarSplashParticle"; -}; - - -datablock SplashData(TR2MortarSplash) -{ - numSegments = 10; - ejectionFreq = 10; - ejectionAngle = 20; - ringLifetime = 0.4; - lifetimeMS = 400; - velocity = 3.0; - startRadius = 0.0; - acceleration = -3.0; - texWrap = 5.0; - - texture = "special/water2"; - - emitter[0] = TR2MortarSplashEmitter; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 1.0"; - colors[2] = "0.7 0.8 1.0 0.0"; - colors[3] = "0.7 0.8 1.0 0.0"; - times[0] = 0.0; - times[1] = 0.4; - times[2] = 0.8; - times[3] = 1.0; -}; - -//--------------------------------------------------------------------------- -// Mortar Shockwaves -//--------------------------------------------------------------------------- -datablock ShockwaveData(UnderwaterTR2MortarShockwave) -{ - width = 6.0; - numSegments = 32; - numVertSegments = 6; - velocity = 10; - acceleration = 20.0; - lifetimeMS = 900; - height = 1.0; - verticalCurve = 0.5; - is2D = false; - - texture[0] = "special/shockwave4"; - texture[1] = "special/gradient"; - texWrap = 6.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.4 0.4 1.0 0.50"; - colors[1] = "0.4 0.4 1.0 0.25"; - colors[2] = "0.4 0.4 1.0 0.0"; - - mapToTerrain = true; - orientToNormal = false; - renderBottom = false; -}; - -datablock ShockwaveData(TR2MortarShockwave) -{ - width = 6.0; - numSegments = 32; - numVertSegments = 6; - velocity = 30; - acceleration = 20.0; - lifetimeMS = 500; - height = 1.0; - verticalCurve = 0.5; - is2D = false; - - texture[0] = "special/shockwave4"; - texture[1] = "special/gradient"; - texWrap = 6.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "0.4 1.0 0.4 0.50"; - colors[1] = "0.4 1.0 0.4 0.25"; - colors[2] = "0.4 1.0 0.4 0.0"; - - mapToTerrain = true; - orientToNormal = false; - renderBottom = false; -}; - - -//-------------------------------------------------------------------------- -// Mortar Explosion Particle effects -//-------------------------------------- -datablock ParticleData( TR2MortarCrescentParticle ) -{ - dragCoefficient = 2; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = -0.0; - lifetimeMS = 600; - lifetimeVarianceMS = 000; - textureName = "special/crescent3"; - colors[0] = "0.7 1.0 0.7 1.0"; - colors[1] = "0.7 1.0 0.7 0.5"; - colors[2] = "0.7 1.0 0.7 0.0"; - sizes[0] = 8.0; - sizes[1] = 16.0; - sizes[2] = 18.0; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData( TR2MortarCrescentEmitter ) -{ - ejectionPeriodMS = 25; - periodVarianceMS = 0; - ejectionVelocity = 40; - velocityVariance = 5.0; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 200; - particles = "TR2MortarCrescentParticle"; -}; - - -datablock ParticleData(TR2MortarExplosionSmoke) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.30; // rises slowly - inheritedVelFactor = 0.025; - - lifetimeMS = 1250; - lifetimeVarianceMS = 500; - - textureName = "particleTest"; - - useInvAlpha = true; - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - textureName = "special/Smoke/bigSmoke"; - - colors[0] = "0.7 0.7 0.7 0.0"; - colors[1] = "0.4 0.4 0.4 0.5"; - colors[2] = "0.4 0.4 0.4 0.5"; - colors[3] = "0.4 0.4 0.4 0.0"; - sizes[0] = 25.0; - sizes[1] = 28.0; - sizes[2] = 40.0; - sizes[3] = 56.0; - times[0] = 0.0; - times[1] = 0.333; - times[2] = 0.666; - times[3] = 1.0; - - - -}; - -datablock ParticleEmitterData(TR2MortarExplosionSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 0; - - ejectionOffset = 8.0; - - - ejectionVelocity = 7.0;//3.25; - velocityVariance = 1.2; - - thetaMin = 0.0; - thetaMax = 90.0; - - lifetimeMS = 500; - - particles = "TR2MortarExplosionSmoke"; - -}; - -//--------------------------------------------------------------------------- -// Underwater Explosion -//--------------------------------------------------------------------------- -datablock ParticleData(TR2UnderwaterExplosionSparks) -{ - dragCoefficient = 0; - gravityCoefficient = 0.0; - inheritedVelFactor = 0.2; - constantAcceleration = 0.0; - lifetimeMS = 500; - lifetimeVarianceMS = 350; - textureName = "special/crescent3"; - colors[0] = "0.4 0.4 1.0 1.0"; - colors[1] = "0.4 0.4 1.0 1.0"; - colors[2] = "0.4 0.4 1.0 0.0"; - sizes[0] = 3.5; - sizes[1] = 3.5; - sizes[2] = 3.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ParticleEmitterData(TR2UnderwaterExplosionSparksEmitter) -{ - ejectionPeriodMS = 2; - periodVarianceMS = 0; - ejectionVelocity = 17; - velocityVariance = 4; - ejectionOffset = 0.0; - thetaMin = 0; - thetaMax = 60; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - orientParticles = true; - lifetimeMS = 100; - particles = "TR2UnderwaterExplosionSparks"; -}; - -datablock ParticleData(TR2MortarExplosionBubbleParticle) -{ - dragCoefficient = 0.0; - gravityCoefficient = -0.25; - inheritedVelFactor = 0.0; - constantAcceleration = 0.0; - lifetimeMS = 1500; - lifetimeVarianceMS = 600; - useInvAlpha = false; - textureName = "special/bubbles"; - - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - colors[0] = "0.7 0.8 1.0 0.0"; - colors[1] = "0.7 0.8 1.0 0.4"; - colors[2] = "0.7 0.8 1.0 0.0"; - sizes[0] = 2.0; - sizes[1] = 2.0; - sizes[2] = 2.0; - times[0] = 0.0; - times[1] = 0.8; - times[2] = 1.0; -}; -datablock ParticleEmitterData(TR2MortarExplosionBubbleEmitter) -{ - ejectionPeriodMS = 5; - periodVarianceMS = 0; - ejectionVelocity = 1.0; - ejectionOffset = 7.0; - velocityVariance = 0.5; - thetaMin = 0; - thetaMax = 80; - phiReferenceVel = 0; - phiVariance = 360; - overrideAdvances = false; - particles = "TR2MortarExplosionBubbleParticle"; -}; - -datablock DebrisData( UnderwaterTR2MortarDebris ) -{ - emitters[0] = MortarExplosionBubbleEmitter; - - explodeOnMaxBounce = true; - - elasticity = 0.4; - friction = 0.2; - - lifetime = 1.5; - lifetimeVariance = 0.2; - - numBounces = 1; -}; - -datablock ExplosionData(UnderwaterTR2MortarSubExplosion1) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - delayMS = 100; - offset = 3.0; - playSpeed = 1.5; - - sizes[0] = "3.25 3.25 3.25";//"0.75 0.75 0.75"; - sizes[1] = "2.5 2.5 2.5";//"1.0 1.0 1.0"; - sizes[2] = "1.5 1.5 1.5";//"0.5 0.5 0.5"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ExplosionData(UnderwaterTR2MortarSubExplosion2) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - delayMS = 50; - offset = 3.0; - playSpeed = 0.75; - - sizes[0] = "4.5 4.5 4.5";//"1.5 1.5 1.5"; - sizes[1] = "4.5 4.5 4.5";//"1.5 1.5 1.5"; - sizes[2] = "3.5 3.5 3.5";//"1.0 1.0 1.0"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ExplosionData(UnderwaterTR2MortarSubExplosion3) -{ - explosionShape = "disc_explosion.dts"; - faceViewer = true; - delayMS = 0; - offset = 0.0; - playSpeed = 0.5; - - sizes[0] = "1.0 1.0 1.0"; - sizes[1] = "2.0 2.0 2.0"; - sizes[2] = "1.5 1.5 1.5"; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - -datablock ExplosionData(UnderwaterTR2MortarExplosion) -{ - soundProfile = UnderwaterTR2MortarExplosionSound; - - shockwave = UnderwaterTR2MortarShockwave; - shockwaveOnTerrain = true; - - subExplosion[0] = UnderwaterTR2MortarSubExplosion1; - subExplosion[1] = UnderwaterTR2MortarSubExplosion2; - subExplosion[2] = UnderwaterTR2MortarSubExplosion3; - - emitter[0] = TR2MortarExplosionBubbleEmitter; - emitter[1] = TR2UnderwaterExplosionSparksEmitter; - - shakeCamera = true; - camShakeFreq = "8.0 9.0 7.0"; - camShakeAmp = "100.0 100.0 100.0"; - camShakeDuration = 1.3; - camShakeRadius = 25.0; -}; - - -//--------------------------------------------------------------------------- -// Explosion -//--------------------------------------------------------------------------- - -datablock ExplosionData(TR2MortarSubExplosion1) -{ - explosionShape = "mortar_explosion.dts"; - faceViewer = true; - - delayMS = 100; - - offset = 5.0; - - playSpeed = 1.5; - - sizes[0] = "8.0 8.0 8.0";//"1.5 1.5 1.5"; - sizes[1] = "8.0 8.0 8.0";//"1.5 1.5 1.5"; - times[0] = 0.0; - times[1] = 1.0; - -}; - -datablock ExplosionData(TR2MortarSubExplosion2) -{ - explosionShape = "mortar_explosion.dts"; - faceViewer = true; - - delayMS = 50; - - offset = 5.0; - - playSpeed = 1.0; - - sizes[0] = "12.0 12.0 12.0";//"3.0 3.0 3.0"; - sizes[1] = "12.0 12.0 12.0";//"3.0 3.0 3.0"; - times[0] = 0.0; - times[1] = 1.0; -}; - -datablock ExplosionData(TR2MortarSubExplosion3) -{ - explosionShape = "mortar_explosion.dts"; - faceViewer = true; - delayMS = 0; - offset = 0.0; - playSpeed = 0.7; - - sizes[0] = "24.0 24.0 24.0";//"3.0 3.0 3.0"; - sizes[1] = "48.0 48.0 48.0";//"6.0 6.0 6.0"; - times[0] = 0.0; - times[1] = 1.0; - -}; - -datablock ExplosionData(TR2MortarExplosion) -{ - soundProfile = TR2MortarExplosionSound; - - shockwave = MortarShockwave; - shockwaveOnTerrain = true; - - subExplosion[0] = TR2MortarSubExplosion1; - subExplosion[1] = TR2MortarSubExplosion2; - subExplosion[2] = TR2MortarSubExplosion3; - - emitter[0] = TR2MortarExplosionSmokeEmitter; - emitter[1] = TR2MortarCrescentEmitter; - - shakeCamera = true; - camShakeFreq = "8.0 9.0 7.0"; - camShakeAmp = "100.0 100.0 100.0"; - camShakeDuration = 1.3; - camShakeRadius = 40.0;//25.0; -}; - -//--------------------------------------------------------------------------- -// Smoke particles -//--------------------------------------------------------------------------- -datablock ParticleData(TR2MortarSmokeParticle) -{ - dragCoeffiecient = 0.4; - gravityCoefficient = -0.3; // rises slowly - inheritedVelFactor = 0.125; - - lifetimeMS = 1200; - lifetimeVarianceMS = 200; - useInvAlpha = true; - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - animateTexture = false; - - textureName = "special/Smoke/bigSmoke"; - - colors[0] = "0.7 1.0 0.7 0.5"; - colors[1] = "0.3 0.7 0.3 0.8"; - colors[2] = "0.0 0.0 0.0 0.0"; - sizes[0] = 4.0;//2.0; - sizes[1] = 8.0;//4.0; - sizes[2] = 17.0;//8.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - -}; - - -datablock ParticleEmitterData(TR2MortarSmokeEmitter) -{ - ejectionPeriodMS = 10; - periodVarianceMS = 3; - - ejectionVelocity = 4.0;//2.25; - velocityVariance = 0.55; - - thetaMin = 0.0; - thetaMax = 40.0; - - particles = "TR2MortarSmokeParticle"; -}; - - -//-------------------------------------------------------------------------- -// Projectile -//-------------------------------------- -datablock GrenadeProjectileData(TR2MortarShot) -{ - projectileShapeName = "mortar_projectile.dts"; - emitterDelay = -1; - directDamage = 0.0; - hasDamageRadius = true; - indirectDamage = 0.2; - damageRadius = 50.0; - radiusDamageType = $DamageType::Mortar; - kickBackStrength = 9500; - - explosion = "MortarExplosion"; - underwaterExplosion = "UnderwaterMortarExplosion"; - velInheritFactor = 0.5; - splash = TR2MortarSplash; - depthTolerance = 10.0; // depth at which it uses underwater explosion - - baseEmitter = TR2MortarSmokeEmitter; - bubbleEmitter = TR2MortarBubbleEmitter; - - grenadeElasticity = 0.15; - grenadeFriction = 0.4; - armingDelayMS = 1200;//2000; - muzzleVelocity = 120.0;//63.7; - drag = 0.1; - gravityMod = 1.5; - - sound = TR2MortarProjectileSound; - - hasLight = true; - lightRadius = 4; - lightColor = "0.05 0.2 0.05"; - - hasLightUnderwaterColor = true; - underWaterLightColor = "0.05 0.075 0.2"; - -}; - -//-------------------------------------------------------------------------- -// Ammo -//-------------------------------------- - -datablock ItemData(TR2MortarAmmo) -{ - className = Ammo; - catagory = "Ammo"; - shapeFile = "ammo_mortar.dts"; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "some mortar ammo"; - - computeCRC = false; - -}; - -//-------------------------------------------------------------------------- -// Weapon -//-------------------------------------- -datablock ItemData(TR2Mortar) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "TR2weapon_mortar.dts"; - image = TR2MortarImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a mortar gun"; - - computeCRC = true; - emap = true; -}; - -datablock ShapeBaseImageData(TR2MortarImage) -{ - className = WeaponImage; - shapeFile = "TR2weapon_mortar.dts"; - item = TR2Mortar; - ammo = TR2MortarAmmo; - offset = "0 0 0"; - emap = true; - - projectile = TR2MortarShot; - projectileType = GrenadeProjectile; - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - stateSound[0] = TR2MortarSwitchSound; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - //stateSound[2] = MortarIdleSound; - - stateName[3] = "Fire"; - stateSequence[3] = "Recoil"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.8; - stateFire[3] = true; - stateRecoil[3] = LightRecoil; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateSound[3] = TR2MortarFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 2.0; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = TR2MortarReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Reload"; - stateSequence[5] = "NoAmmo"; - stateTransitionOnTriggerDown[5] = "DryFire"; - - stateName[6] = "DryFire"; - stateSound[6] = TR2MortarDryFireSound; - stateTimeoutValue[6] = 1.5; - stateTransitionOnTimeout[6] = "NoAmmo"; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2shockLance.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2shockLance.cs deleted file mode 100644 index 7932236c..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2shockLance.cs +++ /dev/null @@ -1,297 +0,0 @@ -//-------------------------------------------------------------------------- -// Shock Lance -// -// -//-------------------------------------------------------------------------- - -datablock EffectProfile(TR2ShockLanceSwitchEffect) -{ - effectname = "weapons/shocklance_activate"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2ShockLanceFireEffect) -{ - effectname = "weapons/shocklance_fire"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2ShockLanceReloadEffect) -{ - effectname = "weapons/shocklance_reload"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(TR2ShockLanceSwitchSound) -{ - filename = "fx/weapons/shocklance_activate.wav"; - description = AudioClosest3d; - preload = true; - effect = ShockLanceSwitchEffect; -}; - -//-------------------------------------------------------------------------- -// Explosion -//-------------------------------------- -datablock AudioProfile(TR2ShockLanceHitSound) -{ - filename = "fx/weapons/shocklance_fire.WAV"; - description = AudioClose3d; - preload = true; - effect = TR2ShockLanceFireEffect; -}; - -datablock AudioProfile(TR2ShockLanceReloadSound) -{ - filename = "fx/weapons/shocklance_reload.WAV"; - description = AudioClosest3d; - preload = true; - effect = TR2ShockLanceReloadEffect; -}; - -datablock AudioProfile(TR2ShockLanceDryFireSound) -{ - filename = "fx/weapons/shocklance_dryfire.WAV"; - description = AudioClose3d; - preload = true; - effect = TR2ShockLanceReloadEffect; -}; - -datablock AudioProfile(TR2ShockLanceMissSound) -{ - filename = "fx/weapons/shocklance_miss.WAV"; - description = AudioExplosion3d; - preload = true; -}; - -//-------------------------------------------------------------------------- -// Particle data -//-------------------------------------------------------------------------- -datablock ParticleData(TR2ShockParticle) -{ - dragCoeffiecient = 0.0; - gravityCoefficient = -0.0; - inheritedVelFactor = 0.0; - - lifetimeMS = 1000; - lifetimeVarianceMS = 0; - - textureName = "particleTest"; - - useInvAlpha = false; - spinRandomMin = -100.0; - spinRandomMax = 100.0; - - numParts = 50; - - animateTexture = true; - framesPerSec = 26; - - animTexName[00] = "special/Explosion/exp_0002"; - animTexName[01] = "special/Explosion/exp_0004"; - animTexName[02] = "special/Explosion/exp_0006"; - animTexName[03] = "special/Explosion/exp_0008"; - animTexName[04] = "special/Explosion/exp_0010"; - animTexName[05] = "special/Explosion/exp_0012"; - animTexName[06] = "special/Explosion/exp_0014"; - animTexName[07] = "special/Explosion/exp_0016"; - animTexName[08] = "special/Explosion/exp_0018"; - animTexName[09] = "special/Explosion/exp_0020"; - animTexName[10] = "special/Explosion/exp_0022"; - animTexName[11] = "special/Explosion/exp_0024"; - animTexName[12] = "special/Explosion/exp_0026"; - animTexName[13] = "special/Explosion/exp_0028"; - animTexName[14] = "special/Explosion/exp_0030"; - animTexName[15] = "special/Explosion/exp_0032"; - animTexName[16] = "special/Explosion/exp_0034"; - animTexName[17] = "special/Explosion/exp_0036"; - animTexName[18] = "special/Explosion/exp_0038"; - animTexName[19] = "special/Explosion/exp_0040"; - animTexName[20] = "special/Explosion/exp_0042"; - animTexName[21] = "special/Explosion/exp_0044"; - animTexName[22] = "special/Explosion/exp_0046"; - animTexName[23] = "special/Explosion/exp_0048"; - animTexName[24] = "special/Explosion/exp_0050"; - animTexName[25] = "special/Explosion/exp_0052"; - - - colors[0] = "0.5 0.5 1.0 1.0"; - colors[1] = "0.5 0.5 1.0 0.5"; - colors[2] = "0.25 0.25 1.0 0.0"; - sizes[0] = 0.5; - sizes[1] = 0.5; - sizes[2] = 0.5; - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; -}; - -datablock ParticleEmitterData(TR2ShockParticleEmitter) -{ - ejectionPeriodMS = 1; - periodVarianceMS = 0; - - ejectionVelocity = 0.25; - velocityVariance = 0.0; - - thetaMin = 0.0; - thetaMax = 30.0; - - particles = "TR2ShockParticle"; -}; - -//-------------------------------------------------------------------------- -// Shockwave -//-------------------------------------------------------------------------- -datablock ShockwaveData( TR2ShocklanceHit ) -{ - width = 0.5; - numSegments = 20; - numVertSegments = 1; - velocity = 0.25; - acceleration = 1.0; - lifetimeMS = 600; - height = 0.1; - verticalCurve = 0.5; - - mapToTerrain = false; - renderBottom = false; - orientToNormal = true; - - texture[0] = "special/shocklanceHit"; - texture[1] = "special/gradient"; - texWrap = 3.0; - - times[0] = 0.0; - times[1] = 0.5; - times[2] = 1.0; - - colors[0] = "1.0 1.0 1.0 1.0"; - colors[1] = "1.0 1.0 1.0 0.5"; - colors[2] = "1.0 1.0 1.0 0.0"; -}; - - -//-------------------------------------- -// Projectile -//-------------------------------------- -datablock ShockLanceProjectileData(TR2BasicShocker) -{ - directDamage = 0.1;//0.45; - radiusDamageType = $DamageType::ShockLance; - kickBackStrength = 12000; - velInheritFactor = 0; - sound = ""; - - zapDuration = 1.0; - impulse = 12000;//1800; - boltLength = 45;//14.0; - extension = 39;//14.0;//14.0; // script variable indicating distance you can shock people from - lightningFreq = 25.0; - lightningDensity = 3.0; - lightningAmp = 0.25; - lightningWidth = 0.05; - - shockwave = TR2ShocklanceHit; - - boltSpeed[0] = 2.0; - boltSpeed[1] = -0.5; - - texWrap[0] = 1.5; - texWrap[1] = 1.5; - - startWidth[0] = 0.3; - endWidth[0] = 0.6; - startWidth[1] = 0.3; - endWidth[1] = 0.6; - - texture[0] = "special/shockLightning01"; - texture[1] = "special/shockLightning02"; - texture[2] = "special/shockLightning03"; - texture[3] = "special/ELFBeam"; - - emitter[0] = TR2ShockParticleEmitter; -}; - - -//-------------------------------------- -// Rifle and item... -//-------------------------------------- -datablock ItemData(TR2ShockLance) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "TR2weapon_shocklance.dts"; - image = TR2ShockLanceImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a shocklance"; - - computeCRC = true; - emap = true; -}; - -datablock ShapeBaseImageData(TR2ShockLanceImage) -{ - classname = WeaponImage; - shapeFile = "TR2weapon_shocklance.dts"; - item = TR2ShockLance; - offset = "0 0 0"; - emap = true; - - projectile = TR2BasicShocker; - - usesEnergy = true; - missEnergy = 0; - hitEnergy = 15; - minEnergy = 15; // needs to change to be datablock's energy drain for a hit - - stateName[0] = "Activate"; - stateTransitionOnTimeout[0] = "ActivateReady"; - stateSound[0] = TR2ShockLanceSwitchSound; - stateTimeoutValue[0] = 0.5; - stateSequence[0] = "Activate"; - - stateName[1] = "ActivateReady"; - stateTransitionOnLoaded[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "CheckWet"; - - stateName[3] = "Fire"; - stateTransitionOnTimeout[3] = "Reload"; - stateTimeoutValue[3] = 0.5; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateSequence[3] = "Fire"; - stateScript[3] = "onFire"; - stateSound[3] = TR2ShockLanceDryFireSound; - - stateName[4] = "Reload"; - stateTransitionOnNoAmmo[4] = "NoAmmo"; - stateTransitionOnTimeout[4] = "Ready"; - stateTimeoutValue[4] = 2.0; - stateAllowImageChange[4] = false; - stateSequence[4] = "Reload"; - stateSound[4] = TR2ShockLanceReloadSound; - - stateName[5] = "NoAmmo"; - stateTransitionOnAmmo[5] = "Ready"; - - stateName[6] = "DryFire"; - stateSound[6] = TR2ShockLanceDryFireSound; - stateTimeoutValue[6] = 1.0; - stateTransitionOnTimeout[6] = "Ready"; - - stateName[7] = "CheckWet"; - stateTransitionOnWet[7] = "DryFire"; - stateTransitionOnNotWet[7] = "Fire"; -}; - diff --git a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2targetingLaser.cs b/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2targetingLaser.cs deleted file mode 100644 index b42d5503..00000000 --- a/docs/base/@vl2/TR2final105-server.vl2/scripts/weapons/TR2targetingLaser.cs +++ /dev/null @@ -1,218 +0,0 @@ -//-------------------------------------------------------------------------- -// Targeting laser -// -//-------------------------------------------------------------------------- -datablock EffectProfile(TR2TargetingLaserSwitchEffect) -{ - effectname = "weapons/generic_switch"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock EffectProfile(TR2TargetingLaserPaintEffect) -{ - effectname = "weapons/targetinglaser_paint"; - minDistance = 2.5; - maxDistance = 2.5; -}; - -datablock AudioProfile(TR2TargetingLaserSwitchSound) -{ - filename = "fx/weapons/generic_switch.wav"; - description = AudioClosest3d; - preload = true; - effect = TargetingLaserSwitchEffect; -}; - -datablock AudioProfile(TR2TargetingLaserPaintSound) -{ - filename = "fx/weapons/targetinglaser_paint.wav"; - description = CloseLooping3d; - preload = true; - effect = TargetingLaserPaintEffect; -}; - - -//-------------------------------------- -// Projectile -//-------------------------------------- -datablock TargetProjectileData(TR2BasicGoldTargeter) -{ - directDamage = 0.0; - hasDamageRadius = false; - indirectDamage = 0.0; - damageRadius = 0.0; - velInheritFactor = 1.0; - - maxRifleRange = 1000; - beamColor = "0.8 0.8 0.0"; - - startBeamWidth = 0.80; - pulseBeamWidth = 0.55; - beamFlareAngle = 3.0; - minFlareSize = 0.0; - maxFlareSize = 400.0; - pulseSpeed = 6.0; - pulseLength = 0.150; - - textureName[0] = "special/nonlingradient"; - textureName[1] = "special/flare"; - textureName[2] = "special/pulse"; - textureName[3] = "special/expFlare"; - beacon = true; -}; - -datablock TargetProjectileData(TR2BasicSilverTargeter) -{ - directDamage = 0.0; - hasDamageRadius = false; - indirectDamage = 0.0; - damageRadius = 0.0; - velInheritFactor = 1.0; - - maxRifleRange = 1000; - beamColor = "0.56 0.56 0.56"; - - startBeamWidth = 0.80; - pulseBeamWidth = 0.55; - beamFlareAngle = 3.0; - minFlareSize = 0.0; - maxFlareSize = 400.0; - pulseSpeed = 6.0; - pulseLength = 0.150; - - textureName[0] = "special/nonlingradient"; - textureName[1] = "special/flare"; - textureName[2] = "special/pulse"; - textureName[3] = "special/expFlare"; - beacon = true; -}; - - -//-------------------------------------- -// Rifle and item... -//-------------------------------------- -datablock ItemData(TR2GoldTargetingLaser) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_targeting.dts"; - image = TR2GoldTargetingLaserImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a targeting laser rifle"; - - computeCRC = false; - -}; - -datablock ItemData(TR2SilverTargetingLaser) -{ - className = Weapon; - catagory = "Spawn Items"; - shapeFile = "weapon_targeting.dts"; - image = TR2SilverTargetingLaserImage; - mass = 1; - elasticity = 0.2; - friction = 0.6; - pickupRadius = 2; - pickUpName = "a targeting laser rifle"; - - computeCRC = false; - -}; - - -datablock ShapeBaseImageData(TR2GoldTargetingLaserImage) -{ - className = WeaponImage; - - shapeFile = "weapon_targeting.dts"; - item = TR2GoldTargetingLaser; - offset = "0 0 0"; - - projectile = TR2BasicGoldTargeter; - projectileType = TargetProjectile; - deleteLastProjectile = true; - - usesEnergy = true; - minEnergy = 1; - - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = TR2TargetingLaserSwitchSound; - stateTimeoutValue[0] = 0.5; - stateTransitionOnTimeout[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateTransitionOnAmmo[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - - stateName[3] = "Fire"; - stateEnergyDrain[3] = 0; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateTransitionOnTriggerUp[3] = "Deconstruction"; - stateTransitionOnNoAmmo[3] = "Deconstruction"; - stateSound[3] = TR2TargetingLaserPaintSound; - - stateName[4] = "NoAmmo"; - stateTransitionOnAmmo[4] = "Ready"; - - stateName[5] = "Deconstruction"; - stateScript[5] = "deconstruct"; - stateTransitionOnTimeout[5] = "Ready"; -}; - -datablock ShapeBaseImageData(TR2SilverTargetingLaserImage) -{ - className = WeaponImage; - - shapeFile = "weapon_targeting.dts"; - item = TR2SilverTargetingLaser; - offset = "0 0 0"; - - projectile = TR2BasicSilverTargeter; - projectileType = TargetProjectile; - deleteLastProjectile = true; - - usesEnergy = true; - minEnergy = 1; - - stateName[0] = "Activate"; - stateSequence[0] = "Activate"; - stateSound[0] = TR2TargetingLaserSwitchSound; - stateTimeoutValue[0] = 0.5; - stateTransitionOnTimeout[0] = "ActivateReady"; - - stateName[1] = "ActivateReady"; - stateTransitionOnAmmo[1] = "Ready"; - stateTransitionOnNoAmmo[1] = "NoAmmo"; - - stateName[2] = "Ready"; - stateTransitionOnNoAmmo[2] = "NoAmmo"; - stateTransitionOnTriggerDown[2] = "Fire"; - - stateName[3] = "Fire"; - stateEnergyDrain[3] = 0; - stateFire[3] = true; - stateAllowImageChange[3] = false; - stateScript[3] = "onFire"; - stateTransitionOnTriggerUp[3] = "Deconstruction"; - stateTransitionOnNoAmmo[3] = "Deconstruction"; - stateSound[3] = TR2TargetingLaserPaintSound; - - stateName[4] = "NoAmmo"; - stateTransitionOnAmmo[4] = "Ready"; - - stateName[5] = "Deconstruction"; - stateScript[5] = "deconstruct"; - stateTransitionOnTimeout[5] = "Ready"; -}; diff --git a/docs/base/@vl2/shapes.vl2/shapes/ammo_chaingun.glb b/docs/base/@vl2/shapes.vl2/shapes/ammo_chaingun.glb new file mode 100644 index 00000000..2c0a0940 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ammo_chaingun.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/ammo_disc.glb b/docs/base/@vl2/shapes.vl2/shapes/ammo_disc.glb new file mode 100644 index 00000000..73fd0cf5 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ammo_disc.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/ammo_grenade.glb b/docs/base/@vl2/shapes.vl2/shapes/ammo_grenade.glb new file mode 100644 index 00000000..6f764ae0 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ammo_grenade.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/ammo_mine.glb b/docs/base/@vl2/shapes.vl2/shapes/ammo_mine.glb new file mode 100644 index 00000000..70491a6c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ammo_mine.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/ammo_missile.glb b/docs/base/@vl2/shapes.vl2/shapes/ammo_missile.glb new file mode 100644 index 00000000..57b6e747 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ammo_missile.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/ammo_mortar.glb b/docs/base/@vl2/shapes.vl2/shapes/ammo_mortar.glb new file mode 100644 index 00000000..6abc021a Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ammo_mortar.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/ammo_plasma.glb b/docs/base/@vl2/shapes.vl2/shapes/ammo_plasma.glb new file mode 100644 index 00000000..879caa2f Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ammo_plasma.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/banner_honor.glb b/docs/base/@vl2/shapes.vl2/shapes/banner_honor.glb new file mode 100644 index 00000000..96927e7d Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/banner_honor.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/banner_strength.glb b/docs/base/@vl2/shapes.vl2/shapes/banner_strength.glb new file mode 100644 index 00000000..5d47bb70 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/banner_strength.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/banner_unity.glb b/docs/base/@vl2/shapes.vl2/shapes/banner_unity.glb new file mode 100644 index 00000000..a881d932 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/banner_unity.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/beacon.glb b/docs/base/@vl2/shapes.vl2/shapes/beacon.glb new file mode 100644 index 00000000..734e0433 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/beacon.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/bio_player_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/bio_player_debris.glb new file mode 100644 index 00000000..f1bd3a80 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/bio_player_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/bioderm_heavy.glb b/docs/base/@vl2/shapes.vl2/shapes/bioderm_heavy.glb new file mode 100644 index 00000000..8c6fc7f2 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/bioderm_heavy.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/bioderm_light.glb b/docs/base/@vl2/shapes.vl2/shapes/bioderm_light.glb new file mode 100644 index 00000000..4efe4243 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/bioderm_light.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/bioderm_medium.glb b/docs/base/@vl2/shapes.vl2/shapes/bioderm_medium.glb new file mode 100644 index 00000000..fdb78933 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/bioderm_medium.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/bmiscf.glb b/docs/base/@vl2/shapes.vl2/shapes/bmiscf.glb new file mode 100644 index 00000000..f8ef09c8 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/bmiscf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/bomb.glb b/docs/base/@vl2/shapes.vl2/shapes/bomb.glb new file mode 100644 index 00000000..f7b5ab93 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/bomb.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg1.glb b/docs/base/@vl2/shapes.vl2/shapes/borg1.glb new file mode 100644 index 00000000..d794f751 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg1.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg12.glb b/docs/base/@vl2/shapes.vl2/shapes/borg12.glb new file mode 100644 index 00000000..636b1b39 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg12.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg13.glb b/docs/base/@vl2/shapes.vl2/shapes/borg13.glb new file mode 100644 index 00000000..3096356b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg13.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg15.glb b/docs/base/@vl2/shapes.vl2/shapes/borg15.glb new file mode 100644 index 00000000..46dc25a1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg15.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg16.glb b/docs/base/@vl2/shapes.vl2/shapes/borg16.glb new file mode 100644 index 00000000..4300235b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg16.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg17.glb b/docs/base/@vl2/shapes.vl2/shapes/borg17.glb new file mode 100644 index 00000000..de6f5cd6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg17.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg18.glb b/docs/base/@vl2/shapes.vl2/shapes/borg18.glb new file mode 100644 index 00000000..fe5267f1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg18.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg19.glb b/docs/base/@vl2/shapes.vl2/shapes/borg19.glb new file mode 100644 index 00000000..df365b97 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg19.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg20.glb b/docs/base/@vl2/shapes.vl2/shapes/borg20.glb new file mode 100644 index 00000000..33b1e545 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg20.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg23.glb b/docs/base/@vl2/shapes.vl2/shapes/borg23.glb new file mode 100644 index 00000000..86253417 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg23.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg25.glb b/docs/base/@vl2/shapes.vl2/shapes/borg25.glb new file mode 100644 index 00000000..72e71a4f Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg25.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg31.glb b/docs/base/@vl2/shapes.vl2/shapes/borg31.glb new file mode 100644 index 00000000..4b67f061 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg31.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg32.glb b/docs/base/@vl2/shapes.vl2/shapes/borg32.glb new file mode 100644 index 00000000..bae9a57b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg32.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg33.glb b/docs/base/@vl2/shapes.vl2/shapes/borg33.glb new file mode 100644 index 00000000..e2093dd4 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg33.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg34.glb b/docs/base/@vl2/shapes.vl2/shapes/borg34.glb new file mode 100644 index 00000000..134404a9 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg34.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/borg7.glb b/docs/base/@vl2/shapes.vl2/shapes/borg7.glb new file mode 100644 index 00000000..117bb960 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/borg7.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/camera.glb b/docs/base/@vl2/shapes.vl2/shapes/camera.glb new file mode 100644 index 00000000..cd86141c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/camera.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/debris_generic.glb b/docs/base/@vl2/shapes.vl2/shapes/debris_generic.glb new file mode 100644 index 00000000..8267a3c4 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/debris_generic.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/debris_generic_small.glb b/docs/base/@vl2/shapes.vl2/shapes/debris_generic_small.glb new file mode 100644 index 00000000..2447a0d1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/debris_generic_small.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/debris_player.glb b/docs/base/@vl2/shapes.vl2/shapes/debris_player.glb new file mode 100644 index 00000000..f572699e Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/debris_player.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/deploy_ammo.glb b/docs/base/@vl2/shapes.vl2/shapes/deploy_ammo.glb new file mode 100644 index 00000000..abbf9f50 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/deploy_ammo.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/deploy_inventory.glb b/docs/base/@vl2/shapes.vl2/shapes/deploy_inventory.glb new file mode 100644 index 00000000..5f9d79f2 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/deploy_inventory.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/deploy_sensor_motion.glb b/docs/base/@vl2/shapes.vl2/shapes/deploy_sensor_motion.glb new file mode 100644 index 00000000..99ef4d1a Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/deploy_sensor_motion.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/deploy_sensor_pulse.glb b/docs/base/@vl2/shapes.vl2/shapes/deploy_sensor_pulse.glb new file mode 100644 index 00000000..68640a2b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/deploy_sensor_pulse.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/disc.glb b/docs/base/@vl2/shapes.vl2/shapes/disc.glb new file mode 100644 index 00000000..456ecc45 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/disc.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/dmiscf.glb b/docs/base/@vl2/shapes.vl2/shapes/dmiscf.glb new file mode 100644 index 00000000..f614f21c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/dmiscf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/dorg15.glb b/docs/base/@vl2/shapes.vl2/shapes/dorg15.glb new file mode 100644 index 00000000..ae11a65b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/dorg15.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/dorg16.glb b/docs/base/@vl2/shapes.vl2/shapes/dorg16.glb new file mode 100644 index 00000000..d6ca4fa0 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/dorg16.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/dorg17.glb b/docs/base/@vl2/shapes.vl2/shapes/dorg17.glb new file mode 100644 index 00000000..2d3531d4 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/dorg17.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/dorg18.glb b/docs/base/@vl2/shapes.vl2/shapes/dorg18.glb new file mode 100644 index 00000000..5342a7e8 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/dorg18.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/dorg19.glb b/docs/base/@vl2/shapes.vl2/shapes/dorg19.glb new file mode 100644 index 00000000..a179b618 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/dorg19.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/effect_plasma_explosion.glb b/docs/base/@vl2/shapes.vl2/shapes/effect_plasma_explosion.glb new file mode 100644 index 00000000..0faf6da0 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/effect_plasma_explosion.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/energy_bolt.glb b/docs/base/@vl2/shapes.vl2/shapes/energy_bolt.glb new file mode 100644 index 00000000..a94da8f3 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/energy_bolt.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/energy_explosion.glb b/docs/base/@vl2/shapes.vl2/shapes/energy_explosion.glb new file mode 100644 index 00000000..cab8b93c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/energy_explosion.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/ext_flagstand.glb b/docs/base/@vl2/shapes.vl2/shapes/ext_flagstand.glb new file mode 100644 index 00000000..37723e34 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/ext_flagstand.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/flag.glb b/docs/base/@vl2/shapes.vl2/shapes/flag.glb new file mode 100644 index 00000000..fe8e7ae4 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/flag.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/gravemarker_1.glb b/docs/base/@vl2/shapes.vl2/shapes/gravemarker_1.glb new file mode 100644 index 00000000..d78151fa Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/gravemarker_1.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/grenade.glb b/docs/base/@vl2/shapes.vl2/shapes/grenade.glb new file mode 100644 index 00000000..85f0ce99 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/grenade.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/heavy_male.glb b/docs/base/@vl2/shapes.vl2/shapes/heavy_male.glb new file mode 100644 index 00000000..4248ac28 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/heavy_male.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/huntersflag.glb b/docs/base/@vl2/shapes.vl2/shapes/huntersflag.glb new file mode 100644 index 00000000..88bb9c99 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/huntersflag.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/int_flagstand.glb b/docs/base/@vl2/shapes.vl2/shapes/int_flagstand.glb new file mode 100644 index 00000000..5cd8b74d Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/int_flagstand.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/light_female.glb b/docs/base/@vl2/shapes.vl2/shapes/light_female.glb new file mode 100644 index 00000000..3c435a6e Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/light_female.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/light_male.glb b/docs/base/@vl2/shapes.vl2/shapes/light_male.glb new file mode 100644 index 00000000..b6e42104 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/light_male.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/medium_female.glb b/docs/base/@vl2/shapes.vl2/shapes/medium_female.glb new file mode 100644 index 00000000..f353ea70 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/medium_female.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/medium_male.glb b/docs/base/@vl2/shapes.vl2/shapes/medium_male.glb new file mode 100644 index 00000000..ae839192 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/medium_male.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/mine.glb b/docs/base/@vl2/shapes.vl2/shapes/mine.glb new file mode 100644 index 00000000..26fd4f11 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/mine.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/mortar_explosion.glb b/docs/base/@vl2/shapes.vl2/shapes/mortar_explosion.glb new file mode 100644 index 00000000..cb7e8498 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/mortar_explosion.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/nexus_effect.glb b/docs/base/@vl2/shapes.vl2/shapes/nexus_effect.glb new file mode 100644 index 00000000..408c2a8a Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/nexus_effect.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/nexusbase.glb b/docs/base/@vl2/shapes.vl2/shapes/nexusbase.glb new file mode 100644 index 00000000..de9f1a72 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/nexusbase.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/nexuscap.glb b/docs/base/@vl2/shapes.vl2/shapes/nexuscap.glb new file mode 100644 index 00000000..686ace21 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/nexuscap.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_aa.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_aa.glb new file mode 100644 index 00000000..394cec26 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_aa.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_elf.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_elf.glb new file mode 100644 index 00000000..4304dbd8 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_elf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_fusion.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_fusion.glb new file mode 100644 index 00000000..48f3b7c5 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_fusion.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_missile.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_missile.glb new file mode 100644 index 00000000..0aedb499 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_missile.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_mortar.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_mortar.glb new file mode 100644 index 00000000..edf639b9 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_barrel_mortar.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_ammo.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_ammo.glb new file mode 100644 index 00000000..9198e1b7 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_ammo.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_inventory.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_inventory.glb new file mode 100644 index 00000000..ef6e0a94 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_inventory.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_sensor_motion.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_sensor_motion.glb new file mode 100644 index 00000000..d5f07ee3 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_sensor_motion.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_sensor_pulse.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_sensor_pulse.glb new file mode 100644 index 00000000..f57d3239 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_sensor_pulse.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_turreti.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_turreti.glb new file mode 100644 index 00000000..6fcb2d9f Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_turreti.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_turreto.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_turreto.glb new file mode 100644 index 00000000..454ba0b8 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_deploy_turreto.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_ammo.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_ammo.glb new file mode 100644 index 00000000..a72aeb47 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_ammo.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_cloaking.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_cloaking.glb new file mode 100644 index 00000000..77f5b6a1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_cloaking.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_energy.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_energy.glb new file mode 100644 index 00000000..5a25d6a6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_energy.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_repair.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_repair.glb new file mode 100644 index 00000000..7d6383a2 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_repair.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_satchel.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_satchel.glb new file mode 100644 index 00000000..6abe3eb6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_satchel.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_sensorjammer.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_sensorjammer.glb new file mode 100644 index 00000000..12d572d4 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_sensorjammer.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_shield.glb b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_shield.glb new file mode 100644 index 00000000..4ada3090 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pack_upgrade_shield.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/pmiscf.glb b/docs/base/@vl2/shapes.vl2/shapes/pmiscf.glb new file mode 100644 index 00000000..d901aedf Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/pmiscf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/porg1.glb b/docs/base/@vl2/shapes.vl2/shapes/porg1.glb new file mode 100644 index 00000000..57a4d5c6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/porg1.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/porg20.glb b/docs/base/@vl2/shapes.vl2/shapes/porg20.glb new file mode 100644 index 00000000..7ca7e521 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/porg20.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/porg3.glb b/docs/base/@vl2/shapes.vl2/shapes/porg3.glb new file mode 100644 index 00000000..b29f75c0 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/porg3.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/porg5.glb b/docs/base/@vl2/shapes.vl2/shapes/porg5.glb new file mode 100644 index 00000000..bf00d805 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/porg5.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/porg6.glb b/docs/base/@vl2/shapes.vl2/shapes/porg6.glb new file mode 100644 index 00000000..ba3877f8 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/porg6.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/repair_kit.glb b/docs/base/@vl2/shapes.vl2/shapes/repair_kit.glb new file mode 100644 index 00000000..c08b560b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/repair_kit.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/repair_patch.glb b/docs/base/@vl2/shapes.vl2/shapes/repair_patch.glb new file mode 100644 index 00000000..e31546d7 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/repair_patch.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/reticle_bomber.glb b/docs/base/@vl2/shapes.vl2/shapes/reticle_bomber.glb new file mode 100644 index 00000000..578d81b8 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/reticle_bomber.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/sensor_pulse_large.glb b/docs/base/@vl2/shapes.vl2/shapes/sensor_pulse_large.glb new file mode 100644 index 00000000..ea639eec Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/sensor_pulse_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/sensor_pulse_medium.glb b/docs/base/@vl2/shapes.vl2/shapes/sensor_pulse_medium.glb new file mode 100644 index 00000000..8dd5a990 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/sensor_pulse_medium.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/smiscf.glb b/docs/base/@vl2/shapes.vl2/shapes/smiscf.glb new file mode 100644 index 00000000..b89752b2 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/smiscf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/solarpanel.glb b/docs/base/@vl2/shapes.vl2/shapes/solarpanel.glb new file mode 100644 index 00000000..e2340f1d Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/solarpanel.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/sorg20.glb b/docs/base/@vl2/shapes.vl2/shapes/sorg20.glb new file mode 100644 index 00000000..14473d96 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/sorg20.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/sorg21.glb b/docs/base/@vl2/shapes.vl2/shapes/sorg21.glb new file mode 100644 index 00000000..588669fc Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/sorg21.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/sorg22.glb b/docs/base/@vl2/shapes.vl2/shapes/sorg22.glb new file mode 100644 index 00000000..eb37a704 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/sorg22.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/sorg24.glb b/docs/base/@vl2/shapes.vl2/shapes/sorg24.glb new file mode 100644 index 00000000..e941052b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/sorg24.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable1l.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable1l.glb new file mode 100644 index 00000000..ff300fc5 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable1l.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable1m.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable1m.glb new file mode 100644 index 00000000..76e812f5 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable1m.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable1s.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable1s.glb new file mode 100644 index 00000000..1d5c7b3b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable1s.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable2l.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable2l.glb new file mode 100644 index 00000000..25e5dc9d Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable2l.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable2m.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable2m.glb new file mode 100644 index 00000000..e2d750f5 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable2m.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable2s.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable2s.glb new file mode 100644 index 00000000..9efd6a10 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable2s.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable3l.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable3l.glb new file mode 100644 index 00000000..121daaa2 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable3l.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable3m.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable3m.glb new file mode 100644 index 00000000..07c5ca6b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable3m.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable3s.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable3s.glb new file mode 100644 index 00000000..ad00ee79 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable3s.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable4l.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable4l.glb new file mode 100644 index 00000000..36cfe5f9 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable4l.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable4m.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable4m.glb new file mode 100644 index 00000000..78f1f9d1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable4m.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable5l.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable5l.glb new file mode 100644 index 00000000..031637ed Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable5l.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/stackable5m.glb b/docs/base/@vl2/shapes.vl2/shapes/stackable5m.glb new file mode 100644 index 00000000..4c2d1c02 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/stackable5m.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/station_generator_large.glb b/docs/base/@vl2/shapes.vl2/shapes/station_generator_large.glb new file mode 100644 index 00000000..8dd9e3b1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/station_generator_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/station_inv_human.glb b/docs/base/@vl2/shapes.vl2/shapes/station_inv_human.glb new file mode 100644 index 00000000..cb7a8f9f Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/station_inv_human.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/station_inv_mpb.glb b/docs/base/@vl2/shapes.vl2/shapes/station_inv_mpb.glb new file mode 100644 index 00000000..226d0c71 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/station_inv_mpb.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/station_teleport.glb b/docs/base/@vl2/shapes.vl2/shapes/station_teleport.glb new file mode 100644 index 00000000..1d0c8a41 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/station_teleport.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/statue_base.glb b/docs/base/@vl2/shapes.vl2/shapes/statue_base.glb new file mode 100644 index 00000000..eb3cdef0 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/statue_base.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/statue_hmale.glb b/docs/base/@vl2/shapes.vl2/shapes/statue_hmale.glb new file mode 100644 index 00000000..d5957931 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/statue_hmale.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/statue_lfemale.glb b/docs/base/@vl2/shapes.vl2/shapes/statue_lfemale.glb new file mode 100644 index 00000000..af2774c9 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/statue_lfemale.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/statue_lmale.glb b/docs/base/@vl2/shapes.vl2/shapes/statue_lmale.glb new file mode 100644 index 00000000..83f5502c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/statue_lmale.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/statue_plaque.glb b/docs/base/@vl2/shapes.vl2/shapes/statue_plaque.glb new file mode 100644 index 00000000..e452adf6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/statue_plaque.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/switch.glb b/docs/base/@vl2/shapes.vl2/shapes/switch.glb new file mode 100644 index 00000000..ce640e69 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/switch.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_bd.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_bd.glb new file mode 100644 index 00000000..680379cd Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_bd.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_be.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_be.glb new file mode 100644 index 00000000..2c6b429d Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_be.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_ds.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_ds.glb new file mode 100644 index 00000000..0d048798 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_ds.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_hb.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_hb.glb new file mode 100644 index 00000000..3a6de765 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_hb.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_inf.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_inf.glb new file mode 100644 index 00000000..d7f9a686 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_inf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_projector.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_projector.glb new file mode 100644 index 00000000..497e350f Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_projector.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_storm.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_storm.glb new file mode 100644 index 00000000..3d3056c1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_storm.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/teamlogo_sw.glb b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_sw.glb new file mode 100644 index 00000000..a26e0e56 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/teamlogo_sw.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_aa_large.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_aa_large.glb new file mode 100644 index 00000000..3e2483cd Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_aa_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_assaulttank_mortar.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_assaulttank_mortar.glb new file mode 100644 index 00000000..15a5b692 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_assaulttank_mortar.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_assaulttank_plasma.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_assaulttank_plasma.glb new file mode 100644 index 00000000..2b6f593c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_assaulttank_plasma.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_base_large.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_base_large.glb new file mode 100644 index 00000000..813f54ad Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_base_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_base_mpb.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_base_mpb.glb new file mode 100644 index 00000000..01be45fb Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_base_mpb.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_belly_barrell.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_belly_barrell.glb new file mode 100644 index 00000000..f7b355cc Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_belly_barrell.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_belly_barrelr.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_belly_barrelr.glb new file mode 100644 index 00000000..8e3237b6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_belly_barrelr.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_belly_base.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_belly_base.glb new file mode 100644 index 00000000..8d5d6988 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_belly_base.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_elf_large.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_elf_large.glb new file mode 100644 index 00000000..07ac82b3 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_elf_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_fusion_large.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_fusion_large.glb new file mode 100644 index 00000000..588f45ed Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_fusion_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployc.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployc.glb new file mode 100644 index 00000000..03e89f8f Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployc.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployf.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployf.glb new file mode 100644 index 00000000..4a2a74d3 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployw.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployw.glb new file mode 100644 index 00000000..1bb62b6b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_indoor_deployw.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_missile_large.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_missile_large.glb new file mode 100644 index 00000000..7f00bcb3 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_missile_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_mortar_large.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_mortar_large.glb new file mode 100644 index 00000000..2475a227 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_mortar_large.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_outdoor_deploy.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_outdoor_deploy.glb new file mode 100644 index 00000000..7fc38d70 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_outdoor_deploy.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_sentry.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_sentry.glb new file mode 100644 index 00000000..a4595d0c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_sentry.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_tank_barrelchain.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_tank_barrelchain.glb new file mode 100644 index 00000000..1502543b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_tank_barrelchain.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_tank_barrelmortar.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_tank_barrelmortar.glb new file mode 100644 index 00000000..9c581595 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_tank_barrelmortar.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/turret_tank_base.glb b/docs/base/@vl2/shapes.vl2/shapes/turret_tank_base.glb new file mode 100644 index 00000000..8f4b28fa Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/turret_tank_base.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_bomber.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_bomber.glb new file mode 100644 index 00000000..5f712ef6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_bomber.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_bomber_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_bomber_debris.glb new file mode 100644 index 00000000..5ef3e477 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_bomber_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_hapc.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_hapc.glb new file mode 100644 index 00000000..81e0c840 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_hapc.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_hapc_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_hapc_debris.glb new file mode 100644 index 00000000..4f207f74 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_hapc_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_scout.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_scout.glb new file mode 100644 index 00000000..2c237752 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_scout.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_scout_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_scout_debris.glb new file mode 100644 index 00000000..14b906bb Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_air_scout_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_scout.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_scout.glb new file mode 100644 index 00000000..2e11d287 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_scout.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_scout_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_scout_debris.glb new file mode 100644 index 00000000..33c6621c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_scout_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank.glb new file mode 100644 index 00000000..fee95300 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank_debris.glb new file mode 100644 index 00000000..8c9d4ce2 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank_wreck.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank_wreck.glb new file mode 100644 index 00000000..b4598c55 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_grav_tank_wreck.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault.glb new file mode 100644 index 00000000..972bd651 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault_debris.glb new file mode 100644 index 00000000..52a3f6b6 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault_wreck.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault_wreck.glb new file mode 100644 index 00000000..f41f5c65 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_assault_wreck.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_mpbase.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_mpbase.glb new file mode 100644 index 00000000..8a171df9 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_mpbase.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_mpbase_debris.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_mpbase_debris.glb new file mode 100644 index 00000000..90e2fbfd Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_land_mpbase_debris.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_pad.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_pad.glb new file mode 100644 index 00000000..6ab7ac12 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_pad.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/vehicle_pad_station.glb b/docs/base/@vl2/shapes.vl2/shapes/vehicle_pad_station.glb new file mode 100644 index 00000000..3ce74f75 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/vehicle_pad_station.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_chaingun.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_chaingun.glb new file mode 100644 index 00000000..4e61ec1b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_chaingun.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_disc.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_disc.glb new file mode 100644 index 00000000..0ce5248c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_disc.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_elf.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_elf.glb new file mode 100644 index 00000000..a74829a0 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_elf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_energy_vehicle.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_energy_vehicle.glb new file mode 100644 index 00000000..ef623492 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_energy_vehicle.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_grenade_launcher.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_grenade_launcher.glb new file mode 100644 index 00000000..5d9eebd7 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_grenade_launcher.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_missile.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_missile.glb new file mode 100644 index 00000000..8c7b3ac1 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_missile.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_mortar.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_mortar.glb new file mode 100644 index 00000000..558e0028 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_mortar.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_plasma.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_plasma.glb new file mode 100644 index 00000000..cbc0c40f Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_plasma.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_repair.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_repair.glb new file mode 100644 index 00000000..1569216c Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_repair.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_shocklance.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_shocklance.glb new file mode 100644 index 00000000..1292b098 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_shocklance.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_sniper.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_sniper.glb new file mode 100644 index 00000000..d46d4bc7 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_sniper.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/weapon_targeting.glb b/docs/base/@vl2/shapes.vl2/shapes/weapon_targeting.glb new file mode 100644 index 00000000..b09b416b Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/weapon_targeting.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/xmiscf.glb b/docs/base/@vl2/shapes.vl2/shapes/xmiscf.glb new file mode 100644 index 00000000..a8775f49 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/xmiscf.glb differ diff --git a/docs/base/@vl2/shapes.vl2/shapes/xorg4.glb b/docs/base/@vl2/shapes.vl2/shapes/xorg4.glb new file mode 100644 index 00000000..235c41c0 Binary files /dev/null and b/docs/base/@vl2/shapes.vl2/shapes/xorg4.glb differ diff --git a/docs/base/@vl2/tournamentNetClient2.vl2/scripts/autoexec/tourneyInit.cs b/docs/base/@vl2/tournamentNetClient2.vl2/scripts/autoexec/tourneyInit.cs deleted file mode 100644 index 0477054a..00000000 --- a/docs/base/@vl2/tournamentNetClient2.vl2/scripts/autoexec/tourneyInit.cs +++ /dev/null @@ -1,8 +0,0 @@ - -if (!isObject(ServerGroup)) -{ - exec("tournament/settings.cs"); - exec("tournament/login.cs"); - tn_community_login_initiate(); - exec("tournament/browser.cs"); -} \ No newline at end of file diff --git a/docs/base/@vl2/tournamentNetClient2.vl2/tournament/browser.cs b/docs/base/@vl2/tournamentNetClient2.vl2/tournament/browser.cs deleted file mode 100644 index ea38a33b..00000000 --- a/docs/base/@vl2/tournamentNetClient2.vl2/tournament/browser.cs +++ /dev/null @@ -1,143 +0,0 @@ -// TribesNext Project -// http://www.tribesnext.com/ -// Copyright 2011 - -// Tribes 2 Community System -// Robot Browser Client - Prototype - -$TribesNext::Community::Browser::Active = 0; - -function CommunityBrowserInterface::onConnected(%this) -{ - //echo("Browser-Sending: " @ %this.data); - %this.primed = 0; - %this.send(%this.data); -} - -function CommunityBrowserInterface::onDisconnect(%this) -{ - $TribesNext::Community::Browser::Active = 0; - tn_community_Browser_executeNextRequest(); -} - -function CommunityBrowserInterface::onLine(%this, %line) -{ - if (trim(%line) $= "") - { - %this.primed = 1; - return; - } - if (!%this.primed) - return; - - //warn("Browser: " @ %line); - %message = getField(%line, 0); - switch$ (%message) - { - // display errors to the user -- some of these should never actually happen - case "ERR": - if (getField(%line, 1) $= "BROWSER") - { - %type = getField(%line, 2); - switch$ (%type) - { - // TODO -- implement different message types - case "BLAH": - %message = "Blah!"; - default: - %message = "Unknown error in browser system: " @ %line; - } - schedule(500, 0, MessageBoxOK, "ERROR", %message); - } - case "DCE": - %dceCert = collapseEscape(getField(%line, 1)); - %index = getField(%dceCert, 1); - $T2CSRI::ClientDCESupport::DCECert[%index] = %dceCert; - case "CEC": - $T2CSRI::CommunityCertificate = collapseEscape(getField(%line, 1)); - // schedule a refresh - %expire = getField($T2CSRI::CommunityCertificate, 2); - rubyEval("tsEval '$temp=\"' + (" @ %expire @ " - Time.now().to_i).to_s + '\";'"); - %expire = $temp - 60; - if (%expire > 0) - { - if (isEventPending($TribesNext::Browser::CertRefreshSch)) - cancel($TribesNext::Browser::CertRefreshSch); - $TribesNext::Browser::CertRefreshSch = schedule(1000 * %expire, 0, tn_community_Browser_request_cert); - } - else - { - schedule(500, 0, MessageBoxOK, "ERROR", "Received expired certificate from community server. Is your computer's clock set correctly?"); - } - } -} - - -function tn_community_browser_initQueue() -{ - if (isObject($BrowserRequestQueue)) - $BrowserRequestQueue.delete(); - $BrowserRequestQueue = new MessageVector(); -} -tn_community_browser_initQueue(); - -function tn_community_browser_processRequest(%request, %payload) -{ - if (%request !$= "") - { - %request = "?guid=" @ getField($LoginCertificate, 1) @ "&uuid=" @ $TribesNext::Community::UUID @ "&" @ %request; - } - if (%payload $= "") - { - %data = "GET " @ $TribesNext::Community::BaseURL @ $TribesNext::Community::BrowserScript @ %request; - %data = %data @ " HTTP/1.1\r\nHost: " @ $TribesNext::Community::Host @ "\r\nUser-Agent: Tribes 2\r\nConnection: close\r\n\r\n"; - } - else - { - %data = "POST " @ $TribesNext::Community::BaseURL @ $TribesNext::Community::BrowserScript @ " HTTP/1.1\r\n"; - %data = %data @ "Host: " @ $TribesNext::Community::Host @ "\r\nUser-Agent: Tribes 2\r\nConnection: close\r\n"; - %data = %data @ %payload; - } - - $BrowserRequestQueue.pushBackLine(%data); - - if (!$TribesNext::Community::Browser::Active) - tn_community_browser_executeNextRequest(); -} - -function tn_community_browser_executeNextRequest() -{ - if ($BrowserRequestQueue.getNumLines() <= 0) - return; - - %data = $BrowserRequestQueue.getLineText(0); - $BrowserRequestQueue.popFrontLine(); - - $TribesNext::Community::Browser::Active = 1; - - if (isObject(CommunityBrowserInterface)) - { - CommunityBrowserInterface.disconnect(); - } - else - { - new TCPObject(CommunityBrowserInterface); - } - CommunityBrowserInterface.data = %data; - CommunityBrowserInterface.connect($TribesNext::Community::Host @ ":" @ $TribesNext::Community::Port); -} - -// implementation of API requests - -function tn_community_Browser_request_cert() -{ - if ($TribesNext::Community::UUID $= "") - { - schedule(3000, 0, tn_community_Browser_request_cert); - return; - } - //error("Browser: Downloading enhanced certificate from community server."); - tn_community_Browser_processRequest("method=cert"); -} - -schedule(3000, 0, tn_community_Browser_request_cert); \ No newline at end of file diff --git a/docs/base/@vl2/tournamentNetClient2.vl2/tournament/login.cs b/docs/base/@vl2/tournamentNetClient2.vl2/tournament/login.cs deleted file mode 100644 index 95dc2a8b..00000000 --- a/docs/base/@vl2/tournamentNetClient2.vl2/tournament/login.cs +++ /dev/null @@ -1,185 +0,0 @@ -// TribesNext Project -// http://www.tribesnext.com/ -// Copyright 2011 - -// Tribes 2 Community System -// Robot Session Client - -// Since the game itself does not store the users' passwords for any longer than is required -// to decrypt their RSA private keys, the "robot" client must negotiate sessions through an -// RSA challenge/response. - -// The robot client issues a challenge request by sending the user's GUID and a random nonce. -// The DCE issues a challenge that is encrypted with the user's public key. The challenge is -// valid for a server configured lifetime, during which any challenge request by the same GUID -// would return the same challenge. The client sends the decrypted challenge back to the DCE, and -// if it is a match, a session is initiated, and a session UUID is returned to the robot client, -// which it uses to verify its identity for all authenticated requests. The challenge lifetime is -// sufficiently generous to allow an RSA decryption and heavy network latency. - -// The client will refresh periodically (every 10 minutes by default) to keep the session alive. - -function CommunitySessionInterface::onLine(%this, %line) -{ - //warn("SInterf: " @ %line); - if (trim(%line) $= "") - { - %this.primed = 1; - return; - } - if (%this.primed) - { - echo(%line); - if (getSubStr(%line, 0, 11) $= "CHALLENGE: ") - { - $TribesNext::Community::SessionErrors = 0; - $TribesNext::Community::Challenge = getSubStr(%line, 11, strlen(%line)); - //error("Challenge set: " @ $TribesNext::Community::Challenge); - - cancel($TribesNext::Community::SessionSchedule); - $TribesNext::Community::SessionSchedule = schedule(200, 0, tn_community_login_initiate); - } - else if (getSubStr(%line, 0, 6) $= "UUID: ") - { - $TribesNext::Community::SessionErrors = 0; - $TribesNext::Community::UUID = getSubStr(%line, 6, strlen(%line)); - $TribesNext::Community::Challenge = ""; - //error("UUID set: " @ $TribesNext::Community::UUID); - - cancel($TribesNext::Community::SessionSchedule); - $TribesNext::Community::SessionSchedule = schedule($TribesNext::Community::SessionRefresh * 1000, 0, tn_community_login_initiate); - } - else if (getSubStr(%line, 0, 5) $= "ERR: ") - { - error("Session negotiation error: " @ getSubStr(%line, 5, strlen(%line))); - $TribesNext::Community::UUID = ""; - $TribesNext::Community::Challenge = ""; - - // add schedule with backoff, up to about 15 minutes - $TribesNext::Community::SessionErrors++; - if ($TribesNext::Community::SessionErrors > 66) - $TribesNext::Community::SessionErrors = 66; - $TribesNext::Community::SessionSchedule = schedule(200 * ($TribesNext::Community::SessionErrors * $TribesNext::Community::SessionErrors), 0, tn_community_login_initiate); - } - else if (getSubStr(%line, 0, 9) $= "REFRESHED") - { - $TribesNext::Community::SessionErrors = 0; - //error("Session refreshed. Scheduling next ping."); - - cancel($TribesNext::Community::SessionSchedule); - $TribesNext::Community::SessionSchedule = schedule($TribesNext::Community::SessionRefresh * 1000, 0, tn_community_login_initiate); - } - else if (getSubStr(%line, 0, 7) $= "TIMEOUT") - { - $TribesNext::Community::SessionErrors = 0; - //error("Session timed out. Refreshing."); - $TribesNext::Community::UUID = ""; - $TribesNext::Community::Challenge = ""; - - cancel($TribesNext::Community::SessionSchedule); - $TribesNext::Community::SessionSchedule = schedule(200, 0, tn_community_login_initiate); - } - } -} - -function CommunitySessionInterface::onConnected(%this) -{ - //echo("Sending: " @ %this.data); - %this.primed = 0; - %this.send(%this.data); -} - -// initiates the session negotiation process -function tn_community_login_initiate() -{ - if (isEventPending($TribesNext::Community::SessionSchedule)) - { - cancel($TribesNext::Community::SessionSchedule); - } - %payload = "GET " @ $TribesNext::Community::BaseURL @ $TribesNext::Community::LoginScript @ "?guid=" @ getField($LoginCertificate, 1) @ "&"; - // is there an existing session? - if ($TribesNext::Community::UUID !$= "") - { - // try to refresh it - %payload = %payload @ "uuid=" @ $TribesNext::Community::UUID; - } - else - { - // no session -- either expired, or never had one - - // is a challenge present - if ($TribesNext::Community::Challenge $= "") - { - // no challenge present... ask for one: - // create a random nonce half of the length of the active RSA key modulus - %length = strlen(getField($LoginCertificate, 3)) / 2; - %nonce = "1"; // start with a one to prevent truncation issues - for (%i = 1; %i < %length; %i++) - { - %nibble = getRandom(0, 15); - if (%nibble == 10) - %nibble = "a"; - else if (%nibble == 11) - %nibble = "b"; - else if (%nibble == 12) - %nibble = "c"; - else if (%nibble == 13) - %nibble = "d"; - else if (%nibble == 14) - %nibble = "e"; - else if (%nibble >= 15) - %nibble = "f"; - %nonce = %nonce @ %nibble; - } - $TribesNext::Community::Nonce = %nonce; - // transmit the request to the community server - %payload = %payload @ "nonce=" @ %nonce; - } - else - { - %challenge = strlwr($TribesNext::Community::Challenge); - for (%i = 0; %i < strlen(%challenge); %i++) - { - %char = strcmp(getSubStr(%challenge, %i, 1), ""); - if ((%char < 48 || %char > 102) || (%char > 57 && %char < 97)) - { - // non-hex characters in the challenge! - error("TNCommunity: Hostile challenge payload returned by server!"); - $TribesNext::Community::Challenge = ""; - tn_community_login_initiate(); - return; - } - } - - // challenge is present... decrypt it and transmit it to the community server - rubyEval("tsEval '$decryptedChallenge=\"' + $accountKey.decrypt('" @ %challenge @ "'.to_i(16)).to_s(16) + '\";'"); - - %verifiedNonce = getSubStr($decryptedChallenge, 0, strLen($TribesNext::Community::Nonce)); - if (%verifiedNonce !$= $TribesNext::Community::Nonce) - { - // this is not the nonce we sent to the community server, try again - error("TNCommunity: Unmatched nonce in challenge returned by server!"); - $TribesNext::Community::Challenge = ""; - tn_community_login_initiate(); - return; - } - else - { - %response = getSubStr($decryptedChallenge, strLen($TribesNext::Community::Nonce), strlen($decryptedChallenge)); - %payload = %payload @ "response=" @ %response; - } - } - } - %payload = %payload @ " HTTP/1.1\r\nHost: " @ $TribesNext::Community::Host @ "\r\nUser-Agent: Tribes 2\r\nConnection: close\r\n\r\n"; - - if (isObject(CommunitySessionInterface)) - { - CommunitySessionInterface.disconnect(); - } - else - { - new TCPObject(CommunitySessionInterface); - } - CommunitySessionInterface.data = %payload; - CommunitySessionInterface.connect($TribesNext::Community::Host @ ":" @ $TribesNext::Community::Port); -} \ No newline at end of file diff --git a/docs/base/@vl2/tournamentNetClient2.vl2/tournament/settings.cs b/docs/base/@vl2/tournamentNetClient2.vl2/tournament/settings.cs deleted file mode 100644 index 88f15f20..00000000 --- a/docs/base/@vl2/tournamentNetClient2.vl2/tournament/settings.cs +++ /dev/null @@ -1,19 +0,0 @@ -// TribesNext Project -// http://www.tribesnext.com/ -// Copyright 2011-2017 - -// Tribes 2 Community System -// Robot Client Settings -// Tournament Version - -// This file contains the URL and server settings for the community system. - -$TribesNext::Community::Host = "tribesnext.thyth.com"; -$TribesNext::Community::Port = 80; -$TribesNext::Community::BaseURL = "/tn/robot/"; - -$TribesNext::Community::LoginScript = "robot_login.php"; -$TribesNext::Community::MailScript = "robot_mail.php"; -$TribesNext::Community::BrowserScript = "robot_browser.php"; - -$TribesNext::Community::SessionRefresh = 10*60; \ No newline at end of file diff --git a/docs/base/@vl2/zAddOnsVL2s/LakRabbit_Client.vl2/scripts/autoexec/LakRabbitObjHud.cs b/docs/base/@vl2/zAddOnsVL2s/LakRabbit_Client.vl2/scripts/autoexec/LakRabbitObjHud.cs deleted file mode 100644 index 4ec1557e..00000000 --- a/docs/base/@vl2/zAddOnsVL2s/LakRabbit_Client.vl2/scripts/autoexec/LakRabbitObjHud.cs +++ /dev/null @@ -1,59 +0,0 @@ - -package LakObjHud { -function setupObjHud(%gameType) -{ - switch$ (%gameType) - { - case LakRabbitGame: - // 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); - } - parent::setupObjHud(%gameType); -} -}; -activatePackage(LakObjHud); diff --git a/docs/base/@vl2/zAddOnsVL2s/arenaSupport.vl2/scripts/autoexec/arenaSupport.cs b/docs/base/@vl2/zAddOnsVL2s/arenaSupport.vl2/scripts/autoexec/arenaSupport.cs deleted file mode 100644 index bd1e4861..00000000 --- a/docs/base/@vl2/zAddOnsVL2s/arenaSupport.vl2/scripts/autoexec/arenaSupport.cs +++ /dev/null @@ -1,372 +0,0 @@ -// #name = Arena Support -// #version = 1.0 -// #date = Febuary 19, 2002 -// #author = Teribaen -// #warrior = Teribaen -// #email = teribaen@planettribes.com -// #description = Adds an objective HUD and admin commands for the Arena gametype -// #readme = scripts/teribaen/arena_support_info.txt -// #status = Release -// ------------------------------------------------------------------ // - -$ArenaSupport::LocalVersion = 1.0; -$ArenaSupport::RemoteVersion = 0; - -$ArenaSupport::TeamCount = 2; - -// ------------------------------------------------------------------ // -// arenaVersionMsg() -// Recieves version information from the Arena server - -function arenaVersionMsg( %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6 ) -{ - %version = detag(%a1); - %versionString = detag(%a2); - - echo( "arenaSupport got remote arena version: "@%versionString@" ("@%version@")" ); - - $ArenaSupport::RemoteVersion = %version; - - // Put this below the objectiveHud arena label for a few seconds - objectiveHud.arenaLabel[2].setValue( %versionString ); - $ArenaSupport::versClearSchedule = schedule( 15000, 0, arenaClearVersionBox ); - - // Respond to the server with our version information - commandToServer( 'ArenaSupportHello', $ArenaSupport::LocalVersion ); -} - - -// ========================================================================== // -// | | // -// | ARENA HUD | // -// | | // -// ========================================================================== // - -// ------------------------------------------------------------------ // -// arenaServerState() -// Receive information about the server setup - -function arenaServerState( %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6 ) -{ - %teamCount = detag(%a1); - - echo( "arenaSupport got teamCount: "@%teamCount ); - - $ArenaSupport::TeamCount = %teamCount; -} - -// ------------------------------------------------------------------ // -// BEGIN PACKAGE [ ArenaHUD ] -// ------------------------------------------------------------------ // - -package ArenaHUD -{ - -// ------------------------------------------------------------------ // -// setupObjHud() -// On entering a game prepare the objective hud based on the gametype - -function setupObjHud( %gameType ) -{ - echo( "setupObjHud called for ArenaHUD" ); - - if ( %gameType $= ArenaGame ) - { - // Set the dividing lines between controls - objectiveHud.setSeparators( "48 150 202" ); - objectiveHud.enableHorzSeparator(); - - // Arena Label ("ARENA") - objectiveHud.arenaLabel[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 3"; - extent = "42 16"; - visible = "1"; - text = "ARENA"; - }; - - // Arena Version (Just displays a string from server) - objectiveHud.arenaLabel[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 19"; - extent = "42 16"; - visible = "1"; - }; - - // Team Names Column - objectiveHud.teamName[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "56 3"; - extent = "90 16"; - visible = "1"; - }; - objectiveHud.teamName[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudLeftProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "56 19"; - extent = "90 16"; - visible = "1"; - }; - - // Team State Column (%alive/%total) - objectiveHud.arenaState[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "156 3"; - extent = "43 16"; - visible = "1"; - }; - objectiveHud.arenaState[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "156 19"; - extent = "43 16"; - visible = "1"; - }; - - // Team Scores Column - objectiveHud.teamScore[1] = new GuiTextCtrl() { - profile = "GuiTextObjGreenCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "209 3"; - extent = "26 16"; - visible = "1"; - }; - objectiveHud.teamScore[2] = new GuiTextCtrl() { - profile = "GuiTextObjHudCenterProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "209 19"; - extent = "26 16"; - visible = "1"; - }; - - // Add our controls to the parent hud object - for(%i = 1; %i <= 2; %i++) - { - objectiveHud.add( objectiveHud.arenaLabel[%i] ); - objectiveHud.add( objectiveHud.teamName[%i] ); - objectiveHud.add( objectiveHud.arenaState[%i] ); - objectiveHud.add( objectiveHud.teamScore[%i] ); - } - } - else - Parent::setupObjHud( %gameType ); -} - -// ------------------------------------------------------------------ // -// swapTeamLines() -// Swap the objective hud lines to put the player's team on top - -function swapTeamLines() -{ - if ( $ArenaSupport::TeamCount != 2 ) - return; - - // Formatting constants - %bLeft = "GuiTextObjHudLeftProfile"; - %bCenter = "GuiTextObjHudCenterProfile"; - %gLeft = "GuiTextObjGreenLeftProfile"; - %gCenter = "GuiTextObjGreenCenterProfile"; - - // Swap the vertical positions of the hud lines - %teamOneY = getWord( objectiveHud.teamName[1].position, 1 ); - %teamTwoY = getWord( objectiveHud.teamName[2].position, 1 ); - - if(%teamOneY > %teamTwoY) - { - // If team one was on the second line, now it'll be on the first - %newTop = 1; - %newBottom = 2; - } - else - { - // If team one was on the first line, now it'll be on the second - %newTop = 2; - %newBottom = 1; - } - - // Swap the controls specific to Arena - if( isObject( objectiveHud.arenaState[1] ) ) - { - %locatX = firstWord( objectiveHud.arenaState[1].position ); - objectiveHud.arenaState[1].position = %locatX SPC %teamTwoY; - objectiveHud.arenaState[2].position = %locatX SPC %teamOneY; - - // Swap profiles so top line is green (don't bother with labels) - objectiveHud.arenaState[%newTop].setProfile( %gCenter ); - objectiveHud.arenaState[%newbottom].setProfile( %bCenter ); - } - - // Swap built-in controls - Parent::swapTeamLines(); -} - -// ------------------------------------------------------------------ // -// DispatchLaunchMode() -// Use this builtin function to add our callbacks - -function DispatchLaunchMode() -{ - echo( "DispatchLaunchMode() adding callbacks for ArenaHUD" ); - - addMessageCallback( 'MsgArenaVersion', arenaVersionMsg ); - addMessageCallback( 'MsgArenaServerState', arenaServerState ); - addMessageCallback( 'MsgArenaAddTeam', arenaAddTeam ); - addMessageCallback( 'MsgArenaTeamState', arenaTeamState ); - - Parent::DispatchLaunchMode(); -} - -}; - -// ------------------------------------------------------------------ // -// END PACKAGE [ ArenaHUD ] -// ------------------------------------------------------------------ // - - -// ------------------------------------------------------------------ // -// arenaAddTeam() -// Add a team to the arena objective hud - -function arenaAddTeam( %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6 ) -{ - %teamNum = detag(%a1); - if ( %teamNum > 2 ) - return; - - %teamName = detag(%a2); - %score = detag(%a3); - if( %score $= "" ) - %score = 0; - - %aliveCount = detag(%a4); - %totalCount = detag(%a5); - if( %aliveCount $= "" ) - %aliveCount = 0; - if( %totalCount $= "" ) - %totalCount = 0; - - if ( $ArenaSupport::TeamCount == 2 ) - { - objectiveHud.teamName[%teamNum].setValue( %teamName ); - objectiveHud.teamScore[%teamNum].setValue( %score ); - objectiveHud.arenaState[%teamNum].setValue( %aliveCount @ "/" @ %totalCount ); - } -} - -// ------------------------------------------------------------------ // -// arenaTeamState() -// Update the alive/total player count for a team on the arena hud - -function arenaTeamState( %msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6 ) -{ - %teamNum = detag(%a1); - if ( %teamNum > 2 ) - return; - - %aliveCount = detag(%a2); - %totalCount = detag(%a3); - - if( %aliveCount $= "" ) - %aliveCount = 0; - if( %totalCount $= "" ) - %totalCount = 0; - - if ( $ArenaSupport::TeamCount == 2 ) - objectiveHud.arenaState[%teamNum].setValue( %aliveCount @ "/" @ %totalCount ); -} - -// ------------------------------------------------------------------ // -// arenaClearVersionBox() -// Clears the objhud version box (under the arena label) - -function arenaClearVersionBox() -{ - objectiveHud.arenaLabel[2].setValue( "" ); -} - - -// ------------------------------------------------------------------ // -// Always execute the ArenaHUD package - -activatePackage( ArenaHUD ); - - - -// ========================================================================== // -// | | // -// | CONSOLE ADMIN COMMANDS | // -// | | // -// ========================================================================== // - -// ------------------------------------------------------------------ // -// arenaForceRoundEnd(); - -function arenaForceRoundEnd( %teamIndex ) -{ - if ( %teamIndex $= "" ) - %teamIndex = 0; - - commandToServer( 'ArenaForceRoundEnd', %teamIndex ); -} - -// ------------------------------------------------------------------ // -// arenaSetCurrentRoundLimit(); - -function arenaSetCurrentRoundLimit( %newRoundLimit ) -{ - commandToServer( 'ArenaSetCurrentRoundLimit', %newRoundLimit ); -} - -// ------------------------------------------------------------------ // -// arenaSetCurrentTimeLimit(); - -function arenaSetCurrentTimeLimit( %newTimeLimit ) -{ - commandToServer( 'ArenaSetCurrentTimeLimit', %newTimeLimit ); -} - -// ------------------------------------------------------------------ // -// arenaEnableDebugging(); - -function arenaEnableDebugging() -{ - commandToServer( 'ArenaEnableDebugging' ); -} - -// ------------------------------------------------------------------ // -// arenaDisableDebugging(); - -function arenaDisableDebugging() -{ - commandToServer( 'ArenaDisableDebugging' ); -} - -// ------------------------------------------------------------------ // -// SADsetJoinPassword(); - -function SADsetJoinPassword( %newPassword ) -{ - commandToServer( 'SetJoinPassword', %newPassword ); -} - - - -// ========================================================================== // -// | | // -// | VOTING/MENU SUPPORT | // -// | | // -// ========================================================================== // - - diff --git a/docs/base/@vl2/zAddOnsVL2s/arenaSupport.vl2/scripts/teribaen/arena_support_info.txt b/docs/base/@vl2/zAddOnsVL2s/arenaSupport.vl2/scripts/teribaen/arena_support_info.txt deleted file mode 100644 index 9e05247d..00000000 --- a/docs/base/@vl2/zAddOnsVL2s/arenaSupport.vl2/scripts/teribaen/arena_support_info.txt +++ /dev/null @@ -1,54 +0,0 @@ --------------------------------------------------- -Arena Support (Version 1.0) - By Teribaen --------------------------------------------------- - -This script adds clientside support for the Tribes 2 Arena gametype, including: - -* ObjectiveHUD (HUD in the lower left) -* Console commands for admins - -Possible future features: - -* Support for voting/admin lobby options - -This version is parallel with the 0.95 arena server and replaces both ArenaHUD versions (0.91 and 0.94d) - - --------------------------------------------------- -Admin Console Commands --------------------------------------------------- - -These commands are entered into your client console (which must be enhanced by Arena Support) - not the server console - -To use these commands you must have admin or super admin access (depending on the command) - - -arenaForceRoundEnd( # ); -The current round will end and the game will advance to the next round -OPTIONAL: Specify the index of a team to win the round (ie: 1 or 2 ) - - -arenaSetCurrentRoundLimit( # ) -Changes the round limit to # - Effective Immediately -IMPORTANT: The change lasts only until the server changes maps - - -arenaSetCurrentTimeLimit( # ) - Requires Arena 0.95b+ -Changes the time limit to # - Effective at the start of the next round -IMPORTANT: The change lasts only until the server changes maps - - -arenaEnableDebugging() -Enables debug output from arena and terAdmin (normally you want this off) - - -arenaDisableDebugging() -Disables debug output from arena and terAdmin - - -SADsetJoinPassword( $ ) -Changes the server join password to $ -Set the password to "" to disable it -IMPORTANT: In Arena 0.95a/b/y/c this lasts only until the map changes - -Example: SADsetJoinPassword( "leet" ); or SADsetJoinPassword( "" ); diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/C_BaseLoPro.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/C_BaseLoPro.glb new file mode 100644 index 00000000..b8671754 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/C_BaseLoPro.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/borg16-Autumn.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/borg16-Autumn.glb new file mode 100644 index 00000000..b901eb55 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/borg16-Autumn.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/borg19-Autumn.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/borg19-Autumn.glb new file mode 100644 index 00000000..5f5756fd Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/borg19-Autumn.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/porg1-dark.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/porg1-dark.glb new file mode 100644 index 00000000..f2822526 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/porg1-dark.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-TCmug.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-TCmug.glb new file mode 100644 index 00000000..75df3ec9 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-TCmug.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-TNmug.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-TNmug.glb new file mode 100644 index 00000000..71318b67 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-TNmug.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-chocotaco.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-chocotaco.glb new file mode 100644 index 00000000..a491ea41 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-chocotaco.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-goonflag.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-goonflag.glb new file mode 100644 index 00000000..fcf3c3e3 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-goonflag.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-samifin.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-samifin.glb new file mode 100644 index 00000000..c6d37bde Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-samifin.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-santahat.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-santahat.glb new file mode 100644 index 00000000..448eaa18 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-santahat.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-taobook.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-taobook.glb new file mode 100644 index 00000000..a0a76022 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-taobook.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-turtle.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-turtle.glb new file mode 100644 index 00000000..9373f02d Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/rst-turtle.glb differ diff --git a/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/vend.glb b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/vend.glb new file mode 100644 index 00000000..a7970df9 Binary files /dev/null and b/docs/base/@vl2/zAddOnsVL2s/zDiscord-Map-Pack-4.7.1.vl2/shapes/vend.glb differ diff --git a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/adminHud.cs b/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/adminHud.cs deleted file mode 100644 index cc7213c3..00000000 --- a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/adminHud.cs +++ /dev/null @@ -1,358 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: ADMIN HUD /////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function CreateAdminHud() -{ - $AdminHudId = new GuiControl(AdminHudDlg) { - profile = "GuiDialogProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new ShellPaneCtrl() { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "170 137"; - extent = "320 260"; - minExtent = "48 92"; - visible = "1"; - helpTag = "0"; - text = "Admin Hud"; - noTitleBar = "0"; - - // -- Drop down menu text label - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 52"; - extent = "50 22"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - text = "Menu:"; - }; - // -- Drop down menu - new ShellPopupMenu(AdminHudMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 44"; - extent = "225 38"; - minExtent = "49 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "- OPTIONS -"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - // -- Input text field label - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 88"; - extent = "50 22"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - text = "Input:"; - }; - // -- Input text field - new ShellTextEditCtrl(AdminHudInput) { - profile = "NewTextEditProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 80"; - extent = "225 38"; - minExtent = "32 38"; - visible = "1"; - command = "AdminHudInput.setField();"; - altCommand = "AdminHudInput.processEnter();"; - helpTag = "0"; - historySize = "0"; - maxLength = "127"; - password = "0"; - glowOffset = "9 9"; - }; - // -- Cancel button - new ShellBitmapButton(AdminHudCancelBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "60 118"; - extent = "120 38"; - minExtent = "32 38"; - visible = "1"; - command = "HideAdminHud();"; - accelerator = "escape"; - helpTag = "0"; - text = "CANCEL"; - simpleStyle = "0"; - }; - // -- Send button - new ShellBitmapButton(AdminHudSendBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "165 118"; - extent = "120 38"; - minExtent = "32 38"; - visible = "1"; - command = "AdminHudSendBtn.adminCommand();"; - helpTag = "0"; - text = "SEND"; - simpleStyle = "0"; - }; - // -- Clan Tag drop down menu text label - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 173"; - extent = "50 22"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - text = "Tags:"; - }; - // -- Clan Tag drop down menu - new ShellPopupMenu(ClanTagHudMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 165"; - extent = "225 38"; - minExtent = "49 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "- CLAN TAGS -"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellBitmapButton(ClanTagSendBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "60 200"; - extent = "225 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "ClanTagSendBtn.sendTagCommand();"; - helpTag = "0"; - text = "CHANGE CLAN TAG"; - simpleStyle = "0"; - }; - }; - }; - ClanTagSendBtn.setActive(0); -} - -function handleActivateAdminHud() -{ - if(!$AdminHudCreated) - { - CreateAdminHud(); // Create the gui - UpdateAdminHudMenu(); // Fill the drop down menu - $AdminHudCreated = 1; // Set the flag - } -} - -addMessageCallback('MsgClientJoin', handleActivateAdminHud); - -function ShowAdminHud() -{ - canvas.pushdialog(AdminHudDlg); - //clientCmdTogglePlayHuds(false); - $AdminHudOpen = 1; -} - -function HideAdminHud() -{ - // Empty out the text input field - AdminHudInput.setValue(%empty); - - canvas.popdialog(AdminHudDlg); - $AdminHudOpen = 0; - //clientCmdTogglePlayHuds(true); -} - -function AdminHudDlg::onWake( %this ) -{ - if ( isObject( AdminHudMap ) ) - { - AdminHudMap.pop(); - AdminHudMap.delete(); - } - new ActionMap( AdminHudMap ); - AdminHudMap.blockBind( moveMap, toggleModHud ); - AdminHudMap.blockBind( moveMap, togglePracticeHud ); - AdminHudMap.blockBind( moveMap, toggleInventoryHud ); - AdminHudMap.blockBind( moveMap, toggleScoreScreen ); - AdminHudMap.blockBind( moveMap, toggleCommanderMap ); - AdminHudMap.bindCmd( keyboard, escape, "", "HideAdminHud();" ); - AdminHudMap.push(); -} - -function AdminHudDlg::onSleep( %this ) -{ - %this.callback = ""; - AdminHudMap.pop(); - AdminHudMap.delete(); -} - -function UpdateAdminHudMenu() -{ - // Populate the drop down menu with options seperated by \t (tab deliniated list). - %line1 = "Choose Option\tEnter Admin Password\tEnter Super Admin Password\tSet Join Password\tSet Admin Password\tSet Super Admin Password"; - %line2 = "\tSet Random Teams\tSet Fair Teams\tSet Max Players\tSet Auto-PW\tSet Auto-PW Password\tSet Auto-PW Count\tSend Bottomprint Message"; - %line3 = "\tSend Centerprint Message\tRemove Map From Rotation\tRestore Map To Rotation\tRemove GameType\tRestore GameType\tRestart Server\tConsole Command"; - %opt = %line1 @ %line2 @ %line3; - AdminHudMenu.hudSetValue(%opt, ""); - // Update the Clan Tag drop down menu as well - commandToServer('canGetClanTags'); -} - -function AdminHudMenu::onSelect(%this, %id, %text) -{ - // Called when an option is selected in drop down menu - $AdminMenu = %this.getValue(); -} - -function AdminHudInput::setField( %this ) -{ - // called when you type in text input field - %value = %this.getValue(); - %this.setValue( %value ); - $AdminInput = %value; - //AdminHudSendBtn.setActive( strlen( stripTrailingSpaces( %value ) ) >= 1 ); -} - -function AdminHudInput::processEnter( %this ) -{ - // Called when you press enter in text input field -} - -function AdminHudSendBtn::adminCommand( %this ) -{ - // Called when you press the send button - - // Update the global from the text input field - AdminHudInput.setField(); - - // Send the current menu selection and text to the server - switch$ ( $AdminMenu ) - { - case "Enter Admin Password": - commandToServer('SAD', $AdminInput); - - case "Enter Super Admin Password": - commandToServer('SAD', $AdminInput); - - case "Set Join Password": - commandToServer('Set', "joinpw", $AdminInput); - - case "Set Admin Password": - commandToServer('Set', "adminpw", $AdminInput); - - case "Set Super Admin Password": - commandToServer('Set', "superpw", $AdminInput); - - case "Set Random Teams": - commandToServer('Set', "random", $AdminInput); - - case "Set Fair Teams": - commandToServer('Set', "fairteams", $AdminInput); - - case "Set Max Players": - commandToServer('Set', "maxplayers", $AdminInput); - - case "Set Auto-PW": - commandToServer('AutoPWSetup', "autopw", $AdminInput); - - case "Set Auto-PW Password": - commandToServer('AutoPWSetup', "autopwpass", $AdminInput); - - case "Set Auto-PW Count": - commandToServer('AutoPWSetup', "autopwcount", $AdminInput); - - case "Send Bottomprint Message": - commandToServer('aprint', $AdminInput, true); - - case "Send Centerprint Message": - commandToServer('aprint', $AdminInput, false); - - case "Remove Map From Rotation": - commandToServer('AddMap', $AdminInput); - - case "Restore Map To Rotation": - commandToServer('RemoveMap', $AdminInput); - - case "Remove GameType": - commandToServer('AddType', $AdminInput); - - case "Restore GameType": - commandToServer('RemoveType', $AdminInput); - - case "Restart Server": - commandToServer('Set', "restart", $AdminInput); - - case "Console Command": - commandToServer('Set', "consolecmd", $AdminInput); - - default: - error("Admin Hud selected option: " @ $AdminMenu @ " input: " @ $AdminInput @ " unknown values."); - } - - // Clear the text input field and disable send button - //AdminHudSendBtn.setActive(0); - AdminHudInput.setValue(%empty); - UpdateAdminHudMenu(); - $AdminInput = ""; - $AdminMenu = ""; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Canadian, 7/19/03. Clan Tag switiching ////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function ClanTagHudMenu::onSelect(%this, %id, %text) -{ - // Called when an option is selected in drop down menu - $CanSelected = %this.getValue(); - ClanTagSendBtn.setActive(1); -} - -function ClanTagSendBtn::sendTagCommand( %this ) -{ - // Called when you press the send button - // Send the current menu selection and text to the server - commandToServer('canUpdateClanTag', $CanSelected); - $CanSelected = ""; - HideAdminHud(); -} - -function clientCmdcanDisplayTags(%tags) -{ - ClanTagHudMenu.hudSetValue(%tags, ""); -} diff --git a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/classicPropMap.cs b/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/classicPropMap.cs deleted file mode 100644 index 1a53ca97..00000000 --- a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/classicPropMap.cs +++ /dev/null @@ -1,19 +0,0 @@ -// terrain sound/puff properties for Classic mod maps. z0dd - ZOD, 7/20/02 - -//"Color: red green blue startAlpha endAlpha" -//Soft sound = 0 -//Hard sound = 1 -//Metal sound = 2 -//Snow sound = 3 - -addMaterialMapping("terrain/GMD.DarkRock", "color: 0.5 0.36 0.16 0.4 0.0", "sound: 1"); -addMaterialMapping("terrain/GMD.DirtMossy", "color: 0.46 0.36 0.26 0.4 0.0", "sound: 0"); -addMaterialMapping("terrain/gmd.grassmixed", "color: 0.46 0.36 0.26 0.4 0.0", "sound: 0"); -addMaterialMapping("terrain/GMD.LightSand", "color: 0.5 0.36 0.16 0.4 0.0", "sound: 0"); -addMaterialMapping("terrain/GMD.SandBurnt", "color: 0.5 0.36 0.16 0.4 0.0", "sound: 0"); -addMaterialMapping("terrain/GMD.GrassLight", "color: 0.46 0.36 0.26 0.4 0.0", "sound: 0"); -addMaterialMapping("terrain/lushworld.lakesand", "color: 0.5 0.36 0.16 0.4 0.0", "sound: 0"); -addMaterialMapping("terrain/Eep.MoonDirt", "color: 0.0 0.0 0.0 0.7 0.0", "sound: 0"); -addMaterialMapping("terrain/Eep.MoonDirtDark", "color: 0.0 0.0 0.0 0.7 0.0", "sound: 0"); -addMaterialMapping("terrain/ril.darkrock", "color: 0.0 0.0 0.0 0.7 0.0", "sound: 1"); -addMaterialMapping("terrain/ril.darkrock1", "color: 0.0 0.0 0.0 0.7 0.0", "sound: 1"); diff --git a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/clientOverloads.cs b/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/clientOverloads.cs deleted file mode 100644 index 2499f184..00000000 --- a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/clientOverloads.cs +++ /dev/null @@ -1,530 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: Overloaded base function package //////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -package zzClientOverloads -{ - function clientCmdMissionStartPhase3(%seq, %missionName) - { - parent::clientCmdMissionStartPhase3(%seq, %missionName); - commandToServer('getMod'); - } - - function LobbyGui::onSleep( %this ) - { - if ( %this.playerDialogOpen ) - LobbyPlayerPopup.forceClose(); - - LobbyVoteMenu.clear(); - LobbyVoteMenu.mode = ""; - LobbyCancelBtn.setVisible( false ); - LobbyStatusText.setText( "" ); - $InLobby = false; - $PrivMsgTarget = ""; - } - - function lobbyReturnToGame() - { - Canvas.setContent( PlayGui ); - $PrivMsgTarget = ""; - } - - function LobbyChatEnter::onEscape( %this ) - { - %this.setValue( "" ); - $PrivMsgTarget = ""; - } - - function LobbyChatEnter::send( %this ) - { - %text = %this.getValue(); - if ( %text $= "" ) - %text = " "; - - if($PrivMsgTarget !$= "") - { - commandToServer('PrivateMessageSent', $PrivMsgTarget, %text); - $PrivMsgTarget = ""; - %this.setValue( "" ); - } - else - { - commandToServer( 'MessageSent', %text ); - %this.setValue( "" ); - } - } - - function OptionsDlg::onWake( %this ) - { - if(!$ClassicHudsBound) - { - $RemapName[$RemapCount] = "Toss Repair Kit"; - $RemapCmd[$RemapCount] = "tossRepairKit"; - $RemapCount++; - $RemapName[$RemapCount] = "Toss Weapon Ammo"; - $RemapCmd[$RemapCount] = "tossAmmo"; - $RemapCount++; - $RemapName[$RemapCount] = "Toss Mine"; - $RemapCmd[$RemapCount] = "tossMine"; - $RemapCount++; - $RemapName[$RemapCount] = "Toss Beacon"; - $RemapCmd[$RemapCount] = "tossBeacon"; - $RemapCount++; - $RemapName[$RemapCount] = "Toss Grenade"; - $RemapCmd[$RemapCount] = "tossGrenade"; - $RemapCount++; - $RemapName[$RemapCount] = "Max Throw Grenade"; - $RemapCmd[$RemapCount] = "throwGrenadeMax"; - $RemapCount++; - $RemapName[$RemapCount] = "Max Throw Mine"; - $RemapCmd[$RemapCount] = "throwMineMax"; - $RemapCount++; - $RemapName[$RemapCount] = "Mod Hud"; - $RemapCmd[$RemapCount] = "toggleModHud"; - $RemapCount++; - $RemapName[$RemapCount] = "Admin Hud"; - $RemapCmd[$RemapCount] = "toggleAdminHud"; - $RemapCount++; - $RemapName[$RemapCount] = "Practice Hud"; - $RemapCmd[$RemapCount] = "togglePracticeHud"; - $RemapCount++; - $ClassicHudsBound = true; - } - parent::onWake( %this ); - } - - function clientCmdSetDefaultVehicleKeys(%inVehicle) - { - Parent::clientCmdSetDefaultVehicleKeys(%inVehicle); - if(%inVehicle) - { - passengerKeys.copyBind( moveMap, toggleModHud ); - passengerKeys.copyBind( moveMap, toggleAdminHud ); - passengerKeys.copyBind( moveMap, togglePracticeHud ); - passengerKeys.copyBind( moveMap, mouseJet ); - passengerKeys.copyBind( moveMap, throwGrenadeMax ); - passengerKeys.copyBind( moveMap, throwMineMax ); - } - } - - function clientCmdSetStationKeys(%inStation) - { - Parent::clientCmdSetStationKeys(%inStation); - if ( %inStation ) - { - stationMap.blockBind( moveMap, toggleModHud ); - stationMap.blockBind( moveMap, toggleAdminHud ); - stationMap.blockBind( moveMap, togglePracticeHud ); - } - } - - function lobbyVote() - { - %id = LobbyVoteMenu.getSelectedId(); - %text = LobbyVoteMenu.getRowTextById( %id ); - switch$ ( LobbyVoteMenu.mode ) - { - case "": - switch$ ( $clVoteCmd[%id] ) - { - case "JoinGame": - CommandToServer( 'clientJoinGame' ); - schedule( 100, 0, lobbyReturnToGame ); - return; - - case "ChooseTeam": - commandToServer( 'ClientJoinTeam', -1, true ); - schedule( 100, 0, lobbyReturnToGame ); - return; - - case "VoteTournamentMode": - LobbyVoteMenu.tourneyChoose = 1; - fillLobbyMissionTypeMenu(); - return; - - case "VoteMatchStart": - startNewVote( "VoteMatchStart" ); - schedule( 100, 0, lobbyReturnToGame ); - return; - - case "MakeObserver": - commandToServer( 'ClientMakeObserver' ); - schedule( 100, 0, lobbyReturnToGame ); - return; - - case "VoteChangeMission": - fillLobbyMissionTypeMenu(); - return; - - case "VoteChangeTimeLimit": - fillLobbyTimeLimitMenu(); - return; - - case "Addbot": - commandToServer( 'addBot' ); - return; - - case "VoteArmorClass": - fillLobbyArmorClassMenu(); - return; - - case "VoteAntiTurtleTime": - fillLobbyAntiTurtleMenu(); - return; - } - case "team": - commandToServer( 'ClientJoinTeam', %id++ ); - LobbyVoteMenu.reset(); - return; - - case "type": - fillLobbyMissionMenu( $clVoteCmd[%id], %text ); - return; - - case "mission": - if( !LobbyVoteMenu.tourneyChoose ) - { - startNewVote( "VoteChangeMission", - %text, // Mission display name - LobbyVoteMenu.typeName, // Mission type display name - $clVoteCmd[%id], // Mission id - LobbyVoteMenu.missionType ); // Mission type id - } - else - { - startNewVote( "VoteTournamentMode", - %text, // Mission display name - LobbyVoteMenu.typeName, // Mission type display name - $clVoteCmd[%id], // Mission id - LobbyVoteMenu.missionType ); // Mission type id - - LobbyVoteMenu.tourneyChoose = 0; - } - LobbyVoteMenu.reset(); - return; - - case "timeLimit": - startNewVote( "VoteChangeTimeLimit", $clVoteCmd[%id] ); - LobbyVoteMenu.reset(); - return; - - case "armorclass": - startNewVote( "VoteArmorClass", $clVoteCmd[%id] ); - LobbyVoteMenu.reset(); - return; - - case "antiturtle": - startNewVote( "VoteAntiTurtleTime", $clVoteCmd[%id] ); - LobbyVoteMenu.reset(); - return; - } - startNewVote( $clVoteCmd[%id], $clVoteAction[%id] ); - fillLobbyVoteMenu(); - } - - function LobbyPlayerPopup::onSelect( %this, %id, %text ) - { - parent::onSelect(%this, %id, %text); - switch( %id ) - { - case 12: - commandToServer('ProcessGameLink', %this.player.clientId); - - case 13: - commandToServer('WarnPlayer', %this.player.clientId); - - case 14: - commandToServer('StripAdmin', %this.player.clientId); - - case 15: - PrivateMessage(%this.player.clientId); - // From Rapture Admin - MeBad - case 16: - commandToServer('PrintClientInfo', %this.player.clientId); - - case 17: - commandToServer('togglePlayerGag', %this.player.clientId); - - case 18: - commandToServer('togglePlayerFreeze', %this.player.clientId); - - case 19: - commandToServer('bootToTheRear', %this.player.clientId); - - case 20: - commandToServer('explodePlayer', %this.player.clientId); - } - Canvas.popDialog( LobbyPlayerActionDlg ); - } - - function VehicleHud::onBuy( %this ) - { - //toggleCursorHuds( 'vehicleHud' ); // z0dd - ZOD, 5/01/02. Dont close veh station HUD after selecting - commandToServer( 'buyVehicle', %this.selected ); - } -}; - -activatePackage(zzClientOverloads); - -function fillLobbyArmorClassMenu() -{ - LobbyVoteMenu.key++; - LobbyVoteMenu.clear(); - LobbyVoteMenu.mode = "armorclass"; - commandToServer( 'GetArmorClassList', LobbyVoteMenu.key ); - LobbyCancelBtn.setVisible( true ); -} - -function fillLobbyAntiTurtleMenu() -{ - LobbyVoteMenu.key++; - LobbyVoteMenu.clear(); - LobbyVoteMenu.mode = "antiturtle"; - commandToServer( 'GetAntiTurtleTimeList', LobbyVoteMenu.key ); - LobbyCancelBtn.setVisible( true ); -} - -function assignMissionType(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) -{ - $thisMissionType = detag(%gameType); -} - -function handleStripAdminMsg(%msgType, %msgString, %super, %admin, %client) -{ - %player = $PlayerList[%client]; - if(%player) - { - %player.isSuperAdmin = false; - %player.isAdmin = false; - lobbyUpdatePlayer(%client); - } - alxPlay(AdminForceSound, 0, 0, 0); -} - -function clientCmdGetClassicModSettings(%val) -{ - if(%val) - { - commandToServer('SetHitSounds', $pref::Classic::playerHitSound, $pref::Classic::playerHitWav, - $pref::Classic::vehicleHitSound, $pref::Classic::vehicleHitWav); - commandToServer('SetRepairKitWaste', $pref::Classic::wasteRepairKit); - } -} - -function clientCmdTeamDestroyMessage(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6) -{ - if($pref::Classic::ignoreTeamDestroyMessages) - %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); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Keybinds //////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function tossAmmo( %val ) { if ( %val ) throw( Ammo ); } -function tossRepairKit( %val ) { if ( %val ) throw( RepairKit ); } -function tossMine( %val ) { if ( %val ) throw( Mine ); } -function tossBeacon( %val ) { if ( %val ) throw( Beacon ); } -function tossGrenade( %val ) { if ( %val ) throw( Grenade ); } - -function toggleModHud(%val) -{ - if(%val && $ModHudCreated) - { - if($ModHudOpen) - HideModHud(); - else - ShowModHud(); - } -} - -function toggleAdminHud(%val) -{ - if(%val && $AdminHudCreated) - { - if($AdminHudOpen) - HideAdminHud(); - else - ShowAdminHud(); - } -} - -function togglePracticeHud(%val) -{ - if(%val && $PracticeHudCreated) - { - if($practiceHudOpen) - HidePracticeHud(); - else - ShowPracticeHud(); - } -} - -function throwGrenadeMax( %val ) -{ - if(($ServerMod !$= "Classic;base") && ($ServerMod !$= "classic;base")) - return; - - if ( !%val ) - { - commandToServer( 'throwMaxEnd' ); - } - $mvTriggerCount4 += $mvTriggerCount4 & 1 == %val ? 2 : 1; -} - -function throwMineMax( %val ) -{ - if(($ServerMod !$= "Classic;base") && ($ServerMod !$= "classic;base")) - return; - - if ( !%val ) - { - commandToServer( 'throwMaxEnd' ); - } - $mvTriggerCount5 += $mvTriggerCount5 & 1 == %val ? 2 : 1; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Grav Cycle Chaingun ///////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function clientCmdShowVehicleWeapons(%vehicleType) -{ - switch$ (%vehicleType) - { - case "Hoverbike": - // 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); - reticleHud.setBitmap("gui/hud_ret_tankchaingun"); - reticleFrameHud.setVisible(false); - - default: - return; - } -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Projectile Hit Sound defaults /////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function setupClassicClientDefaults() -{ - if($pref::Classic::wasteRepairKit $="") - { - $pref::Classic::wasteRepairKit = 0; - export( "$pref::*", "prefs/ClientPrefs.cs", False ); - } - if($pref::Classic::playerHitWav $="") - { - $pref::Classic::playerHitSound = 1; // turns player impact sounds on/off - $pref::Classic::playerHitWav = "~wfx/weapons/cg_hard4.wav"; // wav file to play when hitting enemy player. base dir is .../audio - $pref::Classic::vehicleHitSound = 1; // turns vehicle impact sounds on/off - $pref::Classic::vehicleHitWav = "~wfx/weapons/mine_switch.wav"; // wav file to play when hitting enemy vehicles. base dir is .../audio - export( "$pref::*", "prefs/ClientPrefs.cs", False ); - } - if($pref::Classic::ignoreTeamDestroyMessages $="") - { - $pref::Classic::ignoreTeamDestroyMessages = 0; - export( "$pref::*", "prefs/ClientPrefs.cs", False ); - } -} - -setupClassicClientDefaults(); - -//////////////////////////////////////////////////////////////////////////////////////// -// Bomber Pilot Hud //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -// Addition to give client bomber reticle when piloting. -package pilotBomberHud -{ - function ClientCmdSetHudMode(%mode, %type, %node) - { - parent::clientCmdSetHudMode(%mode, %type, %node); - - if ((%type $= "Bomber") && (%node == 0)) - { - clientCmdStartBomberSight(); - } - else if (($typeHolder $= "Bomber") && ($nodeHolder == 0)) - { - clientCmdEndBomberSight(); - } - $typeHolder = %type; - $nodeHolder = %node; - } -}; - -function activateBomberPilotHud(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) -{ - activatePackage(pilotBomberHud); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Private messaging /////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function PrivateMessage(%clientId) -{ - $PrivMsgTarget = %clientId; - %notice = "\c2Next message you send will be private to: " @ $PlayerList[%clientId].name; - addMessageHudLine(%notice); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Callbacks /////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -addMessageCallback('MsgClientReady', assignMissionType); -addMessageCallback('MsgStripAdminPlayer', handleStripAdminMsg); -addMessageCallback('MsgBomberPilotHud', activateBomberPilotHud); - -function serverCMDgetMod(%client) -{ - %paths = getModPaths(); - commandToClient(%client, 'serverMod', %paths); -} - -function clientCMDserverMod(%value) -{ - $ServerMod = %value; - if((%value $= "Classic;base") || (%value $= "classic;base")) - { - $Camera::movementSpeed = 50; - } -} \ No newline at end of file diff --git a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/modHud.cs b/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/modHud.cs deleted file mode 100644 index b5c88b9a..00000000 --- a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/modHud.cs +++ /dev/null @@ -1,551 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD - sal9000: MOD HUD /////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function CreateModHud() -{ - $ModHudId = new GuiControl(modHud) { - profile = "GuiDialogProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new ShellPaneCtrl(modHudGui) { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "170 90"; - extent = "320 295"; - minExtent = "48 92"; - visible = "1"; - helpTag = "0"; - text = "MOD HUD"; - - new GuiMLTextCtrl(modHudOpt) { - profile = "ShellMediumTextProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "29 38"; - extent = "260 18"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - lineSpacing = "2"; - }; - new ShellPopupMenu(modOptionMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 49"; - extent = "277 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "- OPTIONS -"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiMLTextCtrl(modHudSet) { - profile = "ShellMediumTextProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "29 90"; - extent = "267 18"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - lineSpacing = "2"; - }; - new ShellScrollCtrl(modA) { - profile = "NewScrollCtrlProfile"; - horizSizing = "right"; - vertSizing = "height"; - position = "26 103"; - extent = "267 70"; - 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(modB) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 7"; - extent = "182 239"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellTextList(modSetList) { - profile = "ShellTextArrayProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "182 8"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - enumerate = "0"; - resizeCell = "1"; - columns = "0"; - fitParentWidth = "1"; - clipColumnText = "0"; - }; - }; - }; - new ShellBitmapButton(modCloseBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "22 235"; - extent = "137 35"; - minExtent = "32 35"; - visible = "1"; - command = "HideModHud();"; - accelerator = "return"; - helpTag = "0"; - text = "CLOSE"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modSubmitBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "160 235"; - extent = "137 35"; - minExtent = "32 35"; - visible = "1"; - command = "modSubmit();"; - accelerator = "return"; - helpTag = "0"; - text = "SUBMIT"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn1) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "22 175"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(11);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn2) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "160 175"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(12);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn3) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "22 205"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(13);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn4) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "160 205"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(14);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - }; - }; -} - -function handleActivateModHud(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8) -{ - if(!$ModHudCreated) - { - CreateModHud(); - $ModHudCreated = 1; - } -} - -function handleInitModHud(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) -{ - if($ModHudCreated) - commandToServer('ModHudInitialize', true); -} - -addMessageCallback('MsgClientJoin', handleActivateModHud); -addMessageCallback('MsgClientReady', handleInitModHud); - -// Get the headings from the server -function clientCMDModHudHead(%head, %opt, %set) -{ - modHudGui.settitle(%head); - modHudOpt.setvalue(%opt); - modHudSet.setvalue(%set); -} - -function clientCMDModHudDone() -{ - $ModArray[curopt] = 1; - modOptionMenu.clear(); - for(%z = 1; %z <= $ModArray[index]; %z++) - { - %nam = $ModArray[%z, nam]; - modOptionMenu.add(%nam, %z); - } - modOptionMenu.setSelected($ModArray[curopt]); - modArrayCallOption($ModArray[curopt]); -} - -function modArrayCallOption(%opt) -{ - modSetList.clear(); - for(%x = 1; %x <= $ModArray[%opt, noa]; %x++) - { - %nam = $ModArray[%opt, %x]; - modSetList.addRow(%x, %nam); - } - %pal = $ModArray[%opt, pal]; - %cur = $ModArray[%opt, cur]; - if(%cur $= "") - modSetList.setSelectedByID(%pal); - else - modSetList.setSelectedByID(%cur); -} - -function clientCMDInitializeModHud(%mod) -{ - for(%i = 0; $ModArray[%i, nam] !$= ""; %i++) - { - $ModArray[%i, cur] = ""; - $ModArray[%i, pal] = ""; - $ModArray[%i, nam] = ""; - $ModArray[%i, noa] = ""; - $ModArray[%i, index] = ""; - for(%j = 0; %j < 10; %j++) - $ModArray[%i, %j] = ""; - } - $ModArray[curmode] = %mod; - $ModArray[index] = 0; -} - -function modHudExport() -{ - if($ModArray[curmode] $= "") - return; - - for(%z = 1; %z <= $ModArray[curopt]; %z++) - { - %pal = $ModArray[%z, pal]; - $ModExport[modStu($ModArray[curmode]), modStu($ModArray[%z, index])] = $ModArray[%z, %pal]; - } - export("$ModExport*", "scripts/autoexec/modExport.cs", false); -} - -function modStu(%str) -{ - return strreplace(%str, " ", "_"); -} - -function clientCMDModHudPopulate(%option, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) -{ - %s[1] = %a1; - %s[2] = %a2; - %s[3] = %a3; - %s[4] = %a4; - %s[5] = %a5; - %s[6] = %a6; - %s[7] = %a7; - %s[8] = %a8; - %s[9] = %a9; - %s[10] = %a10; - - $ModArray[index]++; - $ModArray[curopt] = $ModArray[index]; - %cur = $ModArray[curopt]; - $ModArray[%cur, pal] = ""; - $ModArray[%cur, cur] = ""; - $ModArray[%cur, nam] = %option; - - %z = 0; - while(%s[%z++] !$= "") { - $ModArray[%cur, %z] = %s[%z]; - %pal = $ModExport[modStu($ModArray[curmode]), modStu(%opt)]; - if(%s[%z] $= %pal) - %palm = %z; - } - if(%palm $= "") { - $ModArray[%cur, cur] = "1"; - $ModArray[%cur, pal] = "1"; - %id =1; - } - else { - $ModArray[%cur, cur] = %palm; - $ModArray[%cur, pal] = %palm; - %id = %palm; - } - commandToServer('ModUpdateSettings', %cur, %id); - $ModArray[%cur, noa] = %z-1; -} - -function modSetList::onSelect(%this, %id, %text) -{ - $ModArray[$ModArray[curopt], cur] = %id; - //commandToServer('ModUpdateSettings', $ModArray[curopt], %id); -} - -function modOptionMenu::onSelect(%this, %id, %text) -{ - $ModArray[curopt] = %id; - modArraycallOption(%id); -} - -function ShowModHud() -{ - canvas.pushdialog(modHud); - $ModHudOpen = 1; - //clientCmdTogglePlayHuds(false); -} - -function HideModHud() -{ - modHudExport(); - canvas.popdialog(modHud); - $ModHudOpen = 0; - //clientCmdTogglePlayHuds(true); -} - -function modHud::onWake( %this ) -{ - if ($HudHandle[modHud] !$= "") - alxStop($HudHandle[inventoryScreen]); - - alxPlay(HudInventoryActivateSound, 0, 0, 0); - $HudHandle[modHud] = alxPlay(HudInventoryHumSound, 0, 0, 0); - - if ( isObject( modHudMap ) ) - { - modHudMap.pop(); - modHudMap.delete(); - } - new ActionMap( modHudMap ); - modHudMap.blockBind( moveMap, togglePracticeHud ); - modHudMap.blockBind( moveMap, toggleAdminHud ); - modHudMap.blockBind( moveMap, toggleInventoryHud ); - modHudMap.blockBind( moveMap, toggleScoreScreen ); - modHudMap.blockBind( moveMap, toggleCommanderMap ); - modHudMap.bindCmd( keyboard, escape, "", "HideModHud();" ); - modHudMap.push(); -} - -function modHud::onSleep( %this ) -{ - %this.callback = ""; - modHudMap.pop(); - modHudMap.delete(); - alxStop($HudHandle[modHud]); - alxPlay(HudInventoryDeactivateSound, 0, 0, 0); - $HudHandle[modHud] = ""; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Button functions //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function modSubmit() -{ - // Send the currently selected option and setting to the server - commandToServer('ModUpdateSettings', $ModArray[curopt], $ModArray[$ModArray[curopt], cur]); - modHudExport(); -} - -function modBtnProg(%button) -{ - switch ( %button ) - { - case 11: - %value = modBtn1.getValue(); - case 12: - %value = modBtn2.getValue(); - case 13: - %value = modBtn3.getValue(); - case 14: - %value = modBtn4.getValue(); - default: - %value = ""; - } - commandToServer('ModButtonSet', %button, %value); - //HideModHud(); -} - -function clientCMDModHudBtn1(%text, %enabled, %visible) -{ - modBtn1.setActive(%enabled); - modBtn1.visible = %visible; - if(%text !$= "") - modBtn1.text = %text; -} - -function clientCMDModHudBtn2(%text, %enabled, %visible) -{ - modBtn2.setActive(%enabled); - modBtn2.visible = %visible; - if(%text !$= "") - modBtn2.text = %text; -} - -function clientCMDModHudBtn3(%text, %enabled, %visible) -{ - modBtn3.setActive(%enabled); - modBtn3.visible = %visible; - if(%text !$= "") - modBtn3.text = %text; -} - -function clientCMDModHudBtn4(%text, %enabled, %visible) -{ - modBtn4.setActive(%enabled); - modBtn4.visible = %visible; - if(%text !$= "") - modBtn4.text = %text; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Server functions //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function serverCMDModHudInitialize(%client, %value) -{ - Game.InitModHud(%client, %value); -} - -function serverCmdModUpdateSettings(%client, %option, %value) -{ - // %option is the index # of the hud list option - // %value is the index # of the hud list setting - - %option = deTag(%option); - %value = deTag(%value); - Game.UpdateModHudSet(%client, %option, %value); -} - -function serverCmdModButtonSet(%client, %button, %value) -{ - %button = deTag(%button); - %value = deTag(%value); - Game.ModButtonCmd(%client, %button, %value); -} - -function DefaultGame::InitModHud(%game, %client, %value) -{ - // Clear out any previous settings - //commandToClient(%client, 'InitializeModHud', "ModName"); - - // Send the hud labels | Hud Label | | Option label | | Setting label | - //commandToClient(%client, 'ModHudHead', "MOD NAME HUD", "Option:", "Setting:"); - - // Send the Option list and settings per option | Option | | Setting | - //commandToClient(%client, 'ModHudPopulate', "Example1", "Empty"); - //commandToClient(%client, 'ModHudPopulate', "Example2", "Setting1", "Setting2", "Setting3", "Setting4", "Setting5", "Setting6", "Setting7", "Setting8", "Setting9", "Setting10"); - - // Send the button labels and visual settings | Button | | Label | | Visible | | Active | - //commandToClient(%client, 'ModHudBtn1', "BUTTON1", 1, 1); - //commandToClient(%client, 'ModHudBtn2', "BUTTON2", 1, 1); - //commandToClient(%client, 'ModHudBtn3', "BUTTON3", 1, 1); - //commandToClient(%client, 'ModHudBtn4', "BUTTON4", 1, 1); - - // We're done! - //commandToClient(%client, 'ModHudDone'); -} - -function DefaultGame::UpdateModHudSet(%game, %client, %option, %value) -{ - // 1 = Example1 - // 2 = Example2 - - //switch$ ( %option ) - //{ - // case 1: - // %msg = '\c2Something set to: %2.'; - - // case 2: - // %msg = '\c2Something set to: %2.'; - - // default: - // %msg = '\c2Invalid setting.'; - //} - //messageClient( %client, 'MsgModHud', %msg, %option, %value ); -} - -function DefaultGame::ModButtonCmd(%game, %client, %button, %value) -{ - // 11 = Button 1 - // 12 = Button 2 - // 13 = Button 3 - // 14 = Button 4 - - //switch ( %button ) - //{ - // case 11: - // %msg = '\c2Something set to: %2.'; - - // case 12: - // %msg = '\c2Something set to: %2.'; - - // case 13: - // %msg = '\c2Something set to: %2.'; - - // case 14: - // %msg = '\c2Something set to: %2.'; - - // default: - // %msg = '\c2Invalid setting.'; - //} - //messageClient( %client, 'MsgModHud', %msg, %button, %value ); -} diff --git a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/practiceHud.cs b/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/practiceHud.cs deleted file mode 100644 index cd35e44b..00000000 --- a/docs/base/@vl2/zz_Classic_client_v1.vl2/scripts/autoexec/practiceHud.cs +++ /dev/null @@ -1,887 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: PRACTICE HUD //////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -// BUTTON MAP: -// =========== -// -// (00-09: GUI CONTROLS) -// -// (10-19: SERVER BUTTONS) -// 10 = 999 Ammo -// 11 = Auto Return Flags -// 12 = Spawn in Favorites -// 13 = Spawn Only -// 14 = No Score Limit -// 15 = Protect Assests -// 16 = Reset Map -// -// (20-29: TELEPORT OPTIONS) -// 20 = Beacon Mode -// 21 = Teleport Mode -// 22 = Select -// 23 = Destroy -// 24 = Teleport -// -// (30-39: SPAWN VEHICLE) -// 30 = Wildcat -// 31 = Beowulf -// 32 = Jericho -// 33 = Shrike -// 34 = Thundersword -// 35 = Havoc -// -// (40-49: PROJECTILE OBSERVATION) -// 40 = Disc -// 41 = Grenade L. -// 42 = Mortar -// 43 = Missile L. - -function CreatePracticeHud() -{ - $practiceHudId = new GuiControl(practiceHud) { - profile = "GuiDialogProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellPaneCtrl(practiceHudGui) { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "77 43"; - extent = "486 394"; - minExtent = "48 92"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "Practice Hud"; - longTextBuffer = "0"; - maxLength = "255"; - noTitleBar = "0"; - - new ShellFieldCtrl(adminLBorder) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "20 44"; - extent = "260 126"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellToggleButton(UnlimAmmoBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 8"; - extent = "128 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(10);"; - helpTag = "0"; - text = "999 AMMO"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(AutoReturnBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "127 8"; - extent = "128 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(11);"; - helpTag = "0"; - text = "AUTO-RETURN FLAGS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(spawnInFavsBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 37"; - extent = "128 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(12);"; - helpTag = "0"; - text = "SPAWN IN FAVORITE"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(SpawnOnlyBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "127 37"; - extent = "128 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(13);"; - helpTag = "0"; - text = "SPAWN ONLY"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(NoScoreLimitBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 66"; - extent = "128 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(14);"; - helpTag = "0"; - text = "NO SCORE LIMIT"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(ProtectAssestsBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "127 66"; - extent = "128 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(15);"; - helpTag = "0"; - text = "PROTECT ASSETS"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellBitmapButton(ResetMapBtn) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "73 90"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(16);"; - helpTag = "0"; - text = "RESET MAP"; - simpleStyle = "0"; - }; - }; - new ShellFieldCtrl(adminRBorder) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "284 44"; - extent = "184 126"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellPopupMenu(practiceOptionMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 -2"; - extent = "180 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "- OPTIONS -"; - longTextBuffer = "0"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellScrollCtrl(practiceA) { - profile = "NewScrollCtrlProfile"; - horizSizing = "right"; - vertSizing = "height"; - position = "2 25"; - extent = "181 70"; - 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(practiceB) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 7"; - extent = "157 56"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellTextList(practiceSetList) { - profile = "ShellTextArrayProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "157 234"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - enumerate = "0"; - resizeCell = "1"; - columns = "0"; - fitParentWidth = "1"; - clipColumnText = "0"; - }; - }; - }; - new ShellBitmapButton(practiceSubmitBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "42 91"; - extent = "105 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceSubmit();"; - accelerator = "return"; - helpTag = "0"; - text = "SUBMIT"; - simpleStyle = "0"; - }; - }; - new ShellFieldCtrl(projectileBorder) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "20 190"; - extent = "448 42"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiMLTextCtrl(projectileStr) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "173 1"; - extent = "113 14"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - new ShellToggleButton(observeDiscBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 12"; - extent = "108 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(40);"; - helpTag = "0"; - text = "DISC"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(observeGLBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "112 12"; - extent = "108 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(41);"; - helpTag = "0"; - text = "GRENADE L."; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(observeMortarBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "222 12"; - extent = "108 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(42);"; - helpTag = "0"; - text = "MORTAR"; - longTextBuffer = "0"; - maxLength = "255"; - }; - new ShellToggleButton(observeMissileBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "332 12"; - extent = "108 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(43);"; - helpTag = "0"; - text = "MISSILE L."; - longTextBuffer = "0"; - maxLength = "255"; - }; - }; - new ShellFieldCtrl(teleBorder) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "20 237"; - extent = "225 107"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiMLTextCtrl(teleStr) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "76 1"; - extent = "83 14"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - new ShellRadioButton(BeaconModeBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 12"; - extent = "108 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(20);"; - helpTag = "0"; - text = "BEACON MODE"; - longTextBuffer = "0"; - maxLength = "255"; - groupNum = "1"; - }; - new ShellRadioButton(TelepadModeBtn) { - profile = "ShellRadioProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "112 12"; - extent = "107 30"; - minExtent = "26 27"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(21);"; - helpTag = "0"; - text = "TELEPAD MODE"; - longTextBuffer = "0"; - maxLength = "255"; - groupNum = "1"; - }; - new ShellBitmapButton(SelectBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "60 37"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(22);"; - accelerator = "return"; - helpTag = "0"; - text = "SELECT"; - simpleStyle = "0"; - }; - new ShellBitmapButton(DestroyBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "5 67"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(23);"; - accelerator = "return"; - helpTag = "0"; - text = "DESTROY"; - simpleStyle = "0"; - }; - new ShellBitmapButton(TeleportBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "113 67"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(24);"; - accelerator = "return"; - helpTag = "0"; - text = "TELEPORT"; - simpleStyle = "0"; - }; - }; - new ShellFieldCtrl(SpawnVehBorder) { - profile = "ShellFieldProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "256 237"; - extent = "212 107"; - minExtent = "16 18"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new GuiMLTextCtrl(spawnVehStr) { - profile = "GuiDialogProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "58 2"; - extent = "115 14"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - new ShellBitmapButton(spawnVehBtn1) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 12"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(30);"; - helpTag = "0"; - text = "WILDCAT"; - simpleStyle = "0"; - }; - new ShellBitmapButton(spawnVehBtn2) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 42"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(31);"; - helpTag = "0"; - text = "BEOWULF"; - simpleStyle = "0"; - }; - new ShellBitmapButton(spawnVehBtn3) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "2 72"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(32);"; - helpTag = "0"; - text = "JERICHO"; - simpleStyle = "0"; - }; - new ShellBitmapButton(spawnVehBtn4) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "102 12"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(33);"; - helpTag = "0"; - text = "SHRIKE"; - simpleStyle = "0"; - }; - new ShellBitmapButton(spawnVehBtn5) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "102 42"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(34);"; - helpTag = "0"; - text = "THUNDERSWORD"; - simpleStyle = "0"; - }; - new ShellBitmapButton(spawnVehBtn6) { - profile = "ShellButtonProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "102 72"; - extent = "108 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "practiceServerBtns(35);"; - helpTag = "0"; - text = "HAVOC"; - simpleStyle = "0"; - }; - }; - new ShellBitmapButton(closeBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "190 343"; - extent = "120 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "HidePracticeHud();"; - accelerator = "return"; - helpTag = "0"; - text = "CLOSE"; - simpleStyle = "0"; - }; - new GuiMLTextCtrl(serverHudStr) { - profile = "ShellMediumTextProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "192 25"; - extent = "104 18"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - new GuiMLTextCtrl(playerHudStr) { - profile = "ShellMediumTextProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "192 171"; - extent = "104 18"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - lineSpacing = "2"; - allowColorChars = "0"; - maxChars = "-1"; - deniedSound = "InputDeniedSound"; - }; - }; - }; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Callbacks /////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function handleActivatePracticeHud() -{ - if(!$PracticeHudCreated) - { - CreatePracticeHud(); - $PracticeHudCreated = 1; - } -} - -function handleInitPracHud(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) -{ - if($practiceHudCreated) - commandToServer('practiceHudInitialize', true); -} - -function updatePracHud(%msgType, %msgString, %a1, %a2, %a3) -{ - // set hud sensitivity - if(%a3 $= "") - %val = 0; - else - %val = (%a3 > 0); - UnlimAmmoBtn.setactive(%val); - AutoReturnBtn.setactive(%val); - spawnInFavsBtn.setactive(%val); - SpawnOnlyBtn.setactive(%val); - NoScoreLimitBtn.setactive(%val); - ProtectAssestsBtn.setactive(%val); - ResetMapBtn.setactive(%val); - practiceOptionMenu.setActive(%val); - practiceSubmitBtn.setactive(%val); - - // set hud values - UnlimAmmoBtn.setvalue(%a1 & 1); - AutoReturnBtn.setvalue(%a1 & 2); - spawnInFavsBtn.setvalue(%a1 & 4); - SpawnOnlyBtn.setvalue(%a1 & 8); - NoScoreLimitBtn.setvalue(%a1 & 16); - ProtectAssestsBtn.setvalue(%a1 & 32); - observeDiscBtn.setvalue(%a2 & 1); - observeGLBtn.setvalue(%a2 & 2); - observeMortarBtn.setvalue(%a2 & 4); - observeMissileBtn.setvalue(%a2 & 8); - BeaconModeBtn.setvalue(%a2 & 16); - TelepadModeBtn.setvalue(%a2 & 32); -} - -addMessageCallback('MsgClientJoin', handleActivatePracticeHud); -addMessageCallback('MsgClientReady', handleInitPracHud); -addMessageCallback('MsgStripAdminPlayer', updatePracHud); -addMessageCallback('UpdatePracHud', updatePracHud); -addMessageCallback('MsgAdminPlayer', updatePracHud); -addMessageCallback('MsgAdminAdminPlayer', updatePracHud); -addMessageCallback('MsgSuperAdminPlayer', updatePracHud); -addMessageCallback('MsgAdminForce', updatePracHud); - -//////////////////////////////////////////////////////////////////////////////////////// - -// Get the headings from the server -function clientCMDpracticeHudHead(%head, %server, %player, %projectile, %tele, %vehicle) -{ - practiceHudGui.settitle(%head); - serverHudStr.setvalue(%server); - playerHudStr.setvalue(%player); - projectileStr.setvalue(%projectile); - teleStr.setvalue(%tele); - spawnVehStr.setvalue(%vehicle); -} - -function clientCMDpracticeHudDone() -{ - $practiceArray[curopt] = 1; - practiceOptionMenu.clear(); - for(%z = 1; %z <= $practiceArray[index]; %z++) - { - %nam = $practiceArray[%z, nam]; - practiceOptionMenu.add(%nam, %z); - } - practiceOptionMenu.setSelected($practiceArray[curopt]); - practiceArrayCallOption($practiceArray[curopt]); -} - -function practiceArrayCallOption(%opt) -{ - practiceSetList.clear(); - for(%x = 1; %x <= $practiceArray[%opt, noa]; %x++) - { - %nam = $practiceArray[%opt, %x]; - practiceSetList.addRow(%x, %nam); - } - %cur = $practiceArray[%opt, cur]; - practiceSetList.setSelectedByID(%cur); -} - -function clientCMDinitializePracHud(%mode) -{ - for(%i = 0; $ModArray[%i, nam] !$= ""; %i++) - { - $practiceArray[%i, cur] = ""; - $practiceArray[%i, nam] = ""; - $practiceArray[%i, noa] = ""; - for(%j = 0; %j < 10; %j++) - $practiceArray[%i, %j] = ""; - } - $practiceArray[index] = 0; - $practiceArray[curmode] = %mode; -} - -function clientCMDpracticeHudPopulate(%opt, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10, %a11, %a12, %a13, %a14, %a15) -{ - %s[1] = %a1; - %s[2] = %a2; - %s[3] = %a3; - %s[4] = %a4; - %s[5] = %a5; - %s[6] = %a6; - %s[7] = %a7; - %s[8] = %a8; - %s[9] = %a9; - %s[10] = %a10; - %s[11] = %a11; - %s[12] = %a12; - %s[13] = %a13; - %s[14] = %a14; - %s[15] = %a15; - $practiceArray[index]++; - $practiceArray[curopt] = $practiceArray[index]; - %cur = $practiceArray[curopt]; - $practiceArray[%cur, cur] = ""; - $practiceArray[%cur, nam] = %opt; - while(%s[%z++] !$= "") - { - $practiceArray[%cur, %z] = %s[%z]; - } - $practiceArray[%cur, cur] = "1"; - $practiceArray[%cur, noa] = %z-1; -} - -function practiceSetList::onSelect(%this, %id, %text) -{ - $practiceArray[$practiceArray[curopt], cur] = %id; -} - -function practiceOptionMenu::onSelect(%this, %id, %text) -{ - $practiceArray[curopt] = %id; - practiceArraycallOption(%id); -} - -function ShowPracticeHud() -{ - if($thisMissionType $= "PracticeCTFGame") - { - commandToServer('needPracHudUpdate', %opt); - canvas.pushdialog(practiceHud); - $practiceHudOpen = 1; - } -} - -function HidePracticeHud() -{ - canvas.popdialog(practiceHud); - $practiceHudOpen = 0; -} - -function practiceHud::onWake( %this ) -{ - if ( isObject( practiceHudMap ) ) - { - practiceHudMap.pop(); - practiceHudMap.delete(); - } - new ActionMap( practiceHudMap ); - practiceHudMap.blockBind( moveMap, toggleModHud ); - practiceHudMap.blockBind( moveMap, toggleAdminHud ); - practiceHudMap.blockBind( moveMap, toggleInventoryHud ); - practiceHudMap.blockBind( moveMap, toggleScoreScreen ); - practiceHudMap.blockBind( moveMap, toggleCommanderMap ); - practiceHudMap.bindCmd( keyboard, escape, "", "HidePracticeHud();" ); - practiceHudMap.push(); -} - -function practiceHud::onSleep( %this ) -{ - %this.callback = ""; - practiceHudMap.pop(); - practiceHudMap.delete(); -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Button functions //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function practiceServerBtns(%opt) -{ - switch(%opt) - { - case 40: - %val = observeDiscBtn.getValue(); - case 41: - %val = observeGLBtn.getValue(); - case 42: - %val = observeMortarBtn.getValue(); - case 43: - %val = observeMissileBtn.getValue(); - default: - %val = ""; - } - commandToServer('practiceBtnCall', %opt, %val); -} - -function practiceSubmit() -{ - // Send the currently selected option and setting to the server - commandToServer('practiceUpdateSettings', $practiceArray[curopt], $practiceArray[$practiceArray[curopt], cur]); -} diff --git a/docs/base/@vl2/zz_Classic_client_v1.vl2/zz_classic_client_v4.txt b/docs/base/@vl2/zz_Classic_client_v1.vl2/zz_classic_client_v4.txt deleted file mode 100644 index 4d092734..00000000 --- a/docs/base/@vl2/zz_Classic_client_v1.vl2/zz_classic_client_v4.txt +++ /dev/null @@ -1,10 +0,0 @@ -Tribes2 Classic client pack version 4 -7/29/03 - - -The "zz_classic_client_v1.vl2" file should be put into -your "...\Tribes2\GameData\base" directory, overwriting -any existing earlier version. - - -See the "classic_readme.txt" file for a list of changes. diff --git a/docs/base/scripts/autoexec/AllowBotSkin.cs b/docs/base/scripts/autoexec/AllowBotSkin.cs deleted file mode 100755 index 01071087..00000000 --- a/docs/base/scripts/autoexec/AllowBotSkin.cs +++ /dev/null @@ -1,60 +0,0 @@ -package AllowBotSkin -{ - - -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"; - } - - %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 ) - { - if ( %baseSkin ) - %this.realSkin[%count] = $Skin[%i, code]; - %this.add( %skin, %count ); - %count++; - } - //} - } - - %this.sort( true ); -} - -}; - -// Prevent package from being activated if it is already -if (!isActivePackage(AllowBotSkin)) - activatePackage(AllowBotSkin); diff --git a/docs/base/scripts/autoexec/UEfix1.cs b/docs/base/scripts/autoexec/UEfix1.cs deleted file mode 100755 index 4eef4ae1..00000000 --- a/docs/base/scripts/autoexec/UEfix1.cs +++ /dev/null @@ -1,19 +0,0 @@ -// #autoload -// #name = UEfix -// #version = 1.0 -// #date = December 27, 2003 -// #category = Fix -// #author = Lou Cypher -// #warrior = LouCypher -// #email = asta_llama_lincoln@hotmail.com -// #web = http://deadzone.cjb.net -// #description = Prevents clients from being vulnerable to crashing via NULL voice exploit - -package UEfix { - function alxGetWaveLen(%wavFile) { - if ( strstr( %wavFile , ".wav" ) == -1 ) return $MaxMessageWavLength + 1; - echo("Length check: " @ %wavFile); - parent::alxGetWaveLen(%wavFile); - } -}; -activatePackage(UEfix); diff --git a/docs/base/scripts/autoexec/adminHud.cs b/docs/base/scripts/autoexec/adminHud.cs deleted file mode 100755 index 29b04f53..00000000 --- a/docs/base/scripts/autoexec/adminHud.cs +++ /dev/null @@ -1,358 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD: ADMIN HUD /////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function CreateAdminHud() -{ - $AdminHudId = new GuiControl(AdminHudDlg) { - profile = "GuiDialogProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new ShellPaneCtrl() { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "170 137"; - extent = "320 260"; - minExtent = "48 92"; - visible = "1"; - helpTag = "0"; - text = "Admin Hud"; - noTitleBar = "0"; - - // -- Drop down menu text label - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 52"; - extent = "50 22"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - text = "Menu:"; - }; - // -- Drop down menu - new ShellPopupMenu(AdminHudMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 44"; - extent = "225 38"; - minExtent = "49 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "- OPTIONS -"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - // -- Input text field label - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 88"; - extent = "50 22"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - text = "Input:"; - }; - // -- Input text field - new ShellTextEditCtrl(AdminHudInput) { - profile = "NewTextEditProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 80"; - extent = "225 38"; - minExtent = "32 38"; - visible = "1"; - command = "AdminHudInput.setField();"; - altCommand = "AdminHudInput.processEnter();"; - helpTag = "0"; - historySize = "0"; - maxLength = "127"; - password = "0"; - glowOffset = "9 9"; - }; - // -- Cancel button - new ShellBitmapButton(AdminHudCancelBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "60 118"; - extent = "120 38"; - minExtent = "32 38"; - visible = "1"; - command = "HideAdminHud();"; - accelerator = "escape"; - helpTag = "0"; - text = "CANCEL"; - simpleStyle = "0"; - }; - // -- Send button - new ShellBitmapButton(AdminHudSendBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "165 118"; - extent = "120 38"; - minExtent = "32 38"; - visible = "1"; - command = "AdminHudSendBtn.adminCommand();"; - helpTag = "0"; - text = "SEND"; - simpleStyle = "0"; - }; - // -- Clan Tag drop down menu text label - new GuiTextCtrl() { - profile = "ShellTextRightProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "10 173"; - extent = "50 22"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - text = "Tags:"; - }; - // -- Clan Tag drop down menu - new ShellPopupMenu(ClanTagHudMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "60 165"; - extent = "225 38"; - minExtent = "49 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "- CLAN TAGS -"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new ShellBitmapButton(ClanTagSendBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "60 200"; - extent = "225 38"; - minExtent = "32 38"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - command = "ClanTagSendBtn.sendTagCommand();"; - helpTag = "0"; - text = "CHANGE CLAN TAG"; - simpleStyle = "0"; - }; - }; - }; - ClanTagSendBtn.setActive(1); -} - -function handleActivateAdminHud() -{ - if(!$AdminHudCreated) - { - CreateAdminHud(); // Create the gui - UpdateAdminHudMenu(); // Fill the drop down menu - $AdminHudCreated = 1; // Set the flag - } -} - -addMessageCallback('MsgClientJoin', handleActivateAdminHud); - -function ShowAdminHud() -{ - canvas.pushdialog(AdminHudDlg); - //clientCmdTogglePlayHuds(false); - $AdminHudOpen = 1; -} - -function HideAdminHud() -{ - // Empty out the text input field - AdminHudInput.setValue(%empty); - - canvas.popdialog(AdminHudDlg); - $AdminHudOpen = 0; - //clientCmdTogglePlayHuds(true); -} - -function AdminHudDlg::onWake( %this ) -{ - if ( isObject( AdminHudMap ) ) - { - AdminHudMap.pop(); - AdminHudMap.delete(); - } - new ActionMap( AdminHudMap ); - AdminHudMap.blockBind( moveMap, toggleModHud ); - AdminHudMap.blockBind( moveMap, togglePracticeHud ); - AdminHudMap.blockBind( moveMap, toggleInventoryHud ); - AdminHudMap.blockBind( moveMap, toggleScoreScreen ); - AdminHudMap.blockBind( moveMap, toggleCommanderMap ); - AdminHudMap.bindCmd( keyboard, escape, "", "HideAdminHud();" ); - AdminHudMap.push(); -} - -function AdminHudDlg::onSleep( %this ) -{ - %this.callback = ""; - AdminHudMap.pop(); - AdminHudMap.delete(); -} - -function UpdateAdminHudMenu() -{ - // Populate the drop down menu with options seperated by \t (tab deliniated list). - %line1 = "Choose Option\tEnter Admin Password\tEnter Super Admin Password\tSet Join Password\tSet Admin Password\tSet Super Admin Password"; - %line2 = "\tSet Random Teams\tSet Fair Teams\tSet Max Players\tSet Auto-PW\tSet Auto-PW Password\tSet Auto-PW Count\tSend Bottomprint Message"; - %line3 = "\tSend Centerprint Message\tRemove Map From Rotation\tRestore Map To Rotation\tRemove GameType\tRestore GameType\tRestart Server\tConsole Command"; - %opt = %line1 @ %line2 @ %line3; - AdminHudMenu.hudSetValue(%opt, ""); - // Update the Clan Tag drop down menu as well - commandToServer('canGetClanTags'); -} - -function AdminHudMenu::onSelect(%this, %id, %text) -{ - // Called when an option is selected in drop down menu - $AdminMenu = %this.getValue(); -} - -function AdminHudInput::setField( %this ) -{ - // called when you type in text input field - %value = %this.getValue(); - %this.setValue( %value ); - $AdminInput = %value; - //AdminHudSendBtn.setActive( strlen( stripTrailingSpaces( %value ) ) >= 1 ); -} - -function AdminHudInput::processEnter( %this ) -{ - // Called when you press enter in text input field -} - -function AdminHudSendBtn::adminCommand( %this ) -{ - // Called when you press the send button - - // Update the global from the text input field - AdminHudInput.setField(); - - // Send the current menu selection and text to the server - switch$ ( $AdminMenu ) - { - case "Enter Admin Password": - commandToServer('SAD', $AdminInput); - - case "Enter Super Admin Password": - commandToServer('SAD', $AdminInput); - - case "Set Join Password": - commandToServer('Set', "joinpw", $AdminInput); - - case "Set Admin Password": - commandToServer('Set', "adminpw", $AdminInput); - - case "Set Super Admin Password": - commandToServer('Set', "superpw", $AdminInput); - - case "Set Random Teams": - commandToServer('Set', "random", $AdminInput); - - case "Set Fair Teams": - commandToServer('Set', "fairteams", $AdminInput); - - case "Set Max Players": - commandToServer('Set', "maxplayers", $AdminInput); - - case "Set Auto-PW": - commandToServer('AutoPWSetup', "autopw", $AdminInput); - - case "Set Auto-PW Password": - commandToServer('AutoPWSetup', "autopwpass", $AdminInput); - - case "Set Auto-PW Count": - commandToServer('AutoPWSetup', "autopwcount", $AdminInput); - - case "Send Bottomprint Message": - commandToServer('aprint', $AdminInput, true); - - case "Send Centerprint Message": - commandToServer('aprint', $AdminInput, false); - - case "Remove Map From Rotation": - commandToServer('AddMap', $AdminInput); - - case "Restore Map To Rotation": - commandToServer('RemoveMap', $AdminInput); - - case "Remove GameType": - commandToServer('AddType', $AdminInput); - - case "Restore GameType": - commandToServer('RemoveType', $AdminInput); - - case "Restart Server": - commandToServer('Set', "restart", $AdminInput); - - case "Console Command": - commandToServer('Set', "consolecmd", $AdminInput); - - default: - error("Admin Hud selected option: " @ $AdminMenu @ " input: " @ $AdminInput @ " unknown values."); - } - - // Clear the text input field and disable send button - //AdminHudSendBtn.setActive(0); - AdminHudInput.setValue(%empty); - UpdateAdminHudMenu(); - $AdminInput = ""; - $AdminMenu = ""; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Canadian, 7/19/03. Clan Tag switiching ////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function ClanTagHudMenu::onSelect(%this, %id, %text) -{ - // Called when an option is selected in drop down menu - $CanSelected = %this.getValue(); - ClanTagSendBtn.setActive(1); -} - -function ClanTagSendBtn::sendTagCommand( %this ) -{ - // Called when you press the send button - // Send the current menu selection and text to the server - commandToServer('canUpdateClanTag', $CanSelected); - $CanSelected = ""; - HideAdminHud(); -} - -function clientCmdcanDisplayTags(%tags) -{ - ClanTagHudMenu.hudSetValue(%tags, ""); -} diff --git a/docs/base/scripts/autoexec/chatmenuHudClear.cs b/docs/base/scripts/autoexec/chatmenuHudClear.cs deleted file mode 100755 index cd20d55e..00000000 --- a/docs/base/scripts/autoexec/chatmenuHudClear.cs +++ /dev/null @@ -1,23 +0,0 @@ -//Clear VoiceBind Chatmenu at spawn - -package chatmenuHudClear -{ - -function ClientCmdDisplayHuds() -{ - parent::ClientCmdDisplayHuds(); - cancelChatMenu(); -} - -function clientCmdSetInventoryHudItem(%slot, %amount, %addItem) -{ - parent::clientCmdSetInventoryHudItem(%slot, %amount, %addItem); - cancelChatMenu(); -} - -}; - - -// Prevent package from being activated if it is already -if (!isActivePackage(chatmenuHudClear)) - activatePackage(chatmenuHudClear); \ No newline at end of file diff --git a/docs/base/scripts/autoexec/fov.cs b/docs/base/scripts/autoexec/fov.cs deleted file mode 100755 index 2fc7178d..00000000 --- a/docs/base/scripts/autoexec/fov.cs +++ /dev/null @@ -1,25 +0,0 @@ -// #autoload -// #name = Spawn Bug Fix -// #version = 1.0 -// #date = June 28, 2001 -// #status = final -// #author = Daniel Trevino -// #warrior = liq -// #email = liqy@swbell.net -// #web = http://www.toejamsplace.com/ -// #description = Fixes a bug in T2 where your FOV is set back to 90 on respawn. You can now use whatever FOV you want by editing your "$pref::Player::defaultFov" in ClientPrefs.cs - -package spawnFix { - function ClientCmdDisplayHuds() { - parent::ClientCmdDisplayHuds(); - schedule(150, 0, setFov, $pref::Player::defaultFov); - schedule(1000, 0, setFov, $pref::Player::defaultFov); - } - function clientCmdSetInventoryHudItem(%slot, %amount, %addItem) - { - parent::clientCmdSetInventoryHudItem(%slot, %amount, %addItem); - schedule(150, 0, use, disc); - schedule(1000, 0, use, disc); - } -}; -activatePackage(spawnFix); \ No newline at end of file diff --git a/docs/base/scripts/autoexec/ircTempFix.cs b/docs/base/scripts/autoexec/ircTempFix.cs deleted file mode 100755 index f479d924..00000000 --- a/docs/base/scripts/autoexec/ircTempFix.cs +++ /dev/null @@ -1,3 +0,0 @@ -$IRCTestServer = "irc.tribes2.net:6667"; -$IRCClient::state = IDIRC_CONNECTING_WAITING; -$pref::IRCClient::autoreconnect = false; \ No newline at end of file diff --git a/docs/base/scripts/autoexec/meltdownfix.cs b/docs/base/scripts/autoexec/meltdownfix.cs deleted file mode 100755 index 46724577..00000000 --- a/docs/base/scripts/autoexec/meltdownfix.cs +++ /dev/null @@ -1 +0,0 @@ -memPatch("5C88B5","90909090"); \ No newline at end of file diff --git a/docs/base/scripts/autoexec/modHud.cs b/docs/base/scripts/autoexec/modHud.cs deleted file mode 100755 index b5c88b9a..00000000 --- a/docs/base/scripts/autoexec/modHud.cs +++ /dev/null @@ -1,551 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////////////// -// z0dd - ZOD - sal9000: MOD HUD /////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function CreateModHud() -{ - $ModHudId = new GuiControl(modHud) { - profile = "GuiDialogProfile"; - horizSizing = "width"; - vertSizing = "height"; - position = "0 0"; - extent = "640 480"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - - new ShellPaneCtrl(modHudGui) { - profile = "ShellDlgPaneProfile"; - horizSizing = "center"; - vertSizing = "center"; - position = "170 90"; - extent = "320 295"; - minExtent = "48 92"; - visible = "1"; - helpTag = "0"; - text = "MOD HUD"; - - new GuiMLTextCtrl(modHudOpt) { - profile = "ShellMediumTextProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "29 38"; - extent = "260 18"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - lineSpacing = "2"; - }; - new ShellPopupMenu(modOptionMenu) { - profile = "ShellPopupProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 49"; - extent = "277 36"; - minExtent = "49 36"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - text = "- OPTIONS -"; - maxLength = "255"; - maxPopupHeight = "200"; - buttonBitmap = "gui/shll_pulldown"; - rolloverBarBitmap = "gui/shll_pulldownbar_rol"; - selectedBarBitmap = "gui/shll_pulldownbar_act"; - noButtonStyle = "0"; - }; - new GuiMLTextCtrl(modHudSet) { - profile = "ShellMediumTextProfile"; - horizSizing = "center"; - vertSizing = "bottom"; - position = "29 90"; - extent = "267 18"; - minExtent = "8 8"; - visible = "1"; - helpTag = "0"; - lineSpacing = "2"; - }; - new ShellScrollCtrl(modA) { - profile = "NewScrollCtrlProfile"; - horizSizing = "right"; - vertSizing = "height"; - position = "26 103"; - extent = "267 70"; - 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(modB) { - profile = "GuiDefaultProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 7"; - extent = "182 239"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - - new ShellTextList(modSetList) { - profile = "ShellTextArrayProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "0 0"; - extent = "182 8"; - minExtent = "8 8"; - visible = "1"; - hideCursor = "0"; - bypassHideCursor = "0"; - helpTag = "0"; - enumerate = "0"; - resizeCell = "1"; - columns = "0"; - fitParentWidth = "1"; - clipColumnText = "0"; - }; - }; - }; - new ShellBitmapButton(modCloseBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "22 235"; - extent = "137 35"; - minExtent = "32 35"; - visible = "1"; - command = "HideModHud();"; - accelerator = "return"; - helpTag = "0"; - text = "CLOSE"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modSubmitBtn) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "160 235"; - extent = "137 35"; - minExtent = "32 35"; - visible = "1"; - command = "modSubmit();"; - accelerator = "return"; - helpTag = "0"; - text = "SUBMIT"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn1) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "22 175"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(11);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn2) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "160 175"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(12);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn3) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "22 205"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(13);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - new ShellBitmapButton(modBtn4) { - profile = "ShellButtonProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = "160 205"; - extent = "137 35"; - minExtent = "32 35"; - visible = "0"; - command = "modBtnProg(14);"; - accelerator = "return"; - helpTag = "0"; - text = "-Empty-"; - simpleStyle = "0"; - }; - }; - }; -} - -function handleActivateModHud(%msgType, %msgString, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8) -{ - if(!$ModHudCreated) - { - CreateModHud(); - $ModHudCreated = 1; - } -} - -function handleInitModHud(%msgType, %msgString, %gameType, %a2, %a3, %a4, %a5, %a6) -{ - if($ModHudCreated) - commandToServer('ModHudInitialize', true); -} - -addMessageCallback('MsgClientJoin', handleActivateModHud); -addMessageCallback('MsgClientReady', handleInitModHud); - -// Get the headings from the server -function clientCMDModHudHead(%head, %opt, %set) -{ - modHudGui.settitle(%head); - modHudOpt.setvalue(%opt); - modHudSet.setvalue(%set); -} - -function clientCMDModHudDone() -{ - $ModArray[curopt] = 1; - modOptionMenu.clear(); - for(%z = 1; %z <= $ModArray[index]; %z++) - { - %nam = $ModArray[%z, nam]; - modOptionMenu.add(%nam, %z); - } - modOptionMenu.setSelected($ModArray[curopt]); - modArrayCallOption($ModArray[curopt]); -} - -function modArrayCallOption(%opt) -{ - modSetList.clear(); - for(%x = 1; %x <= $ModArray[%opt, noa]; %x++) - { - %nam = $ModArray[%opt, %x]; - modSetList.addRow(%x, %nam); - } - %pal = $ModArray[%opt, pal]; - %cur = $ModArray[%opt, cur]; - if(%cur $= "") - modSetList.setSelectedByID(%pal); - else - modSetList.setSelectedByID(%cur); -} - -function clientCMDInitializeModHud(%mod) -{ - for(%i = 0; $ModArray[%i, nam] !$= ""; %i++) - { - $ModArray[%i, cur] = ""; - $ModArray[%i, pal] = ""; - $ModArray[%i, nam] = ""; - $ModArray[%i, noa] = ""; - $ModArray[%i, index] = ""; - for(%j = 0; %j < 10; %j++) - $ModArray[%i, %j] = ""; - } - $ModArray[curmode] = %mod; - $ModArray[index] = 0; -} - -function modHudExport() -{ - if($ModArray[curmode] $= "") - return; - - for(%z = 1; %z <= $ModArray[curopt]; %z++) - { - %pal = $ModArray[%z, pal]; - $ModExport[modStu($ModArray[curmode]), modStu($ModArray[%z, index])] = $ModArray[%z, %pal]; - } - export("$ModExport*", "scripts/autoexec/modExport.cs", false); -} - -function modStu(%str) -{ - return strreplace(%str, " ", "_"); -} - -function clientCMDModHudPopulate(%option, %a1, %a2, %a3, %a4, %a5, %a6, %a7, %a8, %a9, %a10) -{ - %s[1] = %a1; - %s[2] = %a2; - %s[3] = %a3; - %s[4] = %a4; - %s[5] = %a5; - %s[6] = %a6; - %s[7] = %a7; - %s[8] = %a8; - %s[9] = %a9; - %s[10] = %a10; - - $ModArray[index]++; - $ModArray[curopt] = $ModArray[index]; - %cur = $ModArray[curopt]; - $ModArray[%cur, pal] = ""; - $ModArray[%cur, cur] = ""; - $ModArray[%cur, nam] = %option; - - %z = 0; - while(%s[%z++] !$= "") { - $ModArray[%cur, %z] = %s[%z]; - %pal = $ModExport[modStu($ModArray[curmode]), modStu(%opt)]; - if(%s[%z] $= %pal) - %palm = %z; - } - if(%palm $= "") { - $ModArray[%cur, cur] = "1"; - $ModArray[%cur, pal] = "1"; - %id =1; - } - else { - $ModArray[%cur, cur] = %palm; - $ModArray[%cur, pal] = %palm; - %id = %palm; - } - commandToServer('ModUpdateSettings', %cur, %id); - $ModArray[%cur, noa] = %z-1; -} - -function modSetList::onSelect(%this, %id, %text) -{ - $ModArray[$ModArray[curopt], cur] = %id; - //commandToServer('ModUpdateSettings', $ModArray[curopt], %id); -} - -function modOptionMenu::onSelect(%this, %id, %text) -{ - $ModArray[curopt] = %id; - modArraycallOption(%id); -} - -function ShowModHud() -{ - canvas.pushdialog(modHud); - $ModHudOpen = 1; - //clientCmdTogglePlayHuds(false); -} - -function HideModHud() -{ - modHudExport(); - canvas.popdialog(modHud); - $ModHudOpen = 0; - //clientCmdTogglePlayHuds(true); -} - -function modHud::onWake( %this ) -{ - if ($HudHandle[modHud] !$= "") - alxStop($HudHandle[inventoryScreen]); - - alxPlay(HudInventoryActivateSound, 0, 0, 0); - $HudHandle[modHud] = alxPlay(HudInventoryHumSound, 0, 0, 0); - - if ( isObject( modHudMap ) ) - { - modHudMap.pop(); - modHudMap.delete(); - } - new ActionMap( modHudMap ); - modHudMap.blockBind( moveMap, togglePracticeHud ); - modHudMap.blockBind( moveMap, toggleAdminHud ); - modHudMap.blockBind( moveMap, toggleInventoryHud ); - modHudMap.blockBind( moveMap, toggleScoreScreen ); - modHudMap.blockBind( moveMap, toggleCommanderMap ); - modHudMap.bindCmd( keyboard, escape, "", "HideModHud();" ); - modHudMap.push(); -} - -function modHud::onSleep( %this ) -{ - %this.callback = ""; - modHudMap.pop(); - modHudMap.delete(); - alxStop($HudHandle[modHud]); - alxPlay(HudInventoryDeactivateSound, 0, 0, 0); - $HudHandle[modHud] = ""; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Button functions //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function modSubmit() -{ - // Send the currently selected option and setting to the server - commandToServer('ModUpdateSettings', $ModArray[curopt], $ModArray[$ModArray[curopt], cur]); - modHudExport(); -} - -function modBtnProg(%button) -{ - switch ( %button ) - { - case 11: - %value = modBtn1.getValue(); - case 12: - %value = modBtn2.getValue(); - case 13: - %value = modBtn3.getValue(); - case 14: - %value = modBtn4.getValue(); - default: - %value = ""; - } - commandToServer('ModButtonSet', %button, %value); - //HideModHud(); -} - -function clientCMDModHudBtn1(%text, %enabled, %visible) -{ - modBtn1.setActive(%enabled); - modBtn1.visible = %visible; - if(%text !$= "") - modBtn1.text = %text; -} - -function clientCMDModHudBtn2(%text, %enabled, %visible) -{ - modBtn2.setActive(%enabled); - modBtn2.visible = %visible; - if(%text !$= "") - modBtn2.text = %text; -} - -function clientCMDModHudBtn3(%text, %enabled, %visible) -{ - modBtn3.setActive(%enabled); - modBtn3.visible = %visible; - if(%text !$= "") - modBtn3.text = %text; -} - -function clientCMDModHudBtn4(%text, %enabled, %visible) -{ - modBtn4.setActive(%enabled); - modBtn4.visible = %visible; - if(%text !$= "") - modBtn4.text = %text; -} - -//////////////////////////////////////////////////////////////////////////////////////// -// Server functions //////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////// - -function serverCMDModHudInitialize(%client, %value) -{ - Game.InitModHud(%client, %value); -} - -function serverCmdModUpdateSettings(%client, %option, %value) -{ - // %option is the index # of the hud list option - // %value is the index # of the hud list setting - - %option = deTag(%option); - %value = deTag(%value); - Game.UpdateModHudSet(%client, %option, %value); -} - -function serverCmdModButtonSet(%client, %button, %value) -{ - %button = deTag(%button); - %value = deTag(%value); - Game.ModButtonCmd(%client, %button, %value); -} - -function DefaultGame::InitModHud(%game, %client, %value) -{ - // Clear out any previous settings - //commandToClient(%client, 'InitializeModHud', "ModName"); - - // Send the hud labels | Hud Label | | Option label | | Setting label | - //commandToClient(%client, 'ModHudHead', "MOD NAME HUD", "Option:", "Setting:"); - - // Send the Option list and settings per option | Option | | Setting | - //commandToClient(%client, 'ModHudPopulate', "Example1", "Empty"); - //commandToClient(%client, 'ModHudPopulate', "Example2", "Setting1", "Setting2", "Setting3", "Setting4", "Setting5", "Setting6", "Setting7", "Setting8", "Setting9", "Setting10"); - - // Send the button labels and visual settings | Button | | Label | | Visible | | Active | - //commandToClient(%client, 'ModHudBtn1', "BUTTON1", 1, 1); - //commandToClient(%client, 'ModHudBtn2', "BUTTON2", 1, 1); - //commandToClient(%client, 'ModHudBtn3', "BUTTON3", 1, 1); - //commandToClient(%client, 'ModHudBtn4', "BUTTON4", 1, 1); - - // We're done! - //commandToClient(%client, 'ModHudDone'); -} - -function DefaultGame::UpdateModHudSet(%game, %client, %option, %value) -{ - // 1 = Example1 - // 2 = Example2 - - //switch$ ( %option ) - //{ - // case 1: - // %msg = '\c2Something set to: %2.'; - - // case 2: - // %msg = '\c2Something set to: %2.'; - - // default: - // %msg = '\c2Invalid setting.'; - //} - //messageClient( %client, 'MsgModHud', %msg, %option, %value ); -} - -function DefaultGame::ModButtonCmd(%game, %client, %button, %value) -{ - // 11 = Button 1 - // 12 = Button 2 - // 13 = Button 3 - // 14 = Button 4 - - //switch ( %button ) - //{ - // case 11: - // %msg = '\c2Something set to: %2.'; - - // case 12: - // %msg = '\c2Something set to: %2.'; - - // case 13: - // %msg = '\c2Something set to: %2.'; - - // case 14: - // %msg = '\c2Something set to: %2.'; - - // default: - // %msg = '\c2Invalid setting.'; - //} - //messageClient( %client, 'MsgModHud', %msg, %button, %value ); -} diff --git a/docs/base/scripts/autoexec/perfCounter.cs b/docs/base/scripts/autoexec/perfCounter.cs deleted file mode 100755 index 827b2f47..00000000 --- a/docs/base/scripts/autoexec/perfCounter.cs +++ /dev/null @@ -1 +0,0 @@ -setPerfCounterEnable(1); diff --git a/docs/base/scripts/autoexec/statushud.cs b/docs/base/scripts/autoexec/statushud.cs deleted file mode 100755 index d230f898..00000000 --- a/docs/base/scripts/autoexec/statushud.cs +++ /dev/null @@ -1,560 +0,0 @@ -// #author = |C|-DEbig3 -// #warrior = DEbig3 -// #Rewritten By = DarkTiger -// version 1.0 -$statusHudStats::maxPing = -10000; -$statusHudStats::minPing = 10000; -package statusHudPackage { - function toggleNetDisplayHud(%val) - { - if(%val) - { - $statusHudStatsCounter++; - if($statusHudStatsCounter == 1) - { - NetGraphHudFrame.setVisible(false); - NetBarHudFrame.setVisible(true); - statusHudHud.setVisible(false); - statusHudHud.setPosition(getWord(netGraphHudFrame.getPosition(),0),getWord(netGraphHudFrame.getPosition(),1)); - } - else if($statusHudStatsCounter == 2) - { - netGraphHudFrame.setVisible(true); - netBarHudFrame.setVisible(false); - statusHudHud.setVisible(false); - statusHudHud.setPosition(getWord(netGraphHudFrame.getPosition(),0),getWord(netGraphHudFrame.getPosition(),1)); - } - else if($statusHudStatsCounter == 3){ - NetGraphHudFrame.setVisible(false); - NetBarHudFrame.setVisible(false); - if(!isObject(statusHudHud)) - statusHudBuild(); - statusHudHud.setVisible(true); - statusHudHud.setPosition(getWord(netGraphHudFrame.getPosition(),0),getWord(netGraphHudFrame.getPosition(),1)); - } - else if($statusHudStatsCounter == 4){ - NetGraphHudFrame.setVisible(true); - NetBarHudFrame.setVisible(false); - statusHudHud.setVisible(true); - statusHudHud.setPosition(getWords(NetGraphHudFrame.getPosition(),0) - getWord(NetGraphHudFrame.getExtent(),0),getWords(NetGraphHudFrame.getPosition(),1)); - } - else{ - $statusHudStatsCounter = 0; - NetGraphHudFrame.setVisible(false); - NetBarHudFrame.setVisible(false); - statusHudHud.setVisible(false); - statusHudHud.setPosition(getWord(netGraphHudFrame.getPosition(),0),getWord(netGraphHudFrame.getPosition(),1)); - } - } - } -function NetBarHud::infoUpdate(%this, %ping, %packetLoss, %sendPackets, %sendBytes, %receivePackets, %receiveBytes) { - parent::infoUpdate(%this, %ping, %packetLoss, %sendPackets, %sendBytes, %receivePackets, %receiveBytes); - %dtms = getSimTime() - $statusHudStats::pingSpikeTime; - $statusHudStats::pingSpikeTime = getSimTime(); - if(isObject(statusHudHud) && $statusHudStatsCounter > 2){ - statusHudHud.ppSCurrent.setText("" @ mFormatFloat(%sendPackets, "%4.0f")); - statusHudHud.ppRCurrent.setText("" @ mFormatFloat(%receivePackets, "%4.0f")); - statusHudHud.txCurrent.setText("" @ mFormatFloat(%sendBytes, "%4.0f")); - statusHudHud.rxCurrent.setText("" @ mFormatFloat(%receiveBytes, "%4.0f")); - $statusHudStats::totalPing += %ping; - $statusHudStats::pingcount++; - if(%ping > 500){ - $statusHudStats::lagSec += %dtms; - statusHudHud.lagMSCurrent.setText("" @ mFormatFloat($statusHudStats::lagSec/1000, "%4.1f")); - $statusHudStats::lastlag = getSimTime(); - } - else if(getSimTime() - $statusHudStats::lastlag > 60000){ - statusHudHud.lagMSCurrent.setText("" @ mFormatFloat($statusHudStats::lagSec/1000, "%4.1f")); - if(getSimTime() - $statusHudStats::lastlag > (60000 * 5)){ - $statusHudStats::lagSec = 0; - statusHudHud.lagMSCurrent.setText(mFormatFloat($statusHudStats::lagSec/1000, "%4.1f")); - } - } - %pingAvgReset = 0; - if($statusHudStats::totalPing > 60000){ - $statusHudStats::totalPing = $statusHudStats::totalPing * 0.5; - $statusHudStats::pingcount = $statusHudStats::pingcount * 0.5; - $statusHudStats::maxPing = -10000; - $statusHudStats::minPing = 10000; - %pingAvgReset = 1; - } - if($statusHudStats::flCount++ > 12){ - $statusHudStats::fl = $statusHudStats::flMax - $statusHudStats::flMin; - $statusHudStats::flMax = -10000; - $statusHudStats::flMin = 10000; - $statusHudStats::flCount = 0; - } - else{ - $statusHudStats::flMax = (%ping > $statusHudStats::flMax) ? %ping : $statusHudStats::flMax; - $statusHudStats::flMin = (%ping < $statusHudStats::flMin) ? %ping : $statusHudStats::flMin; - } - - $statusHudStats::avgping= $statusHudStats::totalPing / $statusHudStats::pingcount; - if(%pingAvgReset) - statusHudHud.pingAvgCurrent.setText("" @ mFormatFloat($statusHudStats::avgping, "%4.0f")); - else - statusHudHud.pingAvgCurrent.setText(mFormatFloat($statusHudStats::avgping, "%4.0f")); - - $statusHudStats::maxPing = (%ping > $statusHudStats::maxPing) ? %ping : $statusHudStats::maxPing; - $statusHudStats::minPing = (%ping < $statusHudStats::minPing) ? %ping : $statusHudStats::minPing; - - %speed = mFloor(getControlObjectSpeed()); - %alt = getControlObjectAltitude(); - %fps = $fps::real; - if (%fps > $statusHudStats::maxfps) - $statusHudStats::maxfps = %fps; - %x = strstr($statusHudStats::avgfps, "."); - %avgfps = getSubStr($statusHudStats::avgfps, 0, %x + 2); - $statusHudStats::fpscount++; - $statusHudStats::totalfps += %fps; - %fpsReset = 0; - if($statusHudStats::totalfps > 50000){ - $statusHudStats::totalfps *= 0.5; - $statusHudStats::fpscount *= 0.5; - $statusHudStats::maxfps = 0; - %fpsReset = 1; - } - $statusHudStats::avgfps = $statusHudStats::totalfps / $statusHudStats::fpscount; - if(%fpsReset){ - statusHudHud.fpscurrent.setText("" @ %fps); - statusHudHud.fpsaverage.setText("" @ %avgfps); - statusHudHud.fpsmax.setText("" @ $statusHudStats::maxfps); - } - else{ - statusHudHud.fpscurrent.setText(%fps); - statusHudHud.fpsaverage.setText(%avgfps); - statusHudHud.fpsmax.setText($statusHudStats::maxfps); - } - statusHudHud.ping.setText("" @ mFormatFloat(%ping, "%4.0f")); - if(!isObject($statusHudStats::plObj)){ - $statusHudStats::plObj = getPLID();// to handel packet loss as the client side value is not correct - } - if(isObject($statusHudStats::plObj)){ - $statusHudStats::plupdate += %dtms; - if($statusHudStats::plupdate > 4000){ - commandToServer( 'getScores' ); - $statusHudStats::plupdate = 0; - } - statusHudHud.pl.setText("" @ mFormatFloat($statusHudStats::plObj.packetLoss, "%3.0f")); - } - else{ - statusHudHud.pl.setText("" @ mFormatFloat(%packetLoss, "%3.0f")); - } - statusHudHud.speed.setText(%speed); - statusHudHud.altitude.setText(%alt); - - if(%pingAvgReset){ - statusHudHud.pingMinCurrent.setText("" @ mFloor($statusHudStats::minPing)); - statusHudHud.pingMaxCurrent.setText("" @ mFloor($statusHudStats::maxPing)); - statusHudHud.pingFluxCurrent.setText("" @ mFloor($statusHudStats::fl)); - } - else{ - statusHudHud.pingMinCurrent.setText(mFloor($statusHudStats::minPing)); - statusHudHud.pingMaxCurrent.setText(mFloor($statusHudStats::maxPing)); - statusHudHud.pingFluxCurrent.setText(mFloor($statusHudStats::fl)); - } - } -} -function getPLID(){ - %name = stripTrailingSpaces( strToPlayerName( getField( $pref::Player[$pref::Player::Current], 0 ) ) ); - for (%i = 0; %i < PlayerListGroup.getCount(); %i++) { // the client list - %id = PlayerListGroup.getObject(%i); - %fullName = stripChars(%id.name,"\cp\co\c6\c7\c8\c9\x10\x11"); - if(strlwr(%fullName) $= strlwr(%name)){ - return %id; - } - } -} -function statusHudBuild() { - if (isObject(statusHudHud)) { - statusHudHud.delete(); - } - $statusHud = new ShellFieldCtrl(statusHudHud) { - profile = "GuiChatBackProfile"; - horizSizing = "left"; - vertSizing = "bottom"; - position = netGraphHudFrame.getPosition(); - extent = "170 80"; - minExtent = "2 2"; - visible = "1"; - }; - playgui.add($statusHud); - new GuiControlProfile ("statusHudTagProfile") - { - fontType = "Univers Condensed"; - fontSize = 14; - fontColor = "200 200 200"; - justify = "center"; - }; - new GuiControlProfile ("statusHudTextProfile") - { - fontType = "Univers Condensed"; - fontSize = 14; - justify = "center"; - }; - statusHudHud.fpscurrenttext = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 0"; - extent = "20 16"; - visible = "1"; - text = "fps:"; - }; - statusHudHud.fpscurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 0"; - extent = "25 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.fpsaveragetext = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "53 0"; - extent = "20 16"; - visible = "1"; - text = "avg:"; - }; - statusHudHud.fpsaverage = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "73 0"; - extent = "25 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.fpsmaxtext = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "104 0"; - extent = "20 16"; - visible = "1"; - text = "max:"; - }; - statusHudHud.fpsmax = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "125 0"; - extent = "25 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.pingtext = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 16"; - extent = "20 16"; - visible = "1"; - text = "ping:"; - }; - statusHudHud.ping = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 16"; - extent = "20 16"; - visible = "1"; - text = $statusHudPing; - }; - statusHudHud.pltext = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "141 16"; - extent = "15 16"; - visible = "1"; - text = "pl:"; - }; - statusHudHud.pl = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "148 16"; - extent = "20 16"; - visible = "1"; - text = $statusHudPL; - }; - statusHudHud.speedtext = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "53 16"; - extent = "28 16"; - visible = "1"; - text = "speed:"; - }; - statusHudHud.speed = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "82 16"; - extent = "24 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.altitudetext = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "105 16"; - extent = "15 16"; - visible = "1"; - text = "alt:"; - }; - statusHudHud.altitude = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "119 16"; - extent = "20 16"; - visible = "1"; - text = "0"; - }; - //////////////////////////////////////////////// - statusHudHud.ppSText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 32"; - extent = "20 16"; - visible = "1"; - text = "ppS:"; - }; - statusHudHud.ppSCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 32"; - extent = "25 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.txText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "53 32"; - extent = "20 16"; - visible = "1"; - text = "Tx:"; - }; - statusHudHud.txCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "66 32"; - extent = "25 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.rxText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "105 32"; - extent = "20 16"; - visible = "1"; - text = "Rx:"; - }; - statusHudHud.rxCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "118 32"; - extent = "25 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.ppRText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 48"; - extent = "20 16"; - visible = "1"; - text = "ppR:"; - }; - statusHudHud.ppRCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "22 48"; - extent = "20 16"; - visible = "1"; - text = "0"; - }; - - statusHudHud.lagMSText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "53 48"; - extent = "34 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.lagMSCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "73 48"; - extent = "24 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.pingAvgText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "105 48"; - extent = "36 16"; - visible = "1"; - text = "pingAvg:"; - }; - statusHudHud.pingAvgCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "137 48"; - extent = "20 16"; - visible = "1"; - text = "0"; - }; - - - statusHudHud.pingMinText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "4 64"; - extent = "34 16"; - visible = "1"; - text = "PingMin"; - }; - statusHudHud.pingMinCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "28 64"; - extent = "20 16"; - visible = "1"; - text = "0"; - }; - - statusHudHud.pingMaxText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "53 64"; - extent = "34 16"; - visible = "1"; - text = "PingMax"; - }; - statusHudHud.pingMaxCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "80 64"; - extent = "24 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.pingFluxText = new GuiMLTextCtrl() { - profile = "statusHudTagProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "105 64"; - extent = "36 16"; - visible = "1"; - text = "Flux"; - }; - statusHudHud.pingFluxCurrent = new GuiMLTextCtrl() { - profile = "statusHudTextProfile"; - horizSizing = "right"; - vertSizing = "bottom"; - position = "124 64"; - extent = "20 16"; - visible = "1"; - text = "0"; - }; - statusHudHud.add(statusHudHud.fpscurrenttext); - statusHudHud.add(statusHudHud.fpscurrent); - statusHudHud.fpscurrenttext.setText("fps:"); - - statusHudHud.add(statusHudHud.fpsaveragetext); - statusHudHud.add(statusHudHud.fpsaverage); - statusHudHud.fpsaveragetext.setText("avg:"); - - statusHudHud.add(statusHudHud.fpsmaxtext); - statusHudHud.add(statusHudHud.fpsmax); - statusHudHud.fpsmaxtext.setText("max:"); - - statusHudHud.add(statusHudHud.pingtext); - statusHudHud.add(statusHudHud.ping); - statusHudHud.pingtext.setText("ping:"); - - statusHudHud.add(statusHudHud.pltext); - statusHudHud.add(statusHudHud.pl); - statusHudHud.pltext.setText("pl:"); - - statusHudHud.add(statusHudHud.speedtext); - statusHudHud.add(statusHudHud.speed); - statusHudHud.speedtext.setText("speed:"); - - statusHudHud.add(statusHudHud.altitudetext); - statusHudHud.add(statusHudHud.altitude); - statusHudHud.altitudetext.setText("alt:"); - - ////////////////////////////////////////////// - statusHudHud.add(statusHudHud.ppSText); - statusHudHud.add(statusHudHud.ppSCurrent); - statusHudHud.ppSText.setText("ppS:"); //dcdcdc - - statusHudHud.add(statusHudHud.ppRText); - statusHudHud.add(statusHudHud.ppRCurrent); - statusHudHud.ppRText.setText("ppR:"); //00bef0 - - statusHudHud.add(statusHudHud.rxText); - statusHudHud.rxText.setText("Rx:");//787878 - statusHudHud.add(statusHudHud.rxCurrent); - - statusHudHud.add(statusHudHud.txText); - statusHudHud.add(statusHudHud.txCurrent); - statusHudHud.txText.setText("Tx:");// 0078aa - - statusHudHud.add(statusHudHud.lagMSText); - statusHudHud.add(statusHudHud.lagMSCurrent); - statusHudHud.lagMSText.setText("Lag:"); - - statusHudHud.add(statusHudHud.pingAvgText); - statusHudHud.add(statusHudHud.pingAvgCurrent); - statusHudHud.pingAvgText.setText("PingAvg:"); - - statusHudHud.add(statusHudHud.pingMinText); - statusHudHud.add(statusHudHud.pingMinCurrent); - statusHudHud.pingMinText.setText("PMin:"); - - statusHudHud.add(statusHudHud.pingMaxText); - statusHudHud.add(statusHudHud.pingMaxCurrent); - statusHudHud.pingMaxText.setText("PMax:"); - - statusHudHud.add(statusHudHud.pingFluxText); - statusHudHud.add(statusHudHud.pingFluxCurrent); - statusHudHud.pingFluxText.setText("PDif:"); - statusHudHud.lagMSCurrent.setText(0); - if(isObject(HM) && isObject(HudMover)) { - hudmover::addhud(statusHudHud, "statusHud"); - } -} -}; -activatePackage(statusHudPackage); - - diff --git a/package-lock.json b/package-lock.json index 9804fbb3..03a2a729 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,16 +9,20 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@react-three/drei": "^10.7.6", "@react-three/fiber": "^9.3.0", + "@react-three/postprocessing": "^3.0.4", + "@tanstack/react-query": "^5.90.8", "next": "^15.5.2", "react": "^19.1.1", "react-dom": "^19.1.1", + "react-error-boundary": "^6.0.0", "three": "^0.180.0", "unzipper": "^0.12.3" }, "devDependencies": { "@types/node": "24.3.1", - "@types/react": "19.1.12", + "@types/react": "^19.2.4", "@types/three": "^0.180.0", "@types/unzipper": "^0.10.11", "peggy": "^5.0.6", @@ -40,7 +44,6 @@ "version": "0.12.0", "resolved": "https://registry.npmjs.org/@dimforge/rapier3d-compat/-/rapier3d-compat-0.12.0.tgz", "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", - "dev": true, "license": "Apache-2.0" }, "node_modules/@emnapi/runtime": { @@ -954,6 +957,24 @@ "node": ">=12" } }, + "node_modules/@mediapipe/tasks-vision": { + "version": "0.10.17", + "resolved": "https://registry.npmjs.org/@mediapipe/tasks-vision/-/tasks-vision-0.10.17.tgz", + "integrity": "sha512-CZWV/q6TTe8ta61cZXjfnnHsfWIdFhms03M9T7Cnd5y2mdpylJM0rF1qRq+wsQVRMLz1OYPVEBU9ph2Bx8cxrg==", + "license": "Apache-2.0" + }, + "node_modules/@monogrid/gainmap-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@monogrid/gainmap-js/-/gainmap-js-3.1.0.tgz", + "integrity": "sha512-Obb0/gEd/HReTlg8ttaYk+0m62gQJmCblMOjHSMHRrBP2zdfKMHLCRbh/6ex9fSUJMKdjjIEiohwkbGD3wj2Nw==", + "license": "MIT", + "dependencies": { + "promise-worker-transferable": "^1.0.4" + }, + "peerDependencies": { + "three": ">= 0.159.0" + } + }, "node_modules/@next/env": { "version": "15.5.2", "resolved": "https://registry.npmjs.org/@next/env/-/env-15.5.2.tgz", @@ -1101,11 +1122,52 @@ "node": ">=20.8" } }, + "node_modules/@react-three/drei": { + "version": "10.7.6", + "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.6.tgz", + "integrity": "sha512-ZSFwRlRaa4zjtB7yHO6Q9xQGuyDCzE7whXBhum92JslcMRC3aouivp0rAzszcVymIoJx6PXmibyP+xr+zKdwLg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.26.0", + "@mediapipe/tasks-vision": "0.10.17", + "@monogrid/gainmap-js": "^3.0.6", + "@use-gesture/react": "^10.3.1", + "camera-controls": "^3.1.0", + "cross-env": "^7.0.3", + "detect-gpu": "^5.0.56", + "glsl-noise": "^0.0.0", + "hls.js": "^1.5.17", + "maath": "^0.10.8", + "meshline": "^3.3.1", + "stats-gl": "^2.2.8", + "stats.js": "^0.17.0", + "suspend-react": "^0.1.3", + "three-mesh-bvh": "^0.8.3", + "three-stdlib": "^2.35.6", + "troika-three-text": "^0.52.4", + "tunnel-rat": "^0.1.2", + "use-sync-external-store": "^1.4.0", + "utility-types": "^3.11.0", + "zustand": "^5.0.1" + }, + "peerDependencies": { + "@react-three/fiber": "^9.0.0", + "react": "^19", + "react-dom": "^19", + "three": ">=0.159" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + } + } + }, "node_modules/@react-three/fiber": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@react-three/fiber/-/fiber-9.3.0.tgz", "integrity": "sha512-myPe3YL/C8+Eq939/4qIVEPBW/uxV0iiUbmjfwrs9sGKYDG8ib8Dz3Okq7BQt8P+0k4igedONbjXMQy84aDFmQ==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.17.8", "@types/react-reconciler": "^0.32.0", @@ -1157,6 +1219,32 @@ "integrity": "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==", "license": "MIT" }, + "node_modules/@react-three/postprocessing": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@react-three/postprocessing/-/postprocessing-3.0.4.tgz", + "integrity": "sha512-e4+F5xtudDYvhxx3y0NtWXpZbwvQ0x1zdOXWTbXMK6fFLVDd4qucN90YaaStanZGS4Bd5siQm0lGL/5ogf8iDQ==", + "license": "MIT", + "dependencies": { + "maath": "^0.6.0", + "n8ao": "^1.9.4", + "postprocessing": "^6.36.6" + }, + "peerDependencies": { + "@react-three/fiber": "^9.0.0", + "react": "^19.0", + "three": ">= 0.156.0" + } + }, + "node_modules/@react-three/postprocessing/node_modules/maath": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.6.0.tgz", + "integrity": "sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==", + "license": "MIT", + "peerDependencies": { + "@types/three": ">=0.144.0", + "three": ">=0.144.0" + } + }, "node_modules/@swc/helpers": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz", @@ -1166,11 +1254,42 @@ "tslib": "^2.8.0" } }, + "node_modules/@tanstack/query-core": { + "version": "5.90.8", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.90.8.tgz", + "integrity": "sha512-4E0RP/0GJCxSNiRF2kAqE/LQkTJVlL/QNU7gIJSptaseV9HP6kOuA+N11y4bZKZxa3QopK3ZuewwutHx6DqDXQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.90.8", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.90.8.tgz", + "integrity": "sha512-/3b9QGzkf4rE5/miL6tyhldQRlLXzMHcySOm/2Tm2OLEFE9P1ImkH0+OviDBSvyAvtAOJocar5xhd7vxdLi3aQ==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.90.8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18 || ^19" + } + }, "node_modules/@tweenjs/tween.js": { "version": "23.1.3", "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", "integrity": "sha512-vJmvvwFxYuGnF2axRtPYocag6Clbb5YS7kLL+SO/TeVFzHqDIWrNKYtcsPMibjDx9O+bu+psAy9NKfWklassUA==", - "dev": true, + "license": "MIT" + }, + "node_modules/@types/draco3d": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz", + "integrity": "sha512-AX22jp8Y7wwaBgAixaSvkoG4M/+PlAcm3Qs4OW8yT9DM4xUpWKeFhLueTAyZF39pviAdcDdeJoACapiAceqNcw==", "license": "MIT" }, "node_modules/@types/node": { @@ -1183,10 +1302,16 @@ "undici-types": "~7.10.0" } }, + "node_modules/@types/offscreencanvas": { + "version": "2019.7.3", + "resolved": "https://registry.npmjs.org/@types/offscreencanvas/-/offscreencanvas-2019.7.3.tgz", + "integrity": "sha512-ieXiYmgSRXUDeOntE1InxjWyvEelZGP63M+cGuquuRLuIKKT1osnkXjxev9B7d1nXSug5vpunx+gNlbVxMlC9A==", + "license": "MIT" + }, "node_modules/@types/react": { - "version": "19.1.12", - "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz", - "integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==", + "version": "19.2.4", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.4.tgz", + "integrity": "sha512-tBFxBp9Nfyy5rsmefN+WXc1JeW/j2BpBHFdLZbEVfs9wn3E3NRFxwV0pJg8M1qQAexFpvz73hJXFofV0ZAu92A==", "license": "MIT", "peer": true, "dependencies": { @@ -1206,15 +1331,14 @@ "version": "0.17.4", "resolved": "https://registry.npmjs.org/@types/stats.js/-/stats.js-0.17.4.tgz", "integrity": "sha512-jIBvWWShCvlBqBNIZt0KAshWpvSjhkwkEu4ZUcASoAvhmrgAUI2t1dXrjSL4xXVLB4FznPrIsX3nKXFl/Dt4vA==", - "dev": true, "license": "MIT" }, "node_modules/@types/three": { "version": "0.180.0", "resolved": "https://registry.npmjs.org/@types/three/-/three-0.180.0.tgz", "integrity": "sha512-ykFtgCqNnY0IPvDro7h+9ZeLY+qjgUWv+qEvUt84grhenO60Hqd4hScHE7VTB9nOQ/3QM8lkbNE+4vKjEpUxKg==", - "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@dimforge/rapier3d-compat": "~0.12.0", "@tweenjs/tween.js": "~23.1.3", @@ -1241,11 +1365,28 @@ "integrity": "sha512-GPe4AsfOSpqWd3xA/0gwoKod13ChcfV67trvxaW2krUbgb9gxQjnCx8zGshzMl8LSHZlNH5gQ8LNScsDuc7nGQ==", "license": "MIT" }, + "node_modules/@use-gesture/core": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", + "integrity": "sha512-WcINiDt8WjqBdUXye25anHiNxPc0VOrlT8F6LLkU6cycrOGUDyY/yyFmsg3k8i5OLvv25llc0QC45GhR/C8llw==", + "license": "MIT" + }, + "node_modules/@use-gesture/react": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@use-gesture/react/-/react-10.3.1.tgz", + "integrity": "sha512-Yy19y6O2GJq8f7CHf7L0nxL8bf4PZCPaVOCgJrusOeFHY1LvHgYXnmnXg6N5iwAnbgbZCDjo60SiM6IPJi9C5g==", + "license": "MIT", + "dependencies": { + "@use-gesture/core": "10.3.1" + }, + "peerDependencies": { + "react": ">= 16.8.0" + } + }, "node_modules/@webgpu/types": { "version": "0.1.64", "resolved": "https://registry.npmjs.org/@webgpu/types/-/types-0.1.64.tgz", "integrity": "sha512-84kRIAGV46LJTlJZWxShiOrNL30A+9KokD7RB3dRCIqODFjodS5tCD5yyiZ8kIReGVZSDfA3XkkwyyOIF6K62A==", - "dev": true, "license": "BSD-3-Clause" }, "node_modules/ansi-regex": { @@ -1294,6 +1435,15 @@ ], "license": "MIT" }, + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -1324,6 +1474,19 @@ "ieee754": "^1.2.1" } }, + "node_modules/camera-controls": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-3.1.0.tgz", + "integrity": "sha512-w5oULNpijgTRH0ARFJJ0R5ct1nUM3R3WP7/b8A6j9uTGpRfnsypc/RBMPQV8JQDPayUe37p/TZZY1PcUr4czOQ==", + "license": "MIT", + "engines": { + "node": ">=20.11.0", + "npm": ">=10.8.2" + }, + "peerDependencies": { + "three": ">=0.126.1" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001741", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001741.tgz", @@ -1411,11 +1574,28 @@ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "license": "MIT" }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, "node_modules/cross-spawn": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -1432,6 +1612,15 @@ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", "license": "MIT" }, + "node_modules/detect-gpu": { + "version": "5.0.70", + "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz", + "integrity": "sha512-bqerEP1Ese6nt3rFkwPnGbsUF9a4q+gMmpTVVOEzoCyeCc+y7/RvJnQZJx1JwhgQI5Ntg0Kgat8Uu7XpBqnz1w==", + "license": "MIT", + "dependencies": { + "webgl-constants": "^1.1.1" + } + }, "node_modules/detect-libc": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", @@ -1442,6 +1631,12 @@ "node": ">=8" } }, + "node_modules/draco3d": { + "version": "1.5.7", + "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz", + "integrity": "sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==", + "license": "Apache-2.0" + }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -1511,7 +1706,6 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", - "dev": true, "license": "MIT" }, "node_modules/foreground-child": { @@ -1597,12 +1791,24 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/glsl-noise": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/glsl-noise/-/glsl-noise-0.0.0.tgz", + "integrity": "sha512-b/ZCF6amfAUb7dJM/MxRs7AetQEahYzJ8PtgfrmEdtw6uyGOr+ZSGtgjFm6mfsBkxJ4d2W7kg+Nlqzqvn3Bc0w==", + "license": "MIT" + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, + "node_modules/hls.js": { + "version": "1.6.14", + "resolved": "https://registry.npmjs.org/hls.js/-/hls.js-1.6.14.tgz", + "integrity": "sha512-CSpT2aXsv71HST8C5ETeVo+6YybqCpHBiYrCRQSn3U5QUZuLTSsvtq/bj+zuvjLVADeKxoebzo16OkH8m1+65Q==", + "license": "Apache-2.0" + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -1623,6 +1829,12 @@ ], "license": "BSD-3-Clause" }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", @@ -1646,6 +1858,12 @@ "node": ">=8" } }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "license": "MIT" + }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -1656,7 +1874,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, "license": "ISC" }, "node_modules/its-fine": { @@ -1708,6 +1925,15 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lru-cache": { "version": "11.2.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.1.tgz", @@ -1718,11 +1944,29 @@ "node": "20 || >=22" } }, + "node_modules/maath": { + "version": "0.10.8", + "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz", + "integrity": "sha512-tRvbDF0Pgqz+9XUa4jjfgAQ8/aPKmQdWXilFu2tMy4GWj4NOsx99HlULO4IeREfbO3a0sA145DZYyvXPkybm0g==", + "license": "MIT", + "peerDependencies": { + "@types/three": ">=0.134.0", + "three": ">=0.134.0" + } + }, + "node_modules/meshline": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz", + "integrity": "sha512-/TQj+JdZkeSUOl5Mk2J7eLcYTLiQm2IDzmlSvYm7ov15anEcDJ92GHqqazxTSreeNgfnYu24kiEvvv0WlbCdFQ==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.137" + } + }, "node_modules/meshoptimizer": { "version": "0.22.0", "resolved": "https://registry.npmjs.org/meshoptimizer/-/meshoptimizer-0.22.0.tgz", "integrity": "sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==", - "dev": true, "license": "MIT" }, "node_modules/minimatch": { @@ -1751,6 +1995,16 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/n8ao": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/n8ao/-/n8ao-1.10.1.tgz", + "integrity": "sha512-hhI1pC+BfOZBV1KMwynBrVlIm8wqLxj/abAWhF2nZ0qQKyzTSQa1QtLVS2veRiuoBQXojxobcnp0oe+PUoxf/w==", + "license": "ISC", + "peerDependencies": { + "postprocessing": ">=6.30.0", + "three": ">=0.137" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -1838,7 +2092,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -1913,12 +2166,38 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/postprocessing": { + "version": "6.38.0", + "resolved": "https://registry.npmjs.org/postprocessing/-/postprocessing-6.38.0.tgz", + "integrity": "sha512-tisx8XN/PWTL3uXz2mt8bjlMS1wiOUSCK3ixi4zjwUCFmP8XW8hNhXwrxwd2zf2VmCyCQ3GUaLm7GLnkkBbDsQ==", + "license": "Zlib", + "peer": true, + "peerDependencies": { + "three": ">= 0.157.0 < 0.182.0" + } + }, + "node_modules/potpack": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/potpack/-/potpack-1.0.2.tgz", + "integrity": "sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==", + "license": "ISC" + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, + "node_modules/promise-worker-transferable": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/promise-worker-transferable/-/promise-worker-transferable-1.0.4.tgz", + "integrity": "sha512-bN+0ehEnrXfxV2ZQvU2PetO0n4gqBD4ulq3MI1WOPLgr7/Mg9yRQkX5+0v1vagr74ZTsl7XtzlaYDo2EuCeYJw==", + "license": "Apache-2.0", + "dependencies": { + "is-promise": "^2.1.0", + "lie": "^3.0.2" + } + }, "node_modules/react": { "version": "19.1.1", "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz", @@ -1942,6 +2221,18 @@ "react": "^19.1.1" } }, + "node_modules/react-error-boundary": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-6.0.0.tgz", + "integrity": "sha512-gdlJjD7NWr0IfkPlaREN2d9uUZUlksrfOx7SX62VRerwXbMY6ftGCIZua1VG1aXFNOimhISsTq+Owp725b9SiA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/react-reconciler": { "version": "0.31.0", "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.31.0.tgz", @@ -1993,6 +2284,15 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -2095,7 +2395,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -2108,7 +2407,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -2156,6 +2454,32 @@ "node": ">=0.10.0" } }, + "node_modules/stats-gl": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz", + "integrity": "sha512-g5O9B0hm9CvnM36+v7SFl39T7hmAlv541tU81ME8YeSb3i1CIP5/QdDeSB3A0la0bKNHpxpwxOVRo2wFTYEosQ==", + "license": "MIT", + "dependencies": { + "@types/three": "*", + "three": "^0.170.0" + }, + "peerDependencies": { + "@types/three": "*", + "three": "*" + } + }, + "node_modules/stats-gl/node_modules/three": { + "version": "0.170.0", + "resolved": "https://registry.npmjs.org/three/-/three-0.170.0.tgz", + "integrity": "sha512-FQK+LEpYc0fBD+J8g6oSEyyNzjp+Q7Ks1C568WWaoMRLW+TkNNWmenWeGgJjV105Gd+p/2ql1ZcjYvNiPZBhuQ==", + "license": "MIT" + }, + "node_modules/stats.js": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/stats.js/-/stats.js-0.17.0.tgz", + "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==", + "license": "MIT" + }, "node_modules/string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -2308,6 +2632,68 @@ "license": "MIT", "peer": true }, + "node_modules/three-mesh-bvh": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.8.3.tgz", + "integrity": "sha512-4G5lBaF+g2auKX3P0yqx+MJC6oVt6sB5k+CchS6Ob0qvH0YIhuUk1eYr7ktsIpY+albCqE80/FVQGV190PmiAg==", + "license": "MIT", + "peerDependencies": { + "three": ">= 0.159.0" + } + }, + "node_modules/three-stdlib": { + "version": "2.36.1", + "resolved": "https://registry.npmjs.org/three-stdlib/-/three-stdlib-2.36.1.tgz", + "integrity": "sha512-XyGQrFmNQ5O/IoKm556ftwKsBg11TIb301MB5dWNicziQBEs2g3gtOYIf7pFiLa0zI2gUwhtCjv9fmjnxKZ1Cg==", + "license": "MIT", + "dependencies": { + "@types/draco3d": "^1.4.0", + "@types/offscreencanvas": "^2019.6.4", + "@types/webxr": "^0.5.2", + "draco3d": "^1.4.1", + "fflate": "^0.6.9", + "potpack": "^1.0.1" + }, + "peerDependencies": { + "three": ">=0.128.0" + } + }, + "node_modules/three-stdlib/node_modules/fflate": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.6.10.tgz", + "integrity": "sha512-IQrh3lEPM93wVCEczc9SaAOvkmcoQn/G8Bo1e8ZPlY3X3bnAxWaBdvTdvM1hP62iZp0BXWDy4vTAy4fF0+Dlpg==", + "license": "MIT" + }, + "node_modules/troika-three-text": { + "version": "0.52.4", + "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz", + "integrity": "sha512-V50EwcYGruV5rUZ9F4aNsrytGdKcXKALjEtQXIOBfhVoZU9VAqZNIoGQ3TMiooVqFAbR1w15T+f+8gkzoFzawg==", + "license": "MIT", + "dependencies": { + "bidi-js": "^1.0.2", + "troika-three-utils": "^0.52.4", + "troika-worker-utils": "^0.52.0", + "webgl-sdf-generator": "1.1.1" + }, + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-three-utils": { + "version": "0.52.4", + "resolved": "https://registry.npmjs.org/troika-three-utils/-/troika-three-utils-0.52.4.tgz", + "integrity": "sha512-NORAStSVa/BDiG52Mfudk4j1FG4jC4ILutB3foPnfGbOeIs9+G5vZLa0pnmnaftZUGm4UwSoqEpWdqvC7zms3A==", + "license": "MIT", + "peerDependencies": { + "three": ">=0.125.0" + } + }, + "node_modules/troika-worker-utils": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/troika-worker-utils/-/troika-worker-utils-0.52.0.tgz", + "integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==", + "license": "MIT" + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2334,6 +2720,43 @@ "fsevents": "~2.3.3" } }, + "node_modules/tunnel-rat": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/tunnel-rat/-/tunnel-rat-0.1.2.tgz", + "integrity": "sha512-lR5VHmkPhzdhrM092lI2nACsLO4QubF0/yoOhzX7c+wIpbN1GjHNzCc91QlpxBi+cnx8vVJ+Ur6vL5cEoQPFpQ==", + "license": "MIT", + "dependencies": { + "zustand": "^4.3.2" + } + }, + "node_modules/tunnel-rat/node_modules/zustand": { + "version": "4.5.7", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", + "integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==", + "license": "MIT", + "dependencies": { + "use-sync-external-store": "^1.2.2" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "@types/react": ">=16.8", + "immer": ">=9.0.6", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } + }, "node_modules/typescript": { "version": "5.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", @@ -2382,7 +2805,6 @@ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz", "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==", "license": "MIT", - "peer": true, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } @@ -2393,11 +2815,30 @@ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "license": "MIT" }, + "node_modules/utility-types": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/utility-types/-/utility-types-3.11.0.tgz", + "integrity": "sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/webgl-constants": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz", + "integrity": "sha512-LkBXKjU5r9vAW7Gcu3T5u+5cvSvh5WwINdr0C+9jpzVB41cjQAP5ePArDtk/WHYdVj0GefCgM73BA7FlIiNtdg==" + }, + "node_modules/webgl-sdf-generator": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/webgl-sdf-generator/-/webgl-sdf-generator-1.1.1.tgz", + "integrity": "sha512-9Z0JcMTFxeE+b2x1LJTdnaT8rT8aEp7MVxkNwoycNmJWwPdzoXzMh0BjJSh/AEFP+KPYZUli814h8bJZFIZ2jA==", + "license": "MIT" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" diff --git a/package.json b/package.json index 3b9a77c7..1e1de8cf 100644 --- a/package.json +++ b/package.json @@ -13,19 +13,23 @@ "deploy": "npm run build && git add -f docs && git commit -m \"Deploy\" && git push", "postbuild": "git checkout -- public/base", "prebuild": "npm run clean && git checkout -- docs && rimraf public/base && mv docs/base public/", - "start": "next dev" + "start": "next dev --turbopack" }, "dependencies": { + "@react-three/drei": "^10.7.6", "@react-three/fiber": "^9.3.0", + "@react-three/postprocessing": "^3.0.4", + "@tanstack/react-query": "^5.90.8", "next": "^15.5.2", "react": "^19.1.1", "react-dom": "^19.1.1", + "react-error-boundary": "^6.0.0", "three": "^0.180.0", "unzipper": "^0.12.3" }, "devDependencies": { "@types/node": "24.3.1", - "@types/react": "19.1.12", + "@types/react": "^19.2.4", "@types/three": "^0.180.0", "@types/unzipper": "^0.10.11", "peggy": "^5.0.6", diff --git a/scripts/extract-assets.ts b/scripts/extract-assets.ts index d8513f53..d1419804 100644 --- a/scripts/extract-assets.ts +++ b/scripts/extract-assets.ts @@ -4,7 +4,7 @@ import { normalizePath } from "@/src/stringUtils"; import manifest from "@/public/manifest.json"; import path from "node:path"; -const inputBaseDir = "rawGameData/base"; +const inputBaseDir = process.env.BASE_DIR || "GameData/base"; const outputBaseDir = "docs/base"; const archives = new Map(); diff --git a/scripts/find-missing-dts.ts b/scripts/find-missing-dts.ts new file mode 100644 index 00000000..3a4eac15 --- /dev/null +++ b/scripts/find-missing-dts.ts @@ -0,0 +1,18 @@ +import fs from "node:fs/promises"; + +async function run() { + for await (const inFile of fs.glob("docs/base/**/*.dts")) { + const glbFile = inFile.replace(/\.dts$/, ".glb"); + try { + await fs.stat(glbFile); + } catch (err) { + if (err.code === "ENOENT") { + console.log(inFile); + } else { + throw err; + } + } + } +} + +run(); diff --git a/scripts/generate-manifest.ts b/scripts/generate-manifest.ts index b9bf67b5..6526dc22 100644 --- a/scripts/generate-manifest.ts +++ b/scripts/generate-manifest.ts @@ -6,7 +6,7 @@ import { normalizePath } from "@/src/stringUtils"; const archiveFilePattern = /\.vl2$/i; -const baseDir = "rawGameData/base"; +const baseDir = process.env.BASE_DIR || "GameData/base"; function isArchive(name: string) { return archiveFilePattern.test(name); diff --git a/src/arrayUtils.ts b/src/arrayUtils.ts new file mode 100644 index 00000000..a8e1c713 --- /dev/null +++ b/src/arrayUtils.ts @@ -0,0 +1,7 @@ +export function uint16ToFloat32(src: Uint16Array) { + const out = new Float32Array(src.length); + for (let i = 0; i < src.length; i++) { + out[i] = src[i] / 65535; + } + return out; +} diff --git a/src/components/GenericShape.tsx b/src/components/GenericShape.tsx new file mode 100644 index 00000000..5e7044cd --- /dev/null +++ b/src/components/GenericShape.tsx @@ -0,0 +1,122 @@ +import { Suspense } from "react"; +import { useGLTF, useTexture } from "@react-three/drei"; +import { BASE_URL, shapeTextureToUrl, shapeToUrl } from "../loaders"; +import { filterGeometryByVertexGroups, getHullBoneIndices } from "../meshUtils"; +import { + createAlphaAsRoughnessMaterial, + setupAlphaAsRoughnessTexture, +} from "../shaderMaterials"; +import { MeshStandardMaterial } from "three"; +import { setupColor } from "../textureUtils"; + +const FALLBACK_URL = `${BASE_URL}/black.png`; + +/** + * Load a .glb file that was converted from a .dts, used for static shapes. + */ +export function useStaticShape(shapeName: string) { + const url = shapeToUrl(shapeName); + return useGLTF(url); +} + +export function ShapeTexture({ + material, + shapeName, +}: { + material?: MeshStandardMaterial; + shapeName?: string; +}) { + const url = shapeTextureToUrl(material.name, FALLBACK_URL); + const isOrganic = shapeName && /borg|xorg/i.test(shapeName); + + const texture = useTexture(url, (texture) => { + if (!isOrganic) { + setupAlphaAsRoughnessTexture(texture); + } + return setupColor(texture); + }); + + // Only use alpha-as-roughness material for borg shapes + if (!isOrganic) { + const shaderMaterial = createAlphaAsRoughnessMaterial(); + shaderMaterial.map = texture; + return ; + } + + // For non-borg shapes, use the original GLTF material with updated texture + const clonedMaterial = material.clone(); + clonedMaterial.map = texture; + clonedMaterial.transparent = true; + clonedMaterial.alphaTest = 0.9; + return ; +} + +export function ShapeModel({ shapeName }: { shapeName: string }) { + const { nodes } = useStaticShape(shapeName); + + let hullBoneIndices = new Set(); + const skeletonsFound = Object.values(nodes).filter( + (node: any) => node.skeleton + ); + + if (skeletonsFound.length > 0) { + const skeleton = (skeletonsFound[0] as any).skeleton; + hullBoneIndices = getHullBoneIndices(skeleton); + } + + return ( + <> + {Object.entries(nodes) + .filter( + ([name, node]: [string, any]) => + node.material && + node.material.name !== "Unassigned" && + !node.name.match(/^Hulk/i) + ) + .map(([name, node]: [string, any]) => { + const geometry = filterGeometryByVertexGroups( + node.geometry, + hullBoneIndices + ); + + return ( + + {node.material ? ( + + } + > + {Array.isArray(node.material) ? ( + node.material.map((mat, index) => ( + + )) + ) : ( + + )} + + ) : null} + + ); + })} + + ); +} + +export function ShapePlaceholder({ color }: { color: string }) { + return ( + + + + + ); +} diff --git a/src/components/InspectorControls.tsx b/src/components/InspectorControls.tsx new file mode 100644 index 00000000..36a3d6d4 --- /dev/null +++ b/src/components/InspectorControls.tsx @@ -0,0 +1,88 @@ +import { getResourceList } from "../manifest"; +import { useSettings } from "./SettingsProvider"; + +const excludeMissions = new Set([ + "SkiFree", + "SkiFree_Daily", + "SkiFree_Randomizer", +]); + +const missions = getResourceList() + .map((resourcePath) => resourcePath.match(/^missions\/(.+)\.mis$/)) + .filter(Boolean) + .map((match) => match[1]) + .filter((name) => !excludeMissions.has(name)); + +export function InspectorControls({ + missionName, + onChangeMission, +}: { + missionName: string; + onChangeMission: (name: string) => void; +}) { + const { + fogEnabled, + setFogEnabled, + speedMultiplier, + setSpeedMultiplier, + fov, + setFov, + } = useSettings(); + + return ( +
e.stopPropagation()} + onPointerDown={(e) => e.stopPropagation()} + onClick={(e) => e.stopPropagation()} + > + +
+ { + setFogEnabled(event.target.checked); + }} + /> + +
+
+ + setFov(parseInt(event.target.value))} + /> + {fov} +
+
+ + + setSpeedMultiplier(parseFloat(event.target.value)) + } + /> +
+
+ ); +} diff --git a/src/components/InteriorInstance.tsx b/src/components/InteriorInstance.tsx new file mode 100644 index 00000000..75dda360 --- /dev/null +++ b/src/components/InteriorInstance.tsx @@ -0,0 +1,102 @@ +import { memo, Suspense, useMemo } from "react"; +import { Mesh } from "three"; +import { useGLTF, useTexture } from "@react-three/drei"; +import { BASE_URL, interiorTextureToUrl, interiorToUrl } from "../loaders"; +import { + ConsoleObject, + getPosition, + getProperty, + getRotation, + getScale, +} from "../mission"; +import { setupColor } from "../textureUtils"; + +const FALLBACK_URL = `${BASE_URL}/black.png`; + +/** + * Load a .gltf file that was converted from a .dif, used for "interior" models. + */ +function useInterior(interiorFile: string) { + const url = interiorToUrl(interiorFile); + return useGLTF(url); +} + +function InteriorTexture({ materialName }: { materialName: string }) { + const url = interiorTextureToUrl(materialName, FALLBACK_URL); + const texture = useTexture(url, (texture) => setupColor(texture)); + + return ; +} + +function InteriorMesh({ node }: { node: Mesh }) { + return ( + + {node.material ? ( + + } + > + {Array.isArray(node.material) ? ( + node.material.map((mat, index) => ( + + )) + ) : ( + + )} + + ) : null} + + ); +} + +export const InteriorModel = memo( + ({ interiorFile }: { interiorFile: string }) => { + const { nodes } = useInterior(interiorFile); + + return ( + <> + {Object.entries(nodes) + .filter( + ([name, node]: [string, any]) => + !node.material || !node.material.name.match(/\.\d+$/) + ) + .map(([name, node]: [string, any]) => ( + + ))} + + ); + } +); + +function InteriorPlaceholder() { + return ( + + + + + ); +} + +export const InteriorInstance = memo( + ({ object }: { object: ConsoleObject }) => { + const interiorFile = getProperty(object, "interiorFile").value; + const [z, y, x] = useMemo(() => getPosition(object), [object]); + const [scaleX, scaleY, scaleZ] = useMemo(() => getScale(object), [object]); + const q = useMemo(() => getRotation(object, true), [object]); + + return ( + + }> + + + + ); + } +); diff --git a/src/components/Item.tsx b/src/components/Item.tsx new file mode 100644 index 00000000..f65fad7e --- /dev/null +++ b/src/components/Item.tsx @@ -0,0 +1,85 @@ +import { Suspense, useMemo } from "react"; +import { ErrorBoundary } from "react-error-boundary"; +import { + ConsoleObject, + getPosition, + getProperty, + getRotation, + getScale, +} from "../mission"; +import { ShapeModel, ShapePlaceholder } from "./GenericShape"; + +const dataBlockToShapeName = { + AmmoPack: "pack_upgrade_ammo.dts", + Beacon: "beacon.dts", + Chaingun: "weapon_chaingun.dts", + ChaingunAmmo: "ammo_chaingun.dts", + CloakingPack: "pack_upgrade_cloaking.dts", + ConcussionGrenade: "grenade.dts", + DiscAmmo: "ammo_disc.dts", + ELFGun: "weapon_elf.dts", + EnergyPack: "pack_upgrade_energy.dts", + Flag: "flag.dts", + FlareGrenade: "grenade.dts", + Grenade: "grenade.dts", + GrenadeLauncher: "weapon_grenade_launcher.dts", + GrenadeLauncherAmmo: "ammo_grenade.dts", + InventoryDeployable: "pack_deploy_inventory.dts", + Mine: "ammo_mine.dts", + MotionSensorDeployable: "pack_deploy_sensor_motion.dts", + Plasma: "weapon_plasma.dts", + PlasmaAmmo: "ammo_plasma.dts", + PulseSensorDeployable: "pack_deploy_sensor_pulse.dts", + RepairKit: "repair_kit.dts", + RepairPack: "pack_upgrade_repair.dts", + RepairPatch: "repair_patch.dts", + SensorJammerPack: "pack_upgrade_sensorjammer.dts", + ShieldPack: "pack_upgrade_shield.dts", + ShockLance: "weapon_shocklance.dts", + SniperRifle: "weapon_sniper.dts", +}; + +let _caseInsensitiveLookup: Record; + +function getDataBlockShape(dataBlock: string) { + if (!_caseInsensitiveLookup) { + _caseInsensitiveLookup = Object.fromEntries( + Object.entries(dataBlockToShapeName).map(([key, value]) => { + return [key.toLowerCase(), value]; + }) + ); + } + return _caseInsensitiveLookup[dataBlock.toLowerCase()]; +} + +export function Item({ object }: { object: ConsoleObject }) { + const dataBlock = getProperty(object, "dataBlock").value; + + const [z, y, x] = useMemo(() => getPosition(object), [object]); + const [scaleX, scaleY, scaleZ] = useMemo(() => getScale(object), [object]); + const q = useMemo(() => getRotation(object, true), [object]); + + const shapeName = getDataBlockShape(dataBlock); + + if (!shapeName) { + console.error(` missing shape for dataBlock: ${dataBlock}`); + } + + return ( + + {shapeName ? ( + }> + }> + + + + ) : ( + + )} + + ); +} diff --git a/src/components/Mission.tsx b/src/components/Mission.tsx new file mode 100644 index 00000000..7d2b3871 --- /dev/null +++ b/src/components/Mission.tsx @@ -0,0 +1,20 @@ +import { useQuery } from "@tanstack/react-query"; +import { loadMission } from "../loaders"; +import { renderObject } from "./renderObject"; + +function useMission(name: string) { + return useQuery({ + queryKey: ["mission", name], + queryFn: () => loadMission(name), + }); +} + +export function Mission({ name }: { name: string }) { + const { data: mission } = useMission(name); + + if (!mission) { + return null; + } + + return <>{mission.objects.map((object, i) => renderObject(object, i))}; +} diff --git a/src/components/ObserverCamera.tsx b/src/components/ObserverCamera.tsx new file mode 100644 index 00000000..59676151 --- /dev/null +++ b/src/components/ObserverCamera.tsx @@ -0,0 +1,10 @@ +import { PerspectiveCamera } from "@react-three/drei"; +import { useSettings } from "./SettingsProvider"; + +export function ObserverCamera() { + const { fov } = useSettings(); + + return ( + + ); +} diff --git a/src/components/ObserverControls.tsx b/src/components/ObserverControls.tsx new file mode 100644 index 00000000..8d19c774 --- /dev/null +++ b/src/components/ObserverControls.tsx @@ -0,0 +1,142 @@ +import { useEffect, useRef } from "react"; +import { Vector3 } from "three"; +import { useFrame, useThree } from "@react-three/fiber"; +import { KeyboardControls, useKeyboardControls } from "@react-three/drei"; +import { PointerLockControls } from "three-stdlib"; +import { useSettings } from "./SettingsProvider"; + +enum Controls { + forward = "forward", + backward = "backward", + left = "left", + right = "right", + up = "up", + down = "down", +} + +const BASE_SPEED = 100; // units per second +const MIN_SPEED_ADJUSTMENT = 0.05; +const MAX_SPEED_ADJUSTMENT = 1; + +function CameraMovement() { + const { speedMultiplier, setSpeedMultiplier } = useSettings(); + const [subscribe, getKeys] = useKeyboardControls(); + const { camera, gl } = useThree(); + const controlsRef = useRef(null); + + // Scratch vectors to avoid allocations each frame + const forwardVec = useRef(new Vector3()); + const sideVec = useRef(new Vector3()); + const moveVec = useRef(new Vector3()); + + // Setup pointer lock controls + useEffect(() => { + const controls = new PointerLockControls(camera, gl.domElement); + controlsRef.current = controls; + + const handleClick = (e: MouseEvent) => { + // Only lock if clicking directly on the canvas (not on UI elements) + if (e.target === gl.domElement) { + controls.lock(); + } + }; + + gl.domElement.addEventListener("click", handleClick); + + return () => { + gl.domElement.removeEventListener("click", handleClick); + controls.dispose(); + }; + }, [camera, gl]); + + // Handle mousewheel for speed adjustment + useEffect(() => { + const handleWheel = (e: WheelEvent) => { + e.preventDefault(); + + const direction = e.deltaY > 0 ? -1 : 1; + + const delta = + // Helps normalize sensitivity; trackpad scrolling will have many small + // updates while mouse wheels have fewer updates but large deltas. + Math.max( + MIN_SPEED_ADJUSTMENT, + Math.min(MAX_SPEED_ADJUSTMENT, Math.abs(e.deltaY * 0.01)) + ) * direction; + + setSpeedMultiplier((prev) => { + const newSpeed = Math.round((prev + delta) * 20) / 20; + return Math.max(0.1, Math.min(5, newSpeed)); + }); + }; + + const canvas = gl.domElement; + canvas.addEventListener("wheel", handleWheel, { passive: false }); + + return () => { + canvas.removeEventListener("wheel", handleWheel); + }; + }, [gl]); + + useFrame((_, delta) => { + const { forward, backward, left, right, up, down } = getKeys(); + + if (!forward && !backward && !left && !right && !up && !down) { + return; + } + + const speed = BASE_SPEED * speedMultiplier; + + // Forward/backward: take complete camera angle into account (including Y) + camera.getWorldDirection(forwardVec.current); + forwardVec.current.normalize(); + + // Left/right: move along XZ plane + sideVec.current.crossVectors(camera.up, forwardVec.current).normalize(); + + moveVec.current.set(0, 0, 0); + + if (forward) { + moveVec.current.add(forwardVec.current); + } + if (backward) { + moveVec.current.sub(forwardVec.current); + } + if (left) { + moveVec.current.add(sideVec.current); + } + if (right) { + moveVec.current.sub(sideVec.current); + } + if (up) { + moveVec.current.y += 1; + } + if (down) { + moveVec.current.y -= 1; + } + + if (moveVec.current.lengthSq() > 0) { + moveVec.current.normalize().multiplyScalar(speed * delta); + camera.position.add(moveVec.current); + } + }); + + return null; +} + +const KEYBOARD_CONTROLS = [ + { name: Controls.forward, keys: ["KeyW"] }, + { name: Controls.backward, keys: ["KeyS"] }, + { name: Controls.left, keys: ["KeyA"] }, + { name: Controls.right, keys: ["KeyD"] }, + { name: Controls.up, keys: ["Space"] }, + { name: Controls.down, keys: ["ShiftLeft", "ShiftRight"] }, +]; + +export function ObserverControls() { + return ( + + + + ); +} diff --git a/src/components/SettingsProvider.tsx b/src/components/SettingsProvider.tsx new file mode 100644 index 00000000..04e067d2 --- /dev/null +++ b/src/components/SettingsProvider.tsx @@ -0,0 +1,70 @@ +import React, { useContext, useEffect, useMemo, useState } from "react"; + +const SettingsContext = React.createContext(null); + +type PersistedSettings = { + fogEnabled?: boolean; + speedMultiplier?: number; + fov?: number; +}; + +export function useSettings() { + return useContext(SettingsContext); +} + +export function SettingsProvider({ children }: { children: React.ReactNode }) { + const [fogEnabled, setFogEnabled] = useState(true); + const [speedMultiplier, setSpeedMultiplier] = useState(1); + const [fov, setFov] = useState(90); + + const value = useMemo( + () => ({ + fogEnabled, + setFogEnabled, + speedMultiplier, + setSpeedMultiplier, + fov, + setFov, + }), + [fogEnabled, speedMultiplier, fov] + ); + + // Read persisted settings from localStoarge. + useEffect(() => { + let savedSettings: PersistedSettings = {}; + try { + savedSettings = JSON.parse(localStorage.getItem("settings")) || {}; + } catch (err) { + // Ignore. + } + if (savedSettings.fogEnabled != null) { + setFogEnabled(savedSettings.fogEnabled); + } + if (savedSettings.speedMultiplier != null) { + setSpeedMultiplier(savedSettings.speedMultiplier); + } + if (savedSettings.fov != null) { + setFov(savedSettings.fov); + } + }, []); + + // Persist settings to localStoarge. + useEffect(() => { + const settingsToSave: PersistedSettings = { + fogEnabled, + speedMultiplier, + fov, + }; + try { + localStorage.setItem("settings", JSON.stringify(settingsToSave)); + } catch (err) { + // Probably forbidden by browser settings. + } + }, [fogEnabled, speedMultiplier, fov]); + + return ( + + {children} + + ); +} diff --git a/src/components/SimGroup.tsx b/src/components/SimGroup.tsx new file mode 100644 index 00000000..5ae55e68 --- /dev/null +++ b/src/components/SimGroup.tsx @@ -0,0 +1,6 @@ +import { ConsoleObject } from "../mission"; +import { renderObject } from "./renderObject"; + +export function SimGroup({ object }: { object: ConsoleObject }) { + return object.children.map((child, i) => renderObject(child, i)); +} diff --git a/src/components/Sky.tsx b/src/components/Sky.tsx new file mode 100644 index 00000000..898b247f --- /dev/null +++ b/src/components/Sky.tsx @@ -0,0 +1,193 @@ +import { Suspense, useMemo, useEffect, useRef } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { useCubeTexture } from "@react-three/drei"; +import { Color, ShaderMaterial, BackSide } from "three"; +import { ConsoleObject, getProperty } from "../mission"; +import { useSettings } from "./SettingsProvider"; +import { BASE_URL, getUrlForPath, loadDetailMapList } from "../loaders"; + +const FALLBACK_URL = `${BASE_URL}/black.png`; + +/** + * Load a .dml file, used to list the textures for different faces of a skybox. + */ +function useDetailMapList(name: string) { + return useQuery({ + queryKey: ["detailMapList", name], + queryFn: () => loadDetailMapList(name), + }); +} + +export function SkyBox({ + materialList, + fogColor, + fogDistance, +}: { + materialList: string; + fogColor?: Color; + fogDistance?: number; +}) { + const { data: detailMapList } = useDetailMapList(materialList); + + const skyBoxFiles = useMemo( + () => + detailMapList + ? [ + getUrlForPath(detailMapList[1], FALLBACK_URL), // +x + getUrlForPath(detailMapList[3], FALLBACK_URL), // -x + getUrlForPath(detailMapList[4], FALLBACK_URL), // +y + getUrlForPath(detailMapList[5], FALLBACK_URL), // -y + getUrlForPath(detailMapList[0], FALLBACK_URL), // +z + getUrlForPath(detailMapList[2], FALLBACK_URL), // -z + ] + : [ + FALLBACK_URL, + FALLBACK_URL, + FALLBACK_URL, + FALLBACK_URL, + FALLBACK_URL, + FALLBACK_URL, + ], + [detailMapList] + ); + + const skyBox = useCubeTexture(skyBoxFiles, { path: "" }); + + // Create a shader material for the skybox with fog + const materialRef = useRef(null!); + + const hasFog = !!fogColor && !!fogDistance; + + const shaderMaterial = useMemo(() => { + if (!hasFog) { + return null; + } + + return new ShaderMaterial({ + uniforms: { + skybox: { value: skyBox }, + fogColor: { value: fogColor }, + }, + vertexShader: ` + varying vec3 vDirection; + + void main() { + // Use position directly as direction (no world transform needed) + vDirection = position; + + // Transform position but ignore translation + vec4 pos = projectionMatrix * mat4(mat3(modelViewMatrix)) * vec4(position, 1.0); + gl_Position = pos.xyww; // Set depth to far plane + } + `, + fragmentShader: ` + uniform samplerCube skybox; + uniform vec3 fogColor; + + varying vec3 vDirection; + + // Convert linear to sRGB + vec3 linearToSRGB(vec3 color) { + return pow(color, vec3(1.0 / 2.2)); + } + + void main() { + vec3 direction = normalize(vDirection); + direction.x = -direction.x; + vec4 skyColor = textureCube(skybox, direction); + + // Calculate fog factor based on vertical direction + // direction.y: -1 = straight down, 0 = horizon, 1 = straight up + // 100% fog from bottom to horizon, then fade from horizon (0) to 0.4 + float fogFactor = smoothstep(0.0, 0.4, direction.y); + + // Mix in sRGB space to match Three.js fog rendering + vec3 finalColor = mix(fogColor, skyColor.rgb, fogFactor); + gl_FragColor = vec4(finalColor, 1.0); + } + `, + side: BackSide, + depthWrite: false, + }); + }, [skyBox, fogColor, hasFog]); + + // Update uniforms when fog parameters change + useEffect(() => { + if (materialRef.current && hasFog && shaderMaterial) { + materialRef.current.uniforms.skybox.value = skyBox; + materialRef.current.uniforms.fogColor.value = fogColor!; + } + }, [skyBox, fogColor, hasFog, shaderMaterial]); + + // If fog is disabled, just use the skybox as background + if (!hasFog) { + return ; + } + + return ( + + + + + ); +} + +export function Sky({ object }: { object: ConsoleObject }) { + const { fogEnabled } = useSettings(); + + // Skybox textures. + const materialList = getProperty(object, "materialList")?.value; + + // Fog parameters. + // TODO: There can be multiple fog volumes/layers. Render simple fog for now. + const fogDistance = useMemo(() => { + const distanceString = getProperty(object, "fogDistance")?.value; + if (distanceString) { + return parseFloat(distanceString); + } + }, [object]); + + const fogColor = useMemo(() => { + const colorString = getProperty(object, "fogColor")?.value; + if (colorString) { + // `colorString` might specify an alpha value, but three.js doesn't + // support opacity on fog or scene backgrounds, so ignore it. + const [r, g, b] = colorString.split(" ").map((s) => parseFloat(s)); + return [ + new Color().setRGB(r, g, b), + new Color().setRGB(r, g, b).convertSRGBToLinear(), + ]; + } + }, [object]); + + const backgroundColor = fogColor ? ( + + ) : null; + + return ( + <> + {materialList ? ( + // If there's a skybox, its textures will need to load. Render just the + // fog color as the background in the meantime. + + + + ) : ( + // If there's no skybox, just render the fog color as the background. + backgroundColor + )} + {fogEnabled && fogDistance && fogColor ? ( + + ) : null} + + ); +} diff --git a/src/components/StaticShape.tsx b/src/components/StaticShape.tsx new file mode 100644 index 00000000..c8e3c378 --- /dev/null +++ b/src/components/StaticShape.tsx @@ -0,0 +1,76 @@ +import { Suspense, useMemo } from "react"; +import { ErrorBoundary } from "react-error-boundary"; +import { + ConsoleObject, + getPosition, + getProperty, + getRotation, + getScale, +} from "../mission"; +import { ShapeModel, ShapePlaceholder } from "./GenericShape"; + +const dataBlockToShapeName = { + Banner_Honor: "banner_honor.dts", + Banner_Strength: "banner_strength.dts", + Banner_Unity: "banner_unity.dts", + CreativityPad: "station_teleport.dts", + ExteriorFlagStand: "ext_flagstand.dts", + FlipFlop: "switch.dts", + GeneratorLarge: "station_generator_large.dts", + InteriorFlagStand: "int_flagstand.dts", + LightMaleHuman_Dead: "light_male_dead.dts", + LogoProjector: "teamlogo_projector.dts", + SensorLargePulse: "sensor_pulse_large.dts", + SensorMediumPulse: "sensor_pulse_medium.dts", + SolarPanel: "solarpanel.dts", + StaticShape: "switch.dts", + StationInventory: "station_inv_human.dts", + StationVehicle: "vehicle_pad_station.dts", + StationVehiclePad: "vehicle_pad.dts", + Teleporter: "nexusbase.dts", +}; + +let _caseInsensitiveLookup: Record; + +function getDataBlockShape(dataBlock: string) { + if (!_caseInsensitiveLookup) { + _caseInsensitiveLookup = Object.fromEntries( + Object.entries(dataBlockToShapeName).map(([key, value]) => { + return [key.toLowerCase(), value]; + }) + ); + } + return _caseInsensitiveLookup[dataBlock.toLowerCase()]; +} + +export function StaticShape({ object }: { object: ConsoleObject }) { + const dataBlock = getProperty(object, "dataBlock").value; + + const [z, y, x] = useMemo(() => getPosition(object), [object]); + const [scaleX, scaleY, scaleZ] = useMemo(() => getScale(object), [object]); + const q = useMemo(() => getRotation(object, true), [object]); + + const shapeName = getDataBlockShape(dataBlock); + + if (!shapeName) { + console.error(` missing shape for dataBlock: ${dataBlock}`); + } + + return ( + + {shapeName ? ( + }> + }> + + + + ) : ( + + )} + + ); +} diff --git a/src/components/Sun.tsx b/src/components/Sun.tsx new file mode 100644 index 00000000..ff364330 --- /dev/null +++ b/src/components/Sun.tsx @@ -0,0 +1,48 @@ +import { useMemo } from "react"; +import { Color } from "three"; +import { ConsoleObject, getProperty } from "../mission"; + +export function Sun({ object }: { object: ConsoleObject }) { + const direction = useMemo(() => { + const directionStr = getProperty(object, "direction")?.value ?? "0 0 -1"; + const [x, y, z] = directionStr.split(" ").map((s) => parseFloat(s)); + // Scale the direction vector to position the light far from the scene + const scale = 5000; + return [x * scale, y * scale, z * scale] as [number, number, number]; + }, [object]); + + const color = useMemo(() => { + const colorStr = getProperty(object, "color")?.value ?? "1 1 1 1"; + const [r, g, b] = colorStr.split(" ").map((s) => parseFloat(s)); + return [r, g, b] as [number, number, number]; + }, [object]); + + const ambient = useMemo(() => { + const ambientStr = getProperty(object, "ambient")?.value ?? "0.5 0.5 0.5 1"; + const [r, g, b] = ambientStr.split(" ").map((s) => parseFloat(s)); + return [r, g, b] as [number, number, number]; + }, [object]); + + return ( + <> + {/* Directional light for the sun */} + {/* */} + {/* Ambient light component */} + + + ); +} diff --git a/src/components/TSStatic.tsx b/src/components/TSStatic.tsx new file mode 100644 index 00000000..3bd1d704 --- /dev/null +++ b/src/components/TSStatic.tsx @@ -0,0 +1,32 @@ +import { Suspense, useMemo } from "react"; +import { ErrorBoundary } from "react-error-boundary"; +import { + ConsoleObject, + getPosition, + getProperty, + getRotation, + getScale, +} from "../mission"; +import { ShapeModel, ShapePlaceholder } from "./GenericShape"; + +export function TSStatic({ object }: { object: ConsoleObject }) { + const shapeName = getProperty(object, "shapeName").value; + + const [z, y, x] = useMemo(() => getPosition(object), [object]); + const [scaleX, scaleY, scaleZ] = useMemo(() => getScale(object), [object]); + const q = useMemo(() => getRotation(object, true), [object]); + + return ( + + }> + }> + + + + + ); +} diff --git a/src/components/TerrainBlock.tsx b/src/components/TerrainBlock.tsx new file mode 100644 index 00000000..ba19a3bf --- /dev/null +++ b/src/components/TerrainBlock.tsx @@ -0,0 +1,240 @@ +import { Suspense, useCallback, useMemo } from "react"; +import { useQuery } from "@tanstack/react-query"; +import { + DataTexture, + RedFormat, + FloatType, + NoColorSpace, + NearestFilter, + ClampToEdgeWrapping, + UnsignedByteType, + PlaneGeometry, +} from "three"; +import { useTexture } from "@react-three/drei"; +import { uint16ToFloat32 } from "../arrayUtils"; +import { loadTerrain, terrainTextureToUrl } from "../loaders"; +import { + ConsoleObject, + getPosition, + getProperty, + getRotation, + getScale, +} from "../mission"; +import { + setupColor, + setupMask, + updateTerrainTextureShader, +} from "../textureUtils"; + +/** + * Load a .ter file, used for terrain heightmap and texture info. + */ +function useTerrain(terrainFile: string) { + return useQuery({ + queryKey: ["terrain", terrainFile], + queryFn: () => loadTerrain(terrainFile), + }); +} + +function BlendedTerrainTextures({ + displacementMap, + visibilityMask, + textureNames, + alphaMaps, +}: { + displacementMap: DataTexture; + visibilityMask: DataTexture; + textureNames: string[]; + alphaMaps: Uint8Array[]; +}) { + const baseTextures = useTexture( + textureNames.map((name) => terrainTextureToUrl(name)), + (textures) => { + textures.forEach((tex) => setupColor(tex)); + } + ); + + const alphaTextures = useMemo( + () => alphaMaps.map((data) => setupMask(data)), + [alphaMaps] + ); + + const tiling = useMemo( + () => ({ + 0: 32, + 1: 32, + 2: 32, + 3: 32, + 4: 32, + 5: 32, + }), + [] + ); + + const onBeforeCompile = useCallback( + (shader) => { + updateTerrainTextureShader({ + shader, + baseTextures, + alphaTextures, + visibilityMask, + tiling, + }); + }, + [baseTextures, alphaTextures, visibilityMask, tiling] + ); + + return ( + + ); +} + +function TerrainMaterial({ + heightMap, + textureNames, + alphaMaps, + emptySquares, +}: { + heightMap: Uint16Array; + emptySquares: number[]; + textureNames: string[]; + alphaMaps: Uint8Array[]; +}) { + const displacementMap = useMemo(() => { + const f32HeightMap = uint16ToFloat32(heightMap); + const displacementMap = new DataTexture( + f32HeightMap, + 256, + 256, + RedFormat, + FloatType + ); + displacementMap.colorSpace = NoColorSpace; + displacementMap.generateMipmaps = false; + displacementMap.needsUpdate = true; + return displacementMap; + }, [heightMap]); + + const visibilityMask: DataTexture | null = useMemo(() => { + if (!emptySquares.length) { + return null; + } + + const terrainSize = 256; + + // Create a mask texture (1 = visible, 0 = invisible) + const maskData = new Uint8Array(terrainSize * terrainSize); + maskData.fill(255); // Start with everything visible + + for (const squareId of emptySquares) { + // The squareId encodes position and count: + // Bits 0-7: X position (starting position) + // Bits 8-15: Y position + // Bits 16+: Count (number of consecutive horizontal squares) + const x = squareId & 0xff; + const y = (squareId >> 8) & 0xff; + const count = squareId >> 16; + + for (let i = 0; i < count; i++) { + const px = x + i; + const py = y; + const index = py * terrainSize + px; + if (index >= 0 && index < maskData.length) { + maskData[index] = 0; + } + } + } + + const visibilityMask = new DataTexture( + maskData, + terrainSize, + terrainSize, + RedFormat, + UnsignedByteType + ); + visibilityMask.colorSpace = NoColorSpace; + visibilityMask.wrapS = visibilityMask.wrapT = ClampToEdgeWrapping; + visibilityMask.magFilter = NearestFilter; + visibilityMask.minFilter = NearestFilter; + visibilityMask.needsUpdate = true; + + return visibilityMask; + }, [emptySquares]); + + return ( + + } + > + + + ); +} + +export function TerrainBlock({ object }: { object: ConsoleObject }) { + const terrainFile: string = getProperty(object, "terrainFile").value; + + const emptySquares: number[] = useMemo(() => { + const emptySquaresString: string | undefined = getProperty( + object, + "emptySquares" + )?.value; + + return emptySquaresString + ? emptySquaresString.split(" ").map((s) => parseInt(s, 10)) + : []; + }, [object]); + + const position = useMemo(() => getPosition(object), [object]); + const scale = useMemo(() => getScale(object), [object]); + const q = useMemo(() => getRotation(object), [object]); + + const planeGeometry = useMemo(() => { + const geometry = new PlaneGeometry(2048, 2048, 256, 256); + geometry.rotateX(-Math.PI / 2); + geometry.rotateY(-Math.PI / 2); + return geometry; + }, []); + + const { data: terrain } = useTerrain(terrainFile); + + return ( + + {terrain ? ( + + ) : null} + + ); +} diff --git a/src/components/Turret.tsx b/src/components/Turret.tsx new file mode 100644 index 00000000..feb8b2b9 --- /dev/null +++ b/src/components/Turret.tsx @@ -0,0 +1,60 @@ +import { Suspense, useMemo } from "react"; +import { ErrorBoundary } from "react-error-boundary"; +import { + ConsoleObject, + getPosition, + getProperty, + getRotation, + getScale, +} from "../mission"; +import { ShapeModel, ShapePlaceholder } from "./GenericShape"; + +const dataBlockToShapeName = { + SentryTurret: "turret_sentry.dts", + TurretBaseLarge: "turret_base_large.dts", +}; + +let _caseInsensitiveLookup: Record; + +function getDataBlockShape(dataBlock: string) { + if (!_caseInsensitiveLookup) { + _caseInsensitiveLookup = Object.fromEntries( + Object.entries(dataBlockToShapeName).map(([key, value]) => { + return [key.toLowerCase(), value]; + }) + ); + } + return _caseInsensitiveLookup[dataBlock.toLowerCase()]; +} + +export function Turret({ object }: { object: ConsoleObject }) { + const dataBlock = getProperty(object, "dataBlock").value; + + const [z, y, x] = useMemo(() => getPosition(object), [object]); + const [scaleX, scaleY, scaleZ] = useMemo(() => getScale(object), [object]); + const q = useMemo(() => getRotation(object, true), [object]); + + const shapeName = getDataBlockShape(dataBlock); + + if (!shapeName) { + console.error(` missing shape for dataBlock: ${dataBlock}`); + } + + return ( + + {shapeName ? ( + }> + }> + + + + ) : ( + + )} + + ); +} diff --git a/src/components/WaterBlock.tsx b/src/components/WaterBlock.tsx new file mode 100644 index 00000000..d52fa111 --- /dev/null +++ b/src/components/WaterBlock.tsx @@ -0,0 +1,43 @@ +import { Suspense, useMemo } from "react"; +import { useTexture } from "@react-three/drei"; +import { textureToUrl } from "../loaders"; +import { + ConsoleObject, + getPosition, + getProperty, + getRotation, + getScale, +} from "../mission"; +import { setupColor } from "../textureUtils"; + +export function WaterMaterial({ surfaceTexture }: { surfaceTexture: string }) { + const url = textureToUrl(surfaceTexture); + const texture = useTexture(url, (texture) => setupColor(texture, [8, 8])); + + return ; +} + +export function WaterBlock({ object }: { object: ConsoleObject }) { + const [z, y, x] = useMemo(() => getPosition(object), [object]); + const [scaleZ, scaleY, scaleX] = useMemo(() => getScale(object), [object]); + const q = useMemo(() => getRotation(object, true), [object]); + + const surfaceTexture = + getProperty(object, "surfaceTexture")?.value ?? "liquidTiles/BlueWater"; + + return ( + + + + } + > + + + + ); +} diff --git a/src/components/renderObject.tsx b/src/components/renderObject.tsx new file mode 100644 index 00000000..05556f6b --- /dev/null +++ b/src/components/renderObject.tsx @@ -0,0 +1,29 @@ +import { ConsoleObject } from "../mission"; +import { TerrainBlock } from "./TerrainBlock"; +import { WaterBlock } from "./WaterBlock"; +import { SimGroup } from "./SimGroup"; +import { InteriorInstance } from "./InteriorInstance"; +import { Sky } from "./Sky"; +import { Sun } from "./Sun"; +import { TSStatic } from "./TSStatic"; +import { StaticShape } from "./StaticShape"; +import { Item } from "./Item"; +import { Turret } from "./Turret"; + +const componentMap = { + InteriorInstance, + Item, + SimGroup, + Sky, + StaticShape, + Sun, + TerrainBlock, + TSStatic, + Turret, + WaterBlock, +}; + +export function renderObject(object: ConsoleObject, key: string | number) { + const Component = componentMap[object.className]; + return Component ? : null; +} diff --git a/src/loaders.ts b/src/loaders.ts new file mode 100644 index 00000000..8a06101f --- /dev/null +++ b/src/loaders.ts @@ -0,0 +1,80 @@ +import { getActualResourcePath, getSource } from "./manifest"; +import { parseMissionScript } from "./mission"; +import { parseTerrainBuffer } from "./terrain"; + +export const BASE_URL = "/t2-mapper"; +export const RESOURCE_ROOT_URL = `${BASE_URL}/base/`; + +export function getUrlForPath(resourcePath: string, fallbackUrl?: string) { + resourcePath = getActualResourcePath(resourcePath); + let sourcePath: string; + try { + sourcePath = getSource(resourcePath); + } catch (err) { + if (fallbackUrl) { + // console.error(err); + return fallbackUrl; + } else { + throw err; + } + } + if (!sourcePath) { + return `${RESOURCE_ROOT_URL}${resourcePath}`; + } else { + return `${RESOURCE_ROOT_URL}@vl2/${sourcePath}/${resourcePath}`; + } +} + +export function interiorToUrl(name: string) { + const difUrl = getUrlForPath(`interiors/${name}`); + return difUrl.replace(/\.dif$/i, ".gltf"); +} + +export function shapeToUrl(name: string) { + const difUrl = getUrlForPath(`shapes/${name}`); + return difUrl.replace(/\.dts$/i, ".glb"); +} + +export function terrainTextureToUrl(name: string) { + name = name.replace(/^terrain\./, ""); + return getUrlForPath(`textures/terrain/${name}.png`, `${BASE_URL}/black.png`); +} + +export function interiorTextureToUrl(name: string, fallbackUrl?: string) { + name = name.replace(/\.\d+$/, ""); + return getUrlForPath(`textures/${name}.png`, fallbackUrl); +} + +export function shapeTextureToUrl(name: string, fallbackUrl?: string) { + name = name.replace(/\.\d+$/, ""); + return getUrlForPath(`textures/skins/${name}.png`, fallbackUrl); +} + +export function textureToUrl(name: string) { + try { + return getUrlForPath(`textures/${name}.png`); + } catch (err) { + return `${BASE_URL}/black.png`; + } +} + +export async function loadDetailMapList(name: string) { + const url = getUrlForPath(`textures/${name}`); + const res = await fetch(url); + const text = await res.text(); + return text + .split(/(?:\r\n|\n|\r)/) + .map((line) => `textures/${line.trim().replace(/\.png$/i, "")}.png`); +} + +export async function loadMission(name: string) { + const res = await fetch(getUrlForPath(`missions/${name}.mis`)); + const missionScript = await res.text(); + return parseMissionScript(missionScript); +} + +export async function loadTerrain(fileName: string) { + const res = await fetch(getUrlForPath(`terrains/${fileName}`)); + const terrainBuffer = await res.arrayBuffer(); + return parseTerrainBuffer(terrainBuffer); +} diff --git a/src/manifest.ts b/src/manifest.ts index a70fbbb7..d3e7a631 100644 --- a/src/manifest.ts +++ b/src/manifest.ts @@ -15,12 +15,30 @@ export function getActualResourcePath(resourcePath: string) { } const resourcePaths = getResourceList(); const lowerCased = resourcePath.toLowerCase(); + + // First, try exact case-insensitive match const foundLowerCase = resourcePaths.find( (s) => s.toLowerCase() === lowerCased ); if (foundLowerCase) { return foundLowerCase; } + + // For paths with numeric suffixes (e.g., "generator0.png"), strip the number and try again + // e.g., "generator0.png" -> "generator.png" + const pathWithoutNumber = resourcePath.replace(/\d+(\.(png))$/i, "$1"); + const lowerCasedWithoutNumber = pathWithoutNumber.toLowerCase(); + + if (pathWithoutNumber !== resourcePath) { + // If we stripped a number, try to find the version without it + const foundWithoutNumber = resourcePaths.find( + (s) => s.toLowerCase() === lowerCasedWithoutNumber + ); + if (foundWithoutNumber) { + return foundWithoutNumber; + } + } + const isTexture = resourcePath.startsWith("textures/"); if (isTexture) { const foundNested = resourcePaths.find( diff --git a/src/meshUtils.ts b/src/meshUtils.ts new file mode 100644 index 00000000..ea4109ab --- /dev/null +++ b/src/meshUtils.ts @@ -0,0 +1,81 @@ +/** + * Extract hull bone indices from a skeleton + * @param skeleton - The Three.js skeleton to scan + * @returns Set of bone indices for bones matching the hull pattern (starts with "Hulk") + */ +export function getHullBoneIndices(skeleton: any): Set { + const hullBoneIndices = new Set(); + + skeleton.bones.forEach((bone: any, index: number) => { + if (bone.name.match(/^Hulk/i)) { + hullBoneIndices.add(index); + } + }); + + return hullBoneIndices; +} + +/** + * Filter geometry by removing faces influenced by hull bones + * @param geometry - The Three.js geometry to filter + * @param hullBoneIndices - Set of bone indices that represent hull (collision) geometry + * @returns Filtered geometry with hull-influenced faces removed + */ +export function filterGeometryByVertexGroups( + geometry: any, + hullBoneIndices: Set +): any { + // If no hull bones or no skinning data, return original geometry + if (hullBoneIndices.size === 0 || !geometry.attributes.skinIndex) { + return geometry; + } + + const skinIndex = geometry.attributes.skinIndex; + const skinWeight = geometry.attributes.skinWeight; + const index = geometry.index; + + // Track which vertices are influenced by hull bones + const vertexHasHullInfluence = new Array(skinIndex.count).fill(false); + + // Check each vertex's bone influences + for (let i = 0; i < skinIndex.count; i++) { + for (let j = 0; j < 4; j++) { + const boneIndex = skinIndex.array[i * 4 + j]; + const weight = skinWeight.array[i * 4 + j]; + + // If this vertex has significant weight to a hull bone, mark it + if (weight > 0.01 && hullBoneIndices.has(boneIndex)) { + vertexHasHullInfluence[i] = true; + break; + } + } + } + + // Build new index array excluding faces that use hull-influenced vertices + if (index) { + const newIndices: number[] = []; + const indexArray = index.array; + + for (let i = 0; i < indexArray.length; i += 3) { + const i0 = indexArray[i]; + const i1 = indexArray[i + 1]; + const i2 = indexArray[i + 2]; + + // Only keep face if all vertices don't have hull influence + if ( + !vertexHasHullInfluence[i0] && + !vertexHasHullInfluence[i1] && + !vertexHasHullInfluence[i2] + ) { + newIndices.push(i0, i1, i2); + } + } + + // Create new geometry with filtered indices + const filteredGeometry = geometry.clone(); + filteredGeometry.setIndex(newIndices); + return filteredGeometry; + } + + return geometry; +} diff --git a/src/mission.ts b/src/mission.ts index 92ddeae9..ed2dd39f 100644 --- a/src/mission.ts +++ b/src/mission.ts @@ -1,3 +1,4 @@ +import { Quaternion, Vector3 } from "three"; import parser from "@/generated/mission.cjs"; const definitionComment = /^ (DisplayName|MissionTypes) = (.+)$/; @@ -175,7 +176,8 @@ export function parseMissionScript(script) { }; } -type Mission = ReturnType; +export type Mission = ReturnType; +export type ConsoleObject = Mission["objects"][number]; export function* iterObjects(objectList) { for (const obj of objectList) { @@ -186,18 +188,62 @@ export function* iterObjects(objectList) { } } -export function getTerrainFile(mission: Mission) { - let terrainBlock; +export function getTerrainBlock(mission: Mission): ConsoleObject { for (const obj of iterObjects(mission.objects)) { if (obj.className === "TerrainBlock") { - terrainBlock = obj; - break; + return obj; } } - if (!terrainBlock) { - throw new Error("Error!"); - } + throw new Error("No TerrainBlock found!"); +} + +export function getTerrainFile(mission: Mission) { + const terrainBlock = getTerrainBlock(mission); return terrainBlock.properties.find( (prop) => prop.target.name === "terrainFile" ).value; } + +export function getProperty(obj: ConsoleObject, name: string) { + const property = obj.properties.find((p) => p.target.name === name); + // console.log({ name, property }); + return property; +} + +export function getPosition(obj: ConsoleObject): [number, number, number] { + const position = getProperty(obj, "position")?.value ?? "0 0 0"; + const [x, z, y] = position.split(" ").map((s) => parseFloat(s)); + return [x, y, z]; +} + +export function getScale(obj: ConsoleObject): [number, number, number] { + const scale = getProperty(obj, "scale")?.value ?? "1 1 1"; + const [scaleX, scaleZ, scaleY] = scale.split(" ").map((s) => parseFloat(s)); + return [scaleX, scaleY, scaleZ]; +} + +export function getRotation(obj: ConsoleObject, isInterior = false) { + const rotation = getProperty(obj, "rotation")?.value ?? "1 0 0 0"; + const [ax, az, ay, angle] = rotation.split(" ").map((s) => parseFloat(s)); + + if (isInterior) { + // For interiors: Apply coordinate system transformation + // 1. Convert rotation axis from source coords (ax, az, ay) to Three.js coords + // 2. Apply -90 Y rotation to align coordinate systems + const sourceRotation = new Quaternion().setFromAxisAngle( + new Vector3(az, ay, ax), + -angle * (Math.PI / 180) + ); + const coordSystemFix = new Quaternion().setFromAxisAngle( + new Vector3(0, 1, 0), + Math.PI / 2 + ); + return coordSystemFix.multiply(sourceRotation); + } else { + // For other objects (terrain, etc) + return new Quaternion().setFromAxisAngle( + new Vector3(ax, ay, -az), + angle * (Math.PI / 180) + ); + } +} diff --git a/src/shaderMaterials.ts b/src/shaderMaterials.ts new file mode 100644 index 00000000..552caf93 --- /dev/null +++ b/src/shaderMaterials.ts @@ -0,0 +1,57 @@ +import { + MeshStandardMaterial, + Texture, + RepeatWrapping, + LinearFilter, + LinearMipmapLinearFilter, + SRGBColorSpace, +} from "three"; + +// Shared shader modification function to avoid duplication +const alphaAsRoughnessShaderModifier = (shader: any) => { + // Modify fragment shader to extract alpha channel as roughness after map is sampled + // We need to intercept after diffuseColor is set from the map + shader.fragmentShader = shader.fragmentShader.replace( + "#include ", + ` + #include + // Override roughness with map alpha channel if map exists + #ifdef USE_MAP + roughnessFactor = texture2D(map, vMapUv).a * 1; + #endif + ` + ); +}; + +/** + * Configures a texture for use with alpha-as-roughness materials + * @param texture - The texture to configure + */ +export function setupAlphaAsRoughnessTexture(texture: Texture) { + texture.wrapS = texture.wrapT = RepeatWrapping; + texture.colorSpace = SRGBColorSpace; + texture.flipY = false; + texture.anisotropy = 16; + texture.generateMipmaps = true; + texture.minFilter = LinearMipmapLinearFilter; + texture.magFilter = LinearFilter; + texture.needsUpdate = true; +} + +/** + * Creates a reusable shader-enhanced material that treats alpha as roughness + * The same material instance can be used with different textures by setting the `map` property + * @returns A pre-configured MeshStandardMaterial with the shader modifier attached + */ +export function createAlphaAsRoughnessMaterial() { + const material = new MeshStandardMaterial({ + side: 2, // DoubleSide + metalness: 0.0, + roughness: 1.0, + }); + + // Attach shader modifier (will be applied when shader is compiled) + material.onBeforeCompile = alphaAsRoughnessShaderModifier; + + return material; +} diff --git a/src/textureUtils.ts b/src/textureUtils.ts new file mode 100644 index 00000000..3ea076d3 --- /dev/null +++ b/src/textureUtils.ts @@ -0,0 +1,170 @@ +import { + DataTexture, + LinearFilter, + LinearMipmapLinearFilter, + NoColorSpace, + RedFormat, + RepeatWrapping, + SRGBColorSpace, + UnsignedByteType, +} from "three"; + +export function setupColor(tex, repeat = [1, 1]) { + tex.wrapS = tex.wrapT = RepeatWrapping; + tex.colorSpace = SRGBColorSpace; + tex.repeat.set(...repeat); + tex.flipY = false; // DDS/DIF textures are already flipped + tex.anisotropy = 16; + tex.generateMipmaps = true; + tex.minFilter = LinearMipmapLinearFilter; + tex.magFilter = LinearFilter; + + tex.needsUpdate = true; + + return tex; +} + +export function setupMask(data) { + const tex = new DataTexture( + data, + 256, + 256, + RedFormat, // 1 channel + UnsignedByteType // 8-bit + ); + + // Masks should stay linear + tex.colorSpace = NoColorSpace; + + // Set tiling / sampling. For NPOT sizes, disable mips or use power-of-two. + tex.wrapS = tex.wrapT = RepeatWrapping; + tex.generateMipmaps = false; // if width/height are not powers of two + tex.minFilter = LinearFilter; // avoid mips if generateMipmaps=false + tex.magFilter = LinearFilter; + + tex.needsUpdate = true; + + return tex; +} + +export function updateTerrainTextureShader({ + shader, + baseTextures, + alphaTextures, + visibilityMask, + tiling, +}) { + const layerCount = baseTextures.length; + + baseTextures.forEach((tex, i) => { + shader.uniforms[`albedo${i}`] = { value: tex }; + }); + + alphaTextures.forEach((tex, i) => { + if (i > 0) { + shader.uniforms[`mask${i}`] = { value: tex }; + } + }); + + // Add visibility mask uniform if we have empty squares + if (visibilityMask) { + shader.uniforms.visibilityMask = { value: visibilityMask }; + } + + // Add per-texture tiling uniforms + baseTextures.forEach((tex, i) => { + shader.uniforms[`tiling${i}`] = { + value: tiling[i] ?? 32, + }; + }); + + // Declare our uniforms at the top of the fragment shader + shader.fragmentShader = + ` +uniform sampler2D albedo0; +uniform sampler2D albedo1; +uniform sampler2D albedo2; +uniform sampler2D albedo3; +uniform sampler2D albedo4; +uniform sampler2D albedo5; +uniform sampler2D mask1; +uniform sampler2D mask2; +uniform sampler2D mask3; +uniform sampler2D mask4; +uniform sampler2D mask5; +uniform float tiling0; +uniform float tiling1; +uniform float tiling2; +uniform float tiling3; +uniform float tiling4; +uniform float tiling5; +${visibilityMask ? "uniform sampler2D visibilityMask;" : ""} +` + shader.fragmentShader; + + if (visibilityMask) { + const clippingPlaceholder = "#include "; + shader.fragmentShader = shader.fragmentShader.replace( + clippingPlaceholder, + `${clippingPlaceholder} + // Early discard for invisible areas (before fog/lighting) + float visibility = texture2D(visibilityMask, vMapUv).r; + if (visibility < 0.5) { + discard; + } + ` + ); + } + + // Replace the default map sampling block with our layered blend. + // We rely on vMapUv provided by USE_MAP. + shader.fragmentShader = shader.fragmentShader.replace( + "#include ", + ` + // Sample base albedo layers (sRGB textures auto-decoded to linear) + vec2 baseUv = vMapUv; + vec3 c0 = texture2D(albedo0, baseUv * vec2(tiling0)).rgb; + ${ + layerCount > 1 + ? `vec3 c1 = texture2D(albedo1, baseUv * vec2(tiling1)).rgb;` + : "" + } + ${ + layerCount > 2 + ? `vec3 c2 = texture2D(albedo2, baseUv * vec2(tiling2)).rgb;` + : "" + } + ${ + layerCount > 3 + ? `vec3 c3 = texture2D(albedo3, baseUv * vec2(tiling3)).rgb;` + : "" + } + ${ + layerCount > 4 + ? `vec3 c4 = texture2D(albedo4, baseUv * vec2(tiling4)).rgb;` + : "" + } + ${ + layerCount > 5 + ? `vec3 c5 = texture2D(albedo5, baseUv * vec2(tiling5)).rgb;` + : "" + } + + // Sample linear masks (use R channel) + float a1 = texture2D(mask1, baseUv).r; + ${layerCount > 1 ? `float a2 = texture2D(mask2, baseUv).r;` : ""} + ${layerCount > 2 ? `float a3 = texture2D(mask3, baseUv).r;` : ""} + ${layerCount > 3 ? `float a4 = texture2D(mask4, baseUv).r;` : ""} + ${layerCount > 4 ? `float a5 = texture2D(mask5, baseUv).r;` : ""} + + // Bottom-up compositing: each mask tells how much the higher layer replaces lower + ${layerCount > 1 ? `vec3 blended = mix(c0, c1, clamp(a1, 0.0, 1.0));` : ""} + ${layerCount > 2 ? `blended = mix(blended, c2, clamp(a2, 0.0, 1.0));` : ""} + ${layerCount > 3 ? `blended = mix(blended, c3, clamp(a3, 0.0, 1.0));` : ""} + ${layerCount > 4 ? `blended = mix(blended, c4, clamp(a4, 0.0, 1.0));` : ""} + ${layerCount > 5 ? `blended = mix(blended, c5, clamp(a5, 0.0, 1.0));` : ""} + + // Assign to diffuseColor before lighting + diffuseColor.rgb = ${layerCount > 1 ? "blended" : "c0"}; +` + ); +}