Command que flush handling changed, move from network layer to user layer.

More of new unit reference code.
This commit is contained in:
johns 2000-04-16 22:51:06 +00:00
parent 613906649f
commit e958202ef4
31 changed files with 735 additions and 426 deletions

View file

@ -144,7 +144,7 @@ global void HandleActionBuild(Unit* unit)
build->Command.Data.Builded.Add=stats->HitPoints/n;
build->Command.Data.Builded.Sub=n;
build->Command.Data.Builded.Cancel=0; // FIXME: Is it necessary?
build->Command.Data.Builded.Peon=unit;
build->Command.Data.Builded.Worker=unit;
DebugLevel3("Build Sum %d, Add %d, Val %d, Sub %d\n"
,build->Command.Data.Builded.Sum
,build->Command.Data.Builded.Add
@ -191,11 +191,11 @@ global void HandleActionBuilded(Unit* unit)
//
if( unit->Command.Data.Builded.Cancel ) {
// Drop out unit
peon=unit->Command.Data.Builded.Peon;
peon=unit->Command.Data.Builded.Worker;
peon->Reset=1;
peon->Wait=1;
peon->Command.Action=UnitActionStill;
unit->Command.Data.Builded.Peon=NULL;
unit->Command.Data.Builded.Worker=NULL;
DropOutOnSide(peon,HeadingW,type->TileWidth,type->TileHeight);
// Cancel building
DestroyUnit(unit);
@ -229,7 +229,7 @@ global void HandleActionBuilded(Unit* unit)
unit->Reset=1;
unit->Wait=1;
peon=unit->Command.Data.Builded.Peon;
peon=unit->Command.Data.Builded.Worker;
peon->Command.Action=UnitActionStill;
peon->Reset=1;
peon->Wait=1;
@ -269,7 +269,7 @@ global void HandleActionBuilded(Unit* unit)
}
RemoveUnit( unit );
UnitLost(unit);
FreeUnitMemory(unit);
ReleaseUnit(unit);
return;
}

View file

