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

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

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

#import "HState.h"

#import "DistributedGameManager.h"
#import "HSMarquee.h"
#import "Human.h"
#import "Map.h"
#import "MapView.h"
#import "Unit.h"

#import <AppKit/psopsNeXT.h>

//======================================================================
// This is an abstract class that provides methods that any of its
// subclasses will require.  Subclasses just need to implement the
// methods they require.  It is used by the Human player as part
// of the State pattern, which simplifies state changes and separates
// the implementation of all the different states.
//
// The Human passes itself as the context of the state in all messages
// is sends to state objects.
//
// This also implements a simple marquee that is used by more than one
// state.
//
// I've made a diagram (StateChanges.diagram2) that shows the valid
// state changes.
//
//======================================================================

@implementation HState

- initWithGameManager:(GameManager *)theGameManager
{
    [super init];

    gameManager = theGameManager;

    marqueeTimer = nil;
    marqueeLocation.row = -1;
    marqueeLocation.column = -1;
    offset = 0;

    return self;
}

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

- (void) dealloc
{
    if (marqueeTimer != nil)
        [marqueeTimer invalidate];
    SNRelease (marqueeTimer);

    [super dealloc];
}

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

- (void) continueWithContext:(Human *)context
{
    [context performSelector:@selector (continue:) withObject:nil afterDelay:0.1];
}

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

//----------------------------------------------------------------------
// This is the name describing the state and is shown on screen.
//----------------------------------------------------------------------

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

//----------------------------------------------------------------------
// This is used as the key to a dictionary of states.
//----------------------------------------------------------------------

- (NSString *) stateKey
{
    return nil;
}

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

- (void) stateEntered:(Human *)context
{
}

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

- (void) stateExited:(Human *)context
{
}

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

- (void) beginTurn:(Human *)context
{
    // Beep as default behaviour?
    NSBeep ();
}

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

- (void) endTurn:(Human *)context
{
    NSBeep ();
}

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

- (void) continue:(Human *)context
{
    NSBeep ();
}

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


- (void) mouseDown:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target
{
}

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

- (void) mouseUp:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target
{
}

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

- (void) rightMouseDown:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target
{
}

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

- (void) rightMouseUp:(Human *)context:(unsigned int)modifierFlags atLocation:(EMMapLocation)target
{
}

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

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

    if (uc == 3)
    {
        [context clickActiveButton];
    }
    else
    {
        [[[context mapView] nextResponder] keyDown:theEvent];
    }
}

//----------------------------------------------------------------------
// This report can be shown from the Survey state.
//----------------------------------------------------------------------

- (void) combatReport:(Human *)context
{
}

//----------------------------------------------------------------------
// The final maps can be viewed from the Game Over state.
//----------------------------------------------------------------------

- (void) showFinalMap:(Human *)context forPlayer:(Player)number
{
}

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

- (void) moveMode:(Human *)context
{
}

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

- (void) surveyMode:(Human *)context
{
}

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

- (void) groupMode:(Human *)context
{
}

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

- (void) wait:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) flightPathMode:(Human *)context
{
}

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

- (void) activate:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) centerScreen:(Human *)context mapView:(MapView *)mapView
{
}

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

- (void) centerCursor:(Human *)context mapView:(MapView *)mapView
{
}

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

- (void) centerSelected:(Human *)context mapView:(MapView *)mapView
{
}

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

- (void) productionMap:(Human *)context
{
}

//======================================================================
// Orders
//======================================================================

- (void) goDirection:(Human *)context
{
    NSBeep ();
}

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

- (void) goHome:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) goRandom:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) moveTo:(Human *)context
{
}

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

- (void) patrolTo:(Human *)context
{
}

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

- (void) escortShip:(Human *)context
{
}

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

- (void) explore:(Human *)context unit:(Unit *)unit
{
}

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

- (void) sentry:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) clearOrders:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) clearOrders:(Human *)context city:(City *)aCity
{
}

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

- (void) loadShip:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) unloadShip:(Human *)context unit:(Unit *)aUnit
{
}

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

