[+] Added SideAttack flag, which alters the attacking behavior and turns unit on 90 degrees before attack

This commit is contained in:
cybermind 2015-03-18 17:50:16 +05:00
parent 2776073cb5
commit bb2b5a5d68
4 changed files with 52 additions and 3 deletions

View file

@ -400,8 +400,19 @@ void COrder_Attack::MoveToTarget(CUnit &unit)
if (goal && unit.MapDistanceTo(*goal) <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
if (!GameSettings.Inside || CheckObstaclesBetweenTiles(unit.tilePos, goalPos, MapFieldRocks | MapFieldForest)) {
// Reached another unit, now attacking it
unsigned char oldDir = unit.Direction;
const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
UnitHeadingFromDeltaXY(unit, dir);
if (unit.Type->BoolFlag[SIDEATTACK_INDEX].value) {
unsigned char leftTurn = (unit.Direction - 2 * NextDirection) % (NextDirection * 8);
unsigned char rightTurn = (unit.Direction + 2 * NextDirection) % (NextDirection * 8);
if (abs(leftTurn - oldDir) < abs(rightTurn - oldDir)) {
unit.Direction = leftTurn;
} else {
unit.Direction = rightTurn;
}
UnitUpdateHeading(unit);
}
this->State++;
return;
}
@ -412,7 +423,18 @@ void COrder_Attack::MoveToTarget(CUnit &unit)
&& unit.MapDistanceTo(this->goalPos) <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
if (!GameSettings.Inside || CheckObstaclesBetweenTiles(unit.tilePos, goalPos, MapFieldRocks | MapFieldForest)) {
// Reached wall or ground, now attacking it
unsigned char oldDir = unit.Direction;
UnitHeadingFromDeltaXY(unit, this->goalPos - unit.tilePos);
if (unit.Type->BoolFlag[SIDEATTACK_INDEX].value) {
unsigned char leftTurn = (unit.Direction - 2 * NextDirection) % (NextDirection * 8);
unsigned char rightTurn = (unit.Direction + 2 * NextDirection) % (NextDirection * 8);
if (abs(leftTurn - oldDir) < abs(rightTurn - oldDir)) {
unit.Direction = leftTurn;
} else {
unit.Direction = rightTurn;
}
UnitUpdateHeading(unit);
}
this->State &= WEAK_TARGET;
this->State |= ATTACK_TARGET;
return;
@ -534,7 +556,18 @@ void COrder_Attack::AttackTarget(CUnit &unit)
// Turn always to target
if (goal) {
const Vec2i dir = goal->tilePos + goal->Type->GetHalfTileSize() - unit.tilePos;
unsigned char oldDir = unit.Direction;
UnitHeadingFromDeltaXY(unit, dir);
if (unit.Type->BoolFlag[SIDEATTACK_INDEX].value) {
unsigned char leftTurn = (unit.Direction - 2 * NextDirection) % (NextDirection * 8);
unsigned char rightTurn = (unit.Direction + 2 * NextDirection) % (NextDirection * 8);
if (abs(leftTurn - oldDir) < abs(rightTurn - oldDir)) {
unit.Direction = leftTurn;
} else {
unit.Direction = rightTurn;
}
UnitUpdateHeading(unit);
}
}
}
@ -583,8 +616,18 @@ void COrder_Attack::AttackTarget(CUnit &unit)
dist <= unit.Stats->Variables[ATTACKRANGE_INDEX].Max) {
if (!GameSettings.Inside || CheckObstaclesBetweenTiles(unit.tilePos, goalPos, MapFieldRocks | MapFieldForest)) {
const Vec2i dir = goal.tilePos + goal.Type->GetHalfTileSize() - unit.tilePos;
unsigned char oldDir = unit.Direction;
UnitHeadingFromDeltaXY(unit, dir);
if (unit.Type->BoolFlag[SIDEATTACK_INDEX].value) {
unsigned char leftTurn = (unit.Direction - 2 * NextDirection) % (NextDirection * 8);
unsigned char rightTurn = (unit.Direction + 2 * NextDirection) % (NextDirection * 8);
if (abs(leftTurn - oldDir) < abs(rightTurn - oldDir)) {
unit.Direction = leftTurn;
} else {
unit.Direction = rightTurn;
}
UnitUpdateHeading(unit);
}
this->State |= ATTACK_TARGET;
AttackTarget(unit);
return;

View file

@ -168,6 +168,7 @@ enum {
WALL_INDEX,
NORANDOMPLACING_INDEX,
ORGANIC_INDEX,
SIDEATTACK_INDEX,
NBARALREADYDEFINED
};
@ -569,6 +570,7 @@ public:
unsigned Wall : 1; /// Use special logic for Direction field.
unsigned NoRandomPlacing : 1; /// Don't use random frame rotation
unsigned Organic : 1; /// Organic unit (used for death coil spell)
unsigned SideAttack : 1; /// Unit turns for attack (used for ships)
CUnitStats DefaultStat;
struct BoolFlags {

View file

@ -91,6 +91,7 @@ static const char NONSOLID_KEY[] = "NonSolid";
static const char WALL_KEY[] = "Wall";
static const char NORANDOMPLACING_KEY[] = "NoRandomPlacing";
static const char ORGANIC_KEY[] = "organic";
static const char SIDEATTACK_KEY[] = "SideAttack";
// names of the variable.
static const char HITPOINTS_KEY[] = "HitPoints";
@ -148,7 +149,7 @@ CUnitTypeVar::CBoolKeys::CBoolKeys()
SHOREBUILDING_KEY, CANATTACK_KEY, BUILDEROUTSIDE_KEY,
BUILDERLOST_KEY, CANHARVEST_KEY, HARVESTER_KEY, SELECTABLEBYRECTANGLE_KEY,
ISNOTSELECTABLE_KEY, DECORATION_KEY, INDESTRUCTIBLE_KEY, TELEPORTER_KEY, SHIELDPIERCE_KEY,
SAVECARGO_KEY, NONSOLID_KEY, WALL_KEY, NORANDOMPLACING_KEY, ORGANIC_KEY
SAVECARGO_KEY, NONSOLID_KEY, WALL_KEY, NORANDOMPLACING_KEY, ORGANIC_KEY, SIDEATTACK_KEY
};
for (int i = 0; i < NBARALREADYDEFINED; ++i) {
@ -343,6 +344,7 @@ static void UpdateDefaultBoolFlags(CUnitType &type)
type.BoolFlag[WALL_INDEX].value = type.Wall;
type.BoolFlag[NORANDOMPLACING_INDEX].value = type.NoRandomPlacing;
type.BoolFlag[ORGANIC_INDEX].value = type.Organic;
type.BoolFlag[SIDEATTACK_INDEX].value = type.SideAttack;
}
/**
@ -991,6 +993,8 @@ static int CclDefineUnitType(lua_State *l)
type->NoRandomPlacing = LuaToBoolean(l, -1);
} else if (!strcmp(value, "organic")) {
type->Organic = LuaToBoolean(l, -1);
} else if (!strcmp(value, "SideAttack")) {
type->SideAttack = LuaToBoolean(l, -1);
} else if (!strcmp(value, "Sounds")) {
if (!lua_istable(l, -1)) {
LuaError(l, "incorrect argument");

View file

@ -630,7 +630,7 @@ CUnitType::CUnitType() :
BuilderOutside(0), BuilderLost(0), CanHarvest(0), Harvester(0),
Neutral(0), SelectableByRectangle(0), IsNotSelectable(0), Decoration(0),
Indestructible(0), Teleporter(0), SaveCargo(0),
NonSolid(0), Wall(0), NoRandomPlacing(0), Organic(0),
NonSolid(0), Wall(0), NoRandomPlacing(0), Organic(0), SideAttack(0),
GivesResource(0), Supply(0), Demand(0), PoisonDrain(0), FieldFlags(0), MovementMask(0),
Sprite(NULL), ShadowSprite(NULL)
{