landgreen / n-gon

2-d physics rogue-lite platformer shooter
https://landgreen.github.io/n-gon/
GNU General Public License v3.0
134 stars 193 forks source link

New map: Trial #281

Closed Tarantula-Hawk closed 2 weeks ago

Tarantula-Hawk commented 2 weeks ago

I noticed that frog and other members of the community were recently finishing up their own maps. This inspired me and cirryn to finally complete the map that we were working on but put on the backburner for 9 or so months.

trial() { // trial, collab between Cirryn and Tarantula Hawk
        simulation.makeTextLog(`<strong>trial</strong> by <span class='color-var'>Cirryn and Tarantula Hawk</span>`);
        level.setPosToSpawn(0, -50);
        level.exit.x = 4150;
        level.exit.y = -30;
        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 = 1800;
        simulation.zoomTransition(level.defaultZoom);
        document.body.style.backgroundColor = "#d8dadf";
        const button = level.button(2000, 0);
        const door = level.door(3930, -300, 40, 300, 300, 10);
        door.isClosing = false;
        var didTrialBegin = false;

        const customMob = {
            assassin(x, y) { // modified slasher
                mobs.spawn(x, y, 3, 30, "black");
                let me = mob[mob.length - 1];
                Matter.Body.rotate(me, 2 * Math.PI * Math.random());
                me.accelMag = 0.0008 * simulation.accelScale;
                me.torqueMagnitude = 0.00002 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
                me.frictionStatic = 0;
                me.frictionAir = 0.08;
                me.delay = 120 * simulation.CDScale;
                me.cd = 0;
                spawn.shield(me, x, y);
                me.damageReduction = 0;
                const start = window.performance.now(); // they only last ~ten seconds
                const lifespan = 15000 + 700 * (Math.random() - 0.5);
                me.onDamage = function () {
                    Matter.Body.setAngularVelocity(me, me.angularVelocity + 1);
                };
                me.do = function () {
                    this.checkStatus();
                    this.alwaysSeePlayer();
                    this.attraction();
                    this.health = 1 - (window.performance.now() - start) / lifespan;
                    if (this.health < 0) {
                        this.death();
                    }
                    Matter.Body.setAngularVelocity(me, me.angularVelocity + 0.05);
                };
            },
            mercenary(x, y) { // fast boi
                mobs.spawn(x, y, 3, 60, "white");
                let me = mob[mob.length - 1];
                Matter.Body.rotate(me, 2 * Math.PI * Math.random());
                me.accelMag = 0.001 * simulation.accelScale;
                me.torqueMagnitude = 0.00001 * me.inertia * (Math.random() > 0.5 ? -1 : 1);
                me.frictionStatic = 0;
                me.frictionAir = 0.03;
                me.delay = 120 * simulation.CDScale;
                me.cd = 0;
                spawn.shield(me, x, y);
                me.damageReduction = 0;
                const start = window.performance.now(); // they only last ~ten seconds
                const lifespan = 25000 + 700 * (Math.random() - 0.5);
                me.onDamage = function () {
                    Matter.Body.setAngularVelocity(me, me.angularVelocity + 1);
                };
                me.do = function () {
                    this.checkStatus();
                    this.attraction();
                    this.health = 1 - (window.performance.now() - start) / lifespan;
                    if (this.health < 0) {
                        this.death();
                    }
                    this.alwaysSeePlayer();
                };
            }
            // eventually maybe add more custom mob types
        };

        function randomWave(count, source) { // generates a wave list from a source
            // checks in spawn first, then customMob, for the sources
            var ret = [];
            for (var i = 0; i < count; i++) {
                var pick = source[Math.floor(Math.random() * source.length)];
                if (spawn[pick]) {
                    ret.push(spawn[pick]);
                }
                else if (customMob[pick]) {
                    ret.push(customMob[pick]);
                }
            }
            return ret;
        }

        function wave(mobs) { // takes a list of functions that accept x,y coordinates to spawn a mob and spawns them in the ceiling
            for (var i = 0; i < mobs.length; i++) {
                var x = 1000 + 2400 * i / mobs.length + 200 * (Math.random() - 0.5);
                var y = -950 - 100 * Math.random();
                mobs[i](x, y);
            }
            const ammoCount = Math.random() * (10 - simulation.difficulty / 4);
            for (var i = 0; i < ammoCount; i++) {
                powerUps.spawn(3300, -1000, "ammo");
            }
        }

        level.custom = () => {
            door.openClose();
            level.exit.drawAndCheck();
            level.enter.draw();
        };
        level.customTopLayer = () => {
            button.query();
            button.draw();
            door.draw();
            if (!button.isUp && !didTrialBegin) {
                didTrialBegin = true;
                simulation.makeTextLog('<strong>The Trial has begun.</strong>');

                setTimeout(() => {
                    simulation.makeTextLog('<span style="color: purple;">first wave (domitable)</span>');
                    wave(randomWave(2 + simulation.difficulty * 0.1, spawn.fullPickList));
                }, 3000);

                setTimeout(() => {
                    simulation.makeTextLog('<span style="color: purple;">second wave (domitable)</span>');
                    wave(randomWave(2 + simulation.difficulty * 0.1, spawn.fullPickList));
                }, 13000);

                setTimeout(() => {
                    simulation.makeTextLog('<span style="color: purple;">third wave <strong>(indomitable)</strong></span>');
                    wave(randomWave(4, ["assassin"]));
                }, 23000);

                setTimeout(() => {
                    simulation.makeTextLog('<span style="color: purple;">fourth wave (domitable)</span>');
                    wave(randomWave(4 + simulation.difficulty / 2, spawn.fullPickList));
                }, 39000);

                setTimeout(() => {
                    simulation.makeTextLog('<span style="color: purple;">fifth wave (domitable)</span>');
                    wave(randomWave(4 + simulation.difficulty / 2, spawn.fullPickList));
                }, 49000);

                setTimeout(() => {
                    simulation.makeTextLog('<span style="color: purple;">sixth wave <strong>(indomitable)</strong></span>');
                    wave(randomWave(7, ["mercenary"]));
                }, 59000);

                setTimeout(() => {
                    simulation.makeTextLog('<span style="color: red;">seventh wave <strong>(boss)</strong></span>');
                    spawn.randomLevelBoss(700, -1000);
                    var mainBoss = mob[mob.length - 1];
                    mainBoss.oldOnDeath = mainBoss.onDeath;
                    mainBoss.onDeath = () => {
                        door.isClosing = false;
                        powerUps.spawn(4150, -30, "tech");
                        powerUps.spawn(4150, -30, "tech");
                        mainBoss.oldOnDeath();
                    }
                    spawn.secondaryBossChance(3500, -1000);
                }, 86000);

                door.isClosing = true;
            }
        };

        spawn.mapRect(-100, 0, 10000, 10000); // the left half of the room
        spawn.mapRect(-10000, -300, 9900, 10000);
        spawn.mapRect(-100, -300, 400, 100);
        spawn.mapRect(200, -800, 100, 500);
        spawn.mapRect(200, -800, 500, 100);
        spawn.mapRect(600, -1000, 100, 200);

        spawn.mapRect(600, -1100, 3000, 100); // the ceiling

        spawn.mapRect(3500, -1000, 100, 200); // the right half of the room
        spawn.mapRect(3500, -800, 500, 100);
        spawn.mapRect(3900, -800, 100, 500);
        spawn.mapRect(3900, -300, 400, 100);
        spawn.mapRect(4300, -300, 10000, 10000);

        for (var i = 0; i < 4; i++) { // "door" at the entrance
            spawn.bodyRect(200, -200 + i * 50, 20, 50);
        }

        for (var i = 0; i < 5; i++) { // some random rubble in the first half of the room
            spawn.bodyRect(400 + Math.random() * 1000, -200, 40 + Math.random() * 40, 40 + Math.random() * 40);
        }

        powerUps.addResearchToLevel(); //needs to run after mobs are spawneds
    },
landgreen commented 2 weeks ago

cool, looks good!