- (void) skipMove:(Human *)context unit:(Unit *)aUnit
{
}

//======================================================================
// Interface Management
//======================================================================

- (BOOL) validateMenuItem:(Human *)context:(NSMenuItem *)menuCell
{
    SEL action = [menuCell action];
    BOOL valid = NO;
  
    if (action == @selector(centerScreen:)
        || action == @selector(centerCursor:))
    {
        valid = [[context mapView] cursorEnabled];
    }

    return valid;
}

//----------------------------------------------------------------------
// The Show Production state needs to know if you update the production
// of a city.
//----------------------------------------------------------------------

- (void) cityProductionChanged:(Human *)context city:(City *)theCity
{
}

//----------------------------------------------------------------------
// Select the thing at the given location, and optionally inspect it.
// This has to be careful not to leak information from unexplored
// territory (such as whether there is a city at the given location.)
//----------------------------------------------------------------------

- (void) selectThing:(Human *)context atLocation:(EMMapLocation)target andInspect:(BOOL)inspectFlag
{
    id anObject = nil;
    MapToken mapToken = [[context map] tokenAtLocation:target];
    Terrain terrain;
    Player player;
    Icon icon;
    BOOL explored;

    [[context mapView] positionCursorAtLocation:target];

    [context selectUnit:nil];
    [context selectCity:nil];

    EMMapTokenComponents (mapToken, &terrain, &player, &icon, &explored);

    if (terrain == t_city && explored == YES)
    {
        City *city = [context cityAtLocation:target];
        anObject = city;
        [context selectCity:city];
    }
    else if (player == [context playerNumber]
             && icon != i_none
             && explored == YES)
    {
        Unit *unit = [context unitWithType:EMConvertIconToUnitType (icon) atLocation:target];
        anObject = unit;
        [context selectUnit:unit];
        [context setStatusLine:[unit statusLine]];
    }

    if (anObject == nil || [anObject isKindOfClass:[Unit class]] == NO)
        [context setStatusLine:[NSString stringWithFormat:@"Loc: %d,%d", target.row, target.column]];
  
    if (inspectFlag == YES)
    {
        [context selectThing:anObject];
    }
}

//======================================================================
// Marquee
//======================================================================

//----------------------------------------------------------------------
// Update the marquee, executed by the timer.
//----------------------------------------------------------------------

- (void) showMarquee:(NSTimer *)aTimer
{
    Human *context = [aTimer userInfo];
    MapView *mapView = [context mapView];
    Unit *selectedUnit = [context selectedUnit];
    NSPoint a;
    EMMapLocation unitLocation = [selectedUnit unitLocation];

    a = [mapView getCenterPointForLocation:unitLocation];

    [mapView scrollLocationToVisible:unitLocation];
    [mapView lockFocus];
    PSnewinstance ();
    PSsetinstance (YES);
    HSDrawMarquee (a.x - 8, a.y - 7, a.x + 7, a.y + 8, 5 - offset);
    PSsetinstance (NO);
    [mapView unlockFocus];

    offset = (offset + 1) % 6;
}

//----------------------------------------------------------------------
// Set up a timer for a simple marquee around the given location.
//----------------------------------------------------------------------

- (void) showMarquee:(Human *)context atLocation:(EMMapLocation)target
{
    [self stopMarquee:context];

    marqueeLocation = target;

    // set up a timer until first mouseDown:
    marqueeTimer = [[NSTimer scheduledTimerWithTimeInterval:0.05
                              target:self
                              selector:@selector (showMarquee:)
                              userInfo:context
                              repeats:YES] retain];
}

//----------------------------------------------------------------------
// Stop the timer and remove the marquee from the screen.
//----------------------------------------------------------------------

- (void) stopMarquee:(Human *)context
{
    if (marqueeTimer != nil)
    {
        MapView *mapView = [context mapView];

        [marqueeTimer invalidate];
        SNRelease (marqueeTimer);
        marqueeLocation.row = -1;
        marqueeLocation.column = -1;

        [mapView lockFocus];
        PSnewinstance ();
        [mapView unlockFocus];
    }
}

@end

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