This is Token.m in view mode; [Download] [Up]
//
// $Id: Token.m,v 1.7 1997/10/31 04:52:10 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: Token.m,v 1.7 1997/10/31 04:52:10 nygard Exp $");
#import "Token.h"
static NSColor *player_color[4];
static NSImage *player_icon_images[4][13];
static NSImage *terrain_images[3];
static NSImage *icon_masks[13];
static NSImage *icon_borders[13];
static NSImage *army_innards;
static NSImage *transport2_innards;
static NSImage *hovercraft_innards;
static NSImage *oddball_images[4][2];
struct image_names
{
NSString *i_name;
NSImage **i_image;
};
static struct image_names class_images[] =
{
{ @"unknown.tiff", &terrain_images[t_unknown] },
{ @"land.tiff", &terrain_images[t_land] },
{ @"water.tiff", &terrain_images[t_water] },
{ @"city_mask.tiff", &icon_masks[0] },
{ @"army_mask.tiff", &icon_masks[1] },
{ @"sentry_mask.tiff", &icon_masks[2] },
{ @"fighter_mask.tiff", &icon_masks[3] },
{ @"transport1_mask.tiff", &icon_masks[4] },
{ @"transport2_mask.tiff", &icon_masks[5] },
{ @"submarine_mask.tiff", &icon_masks[6] },
{ @"destroyer_mask.tiff", &icon_masks[7] },
{ @"cruiser_mask.tiff", &icon_masks[8] },
{ @"carrier1_mask.tiff", &icon_masks[9] },
{ @"carrier2_mask.tiff", &icon_masks[10] },
{ @"battleship_mask.tiff", &icon_masks[11] },
{ @"hovercraft_mask.tiff", &icon_masks[12] },
{ @"army_border.tiff", &icon_borders[1] },
{ @"sentry_border.tiff", &icon_borders[2] },
{ @"fighter_border.tiff", &icon_borders[3] },
{ @"transport1_border.tiff", &icon_borders[4] },
{ @"transport2_border.tiff", &icon_borders[5] },
{ @"submarine_border.tiff", &icon_borders[6] },
{ @"destroyer_border.tiff", &icon_borders[7] },
{ @"cruiser_border.tiff", &icon_borders[8] },
{ @"carrier1_border.tiff", &icon_borders[9] },
{ @"carrier2_border.tiff", &icon_borders[10] },
{ @"battleship_border.tiff", &icon_borders[11] },
{ @"hovercraft_border.tiff", &icon_borders[12] },
{ @"army_innards.tiff", &army_innards },
{ @"transport2_innards.tiff", &transport2_innards },
{ @"hovercraft_innards.tiff", &hovercraft_innards },
};
//======================================================================
// This class was required when the images were used in a browser or table
// view, since they made a copy of the image and wouldn't get updates
// to the player colors of the images. Instead of initializing the
// images from data, we provide a method to redraw the image.
//
// The actual tokens are built up from a mask that is used to select
// the colored portion, and possibly an "innards" image, which is a
// part of the final image that should remain black. (For example,
// the bits within the tracks of the Army image.
//
// The final image is composited over the background terrain image. If
// the background terrain is a city, a black border is also composited
// around the unit icon to enhance visibility. (I think I'm using
// about 50% alpha to darken the city.)
//======================================================================
#define Token_VERSION 1
@implementation Token
+ (void) initialize
{
if (self == [Token class])
{
[self setVersion:Token_VERSION];
if ([NSBundle bundleForClass:self] == nil)
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector (loadClassImages)
name:NSApplicationDidFinishLaunchingNotification
object:NSApp];
}
else
{
[self loadClassImages];
}
}
}
//----------------------------------------------------------------------
+ (void) loadClassImages
{
int l;
Player p;
NSBundle *thisBundle;
NSString *imagePath;
thisBundle = [NSBundle bundleForClass:self];
NSAssert (thisBundle != nil, @"Could not get bundle.");
// load class images
for (l = 0; l < sizeof (class_images) / sizeof (struct image_names); l++)
{
imagePath = [thisBundle pathForImageResource:class_images[l].i_name];
NSAssert1 (imagePath != nil, @"Could not find image: '%@'", class_images[l].i_name);
*(class_images[l].i_image) = [[NSImage alloc] initByReferencingFile:imagePath];
NSAssert1 (*(class_images[l].i_image) != nil, @"Couldn't load image: '%@'\n", class_images[l].i_name);
}
for (p = p_neutral; p <= p_player3; p++)
{
for (l = 0; l < 13; l++)
player_icon_images[p][l] = [icon_masks[0] copyWithZone:[self zone]];
for (l = 0; l < 2; l++)
oddball_images[p][l] = [icon_masks[0] copyWithZone:[self zone]];
}
[Token setColor:[NSColor lightGrayColor] forPlayer:p_neutral];
[Token setColor:[NSColor colorWithCalibratedRed:34 / 255.0 green:255 / 255.0 blue:248 / 255.0 alpha:1.0]
forPlayer:p_player1];
[Token setColor:[NSColor colorWithCalibratedRed:255 / 255.0 green:26 / 255.0 blue:6 / 255.0 alpha:1.0]
forPlayer:p_player2];
[Token setColor:[NSColor colorWithCalibratedRed:243 / 255.0 green:255 / 255.0 blue:0 / 255.0 alpha:1.0]
forPlayer:p_player3];
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
//----------------------------------------------------------------------
+ (NSColor *) colorForPlayer:(Player)aPlayer
{
return player_color[aPlayer];
}
//----------------------------------------------------------------------
+ (void) setColor:(NSColor *)aColor forPlayer:(Player)aPlayer
{
player_color[aPlayer] = [aColor retain];
[self rebuildIconsForPlayer:aPlayer];
// Then invalidate the images...
}
//----------------------------------------------------------------------
+ (void) rebuildIconsForPlayer:(Player)aPlayer
{
int l;
NSRect aRect;
NSPoint origin;
origin = NSMakePoint (0, 0);
aRect = NSMakeRect (0, 0, 16, 16);
for (l = i_army; l <= i_hovercraft; l++)
{
[player_icon_images[aPlayer][l] lockFocus];
[player_color[aPlayer] set];
NSRectFill (aRect);
[icon_masks[l] compositeToPoint:origin operation:NSCompositeDestinationIn];
if (l == i_army)
[army_innards compositeToPoint:origin operation:NSCompositeSourceOver];
else if (l == i_loaded_transport)
[transport2_innards compositeToPoint:origin operation:NSCompositeSourceOver];
else if (l == i_hovercraft)
[hovercraft_innards compositeToPoint:origin operation:NSCompositeSourceOver];
[player_icon_images[aPlayer][l] unlockFocus];
}
[player_icon_images[aPlayer][0] lockFocus];
[player_color[aPlayer] set];
aRect = NSMakeRect (0, 0, 16, 16);
NSRectFill (aRect);
[icon_masks[0] compositeToPoint:origin operation:NSCompositeSourceOver];
[player_icon_images[aPlayer][0] unlockFocus];
[oddball_images[aPlayer][0] lockFocus];
PSsetgray (NSBlack);
NSRectFill (aRect);
[player_icon_images[aPlayer][i_army] compositeToPoint:origin operation:NSCompositeSourceOver];
[oddball_images[aPlayer][0] unlockFocus];
[oddball_images[aPlayer][1] lockFocus];
PSsetgray (NSBlack);
NSRectFill (aRect);
[player_icon_images[aPlayer][i_fighter] compositeToPoint:origin operation:NSCompositeSourceOver];
[oddball_images[aPlayer][1] unlockFocus];
}
//----------------------------------------------------------------------
+ (NSImage **) oddballsForPlayer:(Player)aPlayer
{
return oddball_images[aPlayer];
}
//----------------------------------------------------------------------
+ (NSImage **) iconBorders
{
return icon_borders;
}
//======================================================================
- initIcon:(Icon)anIcon onTerrain:(Terrain)someTerrain forPlayer:(Player)aPlayer
{
NSSize tokenSize;
[super init];
player = aPlayer;
icon = anIcon;
terrain = someTerrain;
tokenSize = NSMakeSize (16, 16);
tokenImage = [[NSImage alloc] initWithSize:tokenSize];
NSAssert (tokenImage != nil, @"tokenImage is nil");
[tokenImage addRepresentation:[[[NSCustomImageRep alloc] initWithDrawSelector:@selector (drawToken:) delegate:self]
autorelease]];
return self;
}
//----------------------------------------------------------------------
- (void) dealloc
{
SNRelease (tokenImage);
[super dealloc];
}
//----------------------------------------------------------------------
- (void) drawToken:(NSCustomImageRep *)imageRep
{
NSPoint origin = {0, 0};
//last_color_used = player_color[player];
if (terrain == t_unknown || terrain == t_land || terrain == t_water)
{
[terrain_images[terrain] compositeToPoint:origin operation:NSCompositeSourceOver];
}
else
{
[player_icon_images[player][i_none] compositeToPoint:origin operation:NSCompositeSourceOver];
}
if (icon != i_none)
{
if (terrain == t_city)
{
[[NSColor colorWithCalibratedRed:0 green:0 blue:0 alpha:0.5] set];
PScompositerect (0, 0, 16, 16, NSCompositeSourceOver);
}
[player_icon_images[player][icon] compositeToPoint:origin operation:NSCompositeSourceOver];
if (terrain == t_city)
[icon_borders[icon] compositeToPoint:origin operation:NSCompositeSourceOver];
}
}
//----------------------------------------------------------------------
- (NSImage *) tokenImage
{
#if 0
if ([last_color_used isEqual:player_color[player]] == NO)
[tokenImage recache];
#endif
return tokenImage;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.