Back to Index Page generated: May 8, 2024, 6:16:03 AM

Expansion Space Crowds

Content

Warnings

  1. Unknown key 'upload_date' at https://wiki.alioth.net/img_auth.php/6/6c/Oolite.oxp.astrobe.spacecrowds.oxz!manifest.plist

Manifest

from Expansion Manager's OXP list from Expansion Manifest
Description Adds random encounters in deep space. Based on and inspired from E. Walch's Deep Space Pirates. Adds random encounters in deep space. Based on and inspired from E. Walch's Deep Space Pirates.
Identifier oolite.oxp.astrobe.spacecrowds oolite.oxp.astrobe.spacecrowds
Title Space Crowds Space Crowds
Category Activities Activities
Author Astrobe Astrobe
Version 1.2.0 1.2.0
Tags
Required Oolite Version
Maximum Oolite Version
Required Expansions
Optional Expansions
Conflict Expansions
Information URL http://www.aegidian.org/bb/viewtopic.php?f=4&t=19053 n/a
Download URL https://wiki.alioth.net/img_auth.php/6/6c/Oolite.oxp.astrobe.spacecrowds.oxz http://wiki.alioth.net/img_auth.php/6/6c/Oolite.oxp.astrobe.spacecrowds.oxz
License CC-BY-NC-SA 4.0 CC-BY-NC-SA 4.0
File Size n/a
Upload date 1610873328

Documentation

Also read http://wiki.alioth.net/index.php/Space%20Crowds

Equipment

This expansion declares no equipment. This may be related to warnings.

Ships

Name
DSProck-hermit

Models

This expansion declares no models. This may be related to warnings.

Scripts

Path
Config/script.js
"use strict";
this.name        = "spacecrowds"; 
this.author      = "Astrobe"; 
this.copyright   = "2017 Creative Commons: attribution, non-commercial, sharealike."; 
this.description = "Creates random encounters when the Torus drive has been in use for a long time."; 
this.version     = "1.2.0";
// Configurability contributed by PHKB.
// Additionnal options to preserve derelicts and asteroids contributed by Dybal.

/* How to add your own encounter scenarios:
 * Create a function that spawns all the necessary stuff.
 * This function will be called by Space Crowds (SC):
 * - with one parameter which is around where to spawn the ships (typically you pass it to system.addGroup().
 *   This is a suggested position that is a few scanner ranges ahead of the player. But you can spawn your ships
 *   behind the player if you want. Just make sure the player has good chances to be masslocked as a result.
 *   The masslock doesn't have to be certain, for the player to be able to avoid trouble by careful eyeballing
 *   is considered "fair game" (let other OXPs like Bullet Drive deal with that if that's too easy for some players).
 * - this is bound to SC's script object, so you can use its facilities like $spawnRandomRoles
 * Then, call $pushScenario or $pushRareScenario with your name of the symbol of your function.
 * There are two scenario lists. The former is used 99% of the times, the latter 1% of the times.
 * Among those two lists the probabilities are even.
 * If you really want to give your scenario relatively more weight, just push it multiple times.
 *
 * $spawnRandomRoles(n, role, pos, radius)
 * $spawnRandomRoles is a utility function that let you spawn easily a group of ships in one role.
 * n is the maximum number of ships. The function performs n-1 times a coinflip to determine how many
 * ships to spawn. As a result, we get a bell curve-like distribution centered on n/2, meaning that
 * the function will spawn most often n/2 ships, and more rarely 1 or n. The function will spawn at least
 * one ship.
 * roles is a string indicating the role of the ships ("pirate" or "police" or "trader" etc.)
 * pos is the spawning position; typically you pass the suggested position you've received from SC.
 * radius is the radius of the spawning sphere. The bigger, the more the ships will be spread-out.
 * This parameter is optional and will default to 5Km if not given (scanner range is 25Km).
 *
 * How to test your scenarios
 * The main problem with testing is that scenarios are chosent randomly, so it can take a while
 * until you get your scenario.
 * Use $flushScenarios() to remove the other scenarios and then add your scenario, so your scenario
 * will be the only available one besides the rare scenarios. When you're done testing, remove the
 * the $flushScenarios() line and move your scenario to the $pushRareScenario() if needed.
 * You can use the $report() function to log whatever you need to.
 *
 * Possible errors:
 * Javascript exception "group is null" : role doesn't exist; could be a typo in the name (eg "hunters" instead of "hunter")
 * Javascript exception "commonEvents is undefined": scenario list is empty. Maybe you flushed (for testing purposes)
 * the scenarion list after you added your scenario? Can also be a typo in scenario name.
 */

