Skip to content

Commit

Permalink
Add cliff safeguard
Browse files Browse the repository at this point in the history
  • Loading branch information
krypciak committed May 27, 2024
1 parent 1c462cb commit 1ed0d5e
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
- Announce looping back to the beginning and to the end when navigating through the hints with Gamepad: L1 and Gamepad R1
- Added Sound Glossary entries for: ball direction changer, ball accelerator and ball decelerator
- Mapped battles and puzzled up to including rhombus dungeon
- Added cliff safeguard widget (more info in quick menu help)

### Changed

Expand Down
7 changes: 6 additions & 1 deletion lang/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"dashVoulme": { "name": "Dash volume", "description": "Dash volume multiplier." },
"wallVolume": { "name": "Wall volume", "description": "Wall volume multiplier." },
"wallBumpVolume": { "name": "Wall bumping volume", "description": "Wall bumping volume multiplier." },
"cliffSafeguardVolume": { "name": "Cliff safeguard volume", "description": "Cliff safeguard volume multiplier." },
"jumpHintsVolume": { "name": "Jump hints volume", "description": "Jump hints volume multiplier." },
"wallScanVolume": { "name": "Wall scan volume", "description": "Wall scan volume multiplier." },
"hintsVolume": { "name": "Hints volume", "description": "Hints volume multiplier." },
Expand Down Expand Up @@ -155,6 +156,10 @@
"name": "Collision",
"description": "Plays when you run into an obstacle that stops your movement.\n The more your movement is blocked by the obstacle, the louder the sound."
},
"cliffSafeguard": {
"name": "Cliff safeguard",
"description": "Plays when the cliff safeguard prevented you from falling from a cliff."
},
"jumphintWater": {
"name": "Jump hint: water",
"description": "For 8 directions around the player, this sound will play at each location where the player would fall into water.\n The directions are rotated with the player facing.\n When the player is facing away from the hint, a lower pitch version plays."
Expand Down Expand Up @@ -298,7 +303,7 @@
},
"cliffSafeguard": {
"title": "Cliff safeguard",
"description": ""
"description": "Prevents you from jumping and falling off cliffs."
}
},
"itemHelpPages": [
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 64 additions & 0 deletions src/environment/cliff-safeguard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Lang } from '../lang-manager'

declare global {
namespace ig.ENTITY {
interface Player {
crossedeyes_cliffSafeguardVelCancel?: Vec2
}
}
}

const id = 'crossedeyes-cliffSafeguard'
let block: boolean = localStorage[`ccuilib-quickmenuwidget-${id}`] == 'true'
nax.ccuilib.QuickRingMenuWidgets.addWidget({
name: id,
title: Lang.menu.quickMenu.widgets.cliffSafeguard.title,
description: Lang.menu.quickMenu.widgets.cliffSafeguard.description,
pressEvent: button => {
block = button.isToggleOn()
},
toggle: true,
image: () => ({
gfx: new ig.Image('media/gui/circuit-icons.png'),
srcPos: { x: 25, y: 49 },
pos: { x: 4, y: 4 },
size: { x: 24, y: 24 },
}),
})

/** in miliseconds */
let lastVelCancelSet = 0

ig.Physics.inject({
moveEntityZ(coll, fVel, prevOnGround) {
if (coll !== ig.game.playerEntity.coll || !block) return this.parent(coll, fVel, prevOnGround)
const player = coll.entity as ig.ENTITY.Player

if (lastVelCancelSet + 50 < ig.game.now) {
lastVelCancelSet = ig.game.now
player.crossedeyes_cliffSafeguardVelCancel = Vec2.create()
}

/* dont worry about it */
const collData = coll._collData

const Vec2_length = Vec2.length

if (prevOnGround && coll.zGravityFactor > 0 /*&& !coll.noSlipping */ && !collData.forceMoveFrameVel && (collData.holeInfo.mapRes == 1 || collData.groundEntry)) {
if (collData.holeInfo.mapRes == 1 /* && level.collision!.isOverHole(t, q - level.height!, s, v) */) {
/* dont worry about it */
Vec2.assignC(coll.accelDir, 0, 0)

/* dont worry about it */
Vec2.length = function length(v: Vec2): any {
Vec2.mulC(v, 1.5)
player.crossedeyes_cliffSafeguardVelCancel = Vec2.create(v)
lastVelCancelSet = ig.game.now
}
}
}
this.parent(coll, fVel, prevOnGround)

Vec2.length = Vec2_length
},
})
54 changes: 43 additions & 11 deletions src/environment/movement-sounds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,13 @@ function getSoundFromColl(coll: ig.CollEntry, type: keyof typeof sc.ACTOR_SOUND)
e = sc.ACTOR_SOUND[type] || sc.ACTOR_SOUND.none
return (e as any)[c] ?? e[ig.TERRAIN_DEFAULT]
}
let lastStep: boolean = true
let lastCollStep: boolean = true

