Generic getting resource function, currently only used by haul oil.
This commit is contained in:
parent
94f7613f49
commit
4d9d8470a8
1 changed files with 770 additions and 0 deletions
770
src/action/action_resource.cpp
Normal file
770
src/action/action_resource.cpp
Normal file
|
@ -0,0 +1,770 @@
|
|||
// ___________ _________ _____ __
|
||||
// \_ _____/______ ____ ____ \_ ___ \____________ _/ ____\/ |_
|
||||
// | __) \_ __ \_/ __ \_/ __ \/ \ \/\_ __ \__ \\ __\\ __\
|
||||
// | \ | | \/\ ___/\ ___/\ \____| | \// __ \| | | |
|
||||
// \___ / |__| \___ >\___ >\______ /|__| (____ /__| |__|
|
||||
// \/ \/ \/ \/ \/
|
||||
// ______________________ ______________________
|
||||
// T H E W A R B E G I N S
|
||||
// FreeCraft - A free fantasy real time strategy game engine
|
||||
//
|
||||
/**@name action_resource.c - The generic resource action. */
|
||||
//
|
||||
// (c) Copyright 2001 by Lutz Sammer
|
||||
//
|
||||
// $Id$
|
||||
|
||||
//@{
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Includes
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "freecraft.h"
|
||||
#include "player.h"
|
||||
#include "unit.h"
|
||||
#include "unittype.h"
|
||||
#include "actions.h"
|
||||
#include "pathfinder.h"
|
||||
#include "interface.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Declarations
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Helper structure for getting resources.
|
||||
** FIXME: later we should make this configurable, to allow game
|
||||
** FIXME: designers to create own resources.
|
||||
*/
|
||||
typedef struct _resource_ {
|
||||
int Action; /// Unit action.
|
||||
int Frame; /// Frame for active resource
|
||||
Unit* (*ResourceOnMap)(int,int); /// Get the resource on map.
|
||||
Unit* (*DepositOnMap)(int,int); /// Get the deposit on map.
|
||||
/// Find the source of resource
|
||||
Unit* (*FindResource)(const Player*,int,int);
|
||||
/// Find the deposit of resource
|
||||
Unit* (*FindDeposit)(const Player*,int,int);
|
||||
int Cost; /// How many can the unit carry.
|
||||
UnitType** Human; /// Human worker
|
||||
UnitType** HumanWithResource; /// Human worker with resource
|
||||
UnitType** Orc; /// Orc worker
|
||||
UnitType** OrcWithResource; /// Orc worker with resource
|
||||
|
||||
int GetTime; /// Time to get the resource
|
||||
int PutTime; /// Time to store the resource
|
||||
|
||||
} Resource;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** Move unit to resource.
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
** @param resouce How to handle the resource.
|
||||
**
|
||||
** @return TRUE if reached, otherwise FALSE.
|
||||
*/
|
||||
local int MoveToResource(Unit* unit,const Resource* resource)
|
||||
{
|
||||
Unit* goal;
|
||||
|
||||
switch( HandleActionMove(unit) ) { // reached end-point?
|
||||
case PF_UNREACHABLE:
|
||||
DebugCheck( unit->Command.Action!=resource->Action );
|
||||
return -1;
|
||||
case PF_REACHED:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef NEW_ORDERS
|
||||
goal=unit->Orders[0].Goal;
|
||||
|
||||
DebugCheck( !goal );
|
||||
DebugCheck( unit->Wait!=1 );
|
||||
DebugCheck( MapDistanceToUnit(unit->X,unit->Y,goal)!=1 );
|
||||
|
||||
//
|
||||
// Target is dead, stop getting resources.
|
||||
//
|
||||
if( goal->Destroyed ) {
|
||||
DebugLevel0Fn("Destroyed unit\n");
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
if( !--goal->Refs ) {
|
||||
ReleaseUnit(goal);
|
||||
}
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
} else if( goal->Removed || !goal->HP
|
||||
|| goal->Orders[0].Action==UnitActionDie ) {
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unit->Orders[0].Action=resource->Action;
|
||||
|
||||
//
|
||||
// If resource is still under construction, wait!
|
||||
//
|
||||
if( goal->Orders[0].Action==UnitActionBuilded ) {
|
||||
DebugLevel2Fn("Invalid resource\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
|
||||
//
|
||||
// Activate the resource
|
||||
//
|
||||
goal->Data.Resource.Active++;
|
||||
DebugLevel0Fn("+%d\n",goal->Data.Resource.Active);
|
||||
|
||||
#else
|
||||
|
||||
goal=unit->Command.Data.Move.Goal;
|
||||
|
||||
DebugCheck( !goal );
|
||||
DebugCheck( unit->Wait!=1 );
|
||||
DebugCheck( MapDistanceToUnit(unit->X,unit->Y,goal)!=1 );
|
||||
|
||||
//
|
||||
// Target is dead, stop getting resources.
|
||||
//
|
||||
if( goal->Destroyed ) {
|
||||
DebugLevel0Fn("Destroyed unit\n");
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
if( !--goal->Refs ) {
|
||||
ReleaseUnit(goal);
|
||||
}
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
} else if( goal->Removed || !goal->HP
|
||||
|| goal->Command.Action==UnitActionDie ) {
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unit->Command.Action=resource->Action;
|
||||
|
||||
//
|
||||
// If resource is still under construction, wait!
|
||||
//
|
||||
if( goal->Command.Action==UnitActionBuilded ) {
|
||||
DebugLevel2Fn("Invalid resource\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
|
||||
//
|
||||
// Activate the resource
|
||||
//
|
||||
goal->Command.Data.Resource.Active++;
|
||||
DebugLevel0Fn("+%d\n",goal->Command.Data.Resource.Active);
|
||||
|
||||
#endif
|
||||
|
||||
if( !goal->Frame ) { // show resource working
|
||||
goal->Frame=resource->Frame;
|
||||
CheckUnitToBeDrawn(goal);
|
||||
}
|
||||
|
||||
//
|
||||
// Place unit inside the resource
|
||||
//
|
||||
RemoveUnit(unit);
|
||||
unit->X=goal->X;
|
||||
unit->Y=goal->Y;
|
||||
|
||||
//
|
||||
// Time to collect the resource.
|
||||
//
|
||||
if( resource->GetTime<MAX_UNIT_WAIT ) {
|
||||
unit->Wait=resource->GetTime;
|
||||
} else {
|
||||
unit->Wait=MAX_UNIT_WAIT;
|
||||
}
|
||||
unit->Value=resource->GetTime-unit->Wait;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
** Wait in resource, for collecting the resource.
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
** @param resouce How to handle the resource.
|
||||
**
|
||||
** @return TRUE if ready, otherwise FALSE.
|
||||
*/
|
||||
local int WaitInResource(Unit* unit,const Resource* resource)
|
||||
{
|
||||
Unit* goal;
|
||||
Unit* depot;
|
||||
|
||||
DebugLevel3Fn("Waiting\n");
|
||||
|
||||
if( !unit->Value ) {
|
||||
//
|
||||
// Have the resource
|
||||
//
|
||||
goal=resource->ResourceOnMap(unit->X,unit->Y);
|
||||
IfDebug(
|
||||
DebugLevel3Fn("Found %d,%d=%Zd\n",unit->X,unit->Y,UnitNumber(goal));
|
||||
if( !goal ) {
|
||||
DebugLevel0Fn("No unit? (%d,%d)\n",unit->X,unit->Y);
|
||||
abort();
|
||||
} );
|
||||
|
||||
//
|
||||
// Update the resource.
|
||||
// Remove what we can carry, FIXME: always this?
|
||||
//
|
||||
goal->Value-=DEFAULT_INCOMES[resource->Cost];
|
||||
#ifdef NEW_ORDERS
|
||||
DebugLevel0Fn("-%d\n",goal->Data.Resource.Active);
|
||||
if( !--goal->Data.Resource.Active ) {
|
||||
goal->Frame=0;
|
||||
CheckUnitToBeDrawn(goal);
|
||||
}
|
||||
#else
|
||||
DebugLevel0Fn("-%d\n",goal->Command.Data.Resource.Active);
|
||||
if( !--goal->Command.Data.Resource.Active ) {
|
||||
goal->Frame=0;
|
||||
CheckUnitToBeDrawn(goal);
|
||||
}
|
||||
#endif
|
||||
if( IsSelected(goal) ) {
|
||||
MustRedraw|=RedrawInfoPanel;
|
||||
}
|
||||
|
||||
//
|
||||
// End of resource: destroy the resource.
|
||||
//
|
||||
if( goal->Value<DEFAULT_INCOMES[resource->Cost] ) {
|
||||
unit->Removed=0; // BUG ALERT: Unit not dropped out!
|
||||
DropOutAll(goal);
|
||||
DestroyUnit(goal);
|
||||
goal=NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Change unit to full state. FIXME: more races
|
||||
//
|
||||
if( unit->Type==*resource->Human ) {
|
||||
unit->Type=*resource->HumanWithResource;
|
||||
} else if( unit->Type==*resource->Orc ) {
|
||||
unit->Type=*resource->OrcWithResource;
|
||||
} else {
|
||||
DebugLevel0Fn("Wrong unit-type `%s' for resource `%s'\n"
|
||||
,unit->Type->Ident,DEFAULT_NAMES[resource->Cost]);
|
||||
}
|
||||
|
||||
//
|
||||
// Find and send to resource deposit.
|
||||
//
|
||||
if( !(depot=resource->FindDeposit(unit->Player,unit->X,unit->Y)) ) {
|
||||
if( goal ) {
|
||||
DropOutOnSide(unit,LookingW
|
||||
,goal->Type->TileWidth,goal->Type->TileHeight);
|
||||
} else {
|
||||
DropOutOnSide(unit,LookingW,1,1);
|
||||
}
|
||||
#ifdef NEW_ORDERS
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
// should return 0, done below!
|
||||
} else {
|
||||
if( goal ) {
|
||||
DropOutNearest(unit,depot->X,depot->Y
|
||||
,goal->Type->TileWidth,goal->Type->TileHeight);
|
||||
} else {
|
||||
DropOutNearest(unit,depot->X,depot->Y,1,1);
|
||||
}
|
||||
ResetPath(unit->Orders[0]);
|
||||
unit->Orders[0].Goal=depot;
|
||||
RefsDebugCheck( !depot->Refs );
|
||||
++depot->Refs;
|
||||
unit->Orders[0].RangeX=unit->Orders[0].RangeY=1;
|
||||
unit->Orders[0].X=-1;
|
||||
unit->Orders[0].Y=-1;
|
||||
unit->Orders[0].Action=resource->Action;
|
||||
}
|
||||
|
||||
CheckUnitToBeDrawn(unit);
|
||||
if( IsSelected(unit) ) {
|
||||
UpdateButtonPanel();
|
||||
MustRedraw|=RedrawButtonPanel;
|
||||
}
|
||||
unit->Wait=1;
|
||||
return unit->Orders[0].Action==resource->Action;
|
||||
#else
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
// should return 0, done below!
|
||||
} else {
|
||||
if( goal ) {
|
||||
DropOutNearest(unit,depot->X,depot->Y
|
||||
,goal->Type->TileWidth,goal->Type->TileHeight);
|
||||
} else {
|
||||
DropOutNearest(unit,depot->X,depot->Y,1,1);
|
||||
}
|
||||
ResetPath(unit->Command);
|
||||
unit->Command.Data.Move.Goal=depot;
|
||||
RefsDebugCheck( !depot->Refs );
|
||||
++depot->Refs;
|
||||
unit->Command.Data.Move.Range=1;
|
||||
unit->Command.Data.Move.DX=-1;
|
||||
unit->Command.Data.Move.DY=-1;
|
||||
unit->Command.Action=resource->Action;
|
||||
}
|
||||
|
||||
CheckUnitToBeDrawn(unit);
|
||||
if( IsSelected(unit) ) {
|
||||
UpdateButtonPanel();
|
||||
MustRedraw|=RedrawButtonPanel;
|
||||
}
|
||||
unit->Wait=1;
|
||||
return unit->Command.Action==resource->Action;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Continue waiting
|
||||
//
|
||||
if( unit->Value<MAX_UNIT_WAIT ) {
|
||||
unit->Wait=unit->Value;
|
||||
} else {
|
||||
unit->Wait=MAX_UNIT_WAIT;
|
||||
}
|
||||
unit->Value-=unit->Wait;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Move to resource depot
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
** @param resouce How to handle the resource.
|
||||
**
|
||||
** @return TRUE if ready, otherwise FALSE.
|
||||
*/
|
||||
local int MoveToDepot(Unit* unit,const Resource* resource)
|
||||
{
|
||||
Unit* goal;
|
||||
|
||||
switch( HandleActionMove(unit) ) { // reached end-point?
|
||||
case PF_UNREACHABLE:
|
||||
DebugCheck( unit->Command.Action!=resource->Action );
|
||||
return -1;
|
||||
case PF_REACHED:
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef NEW_ORDERS
|
||||
goal=unit->Orders[0].Goal;
|
||||
|
||||
DebugCheck( !goal );
|
||||
DebugCheck( unit->Wait!=1 );
|
||||
DebugCheck( MapDistanceToUnit(unit->X,unit->Y,goal)!=1 );
|
||||
|
||||
//
|
||||
// Target is dead, stop getting resources.
|
||||
//
|
||||
if( goal->Destroyed ) {
|
||||
DebugLevel0Fn("Destroyed unit\n");
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
if( !--goal->Refs ) {
|
||||
ReleaseUnit(goal);
|
||||
}
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
} else if( goal->Removed || !goal->HP
|
||||
|| goal->Orders[0].Action==UnitActionDie ) {
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unit->Orders[0].Action=resource->Action;
|
||||
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
|
||||
#else
|
||||
|
||||
goal=unit->Command.Data.Move.Goal;
|
||||
|
||||
DebugCheck( !goal );
|
||||
DebugCheck( unit->Wait!=1 );
|
||||
DebugCheck( MapDistanceToUnit(unit->X,unit->Y,goal)!=1 );
|
||||
|
||||
//
|
||||
// Target is dead, stop getting resources.
|
||||
//
|
||||
if( goal->Destroyed ) {
|
||||
DebugLevel0Fn("Destroyed unit\n");
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
if( !--goal->Refs ) {
|
||||
ReleaseUnit(goal);
|
||||
}
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
} else if( goal->Removed || !goal->HP
|
||||
|| goal->Command.Action==UnitActionDie ) {
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
// FIXME: perhaps we should choose an alternative
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
unit->Command.Action=resource->Action;
|
||||
|
||||
//
|
||||
// If depot is still under construction, wait!
|
||||
//
|
||||
if( goal->Command.Action==UnitActionBuilded ) {
|
||||
DebugLevel2Fn("Invalid depot\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
--goal->Refs;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Place unit inside the depot
|
||||
//
|
||||
RemoveUnit(unit);
|
||||
unit->X=goal->X;
|
||||
unit->Y=goal->Y;
|
||||
|
||||
//
|
||||
// Update resource.
|
||||
//
|
||||
unit->Player->Resources[resource->Cost]
|
||||
+=unit->Player->Incomes[resource->Cost];
|
||||
if( unit->Player==ThisPlayer ) {
|
||||
MustRedraw|=RedrawResources;
|
||||
}
|
||||
|
||||
//
|
||||
// Change unit to empty state. FIXME: more races
|
||||
//
|
||||
if( unit->Type==*resource->HumanWithResource ) {
|
||||
unit->Type=*resource->Human;
|
||||
} else if( unit->Type==*resource->OrcWithResource ) {
|
||||
unit->Type=*resource->Orc;
|
||||
} else {
|
||||
DebugLevel0Fn("Wrong unit-type `%s' for resource `%s'\n"
|
||||
,unit->Type->Ident,DEFAULT_NAMES[resource->Cost]);
|
||||
}
|
||||
|
||||
//
|
||||
// Time to store the resource.
|
||||
//
|
||||
if( resource->PutTime<MAX_UNIT_WAIT ) {
|
||||
unit->Wait=resource->PutTime;
|
||||
} else {
|
||||
unit->Wait=MAX_UNIT_WAIT;
|
||||
}
|
||||
unit->Value=resource->PutTime-unit->Wait;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
** Wait in depot, for the resources stored.
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
** @param resouce How to handle the resource.
|
||||
**
|
||||
** @return TRUE if ready, otherwise FALSE.
|
||||
*/
|
||||
local int WaitInDepot(Unit* unit,const Resource* resource)
|
||||
{
|
||||
Unit* depot;
|
||||
Unit* goal;
|
||||
|
||||
DebugLevel3Fn("Waiting\n");
|
||||
if( !unit->Value ) {
|
||||
#ifdef NEW_ORDERS
|
||||
depot=resource->DepositOnMap(unit->X,unit->Y);
|
||||
DebugCheck( !depot );
|
||||
// Could be destroyed, but than we couldn't be in?
|
||||
|
||||
// FIXME: return to last position!
|
||||
if( !(goal=resource->FindResource(unit->Player,unit->X,unit->Y)) ) {
|
||||
DropOutOnSide(unit,LookingW
|
||||
,depot->Type->TileWidth,depot->Type->TileHeight);
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
} else {
|
||||
DropOutNearest(unit,goal->X,goal->Y
|
||||
,depot->Type->TileWidth,depot->Type->TileHeight);
|
||||
ResetPath(unit->Command);
|
||||
unit->Orders[0].Goal=goal;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
++goal->Refs;
|
||||
unit->Orders[0].RangeX=unit->Orders[0].RangeY=1;
|
||||
unit->Orders[0].X=-1;
|
||||
unit->Orders[0].Y=-1;
|
||||
unit->Orders[0].Action=resource->Action;
|
||||
}
|
||||
|
||||
CheckUnitToBeDrawn(unit);
|
||||
unit->Wait=1;
|
||||
return unit->Orders[0].Action==resource->Action;
|
||||
#else
|
||||
depot=resource->DepositOnMap(unit->X,unit->Y);
|
||||
DebugCheck( !depot );
|
||||
// Could be destroyed, but than we couldn't be in?
|
||||
|
||||
// FIXME: return to last position!
|
||||
if( !(goal=resource->FindResource(unit->Player,unit->X,unit->Y)) ) {
|
||||
DropOutOnSide(unit,LookingW
|
||||
,depot->Type->TileWidth,depot->Type->TileHeight);
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
} else {
|
||||
DropOutNearest(unit,goal->X,goal->Y
|
||||
,depot->Type->TileWidth,depot->Type->TileHeight);
|
||||
ResetPath(unit->Command);
|
||||
unit->Command.Data.Move.Goal=goal;
|
||||
RefsDebugCheck( !goal->Refs );
|
||||
++goal->Refs;
|
||||
unit->Command.Data.Move.Range=1;
|
||||
unit->Command.Data.Move.DX=-1;
|
||||
unit->Command.Data.Move.DY=-1;
|
||||
unit->Command.Action=resource->Action;
|
||||
}
|
||||
|
||||
CheckUnitToBeDrawn(unit);
|
||||
unit->Wait=1;
|
||||
return unit->Command.Action==resource->Action;
|
||||
#endif
|
||||
}
|
||||
|
||||
//
|
||||
// Continue waiting
|
||||
//
|
||||
if( unit->Value<MAX_UNIT_WAIT ) {
|
||||
unit->Wait=unit->Value;
|
||||
} else {
|
||||
unit->Wait=MAX_UNIT_WAIT;
|
||||
}
|
||||
unit->Value-=unit->Wait;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Control the unit action: getting a resource.
|
||||
**
|
||||
** This the generic function for oil, gold, ...
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
** @param resouce How to handle the resource.
|
||||
*/
|
||||
global void HandleActionResource(Unit* unit,const Resource* resource)
|
||||
{
|
||||
int ret;
|
||||
|
||||
DebugLevel2Fn("%s(%Zd) SubAction %d\n"
|
||||
,unit->Type->Ident,UnitNumber(unit),unit->SubAction);
|
||||
|
||||
switch( unit->SubAction ) {
|
||||
//
|
||||
// Move to the resource
|
||||
//
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
if( (ret=MoveToResource(unit,resource)) ) {
|
||||
if( ret==-1 ) {
|
||||
if( ++unit->SubAction==5 ) {
|
||||
#ifdef NEW_ORDERS
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
if( unit->Orders[0].Goal ) {
|
||||
RefsDebugCheck( !unit->Orders[0].Goal->Refs );
|
||||
--unit->Orders[0].Goal->Refs;
|
||||
RefsDebugCheck( !unit->Orders[0].Goal->Refs );
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
}
|
||||
#else
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
if( unit->Command.Data.Move.Goal ) {
|
||||
RefsDebugCheck(!unit->Command.Data.Move.Goal->Refs);
|
||||
--unit->Command.Data.Move.Goal->Refs;
|
||||
RefsDebugCheck(!unit->Command.Data.Move.Goal->Refs);
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
}
|
||||
#endif
|
||||
} else { // Do a little delay
|
||||
unit->Wait*=unit->SubAction;
|
||||
DebugLevel0Fn("Retring\n");
|
||||
}
|
||||
} else {
|
||||
unit->SubAction=64;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Wait for collecting the resource
|
||||
//
|
||||
case 64:
|
||||
if( WaitInResource(unit,resource) ) {
|
||||
++unit->SubAction;
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Return to the resource depot
|
||||
//
|
||||
case 65:
|
||||
case 66:
|
||||
case 67:
|
||||
case 68:
|
||||
case 69:
|
||||
if( (ret=MoveToDepot(unit,resource)) ) {
|
||||
if( ret==-1 ) {
|
||||
if( ++unit->SubAction==70 ) {
|
||||
#ifdef NEW_ORDERS
|
||||
unit->Orders[0].Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
if( unit->Orders[0].Goal ) {
|
||||
RefsDebugCheck( !unit->Orders[0].Goal->Refs );
|
||||
--unit->Orders[0].Goal->Refs;
|
||||
RefsDebugCheck( !unit->Orders[0].Goal->Refs );
|
||||
unit->Orders[0].Goal=NoUnitP;
|
||||
}
|
||||
#else
|
||||
unit->Command.Action=UnitActionStill;
|
||||
unit->SubAction=0;
|
||||
if( unit->Command.Data.Move.Goal ) {
|
||||
RefsDebugCheck(!unit->Command.Data.Move.Goal->Refs);
|
||||
--unit->Command.Data.Move.Goal->Refs;
|
||||
RefsDebugCheck(!unit->Command.Data.Move.Goal->Refs);
|
||||
unit->Command.Data.Move.Goal=NoUnitP;
|
||||
}
|
||||
#endif
|
||||
} else { // Do a little delay
|
||||
unit->Wait*=unit->SubAction-65;
|
||||
DebugLevel0Fn("Retring\n");
|
||||
}
|
||||
} else {
|
||||
unit->SubAction=128;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
//
|
||||
// Wait for resource stored
|
||||
//
|
||||
case 128:
|
||||
if( WaitInDepot(unit,resource) ) {
|
||||
unit->SubAction=0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------
|
||||
-- High level
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
** The oil resource.
|
||||
*/
|
||||
local Resource ResourceOil[1] = {
|
||||
{
|
||||
UnitActionHaulOil,
|
||||
2, // FIXME: hardcoded.
|
||||
PlatformOnMap,
|
||||
OilDepositOnMap,
|
||||
FindOilPlatform,
|
||||
FindOilDeposit,
|
||||
OilCost,
|
||||
// FIXME: The & could be removed.
|
||||
&UnitTypeHumanTanker,
|
||||
&UnitTypeHumanTankerFull,
|
||||
&UnitTypeOrcTanker,
|
||||
&UnitTypeOrcTankerFull,
|
||||
|
||||
0, // Must be initialized
|
||||
0, // Must be initialized
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
** Control the unit action haul oil
|
||||
**
|
||||
** @param unit Pointer to unit.
|
||||
*/
|
||||
global void HandleActionHaulOil(Unit* unit)
|
||||
{
|
||||
// FIXME: move into init function, debug could change this values.
|
||||
ResourceOil->GetTime=HAUL_FOR_OIL;
|
||||
ResourceOil->PutTime=WAIT_FOR_OIL;
|
||||
|
||||
HandleActionResource(unit,ResourceOil);
|
||||
}
|
||||
|
||||
//@}
|
Loading…
Add table
Reference in a new issue