| Scripts/pirateCove.js | "use strict";
this.name = "Pirate_Coves";
this.author = "lazygun (JS adaption by EW)";
this.copyright = "lazygun";
this.description = "Adds pirate coves to the system.";
this.version = "2.0";
this._spawning = {
    neutral: {replace:true, chance:0.25}, // should be equivalent to roles = "rockhermit(0.25)";
    chaotic: {replace:false, chance:0.25},
    pirate: {replace:false, chance:0.25},
    single: {
        allowed: true,
        sampleAtDiso: true,
        // max min range calculate
        // if max = 0.3 and min = 0.1, range will be from -0.3 to -0.1 or from +0.1 to +0.3
        xRange: {max: 0.3, min: 0.1},
        yRange: {max: 0.3, min: 0.1},
        zRange: {max: 0.4, min: 0.1}
    }
}
// configuration settings for use in Lib_Config
this._pcConfig = {
	Name: this.name,
	Alias: "Pirate Coves",
	Display: "RH replace spawning options",
	Alive: "_pcConfig",
	Bool: {
		B0: {Name: "_spawning.neutral.replace", Def: true, Desc: "Allow neutral RH replacement"},
		B1: {Name: "_spawning.chaotic.replace", Def: false, Desc: "Allow chaotic RH replacement"},
		B2: {Name: "_spawning.pirate.replace", Def: false, Desc: "Allow pirate RH replacement"},
        Info: "0 - Allows pirate coves to replace neutral Rock Hermits\n" + 
            "1 - Allows pirate coves to replace chaotic Rock Hermits\n" + 
            "2 - Allows pirate coves to replace pirate Rock Hermits"
	},
	SInt: {
		S0: {Name: "_spawning.neutral.chance", Def: 0.25, Min: 0.0, Max: 100, Desc: "Neutral RH replace chance", Float:true},
		S1: {Name: "_spawning.chaotic.chance", Def: 0.25, Min: 0.0, Max: 100, Desc: "Chaotic RH replace chance", Float:true},
		S2: {Name: "_spawning.pirate.chance", Def: 0.25, Min: 0.0, Max: 100, Desc: "Pirate RH replace chance", Float:true},
		Info: "0 - Chance of replacing neutral Rock Hermits (eg 0.25 = 25% chance)\n" +
            "1 - Chance of replacing chaotic Rock Hermits\n" + 
            "2 - Chance of replacing pirate Rock Hermits"
	}
};
this._singleConfig = {
    Name: this.name,
    Alias: "Pirate Coves",
    Display: "Single PC spawning options",
    Alive: "_singleConfig",
    Bool: {
        B0: {Name: "_spawning.single.allowed", Def: true, Desc: "Allow single Pirate Coves"},
        B1: {Name: "_spawning.single.sampleAtDiso", Def: true, Desc: "Ensure PC @ Diso (G1)"},
        Info: "0 - Allows pirate coves to created on their own\n1 - Ensures there's a Pirate Cove at Diso in G1."
    },
    SInt: {
        S0: {Name: "_spawning.single.xRange.max", Def:0.3, Min:0.01, Max: 1, Desc: "X-axis +/- max range for single", Float:true},
        S1: {Name: "_spawning.single.xRange.min", Def:0.0, Min:0.0, Max: 1, Desc: "X-axis +/- min range for single", Float:true},
        S2: {Name: "_spawning.single.yRange.max", Def:0.3, Min:0.01, Max: 1, Desc: "Y-axis +/- max range for single", Float:true},
        S3: {Name: "_spawning.single.yRange.min", Def:0.0, Min:0.0, Max: 1, Desc: "Y-axis +/- min range for single", Float:true},
        S4: {Name: "_spawning.single.zRange.max", Def:0.4, Min:0.1, Max: 0.8, Desc: "Z-axis max range for single", Float:true},
        S5: {Name: "_spawning.single.zRange.min", Def:0.1, Min:0.05, Max: 0.5, Desc: "Z-axis min range for single", Float:true},
        Info: "Range values when spawning single pirate cove.\nX and Y axis values could be + or -. Z axis is only +:\n" + 
            "Calculation is (when +) 'RND * (max - min) + min' or (when -) 'RND * (-max + min) - min'"
    }
};
//-------------------------------------------------------------------------------------------------------------
this.startUp = function () {
    if (missionVariables.pirate_cove_spawning) {
        this._spawning = JSON.parse(missionVariables.pirate_cove_spawning);
    }
    // restore the systems were a pirate cove is missing
    if (missionVariables.pirate_cove_systems) {
        this.pirateCoveSystems = JSON.parse(missionVariables.pirate_cove_systems);
    } else {
        this.pirateCoveSystems = new Array(256);
    }
    this.basicDefenders = Math.round(Math.log(1 + player.score));
};
//-------------------------------------------------------------------------------------------------------------
this.startUpComplete = function() {
	// register our settings, if Lib_Config is present
	if (worldScripts.Lib_Config) {
        worldScripts.Lib_Config._registerSet(this._pcConfig);
        worldScripts.Lib_Config._registerSet(this._singleConfig);
    }
}
//-------------------------------------------------------------------------------------------------------------
this.playerWillSaveGame = function () {
    // encode the systems were a pirate cove is missing
    missionVariables.pirate_cove_systems = JSON.stringify(this.pirateCoveSystems);
    missionVariables.pirate_cove_spawning = JSON.stringify(this._spawning);
}
//-------------------------------------------------------------------------------------------------------------
this.playerEnteredNewGalaxy = function () {
    // reset the systems
    this.pirateCoveSystems = new Array(256);
}
//-------------------------------------------------------------------------------------------------------------
this.systemWillPopulate = function () {
    // Test for [System.countShipsWithRole("pirate-cove") == 0] because the populator might already have added them as rock hermit replacement.
    if (!system.isInterstellarSpace && system.countShipsWithRole("pirate-cove") === 0 && !system.sun.hasGoneNova && this._spawning.single.allowed) {
        this.$addRockHermit();
    }
};
//-------------------------------------------------------------------------------------------------------------
this.$initialiseSystem = function () {
    // initialise
    if (system.countShipsWithPrimaryRole("pirate") > 9) {
        this.pirateCoveSystems[system.ID] = false; // allow stations until killed.
    } else {
        this.pirateCoveSystems[system.ID] = clock.days; // don't allow a station for the next 20 days.
    }
}
//-------------------------------------------------------------------------------------------------------------
this.$addRockHermit = function () {
    var coordinateSystem = (this.$randomZ() < 0.1) ? "psu" : "wpu";
    
    // get the x axis range
    var xRangeMax = this._spawning.single.xRange.max;
    // ensure range will be valid
    if (this._spawning.single.xRange.min > xRangeMax) this._spawning.single.xRange.min = 0;
    var xRangeMin = this._spawning.single.xRange.min;
    
    // get the y-axis range
    var yRangeMax = this._spawning.single.yRange.max;
    // ensure range will be valid
    if (this._spawning.single.yRange.min > yRangeMax) this._spawning.single.yRange.min = 0;
    var yRangeMin = this._spawning.single.yRange.min;
    
    // get the z-axis range
    var zRangeMax = this._spawning.single.zRange.max;
    // ensure range will be valid
    if (this._spawning.single.zRange.min > zRangeMax) this._spawning.single.zRange.min = 0.1;
    var zRangeMin = this._spawning.single.zRange.min;
    
    // 50% chance or either a positive or negative range
    var x = (this.$randomX() > 0.5 ? this.$randomX() * (xRangeMax - xRangeMin) + xRangeMin : this.$randomX() * ((xRangeMax * -1) - (xRangeMin * -1)) - xRangeMin);
    var y = (this.$randomY() > 0.5 ? this.$randomY() * (yRangeMax - yRangeMin) + yRangeMin : this.$randomY() * ((yRangeMax * -1) - (yRangeMin * -1)) - yRangeMin);
    // z range is always positive
    var z = this.$randomZ() * (zRangeMax - zRangeMin) + zRangeMin;
    
    var stnPos = Vector3D(x, y, z).fromCoordinateSystem(coordinateSystem);
    system.setPopulator("piratecove", {
        callback: function(pos) {
            var ws = worldScripts["Pirate_Coves"];
            var isDead = ws.pirateCoveSystems[system.ID];
            if (isDead == undefined || (isDead && (isDead + 20 < clock.days))) {
                ws.$initialiseSystem();
            }
            // make sure diso has a separate pirate cove
            if (galaxyNumber == 0 && system.ID == 147 && ws._spawning.single.sampleAtDiso == true) {
                ws.pirateCoveSystems[system.ID] = false;
            }
            if (!ws.pirateCoveSystems[system.ID]) {
                log("piratecove-populator", "adding pirate cove to system");
                var station = system.addShips("[pirate-cove-single]", 1, pos, 0)[0];
                station.orientation = [1, 0, 0, 0]; // orientate it along the z-axis like oolite hermits.
                var asteroidCount = Math.ceil(3 + ws.$randomZ() * 8);
                system.addShips("asteroid", asteroidCount, pos, 15000);
            }
        },
        location:"COORDINATES",
        coordinates: stnPos,
        deterministic: true 
    });
};
//-------------------------------------------------------------------------------------------------------------
this.$randomZ = function () {
    // return mostly the same value, but change over time.
    var salt = (clock.days & 0xE0) + 15; // change once every 32 days
    return system.scrambledPseudoRandomNumber(salt);
};
//-------------------------------------------------------------------------------------------------------------
this.$randomX = function () {
    var salt = (clock.days & 0xE0) + 20; // change once every 32 days
    return system.scrambledPseudoRandomNumber(salt);
}
//-------------------------------------------------------------------------------------------------------------
this.$randomY = function () {
    var salt = (clock.days & 0xE0) + 25; // change once every 32 days
    return system.scrambledPseudoRandomNumber(salt);
} | 
                
                    | Scripts/pirateCoveMarket.js | "use strict";
