This is Brain.m in view mode; [Download] [Up]
//
// This file is a part of Empire, a game of exploration and conquest.
// Copyright (C) 1996 Steve Nygard
//
// 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., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// You may contact the author by:
// e-mail: nygard@telusplanet.net
//
#import "Empire.h"
RCSID ("$Id: Brain.m,v 1.17 1997/10/31 04:51:32 nygard Exp $");
#import "Brain.h"
#import "DistributedGameManager.h"
#import "Map.h"
#import "MapView.h"
#import "EmPlayer.h"
#import "ClientController.h"
#import "ServerController.h"
#import "EditorController.h"
#import "NewGameController.h"
#import "EmInspectorManager.h"
#define LIBRARY_SUBPATH @"Empire"
#define MODULE_EXTENSION @"eplayer"
@interface NSConnection (PrivateMethods)
+ (void) _enableLogging:(char)fp16;
+ (void) _toggleLogging;
@end
//======================================================================
// The Brain is the application delegate, and does things that
// don't fit anywhere else.
//======================================================================
static Brain *_instance = nil;
#define Brain_VERSION 1
@implementation Brain
+ (void) initialize
{
NSUserDefaults *defaults;
NSMutableDictionary *empireDefaults;
if (self == [Brain class])
{
[self setVersion:Brain_VERSION];
defaults = [NSUserDefaults standardUserDefaults];
empireDefaults = [NSMutableDictionary dictionary];
[empireDefaults setObject:@"NO" forKey:DK_DMakeActive];
[empireDefaults setObject:@"default" forKey:DK_DefaultMap];
[empireDefaults setObject:@"None" forKey:DK_DefaultPlayer1Type];
[empireDefaults setObject:@"None" forKey:DK_DefaultPlayer2Type];
[empireDefaults setObject:@"None" forKey:DK_DefaultPlayer3Type];
[empireDefaults setObject:@"Larry" forKey:DK_DefaultPlayer1Name];
[empireDefaults setObject:@"Curly" forKey:DK_DefaultPlayer2Name];
[empireDefaults setObject:@"Moe" forKey:DK_DefaultPlayer3Name];
[empireDefaults setObject:@"80" forKey:DK_MapWidth];
[empireDefaults setObject:@"50" forKey:DK_MapHeight];
[empireDefaults setObject:@"0.5" forKey:DK_CombatEventDelay];
[empireDefaults setObject:@"NO" forKey:DK_DebugCombatEvents];
[empireDefaults setObject:@"YES" forKey:DK_SeedRandom];
[defaults registerDefaults:empireDefaults];
}
}
//----------------------------------------------------------------------
+ (Brain *) instance
{
if (_instance == nil)
_instance = [[Brain alloc] init];
return _instance;
}
//----------------------------------------------------------------------
- init
{
// This is somewhat of a hack.
NSAssert (_instance == nil, @"Allocated more than one brain.");
_instance = self;
empirePlayerBundles = [[NSMutableArray array] retain];
return self;
}
//----------------------------------------------------------------------
- (void) dealloc
{
SNRelease (empirePlayerBundles);
SNRelease (clientController);
SNRelease (serverController);
SNRelease (editorController);
SNRelease (newGameController);
[super dealloc];
}
//======================================================================
// Interface Managment
//======================================================================
- (void) showInfoPanel:sender
{
if (infoPanel == nil)
{
BOOL loaded = [NSBundle loadNibNamed:@"InfoPanel.nib" owner:self];
NSAssert (loaded == YES, @"Could not load InfoPanel.nib");
[versionTextfield setStringValue:EMPIRE_VERSION];
}
[infoPanel makeKeyAndOrderFront:nil];
}
//----------------------------------------------------------------------
- (void) newGame:sender
{
if (newGameController == nil)
newGameController = [[NewGameController alloc] initWithBrain:self];
[newGameController showPanel];
}
//----------------------------------------------------------------------
- (void) startServer:sender
{
if (serverController == nil)
serverController = [[ServerController alloc] init];
[serverController showPanel];
}
//----------------------------------------------------------------------
- (void) startClient:sender
{
if (clientController == nil)
clientController = [[ClientController alloc] initWithBrain:self];
[clientController showPanel];
}
//----------------------------------------------------------------------
- (void) newMap:sender
{
if (editorController == nil)
editorController = [[EditorController alloc] init];
[editorController newMap];
}
//----------------------------------------------------------------------
- (void) open:sender
{
if (editorController == nil)
editorController = [[EditorController alloc] init];
[editorController open:sender];
}
//----------------------------------------------------------------------
- (NewGameController *) newGameController
{
if (newGameController == nil)
newGameController = [[NewGameController alloc] initWithBrain:self];
return newGameController;
}
//----------------------------------------------------------------------
- (ServerController *) serverController
{
if (serverController == nil)
serverController = [[ServerController alloc] init];
return serverController;
}
//----------------------------------------------------------------------
- (BOOL) validateMenuItem:(NSMenuItem *)menuCell
{
SEL action = [menuCell action];
BOOL valid = NO;
if (action == @selector (open:)
|| action == @selector (newMap:)
|| action == @selector (newGame:)
|| action == @selector (startServer:)
|| action == @selector (startClient:)
|| action == @selector (showInfoPanel:))
{
valid = YES;
}
else if (action == @selector (toggleBerserk:)
|| action == @selector (showCrystalBall:)
|| action == @selector (stopGame:))
{
id responder = [NSApp targetForAction:@selector (gameManager)];
GameManager *gameManager;
if (responder != nil)
{
gameManager = [responder gameManager];
valid = [gameManager validateMenuItem:menuCell];
}
//NSLog (@"validating: %@, valid: %@", NSStringFromSelector (action), valid == YES ? @"Yes" : @"No");
//NSLog (@"Responder was: %@", responder);
}
//NSLog (@"validating: %@, valid: %@", NSStringFromSelector (action), valid == YES ? @"Yes" : @"No");
return valid;
}
//----------------------------------------------------------------------
// The player bundle code comes from Risk...
//----------------------------------------------------------------------
- (void) loadEmpirePlayerBundles
{
NSBundle *mainBundle;
NSMutableSet *loadedEmpirePlayerNames;
NSMutableSet *delayedEmpirePlayerPaths;
NSMutableSet *tempPlayerNames;
NSArray *resourcePaths;
NSEnumerator *pathEnumerator;
NSBundle *playerBundle;
BOOL keepTrying;
NSMutableDictionary *loadedBundles;
NSString *path;
mainBundle = [NSBundle mainBundle];
loadedEmpirePlayerNames = [NSMutableSet set];
delayedEmpirePlayerPaths = [NSMutableSet set];
tempPlayerNames = [NSMutableSet set];
loadedBundles = [NSMutableDictionary dictionary];
resourcePaths = [mainBundle pathsForResourcesOfType:@"empireplayer" inDirectory:nil];
//NSLog (@"resource paths: %@", resourcePaths);
pathEnumerator = [resourcePaths objectEnumerator];
while (path = [pathEnumerator nextObject])
{
NSString *str = [[path lastPathComponent] stringByDeletingPathExtension];
// refuse to load if the name matches a module already loaded
if ([loadedEmpirePlayerNames containsObject:str] == NO)
{
// OK, all is well -- go load the little bugger
//NSLog (@"Load empire player bundle %@", path);
playerBundle = [NSBundle bundleWithPath:path];
if ([playerBundle principalClass] == nil)
{
// Ugh, failed. Put the class name in tempStorage in case
// it can't be loaded because it's a subclass of another
// CP who hasn't been loaded yet.
[delayedEmpirePlayerPaths addObject:path];
}
else
{
// it loaded so add it to the list.
[loadedBundles setObject:playerBundle forKey:str];
//NSLog (@"str: %@, playerBundle: %@", str, playerBundle);
//NSLog (@"priciple class is %@", [playerBundle principalClass]);
[loadedEmpirePlayerNames addObject:str];
}
}
}
// now loop and keep trying to load the ones in tempStorage. Keep trying
// as long as at least one of the failed ones succeeds each time through
// the loop
do
{
keepTrying = NO;
pathEnumerator = [delayedEmpirePlayerPaths objectEnumerator];
while (path = [pathEnumerator nextObject])
{
playerBundle = [NSBundle bundleWithPath:path];
if ([playerBundle principalClass] != nil)
{
NSString *str = [[path lastPathComponent] stringByDeletingPathExtension];
[loadedBundles setObject:playerBundle forKey:str];
//NSLog (@"str: %@, playerBundle: %@", str, playerBundle);
//NSLog (@"(delayed) priciple class is %@", [playerBundle principalClass]);
keepTrying = YES;
[tempPlayerNames addObject:path];
[loadedEmpirePlayerNames addObject:str];
}
}
[delayedEmpirePlayerPaths minusSet:tempPlayerNames];
[tempPlayerNames removeAllObjects];
}
while (keepTrying == YES);
// now cpNameStorage contains a list of all the menu strings.
// we must add them to the menus in the panel.
//NSLog (@"info: %@", [testBundle infoDictionary]);
[empirePlayerBundles addObjectsFromArray:[loadedBundles allValues]];
}
//----------------------------------------------------------------------
- (NSArray *) empirePlayerBundles
{
return empirePlayerBundles;
}
//----------------------------------------------------------------------
// Just testing this...
- (void) bundleLoaded:(NSNotification *)aNotification
{
NSDictionary *userInfo = [aNotification userInfo];
NSArray *loadedClasses = [userInfo objectForKey:@"NSLoadedClasses"];
NSEnumerator *enumerator = [loadedClasses objectEnumerator];
id object;
while (object = [enumerator nextObject])
{
//NSLog (@"Loaded class '%@'\n", NSStringFromClass ([object class]));
}
}
//======================================================================
// Application Delegate
//======================================================================
- (void) applicationDidFinishLaunching:(NSNotification *)notification
{
NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
EmInspectorManager *inspectorManager;
BOOL flag;
// Cause the Inspector Manager to load its panel.
inspectorManager = [EmInspectorManager instance];
[inspectorManager player:p_neutral selectThing:nil];
[inspectorManager showPanel];
[self loadEmpirePlayerBundles];
flag = [defaults boolForKey:DK_DMakeActive];
if (flag == YES)
{
[NSApp activateIgnoringOtherApps:YES];
}
[defaultCenter addObserver:self
selector:@selector (bundleLoaded:)
name:NSBundleDidLoadNotification
object:NSApp];
}
//======================================================================
// GameManager first responder chaining
//======================================================================
//----------------------------------------------------------------------
// We need to do this so that these commands are available while the
// player windows are key.
//----------------------------------------------------------------------
- (void) toggleBerserk:sender
{
id responder = [NSApp targetForAction:@selector (gameManager)];
GameManager *gameManager;
if (responder != nil)
{
gameManager = [responder gameManager];
[gameManager toggleBerserk:sender];
}
}
//----------------------------------------------------------------------
- (void) showCrystalBall:sender
{
id responder = [NSApp targetForAction:@selector (gameManager)];
GameManager *gameManager;
if (responder != nil)
{
gameManager = [responder gameManager];
[gameManager showCrystalBall:sender];
}
}
//----------------------------------------------------------------------
- (void) stopGame:sender
{
id responder = [NSApp targetForAction:@selector (gameManager)];
GameManager *gameManager;
if (responder != nil)
{
gameManager = [responder gameManager];
[gameManager stopGame];
}
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.