Bayesian statistics

blocks drift towards the center of pilot wave's field

mod: Bayesian statistics - no longer stops ammo spawns
  30% to double power ups, but ejects a mod when you take damage

mod: exciton-lattice - 40% damage, but no ammo can spawn
This commit is contained in:
landgreen
2020-09-08 17:38:44 -07:00
parent e3d8dda23f
commit 8ce7f684c8
11 changed files with 135 additions and 107 deletions

View File

@@ -243,7 +243,7 @@ const b = {
sub = Vector.sub(where, mob[i].position);
dist = Vector.magnitude(sub) - mob[i].radius;
if (dist < radius) {
if (mob[i].shield) dmg *= 3 //balancing explosion dmg to shields
if (mob[i].shield) dmg *= 2.5 //balancing explosion dmg to shields
if (Matter.Query.ray(map, mob[i].position, where).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
mob[i].damage(dmg * damageScale * b.dmgScale);
mob[i].locatePlayer();
@@ -2378,7 +2378,7 @@ const b = {
if (Vector.magnitude(Vector.sub(mob[i].position, this.position)) < this.damageRadius) {
let dmg = b.dmgScale * 0.023
if (Matter.Query.ray(map, mob[i].position, this.position).length > 0) dmg *= 0.5 //reduce damage if a wall is in the way
if (mob[i].shield) dmg *= 5 //x5 to make up for the /5 that shields normally take
if (mob[i].shield) dmg *= 4 //x5 to make up for the /5 that shields normally take
mob[i].damage(dmg);
mob[i].locatePlayer();
}

View File

@@ -148,13 +148,13 @@ function collisionChecks(event) {
dmg *= 0.85
}
mech.damage(dmg);
if (mod.isEjectMod) {
if (mod.isBayesian) {
const have = [] //find which mods you have
for (let i = 0; i < mod.mods.length; i++) {
if (mod.mods[i].count > 0) have.push(i)
}
const choose = have[Math.floor(Math.random() * have.length)]
game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> ejected by exciton-lattice`, 300) //message about what mod was lost
game.makeTextLog(`<div class='circle mod'></div> &nbsp; <strong>${mod.mods[choose].name}</strong> ejected by Bayesian statistics`, 300) //message about what mod was lost
for (let i = 0; i < mod.mods[choose].count; i++) powerUps.spawn(mech.pos.x, mech.pos.y, "mod");
mod.mods[choose].count = 0;
mod.mods[choose].remove(); // remove a random mod form the list of mods you have

View File

@@ -381,6 +381,28 @@ const game = {
// }
// setupCanvas();
// }
//color testing
// if (keys[49]) {
// mech.color.hue--
// mech.setFillColors();
// } else if (keys[50]) {
// mech.color.hue++
// mech.setFillColors();
// } else if (keys[51]) {
// mech.color.sat--
// mech.setFillColors();
// } else if (keys[52]) {
// mech.color.sat++
// mech.setFillColors();
// } else if (keys[53]) {
// mech.color.light--
// mech.setFillColors();
// } else if (keys[54]) {
// mech.color.light++
// mech.setFillColors();
// }
if (keys[69]) { // e swap to next active gun
game.nextGun();
} else if (keys[81]) { //q swap to previous active gun

View File

@@ -84,32 +84,20 @@ window.addEventListener('load', (event) => {
}
if (property.substring(0, 3) === "mod") {
let found = false
let index
for (let i = 0; i < mod.mods.length; i++) {
if (set[property] === mod.mods[i].name) {
index = i;
found = true;
build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod', true)
break;
}
}
if (found) build.choosePowerUp(document.getElementById(`mod-${index}`), index, 'mod', true)
}
if (property === "difficulty") {
game.difficultyMode = Number(set[property])
// localSettings.difficultyMode = Number(set[property])
// localStorage.setItem("localSettings", JSON.stringify(localSettings)); //update local storage
// document.getElementById("difficulty-select").value = Number(set[property])
document.getElementById("difficulty-select-custom").value = Number(set[property])
}
if (property === "level") {
document.getElementById("starting-level").value = Number(set[property])
// level.levelsCleared += Number(set[property]);
// level.difficultyIncrease(Number(set[property]) * game.difficultyMode) //increase difficulty based on modes
// spawn.setSpawnList(); //picks a couple mobs types for a themed random mob spawns
// level.onLevel++
}
}
}
@@ -265,12 +253,8 @@ const build = {
modID.classList.add("build-grid-disabled");
modID.onclick = null
}
if (mod.mods[i].count > 0) {
mod.removeMod(i)
}
if (modID.classList.contains("build-mod-selected")) {
modID.classList.remove("build-mod-selected");
}
if (mod.mods[i].count > 0) mod.removeMod(i)
if (modID.classList.contains("build-mod-selected")) modID.classList.remove("build-mod-selected");
}
}
}
@@ -425,6 +409,7 @@ document.getElementById("build-button").addEventListener("click", () => { //setu
modList.push(mod.mods[i].count)
}
}
openCustomBuildMenu();
if (!game.firstRun) { //if player has already died once load that previous build
@@ -435,7 +420,32 @@ document.getElementById("build-button").addEventListener("click", () => { //setu
}
for (let i = 0; i < modList.length; i++) {
for (let j = 0; j < modList[i]; j++) {
build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod')
build.choosePowerUp(document.getElementById(`mod-${i}`), i, 'mod', true)
}
}
//update mod text //disable not allowed mods
for (let i = 0, len = mod.mods.length; i < len; i++) {
const modID = document.getElementById("mod-" + i)
if (!mod.mods[i].isCustomHide) {
if (mod.mods[i].allowed() || mod.mods[i].count > 1) {
if (mod.mods[i].count > 1) {
modID.innerHTML = `<div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name} (${mod.mods[i].count}x)</div>${mod.mods[i].description}</div>`
} else {
modID.innerHTML = `<div class="grid-title"><div class="circle-grid mod"></div> &nbsp; ${mod.mods[i].name}</div>${mod.mods[i].description}</div>`
}
if (modID.classList.contains("build-grid-disabled")) {
modID.classList.remove("build-grid-disabled");
modID.setAttribute("onClick", `javascript: build.choosePowerUp(this,${i},'mod')`);
}
} else {
modID.innerHTML = `<div class="grid-title"><div class="circle-grid grey"></div> &nbsp; ${mod.mods[i].name}</div><span style="color:#666;"><strong>requires:</strong> ${mod.mods[i].requires}</span></div>`
if (!modID.classList.contains("build-grid-disabled")) {
modID.classList.add("build-grid-disabled");
modID.onclick = null
}
// if (mod.mods[i].count > 0) mod.removeMod(i)
// if (modID.classList.contains("build-mod-selected")) modID.classList.remove("build-mod-selected");
}
}
}
}

View File

@@ -15,7 +15,7 @@ const level = {
// game.zoomScale = 1000;
// game.setZoom();
// mech.isStealth = true;
// mech.setField("time dilation field")
// mech.setField("pilot wave")
// b.giveGuns("ice IX")
// mod.giveMod("quantum immortality");
@@ -3166,8 +3166,8 @@ const level = {
difficultyIncrease(num = 1) {
for (let i = 0; i < num; i++) {
game.difficulty++
game.dmgScale += 0.3; //damage done by mobs increases each level
b.dmgScale *= 0.93; //damage done by player decreases each level
game.dmgScale += 0.35; //damage done by mobs increases each level
b.dmgScale *= 0.92; //damage done by player decreases each level
if (game.accelScale < 5) game.accelScale *= 1.027 //mob acceleration increases each level
if (game.lookFreqScale > 0.2) game.lookFreqScale *= 0.975 //mob cycles between looks decreases each level
if (game.CDScale > 0.2) game.CDScale *= 0.966 //mob CD time decreases each level
@@ -3177,9 +3177,9 @@ const level = {
difficultyDecrease(num = 1) { //used in easy mode for game.reset()
for (let i = 0; i < num; i++) {
game.difficulty--
game.dmgScale -= 0.3; //damage done by mobs increases each level
game.dmgScale -= 0.35; //damage done by mobs increases each level
if (game.dmgScale < 0.1) game.dmgScale = 0.1;
b.dmgScale /= 0.93; //damage done by player decreases each level
b.dmgScale /= 0.92; //damage done by player decreases each level
if (game.accelScale > 0.2) game.accelScale /= 1.027 //mob acceleration increases each level
if (game.lookFreqScale < 5) game.lookFreqScale /= 0.975 //mob cycles between looks decreases each level
if (game.CDScale < 5) game.CDScale /= 0.966 //mob CD time decreases each level

View File

@@ -60,37 +60,37 @@ const mobs = {
});
}
function applySlow(target) {
if (!target.shield && !target.isShielded && !mech.isBodiesAsleep) {
if (target.isBoss) cycles = Math.floor(cycles * 0.25)
function applySlow() {
if (!who.shield && !who.isShielded && !mech.isBodiesAsleep) {
if (who.isBoss) cycles = Math.floor(cycles * 0.25)
let i = target.status.length
let i = who.status.length
while (i--) {
if (target.status[i].type === "slow") target.status.splice(i, 1); //remove other "slow" effects on this mob
if (who.status[i].type === "slow") who.status.splice(i, 1); //remove other "slow" effects on this mob
}
target.isSlowed = true;
target.status.push({
who.isSlowed = true;
who.status.push({
effect() {
Matter.Body.setVelocity(target, {
Matter.Body.setVelocity(who, {
x: 0,
y: 0
});
Matter.Body.setAngularVelocity(target, 0);
Matter.Body.setAngularVelocity(who, 0);
ctx.beginPath();
ctx.moveTo(target.vertices[0].x, target.vertices[0].y);
for (let j = 1, len = target.vertices.length; j < len; ++j) {
ctx.lineTo(target.vertices[j].x, target.vertices[j].y);
ctx.moveTo(who.vertices[0].x, who.vertices[0].y);
for (let j = 1, len = who.vertices.length; j < len; ++j) {
ctx.lineTo(who.vertices[j].x, who.vertices[j].y);
}
ctx.lineTo(target.vertices[0].x, target.vertices[0].y);
ctx.lineTo(who.vertices[0].x, who.vertices[0].y);
ctx.strokeStyle = "rgba(0,100,255,0.8)";
ctx.lineWidth = 15;
ctx.stroke();
ctx.fillStyle = target.fill
ctx.fillStyle = who.fill
ctx.fill();
},
endEffect() {
//check to see if there are not other freeze effects?
target.isSlowed = false;
who.isSlowed = false;
},
type: "slow",
endCycle: game.cycle + cycles,
@@ -110,6 +110,7 @@ const mobs = {
while (i--) {
if (who.status[i].type === "stun") who.status.splice(i, 1);
}
who.isStunned = true;
who.status.push({
effect() {
who.seePlayer.yes = false;
@@ -142,7 +143,9 @@ const mobs = {
},
endEffect() {},
endEffect() {
who.isStunned = false
},
type: "stun",
endCycle: game.cycle + cycles,
})
@@ -996,7 +999,7 @@ const mobs = {
dmg *= mod.damageFromMods()
//mobs specific damage changes
if (mod.isFarAwayDmg) dmg *= 1 + Math.sqrt(Math.max(500, Math.min(3000, this.distanceToPlayer())) - 500) * 0.0067 //up to 50% dmg at max range of 3500
if (this.shield) dmg *= 0.05
if (this.shield) dmg *= 0.075
//energy and heal drain should be calculated after damage boosts
if (mod.energySiphon && dmg !== Infinity && this.dropPowerUp) {

View File

@@ -79,8 +79,9 @@ const mod = {
},
damageFromMods() {
let dmg = 1
if (mod.isEnergyNoAmmo) dmg *= 1.4
if (mod.isDamageForGuns) dmg *= 1 + 0.07 * b.inventory.length
if (mod.isLowHealthDmg) dmg *= 1 + 0.5 * Math.max(0, 1 - mech.health)
if (mod.isLowHealthDmg) dmg *= 1 + 0.6 * Math.max(0, 1 - mech.health)
if (mod.isHarmDamage && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 2;
if (mod.isEnergyLoss) dmg *= 1.37;
if (mod.isAcidDmg && mech.health > 1) dmg *= 1.4;
@@ -126,6 +127,22 @@ const mod = {
mod.isEnergyDamage = false;
}
},
{
name: "exciton-lattice",
description: `increase <strong class='color-d'>damage</strong> by <strong>40%</strong>, but<br><strong class='color-g'>ammo</strong> will no longer <strong>spawn</strong>`,
maxCount: 1,
count: 0,
allowed() {
return (mod.haveGunCheck("nail gun") && mod.isIceCrystals) || mod.haveGunCheck("laser") || mod.haveGunCheck("pulse") || mech.fieldUpgrades[mech.fieldMode].name === "plasma torch" || mech.fieldUpgrades[mech.fieldMode].name === "nano-scale manufacturing" || mech.fieldUpgrades[mech.fieldMode].name === "pilot wave"
},
requires: "energy based damage",
effect() {
mod.isEnergyNoAmmo = true;
},
remove() {
mod.isEnergyNoAmmo = false;
}
},
{
name: "acute stress response",
description: "increase <strong class='color-d'>damage</strong> by <strong>37%</strong><br>if a mob <strong>dies</strong> drain stored <strong class='color-f'>energy</strong> by <strong>25%</strong>",
@@ -193,7 +210,7 @@ const mod = {
},
{
name: "negative feedback",
description: "increase <strong class='color-d'>damage</strong> by <strong>5%</strong><br>for every <strong>10%</strong> missing base <strong>health</strong>",
description: "increase <strong class='color-d'>damage</strong> by <strong>6%</strong><br>for every <strong>10%</strong> missing base <strong>health</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -713,22 +730,6 @@ const mod = {
mod.isHarmArmor = false;
}
},
{
name: "exciton-lattice",
description: `reduce <strong class='color-harm'>harm</strong> by <strong>80%</strong>, but<br>after a <strong>collision</strong>, <strong>eject</strong> one of your <strong class='color-m'>mods</strong>`,
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth && (mod.isBayesian || mod.isExtraChoice || mod.manyWorlds || mod.isImmortal || mod.isMineDrop || mod.renormalization)
},
requires: "Bayesian, cardinality, many worlds, immortality, renormalization, or mine synthesis",
effect() {
mod.isEjectMod = true;
},
remove() {
mod.isEjectMod = false;
}
},
{
name: "clock gating",
description: `<strong>slow</strong> <strong>time</strong> by <strong>50%</strong> after receiving <strong class='color-harm'>harm</strong><br>reduce <strong class='color-harm'>harm</strong> by <strong>15%</strong>`,
@@ -768,9 +769,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return mod.superposition + !!mod.isStunField + mod.isPulseStun + !!mod.isNeutronStun + mod.oneSuperBall + mod.isHarmFreeze + mod.isIceField + mod.isIceCrystals + mod.isSporeFreeze + mod.isAoESlow + mod.isFreezeMobs + mod.isPilotFreeze + mod.haveGunCheck("ice IX") > 1
return mod.superposition || mod.isStunField || mod.isPulseStun || mod.isNeutronStun || mod.oneSuperBall || mod.isHarmFreeze || mod.isIceField || mod.isIceCrystals || mod.isSporeFreeze || mod.isAoESlow || mod.isFreezeMobs || mod.isPilotFreeze || mod.haveGunCheck("ice IX")
},
requires: "at least 2 freezing or stunning effects",
requires: "a freezing or stunning effect",
effect() {
mod.isFreezeHarmImmune = true;
},
@@ -1027,8 +1028,8 @@ const mod = {
}
},
{
name: "Bayesian inference",
description: "<strong>33%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-g'>ammo</strong> will no longer <strong>spawn</strong>",
name: "Bayesian statistics",
description: "<strong>25%</strong> chance to <strong>duplicate</strong> spawned <strong>power ups</strong><br>after a <strong>collision</strong>, <strong>eject</strong> one of your <strong class='color-m'>mods</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -1110,9 +1111,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return !mod.isBayesian
return true
},
requires: "not Bayesian inference",
requires: "",
effect() {
mod.isAmmoForGun = true;
},
@@ -1144,9 +1145,9 @@ const mod = {
maxCount: 1,
count: 0,
allowed() {
return !mod.isEnergyHealth && !mod.isBayesian
return !mod.isEnergyHealth
},
requires: "not mass-energy equivalence<br>not Bayesian inference",
requires: "not mass-energy equivalence",
effect: () => {
mod.isAmmoFromHealth = 0.023;
},
@@ -1840,7 +1841,7 @@ const mod = {
},
{
name: "inertial confinement",
description: "<strong>neutron bomb's</strong> initial detonation <br><strong>stuns</strong> nearby mobs for <strong>1</strong> seconds",
description: "<strong>neutron bomb's</strong> detonation <br><strong>stuns</strong> nearby mobs for <strong>1.5</strong> seconds",
maxCount: 3,
count: 0,
allowed() {
@@ -1848,7 +1849,7 @@ const mod = {
},
requires: "neutron bomb",
effect() {
mod.isNeutronStun += 60;
mod.isNeutronStun += 90;
},
remove() {
mod.isNeutronStun = 0;
@@ -2183,7 +2184,7 @@ const mod = {
},
{
name: "shock wave",
description: "mobs caught in <strong>pulse's</strong> explosion are <strong>stunned</strong>",
description: "mobs caught in <strong>pulse's</strong> explosion are <strong>stunned</strong><br>for up to <strong>2 seconds</strong>",
maxCount: 1,
count: 0,
allowed() {
@@ -2719,6 +2720,6 @@ const mod = {
nailGun: null,
nailInstantFireRate: null,
isCapacitor: null,
isEjectMod: null,
isEnergyNoAmmo: null,
isFreezeHarmImmune: null
}

View File

@@ -59,13 +59,15 @@ const mech = {
radius: 30,
fillColor: "#fff",
fillColorDark: "#ccc",
color: {
hue: 0,
sat: 0,
light: 100,
},
setFillColors() {
const hue = 0
const saturation = 10
const light = 70 + mech.harmReduction() * 30
// console.log(mech.harmReduction())
this.fillColor = `hsl(${hue},${saturation}%,${light}%)`
this.fillColorDark = `hsl(${hue},${saturation}%,${light-20}%)`
console.log(mech.color)
this.fillColor = `hsl(${mech.color.hue},${mech.color.sat}%,${mech.color.light}%)`
this.fillColorDark = `hsl(${mech.color.hue},${mech.color.sat}%,${mech.color.light-20}%)`
},
height: 42,
yOffWhen: {
@@ -473,7 +475,6 @@ const mech = {
let dmg = 1
dmg *= mech.fieldHarmReduction
dmg *= mod.isSlowFPS ? 0.85 : 1
if (mod.isEjectMod) dmg *= 0.2
if (mod.isHarmReduce && mech.fieldUpgrades[mech.fieldMode].name === "negative mass field" && mech.isFieldActive) dmg *= 0.6
if (mod.isBotArmor) dmg *= 0.95 ** mod.totalBots()
if (mod.isHarmArmor && mech.lastHarmCycle + 600 > mech.cycle) dmg *= 0.5;
@@ -1481,7 +1482,7 @@ const mech = {
});
}
if (mod.isFreezeMobs) {
const ICE_DRAIN = 0.00015
const ICE_DRAIN = 0.0003
for (let i = 0, len = mob.length; i < len; i++) {
if (mob[i].distanceToPlayer() + mob[i].radius < this.fieldDrawRadius && !mob[i].shield && !mob[i].isShielded) {
if (mech.energy > ICE_DRAIN * 2) {
@@ -2009,7 +2010,12 @@ const mech = {
mech.energy -= DRAIN;
Matter.Body.setVelocity(body[i], velocity); //give block mouse velocity
Matter.Body.setAngularVelocity(body[i], body[i].angularVelocity * 0.8)
body[i].force.y -= body[i].mass * game.g; //remove gravity effects
// body[i].force.y -= body[i].mass * game.g; //remove gravity effects
//blocks drift towards center of pilot wave
const sub = Vector.sub(mech.fieldPosition, body[i].position)
const unit = Vector.mult(Vector.normalise(sub), 0.00005 * Vector.magnitude(sub))
body[i].force.x += unit.x
body[i].force.y += unit.y - body[i].mass * game.g //remove gravity effects
} else {
mech.fieldCDcycle = mech.cycle + 120;
mech.fieldOn = false

View File

@@ -557,10 +557,10 @@ const powerUps = {
spawn(x, y, target, moving = true, mode = null) {
if (
!(mod.isSuperDeterminism && (target === 'gun' || target === 'field' || target === 'reroll')) &&
!(mod.isBayesian && target === 'ammo')
!(mod.isEnergyNoAmmo && target === 'ammo')
) {
powerUps.directSpawn(x, y, target, moving, mode)
if (mod.isBayesian && Math.random() < 0.33) powerUps.directSpawn(x, y, target, moving, mode)
if (mod.isBayesian && Math.random() < 0.3) powerUps.directSpawn(x, y, target, moving, mode)
}
},
};

View File

@@ -81,8 +81,7 @@ const spawn = {
}
}
},
//"shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss",
randomLevelBoss(x, y, options = ["snakeBoss"]) {
randomLevelBoss(x, y, options = ["shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss"]) {
// other bosses: suckerBoss, laserBoss, tetherBoss, //all need a particular level to work so they are not included
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
},