Start system populator framework.
Adds buoys, nothing else
This commit is contained in:
parent
701a750822
commit
68cbeed17b
@ -283,6 +283,7 @@ OOLITE_SCRIPTING_FILES = \
|
||||
OOJSPlanet.m \
|
||||
OOJSPlayer.m \
|
||||
OOJSPlayerShip.m \
|
||||
OOJSPopulatorDefinition.m \
|
||||
OOJSQuaternion.m \
|
||||
OOJSScript.m \
|
||||
OOJSShip.m \
|
||||
|
@ -460,6 +460,7 @@
|
||||
universe.findSystems.badDistance = $error;
|
||||
|
||||
universe.populate = no; // “Populating a system with…” message when generating a star system
|
||||
universe.populate.error = yes;
|
||||
universe.populate.witchspace = inherit;
|
||||
universe.setup.badStation = $scriptError; // Message generated if the main station turns out not to be a station (for instance, this could happen if a non-station ship had the role coriolis).
|
||||
universe.maxEntitiesDump = no; // Dumps all entities when universe is full (Can be quite verbose)
|
||||
|
@ -1,11 +1,18 @@
|
||||
(
|
||||
/* General */
|
||||
"oolite-populator.js",
|
||||
|
||||
/* Interfaces */
|
||||
"oolite-contracts-cargo.js",
|
||||
"oolite-contracts-helpers.js",
|
||||
"oolite-contracts-parcels.js",
|
||||
"oolite-contracts-passengers.js",
|
||||
|
||||
/* Missions */
|
||||
"oolite-constrictor-hunt-mission.js",
|
||||
"oolite-cloaking-device-mission.js",
|
||||
"oolite-nova-mission.js",
|
||||
"oolite-thargoid-plans-mission.js",
|
||||
"oolite-trumbles-mission.js",
|
||||
"oolite-contracts-cargo.js",
|
||||
"oolite-contracts-helpers.js",
|
||||
"oolite-contracts-parcels.js",
|
||||
"oolite-contracts-passengers.js"
|
||||
"oolite-trumbles-mission.js"
|
||||
|
||||
)
|
||||
|
93
Resources/Scripts/oolite-populator.js
Normal file
93
Resources/Scripts/oolite-populator.js
Normal file
@ -0,0 +1,93 @@
|
||||
/*
|
||||
|
||||
oolite-populator.js
|
||||
|
||||
Built-in system populator settings
|
||||
|
||||
|
||||
Oolite
|
||||
Copyright © 2004-2013 Giles C Williams and contributors
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/*jslint white: true, undef: true, eqeqeq: true, bitwise: true, regexp: true, newcap: true, immed: true */
|
||||
/*global missionVariables, player*/
|
||||
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
this.name = "oolite-populator";
|
||||
this.author = "cim";
|
||||
this.copyright = "© 2008-2013 the Oolite team.";
|
||||
this.version = "1.79";
|
||||
|
||||
/* TO-DO:
|
||||
* Buoys need to be given spin (0.15 pitch, 0.1 roll)
|
||||
|
||||
*/
|
||||
this.systemWillPopulate = function() {
|
||||
log(this.name,"System populator");
|
||||
|
||||
/* Priority range 0-100 used by Oolite default populator */
|
||||
|
||||
/* Add navigation buoys */
|
||||
// for the compass to work properly, the buoys need to be added first,
|
||||
// in this order.
|
||||
system.setPopulator("oolite-nav-buoy",
|
||||
{
|
||||
priority: 1,
|
||||
location: "COORDINATES",
|
||||
coordinates: system.mainStation.position.add(system.mainStation.vectorForward.multiply(10E3)),
|
||||
callback: function(pos) {
|
||||
var nb = system.addShips("buoy",1,pos,0)[0];
|
||||
nb.scanClass = "CLASS_BUOY";
|
||||
},
|
||||
deterministic: true
|
||||
});
|
||||
|
||||
system.setPopulator("oolite-witch-buoy",
|
||||
{
|
||||
priority: 2,
|
||||
location: "COORDINATES",
|
||||
coordinates: [0,0,0],
|
||||
callback: function(pos) {
|
||||
var wb = system.addShips("buoy-witchpoint",1,pos,0)[0];
|
||||
wb.scanClass = "CLASS_BUOY";
|
||||
},
|
||||
deterministic: true
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
this.interstellarSpaceWillPopulate = function() {
|
||||
log(this.name,"Interstellar populator");
|
||||
system.setPopulator("oolite-interstellar-thargoids",
|
||||
{
|
||||
priority: 10,
|
||||
location: "WITCHPOINT",
|
||||
groupCount: 2+Math.floor(Math.random()*4),
|
||||
callback: function(pos) {
|
||||
system.addShips("thargoid",1,pos,0);
|
||||
}
|
||||
});
|
||||
}
|
@ -69,6 +69,8 @@ OOINLINE Vector2D MakeVector2D(OOScalar vx, OOScalar vy) INLINE_CONST_FUNC;
|
||||
Vector OORandomUnitVector(void);
|
||||
Vector OOVectorRandomSpatial(OOScalar maxLength); // Random vector uniformly distributed in radius-maxLength sphere. (Longer vectors are more common.)
|
||||
Vector OOVectorRandomRadial(OOScalar maxLength); // Random vector with uniform distribution of direction and radius in radius-maxLength sphere. (Causes clustering at centre.)
|
||||
Vector OORandomPositionInCylinder(Vector centre1, OOScalar exclusion1, Vector centre2, OOScalar exclusion2, OOScalar radius);
|
||||
Vector OORandomPositionInShell(Vector centre, OOScalar inner, OOScalar outer);
|
||||
#endif
|
||||
|
||||
/* Multiply vector by scalar (in place) */
|
||||
|
@ -104,4 +104,29 @@ Vector OORandomPositionInBoundingBox(BoundingBox bb)
|
||||
result.z = bb.min.z + randf() * (bb.max.z - bb.min.z);
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector OORandomPositionInCylinder(Vector centre1, OOScalar exclusion1, Vector centre2, OOScalar exclusion2, OOScalar radius)
|
||||
{
|
||||
OOScalar exc12 = exclusion1*exclusion1;
|
||||
OOScalar exc22 = exclusion2*exclusion2;
|
||||
Vector result;
|
||||
do
|
||||
{
|
||||
result = vector_add(OOVectorInterpolate(centre1,centre2,randf()),OOVectorRandomSpatial(radius));
|
||||
}
|
||||
while(distance2(result,centre1)<exc12 || distance2(result,centre2)<exc22);
|
||||
return result;
|
||||
}
|
||||
|
||||
Vector OORandomPositionInShell(Vector centre, OOScalar inner, OOScalar outer)
|
||||
{
|
||||
Vector result;
|
||||
OOScalar inner2 = inner*inner;
|
||||
do
|
||||
{
|
||||
result = vector_add(centre,OOVectorRandomSpatial(outer));
|
||||
} while(distance2(result,centre)<inner2);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
46
src/Core/Scripting/OOJSPopulatorDefinition.h
Normal file
46
src/Core/Scripting/OOJSPopulatorDefinition.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
|
||||
OOJSPopulatorDefinition.h
|
||||
|
||||
|
||||
Oolite
|
||||
Copyright (C) 2004-2013 Giles C Williams and contributors
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOJSScript.h"
|
||||
#include <jsapi.h>
|
||||
#import "OOVector.h"
|
||||
|
||||
@interface OOJSPopulatorDefinition: OOWeakRefObject
|
||||
{
|
||||
@private
|
||||
jsval _callback;
|
||||
JSObject *_callbackThis;
|
||||
OOJSScript *_owningScript;
|
||||
}
|
||||
|
||||
- (jsval)callback;
|
||||
- (void)setCallback:(jsval)callback;
|
||||
- (JSObject *)callbackThis;
|
||||
- (void)setCallbackThis:(JSObject *)callbackthis;
|
||||
|
||||
- (void)runCallback:(Vector)location;
|
||||
|
||||
@end
|
||||
|
128
src/Core/Scripting/OOJSPopulatorDefinition.m
Normal file
128
src/Core/Scripting/OOJSPopulatorDefinition.m
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
|
||||
OOJSPopulatorDefinition.m
|
||||
|
||||
|
||||
Oolite
|
||||
Copyright (C) 2004-2013 Giles C Williams and contributors
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
MA 02110-1301, USA.
|
||||
|
||||
*/
|
||||
|
||||
#import "OOJSPopulatorDefinition.h"
|
||||
#import "OOJavaScriptEngine.h"
|
||||
#import "OOVector.h"
|
||||
#import "OOJSVector.h"
|
||||
|
||||
@implementation OOJSPopulatorDefinition
|
||||
|
||||
- (id) init {
|
||||
_callback = JSVAL_VOID;
|
||||
_callbackThis = NULL;
|
||||
|
||||
_owningScript = [[OOJSScript currentlyRunningScript] weakRetain];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(deleteJSPointers)
|
||||
name:kOOJavaScriptEngineWillResetNotification
|
||||
object:[OOJavaScriptEngine sharedEngine]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) deleteJSPointers
|
||||
{
|
||||
|
||||
JSContext *context = OOJSAcquireContext();
|
||||
_callback = JSVAL_VOID;
|
||||
_callbackThis = NULL;
|
||||
JS_RemoveValueRoot(context, &_callback);
|
||||
JS_RemoveObjectRoot(context, &_callbackThis);
|
||||
|
||||
OOJSRelinquishContext(context);
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self
|
||||
name:kOOJavaScriptEngineWillResetNotification
|
||||
object:[OOJavaScriptEngine sharedEngine]];
|
||||
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[_owningScript release];
|
||||
|
||||
[self deleteJSPointers];
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (jsval)callback
|
||||
{
|
||||
return _callback;
|
||||
}
|
||||
|
||||
|
||||
- (void)setCallback:(jsval)callback
|
||||
{
|
||||
JSContext *context = OOJSAcquireContext();
|
||||
JS_RemoveValueRoot(context, &_callback);
|
||||
_callback = callback;
|
||||
OOJSAddGCValueRoot(context, &_callback, "OOJSPopulatorDefinition callback function");
|
||||
OOJSRelinquishContext(context);
|
||||
}
|
||||
|
||||
|
||||
- (JSObject *)callbackThis
|
||||
{
|
||||
return _callbackThis;
|
||||
}
|
||||
|
||||
|
||||
- (void)setCallbackThis:(JSObject *)callbackThis
|
||||
{
|
||||
JSContext *context = OOJSAcquireContext();
|
||||
JS_RemoveObjectRoot(context, &_callbackThis);
|
||||
_callbackThis = callbackThis;
|
||||
OOJSAddGCObjectRoot(context, &_callbackThis, "OOJSPopulatorDefinition callback this");
|
||||
OOJSRelinquishContext(context);
|
||||
}
|
||||
|
||||
|
||||
- (void)runCallback:(Vector)location
|
||||
{
|
||||
OOJavaScriptEngine *engine = [OOJavaScriptEngine sharedEngine];
|
||||
JSContext *context = OOJSAcquireContext();
|
||||
jsval loc, rval = JSVAL_VOID;
|
||||
|
||||
VectorToJSValue(context, location, &loc);
|
||||
|
||||
OOJSScript *owner = [_owningScript retain]; // local copy needed
|
||||
[OOJSScript pushScript:owner];
|
||||
|
||||
[engine callJSFunction:_callback
|
||||
forObject:_callbackThis
|
||||
argc:1
|
||||
argv:&loc
|
||||
result:&rval];
|
||||
|
||||
[OOJSScript popScript:owner];
|
||||
[owner release];
|
||||
|
||||
OOJSRelinquishContext(context);
|
||||
}
|
||||
|
||||
@end
|
@ -38,3 +38,4 @@ MA 02110-1301, USA.
|
||||
#define OOJSID(str) ({ static jsid idCache = JSID_VOID; if (EXPECT_NOT(idCache == JSID_VOID)) OOJSInitJSIDCachePRIVATE(""str, &idCache); idCache; })
|
||||
#endif
|
||||
void OOJSInitJSIDCachePRIVATE(const char *name, jsid *idCache);
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#import "OOConstToJSString.h"
|
||||
#import "OOEntityFilterPredicate.h"
|
||||
#import "OOFilteringEnumerator.h"
|
||||
|
||||
#import "OOJSPopulatorDefinition.h"
|
||||
|
||||
static JSObject *sSystemPrototype;
|
||||
|
||||
@ -74,6 +74,7 @@ static JSBool SystemAddGroup(JSContext *context, uintN argc, jsval *vp);
|
||||
static JSBool SystemAddShipsToRoute(JSContext *context, uintN argc, jsval *vp);
|
||||
static JSBool SystemAddGroupToRoute(JSContext *context, uintN argc, jsval *vp);
|
||||
static JSBool SystemAddVisualEffect(JSContext *context, uintN argc, jsval *vp);
|
||||
static JSBool SystemSetPopulator(JSContext *context, uintN argc, jsval *vp);
|
||||
|
||||
static JSBool SystemLegacyAddShips(JSContext *context, uintN argc, jsval *vp);
|
||||
static JSBool SystemLegacyAddSystemShips(JSContext *context, uintN argc, jsval *vp);
|
||||
@ -123,6 +124,7 @@ enum
|
||||
kSystem_name, // name, string, read/write
|
||||
kSystem_planets, // planets in system, array of Planet, read-only
|
||||
kSystem_population, // population, integer, read/write
|
||||
kSystem_populatorSettings, // populator settings, dictionary, read-only
|
||||
kSystem_productivity, // productivity, integer, read/write
|
||||
kSystem_pseudoRandom100, // constant-per-system pseudorandom number in [0..100), integer, read-only
|
||||
kSystem_pseudoRandom256, // constant-per-system pseudorandom number in [0..256), integer, read-only
|
||||
@ -180,6 +182,7 @@ static JSFunctionSpec sSystemMethods[] =
|
||||
{ "filteredEntities", SystemFilteredEntities, 2 },
|
||||
// scrambledPseudoRandomNumber is implemented in oolite-global-prefix.js
|
||||
{ "sendAllShipsAway", SystemSendAllShipsAway, 1 },
|
||||
{ "setPopulator", SystemSetPopulator, 2 },
|
||||
{ "shipsWithPrimaryRole", SystemShipsWithPrimaryRole, 1 },
|
||||
{ "shipsWithRole", SystemShipsWithRole, 1 },
|
||||
|
||||
@ -287,6 +290,10 @@ static JSBool SystemGetProperty(JSContext *context, JSObject *this, jsid propID,
|
||||
case kSystem_breakPattern:
|
||||
*value = OOJSValueFromBOOL([UNIVERSE witchspaceBreakPattern]);
|
||||
return YES;
|
||||
|
||||
case kSystem_populatorSettings:
|
||||
*value = OOJSValueFromNativeObject(context, [UNIVERSE populatorSettings]);
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
@ -1182,6 +1189,64 @@ static JSBool SystemAddVisualEffect(JSContext *context, uintN argc, jsval *vp)
|
||||
OOJS_NATIVE_EXIT
|
||||
}
|
||||
|
||||
static JSBool SystemSetPopulator(JSContext *context, uintN argc, jsval *vp)
|
||||
{
|
||||
OOJS_NATIVE_ENTER(context)
|
||||
|
||||
NSString *key;
|
||||
NSMutableDictionary *settings;
|
||||
JSObject *params = NULL;
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 0U), &OOJS_ARGV[0], nil, @"string (key), object (settings)");
|
||||
return NO;
|
||||
}
|
||||
key = OOStringFromJSValue(context, OOJS_ARGV[0]);
|
||||
if (key == nil)
|
||||
{
|
||||
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 0U), &OOJS_ARGV[0], nil, @"key, settings");
|
||||
return NO;
|
||||
}
|
||||
if (!JS_ValueToObject(context, OOJS_ARGV[1], ¶ms))
|
||||
{
|
||||
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 1U), OOJS_ARGV, NULL, @"key, settings");
|
||||
return NO;
|
||||
}
|
||||
jsval callback = JSVAL_NULL;
|
||||
if (JS_GetProperty(context, params, "callback", &callback) == JS_FALSE || JSVAL_IS_VOID(callback))
|
||||
{
|
||||
OOJSReportBadArguments(context, @"System", @"setPopulator", MIN(argc, 1U), OOJS_ARGV, NULL, @"settings must have a 'callback' property.");
|
||||
return NO;
|
||||
}
|
||||
|
||||
OOJSPopulatorDefinition *populator = [[OOJSPopulatorDefinition alloc] init];
|
||||
[populator setCallback:callback];
|
||||
|
||||
settings = OOJSNativeObjectFromJSObject(context, JSVAL_TO_OBJECT(OOJS_ARGV[1]));
|
||||
[settings setObject:populator forKey:@"callbackObj"];
|
||||
|
||||
jsval coords = JSVAL_NULL;
|
||||
if (JS_GetProperty(context, params, "coordinates", &coords) != JS_FALSE && !JSVAL_IS_VOID(coords))
|
||||
{
|
||||
Vector coordinates = kZeroVector;
|
||||
if (JSValueToVector(context, coords, &coordinates))
|
||||
{
|
||||
// convert vector in NS-storable form
|
||||
[settings setObject:[NSArray arrayWithObjects:[NSNumber numberWithFloat:coordinates.x],[NSNumber numberWithFloat:coordinates.y],[NSNumber numberWithFloat:coordinates.z],nil] forKey:@"coordinates"];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[populator release];
|
||||
|
||||
[UNIVERSE setPopulatorSetting:key to:settings];
|
||||
|
||||
OOJS_RETURN_VOID;
|
||||
|
||||
OOJS_NATIVE_EXIT
|
||||
}
|
||||
|
||||
// *** Helper functions ***
|
||||
|
||||
// Shared implementation of addShips() and addGroup().
|
||||
|
@ -257,6 +257,8 @@ enum
|
||||
OOSunEntity *cachedSun;
|
||||
NSMutableArray *allPlanets;
|
||||
|
||||
NSMutableDictionary *populatorSettings;
|
||||
|
||||
NSArray *closeSystems;
|
||||
|
||||
BOOL strict;
|
||||
@ -339,6 +341,11 @@ enum
|
||||
- (void) setUpWitchspace;
|
||||
- (void) setUpWitchspaceBetweenSystem:(Random_Seed)s1 andSystem:(Random_Seed)s2;
|
||||
- (void) setUpSpace;
|
||||
- (void) populateNormalSpace;
|
||||
- (void) clearSystemPopulator;
|
||||
- (void) populateSystemFromDictionariesWithSun:(OOSunEntity *)sun andPlanet:(OOPlanetEntity *)planet;
|
||||
- (NSDictionary *) populatorSettings;
|
||||
- (void) setPopulatorSetting:(NSString *)key to:(NSDictionary *)setting;
|
||||
- (void) setLighting;
|
||||
- (void) forceLightSwitch;
|
||||
- (void) setMainLightPosition: (Vector) sunPos;
|
||||
@ -742,6 +749,7 @@ OOINLINE Universe *OOGetUniverse(void)
|
||||
#define DESC_PLURAL(key,count) (OOLookUpPluralDescriptionPRIV(key "", count))
|
||||
|
||||
// Not for direct use.
|
||||
NSComparisonResult populatorPrioritySort(id a, id b, void *context);
|
||||
NSString *OOLookUpDescriptionPRIV(NSString *key);
|
||||
NSString *OOLookUpPluralDescriptionPRIV(NSString *key, NSInteger count);
|
||||
|
||||
|
@ -83,6 +83,7 @@ MA 02110-1301, USA.
|
||||
#import "OOScriptTimer.h"
|
||||
#import "OOJSScript.h"
|
||||
#import "OOJSFrameCallbacks.h"
|
||||
#import "OOJSPopulatorDefinition.h"
|
||||
|
||||
#if OO_LOCALIZATION_TOOLS
|
||||
#import "OOConvertSystemDescriptions.h"
|
||||
@ -106,9 +107,11 @@ enum
|
||||
#define STANDARD_STATION_ROLL 0.4
|
||||
#define WOLFPACK_SHIPS_DISTANCE 0.1
|
||||
#define FIXED_ASTEROID_FIELDS 0
|
||||
|
||||
// currently twice scanner radius
|
||||
#define LANE_WIDTH 51200.0
|
||||
|
||||
static NSString * const kOOLogUniversePopulate = @"universe.populate";
|
||||
static NSString * const kOOLogUniversePopulateError = @"universe.populate.error";
|
||||
static NSString * const kOOLogUniversePopulateWitchspace = @"universe.populate.witchspace";
|
||||
extern NSString * const kOOLogEntityVerificationError;
|
||||
static NSString * const kOOLogEntityVerificationRebuild = @"entity.linkedList.verify.rebuild";
|
||||
@ -179,6 +182,7 @@ static OOComparisonResult comparePrice(id dict1, id dict2, void * context);
|
||||
- (void) resetSystemDataCache;
|
||||
|
||||
- (void) populateSpaceFromActiveWormholes;
|
||||
- (Vector) locationByCode:(NSString *)code withSun:(OOSunEntity *)sun andPlanet:(OOPlanetEntity *)planet;
|
||||
- (void) populateSpaceFromHyperPoint:(Vector)h1_pos toPlanetPosition:(Vector)p1_pos andSunPosition:(Vector)s1_pos;
|
||||
- (NSUInteger) scatterAsteroidsAt:(Vector)spawnPos withVelocity:(Vector)spawnVel includingRockHermit:(BOOL)spawnHermit asCinders:(BOOL)asCinders;
|
||||
- (NSUInteger) scatterAsteroidsAt:(Vector)spawnPos withVelocity:(Vector)spawnVel includingRockHermit:(BOOL)spawnHermit asCinders:(BOOL)asCinders clusterSize:(NSUInteger)clusterSize;
|
||||
@ -370,6 +374,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
|
||||
[[GameController sharedController] logProgress:DESC(@"running-scripts")];
|
||||
[player completeSetUp];
|
||||
[self populateNormalSpace];
|
||||
|
||||
#if OO_LOCALIZATION_TOOLS
|
||||
[self runLocalizationTools];
|
||||
@ -410,6 +415,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
[autoAIMap release];
|
||||
[screenBackgrounds release];
|
||||
[gameView release];
|
||||
[populatorSettings release];
|
||||
|
||||
[localPlanetInfoOverrides release];
|
||||
[activeWormholes release];
|
||||
@ -597,6 +603,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
[self setSystemTo: dest];
|
||||
|
||||
[self setUpSpace];
|
||||
[self populateNormalSpace];
|
||||
[player setBounty:([player legalStatus]/2) withReason:kOOLegalStatusReasonNewSystem];
|
||||
if ([player random_factor] < 8) [player erodeReputation]; // every 32 systems or so, dro
|
||||
}
|
||||
@ -669,6 +676,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
if (!dockedStation || !interstel)
|
||||
{
|
||||
[self setUpSpace]; // launching from station that jumped from interstellar space to normal space.
|
||||
[self populateNormalSpace];
|
||||
if (dockedStation)
|
||||
{
|
||||
if ([dockedStation maxFlightSpeed] > 0) // we are a carrier: exit near the WitchspaceExitPosition
|
||||
@ -729,6 +737,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
}
|
||||
|
||||
[self setUpSpace];
|
||||
[self populateNormalSpace];
|
||||
|
||||
[player leaveWitchspace];
|
||||
[player release]; // released here
|
||||
@ -825,6 +834,14 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
OOLog(kOOLogUniversePopulateWitchspace, @"Populating witchspace ...");
|
||||
OOLogIndentIf(kOOLogUniversePopulateWitchspace);
|
||||
|
||||
[self clearSystemPopulator];
|
||||
NSString *populator = [systeminfo oo_stringForKey:@"populator" defaultValue:@"interstellarSpaceWillPopulate"];
|
||||
JSContext *context = OOJSAcquireContext();
|
||||
[PLAYER doWorldScriptEvent:OOJSIDFromString(populator) inContext:context withArguments:NULL count:0 timeLimit:kOOJSLongTimeLimit];
|
||||
OOJSRelinquishContext(context);
|
||||
[self populateSystemFromDictionariesWithSun:nil andPlanet:nil];
|
||||
|
||||
/*
|
||||
// actual thargoids and tharglets next...
|
||||
int n_thargs = 2 + (Ranrot() & 3);
|
||||
if (n_thargs < 1)
|
||||
@ -866,7 +883,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
[thargoid release];
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
// systeminfo might have a 'script_actions' resource we want to activate now...
|
||||
NSArray *script_actions = [systeminfo oo_arrayForKey:@"script_actions"];
|
||||
if (script_actions != nil)
|
||||
@ -913,11 +930,13 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
return [a_planet autorelease];
|
||||
}
|
||||
|
||||
|
||||
/* At any time other than game start, any call to this must be followed
|
||||
* by [self populateNormalSpace]. However, at game start, they need to be
|
||||
* separated to allow Javascript startUp routines to be run in-between */
|
||||
- (void) setUpSpace
|
||||
{
|
||||
Entity *thing;
|
||||
ShipEntity *nav_buoy;
|
||||
// ShipEntity *nav_buoy;
|
||||
StationEntity *a_station;
|
||||
OOSunEntity *a_sun;
|
||||
OOPlanetEntity *a_planet;
|
||||
@ -994,7 +1013,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
int posIterator=0;
|
||||
id dict_object;
|
||||
Quaternion q_sun;
|
||||
Vector sunPos,witchPos;
|
||||
Vector sunPos;
|
||||
|
||||
sunDistanceModifier = [systeminfo oo_nonNegativeDoubleForKey:@"sun_distance_modifier" defaultValue:20.0];
|
||||
// Any smaller than 6, the main planet can end up inside the sun
|
||||
@ -1169,79 +1188,92 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
OO_DEBUG_PUSH_PROGRESS(@"setUpSpace - populate from wormholes");
|
||||
[self populateSpaceFromActiveWormholes];
|
||||
OO_DEBUG_POP_PROGRESS();
|
||||
|
||||
witchPos = [self randomizeFromSeedAndGetWitchspaceExitPosition]; //we need to use this value a few times, without resetting PRNG
|
||||
|
||||
OO_DEBUG_PUSH_PROGRESS(@"setUpSpace - populate from hyperpoint");
|
||||
[self populateSpaceFromHyperPoint:witchPos toPlanetPosition: a_planet->position andSunPosition: a_sun->position];
|
||||
OO_DEBUG_POP_PROGRESS();
|
||||
|
||||
OO_DEBUG_PUSH_PROGRESS(@"setUpSpace - nav beacons");
|
||||
if (a_station != nil)
|
||||
{
|
||||
/*- nav beacon -*/
|
||||
nav_buoy = [self newShipWithRole:@"buoy"]; // retain count = 1
|
||||
if (nav_buoy)
|
||||
{
|
||||
[nav_buoy setRoll: 0.10];
|
||||
[nav_buoy setPitch: 0.15];
|
||||
[nav_buoy setPosition:[a_station beaconPosition]];
|
||||
[nav_buoy setScanClass: CLASS_BUOY];
|
||||
[self addEntity:nav_buoy]; // STATUS_IN_FLIGHT, AI state GLOBAL
|
||||
[nav_buoy release];
|
||||
}
|
||||
}
|
||||
/*--*/
|
||||
|
||||
/*- nav beacon witchpoint -*/
|
||||
nav_buoy = [self newShipWithRole:@"buoy-witchpoint"]; // retain count = 1
|
||||
if (nav_buoy)
|
||||
{
|
||||
[nav_buoy setRoll: 0.10];
|
||||
[nav_buoy setPitch: 0.15];
|
||||
[nav_buoy setPosition:witchPos]; // There should be no need to reset PRNG now.
|
||||
[nav_buoy setScanClass: CLASS_BUOY];
|
||||
[self addEntity:nav_buoy]; // STATUS_IN_FLIGHT, AI state GLOBAL
|
||||
[nav_buoy release];
|
||||
}
|
||||
/*--*/
|
||||
OO_DEBUG_POP_PROGRESS();
|
||||
|
||||
if (sunGoneNova)
|
||||
{
|
||||
OO_DEBUG_PUSH_PROGRESS(@"setUpSpace - post-nova");
|
||||
|
||||
Vector v0 = make_vector(0,0,34567.89);
|
||||
Vector planetPos = a_planet->position;
|
||||
double min_safe_dist2 = 5000000.0 * 5000000.0;
|
||||
while (magnitude2(a_sun->position) < min_safe_dist2) // back off the planetary bodies
|
||||
{
|
||||
v0.z *= 2.0;
|
||||
planetPos = vector_add([a_planet position], v0);
|
||||
[a_planet setPosition:planetPos];
|
||||
|
||||
sunPos = vector_add(sunPos, v0);
|
||||
[a_sun setPosition:sunPos]; // also sets light origin
|
||||
|
||||
stationPos = vector_add(stationPos, v0);
|
||||
[a_station setPosition:stationPos];
|
||||
}
|
||||
|
||||
[self removeEntity:a_planet]; // and Poof! it's gone
|
||||
cachedPlanet = nil;
|
||||
int i;
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
[self scatterAsteroidsAt:planetPos withVelocity:kZeroVector includingRockHermit:NO asCinders:YES];
|
||||
[self scatterAsteroidsAt:witchPos withVelocity:kZeroVector includingRockHermit:NO asCinders:YES];
|
||||
}
|
||||
|
||||
OO_DEBUG_POP_PROGRESS();
|
||||
}
|
||||
|
||||
|
||||
[a_sun release];
|
||||
[a_station release];
|
||||
}
|
||||
|
||||
- (void) populateNormalSpace
|
||||
{
|
||||
NSDictionary *systeminfo = [self generateSystemData:system_seed useCache:NO];
|
||||
|
||||
// Vector witchPos = [self randomizeFromSeedAndGetWitchspaceExitPosition]; //we need to use this value a few times, without resetting PRNG
|
||||
|
||||
OO_DEBUG_PUSH_PROGRESS(@"setUpSpace - populate from hyperpoint");
|
||||
// [self populateSpaceFromHyperPoint:witchPos toPlanetPosition: a_planet->position andSunPosition: a_sun->position];
|
||||
[self clearSystemPopulator];
|
||||
NSString *populator = [systeminfo oo_stringForKey:@"populator" defaultValue:@"systemWillPopulate"];
|
||||
JSContext *context = OOJSAcquireContext();
|
||||
[PLAYER doWorldScriptEvent:OOJSIDFromString(populator) inContext:context withArguments:NULL count:0 timeLimit:kOOJSLongTimeLimit];
|
||||
OOJSRelinquishContext(context);
|
||||
[self populateSystemFromDictionariesWithSun:cachedSun andPlanet:cachedPlanet];
|
||||
|
||||
OO_DEBUG_POP_PROGRESS();
|
||||
|
||||
// OO_DEBUG_PUSH_PROGRESS(@"setUpSpace - nav beacons");
|
||||
// if (a_station != nil)
|
||||
// {
|
||||
// /*- nav beacon -*/
|
||||
// nav_buoy = [self newShipWithRole:@"buoy"]; // retain count = 1
|
||||
// if (nav_buoy)
|
||||
// {
|
||||
// [nav_buoy setRoll: 0.10];
|
||||
// [nav_buoy setPitch: 0.15];
|
||||
// [nav_buoy setPosition:[a_station beaconPosition]];
|
||||
// [nav_buoy setScanClass: CLASS_BUOY];
|
||||
// [self addEntity:nav_buoy]; // STATUS_IN_FLIGHT, AI state GLOBAL
|
||||
// [nav_buoy release];
|
||||
// }
|
||||
// }
|
||||
// /*--*/
|
||||
|
||||
// /*- nav beacon witchpoint -*/
|
||||
// nav_buoy = [self newShipWithRole:@"buoy-witchpoint"]; // retain count = 1
|
||||
// if (nav_buoy)
|
||||
// {
|
||||
// [nav_buoy setRoll: 0.10];
|
||||
// [nav_buoy setPitch: 0.15];
|
||||
// [nav_buoy setPosition:witchPos]; // There should be no need to reset PRNG now.
|
||||
// [nav_buoy setScanClass: CLASS_BUOY];
|
||||
// [self addEntity:nav_buoy]; // STATUS_IN_FLIGHT, AI state GLOBAL
|
||||
// [nav_buoy release];
|
||||
// }
|
||||
// /*--*/
|
||||
// OO_DEBUG_POP_PROGRESS();
|
||||
|
||||
// if (sunGoneNova)
|
||||
// {
|
||||
// OO_DEBUG_PUSH_PROGRESS(@"setUpSpace - post-nova");
|
||||
|
||||
// Vector v0 = make_vector(0,0,34567.89);
|
||||
// Vector planetPos = a_planet->position;
|
||||
// double min_safe_dist2 = 5000000.0 * 5000000.0;
|
||||
// while (magnitude2(a_sun->position) < min_safe_dist2) // back off the planetary bodies
|
||||
// {
|
||||
// v0.z *= 2.0;
|
||||
// planetPos = vector_add([a_planet position], v0);
|
||||
// [a_planet setPosition:planetPos];
|
||||
|
||||
// sunPos = vector_add(sunPos, v0);
|
||||
// [a_sun setPosition:sunPos]; // also sets light origin
|
||||
|
||||
// stationPos = vector_add(stationPos, v0);
|
||||
// [a_station setPosition:stationPos];
|
||||
// }
|
||||
|
||||
// [self removeEntity:a_planet]; // and Poof! it's gone
|
||||
// cachedPlanet = nil;
|
||||
// int i;
|
||||
// for (i = 0; i < 3; i++)
|
||||
// {
|
||||
// [self scatterAsteroidsAt:planetPos withVelocity:kZeroVector includingRockHermit:NO asCinders:YES];
|
||||
// [self scatterAsteroidsAt:witchPos withVelocity:kZeroVector includingRockHermit:NO asCinders:YES];
|
||||
// }
|
||||
|
||||
// OO_DEBUG_POP_PROGRESS();
|
||||
// }
|
||||
|
||||
|
||||
// systeminfo might have a 'script_actions' resource we want to activate now...
|
||||
NSArray *script_actions = [systeminfo oo_arrayForKey:@"script_actions"];
|
||||
if (script_actions != nil)
|
||||
@ -1255,6 +1287,143 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
|
||||
}
|
||||
}
|
||||
|
||||
- (void) clearSystemPopulator
|
||||
{
|
||||
[populatorSettings release];
|
||||
populatorSettings = [[NSMutableDictionary alloc] initWithCapacity:128];
|
||||
}
|
||||
|
||||
- (NSDictionary *) populatorSettings
|
||||
{
|
||||
return populatorSettings;
|
||||
}
|
||||
|
||||
- (void) setPopulatorSetting:(NSString *)key to:(NSDictionary *)setting
|
||||
{
|
||||
[populatorSettings setObject:setting forKey:key];
|
||||
}
|
||||
|
||||
- (void) populateSystemFromDictionariesWithSun:(OOSunEntity *)sun andPlanet:(OOPlanetEntity *)planet
|
||||
{
|
||||
NSArray *blocks = [populatorSettings allValues];
|
||||
NSEnumerator *enumerator = [[blocks sortedArrayUsingFunction:populatorPrioritySort context:nil] objectEnumerator];
|
||||
NSDictionary *populator;
|
||||
Vector location;
|
||||
int locationSeed, groupCount, rndvalue;
|
||||
unsigned i;
|
||||
RANROTSeed rndcache, rndlocal;
|
||||
NSString *locationCode;
|
||||
OOJSPopulatorDefinition *pdef;
|
||||
while ((populator = [enumerator nextObject])) {
|
||||
locationSeed = [populator oo_intForKey:@"locationSeed" defaultValue:0];
|
||||
groupCount = [populator oo_intForKey:@"groupCount" defaultValue:1];
|
||||
|
||||
for (i=0;i<groupCount;i++)
|
||||
{
|
||||
locationCode = [populator oo_stringForKey:@"location" defaultValue:@"COORDINATES"];
|
||||
if ([locationCode isEqualToString:@"COORDINATES"])
|
||||
{
|
||||
location = [populator oo_vectorForKey:@"coordinates" defaultValue:kZeroVector];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(locationSeed != 0)
|
||||
{
|
||||
rndcache = RANROTGetFullSeed();
|
||||
// different place for system
|
||||
rndlocal = RanrotSeedFromRandomSeed(system_seed);
|
||||
rndvalue = RanrotWithSeed(&rndlocal);
|
||||
// ...for location seed
|
||||
rndlocal = MakeRanrotSeed(rndvalue+locationSeed);
|
||||
rndvalue = RanrotWithSeed(&rndlocal);
|
||||
// ...for iteration
|
||||
RANROTSetFullSeed(MakeRanrotSeed(rndvalue+i));
|
||||
}
|
||||
if (sun == nil)
|
||||
{
|
||||
// all interstellar space locations equal to WITCHPOINT
|
||||
location = [self locationByCode:@"WITCHPOINT" withSun:nil andPlanet:nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
location = [self locationByCode:locationCode withSun:sun andPlanet:planet];
|
||||
}
|
||||
if(locationSeed != 0)
|
||||
{
|
||||
// go back to the main random sequence
|
||||
RANROTSetFullSeed(rndcache);
|
||||
}
|
||||
}
|
||||
// location now contains a Vector coordinate, one way or another
|
||||
pdef = [populator objectForKey:@"callbackObj"];
|
||||
[pdef runCallback:location];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
- (Vector) locationByCode:(NSString *)code withSun:(OOSunEntity *)sun andPlanet:(OOPlanetEntity *)planet
|
||||
{
|
||||
Vector result = kZeroVector;
|
||||
if ([code isEqualToString:@"WITCHPOINT"])
|
||||
{
|
||||
result = OOVectorRandomSpatial(SCANNER_MAX_RANGE);
|
||||
}
|
||||
// past this point, can assume non-nil sun, planet
|
||||
else if ([code isEqualToString:@"LANE_WP"])
|
||||
{
|
||||
result = OORandomPositionInCylinder(kZeroVector,SCANNER_MAX_RANGE,[planet position],[planet radius]*3,LANE_WIDTH);
|
||||
}
|
||||
else if ([code isEqualToString:@"LANE_WS"])
|
||||
{
|
||||
result = OORandomPositionInCylinder(kZeroVector,SCANNER_MAX_RANGE,[sun position],[sun radius]*3,LANE_WIDTH);
|
||||
}
|
||||
else if ([code isEqualToString:@"LANE_PS"])
|
||||
{
|
||||
result = OORandomPositionInCylinder([planet position],[planet radius]*3,[sun position],[sun radius]*3,LANE_WIDTH);
|
||||
}
|
||||
else if ([code isEqualToString:@"STATION_AEGIS"])
|
||||
{
|
||||
do
|
||||
{
|
||||
result = OORandomPositionInShell([[self station] position],[[self station] collisionRadius]*1.2,SCANNER_MAX_RANGE*2.0);
|
||||
} while(distance2(result,[planet position])<[planet radius]*[planet radius]*1.5);
|
||||
// loop to make sure not generated too close to the planet's surface
|
||||
}
|
||||
else if ([code isEqualToString:@"PLANET_ORBIT_LOW"])
|
||||
{
|
||||
result = OORandomPositionInShell([planet position],[planet radius]*1.1,[planet radius]*2.0);
|
||||
}
|
||||
else if ([code isEqualToString:@"PLANET_ORBIT"])
|
||||
{
|
||||
result = OORandomPositionInShell([planet position],[planet radius]*2.0,[planet radius]*4.0);
|
||||
}
|
||||
else if ([code isEqualToString:@"PLANET_ORBIT_HIGH"])
|
||||
{
|
||||
result = OORandomPositionInShell([planet position],[planet radius]*4.0,[planet radius]*8.0);
|
||||
}
|
||||
else if ([code isEqualToString:@"STAR_ORBIT_LOW"])
|
||||
{
|
||||
result = OORandomPositionInShell([sun position],[sun radius]*1.1,[sun radius]*2.0);
|
||||
}
|
||||
else if ([code isEqualToString:@"STAR_ORBIT"])
|
||||
{
|
||||
result = OORandomPositionInShell([sun position],[sun radius]*2.0,[sun radius]*4.0);
|
||||
}
|
||||
else if ([code isEqualToString:@"STAR_ORBIT_HIGH"])
|
||||
{
|
||||
result = OORandomPositionInShell([sun position],[sun radius]*4.0,[sun radius]*8.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
OOLog(kOOLogUniversePopulateError,@"Named populator region %@ is not implemented, falling back to WITCHPOINT",code);
|
||||
result = OOVectorRandomSpatial(SCANNER_MAX_RANGE);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
- (void) setLighting
|
||||
{
|
||||
@ -10770,6 +10939,17 @@ static void PreloadOneSound(NSString *soundName)
|
||||
|
||||
@end
|
||||
|
||||
NSComparisonResult populatorPrioritySort(id a, id b, void *context)
|
||||
{
|
||||
NSDictionary *one = (NSDictionary *)a;
|
||||
NSDictionary *two = (NSDictionary *)b;
|
||||
int pri_one = [one oo_intForKey:@"priority" defaultValue:100];
|
||||
int pri_two = [two oo_intForKey:@"priority" defaultValue:100];
|
||||
if (pri_one < pri_two) return NSOrderedAscending;
|
||||
if (pri_one > pri_two) return NSOrderedDescending;
|
||||
return NSOrderedSame;
|
||||
}
|
||||
|
||||
|
||||
NSString *OOLookUpDescriptionPRIV(NSString *key)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user