This is HSurveyState.m in view mode; [Download] [Up]
// // $Id: HSurveyState.m,v 1.3 1997/10/31 03:38:28 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: HSurveyState.m,v 1.3 1997/10/31 03:38:28 nygard Exp $"); #import "HSurveyState.h" #import "City.h" #import "GameManager.h" #import "HCombatReportState.h" #import "HDirectionState.h" #import "HEscortShipState.h" #import "HFlightPathState.h" #import "HIdleState.h" #import "HMoveState.h" #import "HMoveToState.h" #import "HPatrolToState.h" #import "HProductionState.h" #import "Human.h" #import "Map.h" #import "MapView.h" #import "Unit.h" #import "../Orders.subproj/Orders.h" //====================================================================== // This state gives the user another chance to change commands of // units before the turn ends. The user can give them orders which will // be executed on the next turn. //====================================================================== @implementation HSurveyState - initWithGameManager:(GameManager *)theGameManager { [super initWithGameManager:theGameManager]; draggingFromUnit = NO; return self; } //====================================================================== // Subclass responsibilities //====================================================================== - (NSString *) stateName { return @"Survey"; } //---------------------------------------------------------------------- - (NSString *) stateKey { return HS_SURVEY; } //---------------------------------------------------------------------- - (void) stateEntered:(Human *)context { MapView *mapView = [context mapView]; EMMapLocation cursorLocation; draggingFromUnit = NO; [mapView enableCompressedEvents:YES]; [mapView useDefaultCursor]; [mapView setFastCursor:NO]; [mapView setCursorEnabled:YES]; [context setStatusLine:@""]; // Disable both buttons [context enableContinueButton:NO]; if ([context nextUnitAwaitingMovement] == nil) // clears selected unit.. { [context enableEndTurnButton:YES]; if ([gameManager isBerserk] == YES) { [self endTurn:context]; } else { cursorLocation = [mapView cursorLocation]; [self selectThing:context atLocation:cursorLocation andInspect:YES]; } } else { [context enableEndTurnButton:NO]; //[context selectUnit:[context nextUnit]]; cursorLocation = [mapView cursorLocation]; [self selectThing:context atLocation:cursorLocation andInspect:YES]; [context setStatusLine:[[context selectedUnit] statusLine]]; } } //---------------------------------------------------------------------- - (void) endTurn:(Human *)context { // Should this be executed when we enter the idle state? // I don't think so -- we "enter" the idle state upon startup, but // don't want to execute this code. [context turnDone]; [context changeState:HS_IDLE]; } //---------------------------------------------------------------------- - (void) combatReport:(Human *)context { [context saveState]; [context changeState:HS_COMBAT_REPORT]; } //---------------------------------------------------------------------- // This is a bit unusual: You can select nothing, drag over a unit, and // it will enter the MoveTo state... - (void) mouseDown:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target { Map *map = [context map]; MapToken mapToken = [map tokenAtLocation:target]; Unit *unit; EMMapLocation unitLocation; Player player; Icon icon; BOOL explored; [[context mapView] positionCursorAtLocation:target]; //[context selectUnit:nil]; EMMapTokenComponents (mapToken, NULL, &player, &icon, &explored); if (draggingFromUnit == NO && player == [context playerNumber] && icon != i_none && explored == YES) { unit = [context unitWithType:EMConvertIconToUnitType (icon) atLocation:target]; if (unit != nil) { [context selectUnit:unit]; [context setStatusLine:[unit statusLine]]; draggingFromUnit = YES; } } else { [context setStatusLine:[NSString stringWithFormat:@"Loc: %d,%d", target.row, target.column]]; unit = [context selectedUnit]; unitLocation = [unit unitLocation]; if (draggingFromUnit == YES && unit != nil && (target.row != unitLocation.row || target.column != unitLocation.column)) { [context saveState]; if ((modifierFlags & NSControlKeyMask) != 0) [context changeState:HS_PATROL_TO]; else [context changeState:HS_MOVE_TO]; } } } //---------------------------------------------------------------------- - (void) mouseUp:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target { [self selectThing:context atLocation:target andInspect:YES]; draggingFromUnit = NO; } //---------------------------------------------------------------------- - (void) rightMouseUp:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target { [self moveMode:context]; } //---------------------------------------------------------------------- - (void) keyDown:(Human *)context:(NSEvent *)theEvent { NSString *eventCharacters = [theEvent characters]; unichar uc = [eventCharacters characterAtIndex:0]; // I'm going to assume that this is okay, because the alternatives // seem worse. switch (uc) { case '5': case 'c': case 'C': [context centerScreen:nil]; break; case 'd': case 'D': [context goDirection:nil]; break; case 'e': case 'E': [context escortShip:nil]; break; case 'h': case 'H': [context goHome:nil]; break; case 'l': case 'L': [context loadShip:nil]; break; case 'm': case 'M': [self moveMode:context]; break; case 'o': case 'O': // Can clear orders for city too. //[context activateUnit:nil]; [context clearOrders:nil]; break; case 'p': case 'P': [self patrolTo:context]; break; case 'r': case 'R': [context goRandom:nil]; break; case 'S': case 's': [context sentry:nil]; break; case 't': case 'T': [context moveTo:nil]; break; case 'u': case 'U': [context unloadShip:nil]; break; case 'x': case 'X': [context explore:nil]; break; case 3: // This is the Enter key on the number pad... at least, on my machine. [context clickActiveButton]; break; default: [super keyDown:context:theEvent]; break; } } //====================================================================== // Commands //====================================================================== - (void) moveMode:(Human *)context { if ([context nextUnitAwaitingMovement] != nil) [context changeState:HS_MOVE]; } //---------------------------------------------------------------------- - (void) flightPathMode:(Human *)context { [context saveState]; [context changeState:HS_FLIGHT_PATH]; } //---------------------------------------------------------------------- - (void) activate:(Human *)context unit:(Unit *)aUnit { [self clearOrders:context unit:aUnit]; [context activateThisUnit:aUnit]; [self moveMode:context]; } //---------------------------------------------------------------------- - (void) centerScreen:(Human *)context mapView:(MapView *)mapView { [mapView centerScreenAroundCursor]; } //---------------------------------------------------------------------- - (void) productionMap:(Human *)context { [context saveState]; [context changeState:HS_PRODUCTION]; } //====================================================================== // Orders //====================================================================== - (void) goDirection:(Human *)context { [context saveState]; [context changeState:HS_DIRECTION]; } //---------------------------------------------------------------------- - (void) goHome:(Human *)context unit:(Unit *)aUnit { City *target_city; // Find nearest city. target_city = [context ourCityNearestToLocation:[aUnit unitLocation]]; if (target_city != nil) { Order *order; // Set orders to move to that coordinate. order = [[[OShortestMoveTo alloc] initForUnit:aUnit moveToLocation:[target_city cityLocation] onMap:[context map]] autorelease]; [aUnit setOrder:order]; [context setStatusLine:[aUnit statusLine]]; } } //---------------------------------------------------------------------- - (void) goRandom:(Human *)context unit:(Unit *)aUnit { [aUnit setOrder:[[[ORandom alloc] initForUnit:aUnit] autorelease]]; [context setStatusLine:[aUnit statusLine]]; } //---------------------------------------------------------------------- - (void) escortShip:(Human *)context { [context saveState]; [context changeState:HS_ESCORT_SHIP]; } //---------------------------------------------------------------------- - (void) moveTo:(Human *)context { [context saveState]; [context changeState:HS_MOVE_TO]; } //---------------------------------------------------------------------- - (void) patrolTo:(Human *)context { [context saveState]; [context changeState:HS_PATROL_TO]; } //---------------------------------------------------------------------- - (void) explore:(Human *)context unit:(Unit *)unit { [unit setOrder:[[[OExplore alloc] initForUnit:unit explore:[context map]] autorelease]]; [self continueWithContext:context]; } //---------------------------------------------------------------------- - (void) sentry:(Human *)context unit:(Unit *)aUnit { [aUnit setOrder:[[[OSentry alloc] initForUnit:aUnit] autorelease]]; [context setStatusLine:[aUnit statusLine]]; } //---------------------------------------------------------------------- - (void) clearOrders:(Human *)context unit:(Unit *)aUnit { [aUnit setOrder:nil]; [context setStatusLine:[aUnit statusLine]]; } //---------------------------------------------------------------------- // Clear orders, but don't activate units (i.e. do not put in the // units awaiting movement list, even if they can move.) //---------------------------------------------------------------------- - (void) clearOrders:(Human *)context city:(City *)aCity { NSEnumerator *unitEnumerator = [[aCity cityUnits] objectEnumerator]; int count = 0; Unit *unit; while (unit = [unitEnumerator nextObject]) { count++; [unit setOrder:nil]; } [context setStatusLine:[NSString stringWithFormat:@"Orders cleared for %d unit%@.", count, (count == 1) ? @"" : @"s"]]; } //---------------------------------------------------------------------- - (void) loadShip:(Human *)context unit:(Unit *)aUnit { UnitType unitType = [aUnit unitType]; if (unitType == u_transport || unitType == u_carrier) { [aUnit setOrder:[[[OLoadShip alloc] initForUnit:aUnit] autorelease]]; // May lead to inconsistency -- continueWithContext... //[context activateThisUnit:aUnit]; [self continueWithContext:context]; } } //---------------------------------------------------------------------- - (void) unloadShip:(Human *)context unit:(Unit *)aUnit { #if NYC [aUnit unloadShip]; [context wait:nil]; #endif } //---------------------------------------------------------------------- - (void) skipMove:(Human *)context unit:(Unit *)aUnit { [aUnit skipMove]; [context setStatusLine:[aUnit statusLine]]; } //====================================================================== // Interface Management //====================================================================== - (BOOL) validateMenuItem:(Human *)context:(NSMenuItem *)menuCell { SEL action = [menuCell action]; BOOL valid = NO; //Unit *unit = [context selectedUnit]; // Commands if (action == @selector (moveMode:)) { //valid = ([context selectedUnit] == nil) ? NO : YES; valid = YES; } else if (action == @selector (surveyMode:)) { valid = NO; } else if (action == @selector (groupMode:)) { valid = NO; } else if (action == @selector (wait:)) { valid = NO; } else if (action == @selector (flightPaths:)) { valid = YES; } else if (action == @selector (activateUnit:)) { //printf ("selectedUnit: %p\n", [context selectedUnit]); //valid = ([context selectedUnit] != nil && [[context selectedUnit] currentRange] > 0) ? YES : NO; valid = YES; } else if (action == @selector (centerScreen:) || action == @selector (centerCursor:)) { //valid = [[context mapView] cursorEnabled]; valid = YES; } else if (action == @selector (showProductionMap:) || action == @selector (showCombatReport:)) { valid = YES; } // Orders else if (action == @selector (goDirection:) || action == @selector (goHome:) || action == @selector (goRandom:) // Not for fighter || action == @selector (moveTo:) || action == @selector (escortShip:) // Only if ship || action == @selector (sentry:) // Not for fighter not in city/carrier || action == @selector (clearOrders:) // Only if city or unit w/ order || action == @selector (loadShip:) // Only ship || action == @selector (unloadShip:) // Only ship || action == @selector (skipMove:) // Only if has movement left || action == @selector (explore:) ) { //valid = ([context selectedUnit] == nil) ? NO : YES; valid = YES; } else if (action == @selector (patrolTo:) ) { //valid = (unit != nil && ([unit unitType] != u_fighter || [unit isOnBoardShip] == YES || [unit isInCity] == YES)); valid = YES; } return valid; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.