this.$commonEvents=[];
this.$rareEvents=[];
this.$spawnedShips=[];
this.$chance = 0.02;
this.$rare_chance = 0.01;
this.preserve_derelicts = false;
this.preserve_asteroids = false;

this.libSettings = {Name:this.name, Display:"Config", Alias:"Space Crowds", Alive:"libSettings",
Bool:{
    B0:{Name:"$preserve_derelicts", Def:false, Desc:"Preserve derelicts"},
    B1:{Name:"$preserve_asteroids", Def:false, Desc:"Perserve asteroids"},
    Info:"true:Preserve, false:Remove when out of player's sight"},
SInt:{
	S0:{Name:"$chance", Def:0.02, Min:0.0001, Max:1, Desc:"Chance of encounter", Float:true},
	S1:{Name:"$rare_chance", Def:0.01, Min:0.0001, Max:1, Desc:"Rare chance", Float:true},
	Info:"0 - Chance of having an encounter\n1 - Chance of encounter being a rare one"},
};

// utilities
this.$spawnRandomRoles=function(n, roles, pos, radius)
{
	radius = (typeof radius !== 'undefined') ?  radius : 8E3;
	var random=Math.random;
	var count=1; // at least one
	for(var i=0; i<n-1; i++)
	{
		if(random()<0.5) continue;
		count++;
	}

    var group=system.addGroup(roles, count, pos, radius);
	group.ships.forEach(function(ship) {ship.fuel=random()*7; this.$spawnedShips.push(ship); }, this);
    this.$report("Adding " + count + " " + roles);
	return group;
}

// basic scenarios
this.$small_pirate_pack=function(pos) {this.$spawnRandomRoles(5, "pirate", pos);}
this.$small_hunter_pack=function(pos) {this.$spawnRandomRoles(5, "hunter", pos);}
this.$small_police_patrol=function(pos) {this.$spawnRandomRoles(5, "police", pos);}
this.$small_traders_pack=function(pos) {this.$spawnRandomRoles(5, "trader", pos);}

this.$adaptative=function(pos)
{
	this.$report("Adaptative");
	var s=system.government;
	if(s<=4) this.$spawnRandomRoles(7-s, "pirate", pos);
	else this.$spawnRandomRoles(s, "police", pos);
}

this.$pirates_vs_police=function(pos)
{
	this.$report("Pirates vs Police");
	this.$small_pirate_pack(pos);
	this.$small_police_patrol(pos);
}

this.$pirates_vs_hunters=function(pos)
{
	this.$report("Pirates vs Hunters");
	this.$small_pirate_pack(pos);
	this.$small_hunter_pack(pos);
}

this.$pirates_vs_traders=function(pos)
{
	this.$report("Pirates vs Traders");
	this.$small_pirate_pack(pos);
	this.$small_traders_pack(pos);
}

this.$boulder_field=function(pos)
{
	// The "popping" with asteroids is too obvious, so we use boulders.
	// However, they seem to have a low "visibility range", so typically
	// some of them are almost immediately removed.
	// We should give those boulder some speed so as to deter miner-players
	// from setting a way point here in order to come back later; they won't find
	// anything because those boulders will be removed as soon as they get out
	// of sight.
	this.$report("Boulders");
	var g=this.$spawnRandomRoles(20, "boulder", pos, 2E3);
	g.ships.forEach(function(ship) { ship.temperature=0; }, this);

}

this.$empty=function(pos)
{
	this.$report("Empty");
}

this.$cargo=function(pos)
{
	this.$report("Cargo");
	if(Math.random()<0.5) this.$spawnRandomRoles(1, "cargopod", pos);
}

this.$traders_vs_thargoids=function(pos) // rare
{
	this.$report("Traders vs Thargoids");
	this.$small_traders_pack(pos);
	this.$spawnRandomRoles(5, "thargoid", pos);
}

this.$police_vs_thargoids=function(pos) // rare
{
	this.$report("Police vs Thargoids");
	this.$small_police_patrol(pos);
	this.$spawnRandomRoles(6, "thargoid", pos);
}

this.$thargoid_fleet=function(pos) // rare
{
	// Around 5 Thargoid ships, expect no support.
	this.$report("Tharmageddon!");
	this.$spawnRandomRoles(10, "thargoid", pos);
}
this.$pirateNet=function(pos) // rare
{
	// A large group of pirates widely spread in order to catch lone ships
	this.$report("Pirate net");
	this.$spawnRandomRoles(10, "pirate", pos, 15E3);
}

this.$pushScenario = function (proc)
{
	this.$commonEvents.push(proc);
}

this.$pushRareScenario = function (proc)
{
	this.$rareEvents.push(proc);
}

this.$flushScenarios = function (proc)
{
	this.$commonEvents.length=0;
}

this.$report = function (msg)
{
	log(this.name, msg);
}

