Move some code into COrder

This commit is contained in:
joris 2012-02-14 12:08:22 +01:00
parent a34a1b8828
commit 137e4e58fd
4 changed files with 178 additions and 143 deletions

View file

@ -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;

View file

@ -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);
}
/**

View file

@ -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);

View file

@ -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;