ftp.nice.ch/Attic/openStep/games/Empire.0.6.m.NIS.bs.tgz#/Empire.0.6/src/Human.subproj/HMoveState.m

This is HMoveState.m in view mode; [Download] [Up]

//
// $Id: HMoveState.m,v 1.3 1997/10/31 03:38:15 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: HMoveState.m,v 1.3 1997/10/31 03:38:15 nygard Exp $");

#import "HMoveState.h"

#import "City.h"
#import "EmInspectorManager.h"
#import "HDirectionState.h"
#import "HEscortShipState.h"
#import "HFlightPathState.h"
#import "HMoveToState.h"
#import "HPatrolToState.h"
#import "HProductionState.h"
#import "HSurveyState.h"
#import "Human.h"
#import "MapView.h"
#import "Unit.h"

#import "../Orders.subproj/Orders.h"

//======================================================================
// The main state for giving movement commands to units.  You can
// switch back and forth between this and the Survey state while there
// are units that can still move.
//======================================================================

@implementation HMoveState

//======================================================================
// Subclass responsibilities
//======================================================================

- (NSString *) stateName
{
    return @"Move";
}
  
//----------------------------------------------------------------------

- (NSString *) stateKey
{
    return HS_MOVE;
}

//----------------------------------------------------------------------

- (void) stateEntered:(Human *)context
{
    MapView *mapView = [context mapView];
  
    // Set cursor
    //[mapView setCursorIcon:15 player:[context playerNumber]];
    [mapView setCursorEnabled:NO];

    // Disable both buttons
    [context enableContinueButton:NO];
    [context enableEndTurnButton:NO];

    // Temporary hack...
    [[mapView window] makeFirstResponder:mapView];

    [self continueWithContext:context];
}

//----------------------------------------------------------------------

- (void) continue:(Human *)context
{
    MapView *mapView = [context mapView];
    Unit *aUnit = [context nextUnitAwaitingMovement];

    if (aUnit == nil)
    {
        [context changeState:HS_SURVEY];
    }
    else
    {
        EMMapLocation unitLocation = [aUnit unitLocation];
    
        [mapView setCursorEnabled:NO];
    
        [mapView positionCursorAtLocation:unitLocation];
        [mapView setCursor:[aUnit icon] player:[context playerNumber]];
        [mapView setFastCursor:NO];
        [mapView setCursorEnabled:YES];

        if ([aUnit isSentried] == NO)
        {
            [context setStatusLine:[aUnit statusLine]];
        }

        if ([aUnit tryToMove] == YES)
        {
            //[context setStatusLine:[aUnit statusLine]];
            [self continueWithContext:context];
        }
        else
        {
            // May have cleared order/reached destination...
            [context setStatusLine:[aUnit statusLine]];
        }
    }
}

//----------------------------------------------------------------------