this.startUp = function ()
{
	this.dsGroup = new ShipGroup("DeepSpaceShips"); // start with an empty group
	//this.$pushScenario(this.$small_pirate_pack);
	//this.$pushScenario(this.$small_police_patrol);
	this.$pushScenario(this.$small_traders_pack);
	this.$pushScenario(this.$small_hunter_pack);
	this.$pushScenario(this.$empty);
	this.$pushScenario(this.$pirates_vs_police);
	this.$pushScenario(this.$pirates_vs_hunters);
	this.$pushScenario(this.$pirates_vs_traders);
	this.$pushScenario(this.$boulder_field);
	this.$pushScenario(this.$cargo);
	this.$pushScenario(this.$adaptative);
	this.$pushRareScenario(this.$traders_vs_thargoids);
	this.$pushRareScenario(this.$police_vs_thargoids);
	this.$pushRareScenario(this.$thargoid_fleet);
	this.$pushRareScenario(this.$pirateNet);
}

this.startUpComplete = function() {
	if (missionVariables.SpaceCrowds_Chance) this.$chance = parseFloat(missionVariables.SpaceCrowds_Chance);
	if (missionVariables.SpaceCrowds_Rare) this.$rare_chance = parseFloat(missionVariables.SpaceCrowds_Rare);
    if (missionVariables.SpaceCrowds_Preserve_Derelicts && missionVariables.SpaceCrowds_Preserve_Derelicts == 1)
        this.$preserve_derelicts = true;
    else
        this.$preserve_derelicts = false;
    if (missionVariables.SpaceCrowds_Preserve_Asteroids && missionVariables.SpaceCrowds_Preserve_Asteroids == 1)
        this.$preserve_asteroids = true;
    else
        this.$preserve_asteroids = false;

	// register our settings, if Lib_Config is present
	if (worldScripts.Lib_Config) worldScripts.Lib_Config._registerSet(this.libSettings);
}

this.playerWillSaveGame = function() {
	missionVariables.SpaceCrowds_Chance = this.$chance;
	missionVariables.SpaceCrowds_Rare = this.$rare_chance;
    if (this.$preserve_derelicts) 
        missionVariables.SpaceCrowds_Preserve_Derelicts = 1;
    else
        missionVariables.SpaceCrowds_Preserve_Derelicts = 0;
    if (this.$preserve_asteroids) 
        missionVariables.SpaceCrowds_Preserve_Asteroids = 1;
    else
        missionVariables.SpaceCrowds_Preserve_Asteroids = 0;
        
}

this.shipLaunchedFromStation = function ()
{
    if (this.checkTimer)
        this.checkTimer.start()
    else
        this.checkTimer = new Timer(this, this.$check, 5, 1000/(player.ship.maxSpeed*3)); // about every 1.3 second for Adder (maxSpeed=240).
}

this.$check = function ()
{
	if(player.ship.torusEngaged
			&& Math.random()>(1 - this.$chance)
			&& !system.isInterstellarSpace) 
	{
		this.$report("Chance!");
		this.$createEncounter();
	}
	else
	{
		this.$removeFarShips();
	}
}

this.$createEncounter = function ()
{
	var ourShip=player.ship;
	if(system.countShipsWithRole("station", ourShip, 240E3) > 0)
	{
		this.$report("Station nearby");
		return;
	}

	var pos = ourShip.position.add(ourShip.heading.multiply(48E3)).add(Vector3D.random(15E3));

	if(Math.random()<this.$rare_chance)
	{
		var n=Math.floor(Math.random()*this.$rareEvents.length);
		this.$rareEvents[n].call(this, pos);
	}
	else
	{
		var n=Math.floor(Math.random()*this.$commonEvents.length);
		this.$commonEvents[n].call(this, pos);
	}
}

this.$removeFarShips=function()
{
	var spawnedShips=this.$spawnedShips;
	var count=0;
	var e;
	for(var i=0; i<spawnedShips.length; i++)
	{
		// ship might actually be long dead, but Oolite seems to handle that case well.
		try
		{
			if(!spawnedShips[i].position.distanceTo(player.ship.position)>100E3)
			{
				if(spawnedShips[i].isShip && 
						!(this.preserve_derelicts && spawnedShips[i].isDerelict) &&
						!(this.preserve_asteroids && spawnedShips[i].isBoulder) )
				{
					spawnedShips[i].remove();
					spawnedShips[i]=null; // for cleanup
					count++;
				}
			}
		}
		catch(e)
		{
			spawnedShips[i]=null;
		}
	}
	//cleanup
	if(count)
	{
		this.$spawnedShips=spawnedShips.filter(function(e) { return e!=null; });
		this.$report("Removed "+count+" ships");
	}
}