Merged script compiler and some new script actions into trunk.
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@430 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
4c1ae4683b
commit
18544c7d69
@ -21,7 +21,7 @@ endif
|
||||
OBJC_PROGRAM_NAME = oolite
|
||||
|
||||
oolite_C_FILES = vector.c legacy_random.c strlcpy.c
|
||||
oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntity_Additions.m PlayerEntity_contracts.m PlayerEntity_Controls.m PlayerEntity_Sound.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntity_AI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m OOMusic.m SDLImage.m LoadSave.m OOFileManager.m JoystickHandler.m PlayerEntity_StickMapper.m OOBasicSoundReferencePoint.m OOBasicSoundSource.m OOCharacter.m OOTrumble.m WormholeEntity.m ScannerExtension.m OOXMLExtensions.m MutableDictionaryExtension.m Geometry.m Octree.m CollisionRegion.m OOColor.m
|
||||
oolite_OBJC_FILES = Comparison.m AI.m DustEntity.m Entity.m GameController.m GuiDisplayGen.m HeadUpDisplay.m main.m MyOpenGLView.m OpenGLSprite.m ParticleEntity.m PlanetEntity.m PlayerEntity_Additions.m PlayerEntity_contracts.m PlayerEntity_Controls.m PlayerEntity_Sound.m PlayerEntity.m ResourceManager.m RingEntity.m ShipEntity_AI.m ShipEntity.m SkyEntity.m StationEntity.m TextureStore.m Universe.m OOSound.m OOMusic.m SDLImage.m LoadSave.m OOFileManager.m JoystickHandler.m PlayerEntity_StickMapper.m OOBasicSoundReferencePoint.m OOBasicSoundSource.m OOCharacter.m OOTrumble.m WormholeEntity.m ScannerExtension.m OOXMLExtensions.m MutableDictionaryExtension.m Geometry.m Octree.m CollisionRegion.m OOColor.m ScriptCompiler.m StringTokeniser.m
|
||||
|
||||
include $(GNUSTEP_MAKEFILES)/objc.make
|
||||
include GNUmakefile.postamble
|
||||
|
@ -117,6 +117,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
- (void) removeEquipment:(NSString *)equipString; //eg. EQ_NAVAL_ENERGY_UNIT
|
||||
|
||||
- (void) setPlanetinfo:(NSString *)key_valueString; // uses key=value format
|
||||
- (void) setSpecificPlanetInfo:(NSString *)key_valueString; // uses galaxy#=planet#=key=value
|
||||
|
||||
- (void) awardCargo:(NSString *)amount_typeString;
|
||||
- (void) removeAllCargo;
|
||||
@ -166,6 +167,9 @@ Your fair use and other rights are in no way affected by the above.
|
||||
// choices/choice phrases in missiontext.plist and also..
|
||||
- (void) resetMissionChoice; // resets MissionChoice to nil
|
||||
|
||||
- (void) addMissionDestination:(NSString *)destinations; // mark a system on the star charts
|
||||
- (void) removeMissionDestination:(NSString *)destinations; // stop a system being marked on star charts
|
||||
|
||||
- (void) showShipModel: (NSString *)shipKey;
|
||||
- (void) setMissionMusic: (NSString *)value;
|
||||
- (void) setMissionImage: (NSString *)value;
|
||||
|
@ -165,6 +165,7 @@ static NSString * mission_key;
|
||||
|
||||
*/
|
||||
NSMutableArray* tokens = [Entity scanTokensFromString:scriptAction];
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
NSString* selectorString = nil;
|
||||
NSString* valueString = nil;
|
||||
SEL _selector;
|
||||
@ -184,6 +185,9 @@ static NSString * mission_key;
|
||||
{
|
||||
[tokens removeObjectAtIndex:0];
|
||||
valueString = [[tokens componentsJoinedByString:@" "] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
valueString = [universe expandDescriptionWithLocals:valueString forSystem:[self system_seed] withLocalVariables:locals];
|
||||
if (debug)
|
||||
NSLog(@"DEBUG ::::: after expansion: \"%@ %@\"", selectorString, valueString);
|
||||
}
|
||||
|
||||
_selector = NSSelectorFromString(selectorString);
|
||||
@ -239,6 +243,7 @@ static NSString * mission_key;
|
||||
|
||||
*/
|
||||
NSArray* tokens = [Entity scanTokensFromString:scriptCondition];
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
NSString* selectorString = nil;
|
||||
NSString* comparisonString = nil;
|
||||
NSString* valueString = nil;
|
||||
@ -261,6 +266,13 @@ static NSString * mission_key;
|
||||
mission_string_value = (NSString *)[mission_variables objectForKey:selectorString];
|
||||
selectorString = @"mission_string";
|
||||
}
|
||||
else if ([selectorString hasPrefix:@"local_"])
|
||||
{
|
||||
if (debug)
|
||||
NSLog(@"DEBUG ..... checking local variable '%@'",selectorString);
|
||||
mission_string_value = (NSString *)[locals objectForKey:selectorString];
|
||||
selectorString = @"mission_string";
|
||||
}
|
||||
|
||||
if ([tokens count] > 1)
|
||||
{
|
||||
@ -859,6 +871,27 @@ static int shipsFound;
|
||||
|
||||
}
|
||||
|
||||
- (void) setSpecificPlanetInfo:(NSString *)key_valueString // uses galaxy#=planet#=key=value
|
||||
{
|
||||
NSArray* tokens = [[key_valueString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]] componentsSeparatedByString:@"="];
|
||||
NSString* keyString = nil;
|
||||
NSString* valueString = nil;
|
||||
int gnum, pnum;
|
||||
|
||||
if ([tokens count] != 4)
|
||||
{
|
||||
NSLog(@"***** CANNOT SETPLANETINFO: '%@'", key_valueString);
|
||||
return;
|
||||
}
|
||||
|
||||
gnum = [(NSString*)[tokens objectAtIndex:0] intValue];
|
||||
pnum = [(NSString*)[tokens objectAtIndex:1] intValue];
|
||||
keyString = [(NSString*)[tokens objectAtIndex:2] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
valueString = [(NSString*)[tokens objectAtIndex:3] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
|
||||
[universe setSystemDataForGalaxy:gnum planet:pnum key:keyString value:valueString];
|
||||
}
|
||||
|
||||
- (void) awardCargo:(NSString *)amount_typeString
|
||||
{
|
||||
// NSArray* tokens = [amount_typeString componentsSeparatedByString:@" "];
|
||||
@ -1210,8 +1243,10 @@ static int shipsFound;
|
||||
- (void) set:(NSString *)missionvariable_value
|
||||
{
|
||||
NSMutableArray* tokens = [Entity scanTokensFromString:missionvariable_value];
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
NSString* missionVariableString = nil;
|
||||
NSString* valueString = nil;
|
||||
BOOL hasMissionPrefix, hasLocalPrefix;
|
||||
|
||||
if ([tokens count] < 2)
|
||||
{
|
||||
@ -1223,54 +1258,92 @@ static int shipsFound;
|
||||
[tokens removeObjectAtIndex:0];
|
||||
valueString = [tokens componentsJoinedByString:@" "];
|
||||
|
||||
if (([valueString hasSuffix:@"_number"])||([valueString hasSuffix:@"_bool"])||([valueString hasSuffix:@"_string"]))
|
||||
{
|
||||
SEL value_selector = NSSelectorFromString(valueString);
|
||||
if ([self respondsToSelector:value_selector])
|
||||
{
|
||||
// substitute into valueString the result of the call
|
||||
valueString = [NSString stringWithFormat:@"%@", [self performSelector:value_selector]];
|
||||
}
|
||||
}
|
||||
hasMissionPrefix = [missionVariableString hasPrefix:@"mission_"];
|
||||
hasLocalPrefix = [missionVariableString hasPrefix:@"local_"];
|
||||
|
||||
if (![missionVariableString hasPrefix:@"mission_"])
|
||||
if (hasMissionPrefix != YES && hasLocalPrefix != YES)
|
||||
{
|
||||
NSLog(@"***** MISSION VARIABLE '%@' DOES NOT BEGIN WITH 'mission_'", missionvariable_value);
|
||||
NSLog(@"***** IDENTIFIER '%@' DOES NOT BEGIN WITH 'mission_' or 'local_'", missionVariableString);
|
||||
return;
|
||||
}
|
||||
|
||||
[mission_variables setObject:valueString forKey:missionVariableString];
|
||||
if (hasMissionPrefix)
|
||||
[mission_variables setObject:valueString forKey:missionVariableString];
|
||||
else
|
||||
[locals setObject:valueString forKey:missionVariableString];
|
||||
}
|
||||
|
||||
- (void) reset:(NSString *)missionvariable
|
||||
{
|
||||
NSString* missionVariableString = [missionvariable stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
BOOL hasMissionPrefix, hasLocalPrefix;
|
||||
|
||||
if (![missionVariableString hasPrefix:@"mission_"])
|
||||
{
|
||||
NSLog(@"***** MISSION VARIABLE '%@' DOES NOT BEGIN WITH 'mission_'", missionVariableString);
|
||||
return;
|
||||
}
|
||||
hasMissionPrefix = [missionVariableString hasPrefix:@"mission_"];
|
||||
hasLocalPrefix = [missionVariableString hasPrefix:@"local_"];
|
||||
|
||||
[mission_variables removeObjectForKey:missionVariableString];
|
||||
if (hasMissionPrefix)
|
||||
{
|
||||
[mission_variables removeObjectForKey:missionVariableString];
|
||||
}
|
||||
else if (hasLocalPrefix)
|
||||
{
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
[locals removeObjectForKey:missionVariableString];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"***** IDENTIFIER '%@' DOES NOT BEGIN WITH 'mission_' or 'local_'", missionVariableString);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) increment:(NSString *)missionVariableString
|
||||
{
|
||||
BOOL hasMissionPrefix, hasLocalPrefix;
|
||||
int value = 0;
|
||||
if ([mission_variables objectForKey:missionVariableString])
|
||||
value = [(NSString *)[mission_variables objectForKey:missionVariableString] intValue];
|
||||
value++;
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%d", value] forKey:missionVariableString];
|
||||
|
||||
hasMissionPrefix = [missionVariableString hasPrefix:@"mission_"];
|
||||
hasLocalPrefix = [missionVariableString hasPrefix:@"local_"];
|
||||
|
||||
if (hasMissionPrefix)
|
||||
{
|
||||
if ([mission_variables objectForKey:missionVariableString])
|
||||
value = [(NSString *)[mission_variables objectForKey:missionVariableString] intValue];
|
||||
value++;
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%d", value] forKey:missionVariableString];
|
||||
}
|
||||
else if (hasLocalPrefix)
|
||||
{
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
if ([locals objectForKey:missionVariableString])
|
||||
value = [(NSString *)[locals objectForKey:missionVariableString] intValue];
|
||||
value++;
|
||||
[locals setObject:[NSString stringWithFormat:@"%d", value] forKey:missionVariableString];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) decrement:(NSString *)missionVariableString
|
||||
{
|
||||
BOOL hasMissionPrefix, hasLocalPrefix;
|
||||
int value = 0;
|
||||
if ([mission_variables objectForKey:missionVariableString])
|
||||
value = [(NSString *)[mission_variables objectForKey:missionVariableString] intValue];
|
||||
value--;
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%d", value] forKey:missionVariableString];
|
||||
|
||||
hasMissionPrefix = [missionVariableString hasPrefix:@"mission_"];
|
||||
hasLocalPrefix = [missionVariableString hasPrefix:@"local_"];
|
||||
|
||||
if (hasMissionPrefix)
|
||||
{
|
||||
if ([mission_variables objectForKey:missionVariableString])
|
||||
value = [(NSString *)[mission_variables objectForKey:missionVariableString] intValue];
|
||||
value--;
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%d", value] forKey:missionVariableString];
|
||||
}
|
||||
else if (hasLocalPrefix)
|
||||
{
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
if ([locals objectForKey:missionVariableString])
|
||||
value = [(NSString *)[locals objectForKey:missionVariableString] intValue];
|
||||
value--;
|
||||
[locals setObject:[NSString stringWithFormat:@"%d", value] forKey:missionVariableString];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) add:(NSString *)missionVariableString_value
|
||||
@ -1279,6 +1352,8 @@ static int shipsFound;
|
||||
NSString* valueString;
|
||||
double value;
|
||||
NSMutableArray* tokens = [Entity scanTokensFromString:missionVariableString_value];
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
BOOL hasMissionPrefix, hasLocalPrefix;
|
||||
|
||||
if ([tokens count] < 2)
|
||||
{
|
||||
@ -1290,27 +1365,28 @@ static int shipsFound;
|
||||
[tokens removeObjectAtIndex:0];
|
||||
valueString = [tokens componentsJoinedByString:@" "];
|
||||
|
||||
if (![mission_variables objectForKey:missionVariableString])
|
||||
hasMissionPrefix = [missionVariableString hasPrefix:@"mission_"];
|
||||
hasLocalPrefix = [missionVariableString hasPrefix:@"local_"];
|
||||
|
||||
if (hasMissionPrefix)
|
||||
{
|
||||
value = [[mission_variables objectForKey:missionVariableString] doubleValue];
|
||||
value += [valueString doubleValue];
|
||||
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%f", value] forKey:missionVariableString];
|
||||
}
|
||||
else if (hasLocalPrefix)
|
||||
{
|
||||
value = [[locals objectForKey:missionVariableString] doubleValue];
|
||||
value += [valueString doubleValue];
|
||||
|
||||
[locals setObject:[NSString stringWithFormat:@"%f", value] forKey:missionVariableString];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"***** CANNOT ADD: '%@'",missionVariableString_value);
|
||||
NSLog(@"***** NO MISSION VARIABLE: '%@'",missionVariableString);
|
||||
return;
|
||||
NSLog(@"***** IDENTIFIER '%@' DOES NOT BEGIN WITH 'mission_' or 'local_'",missionVariableString);
|
||||
}
|
||||
|
||||
if (([valueString hasSuffix:@"_number"])||([valueString hasSuffix:@"_bool"])||([valueString hasSuffix:@"_string"]))
|
||||
{
|
||||
SEL value_selector = NSSelectorFromString(valueString);
|
||||
if ([self respondsToSelector:value_selector])
|
||||
{
|
||||
// substitute into valueString the result of the call
|
||||
valueString = [NSString stringWithFormat:@"%@", [self performSelector:value_selector]];
|
||||
}
|
||||
}
|
||||
|
||||
value = [[mission_variables objectForKey:missionVariableString] doubleValue];
|
||||
value += [valueString doubleValue];
|
||||
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%f", value] forKey:missionVariableString];
|
||||
}
|
||||
|
||||
- (void) subtract:(NSString *)missionVariableString_value
|
||||
@ -1319,10 +1395,12 @@ static int shipsFound;
|
||||
NSString* valueString;
|
||||
double value;
|
||||
NSMutableArray* tokens = [Entity scanTokensFromString:missionVariableString_value];
|
||||
NSMutableDictionary* locals = [local_variables objectForKey:mission_key];
|
||||
BOOL hasMissionPrefix, hasLocalPrefix;
|
||||
|
||||
if ([tokens count] < 2)
|
||||
{
|
||||
NSLog(@"***** CANNOT ADD: '%@'",missionVariableString_value);
|
||||
NSLog(@"***** CANNOT SUBTRACT: '%@'",missionVariableString_value);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1330,27 +1408,28 @@ static int shipsFound;
|
||||
[tokens removeObjectAtIndex:0];
|
||||
valueString = [tokens componentsJoinedByString:@" "];
|
||||
|
||||
if (![mission_variables objectForKey:missionVariableString])
|
||||
hasMissionPrefix = [missionVariableString hasPrefix:@"mission_"];
|
||||
hasLocalPrefix = [missionVariableString hasPrefix:@"local_"];
|
||||
|
||||
if (hasMissionPrefix)
|
||||
{
|
||||
NSLog(@"***** CANNOT ADD: '%@'",missionVariableString_value);
|
||||
NSLog(@"***** NO MISSION VARIABLE: '%@'",missionVariableString);
|
||||
return;
|
||||
}
|
||||
value = [[mission_variables objectForKey:missionVariableString] doubleValue];
|
||||
value -= [valueString doubleValue];
|
||||
|
||||
if (([valueString hasSuffix:@"_number"])||([valueString hasSuffix:@"_bool"])||([valueString hasSuffix:@"_string"]))
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%f", value] forKey:missionVariableString];
|
||||
}
|
||||
else if (hasLocalPrefix)
|
||||
{
|
||||
SEL value_selector = NSSelectorFromString(valueString);
|
||||
if ([self respondsToSelector:value_selector])
|
||||
{
|
||||
// substitute into valueString the result of the call
|
||||
valueString = [NSString stringWithFormat:@"%@", [self performSelector:value_selector]];
|
||||
}
|
||||
value = [[locals objectForKey:missionVariableString] doubleValue];
|
||||
value -= [valueString doubleValue];
|
||||
|
||||
[locals setObject:[NSString stringWithFormat:@"%f", value] forKey:missionVariableString];
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"***** CANNOT SUBTRACT: '%@'",missionVariableString_value);
|
||||
NSLog(@"***** IDENTIFIER '%@' DOES NOT BEGIN WITH 'mission_' or 'local_'",missionVariableString);
|
||||
}
|
||||
|
||||
value = [[mission_variables objectForKey:missionVariableString] doubleValue];
|
||||
value -= [valueString doubleValue];
|
||||
|
||||
[mission_variables setObject:[NSString stringWithFormat:@"%f", value] forKey:missionVariableString];
|
||||
}
|
||||
|
||||
- (void) checkForShips: (NSString *)roleString
|
||||
@ -1437,6 +1516,68 @@ static int shipsFound;
|
||||
missionChoice = nil;
|
||||
}
|
||||
|
||||
- (void) addMissionDestination:(NSString *)destinations
|
||||
{
|
||||
int i, j;
|
||||
NSNumber *pnump;
|
||||
int pnum, dest;
|
||||
NSMutableArray* tokens = [Entity scanTokensFromString:destinations];
|
||||
BOOL addDestination;
|
||||
|
||||
for (j = 0; j < [tokens count]; j++)
|
||||
{
|
||||
dest = [(NSString *)[tokens objectAtIndex:j] intValue];
|
||||
if (dest < 0 || dest > 255)
|
||||
continue;
|
||||
|
||||
addDestination = YES;
|
||||
for (i = 0; i < [missionDestinations count]; i++)
|
||||
{
|
||||
pnump = (NSNumber *)[missionDestinations objectAtIndex:i];
|
||||
pnum = [pnump intValue];
|
||||
if (pnum == dest)
|
||||
{
|
||||
addDestination = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addDestination == YES)
|
||||
[missionDestinations addObject:[NSNumber numberWithUnsignedInt:dest]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) removeMissionDestination:(NSString *)destinations
|
||||
{
|
||||
int i, j;
|
||||
NSNumber *pnump;
|
||||
int pnum, dest;
|
||||
NSMutableArray* tokens = [Entity scanTokensFromString:destinations];
|
||||
BOOL removeDestination;
|
||||
|
||||
for (j = 0; j < [tokens count]; j++)
|
||||
{
|
||||
dest = [(NSString *)[tokens objectAtIndex:j] intValue];
|
||||
if (dest < 0 || dest > 255)
|
||||
continue;
|
||||
|
||||
removeDestination = NO;
|
||||
for (i = 0; i < [missionDestinations count]; i++)
|
||||
{
|
||||
pnump = (NSNumber *)[missionDestinations objectAtIndex:i];
|
||||
pnum = [pnump intValue];
|
||||
if (pnum == dest)
|
||||
{
|
||||
removeDestination = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (removeDestination == YES)
|
||||
[missionDestinations removeObjectAtIndex:i];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) showShipModel: (NSString *)shipKey
|
||||
{
|
||||
ShipEntity *ship;
|
||||
@ -1676,7 +1817,7 @@ static int shipsFound;
|
||||
|
||||
- (void) debugMessage:(NSString *)args
|
||||
{
|
||||
NSLog(@"SCRIPT debugMessage: %@", [self replaceVariablesInString: args]);
|
||||
NSLog(@"SCRIPT debugMessage: %@", args);
|
||||
}
|
||||
|
||||
- (NSString*) replaceVariablesInString:(NSString*) args
|
||||
@ -1693,8 +1834,7 @@ static int shipsFound;
|
||||
{
|
||||
[tokens replaceObjectAtIndex:i withObject:[mission_variables objectForKey:valueString]];
|
||||
}
|
||||
|
||||
if (([valueString hasSuffix:@"_number"])||([valueString hasSuffix:@"_bool"])||([valueString hasSuffix:@"_string"]))
|
||||
else if (([valueString hasSuffix:@"_number"])||([valueString hasSuffix:@"_bool"])||([valueString hasSuffix:@"_string"]))
|
||||
{
|
||||
SEL value_selector = NSSelectorFromString(valueString);
|
||||
if ([self respondsToSelector:value_selector])
|
||||
|
@ -234,6 +234,7 @@ enum
|
||||
|
||||
NSDictionary *script;
|
||||
NSMutableDictionary *mission_variables;
|
||||
NSMutableDictionary *local_variables;
|
||||
int missionTextRow;
|
||||
ShipEntity *script_target;
|
||||
NSString *missionChoice;
|
||||
@ -262,6 +263,8 @@ enum
|
||||
|
||||
NSMutableDictionary *shipyard_record;
|
||||
|
||||
NSMutableArray *missionDestinations;
|
||||
|
||||
double script_time;
|
||||
double script_time_check;
|
||||
double script_time_interval;
|
||||
|
@ -433,6 +433,8 @@ static Quaternion quaternion_identity = { (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0
|
||||
[result setObject:contracts forKey:@"contracts"];
|
||||
[result setObject:contract_record forKey:@"contract_record"];
|
||||
|
||||
[result setObject:missionDestinations forKey:@"missionDestinations"];
|
||||
|
||||
//shipyard
|
||||
[result setObject:shipyard_record forKey:@"shipyard_record"];
|
||||
|
||||
@ -699,6 +701,20 @@ static Quaternion quaternion_identity = { (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0
|
||||
contract_record = [[NSMutableDictionary dictionaryWithCapacity:8] retain];
|
||||
}
|
||||
|
||||
// mission destinations
|
||||
if ([dict objectForKey:@"missionDestinations"])
|
||||
{
|
||||
if (missionDestinations)
|
||||
[missionDestinations release];
|
||||
missionDestinations = [[NSMutableArray arrayWithArray:(NSArray *)[dict objectForKey:@"missionDestinations"]] retain];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (missionDestinations)
|
||||
[missionDestinations release];
|
||||
missionDestinations = [[NSMutableArray arrayWithCapacity:8] retain];
|
||||
}
|
||||
|
||||
// shipyard
|
||||
if ([dict objectForKey:@"shipyard_record"])
|
||||
{
|
||||
@ -910,8 +926,14 @@ static Quaternion quaternion_identity = { (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0
|
||||
[hud setScannerZoom:1.0];
|
||||
scanner_zoom_rate = 0.0;
|
||||
//
|
||||
script = [[ResourceManager dictionaryFromFilesNamed:@"script.plist" inFolder:@"Config" andMerge:YES] retain];
|
||||
//script = [[ResourceManager dictionaryFromFilesNamed:@"script.plist" inFolder:@"Config" andMerge:YES] retain];
|
||||
script = [[ResourceManager loadScripts] retain];
|
||||
mission_variables =[[NSMutableDictionary dictionaryWithCapacity:16] retain];
|
||||
local_variables =[[NSMutableDictionary dictionaryWithCapacity:[script count]] retain];
|
||||
NSArray *scriptKeys = [script allKeys];
|
||||
for (i = 0; i < [scriptKeys count]; i++)
|
||||
[local_variables setObject:[NSMutableDictionary dictionaryWithCapacity:16] forKey:[scriptKeys objectAtIndex:i]];
|
||||
|
||||
[self setScript_target:nil];
|
||||
[self resetMissionChoice];
|
||||
//
|
||||
@ -938,6 +960,10 @@ static Quaternion quaternion_identity = { (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0
|
||||
[contract_record release];
|
||||
contract_record = [[NSMutableDictionary dictionaryWithCapacity:16] retain];
|
||||
//
|
||||
if (missionDestinations)
|
||||
[missionDestinations release];
|
||||
missionDestinations = [[NSMutableArray alloc] initWithCapacity:8];
|
||||
//
|
||||
if (shipyard_record)
|
||||
[shipyard_record release];
|
||||
shipyard_record = [[NSMutableDictionary dictionaryWithCapacity:4] retain];
|
||||
@ -1422,6 +1448,20 @@ static Quaternion quaternion_identity = { (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0
|
||||
|
||||
if (script) [script release];
|
||||
if (mission_variables) [mission_variables release];
|
||||
|
||||
if (local_variables)
|
||||
{
|
||||
int i;
|
||||
NSArray *objs = [local_variables allValues];
|
||||
for (i = 0; i < [objs count]; i++)
|
||||
{
|
||||
NSMutableDictionary *dict = (NSMutableDictionary *)[objs objectAtIndex:i];
|
||||
[dict dealloc];
|
||||
}
|
||||
[local_variables removeAllObjects];
|
||||
[local_variables dealloc];
|
||||
}
|
||||
|
||||
if (lastTextKey) [lastTextKey release];
|
||||
|
||||
if (extra_equipment) [extra_equipment release];
|
||||
@ -1431,6 +1471,7 @@ static Quaternion quaternion_identity = { (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0
|
||||
if (passenger_record) [passenger_record release];
|
||||
if (contracts) [contracts release];
|
||||
if (contract_record) [contract_record release];
|
||||
if (missionDestinations) [missionDestinations release];
|
||||
if (shipyard_record) [shipyard_record release];
|
||||
|
||||
if (missionBackgroundImage) [missionBackgroundImage release];
|
||||
@ -3791,6 +3832,10 @@ double scoopSoundPlayTime = 0.0;
|
||||
if (contracts)
|
||||
[contracts removeAllObjects];
|
||||
|
||||
// remove any mission destinations for the old galaxy
|
||||
if (missionDestinations)
|
||||
[missionDestinations removeAllObjects];
|
||||
|
||||
// expire passenger contracts for the old galaxy
|
||||
if (passengers)
|
||||
{
|
||||
@ -4528,6 +4573,8 @@ double scoopSoundPlayTime = 0.0;
|
||||
mark[[(NSNumber*)[(NSDictionary*)[passengers objectAtIndex:i] objectForKey:PASSENGER_KEY_DESTINATION] intValue]] = YES;
|
||||
for (i = 0; i < [contracts count]; i++)
|
||||
mark[[(NSNumber*)[(NSDictionary*)[contracts objectAtIndex:i] objectForKey:CONTRACT_KEY_DESTINATION] intValue]] = YES;
|
||||
for (i = 0; i < [missionDestinations count]; i++)
|
||||
mark[[(NSNumber*)[missionDestinations objectAtIndex:i] intValue]] = YES;
|
||||
for (i = 0; i < 256; i++)
|
||||
[destinations addObject:[NSNumber numberWithBool:mark[i]]];
|
||||
|
||||
@ -4552,6 +4599,8 @@ double scoopSoundPlayTime = 0.0;
|
||||
mark[[(NSNumber*)[(NSDictionary*)[passengers objectAtIndex:i] objectForKey:PASSENGER_KEY_DESTINATION] intValue]] = YES;
|
||||
for (i = 0; i < [contracts count]; i++)
|
||||
mark[[(NSNumber*)[(NSDictionary*)[contracts objectAtIndex:i] objectForKey:CONTRACT_KEY_DESTINATION] intValue]] = YES;
|
||||
for (i = 0; i < [missionDestinations count]; i++)
|
||||
mark[[(NSNumber*)[missionDestinations objectAtIndex:i] intValue]] = YES;
|
||||
|
||||
// GUI stuff
|
||||
{
|
||||
|
@ -110,4 +110,5 @@ BOOL always_include_addons;
|
||||
+ (NSString*) stringFromNSPoint: (NSPoint) point;
|
||||
+ (NSPoint) NSPointFromString: (NSString*) point_string;
|
||||
|
||||
+ (NSDictionary *) loadScripts;
|
||||
@end
|
||||
|
@ -44,6 +44,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
#import "MutableDictionaryExtension.h"
|
||||
#import "OOSound.h"
|
||||
|
||||
extern NSDictionary* parseScripts(NSString* script);
|
||||
|
||||
@implementation ResourceManager
|
||||
|
||||
@ -1195,4 +1196,141 @@ NSMutableDictionary* surface_cache;
|
||||
return NSMakePoint( [[tokens objectAtIndex:0] floatValue], [[tokens objectAtIndex:1] floatValue]);
|
||||
}
|
||||
|
||||
+ (NSDictionary *) loadScripts
|
||||
{
|
||||
NSMutableArray *results = [NSMutableArray arrayWithCapacity:16];
|
||||
NSMutableArray *fpaths = [ResourceManager paths];
|
||||
NSString *foldername = [NSString stringWithString:@"Config"];
|
||||
NSString *filename = [NSString stringWithString:@"script.plist"];
|
||||
|
||||
int i;
|
||||
|
||||
NSString* dict_key = [NSString stringWithFormat:@"%@:%@", foldername, filename];
|
||||
if (!dictionary_cache)
|
||||
dictionary_cache = [[NSMutableDictionary alloc] initWithCapacity:32];
|
||||
if ([dictionary_cache objectForKey:dict_key])
|
||||
{
|
||||
return [NSDictionary dictionaryWithDictionary:(NSDictionary *)[dictionary_cache objectForKey:dict_key]]; // return the cached dictionary
|
||||
}
|
||||
|
||||
for (i = 0; i < [fpaths count]; i++)
|
||||
{
|
||||
NSString *xfilepath = [(NSString *)[fpaths objectAtIndex:i] stringByAppendingPathComponent:filename];
|
||||
NSMutableString *filepath = [NSMutableString stringWithString:xfilepath];
|
||||
|
||||
[filepath replaceString:@".plist" withString:@".oos"];
|
||||
//NSLog(@"looking for oos file: %@", filepath);
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath])
|
||||
{
|
||||
// load and compile oos script
|
||||
NSLog(@"trying to load and parse %@", filepath);
|
||||
NSString *script = [NSString stringWithContentsOfFile:filepath];
|
||||
NSDictionary *scriptDict = parseScripts(script);
|
||||
if (scriptDict) {
|
||||
//NSLog(@"parsed ok, adding to results");
|
||||
[results addObject:scriptDict];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[filepath replaceString:@".oos" withString:@".plist"];
|
||||
//NSLog(@"oos not found, looking for plist file: %@", filepath);
|
||||
// All this code replicated from dictionaryFromFileNamed because that method
|
||||
// will traverse all possible locations and any oos files that co-exist with
|
||||
// plist files will probably get their entries overwritten.
|
||||
//
|
||||
// This can be simplified if we make a rule that it is a configuration error
|
||||
// that isn't handled if there is a script.oos and script.plist file in
|
||||
// the same place. But that probably isn't realistic.
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath])
|
||||
{
|
||||
NSDictionary* found_dic = [NSDictionary dictionaryWithContentsOfFile:filepath];
|
||||
|
||||
// FIX FOR WINDOWS GNUSTEP NOT PARSING XML PLISTS
|
||||
NS_DURING
|
||||
if (!found_dic) // try parsing it using our home-grown XML parser
|
||||
found_dic = (NSDictionary*)[ResourceManager parseXMLPropertyList:[NSString stringWithContentsOfFile:filepath]];
|
||||
NS_HANDLER
|
||||
if ([[localException name] isEqual: OOLITE_EXCEPTION_XML_PARSING_FAILURE]) // note it happened here
|
||||
{
|
||||
NSLog(@"***** [ResourceManager dictionaryFromFilesNamed:::] encountered exception : %@ : %@ *****",[localException name], [localException reason]);
|
||||
}
|
||||
else
|
||||
[localException raise];
|
||||
NS_ENDHANDLER
|
||||
|
||||
if (found_dic)
|
||||
[results addObject:found_dic];
|
||||
else
|
||||
NSLog(@"ERROR ***** could not parse %@ as a NSDictionary.", filepath);
|
||||
}
|
||||
}
|
||||
if (foldername)
|
||||
{
|
||||
xfilepath = [[(NSString *)[fpaths objectAtIndex:i] stringByAppendingPathComponent:foldername] stringByAppendingPathComponent:filename];
|
||||
filepath = [NSMutableString stringWithString:xfilepath];
|
||||
[filepath replaceString:@".plist" withString:@".oos"];
|
||||
//NSLog(@"looking for oos file: %@", filepath);
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath])
|
||||
{
|
||||
// load and compile oos script
|
||||
NSLog(@"trying to load and compile %@", filepath);
|
||||
NSString *script = [NSString stringWithContentsOfFile:filepath];
|
||||
NSDictionary *scriptDict = parseScripts(script);
|
||||
if (scriptDict) {
|
||||
//NSLog(@"parsed ok, adding to results");
|
||||
[results addObject:scriptDict];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[filepath replaceString:@".oos" withString:@".plist"];
|
||||
//NSLog(@"oos not found, looking for plist file: %@", filepath);
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:filepath])
|
||||
{
|
||||
NSDictionary* found_dic = [NSDictionary dictionaryWithContentsOfFile:filepath];
|
||||
|
||||
// FIX FOR WINDOWS GNUSTEP NOT PARSING XML PLISTS
|
||||
NS_DURING
|
||||
if (!found_dic) // try parsing it using our home-grown XML parser
|
||||
found_dic = (NSDictionary*)[ResourceManager parseXMLPropertyList:[NSString stringWithContentsOfFile:filepath]];
|
||||
NS_HANDLER
|
||||
if ([[localException name] isEqual: OOLITE_EXCEPTION_XML_PARSING_FAILURE]) // note it happened here
|
||||
{
|
||||
NSLog(@"***** [ResourceManager dictionaryFromFilesNamed:::] encountered exception : %@ : %@ *****",[localException name], [localException reason]);
|
||||
}
|
||||
else
|
||||
[localException raise];
|
||||
NS_ENDHANDLER
|
||||
|
||||
|
||||
if (found_dic)
|
||||
[results addObject:found_dic];
|
||||
else
|
||||
NSLog(@"ERROR ***** could not parse %@ as a NSDictionary.", filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ([results count] == 0)
|
||||
return nil;
|
||||
|
||||
// got results we may want to cache
|
||||
//
|
||||
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithCapacity:128];
|
||||
for (i = 0; i < [results count]; i++)
|
||||
{
|
||||
[result addEntriesFromDictionary:(NSDictionary *)[results objectAtIndex:i]];
|
||||
}
|
||||
//
|
||||
if (result) {
|
||||
[dictionary_cache setObject:result forKey:dict_key];
|
||||
}
|
||||
|
||||
// NSLog(@"DEBUG ResourceManager dictionary_cache keys:\n%@", [dictionary_cache allKeys]);
|
||||
|
||||
return [NSDictionary dictionaryWithDictionary:result];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
246
src/Core/ScriptCompiler.m
Normal file
246
src/Core/ScriptCompiler.m
Normal file
@ -0,0 +1,246 @@
|
||||
/*
|
||||
* Oolite script compiler.
|
||||
*
|
||||
* Copyright (c) 2006 David Taylor. All rights reserved.
|
||||
*
|
||||
* This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
||||
* To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
||||
* or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
||||
*
|
||||
* You are free:
|
||||
*
|
||||
* o to copy, distribute, display, and perform the work
|
||||
* o to make derivative works
|
||||
*
|
||||
* Under the following conditions:
|
||||
*
|
||||
* o Attribution. You must give the original author credit.
|
||||
* o Noncommercial. You may not use this work for commercial purposes.
|
||||
* o Share Alike. If you alter, transform, or build upon this work,
|
||||
* you may distribute the resulting work only under a license identical to this one.
|
||||
*
|
||||
* For any reuse or distribution, you must make clear to others the license terms of this work.
|
||||
* Any of these conditions can be waived if you get permission from the copyright holder.
|
||||
* Your fair use and other rights are in no way affected by the above.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "StringTokeniser.h"
|
||||
|
||||
/*
|
||||
* Preprocess the source read from the oos file.
|
||||
*
|
||||
* Strips blank lines and lines beginning with "//".
|
||||
* Strips leading and trailing whitespace off any lines that are left.
|
||||
*
|
||||
* Returns the processed source.
|
||||
*/
|
||||
NSString* preprocess(NSString* source) {
|
||||
int i;
|
||||
NSMutableString *processedSource = [NSMutableString stringWithString:source];
|
||||
// convert DOS and MAC EOLs to *NIX EOL (DOS EOL will create blank lines,
|
||||
// but these are filtered out in the loop)
|
||||
[processedSource replaceOccurrencesOfString:@"\r" withString:@"\n" options:NSLiteralSearch range:NSMakeRange(0, [processedSource length])];
|
||||
NSArray *lines = [processedSource componentsSeparatedByString:@"\n"];
|
||||
[processedSource setString:@""];
|
||||
|
||||
for (i = 0; i < [lines count]; i++) {
|
||||
NSString* line = (NSString*)[lines objectAtIndex:i];
|
||||
NSMutableString* mutableLine = [NSMutableString stringWithString:line];
|
||||
[mutableLine trimSpaces];
|
||||
line = [NSString stringWithString:mutableLine];
|
||||
if ([line length] == 0)
|
||||
continue;
|
||||
if ([line hasPrefix:@"//"])
|
||||
continue;
|
||||
|
||||
[processedSource appendString:line];
|
||||
[processedSource appendString:@"\n"];
|
||||
}
|
||||
|
||||
return [NSString stringWithString:processedSource];
|
||||
}
|
||||
|
||||
|
||||
NSDictionary* parseIf(StringTokeniser* st) {
|
||||
NSMutableString *statement = [NSMutableString stringWithCapacity:80];
|
||||
NSMutableArray *conditions = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *actions = [[NSMutableArray alloc] init];
|
||||
NSMutableDictionary *ifDict = [[NSMutableDictionary alloc] initWithCapacity:3];
|
||||
BOOL inElse = NO;
|
||||
|
||||
[st nextToken];
|
||||
while (st->tokenType != TT_WORD) {
|
||||
if (st->tokenType == TT_EOS) {
|
||||
// end of the script - this is fine while looking for an "if"
|
||||
return nil;
|
||||
}
|
||||
|
||||
[st nextToken];
|
||||
}
|
||||
|
||||
if ([st->tokenWord isEqual:@"if"] != YES) {
|
||||
NSLog(@"ScriptCompiler: Error (line %d): expected \"if\", found %@", st->lineNo, st->tokenWord);
|
||||
return nil;
|
||||
}
|
||||
|
||||
// parse the conditions
|
||||
while (1) {
|
||||
[st nextToken];
|
||||
if (st->tokenType == TT_EOL)
|
||||
continue;
|
||||
|
||||
if (st->tokenType == TT_EOS) {
|
||||
NSLog(@"ScriptCompiler: Error (line %d): unexpected end of script", st->lineNo);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([st->tokenWord isEqual:@"then"] == YES) {
|
||||
[statement trimSpaces];
|
||||
[statement replaceString:@" = " withString:@" equal "];
|
||||
[statement replaceString:@" < " withString:@" lessthan "];
|
||||
[statement replaceString:@" > " withString:@" greaterthan "];
|
||||
|
||||
NSString* c = [NSString stringWithString: statement];
|
||||
[conditions addObject:c];
|
||||
[statement setString:@""]; // is also used for the actions so needs to be cleared
|
||||
break; // got the then keyword so now parse the actions
|
||||
}
|
||||
|
||||
if ([st->tokenWord isEqual:@"and"] == YES) {
|
||||
[statement trimSpaces];
|
||||
[statement replaceString:@" = " withString:@" equal "];
|
||||
[statement replaceString:@" < " withString:@" lessthan "];
|
||||
[statement replaceString:@" > " withString:@" greaterthan "];
|
||||
NSString* c = [NSString stringWithString: statement];
|
||||
[conditions addObject:c];
|
||||
[statement setString:@""];
|
||||
continue;
|
||||
}
|
||||
|
||||
[statement appendString:st->tokenWord];
|
||||
[statement appendString:@" "];
|
||||
}
|
||||
|
||||
[ifDict setObject:conditions forKey:@"conditions"];
|
||||
|
||||
// parse the actions, including else and endif keywords
|
||||
while (1) {
|
||||
[st nextToken];
|
||||
if (st->tokenType == TT_EOL) { // marks the end of an action
|
||||
[statement trimSpaces];
|
||||
if ([statement length] > 0) {
|
||||
NSString* c = [NSString stringWithString: statement];
|
||||
[actions addObject:c];
|
||||
[statement setString:@""];
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (st->tokenType == TT_EOS) {
|
||||
NSLog(@"ScriptCompiler: Error (line %d): unexpected end of script, expected else or endif", st->lineNo);
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([st->tokenWord isEqual:@"else"] == YES) {
|
||||
if (inElse == YES) {
|
||||
NSLog(@"ScriptCompiler: Error (line %d): already in \"else\" block", st->lineNo);
|
||||
return nil;
|
||||
}
|
||||
|
||||
[ifDict setObject:actions forKey:@"do"];
|
||||
[statement setString:@""];
|
||||
actions = [[NSMutableArray alloc] init];
|
||||
inElse = YES;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ([st->tokenWord isEqual:@"endif"] == YES) {
|
||||
if (inElse == YES) {
|
||||
[ifDict setObject:actions forKey:@"else"];
|
||||
} else {
|
||||
[ifDict setObject:actions forKey:@"do"];
|
||||
}
|
||||
|
||||
[statement setString:@""];
|
||||
break;
|
||||
}
|
||||
|
||||
if ([st->tokenWord isEqual:@"if"] == YES) {
|
||||
[st pushBack];
|
||||
NSDictionary* ifDict = parseIf(st);
|
||||
if (ifDict != nil) {
|
||||
|
||||
[actions addObject:ifDict];
|
||||
}
|
||||
else
|
||||
break; //if we read "if" and got nil back, there has certainly been an error so bail out
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
[statement appendString:st->tokenWord];
|
||||
[statement appendString:@" "];
|
||||
}
|
||||
|
||||
return ifDict;
|
||||
}
|
||||
|
||||
|
||||
NSDictionary* parseScripts(NSString* script) {
|
||||
NSString *processedScript = preprocess(script);
|
||||
StringTokeniser *st = [[StringTokeniser alloc] initWithString:processedScript];
|
||||
NSMutableDictionary *scriptDict = [[NSMutableDictionary alloc] initWithCapacity:10];
|
||||
NSDictionary *ifDict;
|
||||
NSMutableArray *ifStatements = [[NSMutableArray alloc] init];
|
||||
NSString *scriptName;
|
||||
|
||||
while (st->tokenType != TT_EOS) {
|
||||
[st nextToken];
|
||||
if (st->tokenType == TT_EOL)
|
||||
continue;
|
||||
|
||||
if (st->tokenType == TT_EOS)
|
||||
return;
|
||||
|
||||
scriptName = [NSString stringWithString:st->tokenWord];
|
||||
while (st->tokenType != TT_EOS) {
|
||||
[st nextToken];
|
||||
if (st->tokenType == TT_EOL)
|
||||
continue;
|
||||
|
||||
if ([st->tokenWord isEqual:@"if"] == YES) {
|
||||
[st pushBack];
|
||||
ifDict = parseIf(st);
|
||||
if (ifDict != nil) {
|
||||
[ifStatements addObject:ifDict];
|
||||
}
|
||||
} else {
|
||||
[scriptDict setObject:ifStatements forKey:scriptName];
|
||||
ifStatements = [[NSMutableArray alloc] init];
|
||||
[st pushBack];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
return scriptDict;
|
||||
}
|
||||
|
||||
#ifdef SC_TEST
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
NSAutoreleasePool *arp = [[NSAutoreleasePool alloc] init];
|
||||
NSString *filename = [NSString stringWithCString:argv[1]];
|
||||
|
||||
NSString *script = [NSString stringWithContentsOfFile:filename];
|
||||
NSDictionary *scriptDict = parseScripts(script);
|
||||
[scriptDict writeToFile:@"x.plist" atomically:YES];
|
||||
[arp release];
|
||||
return 0;
|
||||
}
|
||||
#endif
|
45
src/Core/StringTokeniser.h
Normal file
45
src/Core/StringTokeniser.h
Normal file
@ -0,0 +1,45 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#define TT_WORD 1
|
||||
#define TT_EOL 2
|
||||
#define TT_EOS 3
|
||||
|
||||
@interface StringTokeniser : NSObject
|
||||
{
|
||||
@public
|
||||
// A local copy of the string to be parsed
|
||||
NSString* stringToParse;
|
||||
char* cString;
|
||||
|
||||
// The zero based index of the next character to be parsed. 0 <= nextcharIdx < [stringToParse length]
|
||||
int nextCharIdx;
|
||||
|
||||
// The index to go back to when a pushBack is issued
|
||||
int pushBackIdx;
|
||||
|
||||
// Set to one of the TT_* constants after a call to nextToken
|
||||
int tokenType;
|
||||
|
||||
// The line number currently being parsed
|
||||
int lineNo;
|
||||
|
||||
// If tokenType is TT_WORD this contains a reference to the parsed word
|
||||
NSString* tokenWord;
|
||||
char* tokenPtr;
|
||||
}
|
||||
|
||||
// Initialise an instance of the string tokeniser to parse the given string
|
||||
- (id)initWithString:(NSString*)string;
|
||||
- (void) dealloc;
|
||||
|
||||
// Parse the next token and set the tokenType property appropriately
|
||||
- (void)nextToken;
|
||||
|
||||
// Push back the current token so the next call to nextToken returns
|
||||
// the same one
|
||||
- (void)pushBack;
|
||||
|
||||
// Returns true once the entire string has been parsed
|
||||
- (BOOL)reachedEOS;
|
||||
|
||||
@end
|
95
src/Core/StringTokeniser.m
Normal file
95
src/Core/StringTokeniser.m
Normal file
@ -0,0 +1,95 @@
|
||||
#import "StringTokeniser.h"
|
||||
|
||||
@implementation StringTokeniser : NSObject
|
||||
|
||||
// Initialise an instance of the string tokeniser to parse the given string
|
||||
- (id)initWithString:(NSString*)string {
|
||||
const char* strPtr;
|
||||
self = [super init];
|
||||
|
||||
stringToParse = [NSString stringWithString:string];
|
||||
strPtr = [stringToParse cString];
|
||||
cString = (char*)calloc(strlen(strPtr + 1), sizeof(char));
|
||||
strcpy(cString, strPtr);
|
||||
nextCharIdx = 0;
|
||||
lineNo = 1;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) dealloc {
|
||||
if (cString != 0x00)
|
||||
free(cString);
|
||||
|
||||
if (tokenPtr != 0x00)
|
||||
free(tokenPtr);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
// Parse the next token and set the tokenType property appropriately
|
||||
- (void)nextToken {
|
||||
int startWordIdx;
|
||||
int len;
|
||||
|
||||
// Incrementing lineNo here so that errors caused by new lines don't get
|
||||
// reported on the line after the error, as would happen if lineNo was
|
||||
// incremented when the TT_EOL token is returned.
|
||||
if (tokenType == TT_EOL)
|
||||
lineNo++;
|
||||
|
||||
if (nextCharIdx >= [stringToParse length]) {
|
||||
tokenType = TT_EOS;
|
||||
return;
|
||||
}
|
||||
|
||||
// skip whitespace before next word or EOL
|
||||
while (cString[nextCharIdx] == 0x20 || cString[nextCharIdx] == 0x09) {
|
||||
nextCharIdx++;
|
||||
pushBackIdx = nextCharIdx;
|
||||
if (nextCharIdx >= [stringToParse length]) {
|
||||
tokenType = TT_EOS;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cString[nextCharIdx] == 0x0A) {
|
||||
tokenType = TT_EOL;
|
||||
nextCharIdx++;
|
||||
pushBackIdx = nextCharIdx;
|
||||
return;
|
||||
}
|
||||
|
||||
startWordIdx = nextCharIdx;
|
||||
pushBackIdx = nextCharIdx;
|
||||
while (cString[nextCharIdx] != 0x20 && cString[nextCharIdx] != 0x09 && cString[nextCharIdx] != 0x0A) {
|
||||
nextCharIdx++;
|
||||
if (nextCharIdx >= [stringToParse length]) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
len = nextCharIdx - startWordIdx+1;
|
||||
tokenPtr = calloc(len, sizeof(char));
|
||||
strncpy(tokenPtr, &cString[startWordIdx], len-1);
|
||||
tokenWord = [NSString stringWithCString:tokenPtr];
|
||||
free(tokenPtr);
|
||||
tokenPtr = 0x00;
|
||||
tokenType = TT_WORD;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
- (void)pushBack {
|
||||
nextCharIdx = pushBackIdx;
|
||||
}
|
||||
|
||||
// Returns true once the entire string has been parsed
|
||||
- (BOOL)reachedEOS {
|
||||
if (nextCharIdx >= [stringToParse length])
|
||||
return YES;
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
@ -417,6 +417,7 @@ extern int debug;
|
||||
- (NSDictionary *) generateSystemData:(Random_Seed) system_seed;
|
||||
- (NSDictionary *) currentSystemData;
|
||||
- (void) setSystemDataKey:(NSString*) key value:(NSObject*) object;
|
||||
- (void) setSystemDataForGalaxy:(int) gnum planet:(int) pnum key:(NSString*) key value:(NSObject*) object;
|
||||
- (NSString *) getSystemName:(Random_Seed) s_seed;
|
||||
- (NSString *) getSystemInhabitants:(Random_Seed) s_seed;
|
||||
- (NSString *) generateSystemName:(Random_Seed) system_seed;
|
||||
@ -464,6 +465,7 @@ NSComparisonResult comparePrice( id dict1, id dict2, void * context);
|
||||
|
||||
- (NSString *) generateSystemDescription:(Random_Seed) s_seed;
|
||||
- (NSString *) expandDescription:(NSString *) desc forSystem:(Random_Seed)s_seed;
|
||||
- (NSString *) expandDescriptionWithLocals:(NSString *) desc forSystem:(Random_Seed)s_seed withLocalVariables:(NSDictionary *)locals;
|
||||
- (NSString *) getRandomDigrams;
|
||||
|
||||
- (Vector) getWitchspaceExitPosition;
|
||||
|
@ -5321,6 +5321,16 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
[local_overrides setObject:object forKey:key];
|
||||
}
|
||||
|
||||
- (void) setSystemDataForGalaxy:(int) gnum planet:(int) pnum key:(NSString*) key value:(NSObject*) object
|
||||
{
|
||||
NSString* override_key = [NSString stringWithFormat:@"%d %d", gnum, pnum];
|
||||
|
||||
if ([local_planetinfo_overrides objectForKey:override_key] == nil)
|
||||
[local_planetinfo_overrides setObject:[NSMutableDictionary dictionaryWithCapacity:8] forKey:override_key];
|
||||
|
||||
NSMutableDictionary* local_overrides = (NSMutableDictionary*)[local_planetinfo_overrides objectForKey:override_key];
|
||||
[local_overrides setObject:object forKey:key];
|
||||
}
|
||||
|
||||
- (NSString *) getSystemName:(Random_Seed) s_seed
|
||||
{
|
||||
@ -6942,13 +6952,17 @@ NSComparisonResult comparePrice( id dict1, id dict2, void * context)
|
||||
return [self expandDescription:@"[14] is [22]." forSystem:s_seed];
|
||||
}
|
||||
|
||||
- (NSString *) expandDescription:(NSString *) desc forSystem:(Random_Seed)s_seed;
|
||||
- (NSString *) expandDescription:(NSString *) desc forSystem:(Random_Seed)s_seed
|
||||
{
|
||||
return [self expandDescriptionWithLocals:desc forSystem:s_seed withLocalVariables:nil];
|
||||
}
|
||||
|
||||
- (NSString *) expandDescriptionWithLocals:(NSString *) desc forSystem:(Random_Seed)s_seed withLocalVariables:(NSDictionary *)locals
|
||||
{
|
||||
PlayerEntity* player = (PlayerEntity*)[self entityZero];
|
||||
NSMutableString* partial = [NSMutableString stringWithString:desc];
|
||||
NSMutableDictionary* all_descriptions = [NSMutableDictionary dictionaryWithDictionary:descriptions];
|
||||
|
||||
////
|
||||
// add in mission_variables if required
|
||||
if ([desc rangeOfString:@"[mission_"].location != NSNotFound)
|
||||
{
|
||||
@ -6958,10 +6972,16 @@ NSComparisonResult comparePrice( id dict1, id dict2, void * context)
|
||||
while (key = [missVarsEnum nextObject])
|
||||
[all_descriptions setObject:[mission_vars objectForKey:key] forKey:key];
|
||||
}
|
||||
//
|
||||
////
|
||||
|
||||
////
|
||||
// also add the mission-local vars, if they have been passed in
|
||||
if (locals != nil && [desc rangeOfString:@"[local_"].location != NSNotFound)
|
||||
{
|
||||
NSEnumerator* localVarsEnum = [locals keyEnumerator];
|
||||
id key;
|
||||
while (key = [localVarsEnum nextObject])
|
||||
[all_descriptions setObject:[locals objectForKey:key] forKey:key];
|
||||
}
|
||||
|
||||
// add in player info if required
|
||||
if ([desc rangeOfString:@"[commander_"].location != NSNotFound)
|
||||
{
|
||||
@ -6978,8 +6998,6 @@ NSComparisonResult comparePrice( id dict1, id dict2, void * context)
|
||||
int legal_index = 0 + (legal_status <= 50) ? 1 : 2;
|
||||
[all_descriptions setObject:[(NSArray *)[descriptions objectForKey:@"legal_status"] objectAtIndex:legal_index] forKey:@"commander_legal_status"];
|
||||
}
|
||||
//
|
||||
////
|
||||
|
||||
while ([partial rangeOfString:@"["].location != NSNotFound)
|
||||
{
|
||||
@ -7006,6 +7024,14 @@ NSComparisonResult comparePrice( id dict1, id dict2, void * context)
|
||||
part = [all_descriptions objectForKey:middle];
|
||||
}
|
||||
}
|
||||
else if (([middle hasSuffix:@"_number"])||([middle hasSuffix:@"_bool"])||([middle hasSuffix:@"_string"]))
|
||||
{
|
||||
SEL value_selector = NSSelectorFromString(middle);
|
||||
if ([player respondsToSelector:value_selector])
|
||||
{
|
||||
part = [NSString stringWithFormat:@"%@", [player performSelector:value_selector]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// no value for that key so interpret it as a number...
|
||||
@ -7021,7 +7047,6 @@ NSComparisonResult comparePrice( id dict1, id dict2, void * context)
|
||||
|
||||
part = (NSString *)[(NSArray *)[(NSArray *)[all_descriptions objectForKey:@"system_description"] objectAtIndex:sub] objectAtIndex:opt];
|
||||
}
|
||||
|
||||
partial = [NSMutableString stringWithFormat:@"%@%@%@",before,part,after];
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user