snakeSpitBoss
new boss snakeSpitBoss - it's just snake boss but it shoots little pink seekers tech: cross disciplinary - get an extra gun or field option in tech menu now that you can scroll the selection menu can be longer unified field theory - now gives 6 research, in addition to letting you switch fields when paused cardinality renamed emergence - and gives some JUNK bug fix where game crashes if you beat the boss
This commit is contained in:
21
js/bullet.js
21
js/bullet.js
@@ -96,20 +96,11 @@ const b = {
|
||||
outOfAmmo() { //triggers after firing when you have NO ammo
|
||||
simulation.makeTextLog(`${b.guns[b.activeGun].name}.<span class='color-gun'>ammo</span><span class='color-symbol'>:</span> 0`);
|
||||
m.fireCDcycle = m.cycle + 30; //fire cooldown
|
||||
if (tech.isAmmoFromHealth) {
|
||||
if (tech.isEnergyHealth) {
|
||||
tech.healMaxEnergyBonus -= 0.01
|
||||
m.setMaxEnergy();
|
||||
} else if (m.maxHealth > 0.01) {
|
||||
tech.extraMaxHealth -= 0.01 //decrease max health
|
||||
m.setMaxHealth();
|
||||
}
|
||||
if (tech.isAmmoFromHealth && m.maxHealth > 0.01) {
|
||||
tech.extraMaxHealth -= 0.01 //decrease max health
|
||||
m.setMaxHealth();
|
||||
for (let i = 0; i < 4; i++) powerUps.spawn(m.pos.x + 50 * (Math.random() - 0.5), m.pos.y + 50 * (Math.random() - 0.5), "ammo");
|
||||
}
|
||||
// if (tech.isAmmoFromHealth && m.maxHealth > 0.01) {
|
||||
// tech.extraMaxHealth -= 0.01 //decrease max health
|
||||
// m.setMaxHealth();
|
||||
// }
|
||||
},
|
||||
refundAmmo() { //triggers after firing when you removed ammo for a gun, but didn't need to (like a rail gun misfire)
|
||||
if (tech.isCrouchAmmo && m.crouch) {
|
||||
@@ -342,7 +333,7 @@ const b = {
|
||||
|
||||
//player damage
|
||||
if (Vector.magnitude(Vector.sub(where, player.position)) < radius) {
|
||||
const DRAIN = (tech.isExplosionHarm ? 0.5 : 0.25) * (tech.isRadioactiveResistance ? 0.25 : 1)
|
||||
const DRAIN = (tech.isExplosionHarm ? 0.7 : 0.25) * (tech.isRadioactiveResistance ? 0.25 : 1)
|
||||
// * (tech.isImmuneExplosion ? Math.min(1, Math.max(1 - m.energy * 0.7, 0)) : 1)
|
||||
if (m.immuneCycle < m.cycle) m.energy -= DRAIN
|
||||
if (m.energy < 0) {
|
||||
@@ -392,7 +383,7 @@ const b = {
|
||||
if (dist < radius) {
|
||||
if (tech.isImmuneExplosion) {
|
||||
const mitigate = Math.min(1, Math.max(1 - m.energy * 0.7, 0))
|
||||
m.damage(mitigate * radius * (tech.isExplosionHarm ? 0.0004 : 0.0001));
|
||||
m.damage(mitigate * radius * (tech.isExplosionHarm ? 0.0003 : 0.0001));
|
||||
} else {
|
||||
m.damage(radius * (tech.isExplosionHarm ? 0.0004 : 0.0001));
|
||||
}
|
||||
@@ -1859,7 +1850,7 @@ const b = {
|
||||
friction: 0,
|
||||
frictionAir: 0.025,
|
||||
thrust: (tech.isFastSpores ? 0.001 : 0.0005) * (1 + 0.5 * (Math.random() - 0.5)),
|
||||
dmg: (tech.isMutualism ? 16.8 : 7) * 3, //bonus damage from tech.isMutualism //3 is extra damage as worm
|
||||
dmg: (tech.isMutualism ? 16.8 : 7) * 2.5, //bonus damage from tech.isMutualism //2.5 is extra damage as worm
|
||||
lookFrequency: 100 + Math.floor(37 * Math.random()),
|
||||
classType: "bullet",
|
||||
collisionFilter: {
|
||||
|
||||
@@ -18,6 +18,7 @@ const color = { //light
|
||||
block: "rgba(140,140,140,0.85)",
|
||||
blockS: "#222",
|
||||
map: "#444",
|
||||
bullet: "#000"
|
||||
}
|
||||
|
||||
// const color = { //dark
|
||||
|
||||
20
js/level.js
20
js/level.js
@@ -13,7 +13,7 @@ const level = {
|
||||
if (level.levelsCleared === 0) { //this code only runs on the first level
|
||||
// localSettings.levelsClearedLastGame = 10
|
||||
// simulation.enableConstructMode() //used to build maps in testing mode
|
||||
// level.difficultyIncrease(10) //30 is near max on hard //60 is near max on why
|
||||
// level.difficultyIncrease(30) //30 is near max on hard //60 is near max on why
|
||||
// simulation.isHorizontalFlipped = true
|
||||
// tech.isFieldFree = true
|
||||
// m.setField("time dilation")
|
||||
@@ -1298,7 +1298,6 @@ const level = {
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
|
||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||
spawn.secondaryBossChance(x + 2000 - 650, y + -875)
|
||||
} else {
|
||||
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
||||
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
||||
@@ -1330,7 +1329,6 @@ const level = {
|
||||
spawn.randomMob(x + 800, y + -125, mobSpawnChance);
|
||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||
spawn.secondaryBossChance(x + 650, y + -875)
|
||||
}
|
||||
},
|
||||
(x = offset.x, y = offset.y) => { //spawn block and fire it
|
||||
@@ -1390,7 +1388,6 @@ const level = {
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
|
||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||
spawn.secondaryBossChance(x + 650, y + -875)
|
||||
} else {
|
||||
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
||||
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
||||
@@ -1447,7 +1444,6 @@ const level = {
|
||||
spawn.randomMob(x + 800, y + -125, mobSpawnChance);
|
||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||
spawn.secondaryBossChance(x + 650, y - 875)
|
||||
}
|
||||
},
|
||||
(x = offset.x, y = offset.y) => { //fire an "ammo clip" of blocks
|
||||
@@ -1518,7 +1514,6 @@ const level = {
|
||||
spawn.randomMob(x + 2000 - 800, y + -125, mobSpawnChance);
|
||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x + 2000 - 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||
spawn.secondaryBossChance(x + 650, y - 875)
|
||||
} else {
|
||||
powerUps.spawnStartingPowerUps(x + 1650, y + -400);
|
||||
spawn.mapRect(x + 1575, y + -625, 25, 375); //wall on top of wall
|
||||
@@ -1586,7 +1581,6 @@ const level = {
|
||||
spawn.randomMob(x + 800, y + -125, mobSpawnChance);
|
||||
let pick = spawn.pickList[Math.floor(Math.random() * spawn.pickList.length)];
|
||||
spawn[pick](x + 1275, y + -150, 90 + Math.random() * 40); //one extra large mob
|
||||
spawn.secondaryBossChance(x + 650, y - 875)
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1884,7 +1878,8 @@ const level = {
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
spawn.randomGroup(x + 300, y + -2200);
|
||||
spawn.randomGroup(x + 1625, y + -2200);
|
||||
spawn.randomLevelBoss(x + 950, y + -2200);
|
||||
spawn.randomLevelBoss(x + 700, y + -2300);
|
||||
spawn.secondaryBossChance(x + 1250, y + -2300)
|
||||
}
|
||||
}
|
||||
)
|
||||
@@ -1950,7 +1945,8 @@ const level = {
|
||||
spawn.randomMob(x + 225, y + -2275, mobSpawnChance);
|
||||
spawn.randomMob(x + 875, y + -2450, mobSpawnChance);
|
||||
spawn.randomMob(x + 1550, y + -2525, mobSpawnChance);
|
||||
if (simulation.difficulty > 3) spawn.randomLevelBoss(x + 1075, y + -1500);
|
||||
spawn.randomLevelBoss(x + 1075, y + -1500);
|
||||
spawn.secondaryBossChance(x + 1200, y + -1000)
|
||||
simulation.draw.setPaths() //update map graphics
|
||||
}
|
||||
}
|
||||
@@ -2276,7 +2272,7 @@ const level = {
|
||||
// spawn.starter(1900, -500, 200) //big boy
|
||||
// spawn.growBossCulture(1900, -500)
|
||||
// spawn.blinkBoss(1900, -500)
|
||||
// spawn.snakeBoss(1900, -500)
|
||||
spawn.snakeSpitBoss(1900, -500)
|
||||
// spawn.growBossCulture(1900, -500)
|
||||
// spawn.sneaker(1900, -500)
|
||||
// spawn.historyBoss(1200, -500)
|
||||
@@ -2285,11 +2281,11 @@ const level = {
|
||||
// spawn.laserTargetingBoss(1700, -120)
|
||||
// spawn.bomberBoss(1400, -500)
|
||||
// spawn.hopBoss(1800, -120)
|
||||
// spawn.streamBoss(1600, -500)
|
||||
spawn.streamBoss(1600, -500)
|
||||
// spawn.powerUpBoss(1600, -500)
|
||||
// spawn.cellBossCulture(1600, -500)
|
||||
// spawn.laserTargetingBoss(1600, -500)
|
||||
spawn.grenadierBoss(1200, -500)
|
||||
// spawn.grenadierBoss(1200, -500)
|
||||
// spawn.shield(mob[mob.length - 1], 1800, -120, 1);
|
||||
|
||||
// spawn.nodeGroup(1200, -500, "grenadier")
|
||||
|
||||
@@ -2607,9 +2607,9 @@ const m = {
|
||||
},
|
||||
{
|
||||
name: "wormhole",
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br><strong>9%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
description: "use <strong class='color-f'>energy</strong> to <strong>tunnel</strong> through a <strong class='color-worm'>wormhole</strong><br><strong class='color-worm'>wormholes</strong> attract <strong class='color-block'>blocks</strong> and power ups<br><strong>8%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong>", //<br>bullets may also traverse <strong class='color-worm'>wormholes</strong>
|
||||
effect: function() {
|
||||
m.duplicateChance = 0.09
|
||||
m.duplicateChance = 0.08
|
||||
powerUps.setDo(); //needed after adjusting duplication chance
|
||||
|
||||
m.hold = function() {
|
||||
|
||||
124
js/powerup.js
124
js/powerup.js
@@ -397,33 +397,32 @@ const powerUps = {
|
||||
size() {
|
||||
return 45;
|
||||
},
|
||||
choiceLog: [], //records all previous choice options
|
||||
effect() {
|
||||
function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
|
||||
let options = [];
|
||||
for (let i = 1; i < who.length; i++) {
|
||||
if (i !== m.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
|
||||
}
|
||||
//remove repeats from last selection
|
||||
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
|
||||
if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
|
||||
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
|
||||
if (options.length > totalChoices) {
|
||||
for (let j = 0, len = options.length; j < len; j++) {
|
||||
if (powerUps.field.choiceLog[powerUps.field.choiceLog.length - 1 - i] === options[j]) {
|
||||
options.splice(j, 1) //remove previous choice from option pool
|
||||
break
|
||||
}
|
||||
pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
|
||||
let options = [];
|
||||
for (let i = 1; i < who.length; i++) {
|
||||
if (i !== m.fieldMode && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) options.push(i);
|
||||
}
|
||||
//remove repeats from last selection
|
||||
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
|
||||
if (powerUps.field.choiceLog.length > totalChoices || powerUps.field.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
|
||||
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
|
||||
if (options.length > totalChoices) {
|
||||
for (let j = 0, len = options.length; j < len; j++) {
|
||||
if (powerUps.field.choiceLog[powerUps.field.choiceLog.length - 1 - i] === options[j]) {
|
||||
options.splice(j, 1) //remove previous choice from option pool
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.length > 0) {
|
||||
return options[Math.floor(Math.random() * options.length)]
|
||||
}
|
||||
}
|
||||
|
||||
let choice1 = pick(m.fieldUpgrades)
|
||||
if (options.length > 0) {
|
||||
return options[Math.floor(Math.random() * options.length)]
|
||||
}
|
||||
},
|
||||
choiceLog: [], //records all previous choice options
|
||||
effect() {
|
||||
let choice1 = powerUps.field.pick(m.fieldUpgrades)
|
||||
let choice2 = -1
|
||||
let choice3 = -1
|
||||
if (choice1 > -1) {
|
||||
@@ -432,15 +431,15 @@ const powerUps = {
|
||||
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>field</h3>`
|
||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice1})"><div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choice1].name}</div> ${m.fieldUpgrades[choice1].description}</div>`
|
||||
if (!tech.isDeterminism) {
|
||||
choice2 = pick(m.fieldUpgrades, choice1)
|
||||
choice2 = powerUps.field.pick(m.fieldUpgrades, choice1)
|
||||
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice2})"><div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choice2].name}</div> ${m.fieldUpgrades[choice2].description}</div>`
|
||||
choice3 = pick(m.fieldUpgrades, choice1, choice2)
|
||||
choice3 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2)
|
||||
if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice3})"><div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choice3].name}</div> ${m.fieldUpgrades[choice3].description}</div>`
|
||||
}
|
||||
if (tech.isExtraChoice) {
|
||||
let choice4 = pick(m.fieldUpgrades, choice1, choice2, choice3)
|
||||
let choice4 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3)
|
||||
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice4})"><div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choice4].name}</div> ${m.fieldUpgrades[choice4].description}</div>`
|
||||
let choice5 = pick(m.fieldUpgrades, choice1, choice2, choice3, choice4)
|
||||
let choice5 = powerUps.field.pick(m.fieldUpgrades, choice1, choice2, choice3, choice4)
|
||||
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choice5})"><div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choice5].name}</div> ${m.fieldUpgrades[choice5].description}</div>`
|
||||
powerUps.field.choiceLog.push(choice4)
|
||||
powerUps.field.choiceLog.push(choice5)
|
||||
@@ -540,6 +539,7 @@ const powerUps = {
|
||||
return choose
|
||||
}
|
||||
}
|
||||
|
||||
let text = ""
|
||||
if (!tech.isDeterminism) text += `<div class='cancel' onclick='powerUps.endDraft("tech",true)'>✕</div>`
|
||||
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>tech</h3>`
|
||||
@@ -566,6 +566,21 @@ const powerUps = {
|
||||
powerUps.tech.choiceLog.push(choice3)
|
||||
// if (powerUps.research.count) text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"><div class="circle-grid research"></div> research <span class="research-select">${powerUps.research.count}</span></div></div>`
|
||||
|
||||
if (tech.isExtraGunField) {
|
||||
if (Math.random() > 0.5) {
|
||||
//bonus gun in tech menu
|
||||
let choiceGun = powerUps.gun.pick(b.guns)
|
||||
powerUps.gun.choiceLog.push(choiceGun)
|
||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choiceGun})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choiceGun].name}</div> ${b.guns[choiceGun].description}</div>`
|
||||
} else {
|
||||
//bonus field in tech menu
|
||||
let choiceField = powerUps.field.pick(m.fieldUpgrades)
|
||||
powerUps.field.choiceLog.push(choiceField)
|
||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('field',${choiceField})"><div class="grid-title"><div class="circle-grid field"></div> ${m.fieldUpgrades[choiceField].name}</div> ${m.fieldUpgrades[choiceField].description}</div>`
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (tech.isJunkResearch && powerUps.research.currentRerollCount < 3) {
|
||||
tech.junkResearchNumber = Math.floor(5 * Math.random())
|
||||
text += `<div class="choose-grid-module" onclick="powerUps.research.use('tech')"><div class="grid-title"> <span style="position:relative;">`
|
||||
@@ -598,36 +613,35 @@ const powerUps = {
|
||||
size() {
|
||||
return 35;
|
||||
},
|
||||
choiceLog: [], //records all previous choice options
|
||||
effect() {
|
||||
function pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
|
||||
let options = [];
|
||||
for (let i = 0; i < who.length; i++) {
|
||||
if (!who[i].have && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
|
||||
options.push(i);
|
||||
}
|
||||
pick(who, skip1 = -1, skip2 = -1, skip3 = -1, skip4 = -1) {
|
||||
let options = [];
|
||||
for (let i = 0; i < who.length; i++) {
|
||||
if (!who[i].have && i !== skip1 && i !== skip2 && i !== skip3 && i !== skip4) {
|
||||
options.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
//remove repeats from last selection
|
||||
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
|
||||
if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
|
||||
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
|
||||
if (options.length > totalChoices) {
|
||||
for (let j = 0, len = options.length; j < len; j++) {
|
||||
if (powerUps.gun.choiceLog[powerUps.gun.choiceLog.length - 1 - i] === options[j]) {
|
||||
options.splice(j, 1) //remove previous choice from option pool
|
||||
break
|
||||
}
|
||||
//remove repeats from last selection
|
||||
const totalChoices = tech.isDeterminism ? 1 : 3 + tech.isExtraChoice * 2
|
||||
if (powerUps.gun.choiceLog.length > totalChoices || powerUps.gun.choiceLog.length === totalChoices) { //make sure this isn't the first time getting a power up and there are previous choices to remove
|
||||
for (let i = 0; i < totalChoices; i++) { //repeat for each choice from the last selection
|
||||
if (options.length > totalChoices) {
|
||||
for (let j = 0, len = options.length; j < len; j++) {
|
||||
if (powerUps.gun.choiceLog[powerUps.gun.choiceLog.length - 1 - i] === options[j]) {
|
||||
options.splice(j, 1) //remove previous choice from option pool
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (options.length > 0) {
|
||||
return options[Math.floor(Math.random() * options.length)]
|
||||
}
|
||||
}
|
||||
|
||||
let choice1 = pick(b.guns)
|
||||
if (options.length > 0) {
|
||||
return options[Math.floor(Math.random() * options.length)]
|
||||
}
|
||||
},
|
||||
choiceLog: [], //records all previous choice options
|
||||
effect() {
|
||||
let choice1 = powerUps.gun.pick(b.guns)
|
||||
let choice2 = -1
|
||||
let choice3 = -1
|
||||
if (choice1 > -1) {
|
||||
@@ -636,15 +650,15 @@ const powerUps = {
|
||||
text += `<h3 style = 'color:#fff; text-align:left; margin: 0px;'>gun</h3>`
|
||||
text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice1})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice1].name}</div> ${b.guns[choice1].description}</div>`
|
||||
if (!tech.isDeterminism) {
|
||||
choice2 = pick(b.guns, choice1)
|
||||
choice2 = powerUps.gun.pick(b.guns, choice1)
|
||||
if (choice2 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice2})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice2].name}</div> ${b.guns[choice2].description}</div>`
|
||||
choice3 = pick(b.guns, choice1, choice2)
|
||||
choice3 = powerUps.gun.pick(b.guns, choice1, choice2)
|
||||
if (choice3 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice3})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice3].name}</div> ${b.guns[choice3].description}</div>`
|
||||
}
|
||||
if (tech.isExtraChoice) {
|
||||
let choice4 = pick(b.guns, choice1, choice2, choice3)
|
||||
let choice4 = powerUps.gun.pick(b.guns, choice1, choice2, choice3)
|
||||
if (choice4 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice4})"><div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice4].name}</div> ${b.guns[choice4].description}</div>`
|
||||
let choice5 = pick(b.guns, choice1, choice2, choice3, choice4)
|
||||
let choice5 = powerUps.gun.pick(b.guns, choice1, choice2, choice3, choice4)
|
||||
if (choice5 > -1) text += `<div class="choose-grid-module" onclick="powerUps.choose('gun',${choice5})">
|
||||
<div class="grid-title"><div class="circle-grid gun"></div> ${b.guns[choice5].name}</div> ${b.guns[choice5].description}</div>`
|
||||
powerUps.gun.choiceLog.push(choice4)
|
||||
@@ -714,7 +728,7 @@ const powerUps = {
|
||||
powerUps.spawn(x, y, "ammo");
|
||||
return;
|
||||
}
|
||||
if (Math.random() < 0.001 * (3 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun up to 3
|
||||
if (Math.random() < 0.0007 * (3 - b.inventory.length)) { //a new gun has a low chance for each not acquired gun up to 3
|
||||
powerUps.spawn(x, y, "gun");
|
||||
return;
|
||||
}
|
||||
@@ -723,7 +737,7 @@ const powerUps = {
|
||||
powerUps.spawn(x, y, "tech");
|
||||
return;
|
||||
}
|
||||
if (Math.random() < 0.003) {
|
||||
if (Math.random() < 0.0015) {
|
||||
powerUps.spawn(x, y, "field");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -680,47 +680,49 @@ const simulation = {
|
||||
},
|
||||
clearNow: false,
|
||||
clearMap() {
|
||||
if (tech.isLongitudinal) {
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "wave beam") {
|
||||
b.guns[i].waves = []; //empty array of wave bullets
|
||||
break;
|
||||
if (m.alive) {
|
||||
if (tech.isLongitudinal) {
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun
|
||||
if (b.guns[i].name === "wave beam") {
|
||||
b.guns[i].waves = []; //empty array of wave bullets
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tech.isMineAmmoBack) {
|
||||
let count = 0;
|
||||
for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map
|
||||
if (bullet[i].bulletType === "mine") count++
|
||||
}
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine
|
||||
if (b.guns[i].name === "mine") {
|
||||
if (tech.isCrouchAmmo) count = Math.ceil(count / 2)
|
||||
b.guns[i].ammo += count
|
||||
simulation.updateGunHUD();
|
||||
break;
|
||||
if (tech.isMineAmmoBack) {
|
||||
let count = 0;
|
||||
for (i = 0, len = bullet.length; i < len; i++) { //count mines left on map
|
||||
if (bullet[i].bulletType === "mine") count++
|
||||
}
|
||||
for (i = 0, len = b.guns.length; i < len; i++) { //find which gun is mine
|
||||
if (b.guns[i].name === "mine") {
|
||||
if (tech.isCrouchAmmo) count = Math.ceil(count / 2)
|
||||
b.guns[i].ammo += count
|
||||
simulation.updateGunHUD();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tech.isMutualism && !tech.isEnergyHealth) {
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].isMutualismActive) {
|
||||
m.health += 0.005 + 0.005 * tech.isSporeWorm
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
m.displayHealth();
|
||||
if (tech.isMutualism && !tech.isEnergyHealth) {
|
||||
for (let i = 0; i < bullet.length; i++) {
|
||||
if (bullet[i].isMutualismActive) {
|
||||
m.health += 0.005 + 0.005 * tech.isSporeWorm
|
||||
if (m.health > m.maxHealth) m.health = m.maxHealth;
|
||||
m.displayHealth();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tech.isEndLevelPowerUp) {
|
||||
for (let i = 0; i < powerUp.length; i++) {
|
||||
if (powerUp[i].name === "tech") {
|
||||
tech.giveTech()
|
||||
} else if (powerUp[i].name === "gun") {
|
||||
if (!tech.isOneGun) b.giveGuns("random")
|
||||
} else if (powerUp[i].name === "field") {
|
||||
if (m.fieldMode === 0) m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1))) //pick a random field, but not field 0
|
||||
} else {
|
||||
powerUp[i].effect();
|
||||
if (tech.isEndLevelPowerUp) {
|
||||
for (let i = 0; i < powerUp.length; i++) {
|
||||
if (powerUp[i].name === "tech") {
|
||||
tech.giveTech()
|
||||
} else if (powerUp[i].name === "gun") {
|
||||
if (!tech.isOneGun) b.giveGuns("random")
|
||||
} else if (powerUp[i].name === "field") {
|
||||
if (m.fieldMode === 0) m.setField(Math.ceil(Math.random() * (m.fieldUpgrades.length - 1))) //pick a random field, but not field 0
|
||||
} else {
|
||||
powerUp[i].effect();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -755,7 +757,7 @@ const simulation = {
|
||||
removeAll(composite);
|
||||
composite = [];
|
||||
// if player was holding something this makes a new copy to hold
|
||||
if (holdTarget) {
|
||||
if (holdTarget && m.alive) {
|
||||
len = body.length;
|
||||
body[len] = Matter.Bodies.fromVertices(0, 0, holdTarget.vertices, {
|
||||
friction: holdTarget.friction,
|
||||
|
||||
127
js/spawn.js
127
js/spawn.js
@@ -1,7 +1,7 @@
|
||||
//main object for spawning things in a level
|
||||
const spawn = {
|
||||
nonCollideBossList: ["cellBossCulture", "bomberBoss", "powerUpBoss", "orbitalBoss", "spawnerBossCulture", "growBossCulture"],
|
||||
randomLevelBoss(x, y, options = ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss"]) {
|
||||
randomLevelBoss(x, y, options = ["shieldingBoss", "orbitalBoss", "historyBoss", "shooterBoss", "cellBossCulture", "bomberBoss", "spiderBoss", "launcherBoss", "laserTargetingBoss", "powerUpBoss", "snakeBoss", "streamBoss", "pulsarBoss", "spawnerBossCulture", "grenadierBoss", "growBossCulture", "blinkBoss", "snakeSpitBoss"]) {
|
||||
// other bosses: suckerBoss, laserBoss, tetherBoss, //these need a particular level to work so they are not included in the random pool
|
||||
spawn[options[Math.floor(Math.random() * options.length)]](x, y)
|
||||
},
|
||||
@@ -316,7 +316,7 @@ const spawn = {
|
||||
} else if (count === 780) {
|
||||
simulation.makeTextLog(`<span class="lore-text">undefined</span> <span class='color-symbol'>=</span> ${lore.techCount}/${lore.techGoal}`)
|
||||
} else if (count === 1020) {
|
||||
simulation.makeTextLog(`Composite.clear(engine.composite) <em>//simulation successful</em>`);
|
||||
simulation.makeTextLog(`Engine.clear(engine) <em>//simulation successful</em>`);
|
||||
} else if (count === 1260) {
|
||||
// tech.isImmortal = false;
|
||||
// m.death()
|
||||
@@ -331,7 +331,10 @@ const spawn = {
|
||||
// build.shareURL(false)
|
||||
setTimeout(function() {
|
||||
simulation.paused = true;
|
||||
Composite.clear(engine.composite);
|
||||
// simulation.clearMap();
|
||||
// Matter.Composite.clear(composite, keepStatic, [deep = false])
|
||||
// Composite.clear(engine.composite);
|
||||
engine.world.bodies.forEach((body) => { Matter.Composite.remove(engine.world, body) })
|
||||
Engine.clear(engine);
|
||||
simulation.splashReturn();
|
||||
}, 6000);
|
||||
@@ -3640,6 +3643,124 @@ const spawn = {
|
||||
this.attraction();
|
||||
};
|
||||
},
|
||||
snakeSpitBoss(x, y, radius = 50) { //snake boss with a laser head
|
||||
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
|
||||
let angle = Math.PI
|
||||
let mag = 300
|
||||
|
||||
const color1 = "rgb(245,180,255)"
|
||||
mobs.spawn(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 8, radius, color1); //"rgb(55,170,170)"
|
||||
let me = mob[mob.length - 1];
|
||||
me.isBoss = true;
|
||||
me.accelMag = 0.0001 + 0.0002 * Math.sqrt(simulation.accelScale)
|
||||
me.memory = 250;
|
||||
me.laserRange = 500;
|
||||
Matter.Body.setDensity(me, 0.0022 + 0.00022 * Math.sqrt(simulation.difficulty)); //extra dense //normal is 0.001 //makes effective life much larger
|
||||
me.onDeath = function() {
|
||||
powerUps.spawnBossPowerUp(this.position.x, this.position.y)
|
||||
for (let i = 0; i < mob.length; i++) { //wake up tail mobs
|
||||
if (mob[i].isSnakeTail && mob[i].alive) {
|
||||
mob[i].isSnakeTail = false;
|
||||
mob[i].do = mob[i].doActive
|
||||
mob[i].removeConsBB();
|
||||
}
|
||||
}
|
||||
};
|
||||
me.canFire = false;
|
||||
me.closestVertex1 = 0;
|
||||
// me.closestVertex2 = 1;
|
||||
me.cycle = 0
|
||||
me.damageReduction = 0.25
|
||||
me.do = function() {
|
||||
// this.armor();
|
||||
this.seePlayerByHistory()
|
||||
this.checkStatus();
|
||||
this.attraction();
|
||||
this.cycle++
|
||||
if (this.seePlayer.recall && ((this.cycle % 15) === 0) && !m.isBodiesAsleep) {
|
||||
if (this.canFire) {
|
||||
if (this.cycle > 120) {
|
||||
this.cycle = 0
|
||||
this.canFire = false
|
||||
// Matter.Body.setAngularVelocity(this, 0.1)
|
||||
// const forceMag = 0.01 * this.mass;
|
||||
// const angle = Math.atan2(this.seePlayer.position.y - this.position.y, this.seePlayer.position.x - this.position.x);
|
||||
// this.force.x -= 2 * forceMag * Math.cos(angle);
|
||||
// this.force.y -= 2 * forceMag * Math.sin(angle); // - 0.0007 * this.mass; //antigravity
|
||||
}
|
||||
spawn.seeker(this.vertices[this.closestVertex1].x, this.vertices[this.closestVertex1].y, 6)
|
||||
Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
|
||||
const velocity = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex1])), -10)
|
||||
Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||
x: this.velocity.x + velocity.x,
|
||||
y: this.velocity.y + velocity.y
|
||||
});
|
||||
// spawn.seeker(this.vertices[this.closestVertex2].x, this.vertices[this.closestVertex2].y, 6)
|
||||
// Matter.Body.setDensity(mob[mob.length - 1], 0.000001); //normal is 0.001
|
||||
// const velocity2 = Vector.mult(Vector.normalise(Vector.sub(this.position, this.vertices[this.closestVertex2])), -10)
|
||||
// Matter.Body.setVelocity(mob[mob.length - 1], {
|
||||
// x: this.velocity.x + velocity2.x,
|
||||
// y: this.velocity.y + velocity2.y
|
||||
// });
|
||||
} else if (this.cycle > 210) {
|
||||
this.cycle = 0
|
||||
this.canFire = true
|
||||
|
||||
//find closest 2 vertexes
|
||||
let distance2 = Infinity
|
||||
for (let i = 0; i < this.vertices.length; i++) {
|
||||
const d = Vector.magnitudeSquared(Vector.sub(this.vertices[i], player.position))
|
||||
if (d < distance2) {
|
||||
distance2 = d
|
||||
// this.closestVertex2 = this.closestVertex1
|
||||
this.closestVertex1 = i
|
||||
}
|
||||
}
|
||||
// if (this.closestVertex2 === this.closestVertex1) {
|
||||
// this.closestVertex2++
|
||||
// if (this.closestVertex2 === this.vertices.length) this.closestVertex2 = 0
|
||||
// }
|
||||
}
|
||||
}
|
||||
};
|
||||
//extra space to give head room
|
||||
angle -= 0.1
|
||||
mag -= 10
|
||||
for (let i = 0; i < nodes; ++i) {
|
||||
angle -= 0.15 + i * 0.008
|
||||
mag -= 5
|
||||
spawn.snakeBody(x + mag * Math.cos(angle), y + mag * Math.sin(angle), 20);
|
||||
}
|
||||
this.constrain2AdjacentMobs(nodes, Math.random() * 0.06 + 0.01);
|
||||
|
||||
for (let i = mob.length - 1, len = i - nodes; i > len; i--) { //set alternating colors
|
||||
if (i % 2) {
|
||||
mob[i].fill = "#778"
|
||||
} else {
|
||||
mob[i].fill = color1
|
||||
}
|
||||
}
|
||||
//constraint with first 3 mobs in line
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
bodyA: mob[mob.length - nodes],
|
||||
bodyB: mob[mob.length - 1 - nodes],
|
||||
stiffness: 0.05
|
||||
});
|
||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
bodyA: mob[mob.length - nodes + 1],
|
||||
bodyB: mob[mob.length - 1 - nodes],
|
||||
stiffness: 0.05
|
||||
});
|
||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||
consBB[consBB.length] = Constraint.create({
|
||||
bodyA: mob[mob.length - nodes + 2],
|
||||
bodyB: mob[mob.length - 1 - nodes],
|
||||
stiffness: 0.05
|
||||
});
|
||||
Composite.add(engine.world, consBB[consBB.length - 1]);
|
||||
// spawn.shield(me, x, y, 1);
|
||||
},
|
||||
snakeBoss(x, y, radius = 50) { //snake boss with a laser head
|
||||
const nodes = Math.min(8 + Math.ceil(0.5 * simulation.difficulty), 40)
|
||||
let angle = Math.PI
|
||||
|
||||
108
js/tech.js
108
js/tech.js
@@ -193,7 +193,7 @@
|
||||
return dmg * tech.slowFire * tech.aimDamage
|
||||
},
|
||||
duplicationChance() {
|
||||
return (tech.isPowerUpsVanish ? 0.2 : 0) + (tech.isStimulatedEmission ? 0.22 : 0) + tech.cancelCount * 0.048 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)
|
||||
return (tech.isPowerUpsVanish ? 0.17 : 0) + (tech.isStimulatedEmission ? 0.2 : 0) + tech.cancelCount * 0.048 + tech.duplicateChance + m.duplicateChance + tech.wormDuplicate + (tech.isAnthropicTech && tech.isDeathAvoidedThisLevel ? 0.5 : 0)
|
||||
},
|
||||
maxDuplicationEvent() {
|
||||
if (tech.is100Duplicate && tech.duplicationChance() > 0.99) {
|
||||
@@ -458,9 +458,9 @@
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isEnergyNoAmmo
|
||||
return !tech.isEnergyNoAmmo && !tech.isEnergyHealth
|
||||
},
|
||||
requires: "exciton-lattice",
|
||||
requires: "exciton-lattice, not mass-energy",
|
||||
effect: () => {
|
||||
tech.isAmmoFromHealth = true;
|
||||
},
|
||||
@@ -773,7 +773,7 @@
|
||||
},
|
||||
{
|
||||
name: "ammonium nitrate",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>25%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>25%</strong>",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong class='color-d'>damage</strong> by <strong>30%</strong><br>increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>30%</strong>",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
@@ -783,7 +783,7 @@
|
||||
},
|
||||
requires: "an explosive damage source, not iridium-192",
|
||||
effect: () => {
|
||||
tech.explosiveRadius += 0.25;
|
||||
tech.explosiveRadius += 0.3;
|
||||
},
|
||||
remove() {
|
||||
tech.explosiveRadius = 1;
|
||||
@@ -809,7 +809,7 @@
|
||||
},
|
||||
{
|
||||
name: "acetone peroxide",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>80%</strong>, but<br>you take <strong>400%</strong> more <strong class='color-harm'>harm</strong> from <strong class='color-e'>explosions</strong>",
|
||||
description: "increase <strong class='color-e'>explosive</strong> <strong>radius</strong> by <strong>80%</strong>, but<br>you take <strong>300%</strong> more <strong class='color-harm'>harm</strong> from <strong class='color-e'>explosions</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
@@ -2824,11 +2824,14 @@
|
||||
requires: "not determinism, at least 3 research",
|
||||
effect() {
|
||||
tech.isBanish = true
|
||||
for (let i = 0; i < 9; i++) powerUps.spawn(m.pos.x + 60 * (Math.random() - 0.5), m.pos.y + 60 * (Math.random() - 0.5), "research", false);
|
||||
for (let i = 0; i < 9; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
},
|
||||
remove() {
|
||||
tech.isBanish = false
|
||||
powerUps.tech.banishLog = [] //reset banish log
|
||||
if (tech.isBanish) {
|
||||
tech.isBanish = false
|
||||
powerUps.tech.banishLog = [] //reset banish log
|
||||
powerUps.research.changeRerolls(-10)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -3036,7 +3039,7 @@
|
||||
},
|
||||
{
|
||||
name: "stimulated emission",
|
||||
description: "<strong>22%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>but, after a <strong>collision</strong> eject <strong>1</strong> <strong class='color-m'>tech</strong>",
|
||||
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br>but, after a <strong>collision</strong> eject <strong>1</strong> <strong class='color-m'>tech</strong>",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3056,7 +3059,7 @@
|
||||
},
|
||||
{
|
||||
name: "metastability",
|
||||
description: "<strong>20%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second <strong>half-life</strong> ",
|
||||
description: "<strong>17%</strong> chance to <strong class='color-dup'>duplicate</strong> spawned <strong>power ups</strong><br><strong class='color-dup'>duplicates</strong> <strong class='color-e'>explode</strong> with a <strong>3</strong> second <strong>half-life</strong> ",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
@@ -3243,24 +3246,6 @@
|
||||
},
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "unified field theory",
|
||||
description: `in the <strong>pause</strong> menu, change your <strong class='color-f'>field</strong><br>by <strong>clicking</strong> on your <strong class='color-f'>field's</strong> box`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
tech.isGunSwitchField = true;
|
||||
},
|
||||
remove() {
|
||||
tech.isGunSwitchField = false;
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "vector fields",
|
||||
description: "</strong>double</strong> the <strong class='flicker'>frequency</strong> of finding <strong class='color-f'>field</strong> <strong class='color-m'>tech</strong><br>spawn a <strong class='color-f'>field</strong>",
|
||||
@@ -3339,21 +3324,67 @@
|
||||
remove() {}
|
||||
},
|
||||
{
|
||||
name: "cardinality",
|
||||
description: "<strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>5</strong> <strong>choices</strong>",
|
||||
name: "unified field theory",
|
||||
description: `spawn <strong>6</strong> <strong class='color-r'>research</strong>, and when <strong>paused</strong><br><strong>clicking</strong> the <strong class='color-f'>field</strong> box switches your <strong class='color-f'>field</strong>`,
|
||||
// description: `in the <strong>pause</strong> menu, change your <strong class='color-f'>field</strong><br>by <strong>clicking</strong> on your <strong class='color-f'>field's</strong> box`,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 2,
|
||||
frequencyDefault: 2,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isSuperDeterminism
|
||||
},
|
||||
requires: "not superdeterminism",
|
||||
effect() {
|
||||
tech.isGunSwitchField = true;
|
||||
for (let i = 0; i < 6; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
},
|
||||
remove() {
|
||||
if (tech.isGunSwitchField) {
|
||||
tech.isGunSwitchField = false;
|
||||
powerUps.research.changeRerolls(-6)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "cross disciplinary",
|
||||
description: "<strong class='color-m'>tech</strong> have an extra <strong class='color-f'>field</strong> or <strong class='color-g'>gun</strong> <strong>choice</strong>", //<br><strong>+7</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool //<br>spawn <strong>2</strong> <strong class='color-r'>research</strong>
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isDeterminism
|
||||
},
|
||||
requires: "not determinism",
|
||||
effect: () => {
|
||||
tech.isExtraGunField = true;
|
||||
// for (let i = 0; i < 2; i++) powerUps.spawn(m.pos.x + 40 * (Math.random() - 0.5), m.pos.y + 40 * (Math.random() - 0.5), "research", false);
|
||||
|
||||
},
|
||||
remove() {
|
||||
tech.isExtraGunField = false;
|
||||
// if (this.count > 0) powerUps.research.changeRerolls(-2)
|
||||
}
|
||||
},
|
||||
{
|
||||
name: "emergence",
|
||||
description: "<strong class='color-m'>tech</strong>, <strong class='color-f'>fields</strong>, and <strong class='color-g'>guns</strong> have <strong>5</strong> <strong>choices</strong><br><strong>+5</strong> <strong class='color-j'>JUNK</strong> to the potential <strong class='color-m'>tech</strong> pool",
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
frequency: 1,
|
||||
frequencyDefault: 1,
|
||||
allowed() {
|
||||
return !tech.isDeterminism
|
||||
},
|
||||
requires: "not determinism",
|
||||
effect: () => {
|
||||
tech.isExtraChoice = true;
|
||||
tech.addJunkTechToPool(5)
|
||||
},
|
||||
remove() {
|
||||
tech.isExtraChoice = false;
|
||||
if (this.count > 0) tech.removeJunkTechFromPool(5)
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -3367,7 +3398,7 @@
|
||||
allowed() {
|
||||
return !tech.isExtraChoice && !tech.isCancelDuplication && !tech.isCancelRerolls
|
||||
},
|
||||
requires: "not cardinality, not futures or commodities exchanges",
|
||||
requires: "not emergence, not futures or commodities exchanges",
|
||||
effect: () => {
|
||||
tech.isDeterminism = true;
|
||||
//if you change the number spawned also change it in Born rule
|
||||
@@ -4560,7 +4591,7 @@
|
||||
},
|
||||
{
|
||||
name: "nematodes",
|
||||
description: "<strong class='color-p' style='letter-spacing: 2px;'>spores</strong> develop into <strong>1/2</strong> as many <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong><br><strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong> do <strong>200%</strong> more <strong class='color-d'>damage</strong>",
|
||||
description: "<strong class='color-p' style='letter-spacing: 2px;'>spores</strong> develop into <strong>1/2</strong> as many <strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong><br><strong class='color-p' style='letter-spacing: -0.8px;'>worms</strong> do <strong>250%</strong> more <strong class='color-d'>damage</strong>",
|
||||
isGunTech: true,
|
||||
maxCount: 1,
|
||||
count: 0,
|
||||
@@ -7365,7 +7396,7 @@
|
||||
},
|
||||
{
|
||||
name: "re-arm",
|
||||
description: "<strong>eject</strong> all your <strong class='color-g'>guns</strong>",
|
||||
description: "remove all your <strong class='color-g'>guns</strong>,<br>and <strong>spawn</strong> new ones",
|
||||
maxCount: 9,
|
||||
count: 0,
|
||||
frequency: 0,
|
||||
@@ -7405,7 +7436,7 @@
|
||||
},
|
||||
requires: "at least 4 research",
|
||||
effect() {
|
||||
for (let i = 0; i < powerUps.research.count; i++) powerUps.spawn(m.pos.x + 160 * (Math.random() - 0.5), m.pos.y + 160 * (Math.random() - 0.5), "research");
|
||||
for (let i = 0; i < powerUps.research.count; i++) powerUps.directSpawn(m.pos.x + 160 * (Math.random() - 0.5), m.pos.y + 160 * (Math.random() - 0.5), "research");
|
||||
powerUps.research.count = 0
|
||||
},
|
||||
remove() {}
|
||||
@@ -7793,5 +7824,6 @@
|
||||
isBlockRestitution: null,
|
||||
isZeno: null,
|
||||
isFieldFree: null,
|
||||
wormSurviveDmg: null
|
||||
wormSurviveDmg: null,
|
||||
isExtraGunField: null
|
||||
}
|
||||
64
todo.txt
64
todo.txt
@@ -1,49 +1,26 @@
|
||||
******************************************************** NEXT PATCH ********************************************************
|
||||
|
||||
missile-bot tech now removes your missile gun, but missile bot fires much faster
|
||||
missile-bot now benefits from all missile tech
|
||||
new boss snakeSpitBoss - it's just snake boss but it shoots little pink seekers
|
||||
|
||||
rail gun has a bit less ammo and fires a bit faster
|
||||
in between how it is was in the last two patches
|
||||
rail gun gets less energy from half-wave rectifier
|
||||
tech: cross disciplinary - get an extra gun or field option in tech menu
|
||||
now that you can scroll the selection menu can be longer
|
||||
|
||||
unified field theory - now gives 6 research, in addition to letting you switch fields when paused
|
||||
cardinality renamed emergence - and gives some JUNK
|
||||
|
||||
bug fix where game crashes if you beat the boss
|
||||
|
||||
******************************************************** TODO ********************************************************
|
||||
|
||||
dark mode
|
||||
build color pallets in a photo editor by redrawing in game screenshots
|
||||
what about just starting with setting the background to be a dark grey?
|
||||
const color = {
|
||||
map:
|
||||
blocks:
|
||||
background:
|
||||
shadows: (0,0,0,0.1)?
|
||||
bullets:
|
||||
mob:
|
||||
heal powerUps:
|
||||
tech powerUps:
|
||||
field powerUps:
|
||||
gun powerUps:
|
||||
damage circle:
|
||||
harm circle:
|
||||
}
|
||||
|
||||
re-word the "reduce difficulty" text, so it's more clear what you get
|
||||
|
||||
tech: Standing Wave: Shockwave. Use FIELD button to shrink your shield and charge up, release to unleash a Shockwave.
|
||||
|
||||
make an area that prevents mob vision, like a bush you can hide in
|
||||
a static block with non collide on most things?
|
||||
drones can combine with other drones to get bigger?
|
||||
drones that grab powers ups can grab more then one and get even bigger each time
|
||||
|
||||
it would be helpful if there was a mechanism to recover mobs that fly off the map
|
||||
add a ceiling system and a left/right walls system similar to the floor checks but only for mobs
|
||||
make non moving bosses not move after getting hit
|
||||
shooter, shielding,
|
||||
|
||||
buff missiles?
|
||||
do more with the missile bot
|
||||
maybe they can release grenades after they explode, like CPT grenades?
|
||||
make the crouch rapid fire a tech, and make the missiles fire faster, and use less ammo?
|
||||
buff railgun
|
||||
buff rail gun
|
||||
buff mines
|
||||
|
||||
make the player get a buff after using wormhole
|
||||
@@ -52,6 +29,7 @@ using wormhole makes you immune to harm and drains energy until you run out
|
||||
disable incoming energy, by saving current energy and just setting energy in the next cycle to be lower then the saved value
|
||||
|
||||
pink seeker boss is cool as heck, make an alt version of it
|
||||
snake tail is cool, make an alt version of it
|
||||
|
||||
block shattering
|
||||
get code from planetesimals
|
||||
@@ -62,6 +40,8 @@ pause should at least show the last in game console message
|
||||
|
||||
in testing mode console log the body you click on
|
||||
|
||||
tech: Standing Wave: Shockwave. Use FIELD button to shrink your shield and charge up, release to unleash a Shockwave.
|
||||
|
||||
tech: quantized shields - harmonic standing wave field can only lose 33 energy per hit
|
||||
draw 1,2,3 levels of the field based on energy?
|
||||
the blocked value only scales up to 2x or 4x (33 energy) blocked
|
||||
@@ -80,9 +60,7 @@ tech plasma : plasma length increases then decreases as you hold down the field
|
||||
extra energy is drained when field is longer
|
||||
|
||||
energy conservation 6% damage recovered as energy
|
||||
there is space for a negative effect in the text
|
||||
|
||||
Weak Anthropic Principle: you get a second chance at life, but ....
|
||||
there is space for a negative effect in the text...
|
||||
|
||||
tech: use the ability for power ups to have custom code
|
||||
(note: this code is half way done, it just needs to be completed)
|
||||
@@ -90,18 +68,6 @@ tech: use the ability for power ups to have custom code
|
||||
attracted to other power ups
|
||||
explode if they touch?
|
||||
|
||||
consider executables:
|
||||
press F to do things
|
||||
ideas:
|
||||
|
||||
nail-gun, or ....
|
||||
1s after being fired your bullets turn:
|
||||
towards the nearest mob
|
||||
in your mouse direction
|
||||
back towards the player
|
||||
current location or location when fired?
|
||||
explode when turning back
|
||||
|
||||
apply the new gun.do functions to other guns
|
||||
rail gun
|
||||
crouching missile?
|
||||
|
||||
Reference in New Issue
Block a user