this.name = "pirate_cove_market";
this.author = "phkb";
this.copyright = "2023 phkb";
this.license = "CC BY-NC-SA 4.0";
this.$originalDefs = {
	"food": [0, 0, 20, -1, 0, 0, 1, 0, 0],
	"textiles": [0, 0, 20, -1, 0, 0, 3, 0, 0],
	"radioactives": [0, 0, 42, -3, -3, 1, 7, 3, 0],
	"slaves": [0, 0, 40, -5, 0, 0, 15, 0, 0],
	"liquor_wines": [0, 0, 105, -5, 0, 0, 15, 0, 0],
	"luxuries": [0, 0, 236, 8, 0, 0, 3, 0, 0],
	"narcotics": [0, 0, 235, 29, 0, 0, 120, 0, 0],
	"computers": [0, 0, 150, 14, 0, 0, 3, 0, 0],
	"machinery": [0, 0, 120, 6, 0, 0, 7, 0, 0],
	"alloys": [0, 0, 70, 1, 0, 0, 31, 2, 0],
	"firearms": [0, 0, 130, 13, 0, 29, 7, 0, 0],
	"furs": [0, 0, 160, -9, 0, 0, 63, 0, 0],
	"minerals": [0, 0, 16, -1, -1, 85, 3, 3, 0],
	"gold": [0, 0, 73, -1, -1, 5, 7, 3, 1],
	"platinum": [0, 0, 145, -2, -2, 6, 31, 7, 1],
	"gem_stones": [0, 0, 25, -1, -1, 250, 15, 15, 2],
	"alien_items": [0, 0, 140, 1, 0, 0, 3, 0, 0]
};
//-------------------------------------------------------------------------------------------------------------
this.updateLocalCommodityDefinition = function (goodDefinition) {
	var commodity = goodDefinition.key;
	var oldDefs = this.$originalDefs[commodity];
	//old style definition found for the good. calculate it the old way
	if (oldDefs) {
		var market_base_price = oldDefs[2];
		var market_eco_adjust_price = oldDefs[3];
		var market_eco_adjust_quantity = oldDefs[4];
		var market_base_quantity = oldDefs[5];
		var market_mask_price = oldDefs[6];
		var market_mask_quantity = oldDefs[7];
		var market_rnd = Math.floor(Math.random() * 256);
		var economy = system.economy;
		var price = (market_base_price + (market_rnd & market_mask_price) + (economy * market_eco_adjust_price)) & 255;
		price *= 0.4;
		var quantity = (market_base_quantity + (market_rnd & market_mask_quantity) - (economy * market_eco_adjust_quantity)) & 255;
		if (quantity > 127) quantity = 0;
		quantity &= 63;
		goodDefinition.price = price * 10;
		goodDefinition.quantity = quantity;
	}
	//no definition found. nullify the goods.
	else {
		goodDefinition.price = 0;
		goodDefinition.quantity = 0;
	}
	return goodDefinition;
};
 |