coyote time

added 5 cycles of "coyote time"
  this means you can still jump for 5/60 = 0.1 seconds after leaving the ground
  let me know if you like the feel
  this might cause some unexpected bugs, or reduce the difficulty of some platforming levels

JUNK tech: NFT - buy your current game seed
  no one is allow to use your seeds
  if they use them they are gonna get in trouble

removed the pavilion/ruins map to see if it's causing bugs
This commit is contained in:
landgreen
2022-04-02 15:05:27 -07:00
parent 92b5065f71
commit 78570d06a6
7 changed files with 89 additions and 50 deletions

View File

@@ -72,6 +72,7 @@ function playerOffGroundCheck(event) {
if (pairs[i].bodyA === jumpSensor || pairs[i].bodyB === jumpSensor) { if (pairs[i].bodyA === jumpSensor || pairs[i].bodyB === jumpSensor) {
if (m.onGround && m.numTouching === 0) { if (m.onGround && m.numTouching === 0) {
m.onGround = false; m.onGround = false;
m.lastOnGroundCycle = m.cycle;
m.hardLandCD = 0 // disable hard landing m.hardLandCD = 0 // disable hard landing
if (m.checkHeadClear()) { if (m.checkHeadClear()) {
if (m.crouch) { if (m.crouch) {
@@ -189,7 +190,7 @@ function collisionChecks(event) {
time: simulation.drawTime time: simulation.drawTime
}); });
} }
if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.005 : 1.05 if (tech.isLessDamageReduction && !mob[k].shield) mob[k].damageReduction *= mob[k].isBoss ? 1.0025 : 1.05
return; return;
} }
//mob + body collisions //mob + body collisions

View File

@@ -1204,9 +1204,9 @@ function localstorageCheck() {
if (localstorageCheck()) { if (localstorageCheck()) {
localSettings = JSON.parse(localStorage.getItem("localSettings")) localSettings = JSON.parse(localStorage.getItem("localSettings"))
if (localSettings) { if (localSettings) {
console.log('localStorage is enabled')
localSettings.isAllowed = true localSettings.isAllowed = true
localSettings.isEmpty = false localSettings.isEmpty = false
console.log('localStorage is enabled')
} else { } else {
console.log('localStorage is enabled, local settings empty') console.log('localStorage is enabled, local settings empty')
localSettings = { localSettings = {
@@ -1215,8 +1215,8 @@ if (localstorageCheck()) {
} }
} }
} else { } else {
localSettings = { isAllowed: false }
console.log("localStorage is disabled") console.log("localStorage is disabled")
localSettings = { isAllowed: false }
} }
@@ -1243,6 +1243,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
document.getElementById("difficulty-select").value = localSettings.difficultyMode document.getElementById("difficulty-select").value = localSettings.difficultyMode
if (localSettings.fpsCapDefault === undefined) localSettings.fpsCapDefault = 'max' if (localSettings.fpsCapDefault === undefined) localSettings.fpsCapDefault = 'max'
if (localSettings.personalSeeds === undefined) localSettings.personalSeeds = [];
if (localSettings.fpsCapDefault === 'max') { if (localSettings.fpsCapDefault === 'max') {
simulation.fpsCapDefault = 999999999; simulation.fpsCapDefault = 999999999;
} else { } else {
@@ -1252,6 +1253,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
} else { } else {
console.log('setting default localSettings') console.log('setting default localSettings')
localSettings = { localSettings = {
personalSeeds: [],
isJunkExperiment: false, isJunkExperiment: false,
isCommunityMaps: false, isCommunityMaps: false,
difficultyMode: '2', difficultyMode: '2',

View File

@@ -8,7 +8,8 @@ const level = {
onLevel: -1, onLevel: -1,
levelsCleared: 0, levelsCleared: 0,
//see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later //see level.populateLevels: (intro, ... , reservoir, reactor, ... , gauntlet, final) added later
playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber", "pavilion"], playableLevels: ["labs", "rooftops", "skyscrapers", "warehouse", "highrise", "office", "aerie", "satellite", "sewers", "testChamber"], //"pavilion"
// playableLevels: ["pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion", "pavilion"],
communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands"], communityLevels: ["stronghold", "basement", "crossfire", "vats", "run", "n-gon", "house", "perplex", "coliseum", "tunnel", "islands"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"], trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [], levels: [],
@@ -18,7 +19,7 @@ const level = {
// m.setField("metamaterial cloaking") // m.setField("metamaterial cloaking")
// b.giveGuns("harpoon") // b.giveGuns("harpoon")
// tech.giveTech("grappling hook") // tech.giveTech("grappling hook")
tech.giveTech("discount") // tech.giveTech("discount")
// tech.giveTech("shape-memory alloy") // tech.giveTech("shape-memory alloy")
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech"); // for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
// for (let i = 0; i < 2; i++) tech.giveTech("corona discharge") // for (let i = 0; i < 2; i++) tech.giveTech("corona discharge")
@@ -870,7 +871,7 @@ const level = {
if (this.isTouched) { if (this.isTouched) {
if (!m.isBodiesAsleep) { if (!m.isBodiesAsleep) {
this.fadeCount-- this.fadeCount--
Matter.Body.setVertices(this, this.shrinkVertices(Math.max(this.fadeCount / this.fadeTime, 0.03))) //take on harpoon shape Matter.Body.setVertices(this, this.shrinkVertices(Math.max(this.fadeCount / this.fadeTime, 0.03)))
} }
if (this.fadeCount < 1) { if (this.fadeCount < 1) {
Matter.Body.setPosition(this, hide) Matter.Body.setPosition(this, hide)
@@ -878,8 +879,8 @@ const level = {
this.isTouched = false this.isTouched = false
this.collisionFilter.mask = 0 //cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet this.collisionFilter.mask = 0 //cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
this.returnCount = this.returnTime this.returnCount = this.returnTime
Matter.Body.setVertices(this, this.shrinkVertices(1)) //take on harpoon shape Matter.Body.setVertices(this, this.shrinkVertices(1))
Matter.Body.setVertices(this, vertices) //take on harpoon shape Matter.Body.setVertices(this, vertices)
} }
} else if (Matter.Query.collides(this, [player]).length) { // || (Matter.Query.collides(this, body).length)) { } else if (Matter.Query.collides(this, [player]).length) { // || (Matter.Query.collides(this, body).length)) {
this.isTouched = true this.isTouched = true

View File

@@ -84,6 +84,7 @@ const m = {
yOff: 70, yOff: 70,
yOffGoal: 70, yOffGoal: 70,
onGround: false, //checks if on ground or in air onGround: false, //checks if on ground or in air
lastOnGroundCycle: 0, //use to calculate coyote time
standingOn: undefined, standingOn: undefined,
numTouching: 0, numTouching: 0,
crouch: false, crouch: false,
@@ -231,13 +232,7 @@ const m = {
} }
}, },
buttonCD_jump: 0, //cool down for player buttons buttonCD_jump: 0, //cool down for player buttons
groundControl() { jump() {
//check for crouch or jump
if (m.crouch) {
if (!(input.down) && m.checkHeadClear() && m.hardLandCD < m.cycle) m.undoCrouch();
} else if (input.down || m.hardLandCD > m.cycle) {
m.doCrouch(); //on ground && not crouched and pressing s or down
} else if ((input.up) && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23) {
m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
//apply a fraction of the jump force to the body the player is jumping off of //apply a fraction of the jump force to the body the player is jumping off of
Matter.Body.applyForce(m.standingOn, m.pos, { Matter.Body.applyForce(m.standingOn, m.pos, {
@@ -250,6 +245,15 @@ const m = {
x: player.velocity.x, x: player.velocity.x,
y: Math.max(-10, Math.min(m.standingOn.velocity.y, 10)) //cap velocity contribution from blocks you are standing on to 10 in the vertical y: Math.max(-10, Math.min(m.standingOn.velocity.y, 10)) //cap velocity contribution from blocks you are standing on to 10 in the vertical
}); });
},
groundControl() {
//check for crouch or jump
if (m.crouch) {
if (!(input.down) && m.checkHeadClear() && m.hardLandCD < m.cycle) m.undoCrouch();
} else if (input.down || m.hardLandCD > m.cycle) {
m.doCrouch(); //on ground && not crouched and pressing s or down
} else if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23) {
m.jump()
} }
if (input.left) { if (input.left) {
@@ -282,6 +286,9 @@ const m = {
} }
}, },
airControl() { airControl() {
//check for coyote time jump
if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23 && m.lastOnGroundCycle + 5 > m.cycle) m.jump()
//check for short jumps //moving up //recently pressed jump //but not pressing jump key now //check for short jumps //moving up //recently pressed jump //but not pressing jump key now
if (m.buttonCD_jump + 60 > m.cycle && !(input.up) && m.Vy < 0) { if (m.buttonCD_jump + 60 > m.cycle && !(input.up) && m.Vy < 0) {
Matter.Body.setVelocity(player, { Matter.Body.setVelocity(player, {
@@ -3776,6 +3783,7 @@ const m = {
m.spin = 0 m.spin = 0
// m.groundControl = () => {} //disable entering ground // m.groundControl = () => {} //disable entering ground
m.onGround = false m.onGround = false
m.lastOnGroundCycle = 0
// playerOnGroundCheck = () => {} // playerOnGroundCheck = () => {}
m.airControl = () => { //tank controls m.airControl = () => { //tank controls
player.force.y -= player.mass * simulation.g; //undo gravity player.force.y -= player.mass * simulation.g; //undo gravity

View File

@@ -713,6 +713,7 @@ const simulation = {
document.getElementById("health-bg").style.display = "inline" document.getElementById("health-bg").style.display = "inline"
m.alive = true; m.alive = true;
m.onGround = false m.onGround = false
m.lastOnGroundCycle = 0
m.setMaxHealth() m.setMaxHealth()
m.health = 0; m.health = 0;
m.addHealth(0.25) m.addHealth(0.25)

View File

@@ -757,7 +757,7 @@ const tech = {
}, },
{ {
name: "regression", name: "regression",
description: "bullet <strong>collisions</strong> increase <strong>vulnerability</strong> to<br><strong class='color-d'>damage</strong> by <strong>5%</strong> for mobs <em>(0.5% for bosses)</em>", description: "bullet <strong>collisions</strong> increase <strong>vulnerability</strong> to<br><strong class='color-d'>damage</strong> by <strong>5%</strong> for mobs <em>(0.25% for bosses)</em>",
maxCount: 1, maxCount: 1,
count: 0, count: 0,
frequency: 1, frequency: 1,
@@ -7491,26 +7491,6 @@ const tech = {
// }, // },
// remove() {} // remove() {}
// }, // },
{
name: "tinker",
description: "<strong>permanently</strong> unlock <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> in experiment mode<br><em>this effect is stored for future visits</em>",
maxCount: 1,
count: 0,
frequency: 0,
frequencyDefault: 0,
isJunk: true,
isNonRefundable: true,
allowed() {
return !localSettings.isJunkExperiment
},
requires: "",
effect() {
console.log('hi')
localSettings.isJunkExperiment = true
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
},
remove() {}
},
{ {
name: "discount", name: "discount",
description: "get 3 random <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> for the price of 1!", description: "get 3 random <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> for the price of 1!",
@@ -9293,6 +9273,43 @@ const tech = {
}, },
remove() {} remove() {}
}, },
{
name: "tinker",
description: "<strong>permanently</strong> unlock <strong class='color-j'>JUNK</strong> <strong class='color-m'>tech</strong> in experiment mode<br><em>this effect is stored for future visits</em>",
maxCount: 1,
count: 0,
frequency: 0,
frequencyDefault: 0,
isJunk: true,
isNonRefundable: true,
allowed() {
return !localSettings.isJunkExperiment
},
requires: "",
effect() {
localSettings.isJunkExperiment = true
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
},
remove() {}
},
{
name: "NFT",
descriptionFunction() { return `buy your current game seed: <strong style = 'font-size:130%;'>${Math.initialSeed}</strong><br><em>no one is allow to use your seeds<br>if they use them they are gonna get in trouble</em><br>your seeds: <span style = 'font-size:70%;'>${localSettings.personalSeeds.join()}</span>` },
maxCount: 1,
count: 0,
frequency: 0,
isJunk: true,
isNonRefundable: true,
allowed() {
return true
},
requires: "",
effect() {
localSettings.personalSeeds.push(Math.initialSeed)
if (localSettings.isAllowed) localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
},
remove() {}
},
//************************************************** //**************************************************
//************************************************** undefined / lore //************************************************** undefined / lore
//************************************************** tech //************************************************** tech

View File

@@ -1,14 +1,25 @@
******************************************************** NEXT PATCH ************************************************** ******************************************************** NEXT PATCH **************************************************
JUNK tech: meteor shower - take a shower, but meteors instead of water added 5 cycles of "coyote time"
JUNK tech: discount - get 3 random JUNK tech for the price of 1! this means you can still jump for 5/60 = 0.1 seconds after leaving the ground
let me know if you like the feel
this might cause some unexpected bugs, or reduce the difficulty of some platforming levels
bug fixes JUNK tech: NFT - buy your current game seed
no one is allow to use your seeds
if they use them they are gonna get in trouble
I'll be off line until Saturday, so please don't submit any bug reports until I return removed the pavilion/ruins map to see if it's causing bugs
******************************************************** TODO ******************************************************** ******************************************************** TODO ********************************************************
tech smoke grenades - mobs inside a cloud can't see player
draw on the region so it's hard for player to see as well
you'd have to make something similar to MACHO that exists after an explosion goes off
maybe just keep it simple:
stun mobs for a long time, and draw a 99& alpha grey circle for the same time
don't worry about mobs seeing you inside the circle, the circle is kinda small so it doesn't matter
tech mines: mines fire _____ instead of nails tech mines: mines fire _____ instead of nails
needles needles
@@ -40,6 +51,8 @@ bug: often game puts player position at NaN
clues: clues:
maybe with vanish or other special blocks and grapple hook maybe with vanish or other special blocks and grapple hook
very high level for tech, duplication very high level for tech, duplication
happened once with only 13 tech
?&seed=7269&gun0=drones&gun1=matter%20wave&gun2=shotgun&tech0=arsenal&tech1=dead%20reckoning&tech2=regression&tech3=unified%20field%20theory&tech4=rivet%20gun&tech5=phonon&tech6=affine%20connection&field=wormhole&difficulty=2
maybe not about JUNK though maybe not about JUNK though
maybe on tons of bullets maybe on tons of bullets
maybe grappling hook, Bulk modulus maybe grappling hook, Bulk modulus
@@ -88,10 +101,6 @@ setting to remove UI, except health bar
except active gun? to see ammo except active gun? to see ammo
checkbox in pause and in settings checkbox in pause and in settings
add coyote jump
log game m.cycle when last on ground
for jump check if game cycle is < last on ground cycle -2
pause time like invariant for other things... pause time like invariant for other things...
throwing blocks throwing blocks
charging railgun charging railgun