4 community levels
new community levels: (you can enable community maps in the settings) rings by thatLittleFrog flappyGon by Digin trial by Cirryn and Tarantula Hawk arena level updated by Whyisthisnotavalable difficulty scaling: 0.84->0.85x player damage per level research spawn per level is no longer in the difficulty settings instead players get 1 research for only the first few levels cell boss has less health at high difficulty converted JUNK tech to additive, instead of the multiplicative makes the first JUNK you take do the same, but if you take too much you can get to 100% right aligned some text in tech descriptions added some circles to the in-game console messages renamed slow light -> delayed-choice - a single 0.4 second delayed 0.7x damage laser beam also now works with reflection plasma torch field gets 1.5x damage by default molecular assembler coupling 0.8->0.6 energy per second nail-bot upgrade 5->4x fire rate foam-bot upgrade 3->2.5x size and fire rate sound-bot upgrade 2.5->2x fire rate, damage, 1->2x wave packet length boom-bot upgrade reduced range, bot acceleration orbital-bot upgrade 1.5->2x radius perimeter defense 0.95->0.96x damage taken per bot network effect 1.05->1.04x damage per bot tech: working mass - cleaned up physics and logic a bit negative feedback scales with health below maxHealth, not health below 100 1.007->1.006x damage per missing health homeostasis scales with missing health, not health below 100 limit of 0.2x at 0 health
This commit is contained in:
192
js/player.js
192
js/player.js
@@ -553,17 +553,18 @@ const m = {
|
||||
if (tech.isHarmMACHO) dmg *= tech.isMoveMACHO ? 0.3 : 0.4
|
||||
if (tech.isImmortal) dmg *= 0.7
|
||||
if (m.fieldMode === 0 || m.fieldMode === 3) dmg *= 0.973 ** m.coupling
|
||||
if (tech.isLowHealthDefense) dmg *= 1 - Math.max(0, 1 - m.health) * 0.8
|
||||
if (tech.isHarmReduceNoKill && m.lastKillCycle + 300 < m.cycle) dmg *= 0.3
|
||||
if (tech.isAddBlockMass && m.isHolding) dmg *= 0.1
|
||||
if (tech.isSpeedHarm && (tech.speedAdded + player.speed) > 0.1) dmg *= 1 - Math.min((tech.speedAdded + player.speed) * 0.0193, 0.8) //capped at speed of 55
|
||||
if (tech.isHarmReduce && input.field) dmg *= 0.1
|
||||
if (tech.isNeutronium && input.field && m.fieldCDcycle < m.cycle) dmg *= 0.05
|
||||
if (tech.isBotArmor) dmg *= 0.95 ** b.totalBots()
|
||||
if (tech.isBotArmor) dmg *= 0.96 ** b.totalBots()
|
||||
if (tech.isHarmArmor && m.lastHarmCycle + 600 > m.cycle) dmg *= 0.3;
|
||||
if (tech.isNoFireDefense && m.cycle > m.fireCDcycle + 120) dmg *= 0.3
|
||||
if (tech.isTurret && m.crouch) dmg *= 0.3;
|
||||
if (tech.isFirstDer && b.inventory[0] === b.activeGun) dmg *= 0.85 ** b.inventory.length
|
||||
// if (tech.isLowHealthDefense) dmg *= Math.pow(0.3, Math.max(0, (tech.isEnergyHealth ? m.maxEnergy - m.energy : m.maxHealth - m.health)))
|
||||
if (tech.isLowHealthDefense) dmg *= Math.pow(0.2, Math.max(0, 1 - (tech.isEnergyHealth ? m.energy / m.maxEnergy : m.health / m.maxHealth)))
|
||||
// return tech.isEnergyHealth ? Math.pow(dmg, 0.7) : dmg //defense has less effect
|
||||
// dmg *= m.fieldHarmReduction
|
||||
return dmg * m.fieldHarmReduction
|
||||
@@ -2115,7 +2116,7 @@ const m = {
|
||||
isFieldActive: false,
|
||||
fieldRange: 155,
|
||||
fieldShieldingScale: 1,
|
||||
// fieldDamage: 1,
|
||||
fieldDamage: 1,
|
||||
isSneakAttack: false,
|
||||
lastHit: 0, //stores value of last damage player took above a threshold, in m.damage
|
||||
sneakAttackCycle: 0,
|
||||
@@ -2152,6 +2153,7 @@ const m = {
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
m.fieldShieldingScale = 1;
|
||||
m.fieldBlockCD = 10;
|
||||
m.fieldDamage = 1
|
||||
m.fieldHarmReduction = 1;
|
||||
m.lastHit = 0
|
||||
m.isSneakAttack = false
|
||||
@@ -2241,7 +2243,7 @@ const m = {
|
||||
} else {
|
||||
m.fieldRegen = 0.001 //6 energy per second
|
||||
}
|
||||
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.000133 * m.coupling
|
||||
if (m.fieldMode === 0 || m.fieldMode === 4) m.fieldRegen += 0.0001 * m.coupling
|
||||
if (tech.isTimeCrystals) {
|
||||
m.fieldRegen *= 2.5
|
||||
} else if (tech.isGroundState) {
|
||||
@@ -2867,7 +2869,7 @@ const m = {
|
||||
case 3: //negative mass
|
||||
return `<strong>${(0.973 ** couple).toFixed(2)}x</strong> <strong class='color-defense'>damage taken</strong>`
|
||||
case 4: //assembler
|
||||
return `<strong>+${(0.8 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
|
||||
return `<strong>+${(0.6 * couple).toFixed(1)}</strong> <strong class='color-f'>energy</strong> per second`
|
||||
case 5: //plasma
|
||||
return `<strong>${(1 + 0.015 * couple).toFixed(3)}x</strong> <strong class='color-d'>damage</strong>`
|
||||
case 6: //time dilation
|
||||
@@ -2883,7 +2885,7 @@ const m = {
|
||||
}
|
||||
},
|
||||
couplingChange(change = 0) {
|
||||
if (change > 0 && level.onLevel !== -1) simulation.makeTextLog(`m.coupling <span class='color-symbol'>+=</span> ${change}`, 60); //level.onLevel !== -1 means not on lore level
|
||||
if (change > 0 && level.onLevel !== -1) simulation.makeTextLog(`<div class="coupling-circle"></div> m.coupling <span class='color-symbol'>+=</span> ${change}`, 60); //level.onLevel !== -1 means not on lore level
|
||||
m.coupling += change
|
||||
if (m.coupling < 0) {
|
||||
//look for coupling power ups on this level and remove them to prevent exploiting tech ejections
|
||||
@@ -2921,7 +2923,7 @@ const m = {
|
||||
document.getElementById("field").innerHTML = m.fieldUpgrades[index].name
|
||||
m.setHoldDefaults();
|
||||
m.fieldUpgrades[index].effect();
|
||||
simulation.makeTextLog(`<span class='color-var'>m</span>.setField("<span class='color-text'>${m.fieldUpgrades[m.fieldMode].name}</span>")`);
|
||||
simulation.makeTextLog(`<div class="circle-grid field"></div> <span class='color-var'>m</span>.setField("<strong class='color-text'>${m.fieldUpgrades[m.fieldMode].name}</strong>")<br>input.key.field<span class='color-symbol'>:</span> ["<span class='color-text'>MouseRight</span>"]`);
|
||||
},
|
||||
fieldUpgrades: [{
|
||||
name: "field emitter",
|
||||
@@ -3058,7 +3060,7 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "perfect diamagnetism",
|
||||
description: "<strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br>maintains <strong>functionality</strong> while <strong>inactive</strong><br><strong>5</strong> <strong class='color-f'>energy</strong> per second",
|
||||
description: "<strong>deflecting</strong> does not drain <strong class='color-f'>energy</strong><br><strong>shield</strong> maintains <strong>functionality</strong> while inactive<br><strong>5</strong> <strong class='color-f'>energy</strong> per second",
|
||||
effect: () => {
|
||||
m.fieldMeterColor = "#48f" //"#0c5"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
@@ -3481,11 +3483,11 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "molecular assembler",
|
||||
description: `excess <strong class='color-f'>energy</strong> used to <strong class='color-print'>print</strong> ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
description: `use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>excess <strong class='color-f'>energy</strong> used to <strong class='color-print'>print</strong> ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br><strong>12</strong> <strong class='color-f'>energy</strong> per second`,
|
||||
setDescription() {
|
||||
return `excess <strong class='color-f'>energy</strong> used to <strong class='color-print'>print</strong> ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br>use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br><strong>12</strong> <strong class='color-f'>energy</strong> per second`
|
||||
return `use <strong class='color-f'>energy</strong> to <strong>deflect</strong> mobs<br>excess <strong class='color-f'>energy</strong> used to <strong class='color-print'>print</strong> ${simulation.molecularMode === 0 ? "<strong class='color-p' style='letter-spacing: 2px;'>spores" : simulation.molecularMode === 1 ? "<strong>missiles" : simulation.molecularMode === 2 ? "<strong class='color-s'>ice IX" : "<strong>drones"}</strong><br><strong>12</strong> <strong class='color-f'>energy</strong> per second`
|
||||
},
|
||||
blockJumpPhase: 0,
|
||||
|
||||
effect: () => {
|
||||
m.fieldMeterColor = "#ff0"
|
||||
m.eyeFillColor = m.fieldMeterColor
|
||||
@@ -3596,115 +3598,15 @@ const m = {
|
||||
m.holdingTarget = null; //clears holding target (this is so you only pick up right after the field button is released and a hold target exists)
|
||||
}
|
||||
m.drawRegenEnergy()
|
||||
|
||||
if (tech.isBlockJump) {
|
||||
if (m.onGround && m.buttonCD_jump + 10 < m.cycle) this.blockJumpPhase = 0 //reset after touching ground or block
|
||||
if (this.blockJumpPhase === 0 && !m.onGround) { //1st jump or fall
|
||||
this.blockJumpPhase = 1
|
||||
} else if (this.blockJumpPhase === 1 && !input.up && m.buttonCD_jump + 10 < m.cycle) { //not pressing jump
|
||||
this.blockJumpPhase = 2
|
||||
} else if (this.blockJumpPhase === 2 && input.up && m.buttonCD_jump + 10 < m.cycle) { //2nd jump
|
||||
this.blockJumpPhase = 3
|
||||
|
||||
//make a block
|
||||
const radius = 25 + Math.floor(15 * Math.random())
|
||||
body[body.length] = Matter.Bodies.polygon(m.pos.x, m.pos.y + 65 + radius, 4, radius, {
|
||||
friction: 0.05,
|
||||
frictionAir: 0.001,
|
||||
collisionFilter: {
|
||||
category: cat.body,
|
||||
mask: cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
|
||||
},
|
||||
classType: "body",
|
||||
});
|
||||
const block = body[body.length - 1]
|
||||
//mess with the block shape (this code is horrible)
|
||||
Composite.add(engine.world, block); //add to world
|
||||
const r1 = radius * (1 + 0.4 * Math.random())
|
||||
const r2 = radius * (1 + 0.4 * Math.random())
|
||||
let angle = 0
|
||||
const vertices = []
|
||||
for (let i = 0, len = block.vertices.length; i < len; i++) {
|
||||
angle += 2 * Math.PI / len
|
||||
vertices.push({ x: block.position.x + r1 * Math.cos(angle), y: block.position.y + r2 * Math.sin(angle) })
|
||||
}
|
||||
Matter.Body.setVertices(block, vertices)
|
||||
Matter.Body.setAngle(block, Math.PI / 4)
|
||||
Matter.Body.setVelocity(block, { x: 0.9 * player.velocity.x, y: 10 });
|
||||
Matter.Body.applyForce(block, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
|
||||
if (tech.isBlockRestitution) {
|
||||
block.restitution = 0.999 //extra bouncy
|
||||
block.friction = block.frictionStatic = block.frictionAir = 0.001
|
||||
}
|
||||
if (tech.isAddBlockMass) {
|
||||
const expand = function (that, massLimit) {
|
||||
if (that.mass < massLimit) {
|
||||
const scale = 1.04;
|
||||
Matter.Body.scale(that, scale, scale);
|
||||
setTimeout(expand, 20, that, massLimit);
|
||||
}
|
||||
};
|
||||
expand(block, Math.min(20, block.mass * 3))
|
||||
}
|
||||
//jump
|
||||
m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
|
||||
let horizontalVelocity = 8 * (- input.left + input.right)
|
||||
Matter.Body.setVelocity(player, { x: player.velocity.x + horizontalVelocity, y: -7.5 + 0.25 * player.velocity.y });
|
||||
player.force.y = -m.jumpForce; //player jump force
|
||||
} else if (this.blockJumpPhase === 3 && m.onGround && m.buttonCD_jump + 10 < m.cycle) {
|
||||
//reset
|
||||
this.blockJumpPhase = 0 //reset
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// if (tech.isBlockJump) {
|
||||
// //make sure only 1 ephemera is running
|
||||
// simulation.ephemera.push({
|
||||
// name: "2 jump",
|
||||
// mode: 0,
|
||||
// do() {
|
||||
// // console.log('hi')
|
||||
// if (m.buttonCD_jump + 20 < m.cycle && m.onGround) simulation.removeEphemera(this.name)
|
||||
// if (this.mode === 0) {
|
||||
// if (!input.up) this.mode = 1
|
||||
// } else if (this.mode === 1) {
|
||||
// if (input.up && m.buttonCD_jump + 20 < m.cycle) {
|
||||
// simulation.removeEphemera(this.name)
|
||||
// //make a block
|
||||
// body[body.length] = Matter.Bodies.polygon(m.pos.x, m.pos.y + 80, 4, 30 + Math.floor(10 * Math.random()), {
|
||||
// friction: 0.05,
|
||||
// frictionAir: 0.001,
|
||||
// collisionFilter: {
|
||||
// category: cat.body,
|
||||
// mask: cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
|
||||
// },
|
||||
// classType: "body",
|
||||
// // isPrinted: true,
|
||||
// });
|
||||
// const who = body[body.length - 1]
|
||||
// Composite.add(engine.world, who); //add to world
|
||||
// Matter.Body.setVelocity(who, { x: player.velocity.x * 0.5, y: +30 });
|
||||
// Matter.Body.applyForce(who, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
|
||||
|
||||
// //jump again
|
||||
// m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
|
||||
// player.force.y = -m.jumpForce; //player jump force
|
||||
// Matter.Body.setVelocity(player, { x: player.velocity.x, y: -7.5 + 0.25 * player.velocity.y });
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// })
|
||||
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "plasma torch",
|
||||
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong class='color-d'>damages</strong> and <strong>pushes</strong> mobs away<br><strong>10</strong> <strong class='color-f'>energy</strong> per second",
|
||||
description: "use <strong class='color-f'>energy</strong> to emit short range <strong class='color-plasma'>plasma</strong><br><strong>1.5x</strong> <strong class='color-d'>damage</strong><br><strong>10</strong> <strong class='color-f'>energy</strong> per second",
|
||||
set() {
|
||||
b.isExtruderOn = false
|
||||
m.fieldDamage = 1.5
|
||||
// m.fieldCDcycleAlternate = 0
|
||||
|
||||
if (m.plasmaBall) {
|
||||
@@ -4500,16 +4402,18 @@ const m = {
|
||||
}
|
||||
this.drawRegenEnergyCloaking()
|
||||
if (m.isSneakAttack && m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) > m.cycle) { //show sneak attack status
|
||||
m.fieldDamage = 4.5 * (1 + 0.033 * m.coupling)
|
||||
const timeLeft = (m.sneakAttackCycle + Math.min(100, 0.66 * (m.cycle - m.enterCloakCycle)) - m.cycle) * 0.5
|
||||
ctx.beginPath();
|
||||
ctx.arc(m.pos.x, m.pos.y, 32, 0, 2 * Math.PI);
|
||||
ctx.strokeStyle = "rgba(180,30,70,0.5)";//"rgba(0,0,0,0.7)";//"rgba(255,255,255,0.7)";//"rgba(255,0,100,0.7)";
|
||||
ctx.lineWidth = Math.max(Math.min(10, timeLeft), 3);
|
||||
ctx.stroke();
|
||||
|
||||
// ctx.globalCompositeOperation = "multiply";
|
||||
// m.drawCloakedM()
|
||||
// ctx.globalCompositeOperation = "source-over";
|
||||
} else {
|
||||
m.fieldDamage = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4742,66 +4646,6 @@ const m = {
|
||||
m.fieldRadius = 0
|
||||
}
|
||||
m.drawRegenEnergy("rgba(0,0,0,0.2)")
|
||||
|
||||
if (tech.isBlockJump) {
|
||||
if (m.onGround && m.buttonCD_jump + 10 < m.cycle) this.blockJumpPhase = 0 //reset after touching ground or block
|
||||
if (this.blockJumpPhase === 0 && !m.onGround) { //1st jump or fall
|
||||
this.blockJumpPhase = 1
|
||||
} else if (this.blockJumpPhase === 1 && !input.up && m.buttonCD_jump + 10 < m.cycle) { //not pressing jump
|
||||
this.blockJumpPhase = 2
|
||||
} else if (this.blockJumpPhase === 2 && input.up && m.buttonCD_jump + 10 < m.cycle) { //2nd jump
|
||||
this.blockJumpPhase = 3
|
||||
|
||||
//make a block
|
||||
const radius = 25 + Math.floor(15 * Math.random())
|
||||
body[body.length] = Matter.Bodies.polygon(m.pos.x, m.pos.y + 60 + radius, 4, radius, {
|
||||
friction: 0.05,
|
||||
frictionAir: 0.001,
|
||||
collisionFilter: {
|
||||
category: cat.body,
|
||||
mask: cat.player | cat.map | cat.body | cat.bullet | cat.mob | cat.mobBullet
|
||||
},
|
||||
classType: "body",
|
||||
});
|
||||
const block = body[body.length - 1]
|
||||
//mess with the block shape (this code is horrible)
|
||||
Composite.add(engine.world, block); //add to world
|
||||
const r1 = radius * (1 + 0.4 * Math.random())
|
||||
const r2 = radius * (1 + 0.4 * Math.random())
|
||||
let angle = 0
|
||||
const vertices = []
|
||||
for (let i = 0, len = block.vertices.length; i < len; i++) {
|
||||
angle += 2 * Math.PI / len
|
||||
vertices.push({ x: block.position.x + r1 * Math.cos(angle), y: block.position.y + r2 * Math.sin(angle) })
|
||||
}
|
||||
Matter.Body.setVertices(block, vertices)
|
||||
Matter.Body.setAngle(block, Math.PI / 4)
|
||||
Matter.Body.setVelocity(block, { x: 0.9 * player.velocity.x, y: 10 });
|
||||
Matter.Body.applyForce(block, m.pos, { x: 0, y: m.jumpForce * 0.12 * Math.min(m.standingOn.mass, 5) });
|
||||
if (tech.isBlockRestitution) {
|
||||
block.restitution = 0.999 //extra bouncy
|
||||
block.friction = block.frictionStatic = block.frictionAir = 0.001
|
||||
}
|
||||
if (tech.isAddBlockMass) {
|
||||
const expand = function (that, massLimit) {
|
||||
if (that.mass < massLimit) {
|
||||
const scale = 1.04;
|
||||
Matter.Body.scale(that, scale, scale);
|
||||
setTimeout(expand, 20, that, massLimit);
|
||||
}
|
||||
};
|
||||
expand(block, Math.min(20, block.mass * 3))
|
||||
}
|
||||
//jump
|
||||
m.buttonCD_jump = m.cycle; //can't jump again until 20 cycles pass
|
||||
let horizontalVelocity = 8 * (- input.left + input.right)
|
||||
Matter.Body.setVelocity(player, { x: player.velocity.x + horizontalVelocity, y: -7.5 + 0.25 * player.velocity.y });
|
||||
player.force.y = -m.jumpForce; //player jump force
|
||||
} else if (this.blockJumpPhase === 3 && m.onGround && m.buttonCD_jump + 10 < m.cycle) {
|
||||
//reset
|
||||
this.blockJumpPhase = 0 //reset
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user