diff --git a/js/engine.js b/js/engine.js
index f6d1e1a..1185985 100644
--- a/js/engine.js
+++ b/js/engine.js
@@ -72,6 +72,7 @@ function playerOffGroundCheck(event) {
if (pairs[i].bodyA === jumpSensor || pairs[i].bodyB === jumpSensor) {
if (m.onGround && m.numTouching === 0) {
m.onGround = false;
+ m.lastOnGroundCycle = m.cycle;
m.hardLandCD = 0 // disable hard landing
if (m.checkHeadClear()) {
if (m.crouch) {
@@ -189,7 +190,7 @@ function collisionChecks(event) {
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;
}
//mob + body collisions
diff --git a/js/index.js b/js/index.js
index cec2bc3..66ce301 100644
--- a/js/index.js
+++ b/js/index.js
@@ -1204,9 +1204,9 @@ function localstorageCheck() {
if (localstorageCheck()) {
localSettings = JSON.parse(localStorage.getItem("localSettings"))
if (localSettings) {
+ console.log('localStorage is enabled')
localSettings.isAllowed = true
localSettings.isEmpty = false
- console.log('localStorage is enabled')
} else {
console.log('localStorage is enabled, local settings empty')
localSettings = {
@@ -1215,8 +1215,8 @@ if (localstorageCheck()) {
}
}
} else {
- localSettings = { isAllowed: false }
console.log("localStorage is disabled")
+ localSettings = { isAllowed: false }
}
@@ -1243,6 +1243,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
document.getElementById("difficulty-select").value = localSettings.difficultyMode
if (localSettings.fpsCapDefault === undefined) localSettings.fpsCapDefault = 'max'
+ if (localSettings.personalSeeds === undefined) localSettings.personalSeeds = [];
if (localSettings.fpsCapDefault === 'max') {
simulation.fpsCapDefault = 999999999;
} else {
@@ -1252,6 +1253,7 @@ if (localSettings.isAllowed && !localSettings.isEmpty) {
} else {
console.log('setting default localSettings')
localSettings = {
+ personalSeeds: [],
isJunkExperiment: false,
isCommunityMaps: false,
difficultyMode: '2',
diff --git a/js/level.js b/js/level.js
index 0c9f24f..6ad2cfe 100644
--- a/js/level.js
+++ b/js/level.js
@@ -8,7 +8,8 @@ const level = {
onLevel: -1,
levelsCleared: 0,
//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"],
trainingLevels: ["walk", "crouch", "jump", "hold", "throw", "throwAt", "deflect", "heal", "fire", "nailGun", "shotGun", "superBall", "matterWave", "missile", "stack", "mine", "grenades", "harpoon"],
levels: [],
@@ -18,7 +19,7 @@ const level = {
// m.setField("metamaterial cloaking")
// b.giveGuns("harpoon")
// tech.giveTech("grappling hook")
- tech.giveTech("discount")
+ // tech.giveTech("discount")
// tech.giveTech("shape-memory alloy")
// for (let i = 0; i < 2; i++) powerUps.directSpawn(0, 0, "tech");
// for (let i = 0; i < 2; i++) tech.giveTech("corona discharge")
@@ -870,7 +871,7 @@ const level = {
if (this.isTouched) {
if (!m.isBodiesAsleep) {
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) {
Matter.Body.setPosition(this, hide)
@@ -878,8 +879,8 @@ const level = {
this.isTouched = false
this.collisionFilter.mask = 0 //cat.player | cat.body | cat.bullet | cat.powerUp | cat.mob | cat.mobBullet
this.returnCount = this.returnTime
- Matter.Body.setVertices(this, this.shrinkVertices(1)) //take on harpoon shape
- Matter.Body.setVertices(this, vertices) //take on harpoon shape
+ Matter.Body.setVertices(this, this.shrinkVertices(1))
+ Matter.Body.setVertices(this, vertices)
}
} else if (Matter.Query.collides(this, [player]).length) { // || (Matter.Query.collides(this, body).length)) {
this.isTouched = true
diff --git a/js/player.js b/js/player.js
index da2f62d..29b8ead 100644
--- a/js/player.js
+++ b/js/player.js
@@ -84,6 +84,7 @@ const m = {
yOff: 70,
yOffGoal: 70,
onGround: false, //checks if on ground or in air
+ lastOnGroundCycle: 0, //use to calculate coyote time
standingOn: undefined,
numTouching: 0,
crouch: false,
@@ -231,25 +232,28 @@ const m = {
}
},
buttonCD_jump: 0, //cool down for player buttons
+ jump() {
+ 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
+ Matter.Body.applyForce(m.standingOn, m.pos, {
+ x: 0,
+ y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5)
+ });
+
+ player.force.y = -m.jumpForce; //player jump force
+ Matter.Body.setVelocity(player, { //zero player y-velocity for consistent jumps
+ 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
+ });
+ },
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.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
- Matter.Body.applyForce(m.standingOn, m.pos, {
- x: 0,
- y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5)
- });
-
- player.force.y = -m.jumpForce; //player jump force
- Matter.Body.setVelocity(player, { //zero player y-velocity for consistent jumps
- 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
- });
+ } else if (input.up && m.buttonCD_jump + 20 < m.cycle && m.yOffWhen.stand > 23) {
+ m.jump()
}
if (input.left) {
@@ -282,6 +286,9 @@ const m = {
}
},
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
if (m.buttonCD_jump + 60 > m.cycle && !(input.up) && m.Vy < 0) {
Matter.Body.setVelocity(player, {
@@ -3776,6 +3783,7 @@ const m = {
m.spin = 0
// m.groundControl = () => {} //disable entering ground
m.onGround = false
+ m.lastOnGroundCycle = 0
// playerOnGroundCheck = () => {}
m.airControl = () => { //tank controls
player.force.y -= player.mass * simulation.g; //undo gravity
diff --git a/js/simulation.js b/js/simulation.js
index 4e980d4..d8e1880 100644
--- a/js/simulation.js
+++ b/js/simulation.js
@@ -713,6 +713,7 @@ const simulation = {
document.getElementById("health-bg").style.display = "inline"
m.alive = true;
m.onGround = false
+ m.lastOnGroundCycle = 0
m.setMaxHealth()
m.health = 0;
m.addHealth(0.25)
diff --git a/js/tech.js b/js/tech.js
index 24561a9..ef0cb01 100644
--- a/js/tech.js
+++ b/js/tech.js
@@ -757,7 +757,7 @@ const tech = {
},
{
name: "regression",
- description: "bullet collisions increase vulnerability to
damage by 5% for mobs (0.5% for bosses)",
+ description: "bullet collisions increase vulnerability to
damage by 5% for mobs (0.25% for bosses)",
maxCount: 1,
count: 0,
frequency: 1,
@@ -7491,26 +7491,6 @@ const tech = {
// },
// remove() {}
// },
- {
- name: "tinker",
- description: "permanently unlock JUNK tech in experiment mode
this effect is stored for future visits",
- 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",
description: "get 3 random JUNK tech for the price of 1!",
@@ -9293,6 +9273,43 @@ const tech = {
},
remove() {}
},
+ {
+ name: "tinker",
+ description: "permanently unlock JUNK tech in experiment mode
this effect is stored for future visits",
+ 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: ${Math.initialSeed}
no one is allow to use your seeds
if they use them they are gonna get in trouble
your seeds: ${localSettings.personalSeeds.join()}` },
+ 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
//************************************************** tech
diff --git a/todo.txt b/todo.txt
index 632c2a3..bc4630b 100644
--- a/todo.txt
+++ b/todo.txt
@@ -1,14 +1,25 @@
******************************************************** NEXT PATCH **************************************************
-JUNK tech: meteor shower - take a shower, but meteors instead of water
-JUNK tech: discount - get 3 random JUNK tech for the price of 1!
+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
-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 ********************************************************
+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
needles
@@ -40,6 +51,8 @@ bug: often game puts player position at NaN
clues:
maybe with vanish or other special blocks and grapple hook
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 on tons of bullets
maybe grappling hook, Bulk modulus
@@ -88,10 +101,6 @@ setting to remove UI, except health bar
except active gun? to see ammo
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...
throwing blocks
charging railgun