Closed Whyisthisnotavalable closed 3 months ago
let isUsingSwordMod = false;
for (let i = 0; i < tech.tech.length; i++) {
if (tech.tech[i].name === 'size-weight illusion') { //to detect if the player is using the sword mod so that it won't mess up their mod. The sword mod adds this tech so if it is detected then the sword won't be removed from the gun array //Landgreen, don't add a tech with the same name
isUsingSwordMod = true;
}
}
if (!isUsingSwordMod) {
const e = {
name: "sword",
descriptionFunction() { return `swing a <b>sword</b> that <b style="color: indigo;">lifesteals</b> <strong class='color-h'>health</strong><br>drains <strong class='color-h'>health</strong> instead of ammunition<br>doesn't use <b>ammo</b>`},
ammo: Infinity,
ammoPack: Infinity,
defaultAmmoPack: Infinity,
have: false,
cycle: 0,
sword: undefined,
swordArray: [],
bladeSegments: undefined,
bladeTrails: [],
angle: 0,
constraint: undefined,
charge: 0,
angle2: 0,
fire() { },
do() {
if(this.sword && this.cycle < 1) {
this.angle2 = Math.atan2(this.sword.position.y - m.pos.y, this.sword.position.x - m.pos.x);
}
if(this.sword) {
this.cycle++;
}
this.normalFire();
this.renderDefault();
this.collision();
},
normalFire() {
if(this.constraint) {
this.constraint.pointA = player.position;
}
if(tech.isStabSword && !m.crouch && this.cycle > 0 && this.stabStatus) {
if(this.sword) {
this.stabStatus = false;
if(tech.isEnergyHealth) {
m.energy = 0.01;
m.immuneCycle = m.cycle + 30;
}
this.cycle = 0;
Matter.Body.setAngularVelocity(this.sword, 0);
Composite.remove(engine.world, this.sword);
this.sword.parts.forEach(part => {
Composite.remove(engine.world, part);
const index = bullet.indexOf(part);
if (index !== -1) {
bullet.splice(index, 1);
}
});
this.sword = undefined;
if(this.constraint) {
Composite.remove(engine.world, this.constraint);
this.constraint = undefined;
}
this.bladeTrails = [];
m.fireCDcycle = 0;
}
}
if(input.fire && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
if(tech.isEnergyHealth) {
m.energy -= 0.004;
} else {
m.health -= 0.001;
m.displayHealth();
}
}
if (input.fire && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
if (!this.sword && b.guns[b.activeGun].name === 'sword') {
({ sword: this.sword, bladeSegments: this.bladeSegments} = this.createAndSwingSword());
this.angle = m.angle;
}
}
if(this.sword && !input.fire) {
this.cycle = 0;
Matter.Body.setAngularVelocity(this.sword, 0);
player.force.x *= 0.01;
player.force.y *= 0.01;
Composite.remove(engine.world, this.sword);
this.sword.parts.forEach(part => {
Composite.remove(engine.world, part);
const index = bullet.indexOf(part);
if (index !== -1) {
bullet.splice(index, 1);
}
});
this.sword = undefined;
if(this.constraint) {
Composite.remove(engine.world, this.constraint);
this.constraint = undefined;
}
this.bladeTrails = [];
m.fireCDcycle = m.cycle + 10;
} else {
if (this.sword && (tech.isEnergyHealth ? m.energy >= 0.11 : m.health >= 0.11)) {
let handle;
for(let i = 0; i < bullet.length; i++) {
if(bullet[i].customName == "handle") {
handle = bullet[i];
}
}
if(tech.infinityEdge) {
const newSize = Math.sqrt(0.5 * m.health) + 1;
Matter.Body.scale(this.sword, newSize * (1 / (this.sword.scale == undefined ? 1 : this.sword.scale)), newSize * (1 / (this.sword.scale == undefined ? 1 : this.sword.scale)), handle.position);
this.sword.scale = newSize;
}
if (!(this.angle > -Math.PI / 2 && this.angle < Math.PI / 2)) {
Matter.Body.setAngularVelocity(this.sword, -Math.PI * 0.1);
} else {
Matter.Body.setAngularVelocity(this.sword, Math.PI * 0.1);
}
if(tech.sizeIllusion) {
player.force.x += Math.cos(m.angle) * player.mass / 500;
player.force.y += Math.sin(m.angle) * player.mass / 500;
}
if(!this.constraint && (m.angle > -Math.PI / 2 && m.angle < Math.PI / 2)) {
this.constraint = Constraint.create({
pointA: player.position,
bodyB: this.sword,
pointB: {x: -9, y: ((handle.position.y - this.sword.position.y))},
stiffness: (tech.infinityEdge ? 0.05 : 0.1),
damping: 0.001815,
length: 0,
});
Composite.add(engine.world, this.constraint);
} else if(!this.constraint) {
this.constraint = Constraint.create({
pointA: player.position,
bodyB: this.sword,
pointB: {x: 9, y: ((handle.position.y - this.sword.position.y))},
stiffness: (tech.infinityEdge ? 0.05 : 0.1),
damping: 0.001815,
length: 0,
});
Composite.add(engine.world, this.constraint);
}
} else if(this.sword) {
if(tech.isEnergyHealth) {
m.energy = 0.01;
m.immuneCycle = m.cycle + 30;
}
this.cycle = 0;
Matter.Body.setAngularVelocity(this.sword, 0);
player.force.x *= 0.01;
player.force.y *= 0.01;
Composite.remove(engine.world, this.sword);
this.sword.parts.forEach(part => {
Composite.remove(engine.world, part);
const index = bullet.indexOf(part);
if (index !== -1) {
bullet.splice(index, 1);
}
});
this.sword = undefined;
if(this.constraint) {
Composite.remove(engine.world, this.constraint);
this.constraint = undefined;
}
this.bladeTrails = [];
m.fireCDcycle = 0;
}
}
},
createAndSwingSword(x = player.position.x, y = player.position.y, angle = m.angle) {
const handleWidth = 20;
const handleHeight = 150;
const handle = Bodies.rectangle(x, y, handleWidth, handleHeight, spawn.propsIsNotHoldable);
bullet[bullet.length] = handle;
handle.customName = "handle";
bullet[bullet.length - 1].do = () => {};
const pommelWidth = 30;
const pommelHeight = 40;
const pommelVertices = [
{ x: x, y: y + handleHeight / 2 + pommelHeight / 2 },
{ x: x + pommelWidth / 2, y: y + handleHeight / 2 },
{ x: x, y: y + handleHeight / 2 - pommelHeight / 2 },
{ x: x - pommelWidth / 2, y: y + handleHeight / 2 },
];
const pommel = Bodies.fromVertices(x, y + handleHeight / 2, pommelVertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = pommel;
bullet[bullet.length - 1].do = () => {};
if(tech.soundSword) {
bullet[bullet.length - 1].draw = () => {};
}
// Blade setup
const bladeWidth = 100 * (tech.soundSword ? 3 : 1);
const bladeHeight = 20 * (tech.soundSword ? 3 : 1);
const numBlades = 15;
const extensionFactor = 5;
const bladeSegments = [];
if ((angle > -Math.PI / 2 && angle < Math.PI / 2)) {
for (let i = 0; i < numBlades; i++) {
const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
const bladeX = x + i * (bladeWidth / 20);
const bladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
const vertices = [
{ x: bladeX, y: bladeY - bladeHeight / 2 },
{ x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
];
const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = blade;
bullet[bullet.length - 1].do = () => {};
if(tech.soundSword) {
bullet[bullet.length - 1].draw = () => {};
}
Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 270) * 15));
bladeSegments.push(blade);
}
} else {
for (let i = 0; i < numBlades; i++) {
const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
const mirroredBladeX = x - i * (bladeWidth / 20);
const mirroredBladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
const mirroredVertices = [
{ x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 },
{ x: mirroredBladeX + bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
{ x: mirroredBladeX - bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
{ x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 + 10 },
];
const mirroredBlade = Bodies.fromVertices(mirroredBladeX, mirroredBladeY, mirroredVertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = mirroredBlade;
bullet[bullet.length - 1].do = () => {};
if(tech.soundSword) {
bullet[bullet.length - 1].draw = () => {};
}
Matter.Body.rotate(mirroredBlade, Math.sin(i * (Math.PI / 270) * 15));
bladeSegments.push(mirroredBlade);
}
}
bladeSegments.push(pommel);
const sword = Body.create({
parts: [handle, ...bladeSegments],
});
Composite.add(engine.world, sword);
Matter.Body.setPosition(sword, { x, y });
sword.collisionFilter.category = cat.bullet;
sword.collisionFilter.mask = cat.mobBullet | cat.powerup | cat.mob;
Body.scale(sword, -1, 1, { x, y });
return { sword, bladeSegments };
},
renderDefault() {
if(this.sword) {
for (let i = 0; i < this.bladeSegments.length; i++) {
const blade = this.bladeSegments[i];
const trail = this.bladeTrails[i] || [];
const vertices = blade.vertices.map(vertex => ({ x: vertex.x, y: vertex.y }));
trail.push(vertices);
if (trail.length > 10) {
trail.shift();
}
this.bladeTrails[i] = trail;
}
for (let i = 0; i < this.bladeTrails.length; i++) {
const trail = this.bladeTrails[i];
const alphaStep = 1 / trail.length;
let alpha = 0;
for (let j = 0; j < trail.length; j++) {
const vertices = trail[j];
ctx.beginPath();
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let k = 1; k < vertices.length; k++) {
ctx.lineTo(vertices[k].x, vertices[k].y);
};
alpha += alphaStep;
ctx.closePath();
if(tech.isEnergyHealth) {
const eyeColor = m.fieldMeterColor;
const r = eyeColor[1];
const g = eyeColor[2];
const b = eyeColor[3];
const color = `#${r}${r}${g}${g}${b}${b}${Math.round(alpha * 255).toString(16).padStart(2, '0')}`;
ctx.fillStyle = color;
} else {
ctx.fillStyle = `rgba(220, 20, 60, ${alpha})`;
}
ctx.fill();
}
}
for(let i = 0; i < this.bladeSegments.length; i++) {
ctx.beginPath();
ctx.lineJoin = "miter";
ctx.miterLimit = 100;
ctx.strokeStyle = tech.isEnergyHealth ? m.fieldMeterColor : tech.isAmmoSword ? "#c0c0c0" : "crimson";
ctx.lineWidth = 5;
ctx.fillStyle = "black";
ctx.moveTo(this.bladeSegments[i].vertices[0].x, this.bladeSegments[i].vertices[0].y);
for(let j = 0; j < this.bladeSegments[i].vertices.length; j++) {
ctx.lineTo(this.bladeSegments[i].vertices[j].x, this.bladeSegments[i].vertices[j].y)
};
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.lineJoin = "round";
ctx.miterLimit = 10;
}
}
},
collision() {
if(this.sword) {
for (let i = 0; i < mob.length; i++) {
if (Matter.Query.collides(this.sword, [mob[i]]).length > 0) {
const dmg = m.dmgScale * Math.sqrt(this.sword.speed) * (tech.sizeIllusion ? 1.1 : 1) * (tech.isStabSword ? 1.5 : 1) * (tech.infinityEdge ? 1.1 : 1);
if(!tech.soundSword) {
if(m.health < m.maxHealth) {
if(tech.isEnergyHealth) {
m.energy += 0.04;
} else {
m.health += 0.01 * (dmg - mob[i].health);
m.displayHealth();
}
} else {
if(tech.isEnergyHealth) {
m.energy += 0.04;
} else {
m.health = m.maxHealth;
m.displayHealth();
}
}
}
mob[i].damage(dmg, true);
simulation.drawList.push({
x: mob[i].position.x,
y: mob[i].position.y,
radius: Math.abs(Math.log(dmg * this.sword.speed) * 40 * mob[i].damageReduction + 3),
color: (tech.soundSword ? "rgba(0, 0, 0, 0.3)": simulation.mobDmgColor),
time: simulation.drawTime
});
break
}
}
if (Matter.Query.collides(this.sword, [genisis]).length > 0) {
m.damage(-0.0142) //balanced!
}
}
}
};
b.guns.push(e);
const gunArray = b.guns.filter(
(obj, index, self) =>
index === self.findIndex((item) => item.name === obj.name)
);
b.guns = gunArray;
} else {
simulation.makeTextLog(`Thank you for using my sword mod<br>I'll save you the trouble of killing genisis<br><div style="font-family: monospace;">g.<span style="color: crimson;">damage</span>(Infinity)</div>`);
g.damage(Infinity);
}
simulation.makeTextLog(`<strong>arena</strong> by <span class='color-var'>Richard0820</span>`);
let index = 0;
let index2 = 0;
let { sword: sword, bladeSegments: bladeSegments } = createSword();
const door = level.door(-950, -3000, 400, 4000, 2000, 10);
const door2 = level.door(550, -3000, 400, 4000, 2000, 10);
level.setPosToSpawn(-7900, -2550); //normal spawn
level.exit.x = 7875;
level.exit.y = -2530;
spawn.mapRect(level.enter.x, level.enter.y + 20, 100, 20); //bump for level entrance
spawn.mapRect(level.exit.x, level.exit.y + 20, 100, 20); //bump for level exit
level.defaultZoom = 2000
simulation.zoomTransition(level.defaultZoom)
document.body.style.backgroundColor = "#987654";
color.map = "#765432" //custom map color
color.block = "#876543";
door.isClosing = true;
door2.isClosing = true;
for (let i = 0; i < 5; i++) {
powerUps.spawn(-6075, -2000, "heal");
}
let bladeTrails = [];
let isOwned = false;
class Particle {
constructor() {
this.x = player.position.x + Math.random() * 10000 - 5000;
this.y = player.position.y + Math.random() * 10000 - 5000;
this.vx = 0;
this.vy = 0;
this.accelX = 0;
this.accelY = 0;
this.life = 2000;
this.alpha = 1;
this.size = 8;
}
update() {
this.vx += this.accelX;
this.vy += this.accelY;
this.x += this.vx;
this.y += this.vy;
if (this.x < player.position.x - 5000 || this.x > player.position.x + 5000 ||
this.y < player.position.y - 5000 || this.y > player.position.y + 5000) {
this.reset();
}
}
reset() {
this.x = player.position.x + Math.random() * 10000 - 5000;
this.y = player.position.y + Math.random() * 10000 - 5000;
this.vx = 0;
this.vy = 0;
this.life = Math.random() * 1000 + 1000;
this.maxLife = this.life;
}
draw() {
ctx.beginPath();
ctx.fillStyle = `rgba(255, 255, 255, ${this.alpha})`;
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
ctx.fill();
ctx.closePath();
}
isAlive() {
return this.life >= 0;
}
}
class ParticleSystem {
constructor() {
this.particles = [];
this.updateHandler = undefined;
}
addParticle(particle) {
this.particles.push(particle);
}
update(deltaTime = 0) {
this.particles.forEach(particle => {
particle.update(deltaTime);
this.updateHandler && this.updateHandler(particle);
});
}
onUpdate(fn) {
this.updateHandler = fn;
}
}
let system = new ParticleSystem();
for (let i = 0; i < 200; i++) {
let particle = new Particle();
system.addParticle(particle);
}
system.onUpdate((particle) => {
if (!particle.isAlive()) {
particle.reset();
}
particle.life -= 10;
particle.accelX = (Math.random() - 0.5) * 0.02;
particle.accelY = (Math.random() - 0.5) * 0.02;
if (particle.life >= particle.maxLife / 2) {
particle.alpha = 1 - (particle.life / particle.maxLife);
} else {
particle.alpha = particle.life / particle.maxLife;
}
particle.update();
});
function update() {
system.update();
}
function draw() {
system.particles.forEach(particle => particle.draw());
}
for(let i = 0; i < system.particles.length; i++) {
system.particles[i].life = 0;
}
level.custom = () => {
update();
draw();
for (let i = 0, len = b.guns.length; i < len; i++) {
if (b.guns[i].name === "sword" && b.guns[i].have) {
isOwned = true;
}
}
Matter.Body.setPosition(sword, { x: -3950, y: -275 - (Math.sin(simulation.cycle / 100) * 50) });
Matter.Body.setAngularVelocity(sword, 0);
door.openClose();
door2.openClose();
if (Matter.Collision.collides(sword, player) && index <= 0 || isOwned) {
bladeTrails = [];
bladeSegments = [];
Composite.remove(engine.world, sword);
sword.parts.forEach(part => {
Composite.remove(engine.world, part);
const index = bullet.indexOf(part);
if (index !== -1) {
bullet.splice(index, 1);
}
});
b.giveGuns("sword");
door.isClosing = false;
door2.isClosing = false;
index++;
}
level.exit.drawAndCheck();
level.enter.draw();
if (tech.isEnergyHealth) {
ctx.beginPath();
const gradient = ctx.createRadialGradient(-3950, 0, 5, -3950, 0, 350 + Math.sin(simulation.cycle * 0.15) * 0.1);
gradient.addColorStop(0, m.fieldMeterColor);
gradient.addColorStop(0.9, "transparent");
// gradient.addColorStop(1, "darkgray");
ctx.fillStyle = gradient;
ctx.strokeStyle = "transparent";
ctx.fillRect(-4000, -350, 100, 350);
ctx.fill();
ctx.stroke();
} else {
ctx.beginPath();
const gradient = ctx.createLinearGradient(-3500, 0, -3500, -350 + Math.sin(simulation.cycle * 0.15) * 0.1);
gradient.addColorStop(0, "crimson");
gradient.addColorStop(0.9, "transparent");
// gradient.addColorStop(1, "darkgray");
ctx.fillStyle = gradient;
ctx.strokeStyle = "transparent";
ctx.fillRect(-4000, -350, 100, 350);
ctx.fill();
ctx.stroke();
}
if (player.position.x > -4000 && player.position.x < -3900 && player.position.y > -350 && player.position.y < 0) {
player.force.y -= 0.03;
}
if (player.position.x > level.exit.x && player.position.x < level.exit.x + 100 && player.position.y > level.exit.y - 150 && player.position.y < level.exit.y - 0 && player.velocity.y < .15 && index2 == 0 && !isUsingSwordMod) {
b.removeGun("sword"); //completely removing the stuff (if you leave properly through the door)
for (let i = 0, len = b.guns.length; i < len; i++) {
if (b.guns[i].name === "sword") {
b.guns.splice(i, 1);
break;
}
}
index2++;
setTimeout(()=> {simulation.makeTextLog(`If you want to keep this sword, visit <a href="https://github.com/Whyisthisnotavalable/n-scythe">https://github.com/Whyisthisnotavalable/n-scythe</a>. The sword is there.`)}, 1000)
}
for (let i = 0; i < bladeSegments.length; i++) {
const blade = bladeSegments[i];
const trail = bladeTrails[i] || [];
const vertices = blade.vertices.map(vertex => ({ x: vertex.x, y: vertex.y }));
trail.push(vertices);
if (trail.length > 10) {
trail.shift();
}
bladeTrails[i] = trail;
}
for (let i = 0; i < bladeTrails.length; i++) {
const trail = bladeTrails[i];
const alphaStep = 1 / trail.length;
let alpha = 0;
for (let j = 0; j < trail.length; j++) {
const vertices = trail[j];
ctx.beginPath();
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let k = 1; k < vertices.length; k++) {
ctx.lineTo(vertices[k].x, vertices[k].y);
};
alpha += alphaStep;
ctx.closePath();
if (tech.isEnergyHealth) {
const eyeColor = m.fieldMeterColor;
const r = eyeColor[1];
const g = eyeColor[2];
const b = eyeColor[3];
const color = `#${r}${r}${g}${g}${b}${b}${Math.round(alpha * 255).toString(16).padStart(2, '0')}`;
ctx.fillStyle = color;
} else {
ctx.fillStyle = `rgba(220, 20, 60, ${alpha})`;
}
ctx.fill();
}
}
for (let i = 0; i < bladeSegments.length; i++) {
ctx.beginPath();
ctx.lineJoin = "miter";
ctx.miterLimit = 100;
ctx.strokeStyle = tech.isEnergyHealth ? m.fieldMeterColor : tech.isAmmoSword ? "#c0c0c0" : "crimson";
ctx.lineWidth = 5;
ctx.fillStyle = "black";
ctx.moveTo(bladeSegments[i].vertices[0].x, bladeSegments[i].vertices[0].y);
for (let j = 0; j < bladeSegments[i].vertices.length; j++) {
ctx.lineTo(bladeSegments[i].vertices[j].x, bladeSegments[i].vertices[j].y)
};
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.lineJoin = "round";
ctx.miterLimit = 10;
}
if (bladeSegments.length) {
ctx.beginPath();
ctx.lineJoin = "miter";
ctx.miterLimit = 100;
ctx.strokeStyle = tech.isEnergyHealth ? m.fieldMeterColor : tech.isAmmoSword ? "#c0c0c0" : "crimson";
ctx.lineWidth = 5;
ctx.fillStyle = "black";
ctx.moveTo(sword.parts[1].vertices[0].x, sword.parts[1].vertices[0].y);
for (let j = 0; j < sword.parts[1].vertices.length; j++) {
ctx.lineTo(sword.parts[1].vertices[j].x, sword.parts[1].vertices[j].y)
};
ctx.closePath();
ctx.fill();
ctx.lineJoin = "round";
ctx.miterLimit = 10;
}
};
level.customTopLayer = () => {};
simulation.ephemera.push({
name: "genesis",
death: false,
pwuspawn: 0,
do() {
if(this.death === true) {
b.explosion(g.pos, 200 * Math.random(), "#000000")
setTimeout(() => {
if(this.pwuspawn === 0) {
powerUps.spawnBossPowerUp(g.pos.x, g.pos.y)
this.pwuspawn++;
}
simulation.removeEphemera(this.name);
simulation.removeEphemera("genisisScythe");
}, 1000);
}
if(g.health >= 0) {
if(g.health < g.maxHealth) {
g.health++;
}
const dist = Matter.Vector.magnitudeSquared(Matter.Vector.sub(genisis.position, player.position));
const time = Math.sqrt(dist) / 60;
g.alive = true;
g.targetX = m.pos.x + player.velocity.x * time;
g.targetY = m.pos.y + player.velocity.y * time;
} else {
this.death = true;
g.alive = false;
}
if(g.alive) {
g.cycle++;
g.move()
g.lookDefault();
g.drawDefault();
g.drawHealth();
genisis.force.y += g.mass * simulation.g
g.setFillColors();
control.right = g.angle > -Math.PI * 2/5 && g.angle < Math.PI * 2/5;
control.left = g.angle > Math.PI * 3/5 || g.angle < -Math.PI * 3/5;
control.down = g.angle > Math.PI * 3/ 10 && g.angle < Math.PI * 7/10;
if(Matter.Query.collides(genisis, body).length || Matter.Query.collides(genisisHead, map).length || Matter.Query.collides(genisisBodySensor, map).length && !control.down) {
if(g.buttonCD_jump < g.cycle) {
g.jump();
}
}
control.up = g.angle > -Math.PI * 6/10 && g.angle < -Math.PI * 4/10;
if (g.onGround) {
g.groundControl()
} else {
g.airControl()
}
if(g.pos.y > simulation.fallHeight) {
Matter.Body.setPosition(genisis, {
x: level.exit.x,
y: level.exit.y
})
}
} else {
genisis.collisionFilter.mask = cat.map | cat.body;
Matter.Body.setPosition(genisis, {
x: 0,
y: 0
})
}
if(simulation.testing) {
ctx.beginPath();
let bodyDraw = genisisJumpSensor.vertices;
ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
for (let j = 1; j < bodyDraw.length; ++j) {
ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
}
ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
ctx.fillStyle = "rgba(255, 0, 0, 0.5)";
ctx.fill();
ctx.beginPath();
bodyDraw = genisisBody.vertices;
ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
for (let j = 1; j < bodyDraw.length; ++j) {
ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
}
ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
ctx.fillStyle = "rgba(0, 255, 255, 0.25)";
ctx.fill();
ctx.beginPath();
bodyDraw = genisisHead.vertices;
ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
for (let j = 1; j < bodyDraw.length; ++j) {
ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
}
ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
ctx.fillStyle = "rgba(255, 255, 0, 0.4)";
ctx.fill();
ctx.beginPath();
bodyDraw = genisisHeadSensor.vertices;
ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
for (let j = 1; j < bodyDraw.length; ++j) {
ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
}
ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
ctx.fillStyle = "rgba(0, 0, 255, 0.25)";
ctx.fill();
ctx.beginPath();
bodyDraw = genisisBodySensor.vertices;
ctx.moveTo(bodyDraw[0].x, bodyDraw[0].y);
for (let j = 1; j < bodyDraw.length; ++j) {
ctx.lineTo(bodyDraw[j].x, bodyDraw[j].y);
}
ctx.lineTo(bodyDraw[0].x, bodyDraw[0].y);
ctx.fillStyle = "rgba(255, 0, 255, 0.25)";
ctx.fill();
}
Events.on(engine, "collisionStart", function(event) {
g.genisisOnGroundCheck(event);
GenisisCollisionChecks(event);
});
Events.on(engine, "collisionActive", function(event) {
g.genisisOnGroundCheck(event);
});
Events.on(engine, "collisionEnd", function(event) {
g.genisisOffGroundCheck(event);
});
}
})
let evo = {
isLongBlade: true,
isScytheRange: true,
scytheRange: 3,
isScytheRad: false,
scytheRad: 0,
isDoubleScythe: false,
isPhaseScythe: false,
isMeleeScythe: false,
isStunScythe: false,
};
simulation.ephemera.push({ name: "genisisScythe", cycle: 0, scythe: undefined, bladeSegments: undefined, bladeTrails: [], angle: 0, constraint: undefined, fireCD: 0, do() { if(isOwned) { if(g.health < 500 && g.health > 200) { evo = { isLongBlade: true, isScytheRange: true, scytheRange: 3, isScytheRad: false, scytheRad: 1, isDoubleScythe: true, isPhaseScythe: false, isMeleeScythe: false, isStunScythe: false, }; } else if(g.health < 200 && g.health > 50) { evo = { isLongBlade: true, isScytheRange: true, scytheRange: 3, isScytheRad: true, scytheRad: 1, isDoubleScythe: true, isPhaseScythe: true, isMeleeScythe: true, isStunScythe: true, }; } else if(g.health < 50) { evo = { isLongBlade: true, isScytheRange: true, scytheRange: 9, isScytheRad: true, scytheRad: 6, isDoubleScythe: true, isPhaseScythe: true, isMeleeScythe: true, isStunScythe: true, }; } if (g.cycle > this.fireCD && !this.scythe) { this.fireCD = g.cycle + 30; if (!this.scythe) { ({ scythe: this.scythe, bladeSegments: this.bladeSegments} = this.createAndSwingScythe()); this.angle = g.angle; } } if(this.scythe && g.cycle > this.cycle + 30 || !g.alive && this.scythe) { Composite.remove(engine.world, this.scythe); this.scythe.parts.forEach(part => { Composite.remove(engine.world, part); const index = bullet.indexOf(part); if (index !== -1) { bullet.splice(index, 1); } }); this.scythe = undefined; this.bladeTrails = []; } else { if (this.scythe && !evo.isMeleeScythe) { if (!(this.angle > -Math.PI / 2 && this.angle < Math.PI / 2)) { Matter.Body.setAngularVelocity(this.scythe, -Math.PI 0.15 - (evo.scytheRad ? evo.scytheRad 0.1 : 0)); } else { Matter.Body.setAngularVelocity(this.scythe, Math.PI 0.15 + (evo.scytheRad ? evo.scytheRad 0.1 : 0)); } Matter.Body.setVelocity(this.scythe, { x: Math.cos(this.angle) 30, y: Math.sin(this.angle) 30 }); } else if(this.scythe && evo.isMeleeScythe) { if (!(this.angle > -Math.PI / 2 && this.angle < Math.PI / 2)) { Matter.Body.setAngularVelocity(this.scythe, -Math.PI 0.1 + (evo.isStunScythe ? 0.1 : 0)); } else { Matter.Body.setAngularVelocity(this.scythe, Math.PI 0.1 - (evo.isStunScythe ? 0.1 : 0)); } Matter.Body.setPosition(this.scythe, genisis.position); } } if(this.scythe) { for (let i = 0; i < this.bladeSegments.length; i++) { const blade = this.bladeSegments[i]; const trail = this.bladeTrails[i] || []; const vertices = blade.vertices.map(vertex => ({ x: vertex.x, y: vertex.y })); trail.push(vertices); if (trail.length > 10) { trail.shift(); } this.bladeTrails[i] = trail; }
for (let i = 0; i < this.bladeTrails.length; i++) {
const trail = this.bladeTrails[i];
const alphaStep = 1 / trail.length;
let alpha = 0;
for (let j = 0; j < trail.length; j++) {
const vertices = trail[j];
ctx.beginPath();
ctx.moveTo(vertices[0].x, vertices[0].y);
for (let k = 1; k < vertices.length; k++) {
ctx.lineTo(vertices[k].x, vertices[k].y);
};
alpha += alphaStep;
ctx.closePath();
ctx.fillStyle = `rgba(100, 20, 255, ${alpha})`;
ctx.fill();
}
}
for(let i = 0; i < this.bladeSegments.length; i++) {
ctx.beginPath();
ctx.lineJoin = "miter";
ctx.miterLimit = 100;
ctx.strokeStyle = `rgb(100, 20, 255)`;
ctx.lineWidth = 5;
ctx.fillStyle = "black";
ctx.moveTo(this.bladeSegments[i].vertices[0].x, this.bladeSegments[i].vertices[0].y);
for(let j = 0; j < this.bladeSegments[i].vertices.length; j++) {
ctx.lineTo(this.bladeSegments[i].vertices[j].x, this.bladeSegments[i].vertices[j].y)
};
ctx.closePath();
ctx.stroke();
ctx.fill();
ctx.lineJoin = "round";
ctx.miterLimit = 10;
}
}
if(this.scythe) {
for (let i = 0; i < mob.length; i++) {
if (Matter.Query.collides(this.scythe, [mob[i]]).length > 0) {
const dmg = m.dmgScale * 0.12 * 2.73 * (evo.isLongBlade ? 1.3 : 1) * (evo.scytheRange ? evo.scytheRange * 1.15 : 1) * (evo.isDoubleScythe ? 0.9 : 1) * (evo.scytheRad ? evo.scytheRad * 1.5 : 1);
mob[i].damage(dmg, true);
simulation.drawList.push({
x: mob[i].position.x,
y: mob[i].position.y,
radius: Math.sqrt(dmg) * 50,
color: simulation.mobDmgColor,
time: simulation.drawTime
});
if(!evo.isMeleeScythe) {
const angle = Math.atan2(mob[i].position.y - this.scythe.position.y, mob[i].position.x - this.scythe.position.x);
this.scythe.force.x += Math.cos(angle) * 2;
this.scythe.force.y += Math.sin(angle) * 2;
}
if(evo.isStunScythe) {
mobs.statusStun(mob[i], 90);
}
break
}
}
if(Matter.Query.collides(this.scythe, [player]).length > 0 && m.immuneCycle < m.cycle) {
const dmg = 0.02 * (evo.isLongBlade ? 1.3 : 1) * (evo.scytheRange ? evo.scytheRange * 1.15 : 1) * (evo.isDoubleScythe ? 0.9 : 1) * (evo.scytheRad ? evo.scytheRad * 1.5 : 1); // actual scythe scallings one tap the player so this is nerfed for genisis
m.damage(dmg);
m.immuneCycle = m.cycle + 10;
simulation.drawList.push({
x: player.position.x,
y: player.position.y,
radius: Math.sqrt(dmg) * 50,
color: simulation.mobDmgColor,
time: simulation.drawTime
});
if(!evo.isMeleeScythe) {
const angle = Math.atan2(player.position.y - this.scythe.position.y, player.position.x - this.scythe.position.x);
this.scythe.force.x += Math.cos(angle) * 2;
this.scythe.force.y += Math.sin(angle) * 2;
}
}
}
}
},
createAndSwingScythe(x = genisis.position.x, y = genisis.position.y, angle = g.angle) {
this.cycle = g.cycle + 60 + (evo.scytheRange * 6);
const handleWidth = 20;
const handleHeight = 200 + (evo.isLongBlade ? 30 : 0) + (evo.isMeleeScythe ? 200 : 0);
const handle = Bodies.rectangle(x, y, handleWidth, handleHeight, spawn.propsIsNotHoldable);
bullet[bullet.length] = handle;
bullet[bullet.length - 1].do = () => {};
const bladeWidth = 100;
const bladeHeight = 20;
const numBlades = 10 + (evo.isLongBlade ? 1 : 0) + (evo.isMeleeScythe ? 3 : 0);
const extensionFactor = 5.5;
const bladeSegments = [];
if(!evo.isDoubleScythe) {
for (let i = 0; i < numBlades; i++) {
const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
const bladeX = x - handleWidth / 2 + i * (bladeWidth / 2) - extensionFactorFraction * (bladeWidth / 2);
const bladeY = y + handleHeight / 2 - i * (bladeHeight / (3 ** i));
const vertices = [
{ x: bladeX, y: bladeY - bladeHeight / 2 },
{ x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
];
const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = blade;
bullet[bullet.length - 1].do = () => {};
Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 180) * 5));
bladeSegments.push(blade);
}
} else {
for (let i = 0; i < numBlades; i++) {
const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
const bladeX = x - handleWidth / 2 + i * (bladeWidth / 2) - extensionFactorFraction * (bladeWidth / 2);
const bladeY = y + handleHeight / 2 - i * (bladeHeight / (3 ** i));
const vertices = [
{ x: bladeX, y: bladeY - bladeHeight / 2 },
{ x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
];
const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = blade;
bullet[bullet.length - 1].do = () => {};
Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 180) * 5));
bladeSegments.push(blade);
}
for (let i = 0; i < numBlades; i++) {
const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
const bladeX = x + handleWidth / 2 - i * (bladeWidth / 2) + extensionFactorFraction * (bladeWidth / 2);
const bladeY = y - handleHeight / 2 - i * (bladeHeight / (3 ** i));
const vertices = [
{ x: bladeX, y: bladeY - bladeHeight / 2 },
{ x: bladeX + bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX - bladeWidth / 2, y: bladeY + bladeHeight / 2 },
{ x: bladeX, y: bladeY - bladeHeight / 2 + 10 },
];
const blade = Bodies.fromVertices(bladeX, bladeY, vertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = blade;
bullet[bullet.length - 1].do = () => {};
Matter.Body.rotate(blade, -Math.sin(i * (Math.PI / 180) * 5) + Math.PI);
bladeSegments.push(blade);
}
}
const scythe = Body.create({
parts: [handle, ...bladeSegments],
});
Composite.add(engine.world, scythe);
Matter.Body.setPosition(scythe, { x, y });
scythe.collisionFilter.category = cat.body;
scythe.collisionFilter.mask = cat.mobBullet | cat.player;
if(!evo.isMeleeScythe) {
setTimeout(()=>{
scythe.collisionFilter.mask = cat.mobBullet | cat.mob | cat.player;
}, 1000)
}
if ((angle > -Math.PI / 2 && angle < Math.PI / 2)) {
Body.scale(scythe, -1, 1, { x, y });
}
scythe.frictionAir -= 0.01;
return { scythe, bladeSegments };
},
})
spawn.mapRect(-10000, 0, 20000, 2000);
spawn.mapRect(-10000, -10000, 2000, 10000);
spawn.mapRect(8000, -10000, 2000, 10000);
spawn.mapRect(-10000, -10000, 20000, 2000);
spawn.spawnStairs(8000, 0, 15, 2500, 2500, true);
spawn.spawnStairs(-8000, 0, 15, 2500, 2500, false);
spawn.mapRect(-4000, -10, 100, 20);
spawn.mapRect(4000, -10, 100, 20);
spawn.mapRect(-1000, -10000, 2000, 8000);
// spawn.mapRect(-500, -10000, 1000, 9700);
function createSword(x = 0, y = 0) { //sword asthetic
const handleWidth = 20;
const handleHeight = 150;
const handle = Bodies.rectangle(x, y, handleWidth, handleHeight, spawn.propsIsNotHoldable);
bullet[bullet.length] = handle;
handle.customName = "handle";
bullet[bullet.length - 1].do = () => {};
const pommelWidth = 30;
const pommelHeight = 40;
const pommelVertices = [
{ x: x, y: y + handleHeight / 2 + pommelHeight / 2 },
{ x: x + pommelWidth / 2, y: y + handleHeight / 2 },
{ x: x, y: y + handleHeight / 2 - pommelHeight / 2 },
{ x: x - pommelWidth / 2, y: y + handleHeight / 2 },
];
const pommel = Bodies.fromVertices(x, y + handleHeight / 2, pommelVertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = pommel;
bullet[bullet.length - 1].do = () => {};
if(tech.soundSword) {
bullet[bullet.length - 1].draw = () => {};
}
// Blade setup
const bladeWidth = 100 * (tech.soundSword ? 3 : 1);
const bladeHeight = 20 * (tech.soundSword ? 3 : 1);
const numBlades = 15;
const extensionFactor = 5;
const bladeSegments = [];
for (let i = 0; i < numBlades; i++) {
const extensionFactorFraction = (i / (numBlades - 1)) * extensionFactor;
const mirroredBladeX = x - i * (bladeWidth / 20);
const mirroredBladeY = y - handleHeight / 2 - i * (bladeHeight / 4.5) * extensionFactor;
const mirroredVertices = [
{ x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 },
{ x: mirroredBladeX + bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
{ x: mirroredBladeX - bladeWidth / 2, y: mirroredBladeY + bladeHeight / 2 },
{ x: mirroredBladeX, y: mirroredBladeY - bladeHeight / 2 + 10 },
];
const mirroredBlade = Bodies.fromVertices(mirroredBladeX, mirroredBladeY, mirroredVertices, spawn.propsIsNotHoldable);
bullet[bullet.length] = mirroredBlade;
bullet[bullet.length - 1].do = () => {};
if(tech.soundSword) {
bullet[bullet.length - 1].draw = () => {};
}
Matter.Body.rotate(mirroredBlade, Math.sin(i * (Math.PI / 270) * 15));
bladeSegments.push(mirroredBlade);
}
bladeSegments.push(pommel);
const sword = Body.create({
parts: [handle, ...bladeSegments],
});
Composite.add(engine.world, sword);
Matter.Body.setPosition(sword, { x, y });
sword.collisionFilter.category = cat.bullet;
sword.collisionFilter.mask = cat.mobBullet | cat.powerup | cat.mob;
Body.scale(sword, -1, 1, { x, y });
Body.rotate(sword, Math.PI + Math.PI / 15)
return { sword, bladeSegments };
}
},
I split it up because it was too long
W richard fr fr
this has the nerdface seal of approval
agreed.
Can you explain what's new in this update. Also can you add the code as a text file attachment.
I added a new boss, updated the sword code, removed mobs because they spawned too high up, and fixed particle rendering bug. I probably fixed some other bugs but I forgot.
ok it's in next patch.