let stepCounter: number = 0
sc.ActorEntity.inject({
update() {
if (this !== (ig.game.playerEntity as any)) return this.parent()
const player = this as unknown as ig.ENTITY.Player
if (player !== ig.game.playerEntity) return this.parent()

/* most copied from the game code */
this.stepStats.terrain = ig.terrain.getTerrain(this.coll, true)
Expand Down Expand Up @@ -62,10 +63,10 @@ sc.ActorEntity.inject({

const sound = getSoundFromColl(this.coll, this.soundType)
let spawnFx = false
let vol: number | undefined
let collVol: number | undefined
if (this.coll._collData?.collided && this == (ig.game.playerEntity as sc.ActorEntity)) {
const dist = Vec3.distance(Vec3.create(), this.coll.vel)
vol = dist.map(40, 180, 1, 0.4)
collVol = dist.map(40, 180, 1, 0.4)
if (dist > 170) {
const minDist = Math.min(
Vec2.distance(Vec2.createC(0, 1), this.coll._collData.blockDir),
Expand All @@ -75,37 +76,68 @@ sc.ActorEntity.inject({
)
/* check if the player is going diagoally */
if (minDist > 0.5) {
vol = 1
collVol = 1
}
}
if (stepCounter == 2) {
ig.SoundHelper.playAtEntity(
new ig.Sound(lastStep ? SoundManager.sounds.hitOrganic1 : SoundManager.sounds.hitOrganic2, Opts.wallBumpVolume * vol),
new ig.Sound(lastCollStep ? SoundManager.sounds.hitOrganic1 : SoundManager.sounds.hitOrganic2, Opts.wallBumpVolume * collVol),
this,
null,
null,
700
)
} else if (stepCounter == 5) {
ig.SoundHelper.playAtEntity(
new ig.Sound(lastStep ? SoundManager.sounds.hitOrganic3 : SoundManager.sounds.hitOrganic4, Opts.wallBumpVolume * vol),
new ig.Sound(lastCollStep ? SoundManager.sounds.hitOrganic3 : SoundManager.sounds.hitOrganic4, Opts.wallBumpVolume * collVol),
this,
null,
null,
700
)
lastStep = !lastStep
lastCollStep = !lastCollStep
}
}
if (vol === undefined || vol < 0.6) {

let cliffSafeguardVol: number = 0
let cliffSafeguardPos: Vec2 | undefined
if (player.crossedeyes_cliffSafeguardVelCancel && !Vec2.isZero(player.crossedeyes_cliffSafeguardVelCancel)) {
const accelDir = Vec2.create(player.coll.accelDir)

const velCancel = Vec2.create(player.crossedeyes_cliffSafeguardVelCancel)
Vec2.divC(velCancel, 3)

let dot = Math.abs(Vec2.dot(velCancel, accelDir))
if (Math.abs(velCancel.x) > 0 && Math.abs(velCancel.y) > 0) {
dot *= 1.5
}

cliffSafeguardVol = dot.limit(0, 1).round(2)
cliffSafeguardPos = Vec2.create(velCancel)
}

if (cliffSafeguardVol > 0) {
const vol = (cliffSafeguardVol + 0.2) * Opts.cliffSafeguardVolume
const pos = Vec2.sub(Vec3.create(player.coll.pos), Vec2.mulC(cliffSafeguardPos!, 16 * 5)) as Vec3

if (stepCounter == 0) {
SoundManager.playSound('cliffSafeguard1', 1, vol, pos)
}
if (stepCounter == 3) {
SoundManager.playSound('cliffSafeguard2', 1, vol, pos)
}
}

if (cliffSafeguardVol != 1 && (collVol === undefined || collVol < 0.6)) {
const vol = cliffSafeguardVol.map(0.7, 1, 1, 0.3).limit(0, 1) * Opts.footstepVolume
if (stepCounter == 2) {
spawnFx = true
ig.SoundHelper.playAtEntity(SoundManager.muliplySoundVol(sound.step1!, Opts.footstepVolume as number), this, null, null, 700)
ig.SoundHelper.playAtEntity(SoundManager.muliplySoundVol(sound.step1!, vol), this, null, null, 700)
this.onMoveEffect && this.onMoveEffect('step')
}
if (stepCounter == 5) {
spawnFx = true
ig.SoundHelper.playAtEntity(SoundManager.muliplySoundVol(sound.step2!, Opts.footstepVolume as number), this, null, null, 700)
ig.SoundHelper.playAtEntity(SoundManager.muliplySoundVol(sound.step2!, vol), this, null, null, 700)
this.onMoveEffect && this.onMoveEffect('step')
}
}
Expand Down
10 changes: 10 additions & 0 deletions src/manuals/hud/sound-glossary-entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ export function getSoundGlossaryEntries() {
getVolume: () => Opts.wallBumpVolume,
},
},
cliffSafeguard: {
config: {
eventSteps: [
{ volume: Opts.cliffSafeguardVolume, type: 'PLAY_SOUND', sound: SoundManager.sounds.cliffSafeguard1 },
{ time: 0.2, type: 'WAIT' },
{ volume: Opts.cliffSafeguardVolume, type: 'PLAY_SOUND', sound: SoundManager.sounds.cliffSafeguard2 },
{ time: 0.2, type: 'WAIT' },
],
},
},
jumphintWater: {
config: SoundManager.pickContiniousSettingsPath(LoudJump.continiousConfig, 0),
dirs: loudjumpDirs,
Expand Down
1 change: 1 addition & 0 deletions src/misc/quick-menu-layout-enforce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function updateQuickRingMenuLayoutLock() {
2: '11_analyze',
4: '11_party',
6: '11_map',
7: 'crossedeyes-cliffSafeguard',
1000: 'crossedeyes-aimAnalysis',
1002: 'crossedeyes-wallScan',
1012: 'cc-blitzkrieg_puzzleSkip',
Expand Down
9 changes: 9 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,15 @@ export function getOptions() {
fill: true,
showPercentage: true,
},
cliffSafeguardVolume: {
type: 'OBJECT_SLIDER',
init: 1,
min: 0,
max: 2,
step: 0.1,
fill: true,
showPercentage: true,
},
jumpHintsVolume: {
type: 'OBJECT_SLIDER',
init: 1,
Expand Down
14 changes: 4 additions & 10 deletions src/sound-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export class SoundManager implements PauseListener {
bounce2: 'media/sound/battle/ball-bounce-2.ogg',
bounce3: 'media/sound/battle/ball-bounce-3.ogg',

cliffSafeguard1: 'media/sound/scenes/dash.ogg',
cliffSafeguard2: 'media/sound/scenes/dash-2.ogg',

// sound glossary stuff
dash: 'media/sound/battle/dash-3.ogg',
soundglossaryJump: 'media/sound/crossedeyes/soundglossary/jump.ogg',
Expand Down Expand Up @@ -124,16 +127,7 @@ export class SoundManager implements PauseListener {
}
},
})
// let i = 0
// ig.SoundManager.inject({
// update() {
// this.parent()
// if ((i += ig.system.ingameTick) > 10) {
// i = 0
// SoundManager.cleanupDeadSounds()
// }
// },
// })

/* preload sounds */
Object.values(SoundManager.sounds).forEach(path => new ig.Sound(path))

Expand Down

0 comments on commit 1ed0d5e

Please sign in to comment.