Back to Index Page generated: Oct 27, 2025, 5:37:22 AM

Expansion Stashes

Content

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Adds fun activities and events in space: treasure caches, honeypots, abandoned stashes, restricted military airspace, asteroids, etc. Adds fun activities and events in space: treasure caches, honeypots, abandoned stashes, restricted military airspace, asteroids, etc.
Identifier oolite.oxp.popsch.Stashes oolite.oxp.popsch.Stashes
Title Stashes Stashes
Category Activities Activities
Author Popsch Popsch
Version 0.3.2 0.3.2
Tags popsch, proximity popsch, proximity
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL https://wiki.alioth.net/index.php/Stashes n/a
Download URL https://wiki.alioth.net/img_auth.php/c/c3/Stashes-0.3.2.oxz n/a
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1761538753

Documentation

Also read http://wiki.alioth.net/index.php/Stashes

Equipment

This expansion declares no equipment.

Ships

Name
No-Fly Zone Marker
piratetrap_asteroid

Models

This expansion declares no models.

Scripts

Path
Scripts/speculatius.js
this.name = 'AsteroidTrap';
this.copyright = '(C) 2015 Popsch.';
this.licence = 'CC-NC-by-SA 2.0';

this.debug = false;

'use strict';

/** Distance at which the pirates take off */
this.proximityWarning = 15000;

/** Likelyhood of police trap present */
this.TRAP_LIKELIHOOD = 0.4; // will be divided by the tech level
//this.TRAP_LIKELIHOOD = 1;

this.asteroids = null;
this.announcer = null;

this.distanceChecker = null;

/** launch from station for testing */
this.shipWillLaunchFromStation = function () {
    if (!this.debug) return;

    log(this.name, 'Ship LAUNCHED.');
    player.ship.position = system.locationFromCode('OUTER_SYSTEM_OFFPLANE');

    this.$populateWithTrap(player.ship.position.add([1E4, 1E4, 1E4]));
};

this.$populateWithTrap = function (pos) {
    var asteroidCount = (system.scrambledPseudoRandomNumber(clock.seconds) / 2) * 10 + 2;
    if (this.debug) log(this.name, 'initialized trap with asteroids: ' + asteroidCount);

    // instantiate cargopods
    this.asteroids = system.addShips('piratetrap_asteroid', asteroidCount, pos, 7000);

    this.distanceChecker = new Timer(this, this.$checkDistance, 5);

};

/** populate the system */
this.systemWillPopulate = function (station) {
    if (system.scrambledPseudoRandomNumber(clock.seconds) < this.TRAP_LIKELIHOOD / system.techLevel) {
        system.setPopulator('trap', {
            callback: function (pos) {
                this.$populateWithTrap(pos);
            }.bind(this),
            location: 'LANE_WP'
        });
    }
};

/** Timer function callback to check the distance to the player */
this.$checkDistance = function () {
    var ships = system.filteredEntities(this,
        function $checkAsteroid(entity) {
            return (entity.primaryRole == 'piratetrap_asteroid');
        },
        player.ship, 17000);

    //log(this.name,'timer: '+this.distanceChecker);

    if ((ships == null) || (ships.length == 0)) {
        // nothing close
        this.distanceChecker.stop();
        this.distanceChecker = new Timer(this, this.$checkDistance, 5);
        return;
    }

    // spring the trap
    this.asteroids.forEach(function (entry) {
        var s = system.addShips('pirate', 1, entry.position, 250)[0];
        s.target = player.ship;
        s.performAttack();
        this.announcer = s;
    }.bind(this));

    s.commsMessage(expandMissionText("stashes_trap_surprise"));

    this.distanceChecker.stop();
    this.distanceChecker = null;
};
Scripts/stashes.js
this.name = 'Stashes';
this.copyright = '(C) 2015 Popsch.';
this.licence = 'CC-NC-by-SA 2.0';

this.debugProximityTrap = 0;

'use strict';

this.debug = false;

/** Distance at which a warning message gets triggered */
this.proximityWarning = 23000;

/** Distance at which the alarm gets triggered */
this.proximityAlert = 15010;

/** Likelyhood of police trap present */
this.TrapLikelihood = 0.02;
//this.TrapLikelihood = 1;

this.trapPosition;

this.TRAP_SPRUNG = 0;
this.TRAP_ACTIVE = 1;

this.trapState = TRAP_ACTIVE;

this.trapType = 0;

this.buoy = null;

this.$sendMilitaryWarning = function () {
    this.buoy.commsMessage(expandMissionText("stashes_military_warning"), player.ship);
};

this.$sendNormalWarning = function () {
    this.buoy.commsMessage(expandMissionText("stashes_normal_warning"), player.ship);
};

this.$respondAlertMilitary = function () {
    player.bounty += 100;

    var s = system.addShips('police', 3, player.ship.position, 10000);
    s.forEach(function (entry) {
        entry.target = player.ship;
        entry.performAttack();
    });
    s[0].commsMessage(expandMissionText("stashes_spy_alert"), player.ship);
};

this.$respondAlertRaiders = function () {
    var s = system.addShips('pirate', 4, player.ship.position, 10000);
    s.forEach(function (entry) {
        entry.target = player.ship;
        entry.performAttack();
    });
    s[0].commsMessage(expandMissionText("stashes_raider_alert"), s[1]);
};

