mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-01-19 20:25:01 +00:00
Merge pull request #5 from exogen/chore/react-three-fiber
Migrate to react-three-fiber
This commit is contained in:
commit
5830f97aa6
6
.gitignore
vendored
6
.gitignore
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ Click inside the map preview area to capture the mouse.
|
|||
| <kbd>Space</kbd> | Up |
|
||||
| <kbd>Shift</kbd> | Down |
|
||||
| <kbd>Esc</kbd> | Release mouse |
|
||||
| △ Scroll/mouse wheel up | Increase speed |
|
||||
| ▽ Scroll/mouse wheel down | Decrease speed |
|
||||
|
||||
|
||||
## Development
|
||||
|
|
|
|||
769
app/page.tsx
769
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<HTMLCanvasElement>(null);
|
||||
const [missionName, setMissionName] = useState("TWL2_WoodyMyrk");
|
||||
const [fogEnabled, setFogEnabled] = useState(true);
|
||||
const threeContext = useRef<Record<string, any>>({});
|
||||
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 <clipping_planes_fragment>';
|
||||
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 <map_fragment>",
|
||||
`
|
||||
// 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 (
|
||||
<main>
|
||||
<canvas ref={canvasRef} id="canvas" />
|
||||
<div id="controls">
|
||||
<select
|
||||
id="missionList"
|
||||
value={missionName}
|
||||
onChange={(e) => setMissionName(e.target.value)}
|
||||
>
|
||||
{missions.map((missionName) => (
|
||||
<option key={missionName}>{missionName}</option>
|
||||
))}
|
||||
</select>
|
||||
<div className="CheckboxField">
|
||||
<input
|
||||
id="fogInput"
|
||||
type="checkbox"
|
||||
checked={fogEnabled}
|
||||
onChange={(event) => {
|
||||
setFogEnabled(event.target.checked);
|
||||
}}
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<main>
|
||||
<SettingsProvider>
|
||||
<Canvas shadows>
|
||||
<ObserverControls />
|
||||
<Mission key={missionName} name={missionName} />
|
||||
<ObserverCamera />
|
||||
<EffectComposer>
|
||||
<N8AO intensity={3} aoRadius={3} quality="performance" />
|
||||
</EffectComposer>
|
||||
</Canvas>
|
||||
<InspectorControls
|
||||
missionName={missionName}
|
||||
onChangeMission={setMissionName}
|
||||
/>
|
||||
<label htmlFor="fogInput">Fog?</label>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</SettingsProvider>
|
||||
</main>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 444 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 447 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 461 KiB |
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2flag.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2flag.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2heavy_male.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2heavy_male.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_female.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_female.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_male.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2light_male.glb
Normal file
Binary file not shown.
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_male.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2medium_male.glb
Normal file
Binary file not shown.
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_disc.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/TR2weapon_disc.glb
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_1.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_1.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_2.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_2.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_3.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_3.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_4.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/billboard_4.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_back.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_back.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_panel.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_panel.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_side.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_side.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_top.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/goal_top.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_back.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_back.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_side.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_side.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_top.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/gold_goal_top.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/golden_pole.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/golden_pole.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/silver_pole.glb
Normal file
BIN
docs/base/@vl2/TR2final105-client.vl2/shapes/silver_pole.glb
Normal file
Binary file not shown.
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -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] = "<color:CCCC00>"; // Gold
|
||||
$TR2::teamColor[2] = "<color:BBBBBB>"; // Silver
|
||||
|
||||
function initializeBonuses()
|
||||
{
|
||||
// Flag bonus
|
||||
if (!isObject(FlagBonus))
|
||||
{
|
||||
new ScriptObject(FlagBonus)
|
||||
{
|
||||
class = FlagBonus;
|
||||
superclass = Bonus;
|
||||
history = FlagBonusHistory;
|
||||
};
|
||||
FlagBonus.addCategory(Prefix, $PrefixList);
|
||||
FlagBonus.addCategory(Noun, $NounList);
|
||||
FlagBonus.addCategory(Qualifier, $QualifierList);
|
||||
FlagBonus.addCategory(Description, $DescriptionList);
|
||||
//MissionCleanup.add(FlagBonus);
|
||||
}
|
||||
|
||||
// Weapon kill bonus
|
||||
if (!isObject(WeaponBonus))
|
||||
{
|
||||
new ScriptObject(WeaponBonus)
|
||||
{
|
||||
class = WeaponBonus;
|
||||
superclass = Bonus;
|
||||
instant = true;
|
||||
history = "";
|
||||
};
|
||||
WeaponBonus.addCategory(HeightBonus, $WeaponHeightBonusList);
|
||||
WeaponBonus.addCategory(SpeedBonus, $WeaponSpeedBonusList);
|
||||
WeaponBonus.addCategory(WeaponTypeBonus, $WeaponTypeBonusList);
|
||||
//MissionCleanup.add(WeaponBonus);
|
||||
}
|
||||
|
||||
// Go-go Gadget Bonus
|
||||
if (!isObject(G4Bonus))
|
||||
{
|
||||
new ScriptObject(G4Bonus)
|
||||
{
|
||||
class = G4Bonus;
|
||||
superclass = Bonus;
|
||||
history = "";
|
||||
};
|
||||
G4Bonus.addCategory(Noun, $NounList);
|
||||
//MissionCleanup.add(G4Bonus);
|
||||
}
|
||||
|
||||
// Midair Bonus
|
||||
if (!isObject(MidairBonus))
|
||||
{
|
||||
new ScriptObject(MidairBonus)
|
||||
{
|
||||
class = MidairBonus;
|
||||
superclass = Bonus;
|
||||
history = "";
|
||||
};
|
||||
//MissionCleanup.add(MidairBonus);
|
||||
}
|
||||
|
||||
// Collision Bonus
|
||||
if (!isObject(CollisionBonus))
|
||||
{
|
||||
new ScriptObject(CollisionBonus)
|
||||
{
|
||||
class = CollisionBonus;
|
||||
superclass = Bonus;
|
||||
history = "";
|
||||
};
|
||||
//MissionCleanup.add(CollisionBonus);
|
||||
}
|
||||
|
||||
// Creativity Bonus
|
||||
if (!isObject(CreativityBonus))
|
||||
{
|
||||
new ScriptObject(CreativityBonus)
|
||||
{
|
||||
class = CreativityBonus;
|
||||
superclass = Bonus;
|
||||
instant = true;
|
||||
lastVariance = 0;
|
||||
lastVarianceLevel = 0;
|
||||
varianceLevels = 4;
|
||||
varianceThreshold[0] = 0;
|
||||
varianceThreshold[1] = 17;
|
||||
varianceThreshold[2] = 34;
|
||||
varianceThreshold[3] = 51;
|
||||
varianceValue[0] = 0;
|
||||
varianceValue[1] = 25;
|
||||
varianceValue[2] = 50;
|
||||
varianceValue[3] = 75;
|
||||
varianceSound[0] = "";
|
||||
varianceSound[1] = Creativity1Sound;
|
||||
varianceSound[2] = Creativity2Sound;
|
||||
varianceSound[3] = Creativity3Sound;
|
||||
history = "";
|
||||
};
|
||||
//MissionCleanup.add(CreativityBonus);
|
||||
}
|
||||
}
|
||||
|
||||
function Bonus::addCategory(%this, %newCategory, %data)
|
||||
{
|
||||
if (%this.numCategories $= "")
|
||||
%this.numCategories = 0;
|
||||
|
||||
// A category can be used in multiple bonuses
|
||||
%this.category[%this.numCategories] = %newCategory;
|
||||
%this.category[%this.numCategories].data = %data;
|
||||
%this.numCategories++;
|
||||
}
|
||||
|
||||
function Bonus::evaluate(%this, %obj1, %obj2, %obj3, %obj4, %obj5)
|
||||
{
|
||||
// This is added to the bonus history and eventually deleted
|
||||
%newBonusData = new ScriptObject()
|
||||
{
|
||||
class = BonusData;
|
||||
};
|
||||
MissionCleanup.add(%newBonusData);
|
||||
%newBonusData.initialize(%this);
|
||||
|
||||
// Construct the bonus by iterating through categories
|
||||
for (%i=0; %i<%this.numCategories; %i++)
|
||||
{
|
||||
%newCategoryData = %this.category[%i].evaluate(%obj1, %obj2, %obj3, %obj4);
|
||||
if (%newCategoryData > 0)
|
||||
{
|
||||
%newBonusData.addCategoryData(%newCategoryData, %i);
|
||||
|
||||
// Perform audiovisual effects
|
||||
%delay = %this.category[%i].soundDelay;
|
||||
%this.category[%i].schedule(%delay, "performEffects", %newCategoryData, %obj2);
|
||||
}
|
||||
}
|
||||
|
||||
// Award the bonus
|
||||
if (%newBonusData.getValue() != 0)
|
||||
%this.award(%newBonusData, %obj1, %obj2, %obj3);
|
||||
else
|
||||
%newBonusData.delete();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// BonusData
|
||||
// This class stores an instance of a dynamically constructed bonus.
|
||||
function BonusData::initialize(%this, %bonus)
|
||||
{
|
||||
%this.bonus = %bonus;
|
||||
%this.time = GetSimTime();
|
||||
|
||||
%this.maxCategoryDatas = %bonus.numCategories;
|
||||
for (%i=0; %i < %this.numCategoryDatas; %i++)
|
||||
%this.categoryData[%i] = "";
|
||||
|
||||
%this.totalValue = 0;
|
||||
}
|
||||
|
||||
function BonusData::addCategoryData(%this, %newCategoryData, %index)
|
||||
{
|
||||
// This little trick allows a BonusData instance to mirror its
|
||||
// Bonus type...it allows a BonusData to have empty component
|
||||
// slots. Empty slots are needed so that successive Bonuses "line up"
|
||||
// for calculating variance. There's likely a better way to do this.
|
||||
%this.categoryData[%index] = %newCategoryData;
|
||||
%this.totalValue += %newCategoryData.value;
|
||||
}
|
||||
|
||||
function BonusData::getString(%this)
|
||||
{
|
||||
%str = %this.categoryData[0].text;
|
||||
|
||||
for (%i=1; %i < %this.maxCategoryDatas; %i++)
|
||||
if (%this.categoryData[%i] !$= "")
|
||||
%str = %str SPC %this.categoryData[%i].text;
|
||||
|
||||
return %str;
|
||||
}
|
||||
|
||||
function BonusData::getValue(%this)
|
||||
{
|
||||
return %this.totalValue;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Bonus history and variance
|
||||
new ScriptObject(FlagBonusHistory)
|
||||
{
|
||||
class = FlagBonusHistory;
|
||||
superclass = BonusHistory;
|
||||
bonusType = FlagBonus;
|
||||
numBonuses = 0;
|
||||
variance = 0;
|
||||
};
|
||||
|
||||
function BonusHistory::initialize(%this)
|
||||
{
|
||||
for (%i=0; %i<%this.numBonuses; %i++)
|
||||
%this.bonus[%i].delete();
|
||||
|
||||
%this.numBonuses = 0;
|
||||
%this.variance = 0;
|
||||
}
|
||||
|
||||
function BonusHistory::add(%this, %newBonus)
|
||||
{
|
||||
%this.bonus[%this.numBonuses] = %newBonus;
|
||||
%this.numBonuses++;
|
||||
|
||||
// Calculate the new variance
|
||||
return %this.calculateIncrementalVariance();
|
||||
}
|
||||
|
||||
// An incremental way of calculating the creativity within a bonus
|
||||
// history as new bonuses are added (incremental approach used for efficiency)
|
||||
function BonusHistory::calculateIncrementalVariance(%this)
|
||||
{
|
||||
if (%this.numBonuses <= 1)
|
||||
return 0;
|
||||
|
||||
%i = %this.numBonuses - 1;
|
||||
for(%j=0; %j<%this.bonus[%i].maxCategoryDatas; %j++)
|
||||
{
|
||||
%categoryData = %this.bonus[%i].categoryData[%j];
|
||||
// Don't count empty component slots
|
||||
if(%categoryData !$= "")
|
||||
for(%k=0; %k<%categoryData.numParameters; %k++)
|
||||
%this.variance += mAbs(%categoryData.parameter[%k] -
|
||||
%this.bonus[%i-1].categoryData[%j].parameter[%k]);
|
||||
}
|
||||
|
||||
return %this.variance;
|
||||
}
|
||||
|
||||
|
||||
// An instantaneous way of calculating the creativity within a bonus
|
||||
// history (inefficient and not intended to be used; for informational
|
||||
// and debugging purposes only)
|
||||
function BonusHistory::calculateVariance(%this)
|
||||
{
|
||||
if (%this.numBonuses <= 1)
|
||||
return 0;
|
||||
|
||||
%this.variance = 0;
|
||||
|
||||
for(%i=1; %i<%this.numBonuses; %i++)
|
||||
for(%j=0; %j<%this.bonus[%i].maxCategoryDatas; %j++)
|
||||
{
|
||||
%categoryData = %this.bonus[%i].categoryData[%j];
|
||||
if (%categoryData !$= "")
|
||||
for(%k=0; %k<%categoryData.numParameters; %k++)
|
||||
%this.variance += abs(%categoryData.parameter[%k] -
|
||||
%this.bonus[%i-1].categoryData[%j].parameter[%k]);
|
||||
}
|
||||
|
||||
return %this.variance;
|
||||
}
|
||||
|
||||
function BonusHistory::getVariance(%this)
|
||||
{
|
||||
return %this.variance;
|
||||
}
|
||||
|
||||
function BonusHistory::getRecentRecipient(%this, %index)
|
||||
{
|
||||
if (%index $= "")
|
||||
%index = 0;
|
||||
|
||||
return %this.bonus[%this.numBonuses-1-%index].recipient;
|
||||
}
|
||||
|
||||
function Bonus::award(%this, %bonusData, %player1, %player2, %action, %suffix, %extraval, %sound)
|
||||
{
|
||||
// Handle instant bonuses (previously handled via subclassing)
|
||||
if (%this.instant)
|
||||
return %this.awardInstantBonus(%bonusData, %player1, %player2, %action, %suffix, %extraval, %sound);
|
||||
|
||||
if (%bonusData !$= "")
|
||||
%val = %bonusData.getValue();
|
||||
else
|
||||
%val = 0;
|
||||
|
||||
if (%extraval !$= "")
|
||||
%val += %extraval;
|
||||
|
||||
if (%val < 0)
|
||||
%val = 0;
|
||||
|
||||
// Send message to bonus display mechanism
|
||||
if (%val > 0)
|
||||
Game.updateCurrentBonusAmount(%val, %player1.team);
|
||||
|
||||
if (%bonusData !$= "")
|
||||
%text = %bonusData.getString();
|
||||
|
||||
if (%suffix !$= "")
|
||||
%text = %text SPC %suffix;
|
||||
|
||||
if (%player1.team != %player2.team)
|
||||
%actionColor = "<color:dd0000>";
|
||||
else
|
||||
%actionColor = "<color:00dd00>";
|
||||
|
||||
%player1Color = $TR2::teamColor[%player1.team];
|
||||
%player2Color = $TR2::teamColor[%player2.team];
|
||||
|
||||
%summary = %player1Color @ getTaggedString(%player1.client.name)
|
||||
SPC %actionColor @ %action
|
||||
SPC %player2Color @ getTaggedString(%player2.client.name);
|
||||
|
||||
messageAll('MsgTR2Event', "", %summary, %text, %val);
|
||||
|
||||
if (%this.history !$= "")
|
||||
// Add to BonusHistory and calculate variance
|
||||
%this.history.add(%bonusData);
|
||||
else if (%bonusData !$= "")
|
||||
// Otherwise just get rid of it
|
||||
%bonusData.delete();
|
||||
}
|
||||
|
||||
function Bonus::awardInstantBonus(%this, %bonusData, %player1, %player2, %action, %suffix, %extraVal, %sound)
|
||||
{
|
||||
if (%bonusData !$= "")
|
||||
%val = %bonusData.getValue();
|
||||
else
|
||||
%val = 0;
|
||||
|
||||
if (%extraVal !$= "")
|
||||
%val += %extraVal;
|
||||
|
||||
if (%val < 0)
|
||||
%val = 0;
|
||||
|
||||
if (%player2 !$= "")
|
||||
%summary = getTaggedString(%player1.client.name) SPC %action SPC
|
||||
getTaggedString(%player2.client.name);
|
||||
//else if (%player1 !$= "")
|
||||
// %summary = getTaggedString(%player1.client.name);
|
||||
|
||||
// Send message to bonus display mechanism
|
||||
%scoringTeam = %player1.client.team;
|
||||
$teamScore[%scoringTeam] += %val;
|
||||
messageAll('MsgTR2SetScore', "", %scoringTeam, $teamScore[%scoringTeam]);
|
||||
|
||||
if (%bonusData !$= "")
|
||||
%text = %bonusData.getString() SPC %suffix;
|
||||
else
|
||||
%text = %suffix;
|
||||
|
||||
%scoringTeam = %player1.team;
|
||||
%otherTeam = (%scoringTeam == 1) ? 2 : 1;
|
||||
|
||||
//messageAll('MsgTR2Event', "", %summary, %text, %val);
|
||||
messageTeam(%scoringTeam, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")");
|
||||
messageTeam(%otherTeam, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")");
|
||||
messageTeam(0, 'MsgTR2InstantBonus', "\c4" @ %text SPC "\c3(+" @ %val @ ")");
|
||||
|
||||
if (%sound !$= "")
|
||||
serverPlay2D(%sound);
|
||||
|
||||
if (%this.history !$= "")
|
||||
// Add to BonusHistory and calculate variance
|
||||
%this.history.add(%bonusData);
|
||||
else if (%bonusData !$= "")
|
||||
// Otherwise just get rid of it
|
||||
%bonusData.delete();
|
||||
}
|
||||
|
||||
|
||||
function FlagBonus::award(%this, %bonusData, %dropper, %grabber, %flag)
|
||||
{
|
||||
// Hmm, should update this to use Parent::
|
||||
|
||||
// Calculate bonus value
|
||||
%val = %bonusData.getValue();
|
||||
|
||||
// Sneaky workaround so that some bonuses still display even though
|
||||
// they're worth nothing
|
||||
if (%val < 0)
|
||||
%val = 0;
|
||||
|
||||
if (%val >= 20)
|
||||
ServerPlay2D(CrowdCheerSound);
|
||||
|
||||
if (!%flag.atHome && !%flag.onGoal && !%flag.dropperKilled)
|
||||
{
|
||||
if (%flag.dropper.team == %grabber.team)
|
||||
{
|
||||
%actionColor = "<color:00dd00>";
|
||||
%ppoints = mCeil(%val / 2);
|
||||
%rpoints = mFloor(%val / 2);
|
||||
%grabber.client.score += %rpoints;
|
||||
%grabber.client.receivingScore += %rpoints;
|
||||
%flag.dropper.client.score += %ppoints;
|
||||
%flag.dropper.client.passingScore += %ppoints;
|
||||
} else {
|
||||
%actionColor = "<color:dd0000>";
|
||||
%grabber.client.score += %val;
|
||||
%grabber.client.interceptingScore += %val;
|
||||
%this.history.initialize();
|
||||
|
||||
// If grabber was a goalie, count this as a save
|
||||
if (%grabber.client.currentRole $= Goalie)
|
||||
%grabber.client.saves++;
|
||||
}
|
||||
|
||||
if (%flag.dropper.client !$= "")
|
||||
{
|
||||
%dropperColor = $TR2::teamColor[%dropper.team];
|
||||
%grabberColor = $TR2::teamColor[%grabber.team];
|
||||
%summary = %dropperColor @ getTaggedString(%dropper.client.name)
|
||||
SPC %actionColor @ "to"
|
||||
SPC %grabberColor @ getTaggedString(%grabber.client.name);
|
||||
}
|
||||
} else {
|
||||
// Handle regular flag pickups
|
||||
%summary = $TR2::teamColor[%grabber.team] @ getTaggedString(%grabber.client.name);
|
||||
%this.history.initialize();
|
||||
}
|
||||
|
||||
// Add to BonusHistory and calculate variance
|
||||
%bonusData.recipient = %grabber;
|
||||
%this.history.add(%bonusData);
|
||||
|
||||
// Use variance to calculate creativity
|
||||
%variance = %this.history.getVariance();
|
||||
CreativityBonus.evaluate(%variance, %grabber);
|
||||
|
||||
// Send message to bonus display mechanism
|
||||
// <color:000000>
|
||||
Game.updateCurrentBonusAmount(%val, %grabber.team);
|
||||
messageAll('MsgTR2Event', "", %summary, %bonusData.getString(), %val);
|
||||
}
|
||||
|
||||
function WeaponBonus::award(%this, %bonusData, %shooter, %victim)
|
||||
{
|
||||
%shooter.client.fcHits++;
|
||||
if (%bonusData.getValue() >= 5)
|
||||
ServerPlay2D(MonsterSound);
|
||||
Parent::award(%this, %bonusData, %shooter, %victim, "immobilized", "Hit \c2(" @ getTaggedString(%shooter.client.name) @ ")");
|
||||
}
|
||||
|
||||
function G4Bonus::award(%this, %bonusData, %plAttacker, %plVictim, %damageType, %damageLoc, %val)
|
||||
{
|
||||
Parent::award(%this, %bonusData, %plAttacker, %plVictim, "G4'd",
|
||||
"Bionic Grab", %val);
|
||||
}
|
||||
|
||||
function CollisionBonus::award(%this, %bonusData, %plPasser, %plReceiver, %action, %desc, %val)
|
||||
{
|
||||
Parent::award(%this, %bonusData, %plPasser, %plReceiver, %action, %desc, %val);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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]);
|
||||
}
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -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";
|
||||
};
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
// Penalties
|
||||
|
||||
new ScriptObject(TeamkillPenalty)
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
|
@ -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";
|
||||
};
|
||||
|
||||
|
|
@ -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";
|
||||
};
|
||||
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_chaingun.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_chaingun.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_disc.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_disc.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_grenade.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_grenade.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_mine.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_mine.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_missile.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_missile.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_mortar.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_mortar.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_plasma.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/ammo_plasma.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/banner_honor.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/banner_honor.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/banner_strength.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/banner_strength.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/banner_unity.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/banner_unity.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/beacon.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/beacon.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/bio_player_debris.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/bio_player_debris.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/bioderm_heavy.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/bioderm_heavy.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/bioderm_light.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/bioderm_light.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/bioderm_medium.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/bioderm_medium.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/bmiscf.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/bmiscf.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/bomb.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/bomb.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg1.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg1.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg12.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg12.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg13.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg13.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg15.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg15.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg16.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg16.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg17.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg17.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg18.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg18.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg19.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg19.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg20.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg20.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg23.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg23.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg25.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg25.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg31.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg31.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg32.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg32.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg33.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg33.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg34.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg34.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/borg7.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/borg7.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/camera.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/camera.glb
Normal file
Binary file not shown.
BIN
docs/base/@vl2/shapes.vl2/shapes/debris_generic.glb
Normal file
BIN
docs/base/@vl2/shapes.vl2/shapes/debris_generic.glb
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue