Command que flush handling changed, move from network layer to user layer.
More of new unit reference code.
This commit is contained in:
parent
613906649f
commit
e958202ef4
31 changed files with 735 additions and 426 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 ) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
//@}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
//@}
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
126
ui/mouse.cpp
126
ui/mouse.cpp
|
@ -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);
|
||||
|
|
|
@ -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")) ) {
|
||||
|
|
167
unit/unit.cpp
167
unit/unit.cpp
|
@ -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");
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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) ); }
|
||||
|
||||
|
|
Loading…
Reference in a new issue