This is Human.m in view mode; [Download] [Up]
// // $Id: Human.m,v 1.3 1997/10/31 03:38:30 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: Human.m,v 1.3 1997/10/31 03:38:30 nygard Exp $"); #import "Human.h" #import "Brain.h" #import "City.h" #import "CombatEvent.h" #import "DistributedGameManager.h" #import "EmInspectorManager.h" #import "Map.h" #import "MapPathView.h" #import "Unit.h" #import "WorldMapController.h" #import "HState.h" #import "HCombatReportState.h" #import "HDirectionState.h" #import "HEscortShipState.h" #import "HFlightPathState.h" #import "HIdleState.h" #import "HInitialState.h" #import "HMoveState.h" #import "HMoveToState.h" #import "HPatrolToState.h" #import "HProductionState.h" #import "HSetFlightPathState.h" #import "HSurveyState.h" #import "HGameOverState.h" //====================================================================== @implementation Human - (void) awakeFromNib { NSString *imagePath; NSImage *image; imagePath = [[NSBundle mainBundle] pathForImageResource:@"mwi_map.tiff"]; NSAssert (imagePath != nil, @"Couldn't find mwi_map.tiff"); image = [[[NSImage alloc] initWithContentsOfFile:imagePath] autorelease]; NSAssert (image != nil, @"Couldn't load mwi_map.tiff"); [playerWindow setMiniwindowImage:image]; [self retain]; // Released when window closed } //---------------------------------------------------------------------- - initWithName:(NSString *)aName number:(Player)number world:(Map *)aMap capital:(City *)capitalCity withEfficiencies:(int)pe:(int)ce gameManager:(GameManager *)theGameManager { EMMapLocation cityLocation; NSRect frameRect; BOOL loaded; [super initWithName:aName number:number world:aMap capital:capitalCity withEfficiencies:pe:ce gameManager:theGameManager]; loaded = [NSBundle loadNibNamed:@"Human.nib" owner:self]; NSAssert (loaded == YES, @"Could not load Human.nib"); frameRect = [playerWindow frame]; frameRect.origin.x += number * 24; frameRect.origin.y -= number * 24; [playerWindow setFrameOrigin:frameRect.origin]; [mapView setMap:map]; cityLocation = [capitalCity cityLocation]; [mapView positionCursorAtLocation:cityLocation]; [mapView centerScreenAroundCursor]; [playerWindow makeFirstResponder:mapView]; [playerWindow setTitle:[NSString stringWithFormat:@"Player %d - %@", number, aName]]; [mapView useDefaultCursor]; [mapView setCursorEnabled:YES]; [turnNumberTextfield setIntValue:0]; //[playerWindow setFrame:frameRect display:YES]; [playerWindow orderFront:nil]; state = nil; savedStateKey = nil; selectedUnit = nil; worldMapController = nil; selectedCity = nil; combatEvents = [[NSMutableArray array] retain]; savedMap = nil; stateGroup = [[NSMutableDictionary dictionary] retain]; [stateGroup setObject:[[[HCombatReportState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_COMBAT_REPORT]; [stateGroup setObject:[[[HDirectionState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_DIRECTION]; [stateGroup setObject:[[[HEscortShipState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_ESCORT_SHIP]; [stateGroup setObject:[[[HFlightPathState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_FLIGHT_PATH]; [stateGroup setObject:[[[HIdleState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_IDLE]; [stateGroup setObject:[[[HInitialState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_INITIAL]; [stateGroup setObject:[[[HMoveState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_MOVE]; [stateGroup setObject:[[[HMoveToState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_MOVE_TO]; [stateGroup setObject:[[[HPatrolToState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_PATROL_TO]; [stateGroup setObject:[[[HProductionState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_PRODUCTION]; [stateGroup setObject:[[[HSetFlightPathState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_SET_FLIGHT_PATH]; [stateGroup setObject:[[[HSurveyState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_SURVEY]; [stateGroup setObject:[[[HGameOverState alloc] initWithGameManager:gameManager] autorelease] forKey:HS_GAME_OVER]; [self changeState:HS_IDLE]; return self; } //---------------------------------------------------------------------- - (void) dealloc { SNRelease (worldMapController); SNRelease (savedStateKey); SNRelease (stateGroup); SNRelease (combatEvents); SNRelease (savedMap); [super dealloc]; } //====================================================================== // Turn phases //====================================================================== - (void) yourTurn:(int)turn { [map detach:self]; [super yourTurn:turn]; selectedUnit = nil; [turnNumberTextfield setIntValue:turn]; if ([playerWindow isVisible] == YES) [playerWindow makeKeyAndOrderFront:self]; if (state != nil) [state beginTurn:self]; } //====================================================================== // Interface Management //====================================================================== - (void) continue:sender { if (state != nil) [state continue:self]; } //---------------------------------------------------------------------- - (void) endTurn:sender { if (state != nil) [state endTurn:self]; [combatEvents removeAllObjects]; SNRelease (savedMap); savedMap = [map copyWithZone:[self zone]]; [map attach:self]; } //---------------------------------------------------------------------- - (void) enableContinueButton:(BOOL)flag { if (flag == NO && [playerWindow firstResponder] == continueButton) [playerWindow makeFirstResponder:endTurnButton]; [continueButton setEnabled:flag]; } //---------------------------------------------------------------------- - (void) enableEndTurnButton:(BOOL)flag { [endTurnButton setEnabled:flag]; if (flag == NO && [playerWindow firstResponder] == endTurnButton) [playerWindow makeFirstResponder:mapView]; //[playerWindow makeFirstResponder:continueButton]; } //---------------------------------------------------------------------- // Hmm. Always default to NO, and if super returns NO, run through our checks? - (BOOL) validateMenuItem:(NSMenuItem *)menuCell { SEL action = [menuCell action]; BOOL valid = NO; if (action == @selector (showCrystalBall:) || action == @selector (toggleBerserk:) || action == @selector (stopGame:)) { valid = [super validateMenuItem:menuCell]; } else if (action == @selector (showWarReport:)) { valid = gameOver == NO; } else if (action == @selector (showWorldMap:) || action == @selector (showShipReport:)) { valid = YES; } else if (action == @selector (resignFromGame:)) { valid = YES; } else if (state != nil) { valid = [state validateMenuItem:self:menuCell]; } return valid; } //---------------------------------------------------------------------- - (void) clickActiveButton { if ([endTurnButton isEnabled] == YES) [endTurnButton performClick:nil]; else if ([continueButton isEnabled] == YES) [continueButton performClick:nil]; } //---------------------------------------------------------------------- - (void) setStatusLine:(NSString *)text { if (text != nil) [statusTextfield setStringValue:text]; } //---------------------------------------------------------------------- - (void) selectThing:object { [[EmInspectorManager instance] player:playerNumber selectThing:object]; } //---------------------------------------------------------------------- - (void) selectUnit:(Unit *)aUnit { selectedUnit = aUnit; } //---------------------------------------------------------------------- - (MapView *) mapView { return mapView; } //======================================================================- // Commands //======================================================================- - (void) moveMode:sender { if (state != nil) [state moveMode:self]; } //---------------------------------------------------------------------- - (void) surveyMode:sender { if (state != nil) [state surveyMode:self]; } //---------------------------------------------------------------------- - (void) groupMode:sender { if (state != nil) [state groupMode:self]; } //---------------------------------------------------------------------- - (void) wait:sender { if (state != nil && selectedUnit != nil) [state wait:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) flightPaths:sender { if (state != nil) [state flightPathMode:self]; } //---------------------------------------------------------------------- - (void) activateUnit:sender { if (state != nil && selectedUnit != nil) [state activate:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) centerScreen:sender { if (state != nil) [state centerScreen:self mapView:mapView]; } //---------------------------------------------------------------------- - (void) centerCursor:sender { if (state != nil) [state centerCursor:self mapView:mapView]; } //---------------------------------------------------------------------- - (void) centerSelected:sender { if (state != nil) [state centerSelected:self mapView:mapView]; } //====================================================================== // End of game Reports //====================================================================== - (void) showFinalCombinedMap:sender { if (state != nil) [state showFinalMap:self forPlayer:p_neutral]; } //---------------------------------------------------------------------- - (void) showFinalPlayer1Map:sender { if (state != nil) [state showFinalMap:self forPlayer:p_player1]; } //---------------------------------------------------------------------- - (void) showFinalPlayer2Map:sender { if (state != nil) [state showFinalMap:self forPlayer:p_player2]; } //---------------------------------------------------------------------- - (void) showFinalPlayer3Map:sender { if (state != nil) [state showFinalMap:self forPlayer:p_player3]; } //---------------------------------------------------------------------- - (void) showFinalMapForPlayer:(Player)number { if (finalMaps[number] == nil) return; if (number == p_neutral) [statusTextfield setStringValue:@"Final Combined Map"]; else [statusTextfield setStringValue:[NSString stringWithFormat:@"Final Player %d Map", number]]; // main and world maps... [mapView setMap:finalMaps[number]]; if (worldMapController != nil) { [worldMapController setMap:finalMaps[number]]; } } //======================================================================- // Orders //======================================================================- - (void) goDirection:sender { if (state != nil) [state goDirection:self]; } //---------------------------------------------------------------------- - (void) goHome:sender { if (state != nil && selectedUnit != nil) [state goHome:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) goRandom:sender { if (state != nil && selectedUnit != nil) [state goRandom:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) moveTo:sender { if (state != nil) [state moveTo:self]; } //---------------------------------------------------------------------- - (void) patrolTo:sender { if (state != nil) [state patrolTo:self]; } //---------------------------------------------------------------------- - (void) escortShip:sender { if (state != nil) [state escortShip:self]; } //---------------------------------------------------------------------- - (void) explore:sender { if (state != nil && selectedUnit != nil) [state explore:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) sentry:sender { if (state != nil && selectedUnit != nil) [state sentry:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) clearOrders:sender { if (state != nil) { if (selectedUnit != nil) { [state activate:self unit:selectedUnit]; //[state clearOrders:self unit:selectedUnit]; } else { City *city = [self cityAtLocation:[mapView cursorLocation]]; [state clearOrders:self city:city]; } } } //---------------------------------------------------------------------- - (void) loadShip:sender { if (state != nil && selectedUnit != nil) [state loadShip:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) unloadShip:sender { if (state != nil && selectedUnit != nil) [state unloadShip:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) skipMove:sender { if (state != nil && selectedUnit != nil) [state skipMove:self unit:selectedUnit]; } //---------------------------------------------------------------------- - (void) resignFromGame:sender { NSAssert (gameOver == NO, @"The game is already over."); // Confirm.. [self resign]; } //====================================================================== // Reports //====================================================================== - (void) showCombatReport:sender { if (state != nil) [state combatReport:self]; } //---------------------------------------------------------------------- - (void) showProductionMap:sender { if (state != nil) [state productionMap:self]; } //---------------------------------------------------------------------- - (void) showShipReport:sender { [gameManager showShipReport:sender forPlayer:self]; } //---------------------------------------------------------------------- // We need the game manager to have a world, so that we can get the // worldCityCount for the war report even after the game is over. //---------------------------------------------------------------------- - (void) showWarReport:sender { NSAssert (gameOver == NO, @"The game is over."); [gameManager showWarReport:sender forPlayer:self]; } //---------------------------------------------------------------------- - (void) showWorldMap:sender { if (worldMapController == nil) { worldMapController = [[WorldMapController alloc] init]; [worldMapController setMap:map]; [worldMapController setDelegate:self]; [worldMapController setTitle:[NSString stringWithFormat:@"Player %d World Map", playerNumber] autosaveFrame:YES]; } [worldMapController showPanel]; } //====================================================================== // MapView delegate //====================================================================== - (void) mouseDown:(unsigned int)modifierFlags atLocation:(EMMapLocation)target { if (state != nil) [state mouseDown:self:modifierFlags atLocation:target]; } //---------------------------------------------------------------------- - (void) mouseUp:(unsigned int)modifierFlags atLocation:(EMMapLocation)target { if (state != nil) [state mouseUp:self:modifierFlags atLocation:target]; } //---------------------------------------------------------------------- - (void) rightMouseDown:(unsigned int)modifierFlags atLocation:(EMMapLocation)target { if (state != nil) [state rightMouseDown:self:modifierFlags atLocation:target]; } //---------------------------------------------------------------------- - (void) rightMouseUp:(unsigned int)modifierFlags atLocation:(EMMapLocation)target { if (state != nil) [state rightMouseUp:self:modifierFlags atLocation:target]; } //---------------------------------------------------------------------- - (void) keyDown:(NSEvent *)theEvent { if (state != nil) [state keyDown:self:theEvent]; } //====================================================================== // Window Delegate //====================================================================== - (BOOL) windowShouldClose:sender { BOOL shouldClose = YES; int result; // This may also be the delegate of the world map window. // Only if still connected, running... if (sender == playerWindow && gameOver == NO) { result = NSRunAlertPanel (@"Exit Game", @"Closing this window will end the game for player %d.", @"Keep playing", @"Exit game", nil, playerNumber); shouldClose = result == NSAlertAlternateReturn; if (shouldClose == YES) { // Notify game manager... [self resignFromGame:nil]; } } return shouldClose; } //---------------------------------------------------------------------- - (void) windowWillClose:(NSNotification *)aNotification { NSWindow *window; window = [aNotification object]; if (window == playerWindow) { [self autorelease]; // Important for timing. } } //====================================================================== // End of player //====================================================================== - (void) gameStopped:(int)activePlayers { [super gameStopped:activePlayers]; [self changeState:HS_GAME_OVER]; [self setStatusLine:@"The game has been stopped."]; } //---------------------------------------------------------------------- // Returns YES to continue playing, NO to stop game. // Does this block (whirling disk) the server? //---------------------------------------------------------------------- - (BOOL) playerHasWon:(int)activePlayers { BOOL keepPlaying = YES; int result; result = NSRunAlertPanel (@"Game Over", @"Player %d has won.", @"End Game", @"Continue Moving", nil, playerNumber); if (result == NSAlertDefaultReturn) { [super playerHasWon:activePlayers]; [self changeState:HS_GAME_OVER]; [self setStatusLine:@"You win."]; keepPlaying = NO; } return keepPlaying; } //---------------------------------------------------------------------- - (void) playerHasLost:(int)activePlayers { [super playerHasLost:activePlayers]; [self changeState:HS_GAME_OVER]; [self setStatusLine:@"All your cities have been captured."]; } //---------------------------------------------------------------------- - (void) playerHasResigned:(int)activePlayers { [super playerHasResigned:activePlayers]; [self changeState:HS_GAME_OVER]; [self setStatusLine:@"You have resigned from the game."]; } //====================================================================== // HState Management //====================================================================== - (void) changeState:(NSString *)newStateName { HState *newState; newState = [stateGroup objectForKey:newStateName]; NSAssert1 (newState != nil, @"Couldn't find state '%@' in group.", newStateName); if (state != nil) [state stateExited:self]; state = newState; [modeTextfield setStringValue:[state stateName]]; [state stateEntered:self]; } //---------------------------------------------------------------------- - (void) saveState { // We can only save one state at a time. NSAssert (savedStateKey == nil, @"Saved state not nil."); savedStateKey = [[state stateKey] retain]; } //---------------------------------------------------------------------- - (void) restoreState { NSAssert (savedStateKey != nil, @"Saved state is nil"); [self changeState:savedStateKey]; SNRelease (savedStateKey); } //====================================================================== // HState Access //====================================================================== - (City *) selectedCity { return selectedCity; } //---------------------------------------------------------------------- - (void) selectCity:(City *)city { selectedCity = city; } //---------------------------------------------------------------------- - (Map *) finalMapForPlayer:(Player)number { return finalMaps[number]; } //====================================================================== // Combat Report //====================================================================== - (Map *) savedMap { return savedMap; } //---------------------------------------------------------------------- - (NSArray *) combatEvents { return combatEvents; } //====================================================================== // Map Delegate //====================================================================== //---------------------------------------------------------------------- // The methods record combat events. They are only observed while // other players are playing their turns. //---------------------------------------------------------------------- - (void) refreshLocation:(EMMapLocation)target { [combatEvents addObject:[CombatEvent updateAtLocation:target ofMap:map]]; } //---------------------------------------------------------------------- - (void) refresh3x3Location:(EMMapLocation)target { [combatEvents addObject:[CombatEvent update3x3AroundLocation:target ofMap:map]]; } //---------------------------------------------------------------------- - (void) strippedIconsOfPlayer:(Player)number { [combatEvents addObject:[CombatEvent stripIconsOfPlayer:number]]; } //====================================================================== // Other //====================================================================== - (void) showExplosions:(int)count atLocation:(EMMapLocation)target { [super showExplosions:count atLocation:target]; [mapView showExplosions:count atLocation:target]; } //====================================================================== // Subclass Notifications //====================================================================== - (void) selectedUnitTriedToMove:(MoveResult)moveResult { [super selectedUnitTriedToMove:moveResult]; if (moveResult == mr_moved || moveResult == mr_victory) { [mapView setCursorEnabled:NO]; [mapView positionCursorAtLocation:[selectedUnit unitLocation]]; [mapView setCursorEnabled:YES]; } else if (moveResult == mr_destroyed) { [mapView setCursorEnabled:NO]; } else if (moveResult == mr_blocked) { [mapView setFastCursor:YES]; } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.