Move some code into COrder
This commit is contained in:
parent
a34a1b8828
commit
137e4e58fd
4 changed files with 178 additions and 143 deletions
src
|
@ -58,11 +58,52 @@
|
|||
|
||||
unsigned SyncHash; /// Hash calculated to find sync failures
|
||||
|
||||
|
||||
extern void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type);
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
COrder::~COrder() {
|
||||
COrder::COrder(const COrder &rhs): Goal(rhs.Goal), Range(rhs.Range),
|
||||
MinRange(rhs.MinRange), Width(rhs.Width), Height(rhs.Height),
|
||||
Action(rhs.Action), CurrentResource(rhs.CurrentResource),
|
||||
goalPos(rhs.goalPos)
|
||||
{
|
||||
if (Goal) {
|
||||
Goal->RefsIncrease();
|
||||
}
|
||||
|
||||
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
|
||||
memcpy(&Data, &rhs.Data, sizeof (Data));
|
||||
if (Action == UnitActionResource && Arg1.Resource.Mine) {
|
||||
Arg1.Resource.Mine->RefsIncrease();
|
||||
}
|
||||
}
|
||||
|
||||
COrder& COrder::operator=(const COrder &rhs) {
|
||||
if (this != &rhs) {
|
||||
Action = rhs.Action;
|
||||
Range = rhs.Range;
|
||||
MinRange = rhs.MinRange;
|
||||
Width = rhs.Width;
|
||||
Height = rhs.Height;
|
||||
CurrentResource = rhs.CurrentResource;
|
||||
SetGoal(rhs.Goal);
|
||||
goalPos = rhs.goalPos;
|
||||
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
|
||||
memcpy(&Data, &rhs.Data, sizeof (Data));
|
||||
//FIXME: Hardcoded wood
|
||||
if (Action == UnitActionResource && Arg1.Resource.Mine) {
|
||||
Arg1.Resource.Mine->RefsIncrease();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
COrder::~COrder()
|
||||
{
|
||||
if (Goal) {
|
||||
Goal->RefsDecrease();
|
||||
Goal = NoUnitP;
|
||||
|
@ -110,46 +151,6 @@ void COrder::ReleaseRefs(CUnit &unit)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
COrder::COrder(const COrder &rhs): Goal(rhs.Goal), Range(rhs.Range),
|
||||
MinRange(rhs.MinRange), Width(rhs.Width), Height(rhs.Height),
|
||||
Action(rhs.Action), CurrentResource(rhs.CurrentResource),
|
||||
goalPos(rhs.goalPos)
|
||||
{
|
||||
if (Goal) {
|
||||
Goal->RefsIncrease();
|
||||
}
|
||||
|
||||
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
|
||||
memcpy(&Data, &rhs.Data, sizeof (Data));
|
||||
if (Action == UnitActionResource && Arg1.Resource.Mine) {
|
||||
Arg1.Resource.Mine->RefsIncrease();
|
||||
}
|
||||
}
|
||||
|
||||
COrder& COrder::operator=(const COrder &rhs) {
|
||||
if (this != &rhs) {
|
||||
Action = rhs.Action;
|
||||
Range = rhs.Range;
|
||||
MinRange = rhs.MinRange;
|
||||
Width = rhs.Width;
|
||||
Height = rhs.Height;
|
||||
CurrentResource = rhs.CurrentResource;
|
||||
SetGoal(rhs.Goal);
|
||||
goalPos = rhs.goalPos;
|
||||
memcpy(&Arg1, &rhs.Arg1, sizeof(Arg1));
|
||||
memcpy(&Data, &rhs.Data, sizeof (Data));
|
||||
//FIXME: Hardcoded wood
|
||||
if (Action == UnitActionResource && Arg1.Resource.Mine) {
|
||||
Arg1.Resource.Mine->RefsIncrease();
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void COrder::SetGoal(CUnit *const new_goal)
|
||||
{
|
||||
if (new_goal) {
|
||||
|
@ -175,6 +176,118 @@ bool COrder::CheckRange() const
|
|||
return (Range <= Map.Info.MapWidth || Range <= Map.Info.MapHeight);
|
||||
}
|
||||
|
||||
void COrder::FillSeenValues(CUnit &unit) const
|
||||
{
|
||||
unit.Seen.State = (Action == UnitActionBuilt) | ((Action == UnitActionUpgradeTo) << 1);
|
||||
if (unit.CurrentAction() == UnitActionDie) {
|
||||
unit.Seen.State = 3;
|
||||
}
|
||||
if (Action == UnitActionBuilt) {
|
||||
unit.Seen.CFrame = Data.Built.Frame;
|
||||
} else {
|
||||
unit.Seen.CFrame = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool COrder::OnAiHitUnit(CUnit &unit, CUnit *attacker, int /*damage*/)
|
||||
{
|
||||
Assert(unit.CurrentOrder() == this);
|
||||
|
||||
switch (Action) {
|
||||
case UnitActionTrain:
|
||||
case UnitActionUpgradeTo:
|
||||
case UnitActionResearch:
|
||||
case UnitActionBuilt:
|
||||
case UnitActionBuild:
|
||||
case UnitActionTransformInto:
|
||||
case UnitActionBoard:
|
||||
case UnitActionUnload:
|
||||
case UnitActionReturnGoods:
|
||||
// Unit is working ?
|
||||
// Maybe AI should cancel action and save resources ???
|
||||
return true;
|
||||
case UnitActionResource:
|
||||
if (unit.SubAction >= 65) {
|
||||
//Normal return to depot
|
||||
return true;
|
||||
}
|
||||
if (unit.SubAction > 55 &&
|
||||
unit.ResourcesHeld > 0) {
|
||||
//escape to Depot with this what you have;
|
||||
Data.ResWorker.DoneHarvesting = 1;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case UnitActionAttack:
|
||||
{
|
||||
CUnit *goal = GetGoal();
|
||||
if (goal) {
|
||||
if (goal == attacker ||
|
||||
(goal->CurrentAction() == UnitActionAttack &&
|
||||
goal->CurrentOrder()->GetGoal() == &unit))
|
||||
{
|
||||
//we already fight with one of attackers;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** Called when unit is killed.
|
||||
** warn the AI module.
|
||||
*/
|
||||
void COrder::AiUnitKilled(CUnit& unit)
|
||||
{
|
||||
switch (Action) {
|
||||
case UnitActionStill:
|
||||
case UnitActionAttack:
|
||||
case UnitActionMove:
|
||||
break;
|
||||
case UnitActionBuilt:
|
||||
DebugPrint("%d: %d(%s) killed, under construction!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str());
|
||||
AiReduceMadeInBuilt(*unit.Player->Ai, *unit.Type);
|
||||
break;
|
||||
case UnitActionBuild:
|
||||
DebugPrint("%d: %d(%s) killed, with order %s!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_
|
||||
unit.Type->Ident.c_str() _C_ Arg1.Type->Ident.c_str());
|
||||
if (!HasGoal()) {
|
||||
AiReduceMadeInBuilt(*unit.Player->Ai, *Arg1.Type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DebugPrint("FIXME: %d: %d(%s) killed, with order %d!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_
|
||||
unit.Type->Ident.c_str() _C_ Action);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Call when animation step is "attack"
|
||||
*/
|
||||
void COrder::OnAnimationAttack(CUnit &unit)
|
||||
{
|
||||
Assert(unit.CurrentOrder() == this);
|
||||
|
||||
if (Action == UnitActionSpellCast) {
|
||||
CUnit *goal = GetGoal();
|
||||
if (goal && !goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
unit.ReCast = 0;
|
||||
} else {
|
||||
unit.ReCast = SpellCast(unit, Arg1.Spell, goal, goalPos.x, goalPos.y);
|
||||
}
|
||||
} else {
|
||||
FireMissile(unit);
|
||||
}
|
||||
UnHideUnit(unit); // unit is invisible until attacks
|
||||
}
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
|
@ -282,21 +395,10 @@ int UnitShowAnimationScaled(CUnit &unit, const CAnimation *anim, int scale)
|
|||
break;
|
||||
|
||||
case AnimationAttack:
|
||||
if (unit.CurrentAction() == UnitActionSpellCast) {
|
||||
CUnit *goal = unit.CurrentOrder()->GetGoal();
|
||||
if (goal && !goal->IsVisibleAsGoal(*unit.Player)) {
|
||||
unit.ReCast = 0;
|
||||
} else {
|
||||
COrderPtr order = unit.CurrentOrder();
|
||||
unit.ReCast = SpellCast(unit, order->Arg1.Spell,
|
||||
goal, order->goalPos.x, order->goalPos.y);
|
||||
}
|
||||
} else {
|
||||
FireMissile(unit);
|
||||
}
|
||||
UnHideUnit(unit); // unit is invisible until attacks
|
||||
{
|
||||
unit.CurrentOrder()->OnAnimationAttack(unit);
|
||||
break;
|
||||
|
||||
}
|
||||
case AnimationSpawnMissile:
|
||||
x = unit.tilePos.x * PixelTileSize.x + PixelTileSize.x / 2;
|
||||
y = unit.tilePos.y * PixelTileSize.y + PixelTileSize.y / 2;
|
||||
|
|
|
@ -620,17 +620,17 @@ static void AiRemoveFromBuilt(PlayerAi *pai, const CUnitType &type)
|
|||
** @param type Unit-type which is now available.
|
||||
** @return True if the unit-type could be reduced.
|
||||
*/
|
||||
static int AiReduceMadeInBuilt2(PlayerAi *pai, const CUnitType &type)
|
||||
static bool AiReduceMadeInBuilt2(PlayerAi &pai, const CUnitType &type)
|
||||
{
|
||||
std::vector<AiBuildQueue>::iterator i;
|
||||
|
||||
for (i = pai->UnitTypeBuilt.begin(); i != pai->UnitTypeBuilt.end(); ++i) {
|
||||
for (i = pai.UnitTypeBuilt.begin(); i != pai.UnitTypeBuilt.end(); ++i) {
|
||||
if (&type == (*i).Type && (*i).Made) {
|
||||
(*i).Made--;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -639,7 +639,7 @@ static int AiReduceMadeInBuilt2(PlayerAi *pai, const CUnitType &type)
|
|||
** @param pai Computer AI player.
|
||||
** @param type Unit-type which is now available.
|
||||
*/
|
||||
static void AiReduceMadeInBuilt(PlayerAi *pai, const CUnitType &type)
|
||||
void AiReduceMadeInBuilt(PlayerAi &pai, const CUnitType &type)
|
||||
{
|
||||
if (AiReduceMadeInBuilt2(pai, type)) {
|
||||
return;
|
||||
|
@ -653,7 +653,7 @@ static void AiReduceMadeInBuilt(PlayerAi *pai, const CUnitType &type)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (pai->Player == ThisPlayer) {
|
||||
if (pai.Player == ThisPlayer) {
|
||||
DebugPrint
|
||||
("My guess is that you built something under ai me. naughty boy!\n");
|
||||
return;
|
||||
|
@ -722,6 +722,7 @@ void AiHelpMe(const CUnit *attacker, CUnit &defender)
|
|||
|
||||
if (aiunit.StoreOrder(savedOrder) == false) {
|
||||
delete savedOrder;
|
||||
savedOrder = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -779,31 +780,7 @@ void AiUnitKilled(CUnit &unit)
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME: must handle all orders...
|
||||
switch (unit.CurrentAction()) {
|
||||
case UnitActionStill:
|
||||
case UnitActionAttack:
|
||||
case UnitActionMove:
|
||||
break;
|
||||
case UnitActionBuilt:
|
||||
DebugPrint("%d: %d(%s) killed, under construction!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_ unit.Type->Ident.c_str());
|
||||
AiReduceMadeInBuilt(unit.Player->Ai, *unit.Type);
|
||||
break;
|
||||
case UnitActionBuild:
|
||||
DebugPrint("%d: %d(%s) killed, with order %s!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_
|
||||
unit.Type->Ident.c_str() _C_ unit.CurrentOrder()->Arg1.Type->Ident.c_str());
|
||||
if (!unit.CurrentOrder()->HasGoal()) {
|
||||
AiReduceMadeInBuilt(unit.Player->Ai, *unit.CurrentOrder()->Arg1.Type);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
DebugPrint("FIXME: %d: %d(%s) killed, with order %d!\n" _C_
|
||||
unit.Player->Index _C_ UnitNumber(unit) _C_
|
||||
unit.Type->Ident.c_str() _C_ unit.CurrentAction());
|
||||
break;
|
||||
}
|
||||
unit.CurrentOrder()->AiUnitKilled(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -840,7 +817,7 @@ void AiCanNotBuild(CUnit &unit, const CUnitType &what)
|
|||
what.Ident.c_str() _C_ unit.tilePos.x _C_ unit.tilePos.y);
|
||||
|
||||
Assert(unit.Player->Type != PlayerPerson);
|
||||
AiReduceMadeInBuilt(unit.Player->Ai, what);
|
||||
AiReduceMadeInBuilt(*unit.Player->Ai, what);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -852,7 +829,7 @@ void AiCanNotBuild(CUnit &unit, const CUnitType &what)
|
|||
void AiCanNotReach(CUnit &unit, const CUnitType &what)
|
||||
{
|
||||
Assert(unit.Player->Type != PlayerPerson);
|
||||
AiReduceMadeInBuilt(unit.Player->Ai, what);
|
||||
AiReduceMadeInBuilt(*unit.Player->Ai, what);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -144,6 +144,12 @@ public:
|
|||
void NewResetPath() { Data.Move.Fast = 1; Data.Move.Length = 0; }
|
||||
|
||||
|
||||
void FillSeenValues(CUnit &unit) const;
|
||||
|
||||
bool OnAiHitUnit(CUnit &unit, CUnit *attacker, int /*damage*/);
|
||||
void AiUnitKilled(CUnit &unit);
|
||||
|
||||
void OnAnimationAttack(CUnit &unit);
|
||||
private:
|
||||
friend void CclParseOrder(lua_State *l, const CUnit &unit, COrder* order);
|
||||
|
||||
|
|
|
@ -1127,18 +1127,10 @@ static void UnitFillSeenValues(CUnit &unit)
|
|||
unit.Seen.IY = unit.IY;
|
||||
unit.Seen.IX = unit.IX;
|
||||
unit.Seen.Frame = unit.Frame;
|
||||
unit.Seen.State = (unit.CurrentAction() == UnitActionBuilt) |
|
||||
((unit.CurrentAction() == UnitActionUpgradeTo) << 1);
|
||||
if (unit.CurrentAction() == UnitActionDie) {
|
||||
unit.Seen.State = 3;
|
||||
}
|
||||
unit.Seen.Type = unit.Type;
|
||||
unit.Seen.Constructed = unit.Constructed;
|
||||
if (unit.CurrentAction() == UnitActionBuilt) {
|
||||
unit.Seen.CFrame = unit.CurrentOrder()->Data.Built.Frame;
|
||||
} else {
|
||||
unit.Seen.CFrame = NULL;
|
||||
}
|
||||
|
||||
unit.CurrentOrder()->FillSeenValues(unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2949,55 +2941,13 @@ void HitUnit(CUnit *attacker, CUnit &target, int damage)
|
|||
}
|
||||
|
||||
/* Target Reaction on Hit */
|
||||
if (target.Player->AiEnabled){
|
||||
switch (target.CurrentAction()) {
|
||||
case UnitActionTrain:
|
||||
case UnitActionUpgradeTo:
|
||||
case UnitActionResearch:
|
||||
case UnitActionBuilt:
|
||||
case UnitActionBuild:
|
||||
case UnitActionTransformInto:
|
||||
case UnitActionBoard:
|
||||
case UnitActionUnload:
|
||||
case UnitActionReturnGoods:
|
||||
//
|
||||
// Unit is working?
|
||||
// Maybe AI should cance action and save resources???
|
||||
//
|
||||
return;
|
||||
case UnitActionResource:
|
||||
if (target.SubAction >= 65) {
|
||||
//Normal return to depot
|
||||
return;
|
||||
}
|
||||
if (target.SubAction > 55 &&
|
||||
target.ResourcesHeld > 0) {
|
||||
//escape to Depot with this what you have;
|
||||
target.CurrentOrder()->Data.ResWorker.DoneHarvesting = 1;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case UnitActionAttack:
|
||||
{
|
||||
CUnit *goal = target.CurrentOrder()->GetGoal();
|
||||
if (goal) {
|
||||
if (goal == attacker ||
|
||||
(goal->CurrentAction() == UnitActionAttack &&
|
||||
goal->CurrentOrder()->GetGoal() == &target))
|
||||
{
|
||||
//we already fight with one of attackers;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
break;
|
||||
if (target.Player->AiEnabled) {
|
||||
if (target.CurrentOrder()->OnAiHitUnit(target, attacker, damage)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Attack units in range (which or the attacker?)
|
||||
//
|
||||
if (attacker && target.IsAgressive() && target.CanMove()) {
|
||||
if (target.CurrentAction() != UnitActionStill && !target.Player->AiEnabled) {
|
||||
return;
|
||||
|
|
Loading…
Add table
Reference in a new issue