@ -49,10 +49,10 @@ global int HandleActionDie(Unit* unit)
//
// Show death animation
//
if( unit->Type->Animations ) {
if( unit->Type->Animations && unit->Type->Animations->Die ) {
UnitShowAnimation(unit,unit->Type->Animations->Die);
} else {
DebugLevel0("FIXME: die animation missing\n");
// some units has no death animation
unit->Reset=1;
unit->Wait=1;
}
@ -63,7 +63,7 @@ global int HandleActionDie(Unit* unit)
if( unit->Reset ) {
DebugLevel3("Die complete %Zd\n",UnitNumber(unit));
if( !unit->Type->CorpseType ) {
FreeUnitMemory(unit);
ReleaseUnit(unit);
return 1;
}

View file

@ -166,10 +166,10 @@ local int ChopWood(Unit* unit)
if( !(unit->WoodToHarvest = --unit->Value) ) {
// Have wood
if( unit->Type->Type==UnitPeon ) {
unit->Type=&UnitTypes[UnitPeonWithWood];
} else if( unit->Type->Type==UnitPeasant ) {
unit->Type=&UnitTypes[UnitPeasantWithWood];
if( unit->Type==UnitTypeOrcWorker ) {
unit->Type=UnitTypeOrcWorkerWithWood;
} else if( unit->Type==UnitTypeHumanWorker ) {
unit->Type=UnitTypeHumanWorkerWithWood;
} else {
DebugLevel0("Wrong unit for chopping wood %d\n"
,unit->Type->Type);
@ -290,10 +290,10 @@ local int ReturnWithWood(Unit* unit)
MustRedraw|=RedrawResources;
}
if( unit->Type->Type==UnitPeonWithWood ) {
unit->Type=&UnitTypes[UnitPeon];
} else if( unit->Type->Type==UnitPeasantWithWood ) {
unit->Type=&UnitTypes[UnitPeasant];
if( unit->Type==UnitTypeOrcWorkerWithWood ) {
unit->Type=UnitTypeOrcWorker;
} else if( unit->Type==UnitTypeHumanWorkerWithWood ) {
unit->Type=UnitTypeHumanWorker;
} else {
DebugLevel0("Wrong unit for returning wood %d\n"
,unit->Type->Type);

View file

@ -157,15 +157,15 @@ local int HaulInOilWell(Unit* unit)
}
//
// Change unit to full state.
// Change unit to full state. FIXME: hardcoded good or bad?
//
if( unit->Type->Type==UnitTankerHuman ) {
unit->Type=&UnitTypes[UnitTankerHumanFull];
} else if( unit->Type->Type==UnitTankerOrc ) {
unit->Type=&UnitTypes[UnitTankerOrcFull];
if( unit->Type==UnitTypeHumanTanker ) {
unit->Type=UnitTypeHumanTankerFull;
} else if( unit->Type==UnitTypeOrcTanker ) {
unit->Type=UnitTypeOrcTankerFull;
} else {
DebugLevel0("Wrong unit-type for haul oil %d\n"
,unit->Type->Type);
DebugLevel0("Wrong unit-type for haul oil `%s'\n"
,unit->Type->Ident);
}
//
@ -270,13 +270,13 @@ local int MoveToOilDepot(Unit* unit)
MustRedraw|=RedrawResources;
}
if( unit->Type->Type==UnitTankerHumanFull ) {
unit->Type=&UnitTypes[UnitTankerHuman];
} else if( unit->Type->Type==UnitTankerOrcFull ) {
unit->Type=&UnitTypes[UnitTankerOrc];
if( unit->Type==UnitTypeHumanTankerFull ) {
unit->Type=UnitTypeHumanTanker;
} else if( unit->Type==UnitTypeOrcTankerFull ) {
unit->Type=UnitTypeOrcTanker;
} else {
DebugLevel0("Wrong unit for returning oil %d\n"
,unit->Type->Type);
DebugLevel0("Wrong unit for returning oil `%s'\n"
,unit->Type->Ident);
}
if( WAIT_FOR_OIL<UNIT_MAX_WAIT ) {

View file

@ -162,10 +162,10 @@ local int MineInGoldmine(Unit* unit)
unit->Command.Action=UnitActionMineGold;
}
if( unit->Type->Type==UnitPeon ) {
unit->Type=&UnitTypes[UnitPeonWithGold];
} else if( unit->Type->Type==UnitPeasant ) {
unit->Type=&UnitTypes[UnitPeasantWithGold];
if( unit->Type==UnitTypeOrcWorker ) {
unit->Type=UnitTypeOrcWorkerWithGold;
} else if( unit->Type==UnitTypeHumanWorker ) {
unit->Type=UnitTypeHumanWorkerWithGold;
} else {
DebugLevel0("Wrong unit (%d,%d) for mining gold %d (%s)\n"
,unit->X,unit->Y
@ -280,10 +280,10 @@ global void HandleActionMineGold(Unit* unit)
MustRedraw|=RedrawResources;
}
if( unit->Type->Type==UnitPeonWithGold ) {
unit->Type=&UnitTypes[UnitPeon];
} else if( unit->Type->Type==UnitPeasantWithGold ) {
unit->Type=&UnitTypes[UnitPeasant];
if( unit->Type==UnitTypeOrcWorkerWithGold ) {
unit->Type=UnitTypeOrcWorker;
} else if( unit->Type==UnitTypeHumanWorkerWithGold ) {
unit->Type=UnitTypeHumanWorker;
} else {
DebugLevel0("Wrong unit (%d,%d) for returning gold %d (%s)\n"
,unit->X,unit->Y

View file

@ -15,14 +15,6 @@
** $Id$
*/
/*
This is a quick hack: repair action, done with attack action reversing
:)
*/
//@{
/*----------------------------------------------------------------------------
@ -57,52 +49,73 @@
*/
local void DoActionRepairGeneric(Unit* unit,const Animation* repair)
{
Unit* goal;
int flags;
Player* player;
flags=UnitShowAnimation(unit,repair);
if( (flags&AnimationSound) ) {
PlayUnitSound(unit,VoiceAttacking); //FIXME: should be something else...
}
}
goal=unit->Command.Data.Move.Goal;
if (!goal) {
// FIXME: Should abort the repair
return;
}
// FIXME: Should substract the correct values for repair
// Check if enough resources are available
/**
** Repair an unit.
*/
local void RepairUnit(Unit* unit,Unit* goal)
{
Player* player;
int costs[MaxCosts];
int i;
#define GIVES_HP 16
#define DIVISOR 2
player=unit->Player;
if( !player->Resources[GoldCost] || !player->Resources[WoodCost] ) {
// FIXME: perhaps we should not animate if no resources are available.
return;
// FIXME: Should substract the correct values for repair
//
// Calculate the costs.
//
DebugCheck( !goal->Stats->HitPoints );
for( i=1; i<MaxCosts; ++i ) {
costs[i]=((goal->Stats->Costs[i]*GIVES_HP)
/goal->Stats->HitPoints)/DIVISOR;
// FIXME: unit costs something but to less costs calculated
IfDebug(
if( !costs[i] && goal->Stats->Costs[i] ) {
DebugLevel0("Costs %d-%d\n",i,costs[i]);
}
);
}
//
// Check if enough resources are available
//
for( i=1; i<MaxCosts; ++i ) {
if( player->Resources[i]<costs[i] ) {
// FIXME: we should show a message, we need resources!
// FIXME: perhaps we should not animate if no resources are available.
return;
}
}
//
// Repair the unit
goal->HP++;
//
goal->HP+=GIVES_HP;
if ( goal->HP > goal->Stats->HitPoints ) {
goal->HP = goal->Stats->HitPoints;
}
//
// Subtract the resources
//
PlayerSubCosts(player,costs);
player->Resources[GoldCost]--; // FIXME: correct sources?
player->Resources[WoodCost]--;
// FIXME: if visibile on map must redraw map area.
// Must update panel if unit is selected
if( IsSelected(goal) ) {
if( IsSelected(goal) ) { // Update panel if unit is selected
MustRedraw|=RedrawInfoPanel;
}
if( player==ThisPlayer ) {
MustRedraw|=RedrawResources;
}
}
/**
@ -151,16 +164,25 @@ global int HandleActionRepair(Unit* unit)
//
#ifdef NEW_UNIT
// Check if goal is correct unit.
if( goal && goal->Destroyed ) {
DebugLevel0(__FUNCTION__": destroyed unit\n");
if( !--goal->Refs ) {
FreeUnitMemory(goal);
// FIXME: should I do a function for this?
if( goal ) {
if( goal->Destroyed ) {
DebugLevel0(__FUNCTION__": destroyed unit\n");
if( !--goal->Refs ) {
ReleaseUnit(goal);
}
// FIXME: should I clear this here?
unit->Command.Data.Move.Goal=goal=NULL;
unit->Command.Data.Move.DX=goal->X;
unit->Command.Data.Move.DY=goal->Y;
} else if( goal->Command.Action==UnitActionDie ) {
// FIXME: should I clear this here?
unit->Command.Data.Move.Goal=goal=NULL;
unit->Command.Data.Move.DX=goal->X;
unit->Command.Data.Move.DY=goal->Y;
}
// FIXME: should I clear this here?
unit->Command.Data.Move.Goal=goal=NULL;
}
#endif
//
// Have reached target?
//
@ -173,6 +195,10 @@ global int HandleActionRepair(Unit* unit)
}
unit->SubAction=1;
} else if( err ) {
DebugCheck( unit->Command.Action!=UnitActionStill );
if( goal ) {
goal->Refs--;
}
return 1;
}
unit->Command.Action=UnitActionRepair;
@ -187,34 +213,51 @@ global int HandleActionRepair(Unit* unit)
if( unit->Reset ) {
goal=unit->Command.Data.Move.Goal;
//
// Target is dead, choose new one.
//
#ifdef NEW_UNIT
// Check if goal is correct unit.
// FIXME: should I do a function for this?
if( goal ) {
if( goal->Destroyed ) {
DebugLevel0(__FUNCTION__": destroyed unit\n");
if( !--goal->Refs ) {
ReleaseUnit(goal);
}
// FIXME: should I clear this here?
unit->Command.Data.Move.Goal=goal=NULL;
unit->Command.Data.Move.DX=goal->X;
unit->Command.Data.Move.DY=goal->Y;
} else if( goal->Command.Action==UnitActionDie ) {
// FIXME: should I clear this here?
unit->Command.Data.Move.Goal=goal=NULL;
unit->Command.Data.Move.DX=goal->X;
unit->Command.Data.Move.DY=goal->Y;
}
}
#endif
if( goal ) {
RepairUnit(unit,goal);
}
//
// Target is fine, choose new one.
//
if ( !goal || goal->HP >= goal->Stats->HitPoints ) {
if( !goal || goal->HP >= goal->Stats->HitPoints ) {
if( goal ) {
goal->Refs--;
}
unit->Command.Action=UnitActionStill;
unit->SubAction=0;
unit->State=0;
return 1;
}
#if 0
//
// Still near to target, if not goto target.
//
if( MapDistanceToUnit(unit->X,unit->Y,goal)
>unit->Type->AttackRange ) {
unit->Command.Data.Move.Fast=1;
unit->Command.Data.Move.DX=goal->X;
unit->Command.Data.Move.DY=goal->Y;
unit->Frame=0;
unit->State=0;
unit->SubAction=0;
break;
}
#endif
// FIXME: automatic repair
}
break;
}
return 0;
}

View file

@ -37,18 +37,16 @@
*/
global void HandleActionResearch(Unit* unit)
{
int upgrade;
Upgrade* upgrade;
DebugLevel3("Research %d\n",unit);
upgrade=unit->Command.Data.Research.What;
unit->Command.Data.Research.Ticks+=SpeedResearch;
if( unit->Command.Data.Research.Ticks
>=Upgrades[upgrade].Costs[TimeCost] ) {
if( unit->Command.Data.Research.Ticks>=upgrade->Costs[TimeCost] ) {
// FIXME: should als speak and tell ai
SetMessage("Upgrade complete");
// NewUpgrade(upgrade);
UpgradeAcquire(unit->Player,upgrade);
unit->Reset=1;

View file

@ -32,18 +32,20 @@
/**
** Return goods to gold/wood deposit.
**
** FIXME: must support to move to a specified deposit.
**
** @param unit pointer to unit.
*/
global void HandleActionReturnGoods(Unit* unit)
{
int type;
UnitType* type;
Unit* destu;
//
// Select target to return goods.
//
type=unit->Type->Type;
if( type==UnitPeonWithGold || type==UnitPeasantWithGold ) {
type=unit->Type;
if( type==UnitTypeHumanWorkerWithGold || type==UnitTypeOrcWorkerWithGold ) {
if( !(destu=FindGoldDeposit(unit,unit->X,unit->Y)) ) {
unit->Command.Action=UnitActionStill;
return;
@ -66,7 +68,7 @@ global void HandleActionReturnGoods(Unit* unit)
return;
}
if( type==UnitPeonWithWood || type==UnitPeasantWithWood ) {
if( type==UnitTypeHumanWorkerWithWood || type==UnitTypeOrcWorkerWithWood ) {
if( !(destu=FindWoodDeposit(unit->Player,unit->X,unit->Y)) ) {
unit->Command.Action=UnitActionStill;
return;
@ -93,7 +95,7 @@ global void HandleActionReturnGoods(Unit* unit)
return;
}
if( type==UnitTankerHumanFull || type==UnitTankerOrcFull ) {
if( type==UnitTypeHumanTankerFull || type==UnitTypeOrcTankerFull ) {
if( !(destu=FindOilDeposit(unit->Player,unit->X,unit->Y)) ) {
unit->Command.Action=UnitActionStill;
return;

View file

@ -169,7 +169,7 @@ global void HandleActionStandGround(Unit* unit)
//
// Workers and mage didn't attack automatic
// removed with standground && !type->CowerPeon && !type->CowerMage
// removed with standground && !type->CowerWorker && !type->CowerMage
if( type->CanAttack ) {
//
// Units attacks in attacking range.

View file

@ -119,7 +119,7 @@ global void HandleActionStill(Unit* unit)
//
if( type->Vanishes ) {
//UnitCacheRemove(unit);
FreeUnitMemory(unit);
ReleaseUnit(unit);
return;
}
#endif
@ -183,7 +183,7 @@ global void HandleActionStill(Unit* unit)
//
// Workers and mage didn't attack automatic
//
if( type->CanAttack && !type->CowerPeon && !type->CowerMage ) {
if( type->CanAttack && !type->CowerWorker && !type->CowerMage ) {
//
// JOHNS: removed Human controlled units attacks in attacking range.
// JOHNS: use stand ground for old behavior.

View file

@ -112,7 +112,7 @@ global void HandleActionTrain(Unit* unit)
if ( --unit->Command.Data.Train.Count ) {
int z;
for( z = 0; z < MAX_UNIT_TRAIN-1; z++ ) {
for( z = 0; z < unit->Command.Data.Train.Count ; z++ ) {
unit->Command.Data.Train.What[z] =
unit->Command.Data.Train.What[z+1];
}

View file

@ -147,6 +147,10 @@ local void HandleUnitAction(Unit* unit)
HandleActionStandGround(unit);
break;
case UnitActionFollow: // FIXME: not written
//HandleActionFollow(unit);
//break;
case UnitActionMove: // THE HARD ONE
HandleActionMove(unit);
break;

View file

@ -34,6 +34,7 @@
#include "actions.h"
#include "tileset.h"
#include "map.h"
#include "upgrade.h"
/*----------------------------------------------------------------------------
-- Functions
@ -55,7 +56,7 @@ local Command* GetNextCommand(Unit* unit,int flush)
} else if( unit->NextCount==MAX_COMMANDS ) {
// FIXME: johns: wrong place for an error message.
// FIXME: johns: should be checked by AI or the user interface
if(unit->Player==ThisPlayer) {
if( unit->Player==ThisPlayer ) {
SetMessage( "Unit action list is full" );
}
return NULL;
@ -68,15 +69,12 @@ local Command* GetNextCommand(Unit* unit,int flush)
-- Commands
----------------------------------------------------------------------------*/
// FIXME: here we must add network support! JOHNS: moved to network.
/**
** Stop unit.
**
** @param unit pointer to unit.
** @param flush if true, flush command queue.
*/
global void CommandStopUnit(Unit* unit,int flush)
global void CommandStopUnit(Unit* unit)
{
unit->NextFlush=1;
unit->NextCount=1;
@ -102,6 +100,30 @@ global void CommandStandGround(Unit* unit,int flush)
command->Action=UnitActionStandGround;
}
/**
** Follow unit to new position
**
** @param unit pointer to unit.
** @param dest unit to be followed
** @param flush if true, flush command queue.
*/
global void CommandFollow(Unit* unit,Unit* dest,int flush)
{
Command* command;
if( !(command=GetNextCommand(unit,flush)) ) {
return;
}
command->Action=UnitActionFollow;
command->Data.Move.Fast=1;
command->Data.Move.Goal=dest;
dest->Refs++;
command->Data.Move.Range=1;
command->Data.Move.SX=unit->X;
command->Data.Move.SY=unit->Y;
}
/**
** Move unit to new position
**
@ -110,7 +132,7 @@ global void CommandStandGround(Unit* unit,int flush)
** @param y Y map position to move to.
** @param flush if true, flush command queue.
*/
global void CommandMoveUnit(Unit* unit,int x,int y,int flush)
global void CommandMove(Unit* unit,int x,int y,int flush)
{
Command* command;
@ -121,7 +143,10 @@ global void CommandMoveUnit(Unit* unit,int x,int y,int flush)
}
);
if( !(command=GetNextCommand(unit,flush)) ) {
if( unit->Type->Building ) {
// FIXME: should find a better way for pending commands.
command=&unit->PendCommand;
} else if( !(command=GetNextCommand(unit,flush)) ) {
return;
}
@ -133,8 +158,6 @@ global void CommandMoveUnit(Unit* unit,int x,int y,int flush)
command->Data.Move.SY=unit->Y;
command->Data.Move.DX=x;
command->Data.Move.DY=y;
unit->PendCommand=*command;
}
/**
@ -143,9 +166,10 @@ global void CommandMoveUnit(Unit* unit,int x,int y,int flush)
** @param unit pointer to unit.
** @param x X map position to repair.
** @param y Y map position to repair.
** @param dest or unit to be repaired. FIXME: not supported
** @param flush if true, flush command queue.
*/
global void CommandRepair(Unit* unit,int x,int y,int flush)
global void CommandRepair(Unit* unit,int x,int y,Unit* dest,int flush)
{
Command* command;
@ -154,22 +178,29 @@ global void CommandRepair(Unit* unit,int x,int y,int flush)
DebugLevel0("Internal movement error\n");
return;
}
// FIXME: dest until now not supported
if( dest ) {
DebugLevel0(__FUNCTION__": not used %p\n",dest);
}
);
if( !(command=GetNextCommand(unit,flush)) ) {
if( unit->Type->Building ) {
// FIXME: should find a better way for pending commands.
command=&unit->PendCommand;
} else if( !(command=GetNextCommand(unit,flush)) ) {
return;
}
command->Action=UnitActionRepair;
command->Data.Move.Fast=1;
command->Data.Move.Goal=RepairableOnMapTile(x,y);
command->Data.Move.Goal->Refs++;
command->Data.Move.Range=REPAIR_RANGE;
command->Data.Move.SX=unit->X;
command->Data.Move.SY=unit->Y;
command->Data.Move.DX=x;
command->Data.Move.DY=y;
unit->PendCommand=*command;
}
/**
@ -199,7 +230,10 @@ global void CommandAttack(Unit* unit,int x,int y,Unit* attack,int flush)
DebugLevel3(__FUNCTION__": %Zd attacks %Zd\n"
,UnitNumber(unit),attack ? UnitNumber(attack) : 0);
if( !(command=GetNextCommand(unit,flush)) ) {
if( unit->Type->Building ) {
// FIXME: should find a better way for pending commands.
command=&unit->PendCommand;
} else if( !(command=GetNextCommand(unit,flush)) ) {
return;
}
@ -221,8 +255,6 @@ global void CommandAttack(Unit* unit,int x,int y,Unit* attack,int flush)
command->Data.Move.SY=unit->Y;
command->Data.Move.DX=x;
command->Data.Move.DY=y;
unit->PendCommand=*command;
}
/**
@ -323,7 +355,7 @@ global void CommandBoard(Unit* unit,Unit* dest,int flush)
** @param unit pointer to unit.
** @param x X map position to unload.
** @param y Y map position to unload.
** @param what unit to be unload.
** @param what unit to be unloaded, NoUnitP all.
** @param flush if true, flush command queue.
*/
global void CommandUnload(Unit* unit,int x,int y,Unit* what,int flush)
@ -360,7 +392,8 @@ global void CommandUnload(Unit* unit,int x,int y,Unit* what,int flush)
** @param what Unit type to build.
** @param flush if true, flush command queue.
*/
global void CommandBuildBuilding(Unit* unit,int x,int y,UnitType* what,int flush)
global void CommandBuildBuilding(Unit* unit,int x,int y
,UnitType* what,int flush)
{
Command* command;
@ -394,16 +427,16 @@ global void CommandBuildBuilding(Unit* unit,int x,int y,UnitType* what,int flush
** Cancel the building construction.
**
** @param unit pointer to unit.
** @param peon pointer to unit.
** @param worker pointer to unit.
*/
global void CommandCancelBuilding(Unit* unit,Unit* peon)
global void CommandCancelBuilding(Unit* unit,Unit* worker)
{
unit->NextCount=1;
unit->NextFlush=1;
unit->NextCommand[0].Action=UnitActionBuilded;
unit->NextCommand[0].Data.Builded.Cancel=1;
unit->NextCommand[0].Data.Builded.Peon=peon;
unit->NextCommand[0].Data.Builded.Worker=worker;
unit->Wait=1;
unit->Reset=1;
@ -447,7 +480,6 @@ global void CommandHarvest(Unit* unit,int x,int y,int flush)
// FIXME: this hack didn't work correct on map border
command->Data.Move.DX=x ? x-1 : x;
command->Data.Move.DY=y ? y-1 : y;
}
/**
@ -496,7 +528,10 @@ global void CommandHaulOil(Unit* unit,Unit* dest,int flush)
{
Command* command;
if( !(command=GetNextCommand(unit,flush)) ) {
if( unit->Type->Building ) {
// FIXME: should find a better way for pending commands.
command=&unit->PendCommand;
} else if( !(command=GetNextCommand(unit,flush)) ) {
return;
}
@ -515,8 +550,6 @@ global void CommandHaulOil(Unit* unit,Unit* dest,int flush)
command->Data.Move.DX=dest->X;
command->Data.Move.DY=dest->Y;
#endif
unit->PendCommand=*command;
}
/**
@ -527,6 +560,7 @@ global void CommandHaulOil(Unit* unit,Unit* dest,int flush)
*/
global void CommandReturnGoods(Unit* unit,int flush)
{
// FIXME: flush, and command que not supported!
unit->NextCount=1;
unit->NextFlush=1;
@ -596,10 +630,12 @@ global void CommandTrainUnit(Unit* unit,UnitType* what,int flush)
**
** @param unit pointer to unit.
*/
global void CommandCancelTraining(Unit* unit)
global void CommandCancelTraining(Unit* unit,int slot)
{
int i;
DebugCheck( slot );
if ( --unit->Command.Data.Train.Count ) {
for( i = 0; i < MAX_UNIT_TRAIN-1; i++ ) {
unit->Command.Data.Train.What[i] =
@ -640,7 +676,7 @@ global void CommandUpgradeTo(Unit* unit,UnitType* what,int flush)
** @param unit pointer to unit.
** @param flush if true, flush command queue.
*/
global void CommandCancelUpgradeTo(Unit* unit,int flush)
global void CommandCancelUpgradeTo(Unit* unit)
{
unit->Command.Action=UnitActionStill;
@ -655,11 +691,12 @@ global void CommandCancelUpgradeTo(Unit* unit,int flush)
** @param what what to research.
** @param flush if true, flush command queue.
*/
global void CommandResearch(Unit* unit,int what,int flush)
global void CommandResearch(Unit* unit,Upgrade* what,int flush)
{
unit->NextCount=1;
unit->NextFlush=1;
DebugLevel0(__FUNCTION__": FIXME: must support command queing!!");
unit->NextCommand[0].Action=UnitActionResearch;
unit->NextCommand[0].Data.Research.Ticks=0;
unit->NextCommand[0].Data.Research.What=what;
@ -674,7 +711,7 @@ global void CommandResearch(Unit* unit,int what,int flush)
** @param unit pointer to unit.
** @param flush if true, flush command queue.
*/
global void CommandCancelResearch(Unit* unit,int flush)
global void CommandCancelResearch(Unit* unit)
{
unit->Command.Action=UnitActionStill;
@ -702,7 +739,10 @@ global void CommandDemolish(Unit* unit,int x,int y,Unit* dest,int flush)
}
);
if( !(command=GetNextCommand(unit,flush)) ) {
if( unit->Type->Building ) {
// FIXME: should find a better way for pending commands.
command=&unit->PendCommand;
} else if( !(command=GetNextCommand(unit,flush)) ) {
return;
}
@ -724,8 +764,6 @@ global void CommandDemolish(Unit* unit,int x,int y,Unit* dest,int flush)
command->Data.Move.SY=unit->Y;
command->Data.Move.DX=x;
command->Data.Move.DY=y;
unit->PendCommand=*command;
}
//@}

View file

@ -63,7 +63,7 @@ typedef struct _ai_command_ {
} AiCommand;
typedef struct _ai_force_ {
int Peasant;
int Worker;
int Footman;
int Archer;
int Ballista;
@ -187,12 +187,12 @@ local int AiFindFreeWorkers(Unit** table)
Unit* unit;
nunits = FindPlayerUnitsByType(AiPlayer->Player,
UnitTypes+AiChooseRace(UnitPeasant),table);
UnitTypes+AiChooseRace(UnitTypeHumanWorker->Type),table);
/*
nunits += FindPlayerUnitsByType(AiPlayer->Player,
UnitTypes+AiChooseRace(UnitPeasantWithGold),table+nunits);
UnitTypes+AiChooseRace(UnitTypeHumanWorkerWithGold),table+nunits);
nunits += FindPlayerUnitsByType(AiPlayer->Player,
UnitTypes+AiChooseRace(UnitPeasantWithWood),table+nunits);
UnitTypes+AiChooseRace(UnitTypeHumanWorkerWithWood),table+nunits);
*/
// Remove all workers on the way building
@ -700,7 +700,7 @@ local int AiTrainCreature(int type)
int nunits;
Player* player;
DebugLevel3(__FUNCTION__":\n");
if(type == AiChooseRace(UnitPeasant))
if(type == AiChooseRace(UnitTypeHumanWorker->Type))
{nunits = AiFindHalls(units);}
else
{
@ -898,8 +898,8 @@ local void AiAssignWorker(void)
action=workers[w]->Command.Action;
if(action==UnitActionStill)
{
if(type == AiChooseRace(UnitPeasantWithGold) ||
type == AiChooseRace(UnitPeasantWithWood))
if(type == AiChooseRace(UnitTypeHumanWorkerWithGold->Type) ||
type == AiChooseRace(UnitTypeHumanWorkerWithWood->Type))
{CommandReturnGoods(workers[w],1);}
else
{
@ -921,8 +921,8 @@ local void AiAssignWorker(void)
for(w=0; w<num_worker; ++w)
{
type=workers[w]->Type->Type;
if(type == AiChooseRace(UnitPeasantWithWood) ||
type == AiChooseRace(UnitPeasantWithGold))
if(type == AiChooseRace(UnitTypeHumanWorkerWithWood->Type) ||
type == AiChooseRace(UnitTypeHumanWorkerWithGold->Type))
{CommandReturnGoods(workers[w],1);}
else
{
@ -945,8 +945,8 @@ local void AiAssignWorker(void)
for(w=0; w<num_worker; ++w)
{
type=workers[w]->Type->Type;
if(type == AiChooseRace(UnitPeasantWithWood) ||
type == AiChooseRace(UnitPeasantWithGold))
if(type == AiChooseRace(UnitTypeHumanWorkerWithWood->Type) ||
type == AiChooseRace(UnitTypeHumanWorkerWithGold->Type))
{CommandReturnGoods(workers[w],1);}
else
{
@ -968,8 +968,8 @@ local void AiAssignWorker(void)
if(action==UnitActionStill)
{
type=workers[w]->Type->Type;
if(type==AiChooseRace(UnitPeasantWithGold)
|| type==AiChooseRace(UnitPeasantWithWood))
if(type==AiChooseRace(UnitTypeHumanWorkerWithGold->Type)
|| type==AiChooseRace(UnitTypeHumanWorkerWithWood->Type))
{
if(AiPlayer->MainHall)
{
@ -998,7 +998,7 @@ local void AiAssignWorker(void)
// Send standing workers home.
//
num_worker = FindPlayerUnitsByType(AiPlayer->Player,
UnitTypes+AiChooseRace(UnitPeasantWithGold),workers);
UnitTypes+AiChooseRace(UnitTypeHumanWorkerWithGold->Type),workers);
DebugLevel3("Gold %d\n",num_worker);
if(num_worker)
{ // assign the non working
@ -1015,7 +1015,7 @@ local void AiAssignWorker(void)
}
}
num_worker = FindPlayerUnitsByType(AiPlayer->Player,
UnitTypes+AiChooseRace(UnitPeasantWithWood),workers);
UnitTypes+AiChooseRace(UnitTypeHumanWorkerWithWood->Type),workers);
DebugLevel3("Wood %d\n",num_worker);
if(num_worker)
{ // assign the non working
@ -1151,8 +1151,13 @@ local int AiNoBuilding(int type)
*/
local int AiNeedBuilding(int type)
{
UnitType* typep;
type = AiChooseRace(type);
// FIXME: johns should use dependence rules some time
typep=UnitTypes+type;
if( typep==UnitTypeHumanWorker || typep==UnitTypeOrcWorker ) {
if(AiNoBuilding(UnitTownHall)) return 1;
}
switch(type)
{
case UnitBallista: case UnitCatapult:
@ -1164,9 +1169,6 @@ local int AiNeedBuilding(int type)
case UnitFootman: case UnitGrunt:
if(AiNoBuilding(UnitTownHall)) return 1;
if(AiNoBuilding(UnitBarracksHuman)) return 1;
case UnitPeasant: case UnitPeon:
if(AiNoBuilding(UnitTownHall)) return 1;
break;
}
return 0;
}
@ -1182,11 +1184,12 @@ local int AiCommandBuild(int type,int number,int action)
type = AiChooseRace(type);
if(AiBuildingUnitType(type)) {return 0;} //already training
AiCountUnits();
if(type == AiChooseRace(UnitPeasant))
if(type == AiChooseRace(UnitTypeHumanWorker->Type))
{
if((UnitTypesCount[type]
+UnitTypesCount[AiChooseRace(UnitPeasantWithGold)]
+UnitTypesCount[AiChooseRace(UnitPeasantWithWood)]) >= number)
+UnitTypesCount[AiChooseRace(UnitTypeHumanWorkerWithGold->Type)]
+UnitTypesCount[AiChooseRace(UnitTypeHumanWorkerWithWood->Type)])
>= number)
return 1;
}
else { if(UnitTypesCount[type] >= number) return 1; }
@ -1229,8 +1232,8 @@ local int AiCommandAttack(int unittype,int attack,int home)
*/
local int AiCommandArmy(int home, int attack)
{
if(!AiCommandBuild(UnitPeasant,ForceAtHome[home].Peasant +
ForceAttacking[attack].Peasant, AiCmdCreature)) {return 0;}
if(!AiCommandBuild(UnitTypeHumanWorker->Type,ForceAtHome[home].Worker +
ForceAttacking[attack].Worker, AiCmdCreature)) {return 0;}
if(!AiCommandBuild(UnitFootman,ForceAtHome[home].Footman +
ForceAttacking[attack].Footman, AiCmdCreature)) {return 0;}
if(!AiCommandBuild(UnitArcher,ForceAtHome[home].Archer +
@ -1355,7 +1358,7 @@ global void AiTrainingComplete(Unit* unit,Unit* what)
}
// FIXME: Should I put an AiPlayer pointer into the player struct?
AiPlayer=&Ais[unit->Player->Player];
if(what->Type->CowerPeon) {
if(what->Type->CowerWorker) {
AiAssignWorker();
}
AiClearBuildUnitType(what->Type->Type);

View file

@ -26,6 +26,7 @@
#include "unittype.h"
#include "unit.h"
#include "upgrade.h"
/*----------------------------------------------------------------------------
-- Declarations
@ -40,13 +41,15 @@
----------------------------------------------------------------------------*/
/// Prepare command stop
extern void CommandStopUnit(Unit* unit,int flush);
extern void CommandStopUnit(Unit* unit);
/// Prepare command stand ground
extern void CommandStandGround(Unit* unit,int flush);
/// Prepare command follow
extern void CommandFollow(Unit* unit,Unit* dest,int flush);
/// Prepare command move
extern void CommandMoveUnit(Unit* unit,int x,int y,int flush);
extern void CommandMove(Unit* unit,int x,int y,int flush);
/// Prepare command repair
extern void CommandRepair(Unit* unit,int x,int y,int flush);
extern void CommandRepair(Unit* unit,int x,int y,Unit* dest,int flush);
/// Prepare command attack
extern void CommandAttack(Unit* unit,int x,int y,Unit* dest,int flush);
/// Prepare command attack ground
@ -58,9 +61,9 @@ extern void CommandBoard(Unit* unit,Unit* dest,int flush);
/// Prepare command unload
extern void CommandUnload(Unit* unit,int x,int y,Unit* what,int flush);
/// Prepare command build
extern void CommandBuildBuilding(Unit* unit,int x,int y,UnitType* what,int flush);
extern void CommandBuildBuilding(Unit*,int,int,UnitType*,int);
/// Prepare command cancel build
extern void CommandCancelBuilding(Unit* unit,Unit* preon);
extern void CommandCancelBuilding(Unit* unit,Unit* worker);
/// Prepare command harvest
extern void CommandHarvest(Unit* unit,int x,int y,int flush);
/// Prepare command mine
@ -72,15 +75,15 @@ extern void CommandReturnGoods(Unit* unit,int flush);
/// Prepare command train
extern void CommandTrainUnit(Unit* unit,UnitType* what,int flush);
/// Prepare command cancel training
extern void CommandCancelTraining(Unit* unit);
extern void CommandCancelTraining(Unit* unit,int slot);
/// Prepare command upgrade to
extern void CommandUpgradeTo(Unit* unit,UnitType* what,int flush);
/// Prepare command cancel upgrade to
extern void CommandCancelUpgradeTo(Unit* unit,int flush);
extern void CommandCancelUpgradeTo(Unit* unit);
/// Prepare command research
extern void CommandResearch(Unit* unit,int what,int flush);
extern void CommandResearch(Unit* unit,Upgrade* what,int flush);
/// Prepare command cancel research
extern void CommandCancelResearch(Unit* unit,int flush);
extern void CommandCancelResearch(Unit* unit);
/// Prepare command upgrade
//extern void CommandUpgradeUnit(Unit* unit,int what,int flush);
/// Prepare command demolish

View file

@ -26,11 +26,14 @@
#include "unittype.h"
#include "unit.h"
#include "upgrade.h"
/*----------------------------------------------------------------------------
-- Defines
----------------------------------------------------------------------------*/
#define NetworkLag 30 /// Debuging network lag (# frames)
/*----------------------------------------------------------------------------
-- Variables
----------------------------------------------------------------------------*/
@ -48,52 +51,55 @@ extern void ExitNetwork(void); /// cleanup network module
extern void NetworkEvent(void); /// handle network events
extern void NetworkSync(void); /// hold in sync
extern void NetworkQuit(void); /// quit game
extern void NetworkCommands(void); /// get all network commands
extern void NetworkChatMessage(const char*msg); /// send chat message
/// Send stop command
extern void SendCommandStopUnit(Unit* unit);
/// Send stand ground command
extern void SendCommandStandGround(Unit* unit);
extern void SendCommandStandGround(Unit* unit,int flush);
/// Send follow command
extern void SendCommandFollow(Unit* unit,Unit* dest,int flush);
/// Send move command
extern void SendCommandMoveUnit(Unit* unit,int x,int y);
extern void SendCommandMove(Unit* unit,int x,int y,int flush);
/// Send repair command
extern void SendCommandRepair(Unit* unit,int x,int y);
extern void SendCommandRepair(Unit* unit,int x,int y,Unit* dest,int flush);
/// Send attack command
extern void SendCommandAttack(Unit* unit,int x,int y,Unit* dest);
extern void SendCommandAttack(Unit* unit,int x,int y,Unit* dest,int flush);
/// Send attack ground command
extern void SendCommandAttackGround(Unit* unit,int x,int y);
extern void SendCommandAttackGround(Unit* unit,int x,int y,int flush);
/// Send patrol command
extern void SendCommandPatrolUnit(Unit* unit,int x,int y);
extern void SendCommandPatrol(Unit* unit,int x,int y,int flush);
/// Send board command
extern void SendCommandBoard(Unit* unit,Unit* dest);
extern void SendCommandBoard(Unit* unit,int x,int y,Unit* dest,int flush);
/// Send unload command
extern void SendCommandUnload(Unit* unit,int x,int y,Unit* what);
extern void SendCommandUnload(Unit* unit,int x,int y,Unit* what,int flush);
/// Send build building command
extern void SendCommandBuildBuilding(Unit* unit,int x,int y,UnitType* what);
extern void SendCommandBuildBuilding(Unit*,int,int,UnitType*,int);
/// Send cancel building command
extern void SendCommandCancelBuilding(Unit* unit,Unit* peon);
/// Send harvest command
extern void SendCommandHarvest(Unit* unit,int x,int y);
extern void SendCommandHarvest(Unit* unit,int x,int y,int flush);
/// Send mine gold command
extern void SendCommandMineGold(Unit* unit,Unit* dest);
extern void SendCommandMineGold(Unit* unit,Unit* dest,int flush);
/// Send haul oil command
extern void SendCommandHaulOil(Unit* unit,Unit* dest);
extern void SendCommandHaulOil(Unit* unit,Unit* dest,int flush);
/// Send return goods command
extern void SendCommandReturnGoods(Unit* unit);
extern void SendCommandReturnGoods(Unit* unit,int flush);
/// Send train command
extern void SendCommandTrainUnit(Unit* unit,UnitType* what);
extern void SendCommandTrainUnit(Unit* unit,UnitType* what,int flush);
/// Send cancel training command
extern void SendCommandCancelTraining(Unit* unit);
extern void SendCommandCancelTraining(Unit* unit,int slot);
/// Send upgrade to command
extern void SendCommandUpgradeTo(Unit* unit,UnitType* what);
extern void SendCommandUpgradeTo(Unit* unit,UnitType* what,int flush);
/// Send cancel upgrade to command
extern void SendCommandCancelUpgradeTo(Unit* unit);
/// Send research command
extern void SendCommandResearch(Unit* unit,int what);
extern void SendCommandResearch(Unit* unit,Upgrade* what,int flush);
/// Send cancel research command
extern void SendCommandCancelResearch(Unit* unit);
/// Send demolish command
extern void SendCommandDemolish(Unit* unit,int x,int y,Unit* dest);
extern void SendCommandDemolish(Unit* unit,int x,int y,Unit* dest,int flush);
//@}

View file

@ -26,14 +26,13 @@
#ifndef __STRUCT_PLAYER__
#define __STRUCT_PLAYER__
typedef struct _player_ Player;
// #include "player.h" // recursive!
typedef struct _player_ Player; // recursive includes :(
#endif
#include "video.h"
#include "unittype.h"
#include "upgrade_structs.h"
#include "upgrade.h"
/*----------------------------------------------------------------------------
-- Declarations
@ -56,6 +55,7 @@ enum _unit_action_ {
UnitActionStill, /// unit stand still, does nothing
UnitActionStandGround, /// unit stands ground
UnitActionFollow, /// unit follows units
UnitActionMove, /// unit moves to position/unit
UnitActionAttack, /// unit attacks position/unit
UnitActionDie, /// unit dies
@ -116,7 +116,7 @@ struct _command_ {
int Val; /// Counter
int Sub;
int Cancel; /// Cancel construction
Unit* Peon; /// Peon/Peasant building the unit
Unit* Worker; /// Worker building the unit
} Builded; // builded:
struct {
unsigned Ticks; /// Ticks to complete
@ -131,7 +131,7 @@ struct _command_ {
} UpgradeTo; /// upgradeto:
struct {
unsigned Ticks; /// Ticks to complete
int What; /// Unit researching this
Upgrade* What; /// Unit researching this
} Research; /// research:
struct {
unsigned Active; /// how much units are in the goldmine
@ -163,8 +163,9 @@ typedef enum _unit_voice_group_ {
*/
struct _unit_ {
#ifdef NEW_UNIT
short Refs; /// Reference counter
UnitRef Slot; /// Assignd slot number
// int is faster than shorts.
unsigned Refs; /// Reference counter
unsigned Slot; /// Assignd slot number
Unit** UnitSlot; /// slot pointer of Units
Unit** PlayerSlot; /// slot pointer of Player->Units
Unit* Next; /// generic link pointer
@ -341,6 +342,8 @@ extern Unit* Selected[MaxSelectable]; /// currently selected units
extern void InitUnitsMemory(void);
/// Free memory used by unit
extern void FreeUnitMemory(Unit* unit);
/// Release an unit.
extern void ReleaseUnit(Unit* unit);
/// Create a new unit
extern Unit* MakeUnit(UnitType* type,Player* player);
/// Create a new unit and place on map

View file

@ -152,17 +152,17 @@ struct _unit_type_ {
unsigned AirUnit : 1; /// Air animated
unsigned SeaUnit : 1; /// Sea animated
unsigned ExplodeWhenKilled : 1; /// Death explosion animated
unsigned Critter : 1; ///
unsigned Building : 1; ///
unsigned Submarine : 1; ///
unsigned CanSeeSubmarine : 1; ///
unsigned CowerPeon : 1; ///
unsigned Tanker : 1; ///
unsigned Transporter : 1; ///
unsigned GivesOil : 1; ///
unsigned StoresGold : 1; ///
unsigned Critter : 1; /// Unit is controlled by nobody
unsigned Building : 1; /// Building
unsigned Submarine : 1; /// Is only visible by CanSeeSubmarine
unsigned CanSeeSubmarine : 1; /// Only this units can see Submarine
unsigned CowerWorker : 1; /// Is a worker, runs away if attcked
unsigned Tanker : 1; /// FIXME: used? Can transport oil
unsigned Transporter : 1; /// can transport units
unsigned GivesOil : 1; /// We get here oil
unsigned StoresGold : 1; /// We can store gold/wood here
unsigned Vanishes : 1; /// Corpes & destroyed places.
unsigned GroundAttack : 1; ///
unsigned GroundAttack : 1; /// Can do command ground attack
unsigned IsUndead : 1; ///
unsigned ShoreBuilding : 1; ///
unsigned CanCastSpell : 1; ///
@ -230,8 +230,8 @@ struct _unit_type_ {
#define UnitDentarg 0x17
#define UnitKhadgar 0x18
#define UnitGromHellscream 0x19
#define UnitTankerHuman 0x1A
#define UnitTankerOrc 0x1B
//#define UnitTankerHuman 0x1A
//#define UnitTankerOrc 0x1B
#define UnitTransportHuman 0x1C
#define UnitTransportOrc 0x1D
#define UnitElvenDestroyer 0x1E
@ -319,12 +319,12 @@ struct _unit_type_ {
// This are internal used unit-types:
#define UnitPeasantWithGold 0x6E
#define UnitPeonWithGold 0x6F
#define UnitPeasantWithWood 0x70
#define UnitPeonWithWood 0x71
#define UnitTankerHumanFull 0x72
#define UnitTankerOrcFull 0x73
//#define UnitPeasantWithGold 0x6E
//#define UnitPeonWithGold 0x6F
//#define UnitPeasantWithWood 0x70
//#define UnitPeonWithWood 0x71
//#define UnitTankerHumanFull 0x72
//#define UnitTankerOrcFull 0x73
#endif
@ -342,6 +342,16 @@ extern char UnitTypeType[]; /// unit type type
extern UnitType UnitTypes[UnitTypeInternalMax]; /// all unit types
extern UnitType*UnitTypeGoldMine; /// Gold-mine unit type pointer.
extern UnitType*UnitTypeHumanTanker; /// orc tanker unit type pointer.
extern UnitType*UnitTypeOrcTanker; /// human tanker unit type pointer.
extern UnitType*UnitTypeHumanTankerFull;/// orc tanker full unit type pointer.
extern UnitType*UnitTypeOrcTankerFull; /// human tanker full unit type pointer.
extern UnitType*UnitTypeHumanWorker; /// Human worker.
extern UnitType*UnitTypeOrcWorker; /// Orc worker.
extern UnitType*UnitTypeHumanWorkerWithGold; /// Human worker with gold.
extern UnitType*UnitTypeOrcWorkerWithGold; /// Orc worker with gold.
extern UnitType*UnitTypeHumanWorkerWithWood; /// Human worker with wood.
extern UnitType*UnitTypeOrcWorkerWithWood; /// Orc worker with wood.
/*----------------------------------------------------------------------------
-- Functions

View file

@ -24,10 +24,15 @@
-- Includes
----------------------------------------------------------------------------*/
#include "player.h"
#ifndef __STRUCT_PLAYER__
#define __STRUCT_PLAYER__
typedef struct _player_ Player; // recursive includes :(
#endif
#include "upgrade_structs.h"
/*----------------------------------------------------------------------------
-- Declartion
-- Declarations
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
@ -46,9 +51,6 @@ extern void ParsePudUGRD(const char*,int); /// parse pud ugrd table
extern void UpgradesCclRegister(void); /// Register CCL features for upgrades
// CHAOS PUR
/*
@ -153,8 +155,9 @@ void UpgradeIncTime2( Player* player, char* sid, int amount ); // by ident strin
// this function will mark upgrade done and do all required modifications to
// unit types and will modify allow/forbid maps
void UpgradeAcquire( Player* player, int id ); // called by UpgradeIncTime() when timer reached
void UpgradeAcquire2( Player* player, char* sid ); // by ident string
// called by UpgradeIncTime() when timer reached
void UpgradeAcquire( Player* player,Upgrade* upgrade );
// for now it will be empty?
// perhaps acquired upgrade can be lost if ( for example ) a building is lost

View file

@ -40,6 +40,9 @@
#endif
#include "freecraft.h"
#ifndef NEW_NETWORK // {
#include "video.h"
#include "sound_id.h"
#include "unitsound.h"
@ -50,13 +53,6 @@
#include "network.h"
#include "map.h"
// FIXME: cade: this is a hack, not the right place
#include "interface.h"
extern global enum KeyModifiers_e KeyModifiers;/// current keyboard modifiers
#define flush \
(unit->Player==ThisPlayer && !(KeyModifiers&ModifierShift))
/*----------------------------------------------------------------------------
-- Declaration
----------------------------------------------------------------------------*/
@ -108,6 +104,7 @@ enum __message_type__ {
MessageCommandStop, /// unit command stop
MessageCommandStand, /// unit command stand ground
MessageCommandFollow, /// unit command follow
MessageCommandMove, /// unit command move
MessageCommandRepair, /// unit command repair
MessageCommandAttack, /// unit command attack
@ -130,6 +127,7 @@ enum __message_type__ {
MessageCommandDemolish, /// unit command demolish
};
/// Send command over the network
extern void NetworkSendCommand(int command,Unit* unit,int x,int y
,Unit* dest,UnitType* type,int flags);
@ -389,8 +387,12 @@ local void CommandLog(const char* name,const Unit* unit,int flag,
fprintf(logf,"(log %d 'U%Zd '%s '%s",
FrameCounter,UnitNumber(unit),name,
flag ? "flush" : "append");
if( position ) {
fprintf(logf," (%d %d)",x,y);
switch( position ) {
case 1:
fprintf(logf," (%d %d)",x,y);
break;
case 2:
fprintf(logf," %d",x);
}
if( dest ) {
fprintf(logf," 'U%Zd",UnitNumber(unit));
@ -418,11 +420,11 @@ local void CommandLog(const char* name,const Unit* unit,int flag,
*/
global void SendCommandStopUnit(Unit* unit)
{
CommandLog("stop",unit,flush,0,0,0,NULL,NULL);
CommandLog("stop",unit,1,0,0,0,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandStopUnit(unit,flush);
CommandStopUnit(unit);
} else {
NetworkSendCommand(MessageCommandStop,unit,0,0,NoUnitP,0,flush);
NetworkSendCommand(MessageCommandStop,unit,0,0,NoUnitP,0,1);
}
}
@ -430,10 +432,11 @@ global void SendCommandStopUnit(Unit* unit)
** Send command: Unit stand ground.
**
** @param unit pointer to unit.
** @param flush Flag flush all pending commands.
*/
global void SendCommandStandGround(Unit* unit)
global void SendCommandStandGround(Unit* unit,int flush)
{
CommandLog("stand-ground",unit,flush,0,0,0,NULL,NULL);
CommandLog("stand-ground",unit,flush,0,0,0,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandStandGround(unit,flush);
} else {
@ -442,17 +445,36 @@ global void SendCommandStandGround(Unit* unit)
}
/**
** Send command: Unit move to position.
** Send command: Follow unit to position.
**
** @param unit pointer to unit.
** @param x X map tile position to move to.
** @param y Y map tile position to move to.
** @param flush Flag flush all pending commands.
*/
global void SendCommandMoveUnit(Unit* unit,int x,int y)
global void SendCommandFollow(Unit* unit,Unit* dest,int flush)
{
CommandLog("move",unit,flush,1,x,y,NULL,NULL);
CommandLog("move",unit,flush,0,0,0,dest,NULL);
if( NetworkFildes==-1 ) {
CommandMoveUnit(unit,x,y,flush);
CommandFollow(unit,dest,flush);
} else {
NetworkSendCommand(MessageCommandFollow,unit,0,0,dest,0,flush);
}
}
/**
** Send command: Move unit to position.
**
** @param unit pointer to unit.
** @param x X map tile position to move to.
** @param y Y map tile position to move to.
** @param flush Flag flush all pending commands.
*/
global void SendCommandMove(Unit* unit,int x,int y,int flush)
{
CommandLog("move",unit,flush,1,x,y,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandMove(unit,x,y,flush);
} else {
NetworkSendCommand(MessageCommandMove,unit,x,y,NoUnitP,0,flush);
}
@ -464,14 +486,15 @@ global void SendCommandMoveUnit(Unit* unit,int x,int y)
** @param unit pointer to unit.
** @param x X map tile position to repair.
** @param y Y map tile position to repair.
** @param flush Flag flush all pending commands.
*/
global void SendCommandRepair(Unit* unit,int x,int y)
global void SendCommandRepair(Unit* unit,int x,int y,Unit* dest,int flush)
{
CommandLog("repair",unit,flush,1,x,y,NULL,NULL);
CommandLog("repair",unit,flush,1,x,y,dest,NULL);
if( NetworkFildes==-1 ) {
CommandRepair(unit,x,y,flush);
CommandRepair(unit,x,y,dest,flush);
} else {
NetworkSendCommand(MessageCommandRepair,unit,x,y,NoUnitP,0,flush);
NetworkSendCommand(MessageCommandRepair,unit,x,y,dest,0,flush);
}
}
@ -482,8 +505,9 @@ global void SendCommandRepair(Unit* unit,int x,int y)
** @param x X map tile position to attack.
** @param y Y map tile position to attack.
** @param attack or !=NoUnitP unit to be attacked.
** @param flush Flag flush all pending commands.
*/
global void SendCommandAttack(Unit* unit,int x,int y,Unit* attack)
global void SendCommandAttack(Unit* unit,int x,int y,Unit* attack,int flush)
{
CommandLog("attack",unit,flush,1,x,y,attack,NULL);
if( NetworkFildes==-1 ) {
@ -499,10 +523,11 @@ global void SendCommandAttack(Unit* unit,int x,int y,Unit* attack)
** @param unit pointer to unit.
** @param x X map tile position to fire on.
** @param y Y map tile position to fire on.
** @param flush Flag flush all pending commands.
*/
global void SendCommandAttackGround(Unit* unit,int x,int y)
global void SendCommandAttackGround(Unit* unit,int x,int y,int flush)
{
CommandLog("attack-ground",unit,flush,1,x,y,NULL,NULL);
CommandLog("attack-ground",unit,flush,1,x,y,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandAttackGround(unit,x,y,flush);
} else {
@ -516,10 +541,11 @@ global void SendCommandAttackGround(Unit* unit,int x,int y)
** @param unit pointer to unit.
** @param x X map tile position to patrol between.
** @param y Y map tile position to patrol between.
** @param flush Flag flush all pending commands.
*/
global void SendCommandPatrolUnit(Unit* unit,int x,int y)
global void SendCommandPatrol(Unit* unit,int x,int y,int flush)
{
CommandLog("patrol",unit,flush,1,x,y,NULL,NULL);
CommandLog("patrol",unit,flush,1,x,y,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandPatrolUnit(unit,x,y,flush);
} else {
@ -532,14 +558,15 @@ global void SendCommandPatrolUnit(Unit* unit,int x,int y)
**
** @param unit pointer to unit.
** @param dest Destination to be boarded.
** @param flush Flag flush all pending commands.
*/
global void SendCommandBoard(Unit* unit,Unit* dest)
global void SendCommandBoard(Unit* unit,int x,int y,Unit* dest,int flush)
{
CommandLog("board",unit,flush,0,0,0,dest,NULL);
CommandLog("board",unit,flush,1,x,y,dest,NULL);
if( NetworkFildes==-1 ) {
CommandBoard(unit,dest,flush);
} else {
NetworkSendCommand(MessageCommandBoard,unit,0,0,dest,0,flush);
NetworkSendCommand(MessageCommandBoard,unit,x,y,dest,0,flush);
}
}
@ -550,8 +577,9 @@ global void SendCommandBoard(Unit* unit,Unit* dest)
** @param x X map tile position of unload.
** @param y Y map tile position of unload.
** @param what Passagier to be unloaded.
** @param flush Flag flush all pending commands.
*/
global void SendCommandUnload(Unit* unit,int x,int y,Unit* what)
global void SendCommandUnload(Unit* unit,int x,int y,Unit* what,int flush)
{
CommandLog("unload",unit,flush,1,x,y,what,NULL);
if( NetworkFildes==-1 ) {
@ -568,8 +596,10 @@ global void SendCommandUnload(Unit* unit,int x,int y,Unit* what)
** @param x X map tile position of construction.
** @param y Y map tile position of construction.
** @param what pointer to unit-type of the building.
** @param flush Flag flush all pending commands.
*/
global void SendCommandBuildBuilding(Unit* unit,int x,int y,UnitType* what)
global void SendCommandBuildBuilding(Unit* unit,int x,int y
,UnitType* what,int flush)
{
CommandLog("build",unit,flush,1,x,y,NULL,what->Ident);
if( NetworkFildes==-1 ) {
@ -584,14 +614,14 @@ global void SendCommandBuildBuilding(Unit* unit,int x,int y,UnitType* what)
**
** @param unit pointer to unit.
*/
global void SendCommandCancelBuilding(Unit* unit,Unit* peon)
global void SendCommandCancelBuilding(Unit* unit,Unit* worker)
{
// FIXME: currently unit and peon are same?
CommandLog("cancel-build",unit,flush,0,0,0,peon,NULL);
// FIXME: currently unit and worker are same?
CommandLog("cancel-build",unit,1,0,0,0,worker,NULL);
if( NetworkFildes==-1 ) {
CommandCancelBuilding(unit,peon);
CommandCancelBuilding(unit,worker);
} else {
NetworkSendCommand(MessageCommandCancelBuild,unit,0,0,peon,0,0);
NetworkSendCommand(MessageCommandCancelBuild,unit,0,0,worker,0,1);
}
}
@ -601,10 +631,11 @@ global void SendCommandCancelBuilding(Unit* unit,Unit* peon)
** @param unit pointer to unit.
** @param x X map tile position where to harvest.
** @param y Y map tile position where to harvest.
** @param flush Flag flush all pending commands.
*/
global void SendCommandHarvest(Unit* unit,int x,int y)
global void SendCommandHarvest(Unit* unit,int x,int y,int flush)
{
CommandLog("harvest",unit,flush,1,x,y,NULL,NULL);
CommandLog("harvest",unit,flush,1,x,y,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandHarvest(unit,x,y,flush);
} else {
@ -617,8 +648,9 @@ global void SendCommandHarvest(Unit* unit,int x,int y)
**
** @param unit pointer to unit.
** @param dest pointer to destination (gold-mine).
** @param flush Flag flush all pending commands.
*/
global void SendCommandMineGold(Unit* unit,Unit* dest)
global void SendCommandMineGold(Unit* unit,Unit* dest,int flush)
{
CommandLog("mine",unit,flush,0,0,0,dest,NULL);
if( NetworkFildes==-1 ) {
@ -633,8 +665,9 @@ global void SendCommandMineGold(Unit* unit,Unit* dest)
**
** @param unit pointer to unit.
** @param dest pointer to destination (oil-platform).
** @param flush Flag flush all pending commands.
*/
global void SendCommandHaulOil(Unit* unit,Unit* dest)
global void SendCommandHaulOil(Unit* unit,Unit* dest,int flush)
{
CommandLog("haul",unit,flush,0,0,0,dest,NULL);
if( NetworkFildes==-1 ) {
@ -648,10 +681,11 @@ global void SendCommandHaulOil(Unit* unit,Unit* dest)
** Send command: Unit return goods.
**
** @param unit pointer to unit.
** @param flush Flag flush all pending commands.
*/
global void SendCommandReturnGoods(Unit* unit)
global void SendCommandReturnGoods(Unit* unit,int flush)
{
CommandLog("return",unit,flush,0,0,0,NULL,NULL);
CommandLog("return",unit,flush,0,0,0,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandReturnGoods(unit,flush);
} else {
@ -664,8 +698,9 @@ global void SendCommandReturnGoods(Unit* unit)
**
** @param unit pointer to unit.
** @param what pointer to unit-type of the unit to be trained.
** @param flush Flag flush all pending commands.
*/
global void SendCommandTrainUnit(Unit* unit,UnitType* what)
global void SendCommandTrainUnit(Unit* unit,UnitType* what,int flush)
{
CommandLog("train",unit,flush,0,0,0,NULL,what->Ident);
if( NetworkFildes==-1 ) {
@ -680,13 +715,13 @@ global void SendCommandTrainUnit(Unit* unit,UnitType* what)
**
** @param unit pointer to unit.
*/
global void SendCommandCancelTraining(Unit* unit)
global void SendCommandCancelTraining(Unit* unit,int slot)
{
CommandLog("cancel-train",unit,flush,0,0,0,NULL,NULL);
CommandLog("cancel-train",unit,1,2,slot,0,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandCancelTraining(unit);
CommandCancelTraining(unit,slot);
} else {
NetworkSendCommand(MessageCommandCancelTrain,unit,0,0,NoUnitP,0,0);
NetworkSendCommand(MessageCommandCancelTrain,unit,slot,0,NoUnitP,0,1);
}
}
@ -695,8 +730,9 @@ global void SendCommandCancelTraining(Unit* unit)
**
** @param unit pointer to unit.
** @param what pointer to unit-type of the unit upgrade.
** @param flush Flag flush all pending commands.
*/
global void SendCommandUpgradeTo(Unit* unit,UnitType* what)
global void SendCommandUpgradeTo(Unit* unit,UnitType* what,int flush)
{
CommandLog("upgrade-to",unit,flush,0,0,0,NULL,what->Ident);
if( NetworkFildes==-1 ) {
@ -713,12 +749,12 @@ global void SendCommandUpgradeTo(Unit* unit,UnitType* what)
*/
global void SendCommandCancelUpgradeTo(Unit* unit)
{
CommandLog("cancel-upgrade-to",unit,flush,0,0,0,NULL,NULL);
CommandLog("cancel-upgrade-to",unit,1,0,0,0,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandCancelUpgradeTo(unit,flush);
CommandCancelUpgradeTo(unit);
} else {
NetworkSendCommand(MessageCommandCancelUpgrade,unit
,0,0,NoUnitP,NULL,flush);
,0,0,NoUnitP,NULL,1);
}
}
@ -727,14 +763,16 @@ global void SendCommandCancelUpgradeTo(Unit* unit)
**
** @param unit pointer to unit.
** @param what research-type of the research.
** @param flush Flag flush all pending commands.
*/
global void SendCommandResearch(Unit* unit,int what)
global void SendCommandResearch(Unit* unit,Upgrade* what,int flush)
{
CommandLog("research",unit,flush,0,0,0,NULL,Upgrades[what].Ident);
CommandLog("research",unit,flush,0,0,0,NULL,what->Ident);
if( NetworkFildes==-1 ) {
CommandResearch(unit,what,flush);
} else {
NetworkSendCommand(MessageCommandResearch,unit,what,0,NoUnitP,0,flush);
NetworkSendCommand(MessageCommandResearch,unit
,what-Upgrades,0,NoUnitP,0,flush);
}
}
@ -745,12 +783,12 @@ global void SendCommandResearch(Unit* unit,int what)
*/
global void SendCommandCancelResearch(Unit* unit)
{
CommandLog("cancel-research",unit,flush,0,0,0,NULL,NULL);
CommandLog("cancel-research",unit,1,0,0,0,NoUnitP,NULL);
if( NetworkFildes==-1 ) {
CommandCancelResearch(unit,flush);
CommandCancelResearch(unit);
} else {
NetworkSendCommand(MessageCommandCancelResearch,unit
,0,0,NoUnitP,0,flush);
,0,0,NoUnitP,0,1);
}
}
@ -761,8 +799,9 @@ global void SendCommandCancelResearch(Unit* unit)
** @param x X map tile position where to demolish.
** @param y Y map tile position where to demolish.
** @param attack or !=NoUnitP unit to be demolished.
** @param flush Flag flush all pending commands.
*/
global void SendCommandDemolish(Unit* unit,int x,int y,Unit* attack)
global void SendCommandDemolish(Unit* unit,int x,int y,Unit* attack,int flush)
{
CommandLog("demolish",unit,flush,1,x,y,attack,NULL);
if( NetworkFildes==-1 ) {
@ -959,7 +998,7 @@ local Unit* NetworkValidUnit(int nr,int id)
/**
** Parse network commands.
**
** @param messge Client unit command message.
** @param message Client unit command message.
**
** We must validate, if the command is still possible!
*/
@ -972,20 +1011,20 @@ local void ParseNetworkCommand(Message* message)
unit=NetworkValidUnit(message->Data.Command.UnitNr
,message->Data.Command.UnitId);
if( !unit ) {
return;
return; // not a valid unit, drop command
}
status = ntohl(message->Status); // FIXME: little much memory
switch( ntohl(message->Command) ) {
case MessageCommandStop:
CommandStopUnit(unit,status);
CommandStopUnit(unit);
break;
case MessageCommandStand:
CommandStandGround(unit,status);
break;
case MessageCommandMove:
CommandMoveUnit(unit
CommandMove(unit
,ntohl(message->Data.Command.X)
,ntohl(message->Data.Command.Y)
,status
@ -1056,7 +1095,7 @@ local void ParseNetworkCommand(Message* message)
);
break;
case MessageCommandCancelBuild:
// dest is the peon building the unit...
// dest is the worker building the unit...
dest=NoUnitP;
if( message->Data.Command.DestNr!=htonl(-1) ) {
dest=NetworkValidUnit(message->Data.Command.DestNr
@ -1106,19 +1145,17 @@ local void ParseNetworkCommand(Message* message)
);
break;
case MessageCommandCancelTrain:
CommandCancelTraining(unit);
// FIXME: cancel slot?
CommandCancelTraining(unit,0);
break;
case MessageCommandUpgrade:
CommandUpgradeTo(
unit,UnitTypes+ntohl(message->Data.Command.TypeNr)
,status
);
,status);
break;
case MessageCommandResearch:
CommandResearch(
unit,ntohl(message->Data.Command.X)
,status
);
unit,&Upgrades[ntohl(message->Data.Command.X)],status);
break;
case MessageCommandDemolish:
dest=NoUnitP;
@ -1330,4 +1367,15 @@ global void NetworkSendCommand(int command,Unit* unit,int x,int y
ChannelWrite(NetworkServer,&message,sizeof(message));
}
/**
** Get all network commands.
*/
global void NetworkCommands(void)
{
// FIXME: noop now
// FIXME: NetworkEvent should place the commands in a loop
}
#endif // } !NEW_NETWORK
//@}

View file

@ -168,7 +168,7 @@ local SoundId ChooseUnitVoiceSoundId(Unit *unit,UnitVoiceGroup voice) {
global void PlayUnitSound(Unit* unit,UnitVoiceGroup unit_voice_group)
{
#ifdef NEW_UNIT
DebugLevel0("FIXME: fabrice please look\n");
DebugLevel3("FIXME: fabrice please look\n");
InsertSoundRequest(unit,
unit->Slot,
ViewPointDistanceToUnit(unit),

View file

@ -422,6 +422,15 @@ global void GameMainLoop(void)
for( ;; ) {
if(!GamePaused) {
++FrameCounter;
if( !FrameCounter ) {
// FIXME: tests with frame counters now fails :(
// FIXME: Should happen in 68 years :)
fprintf(stderr,"FIXME: *** round robin ***\n");
fprintf(stderr,"FIXME: *** round robin ***\n");
fprintf(stderr,"FIXME: *** round robin ***\n");
fprintf(stderr,"FIXME: *** round robin ***\n");
}
NetworkCommands(); // Get network commands
UnitActions(); // handle units
MissileActions(); // handle missiles
PlayersEachFrame(); // handle players

View file

@ -536,7 +536,7 @@ global void FireMissile(Unit* unit)
if( goal->Destroyed ) {
DebugLevel0(__FUNCTION__": destroyed unit\n");
if( !--goal->Refs ) {
FreeUnitMemory(goal);
ReleaseUnit(goal);
}
// FIXME: should I clear this here?
unit->Command.Data.Move.Goal=NULL;

View file

@ -270,13 +270,16 @@ global int PlayerCheckCosts(const Player* player,const int* costs)
err=0;
for( i=1; i<MaxCosts; ++i ) {
if( player->Resources[i]<costs[i] ) {
sprintf(buf,"Not enough %s...%s more %s."
,DEFAULT_NAMES[i],DEFAULT_ACTIONS[i],DEFAULT_NAMES[i]);
// FIXME: use the general notify function vor this
if( player==ThisPlayer ) {
SetMessageDup(buf);
} else {
DebugLevel3("Ai: %s.\n",buf);
// FIXME: noticed all or only one?
if( !err ) {
sprintf(buf,"Not enough %s...%s more %s."
,DEFAULT_NAMES[i],DEFAULT_ACTIONS[i],DEFAULT_NAMES[i]);
// FIXME: use the general notify function vor this
if( player==ThisPlayer ) {
SetMessageDup(buf);
} else {
DebugLevel3("Ai: %s.\n",buf);
}
}
err|=1<<i;
}

View file

@ -580,10 +580,14 @@ global void DoButtonButtonClicked(int button)
//
switch( CurrentButtons[button].Action ) {
case B_Unload:
//
// Unload on coast, unload all units.
//
if( NumSelected==1
&& CoastOnMap(Selected[0]->X,Selected[0]->Y) ) {
SendCommandUnload(Selected[0]
,Selected[0]->X,Selected[0]->Y,NoUnitP);
,Selected[0]->X,Selected[0]->Y,NoUnitP
,!(KeyModifiers&ModifierShift));
break;
}
case B_Move:
@ -603,7 +607,8 @@ global void DoButtonButtonClicked(int button)
break;
case B_Return:
for( i=0; i<NumSelected; ++i ) {
SendCommandReturnGoods(Selected[i]);
SendCommandReturnGoods(Selected[i]
,!(KeyModifiers&ModifierShift));
}
break;
case B_Stop:
@ -613,7 +618,8 @@ global void DoButtonButtonClicked(int button)
break;
case B_StandGround:
for( i=0; i<NumSelected; ++i ) {
SendCommandStandGround(Selected[i]);
SendCommandStandGround(Selected[i]
,!(KeyModifiers&ModifierShift));
}
break;
case B_Button:
@ -629,8 +635,9 @@ global void DoButtonButtonClicked(int button)
PlayerAddCostsFactor(ThisPlayer,stats->Costs,75);
SendCommandCancelUpgradeTo(Selected[0]);
} else if( Selected[0]->Command.Action == UnitActionResearch ) {
i=Selected[0]->Command.Data.Research.What;
PlayerAddCostsFactor(ThisPlayer,Upgrades[i].Costs,75);
PlayerAddCostsFactor(ThisPlayer
,Selected[0]->Command.Data.Research.What->Costs
,75);
SendCommandCancelResearch(Selected[0]);
}
}
@ -649,12 +656,21 @@ global void DoButtonButtonClicked(int button)
case B_CancelTrain:
// FIXME: This didn't work in the network
DebugCheck( !Selected[0]->Command.Data.Train.Count );
#if 0
// FIXME: didn't support cancel of the last slot :(
PlayerAddUnitType(ThisPlayer
,Selected[0]->Command.Data.Train.What[
Selected[0]->Command.Data.Train.Count-1]);
ClearStatusLine();
ClearCosts();
SendCommandCancelTraining(Selected[0]);
SendCommandCancelTraining(Selected[0]
,Selected[0]->Command.Data.Train.Count-1);
#endif
PlayerAddUnitType(ThisPlayer
,Selected[0]->Command.Data.Train.What[0]);
ClearStatusLine();
ClearCosts();
SendCommandCancelTraining(Selected[0],0);
UpdateButtonPanel();
break;
case B_CancelBuild:
@ -664,7 +680,7 @@ global void DoButtonButtonClicked(int button)
// Player gets back 75% of the original cost for a building.
PlayerAddCostsFactor(ThisPlayer,stats->Costs,75);
SendCommandCancelBuilding(Selected[0],
Selected[0]->Command.Data.Builded.Peon);
Selected[0]->Command.Data.Builded.Worker);
}
break;
@ -682,10 +698,13 @@ global void DoButtonButtonClicked(int button)
break;
case B_Train:
type=&UnitTypes[CurrentButtons[button].Value];
// FIXME: Johns: I want to place commands in que, even if not
// FIXME: enought resources are available
if( PlayerCheckFood(ThisPlayer,type)
&& !PlayerCheckUnitType(ThisPlayer,type) ) {
PlayerSubUnitType(ThisPlayer,type);
SendCommandTrainUnit(Selected[0],type);
SendCommandTrainUnit(Selected[0],type
,!(KeyModifiers&ModifierShift));
ClearStatusLine();
ClearCosts();
UpdateButtonPanel();
@ -700,7 +719,8 @@ global void DoButtonButtonClicked(int button)
,type->_Costs[GoldCost]
,type->_Costs[WoodCost]);
PlayerSubUnitType(ThisPlayer,type);
SendCommandUpgradeTo(Selected[0],type);
SendCommandUpgradeTo(Selected[0],type
,!(KeyModifiers&ModifierShift));
ClearStatusLine();
ClearCosts();
UpdateButtonPanel();
@ -711,7 +731,8 @@ global void DoButtonButtonClicked(int button)
i=CurrentButtons[button].Value;
if( !PlayerCheckCosts(ThisPlayer,Upgrades[i].Costs) ) {
PlayerSubCosts(ThisPlayer,Upgrades[i].Costs);
SendCommandResearch(Selected[0],i);
SendCommandResearch(Selected[0],&Upgrades[i]
,!(KeyModifiers&ModifierShift));
ClearStatusLine();
ClearCosts();
// FIXME: ? Johns CurrentButtons=CancelUpgradeButtons;

View file

@ -218,11 +218,11 @@ global void DrawUnitInfo(Unit* unit)
}
if( unit->Command.Action==UnitActionResearch ) {
DrawText(16,y+8+78,GameFont,"Researching:");
DrawUnitIcon(Upgrades[unit->Command.Data.Research.What].Icon
DrawUnitIcon(unit->Command.Data.Research.What->Icon
,0,x+107,y+8+70);
DrawCompleted(
Upgrades[unit->Command.Data.Research.What].Costs[TimeCost]
unit->Command.Data.Research.What->Costs[TimeCost]
,unit->Command.Data.Research.Ticks);
return;
}

View file

@ -131,6 +131,7 @@ global void DoRightButton(int x,int y)
UnitType* type;
int action;
int acknowledged;
int flush;
//
// No unit selected
@ -147,6 +148,14 @@ global void DoRightButton(int x,int y)
return;
}
//
// Right mouse with SHIFT appends command to old commands.
//
flush=!(KeyModifiers&ModifierShift);
// FIXME: the next should be rewritten, must select the units with
// FIXME: the box size and not with the tile position
// FIXME: and for a group of units slow!
acknowledged=0;
for( i=0; i<NumSelected; ++i ) {
unit=Selected[i];
@ -161,55 +170,56 @@ global void DoRightButton(int x,int y)
//
// Enter transporters?
//
// FIXME: UnitOnMapTile returns random unit on tile
//
dest=UnitOnMapTile(x,y);
if( dest && dest->Type->Transporter
&& dest->Player==ThisPlayer
&& unit->Type->UnitType==UnitTypeLand ) {
dest->Blink=3;
DebugLevel3(__FUNCTION__": Board transporter\n");
SendCommandBoard(unit,dest);
SendCommandBoard(unit,-1,-1,dest,flush);
continue;
}
//
// Peon/Peasant
// Worker of human or orcs
//
if( action==MouseActionHarvest ) {
DebugLevel3("Action %x\n",TheMap.ActionMap[x+y*TheMap.Width]);
if( type->Type==UnitPeonWithWood
|| type->Type==UnitPeasantWithWood
|| type->Type==UnitPeonWithGold
|| type->Type==UnitPeasantWithGold ) {
if( type==UnitTypeOrcWorkerWithWood
|| type==UnitTypeHumanWorkerWithWood
|| type==UnitTypeOrcWorkerWithGold
|| type==UnitTypeHumanWorkerWithGold ) {
dest=UnitOnMapTile(x,y);
if( dest ) {
dest->Blink=3;
if( dest->Type->StoresGold
&& (type->Type==UnitPeonWithGold
|| type->Type==UnitPeasantWithGold) ) {
&& (type==UnitTypeOrcWorkerWithGold
|| type==UnitTypeHumanWorkerWithGold) ) {
DebugLevel3("GOLD-DEPOSIT\n");
// FIXME: return to this depot??
SendCommandReturnGoods(unit);
SendCommandReturnGoods(unit,flush);
continue;
}
if( (dest->Type->StoresWood || dest->Type->StoresGold)
&& (type->Type==UnitPeonWithWood
|| type->Type==UnitPeasantWithWood) ) {
&& (type==UnitTypeOrcWorkerWithWood
|| type==UnitTypeHumanWorkerWithWood) ) {
DebugLevel3("WOOD-DEPOSIT\n");
// FIXME: return to this depot??
SendCommandReturnGoods(unit);
SendCommandReturnGoods(unit,flush);
continue;
}
}
} else {
if( ForestOnMap(x,y) ) {
SendCommandHarvest(unit,x,y);
SendCommandHarvest(unit,x,y,flush);
continue;
}
if( (dest=GoldMineOnMap(x,y)) ) {
dest->Blink=3;
DebugLevel3("GOLD-MINE\n");
SendCommandMineGold(unit,dest);
SendCommandMineGold(unit,dest,flush);
continue;
}
}
@ -220,13 +230,13 @@ global void DoRightButton(int x,int y)
dest->Blink=3;
if( dest->Player==ThisPlayer ||
dest->Player->Player==PlayerNumNeutral) {
SendCommandMoveUnit(unit,x,y);
// FIXME: SendCommandFollow(unit,x,y,dest);
// FIXME: continue;
// FIXME: lokh: maybe we should add the ally players here
// FIXME: don't work must check repairable first
// SendCommandFollow(unit,dest,flush);
// continue;
} else {
// FIXME: can I attack this unit?
SendCommandAttack(unit,x,y,dest);
SendCommandAttack(unit,x,y,dest,flush);
continue;
}
}
@ -237,9 +247,9 @@ global void DoRightButton(int x,int y)
&& dest->Player==ThisPlayer
&& dest->HP<dest->Stats[dest->Player->Player].HitPoints
&& dest->Type->Building ) {
SendCommandRepair(unit,x,y);
SendCommandRepair(unit,x,y,dest,flush);
} else {
SendCommandMoveUnit(unit,x,y);
SendCommandMove(unit,x,y,flush);
}
continue;
}
@ -248,19 +258,28 @@ global void DoRightButton(int x,int y)
// Tanker
//
if( action==MouseActionHaulOil ) {
if( type->Type==UnitTankerOrcFull
|| type->Type==UnitTankerHumanFull ) {
// FIXME: How can I remove here the unit type?
if( type==UnitTypeOrcTankerFull || type==UnitTypeHumanTankerFull ) {
DebugLevel2("Should return to oil deposit\n");
if( (dest=UnitOnMapTile(x,y)) ) {
dest->Blink=3;
if( dest->Type->StoresOil ) {
DebugLevel3("OIL-DEPOSIT\n");
// FIXME: return to this depot??
SendCommandReturnGoods(unit,flush);
continue;
}
}
} else {
if( (dest=PlatformOnMap(x,y)) ) {
dest->Blink=3;
DebugLevel2("PLATFORM\n");
SendCommandHaulOil(unit,dest);
DebugLevel3("PLATFORM\n");
SendCommandHaulOil(unit,dest,flush);
continue;
}
}
SendCommandMoveUnit(unit,x,y);
SendCommandMove(unit,x,y,flush);
continue;
}
@ -274,13 +293,12 @@ global void DoRightButton(int x,int y)
dest->Blink=3;
if( dest->Player==ThisPlayer ||
dest->Player->Player==PlayerNumNeutral) {
SendCommandMoveUnit(unit,x,y);
// FIXME: SendCommandFollow(unit,x,y,dest);
// FIXME: continue;
// FIXME: lokh: maybe we should add the ally players here
SendCommandFollow(unit,dest,flush);
continue;
} else {
// FIXME: can I attack this unit?
SendCommandAttack(unit,x,y,dest);
SendCommandAttack(unit,x,y,dest,flush);
continue;
}
}
@ -289,15 +307,16 @@ global void DoRightButton(int x,int y)
if( ThisPlayer->Race==PlayerRaceHuman
&& OrcWallOnMap(x,y) ) {
DebugLevel3("HUMAN ATTACKS ORC\n");
SendCommandAttack(unit,x,y,NoUnitP);
SendCommandAttack(unit,x,y,NoUnitP,flush);
}
if( ThisPlayer->Race==PlayerRaceOrc
&& HumanWallOnMap(x,y) ) {
DebugLevel3("ORC ATTACKS HUMAN\n");
SendCommandAttack(unit,x,y,NoUnitP);
SendCommandAttack(unit,x,y,NoUnitP,flush);
}
}
SendCommandMoveUnit(unit,x,y);
// Note: move is correct here, right default is move
SendCommandMove(unit,x,y,flush);
continue;
}
@ -308,7 +327,7 @@ global void DoRightButton(int x,int y)
}
// if( !unit->Type->Building ) {
SendCommandMoveUnit(unit,x,y);
SendCommandMove(unit,x,y,flush);
// }
}
}
@ -581,8 +600,8 @@ local void SendRepair(int x,int y)
unit=Selected[i];
// FIXME: only worker could be send repairing
// if( !unit->Type->Building ) {
// if( unit->Type->CowerPeon ) {
SendCommandRepair(unit,x,y);
// if( unit->Type->CowerWorker ) {
SendCommandRepair(unit,x,y,NoUnitP,!(KeyModifiers&ModifierShift));
// }
}
}
@ -601,7 +620,7 @@ local void SendMove(int x,int y)
for( i=0; i<NumSelected; ++i ) {
unit=Selected[i];
// if( !unit->Type->Building ) {
SendCommandMoveUnit(unit,x,y);
SendCommandMove(unit,x,y,!(KeyModifiers&ModifierShift));
// }
}
}
@ -632,10 +651,10 @@ local void SendAttack(int x,int y)
dest=TargetOnMapTile(unit,x,y);
DebugLevel3(__FUNCTION__": Attacking %p\n",dest);
if( dest!=unit ) { // don't let an unit self destruct
SendCommandAttack(unit,x,y,dest);
SendCommandAttack(unit,x,y,dest,!(KeyModifiers&ModifierShift));
}
} else {
SendCommandMoveUnit(unit,x,y);
SendCommandMove(unit,x,y,!(KeyModifiers&ModifierShift));
}
}
}
@ -654,9 +673,9 @@ local void SendAttackGround(int x,int y)
for( i=0; i<NumSelected; ++i ) {
unit=Selected[i];
if( unit->Type->CanAttack ) {
SendCommandAttackGround(unit,x,y);
SendCommandAttackGround(unit,x,y,!(KeyModifiers&ModifierShift));
} else {
SendCommandMoveUnit(unit,x,y);
SendCommandMove(unit,x,y,!(KeyModifiers&ModifierShift));
}
}
}
@ -672,7 +691,7 @@ local void SendPatrol(int x,int y)
for( i=0; i<NumSelected; i++ ) {
unit=Selected[i];
// FIXME: Can the unit patrol ?
SendCommandPatrolUnit(unit,x,y);
SendCommandPatrol(unit,x,y,!(KeyModifiers&ModifierShift));
}
}
@ -693,7 +712,7 @@ local void SendDemolish(int x,int y)
if( dest==unit ) { // don't let an unit self destruct
dest=NoUnitP;
}
SendCommandDemolish(unit,x,y,dest);
SendCommandDemolish(unit,x,y,dest,!(KeyModifiers&ModifierShift));
} else {
DebugLevel0(__FUNCTION__": can't demolish %p\n",unit);
}
@ -714,18 +733,17 @@ local void SendHarvest(int x,int y)
for( i=0; i<NumSelected; ++i ) {
if( (dest=PlatformOnMap(x,y)) ) {
dest->Blink=3;
DebugLevel2("PLATFORM\n");
SendCommandHaulOil(Selected[i],dest);
DebugLevel3("PLATFORM\n");
SendCommandHaulOil(Selected[i],dest,!(KeyModifiers&ModifierShift));
continue;
}
if( (dest=GoldMineOnMap(x,y)) ) {
dest->Blink=3;
DebugLevel2("GOLD-MINE\n");
SendCommandMineGold(Selected[i],dest);
DebugLevel3("GOLD-MINE\n");
SendCommandMineGold(Selected[i],dest,!(KeyModifiers&ModifierShift));
continue;
}
//SendCommandMoveUnit(Selected[i],x,y);
SendCommandHarvest(Selected[i],x,y);
SendCommandHarvest(Selected[i],x,y,!(KeyModifiers&ModifierShift));
}
}
@ -740,7 +758,9 @@ local void SendUnload(int x,int y)
int i;
for( i=0; i<NumSelected; i++ ) {
SendCommandUnload(Selected[i],x,y,NoUnitP);
// FIXME: not only transporter selected?
SendCommandUnload(Selected[i],x,y,NoUnitP
,!(KeyModifiers&ModifierShift));
}
}
@ -872,7 +892,8 @@ global void UIHandleButtonDown(int b)
&& MAPEXPLORED(x,y) ) {
PlayGameSound(GameSounds.PlacementSuccess.Sound
,MaxSampleVolume);
SendCommandBuildBuilding(Selected[0],x,y,CursorBuilding);
SendCommandBuildBuilding(Selected[0],x,y,CursorBuilding
,!(KeyModifiers&ModifierShift));
if( !(KeyModifiers&ModifierAlt) ) {
CancelBuildingMode();
}
@ -934,7 +955,8 @@ global void UIHandleButtonDown(int b)
if( Selected[0]->OnBoard[ButtonUnderCursor-4] ) {
SendCommandUnload(Selected[0]
,Selected[0]->X,Selected[0]->Y
,Selected[0]->OnBoard[ButtonUnderCursor-4]);
,Selected[0]->OnBoard[ButtonUnderCursor-4]
,!(KeyModifiers&ModifierShift));
}
}
DebugLevel0("Button %d\n",ButtonUnderCursor);

View file

@ -398,7 +398,7 @@ local SCM CclDefineUnitType(SCM list)
type->Building=0;
type->Submarine=0;
type->CanSeeSubmarine=0;
type->CowerPeon=0;
type->CowerWorker=0;
type->Tanker=0;
type->Transporter=0;
type->GivesOil=0;
@ -473,8 +473,8 @@ local SCM CclDefineUnitType(SCM list)
type->Submarine=1;
} else if( gh_eq_p(value,gh_symbol2scm("can-see-submarine")) ) {
type->CanSeeSubmarine=0;
} else if( gh_eq_p(value,gh_symbol2scm("cower-peon")) ) {
type->CowerPeon=1;
} else if( gh_eq_p(value,gh_symbol2scm("cower-worker")) ) {
type->CowerWorker=1;
} else if( gh_eq_p(value,gh_symbol2scm("tanker")) ) {
type->Tanker=1;
} else if( gh_eq_p(value,gh_symbol2scm("transporter")) ) {

View file

@ -27,6 +27,7 @@
#include <limits.h>
#include "freecraft.h"
#include "video.h"
#include "sound_id.h"
#include "unitsound.h"
@ -42,6 +43,7 @@
#include "sound.h"
#include "ai.h"
#include "pathfinder.h"
#include "network.h"
/*----------------------------------------------------------------------------
-- Variables
@ -50,9 +52,12 @@
#ifdef NEW_UNIT
global Unit* UnitSlots[MAX_UNIT_SLOTS]; /// All possible units
global Unit** UnitSlotFree; /// First free unit slot
local Unit* ReleasedHead; /// List of released units.
local Unit** ReleasedTail; /// List tail of released units.
global Unit* Units[MAX_UNIT_SLOTS]; /// Array of used slots
global int NumUnits; /// Number of slots used
#else
// The pool is currently hardcoded to MAX_UNITS
global Unit* UnitsPool; /// All units in play
@ -60,8 +65,8 @@ global Unit* UnitsPool; /// All units in play
global int NumUnits; /// Number of slots used
global Unit** Units; /// Array of used slots
static Unit** FreeUnits; /// Array of free slots
static int NumFreeUnits; /// Number of free slots
local Unit** FreeUnits; /// Array of free slots
local int NumFreeUnits; /// Number of free slots
#endif
/*----------------------------------------------------------------------------
@ -79,11 +84,14 @@ global void InitUnitsMemory(void)
// Initiallize the "list" of free unit slots
slot=UnitSlots+MAX_UNIT_SLOTS;
*--slot=NULL; // leave the last slot free as no marker
*--slot=NULL;
do {
slot[-1]=(void*)slot;
} while( --slot>UnitSlots );
UnitSlotFree=slot;
ReleasedTail=&ReleasedHead;
#else
int i;
@ -118,40 +126,18 @@ global void InitUnitsMemory(void)
/**
** Free the memory for an unit slot. Update all units tables.
** Memory is only freed, if all references are dropped.
**
** @param unit Pointer to unit.
*/
global void FreeUnitMemory(Unit* unit)
{
#ifdef NEW_UNIT
Player* player;
Unit** slot;
Unit* temp;
if( unit->Refs>1 ) {
DebugLevel0(__FUNCTION__": too much references\n");
}
// Remove the unit from the player's units table.
if( (player=unit->Player) ) {
DebugCheck( *unit->PlayerSlot!=unit );
temp=player->Units[--player->TotalNumUnits];
player->Units[player->TotalNumUnits]=NULL;
temp->PlayerSlot=unit->PlayerSlot;
*unit->PlayerSlot=temp;
}
// Remove the unit from the global units table.
DebugCheck( *unit->UnitSlot!=unit );
temp=Units[--NumUnits];
Units[NumUnits]=NULL;
temp->UnitSlot=unit->UnitSlot;
*unit->UnitSlot=temp;
//
// Remove from slot table
//
slot=UnitSlots+unit->Slot;
DebugCheck( *slot!=unit );
@ -192,6 +178,65 @@ global void FreeUnitMemory(Unit* unit)
#endif
}
/**
** Release an unit.
**
** The unit is only released if all references are dropped.
**
** @param unit Pointer to unit.
*/
global void ReleaseUnit(Unit* unit)
{
#ifdef NEW_UNIT
DebugCheck( !unit->Type ); // already free.
//
// First release, remove from lists/tables.
//
if( !unit->Destroyed ) {
Player* player;
Unit* temp;
//
// Remove the unit from the player's units table.
//
if( (player=unit->Player) ) {
DebugCheck( *unit->PlayerSlot!=unit );
temp=player->Units[--player->TotalNumUnits];
player->Units[player->TotalNumUnits]=NULL;
temp->PlayerSlot=unit->PlayerSlot;
*unit->PlayerSlot=temp;
}
//
// Remove the unit from the global units table.
//
DebugCheck( *unit->UnitSlot!=unit );
temp=Units[--NumUnits];
Units[NumUnits]=NULL;
temp->UnitSlot=unit->UnitSlot;
*unit->UnitSlot=temp;
}
//
// Are more references remaining?
//
if( unit->Refs-->1 ) {
unit->Destroyed=1; // mark as destroyed
DebugLevel0(__FUNCTION__": more references\n");
return;
}
//
// No more references remaining, but the network could have an order
// on the way.
//
*ReleasedTail=unit;
ReleasedTail=&unit->Next;
unit->Refs=FrameCounter+NetworkLag; // could reuse after this.
unit->Type=NULL; // for debugging.
#else
FreeUnitMemory(unit);
#endif
}
/**
** Create a new unit.
**
@ -219,16 +264,27 @@ global Unit* MakeUnit(UnitType* type,Player* player)
#ifdef NEW_UNIT
//
// Allocate structure
// Can use released unit?
//
if( !(slot=UnitSlotFree) ) { // should not happen!
DebugLevel0(__FUNCTION__": Maximum of units reached\n");
return NoUnitP;
if( ReleasedHead && ReleasedHead->Refs<FrameCounter ) {
unit=ReleasedHead;
ReleasedHead=unit->Next;
memset(unit,0,sizeof(*unit));
DebugLevel0(__FUNCTION__": release %p\n",unit);
// FIXME: can release here more slots.
} else {
//
// Allocate structure
//
if( !(slot=UnitSlotFree) ) { // should not happen!
DebugLevel0(__FUNCTION__": Maximum of units reached\n");
return NoUnitP;
}
UnitSlotFree=(void*)*slot;
*slot=unit=calloc(1,sizeof(Unit));
unit->Refs=1;
unit->Slot=slot-UnitSlots; // back index
}
UnitSlotFree=(void*)*slot;
*slot=unit=calloc(1,sizeof(Unit));
unit->Refs=1;
unit->Slot=slot-UnitSlots; // back index
//
// Build all unit table
@ -279,7 +335,7 @@ global Unit* MakeUnit(UnitType* type,Player* player)
unit->Player=player;
unit->Stats=&type->Stats[unit->Player->Player];
if( type->CowerPeon ) {
if( type->CowerWorker ) {
unit->WoodToHarvest=CHOP_FOR_WOOD;
}
if( type->CanCastSpell ) {
@ -1966,7 +2022,7 @@ global void DestroyUnit(Unit* unit)
if( type->OilPatch || unit->Removed ) {
RemoveUnit(unit);
UnitLost(unit);
FreeUnitMemory(unit);
ReleaseUnit(unit);
return;
}
@ -1981,7 +2037,7 @@ global void DestroyUnit(Unit* unit)
,0,0);
RemoveUnit(unit);
UnitLost(unit);
FreeUnitMemory(unit);
ReleaseUnit(unit);
return;
}
@ -2034,7 +2090,7 @@ global void DestroyUnit(Unit* unit)
}
// no corpse available
FreeUnitMemory(unit);
ReleaseUnit(unit);
return;
}
@ -2055,6 +2111,10 @@ global void DestroyUnit(Unit* unit)
unit->Type=UnitTypeByIdent("unit-peasant");
}
//
// Unit has no death animation.
//
// Not good: UnitNewHeading(unit);
unit->SubAction=0;
unit->Removed=0;
@ -2083,7 +2143,7 @@ global void DestroyAllInside(Unit* source)
// DestroyUnit(unit);
RemoveUnit(unit);
UnitLost(unit);
FreeUnitMemory(unit);
ReleaseUnit(unit);
}
}
return;
@ -2094,8 +2154,8 @@ global void DestroyAllInside(Unit* source)
//
if( source->Type->Building
&& source->Command.Action==UnitActionBuilded
&& source->Command.Data.Builded.Peon ) {
DestroyUnit(source->Command.Data.Builded.Peon);
&& source->Command.Data.Builded.Worker ) {
DestroyUnit(source->Command.Data.Builded.Worker);
return;
}
@ -2189,7 +2249,7 @@ global void HitUnit(Unit* unit,int damage)
//
// Attack units in range (which or the attacker?)
//
if( !type->CowerPeon && !type->CowerMage ) {
if( !type->CowerWorker && !type->CowerMage ) {
if( type->CanAttack && !type->Tower ) {
goal=AttackUnitsInReactRange(unit);
if( goal ) {
@ -2392,6 +2452,13 @@ local void SaveCommand(const Command* command,FILE* file)
free(ref);
}
break;
case UnitActionFollow:
fprintf(file,"'follow");
ref=UnitReference(command->Data.Move.Goal);
fprintf(file," %s",ref);
fprintf(file," %d",command->Data.Move.Range);
free(ref);
break;
case UnitActionMove:
fprintf(file,"'move");
fprintf(file," (%d %d)"
@ -2404,13 +2471,19 @@ local void SaveCommand(const Command* command,FILE* file)
free(ref);
}
fprintf(file," %d",command->Data.Move.Range);
if( command->Data.Move.Fast ) {
fprintf(file," 'fast");
}
break;
case UnitActionAttack:
fprintf(file,"'attack");
fprintf(file," \"FIXME:\"");
fprintf(file," (%d %d)"
,command->Data.Move.SX,command->Data.Move.SY);
fprintf(file," (%d %d)"
,command->Data.Move.DX,command->Data.Move.DY);
if( command->Data.Move.Goal ) {
ref=UnitReference(command->Data.Move.Goal);
fprintf(file," %s",ref);
free(ref);
}
fprintf(file," %d",command->Data.Move.Range);
break;
case UnitActionDie:
fprintf(file,"'die");

View file

@ -47,7 +47,17 @@
/*
** Next unit type are used hardcoded in the source.
*/
global UnitType* UnitTypeGoldMine; /// Gold mine unit type pointer.
global UnitType*UnitTypeGoldMine; /// Gold mine unit type pointer.
global UnitType*UnitTypeOrcTanker; /// Orc tanker unit type pointer.
global UnitType*UnitTypeHumanTanker; /// Human tanker unit type pointer.
global UnitType*UnitTypeOrcTankerFull; /// Orc tanker full unit type pointer.
global UnitType*UnitTypeHumanTankerFull;/// Human tanker full unit type pointer.
global UnitType*UnitTypeHumanWorker; /// Human worker.
global UnitType*UnitTypeOrcWorker; /// Orc worker.
global UnitType*UnitTypeHumanWorkerWithGold; /// Human worker with gold.
global UnitType*UnitTypeOrcWorkerWithGold; /// Orc worker with gold.
global UnitType*UnitTypeHumanWorkerWithWood; /// Human worker with wood.
global UnitType*UnitTypeOrcWorkerWithWood; /// Orc worker with wood.
/**
** Lookup table for unit-type names
@ -416,7 +426,7 @@ global void PrintUnitTypeTable(void)
printf("\t//SeeSu\tCowerP\tTanker\tTrans\tGOil\tSOil\tVanish\tGrAtt\n");
printf("\t,%6d,%6d,%7d,%6d,%6d,%7d,%9d,%8d\n"
,type->CanSeeSubmarine
,type->CowerPeon
,type->CowerWorker
,type->Tanker
,type->Transporter
,type->GivesOil
@ -692,7 +702,7 @@ global void ParsePudUDTA(const char* udta,int length)
unittype->Building=BIT(5,v);
unittype->Submarine=BIT(6,v);
unittype->CanSeeSubmarine=BIT(7,v);
unittype->CowerPeon=BIT(8,v);
unittype->CowerWorker=BIT(8,v);
unittype->Tanker=BIT(9,v);
unittype->Transporter=BIT(10,v);
unittype->GivesOil=BIT(11,v);
@ -897,8 +907,8 @@ global void SaveUnitType(const UnitType* type,FILE* file)
if( type->CanSeeSubmarine ) {
fprintf(file," 'can-see-submarine\n");
}
if( type->CowerPeon ) {
fprintf(file," 'cower-peon\n");
if( type->CowerWorker ) {
fprintf(file," 'cower-worker\n");
}
if( type->Tanker ) {
fprintf(file," 'tanker\n");
@ -1050,6 +1060,16 @@ global void InitUnitTypes(void)
// Setup hardcoded unit types.
//
UnitTypeGoldMine=UnitTypeByIdent("unit-gold-mine");
UnitTypeHumanTanker=UnitTypeByIdent("unit-human-oil-tanker");
UnitTypeOrcTanker=UnitTypeByIdent("unit-orc-oil-tanker");
UnitTypeHumanTankerFull=UnitTypeByIdent("unit-human-oil-tanker-full");
UnitTypeOrcTankerFull=UnitTypeByIdent("unit-orc-oil-tanker-full");
UnitTypeHumanWorker=UnitTypeByIdent("unit-peasant");
UnitTypeOrcWorker=UnitTypeByIdent("unit-peon");
UnitTypeHumanWorkerWithGold=UnitTypeByIdent("unit-peasant-with-gold");
UnitTypeOrcWorkerWithGold=UnitTypeByIdent("unit-peon-with-gold");
UnitTypeHumanWorkerWithWood=UnitTypeByIdent("unit-peasant-with-wood");
UnitTypeOrcWorkerWithWood=UnitTypeByIdent("unit-peon-with-wood");
}
/**

View file

@ -1241,7 +1241,7 @@ void UpgradeIncTime( Player* player, int id, int amount )
if ( player->UTimers.upgrades[id] >= Upgrades[id].Costs[TimeCost] )
{
player->UTimers.upgrades[id] = Upgrades[id].Costs[TimeCost];
UpgradeAcquire( player, id );
UpgradeAcquire( player, &Upgrades[id] );
}
}
@ -1298,11 +1298,13 @@ void ApplyUpgradeModifier( Player* player, UpgradeModifier* um )
}
// called by UpgradeIncTime() when timer reached
global void UpgradeAcquire( Player* player, int id )
global void UpgradeAcquire( Player* player, Upgrade* upgrade )
{
int z;
int id;
player->UTimers.upgrades[id] = Upgrades[id].Costs[TimeCost];
id=upgrade-Upgrades;
player->UTimers.upgrades[id] = upgrade->Costs[TimeCost];
AllowUpgradeId( player, id, 'R' ); // research done
for ( z = 0; z < UpgradeModifiersCount; z++ ) {
@ -1371,8 +1373,6 @@ global char UpgradeIdAllowed(const Player* player, int id )
// ***************by sid's
void UpgradeIncTime2( Player* player, char* sid, int amount ) // by ident string
{ UpgradeIncTime( player, UpgradeIdByIdent(sid), amount ); }
void UpgradeAcquire2( Player* player, char* sid ) // by ident string
{ UpgradeAcquire( player, UpgradeIdByIdent(sid) ); }
void UpgradeLost2( Player* player, char* sid ) // by ident string
{ UpgradeLost( player, UpgradeIdByIdent(sid) ); }