- (void) mouseDown:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target
{
    int delta_row, delta_col;
    Unit *unit = [context selectedUnit];
    EMMapLocation unitLocation;

    NSAssert (unit != nil, @"No unit selected!");

    //unitLocation = [unit unitLocation];
    unitLocation = [[context mapView] cursorLocation];
    delta_row = target.row - unitLocation.row;
    delta_col = target.column - unitLocation.column;

    if (delta_row >= -1 && delta_row <= 1 && delta_col >= -1 && delta_col <= 1)
    {
        // Do nothing until mouse up.
    }
    else
    {
        [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
{
    int delta_row, delta_col;
    Unit *unit = [context selectedUnit];
    Direction delta_to_dir[9] = {d_northwest, d_north, d_northeast, d_west, d_none, d_east, d_southwest, d_south, d_southeast};
    EMMapLocation unitLocation = [unit unitLocation];

    delta_row = target.row - unitLocation.row;
    delta_col = target.column - unitLocation.column;
  
    if (delta_row >= -1 && delta_row <= 1 && delta_col >= -1 && delta_col <= 1)
    {
        [self move:context:delta_to_dir[3 * (delta_row + 1) + delta_col + 1]];
    }
}

//----------------------------------------------------------------------

- (void) rightMouseUp:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target
{
    [self surveyMode:context];
}

//----------------------------------------------------------------------

- (void) keyDown:(Human *)context:(NSEvent *)theEvent
{
    NSString *eventCharacters = [theEvent characters];
    unichar uc = [eventCharacters characterAtIndex:0];

    switch (uc)
    {
      case '1':
          [self move:context:d_southwest];
          break;
      
      case NSDownArrowFunctionKey:
      case '2':
          [self move:context:d_south];
          break;
      
      case '3':
          [self move:context:d_southeast];
          break;
      
      case NSLeftArrowFunctionKey:
      case '4':
          [self move:context:d_west];
          break;
      
      case '5':
      case 'C':
      case 'c':
          [context centerScreen:nil];
          break;

      case NSRightArrowFunctionKey:
      case '6':
          [self move:context:d_east];
          break;
      
      case '7':
          [self move:context:d_northwest];
          break;
      
      case NSUpArrowFunctionKey:
      case '8':
          [self move:context:d_north];
          break;
      
      case '9':
          [self move:context:d_northeast];
          break;

      case 'd':
      case 'D':
          [context goDirection:self];
          break;

      case 'e':
      case 'E':
          [context escortShip:self];
          break;

      case 'h':
      case 'H':
          [context goHome:self];
          break;

      case 'l':
      case 'L':
          [context loadShip:self];
          break;

      case 'o':
      case 'O':
          [context clearOrders:self];
          break;

      case 'p':
      case 'P':
          [self patrolTo:context];
          break;

      case 'r':
      case 'R':
          [context goRandom:self];
          break;

      case 's':
      case 'S':
          [context sentry:nil];
          break;

      case 't':
      case 'T':
          [context moveTo:self];
          break;

      case 'u':
      case 'U':
          [context unloadShip:self];
          break;
      
      case 'v':
      case 'V':
          [self surveyMode:context];
          break;

      case 'w':
      case 'W':
          [context wait:self];
          break;

      case 'x':
      case 'X':
          [context explore:self];
          break;

      case ' ':
          [context skipMove:self];
          break;

      default:
          [super keyDown:context:theEvent];
          break;
    }
}

//======================================================================
// Commands
//======================================================================

- (void) surveyMode:(Human *)context
{
    [context changeState:HS_SURVEY];
}

//----------------------------------------------------------------------

- (void) flightPathMode:(Human *)context
{
    [context saveState];
    [context changeState:HS_FLIGHT_PATH];
}

//----------------------------------------------------------------------

- (void) wait:(Human *)context unit:(Unit *)aUnit
{
    [context waitUnit:aUnit];
    [self continueWithContext: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];

        [self continueWithContext:context];
    }
}

//----------------------------------------------------------------------

- (void) goRandom:(Human *)context unit:(Unit *)aUnit
{
    [aUnit setOrder:[[[ORandom alloc] initForUnit:aUnit] autorelease]];

    [self continueWithContext:context];
}

//----------------------------------------------------------------------

- (void) moveTo:(Human *)context
{
    [context saveState];
    [context changeState:HS_MOVE_TO];
}

//----------------------------------------------------------------------

- (void) patrolTo:(Human *)context
{
    [context saveState];
    [context changeState:HS_PATROL_TO];
}

//----------------------------------------------------------------------

- (void) escortShip:(Human *)context
{
    [context saveState];
    [context changeState:HS_ESCORT_SHIP];
}

//----------------------------------------------------------------------

- (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]];

    [self continueWithContext:context];
}

//----------------------------------------------------------------------

- (void) clearOrders:(Human *)context unit:(Unit *)aUnit
{
    [aUnit setOrder:nil];

    [self continueWithContext:context];
}

//----------------------------------------------------------------------

- (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]];
        //[context activateThisUnit:aUnit];

        [self continueWithContext:context];
    }
}

//----------------------------------------------------------------------

- (void) unloadShip:(Human *)context unit:(Unit *)aUnit
{
    [aUnit unloadShip];
    [context wait:self];
}

//----------------------------------------------------------------------

- (void) skipMove:(Human *)context unit:(Unit *)aUnit
{
    [aUnit skipMove];

    [self continueWithContext:context];
}
  
//======================================================================
// 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 = NO;
    }
    else if (action == @selector (surveyMode:))
    {
        valid = YES;
    }
    else if (action == @selector (groupMode:))
    {
        valid = NO;
    }
    else if (action == @selector (wait:))
    {
        valid = ([context selectedUnit] == nil) ? NO : YES;
    }
    else if (action == @selector (flightPaths:))
    {
        valid = YES;
    }
    else if (action == @selector (activateUnit:))
    {
        valid = NO;
    }
    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;
    }
    else if (action == @selector (patrolTo:) )
    {
        valid = (unit != nil && ([unit unitType] != u_fighter || [unit isOnBoardShip] == YES || [unit isInCity] == YES));
    }

    return valid;
}

//======================================================================
// Other
//======================================================================

- (BOOL) move:(Human *)context:(Direction)dir
{
    BOOL moved = NO;

    if (dir != d_none)
        moved = [context tryToMoveSelectedUnitInDirection:dir];

    if (moved)
        [self continueWithContext:context];

    return moved;
}

@end

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.