This is XoxWars.m in view mode; [Download] [Up]
#import "XoxWars.h"
#import "BackView.h"
#import "Ship.h"
#import "ActorMgr.h"
#import "SoundMgr.h"
#import "XWBullet.h"
#import "XWShip.h"
#import "XWSpaceGen.h"
#import "XWSun.h"
#ifdef METEORS
#import "XWMeteor.h"
#endif
#import "GOLetter.h"
#import "Explosion.h"
#import "Thinker.h"
int xx_xwbullet, xx_xwship, xx_xwspace;
float xw_gravity;
int xw_bulletSpeed, xw_bounce, xw_meteors, xw_nastyShots;
int xw_bulletMass;
float xx_difficulty;
#import "CrazyMander.h"
#import "TrackMander.h"
@implementation XoxWars
- newGame
{
dartKills = clawKills = 0;
[[clawKillsText setIntValue:clawKills] display];
[[dartKillsText setIntValue:dartKills] display];
return self;
}
// invoked only by the actor manager
- _createLevel:(int)lev
{
NXRect r;
char title[40];
goToNextLevel = explosionCount = goodBullets = badBullets = 0;
goodShip = [actorMgr newActor:xx_xwship for:self tag:GOOD];
badShip = [actorMgr newActor:xx_xwship for:self tag:EVIL];
space = [actorMgr newActor:xx_xwspace for:self tag:0];
if (sun) sun = [actorMgr newActor:(int)[XWSun class] for:self tag:0];
#ifdef METEORS
int i;
for (i=0; i<xw_meteors; i++)
[actorMgr newActor:(int)[XWMeteor class] for:self tag:0];
#endif
[mainView getBounds:&r];
[space newSize:&r.size];
sprintf(title,"Xox Wars");
[[mainView window] setTitle:title];
if (!commanders) {
commanders = [[List alloc] init];
playerClasses = [[List alloc] init];
[commanders addObject:[[[
[Commander alloc] init] addShip:goodShip] addTarget:badShip]];
[commanders addObject:[[[
[Commander alloc] init] addShip:badShip] addTarget:goodShip]];
[self initPlayers];
}
return self;
}
-free
{
[[commanders freeObjects] free];
[playerClasses free];
return [super free];
}
- initPlayers
{
id buttons = [[playerBox contentView] subviews];
int n = [buttons count];
[self loadPlayers];
while (n--) {
static char title[20];
PopUpList* popup = [[buttons objectAt:n] target];
sprintf(title, "Player %d", n);
[popup setTitle:title];
[self changePlayer:[popup itemList]];
}
return self;
}
- loadPlayers
{
[playerClasses addObject:[Commander class]];
[playerClasses addObject:[CrazyMander class]];
[playerClasses addObject:[TrackMander class]];
return [self setPlayers];
}
- setPlayers
{
List* buttons = [[playerBox contentView] subviews];
int count = [playerClasses count];
int i;
int n = [buttons count];
while (n--) {
PopUpList* popup = [[buttons objectAt:n] target];
for (i=0; i<count; ++i) {
Class pc = [playerClasses objectAt:i];
Cell* newCell = [popup addItem:[pc name]];
[newCell setTag:i];
[[newCell setTarget:self] setAction:@selector(changePlayer:)];
}
}
return self;
}
- changePlayer:sender
{
const char* title = [[sender window] title];
const char* ptr = strchr(title, ' ');
int np = atoi(++ptr);
Class nc = [playerClasses objectAt:[[sender selectedCell] tag]];
id newComm = [[nc alloc] init] ;
id oldComm = [commanders replaceObjectAt:np with:newComm];
[[oldComm transferTo:newComm] free];
return self;
}
- infoView
{
return infoView;
}
- didActivate:(Actor *)theActor
{
if(theActor->actorType == xx_explosion)
explosionCount++;
else if(theActor->actorType == xx_xwbullet)
{
(theActor->theta == 0.) ? goodBullets++ : badBullets++;
}
else
{
}
return self;
}
- didRetire:(Actor *)theActor
{
if(theActor->actorType == xx_xwship)
{
if (theActor->alliance == GOOD)
{
[[clawKillsText setIntValue:++clawKills] display];
}
else
{
[[dartKillsText setIntValue:++dartKills] display];
}
if (dartKills >= 10 || clawKills >= 10)
{
if ([actorMgr gameStatus] != GAME_DYING)
[GOLetter gameOver:self];
[actorMgr setGameStatus: GAME_DYING];
goToNextLevel = 0;
}
else goToNextLevel = 1;
}
else if(theActor->actorType == xx_explosion)
{
if ((--explosionCount <= 0) && goToNextLevel)
{
[actorMgr requestLevel: 1];
}
}
else if(theActor->actorType == xx_xwbullet)
{
(theActor->theta == 0.) ? goodBullets-- : badBullets--;
}
else
{
}
return self;
}
- keyDown:(NXEvent *)theEvent
{
if (theEvent->data.key.repeat > 0) return self;
switch(theEvent->data.key.charCode)
{
case 'z': // rotate left
[goodShip setTurning:LEFT down:YES time:theEvent->time];
break;
case 'x': // rotate right
[goodShip setTurning:RIGHT down:YES time:theEvent->time];
break;
case '.': // fire
[goodShip fire];
break;
case ',': // thrust
[goodShip setThrusting:YES time:theEvent->time];
break;
case ' ': // shields
[goodShip setShields:1];
break;
case '1': // rotate left
[badShip setTurning:LEFT down:YES time:theEvent->time];
break;
case '2': // rotate right
[badShip setTurning:RIGHT down:YES time:theEvent->time];
break;
case '9': // fire
[badShip fire];
break;
case '6': // thrust
[badShip setThrusting:YES time:theEvent->time];
break;
case '\003': // shields
[badShip setShields:1];
break;
}
return self;
}
- keyUp:(NXEvent *)theEvent
{
switch(theEvent->data.key.charCode)
{
case 'z': // rotate left
[goodShip setTurning:LEFT down:NO time:theEvent->time];
break;
case 'x': // rotate right
[goodShip setTurning:RIGHT down:NO time:theEvent->time];
break;
case ',': // thrust
[goodShip setThrusting:NO time:theEvent->time];
break;
case ' ': // shields
[goodShip setShields:0];
break;
case '1': // rotate left
[badShip setTurning:LEFT down:NO time:theEvent->time];
break;
case '2': // rotate right
[badShip setTurning:RIGHT down:NO time:theEvent->time];
break;
case '6': // thrust
[badShip setThrusting:NO time:theEvent->time];
break;
case '\003': // shields
[badShip setShields:0];
break;
}
return self;
}
- scenarioSelected
{
goodShip = [actorMgr newActor:xx_xwship for:self tag:GOOD];
badShip = [actorMgr newActor:xx_xwship for:self tag:EVIL];
[goodShip scenarioSelected];
[badShip scenarioSelected];
return self;
}
- scenarioDeselected
{ return self; }
- newSize:(NXSize *)s
{
[space newSize:s];
return self;
}
- (COLLISION_PARADIGM)collisionParadigm
{
return GOOD_V_EVIL;
}
- init
{
char path[256];
id cv, subviews;
[super init];
if ([[NXBundle bundleForClass:[self class]]
getPath:path
forResource:"xoxwars"
ofType:"nib"])
{
[NXApp loadNibFile:path
owner:self
withNames:NO
fromZone:[self zone]];
cv = [uselessBox contentView];
subviews = [cv subviews];
while ([subviews count] > 0)
[scoreView addSubview:[subviews objectAt:0]];
}
xx_xwbullet = (int)[XWBullet class];
xx_xwship = (int)[XWShip class];
xx_xwspace = (int)[XWSpaceGen class];
[self adjustSettings:self];
[[NXApp delegate] addImageResource:"explosionM" for: [Explosion class]];
[[NXApp delegate] addImageResource:"explosionS" for: [Explosion class]];
[[NXApp delegate] addSoundResource: SHIPSND];
return self;
}
- tile
{
NXRect r;
float f;
[gcontentView getBounds:&r];
r.size.width -= 60;
f = r.size.width;
[abackView setFrame:&r];
[gcontentView getBounds:&r];
r.size.width = 60;
r.origin.x = f;
[scoreView setFrame:&r];
[gcontentView addSubview:abackView];
[gcontentView addSubview:scoreView];
return abackView;
}
//
// Scenario-specific actions
- (int) bullets : (int) type
{
return (type == GOOD) ? goodBullets : badBullets;
}
- (BOOL) hasBullets : (int) type
{
return ([self bullets:type] < 5);
}
- adjustSettings:sender
{
switch([gravityMatrix selectedRow])
{
case 0: xw_gravity = 30000; break;
case 1: xw_gravity = 0; break;
case 2: xw_gravity = -30000; break;
case 3: xw_gravity = -66000; break;
}
switch([bulletMatrix selectedRow])
{
case 0: xw_bulletSpeed = 13; break;
case 1: xw_bulletSpeed = 22; break;
case 2: xw_bulletSpeed = 34; break;
}
if ([[settingsMatrix cellAt:0:0] state])
{ // sun enabled
if (!sun) sun = [actorMgr newActor:(int)[XWSun class] for:self tag:0];
}
else
{
if (sun) [actorMgr destroyActor:sun];
sun = nil;
}
xw_bounce = ([[settingsMatrix cellAt:1:0] state]);
xw_nastyShots = ([[settingsMatrix cellAt:2:0] state]);
xw_bulletMass = ([[settingsMatrix cellAt:3:0] state]);
#ifdef METEORS
xw_meteors = ([meteorsSlider intValue]);
#endif
xx_difficulty = [difficultySlider floatValue];
return self;
}
- oneStep
{
static int phase = 0;
int STEP = 20.0 * (1.0-xx_difficulty) + 1.0;
[commanders makeObjectsPerform:@selector(reset)];
if ((phase++ % STEP) == 0)
[commanders makeObjectsPerform:@selector(oneStep:) with:self];
return self;
}
@end
@implementation ActorMgr(XoxWarsAdditions)
- listFor:(ALLIANCE)alliance
{
switch((int)alliance)
{
case GOOD:
return goodList;
case EVIL:
return badList;
case DESTROYALL:
return destroyAllList;
// these will be collided twice against destroyall actors
case GOODNBAD:
return nil;
}
return nil;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.