this.$respondAlertPolice = function () {
    player.bounty += 25;

    var s = system.addShips('police', 1, player.ship.position, 10000);
    s.forEach(function (entry) {
        entry.target = player.ship;
        entry.performAttack();
    });
    s[0].commsMessage(expandMissionText("stashes_police_alert"), player.ship);
};

this.$respondAlertMerchant = function () {
    this.buoy.commsMessage(expandMissionText("stashes_trader_alert"), player.ship);
    for (var i = 0; i < 2; i++) {
        var adder = system.addShips('[adder]', 1, this.buoy.position, 100)[0];
        adder.target = player.ship;
        adder.awardEquipment('EQ_HARDENED_MISSILE');
        adder.fireMissile();
        adder.remove();
    }
    // keep the trap active
    this.trapState = TRAP_ACTIVE;
    this.distanceChecker = new Timer(this, this.$checkDistance, 4);
};

this.$respondAlertAbandoned = function () {
    this.buoy.commsMessage(expandMissionText("stashes_trader_alert"), player.ship);
};

this.$respondAlertMalfunction = function () {
    this.buoy.commsMessage(expandMissionText("stashes_faulty_alert"), player.ship);
};

this.TRAPS = [
    //prob, min-pods, max-pods, warning callback, alert callback
    0.05, 4, 7, this.$sendMilitaryWarning, this.$respondAlertMilitary,
    0.20, 3, 7, this.$sendNormalWarning, this.$respondAlertRaiders,
    0.30, 3, 4, this.$sendNormalWarning, this.$respondAlertPolice,
    0.70, 3, 7, this.$sendNormalWarning, this.$respondAlertMerchant,
    0.85, 0, 0, this.$sendNormalWarning, this.$respondAlertAbandoned,
    1.00, 3, 7, this.$sendNormalWarning, this.$respondAlertMalfunction
];


/** launch from station for testing */
this.shipWillLaunchFromStation = function () {
    if (this.debugProximityTrap != 1) return;

    if (this.debug) {
        log(this.name, 'Ship LAUNCHED.');
        log(this.name, this.TRAPS);
    }
    player.ship.position = system.locationFromCode('OUTER_SYSTEM_OFFPLANE');

    this.$populateWithTrap(player.ship.position.add([1E4, 1E4, 1E4]));
};

this.$pickTrap = function () {
    var x = system.scrambledPseudoRandomNumber(clock.seconds);
    for (var idx = 0; idx < this.TRAPS.length; idx += 5) {
        // log(this.name, x + ' :: ' + idx + ' :: ' + this.TRAPS[idx]);
        if (x < this.TRAPS[idx]) {
            return (idx / 5);
        }
    }
    return (idx / 5);
};

this.$populateWithTrap = function (pos) {
    this.trapType = this.$pickTrap();
    this.trapState = TRAP_ACTIVE;
    if (this.debug) log(this.name, 'initialize trap type: ' + this.trapType);

    // location of the stash
    this.trapPosition = pos;

    // instantiate cargopods
    var pods = Math.floor(system.scrambledPseudoRandomNumber(clock.seconds) * (this.TRAPS[this.trapType * 5 + 2] - this.TRAPS[this.trapType * 5 + 1] + 1)) + this.TRAPS[this.trapType * 5 + 1];

    if (pods != 0)
        system.addShips('cargopod', pods, this.trapPosition, 1000);

    var buoys = system.addShips('nofly_buoy', 1, this.trapPosition, 1000);
    this.buoy = buoys[0];

    this.distanceChecker = new Timer(this, this.$checkDistance, 5, 5);
};

/** launch from station for testing */
this.systemWillPopulate = function (station) {
    if (system.scrambledPseudoRandomNumber(clock.seconds) < this.TrapLikelihood * system.techLevel) {
        //player.commsMessage('This system looks interesting!');
        system.setPopulator('trap', {
            callback: function (pos) {
                this.$populateWithTrap(pos);
            }.bind(this),
            location: 'LANE_WP'
        });
    }
};


/** Timer function callback to check the distance to the player */
this.$checkDistance = function () {

    if (this.trapState != TRAP_ACTIVE) {
        // how can we still be here?
        // nevertheless, defensive programming
        if (this.debug) log(this.name, 'trapstate not active (' + this.trapState + '); disable checker.');
        this.distanceChecker.stop();
        return;
    }

    var ships = system.filteredEntities(this,
        function $isNoFlyBuoy(entity) {
            return (entity.primaryRole == 'nofly_buoy');
        },
        player.ship, 25600);


    if (ships == null) return; // nothing close
    if (ships.length == 0) return; // nothing close

    // de-array
    var ship = ships[0];

    var distance = player.ship.position.distanceTo(ship);

    //log(this.name, 'distance from buoy:' + distance);

    // proximity alert must come first before warning due to 'return' statement
    if (distance < this.proximityAlert) {
        this.trapState = this.TRAP_SPRUNG;
        if (this.debug) log(this.name, 'Stopping timer since the alarm went off.');
        this.distanceChecker.stop();

        //log(this.name, 'issuing alert ('+ (this.trapType * 5 + 4) +'):'+TRAPS[this.trapType * 5 + 4]);

        this.TRAPS[this.trapType * 5 + 4]();
        return;
    }

    if (distance < this.proximityWarning) {
        //log(this.name, 'issuing waring ('+ (this.trapType * 5 + 3) +'): '+TRAPS[this.trapType * 5 + 3]);
        this.TRAPS[this.trapType * 5 + 3]();
        return;
    }
}