Skip to content

Instantly share code, notes, and snippets.

@root-cause
Created October 11, 2024 16:49
Show Gist options
  • Save root-cause/19e25edbee028309be735a37e538fdcc to your computer and use it in GitHub Desktop.
Save root-cause/19e25edbee028309be735a37e538fdcc to your computer and use it in GitHub Desktop.
const m23_1_prop_m31_ghostsalton_01a = mp.game.joaat("m23_1_prop_m31_ghostsalton_01a");
const m23_1_prop_m31_ghostrurmeth_01a = mp.game.joaat("m23_1_prop_m31_ghostrurmeth_01a");
const m23_1_prop_m31_ghostskidrow_01a = mp.game.joaat("m23_1_prop_m31_ghostskidrow_01a");
const m23_1_prop_m31_ghostzombie_01a = mp.game.joaat("m23_1_prop_m31_ghostzombie_01a");
const m23_1_prop_m31_ghostjohnny_01a = mp.game.joaat("m23_1_prop_m31_ghostjohnny_01a");
const m24_1_prop_m41_ghost_dom_01a = mp.game.joaat("m24_1_prop_m41_ghost_dom_01a");
const GHOST_DATA = [
// mp2023
{ model: m23_1_prop_m31_ghostsalton_01a, position: new mp.Vector3(63.7611, 6664.9165, 30.7754), rotation: new mp.Vector3(0.0, 0.0, -127.2) },
{ model: m23_1_prop_m31_ghostrurmeth_01a, position: new mp.Vector3(1907.7869, 4931.8643, 53.9633), rotation: new mp.Vector3(0.0, 0.0, 151.9991) },
{ model: m23_1_prop_m31_ghostskidrow_01a, position: new mp.Vector3(1487.9966, 3640.324, 34.5941), rotation: new mp.Vector3(0.0, 0.0, -148.6015) },
{ model: m23_1_prop_m31_ghostzombie_01a, position: new mp.Vector3(2771.9521, 4231.4917, 47.5589), rotation: new mp.Vector3(0.0, 0.0, 25.5985) },
{ model: m23_1_prop_m31_ghostrurmeth_01a, position: new mp.Vector3(3428.8845, 5175.512, 34.8858), rotation: new mp.Vector3(0.0, 0.0, -124.602) },
{ model: m23_1_prop_m31_ghostsalton_01a, position: new mp.Vector3(162.7387, 3132.652, 42.6697), rotation: new mp.Vector3(0.0, 0.0, 89.1973) },
{ model: m23_1_prop_m31_ghostzombie_01a, position: new mp.Vector3(-278.0607, 2844.7852, 53.0073), rotation: new mp.Vector3(0.0, 0.0, -54.607) },
{ model: m23_1_prop_m31_ghostrurmeth_01a, position: new mp.Vector3(-1648.1831, 2082.6343, 86.9693), rotation: new mp.Vector3(0.0, 0.0, 72.7919) },
{ model: m23_1_prop_m31_ghostskidrow_01a, position: new mp.Vector3(-521.8892, 4424.734, 88.7805), rotation: new mp.Vector3(0.0, 0.0, -94.6521) },
{ model: m23_1_prop_m31_ghostjohnny_01a, position: new mp.Vector3(2015.5793, 3827.2444, 32.3306), rotation: new mp.Vector3(0.0, 0.0, 7.5477) },
// mp2024
{ model: m23_1_prop_m31_ghostrurmeth_01a, position: new mp.Vector3(-1725.379, -192.303, 59.048), rotation: new mp.Vector3(0.0, 0.0, -86.854) },
{ model: m23_1_prop_m31_ghostskidrow_01a, position: new mp.Vector3(122.749, -1180.895, 29.666), rotation: new mp.Vector3(0.0, 0.0, 44.545) },
{ model: m23_1_prop_m31_ghostsalton_01a, position: new mp.Vector3(1295.17, -1590.502, 52.538), rotation: new mp.Vector3(0.0, 0.0, 146.745) },
{ model: m23_1_prop_m31_ghostzombie_01a, position: new mp.Vector3(-550.607, -2238.787, 121.327), rotation: new mp.Vector3(0.0, 0.0, 52.544) },
{ model: m23_1_prop_m31_ghostzombie_01a, position: new mp.Vector3(-1797.33, 437.401, 141.193), rotation: new mp.Vector3(0.0, 0.0, -7.656) },
{ model: m23_1_prop_m31_ghostskidrow_01a, position: new mp.Vector3(1006.57, -2167.482, 33.185), rotation: new mp.Vector3(0.0, 0.0, 177.344) },
{ model: m23_1_prop_m31_ghostsalton_01a, position: new mp.Vector3(-759.2323, -20.4763, 56.4413), rotation: new mp.Vector3(0.0, 0.0, 32.0) },
{ model: m23_1_prop_m31_ghostrurmeth_01a, position: new mp.Vector3(-765.8267, -692.7062, 70.1087), rotation: new mp.Vector3(0.0, 0.0, -1.0) },
{ model: m23_1_prop_m31_ghostsalton_01a, position: new mp.Vector3(947.0914, -207.4323, 78.2858), rotation: new mp.Vector3(0.0, 0.0, 112.5993) },
{ model: m24_1_prop_m41_ghost_dom_01a, position: new mp.Vector3(1654.8757, -20.7952, 135.0277), rotation: new mp.Vector3(0.0, 0.0, -86.854) }
];
const GHOST_DETAIL_RANGE = 50.0;
let ghostColshapes = new Array(GHOST_DATA.length);
let ghostPtfxHandle = 0;
let ghostSoundId = 0;
// functions
function getGhostSoundSet(model) {
switch (model) {
case m24_1_prop_m41_ghost_dom_01a:
return "DLC_24-1_Ghost_Hunt_Sounds";
default:
return "Ghost_Hunt_Sounds";
}
}
function getGhostSoundName(model) {
switch (model) {
case m23_1_prop_m31_ghostsalton_01a:
case m23_1_prop_m31_ghostzombie_01a:
return "Male_Ghost";
case m23_1_prop_m31_ghostrurmeth_01a:
case m23_1_prop_m31_ghostskidrow_01a:
return "Female_Ghost";
case m23_1_prop_m31_ghostjohnny_01a:
return "JK_Ghost";
case m24_1_prop_m41_ghost_dom_01a:
return "DM_Ghost";
default:
return "";
}
}
function removeGhostPtfx() {
if (ghostPtfxHandle) {
mp.game.graphics.stopParticleFxLooped(ghostPtfxHandle, false);
ghostPtfxHandle = 0;
}
}
function removeGhostSound() {
if (ghostSoundId) {
mp.game.audio.stopSound(ghostSoundId);
mp.game.audio.releaseSoundId(ghostSoundId);
ghostSoundId = 0;
}
}
// event handlers
function init() {
mp.game.streaming.requestAnimDict("anim@scripted@freemode@ig2_ghost@");
mp.game.streaming.requestNamedPtfxAsset("scr_srr_hal");
mp.game.audio.requestScriptBank("DLC_MP2023_1/DLC_MP2023_1_GH", false, -1);
mp.game.audio.requestScriptBank("DLC_24-1/GH_DM_01", false, -1);
GHOST_DATA.forEach((ghost, index) => {
const colshape = mp.colshapes.newSphere(ghost.position.x, ghost.position.y, ghost.position.z, GHOST_DETAIL_RANGE);
colshape._ghostProp = mp.objects.new(ghost.model, ghost.position, { rotation: ghost.rotation });
ghostColshapes[index] = colshape;
});
}
function onPlayerEnterColshape(colshape) {
if (!ghostColshapes.includes(colshape)) {
// not a colshape from this script, ignore
return;
}
// remove existing effects, the ghosts are far apart enough to not trigger this twice but just in case
removeGhostPtfx();
removeGhostSound();
// apply the effects
// warning: teleporting to a ghost doesn't work too well because ghostProp might not have streamed in yet, resulting in its handle being 0
const ghostProp = colshape._ghostProp;
mp.game.entity.setCollision(ghostProp.handle, false, false);
mp.game.entity.setCanClimbOn(ghostProp.handle, false);
mp.game.graphics.useParticleFxAsset("scr_srr_hal");
ghostPtfxHandle = mp.game.graphics.startParticleFxLoopedOnEntity("scr_srr_hal_ghost_haze", ghostProp.handle, 0.0, 0.0, 0.7, 0.0, 0.0, 0.0, 1.0, false, false, false);
ghostSoundId = mp.game.audio.getSoundId();
mp.game.audio.playSoundFromEntity(ghostSoundId, getGhostSoundName(ghostProp.model), ghostProp.handle, getGhostSoundSet(ghostProp.model), false, 0);
ghostProp.playAnim("float_1", "anim@scripted@freemode@ig2_ghost@", 8.0, true, false, false, 0.0, 0);
ghostProp.forceAiAndAnimationUpdate();
}
function onPlayerExitColshape(colshape) {
if (!ghostColshapes.includes(colshape)) {
// not a colshape from this script, ignore
return;
}
removeGhostPtfx();
removeGhostSound();
}
function cleanUp(player) {
if (player !== mp.players.local) {
return;
}
removeGhostPtfx();
removeGhostSound();
for (let i = 0; i < GHOST_DATA.length; i++) {
const colshape = ghostColshapes[i];
colshape._ghostProp.destroy();
colshape.destroy();
delete colshape._ghostProp;
ghostColshapes[i] = null;
}
}
// register event handlers
mp.events.add({
"playerReady": init,
"playerEnterColshape": onPlayerEnterColshape,
"playerExitColshape": onPlayerExitColshape,
"playerQuit": cleanUp
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment