This is NewGameController.m in view mode; [Download] [Up]
//
// $Id: NewGameController.m,v 1.11 1997/10/31 04:51:57 nygard Exp $
//
//
// 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: NewGameController.m,v 1.11 1997/10/31 04:51:57 nygard Exp $");
#import "NewGameController.h"
#import "EmpireImageVendor.h"
#import "Human.subproj/Human.h"
#import "Client.h"
#import "Brain.h"
#import "ServerController.h"
#import "DistributedGameManager.h"
//======================================================================
// The New Game Controller provides access to the panel for selecting
// the parameters of a new game. It's creates the game manager for a
// new game, and instructs it on the type and parameters of players
// to add to the game.
//
// Also, it provides a window for clients to select the parameters of
// their player in distributed games.
//
// The controller observes the server controller so it can update the
// list of available remote hosts.
//
// It will also need to know the type of computer players that are
// available.
//======================================================================
@implementation NewGameController
- (void) awakeFromNib
{
int l;
EmpireImageVendor *vendor;
NSImage *city;
NSImage **onLand;
NSImage **onWater;
NSImage **onCity;
int loop_to_land[2] = {0, 2};
int loop_to_water[7] = {1, 3, 4, 5, 6, 8, 9};
NSString *resourcePath, *mapName;
NSBundle *bundle;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *tmp;
vendor = [EmpireImageVendor instance];
[vendor player:p_player1:&city:&onLand:&onWater:&onCity:NULL];
[[player1UnitImageMatrix cellAtRow:0 column:0] setImage:city];
for (l = 0; l < 2; l++)
[[player1UnitImageMatrix cellAtRow:0 column:l+1] setImage:onLand[loop_to_land[l]]];
for (l = 0; l < 7; l++)
[[player1UnitImageMatrix cellAtRow:0 column:l+3] setImage:onWater[loop_to_water[l]]];
[vendor player:p_player2:&city:&onLand:&onWater:&onCity:NULL];
[[player2UnitImageMatrix cellAtRow:0 column:0] setImage:city];
for (l = 0; l < 2; l++)
[[player2UnitImageMatrix cellAtRow:0 column:l+1] setImage:onLand[loop_to_land[l]]];
for (l = 0; l < 7; l++)
[[player2UnitImageMatrix cellAtRow:0 column:l+3] setImage:onWater[loop_to_water[l]]];
[vendor player:p_player3:&city:&onLand:&onWater:&onCity:NULL];
[[player3UnitImageMatrix cellAtRow:0 column:0] setImage:city];
for (l = 0; l < 2; l++)
[[player3UnitImageMatrix cellAtRow:0 column:l+1] setImage:onLand[loop_to_land[l]]];
for (l = 0; l < 7; l++)
[[player3UnitImageMatrix cellAtRow:0 column:l+3] setImage:onWater[loop_to_water[l]]];
[vendor attach:self];
[player1ColorWell setColor:[vendor colorForPlayer:p_player1]];
[player2ColorWell setColor:[vendor colorForPlayer:p_player2]];
[player3ColorWell setColor:[vendor colorForPlayer:p_player3]];
bundle = [NSBundle bundleForClass:[self class]];
mapName = [defaults stringForKey:DK_DefaultMap];
resourcePath = [bundle pathForResource:mapName ofType:@"map"];
NSAssert1 (resourcePath != nil, @"Could not find %@.", mapName);
[mapTextfield setStringValue:resourcePath];
tmp = [defaults stringForKey:DK_DefaultPlayer1Type];
[player1TypePopup selectItemWithTitle:tmp];
tmp = [defaults stringForKey:DK_DefaultPlayer2Type];
[player2TypePopup selectItemWithTitle:tmp];
tmp = [defaults stringForKey:DK_DefaultPlayer3Type];
[player3TypePopup selectItemWithTitle:tmp];
tmp = [defaults stringForKey:DK_DefaultPlayer1Name];
[player1NameTextfield setStringValue:tmp];
tmp = [defaults stringForKey:DK_DefaultPlayer2Name];
[player2NameTextfield setStringValue:tmp];
tmp = [defaults stringForKey:DK_DefaultPlayer3Name];
[player3NameTextfield setStringValue:tmp];
}
//----------------------------------------------------------------------
- initWithBrain:(Brain *)theBrain
{
NSString *nibFile;
BOOL loaded;
[super init];
clientGameManager = nil;
nibFile = @"NewGamePanel.nib";
loaded = [NSBundle loadNibNamed:nibFile owner:self];
if (loaded == NO)
{
NSLog (@"Could not load %@.", nibFile);
[super dealloc];
return nil;
}
serverController = [theBrain serverController];
if (serverController != nil)
{
[serverController attach:self];
}
return self;
}
//----------------------------------------------------------------------
- (void) dealloc
{
SNRelease (clientGameManager);
[super dealloc];
}
//----------------------------------------------------------------------
- (void) updatePlayer1Color:sender
{
[[EmpireImageVendor instance] setColor:[player1ColorWell color] forPlayer:p_player1];
}
//----------------------------------------------------------------------
- (void) updatePlayer2Color:sender
{
[[EmpireImageVendor instance] setColor:[player2ColorWell color] forPlayer:p_player2];
}
//----------------------------------------------------------------------
- (void) updatePlayer3Color:sender
{
[[EmpireImageVendor instance] setColor:[player3ColorWell color] forPlayer:p_player3];
}
//----------------------------------------------------------------------
- (void) createNewGame:sender
{
int playerCount;
DistributedGameManager *gameManager;
BOOL ps[3];
Client *remoteClient;
int remoteClientIndex;
int l, m;
struct {
int player;
NSTextField *nameText;
NSSlider *productionEffSlider;
NSSlider *combatEffSlider;
NSPopUpButton *remoteClientPopup;
} player_things[] = {
{ p_player1, player1NameTextfield, player1ProductionEffSlider,
player1CombatEffSlider, player1RemoteClientPopup },
{ p_player2, player2NameTextfield, player2ProductionEffSlider,
player2CombatEffSlider, player2RemoteClientPopup },
{ p_player3, player3NameTextfield, player3ProductionEffSlider,
player3CombatEffSlider, player3RemoteClientPopup }
};
#if 0
// Check whether there is a game in progress
if ([gameManager gameInProgress] == YES)
{
if (NSRunAlertPanel (@"New Game", @"There is already a game in progress or starting.", @"Cancel", @"Start new game", nil) == NSAlertDefaultReturn)
{
return;
}
[gameManager stopGame];
}
#endif
// Count the number of participating players
ps[0] = [[player1TypePopup selectedItem] tag]; // Why not use indexOfSelectedItem?
ps[1] = [[player2TypePopup selectedItem] tag];
ps[2] = [[player3TypePopup selectedItem] tag];
playerCount = ((ps[0] > 0) ? 1 : 0) + ((ps[1] > 0) ? 1 : 0) + ((ps[2] > 0) ? 1 : 0);
if (playerCount < 1)
{
NSRunAlertPanel (@"New Game", @"There must be at least one player.", @"", nil, nil);
return;
}
for (l = 0; l < 3; l++)
{
if (ps[l] == 3)
{
NSPopUpButton *rc_popup = player_things[l].remoteClientPopup;
remoteClientIndex = [rc_popup indexOfSelectedItem];
if (remoteClientIndex < 1)
{
NSRunAlertPanel (@"New Game", @"You must select a client for the Remote player %d.", @"", nil, nil, l);
return;
}
}
}
for (l = 0; l < 3; l++)
{
if (ps[l] == 3)
{
remoteClientIndex = [player_things[l].remoteClientPopup indexOfSelectedItem];
for (m = l + 1; m < 3; m++)
{
if (ps[l] == 3 && [player_things[m].remoteClientPopup indexOfSelectedItem] == remoteClientIndex)
{
NSRunAlertPanel (@"New Game", @"Remote players %d and %d must have different clients.",
@"", nil, nil, l + 1, m + 1);
return;
}
}
}
}
gameManager = [[[DistributedGameManager alloc] init] autorelease];
// Start a new game with the given map name
[gameManager startGameWithMapNamed:[mapTextfield stringValue]];
[[sender window] orderOut:self];
for (l = 0; l < 3; l++)
{
int pn = player_things[l].player;
NSString *name = [player_things[l].nameText stringValue];
int pe = [player_things[l].productionEffSlider intValue];
int ce = [player_things[l].combatEffSlider intValue];
NSPopUpButton *rc_popup = player_things[l].remoteClientPopup;
switch (ps[l])
{
case 0:
break;
case 1:
[gameManager addPlayer:pn name:name type:@"Human"
withEfficiencies:pe:ce];
break;
case 3:
remoteClientIndex = [rc_popup indexOfSelectedItem];
NSAssert (remoteClientIndex > 0, @"No remote player chosen!");
//NSLog (@"remote player[%d]: '%@'\n", remoteClientIndex, [rc_popup titleOfSelectedItem]);
remoteClient = [[serverController clientAtIndex:remoteClientIndex - 1] client];
[gameManager addRemotePlayer:pn forClient:remoteClient];
break;
default:
NSLog (@"Unknown player type #%d", ps[l]);
}
}
// Begin game
[gameManager beginGame];
}
//----------------------------------------------------------------------
- (void) aboutPlayer1:sender
{
[NSApp runModalForWindow:aboutPanel];
}
//----------------------------------------------------------------------
- (void) aboutPlayer2:sender
{
[NSApp runModalForWindow:aboutPanel];
}
//----------------------------------------------------------------------
- (void) aboutPlayer3:sender
{
[NSApp runModalForWindow:aboutPanel];
}
//----------------------------------------------------------------------
- (void) aboutStopAction:sender
{
[NSApp stopModal];
[aboutPanel orderOut:self];
}
//----------------------------------------------------------------------
- (void) setMapPanel:sender
{
NSArray *types = [NSArray arrayWithObject:@"map"];
NSOpenPanel *openPanel = [NSOpenPanel openPanel];
[openPanel setAllowsMultipleSelection:NO];
if ([openPanel runModalForTypes:types] == NSOKButton)
{
[mapTextfield setStringValue:[openPanel filename]];
}
}
//----------------------------------------------------------------------
- (void) showPanel
{
[newGamePanel makeKeyAndOrderFront:self];
}
//----------------------------------------------------------------------
- (void) choosePlayer:(Player)number forGameManager:(DistributedGameManager *)gameManager
{
int l;
EmpireImageVendor *vendor;
NSImage *city;
NSImage **onLand;
NSImage **onWater;
NSImage **onCity;
int loop_to_land[2] = {0, 2};
int loop_to_water[7] = {1, 3, 4, 5, 6, 8, 9};
id nameTexts[] = { player1NameTextfield, player2NameTextfield, player3NameTextfield };
NSRect frameRect;
NSAssert (clientGameManager == nil, @"Expected client game manager to be nil.");
clientGameManager = [gameManager retain];
ncPlayerNumber = number;
frameRect = [newClientPanel frame];
frameRect.origin.x += number * 24;
frameRect.origin.y -= number * 24;
[newClientPanel setFrameOrigin:frameRect.origin];
[ncPlayerBox setTitle:[NSString stringWithFormat:@"Player %d", number]];
vendor = [EmpireImageVendor instance];
[vendor player:number:&city:&onLand:&onWater:&onCity:NULL];
[[ncUnitImageMatrix cellAtRow:0 column:0] setImage:city];
for (l = 0; l < 2; l++)
[[ncUnitImageMatrix cellAtRow:0 column:l+1] setImage:onLand[loop_to_land[l]]];
for (l = 0; l < 7; l++)
[[ncUnitImageMatrix cellAtRow:0 column:l+3] setImage:onWater[loop_to_water[l]]];
[ncColorWell setColor:[vendor colorForPlayer:number]];
[ncNameTextfield takeStringValueFrom:nameTexts[number - p_player1]];
[newClientPanel makeKeyAndOrderFront:self];
}
//----------------------------------------------------------------------
- (void) createNewClient:sender
{
int playerType = [[ncTypePopup selectedItem] tag];
int pn;
NSString *name;
int pe;
int ce;
NSAssert (clientGameManager != nil, @"Expected a client game manager to exist.");
[newClientPanel orderOut:self];
pn = ncPlayerNumber;
name = [ncNameTextfield stringValue];
pe = [ncProductionEffSlider intValue];
ce = [ncCombatEffSlider intValue];
switch (playerType)
{
case 0:
break;
case 1:
[clientGameManager addPlayer:pn name:name type:@"Human"
withEfficiencies:pe:ce];
break;
default:
NSLog (@"Unknown player type #%d", playerType);
}
[clientGameManager notifyMasterForPlayer:pn];
SNRelease (clientGameManager);
}
//======================================================================
// Empire Image Vendor Notification
//======================================================================
- (void) vendorImagesUpdated:(BOOL)player1:(BOOL)player2:(BOOL)player3:(BOOL)other
{
if (player1)
[player1UnitImageMatrix setNeedsDisplay:YES];
if (player2)
[player2UnitImageMatrix setNeedsDisplay:YES];
if (player3)
[player3UnitImageMatrix setNeedsDisplay:YES];
}
//======================================================================
// Window Delegate
//======================================================================
- (void) windowDidBecomeKey:(NSNotification *)notification
{
NSWindow *theWindow = [notification object];
if (theWindow == newGamePanel)
{
[theWindow makeFirstResponder:okayButton];
}
}
//======================================================================
// Client Host Notification
//======================================================================
- (void) newClientHost:(NSString *)hostname
{
[player1RemoteClientPopup addItemWithTitle:hostname];
[player2RemoteClientPopup addItemWithTitle:hostname];
[player3RemoteClientPopup addItemWithTitle:hostname];
}
//----------------------------------------------------------------------
- (void) removedClientHostNumber:(int)index
{
[player1RemoteClientPopup removeItemAtIndex:index + 1];
[player2RemoteClientPopup removeItemAtIndex:index + 1];
[player3RemoteClientPopup removeItemAtIndex:index + 1];
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.