Easy access to UnitTypeFlag with BoolFlag

This commit is contained in:
jarod42 2004-10-26 16:44:44 +00:00
parent fed091c9f5
commit 4bb9c0c16e
7 changed files with 78 additions and 52 deletions

View file

@ -246,32 +246,23 @@ on the unit properties. Here is how a condition looks like:
"max-slow-ticks", 10}</pre>
Here are the supported parameters:<p>
<dl>
<dt>"building", "true" or "false" or "only"</dt>
<dt>"alliance", "true" or "false" or "only"</dt>
<dd>This is one of the bool parameters (can't think of a better name). It is
followed by "true", "false" or "only". Imagine this as a question, is the target a
building? The answer is yes/no. A "true" parameter makes it always pass(and
followed by "true", "false" or "only". Imagine this as a question, is the target in
alliance? The answer is yes/no. A "true" parameter makes it always pass(and
it's the default.), "false" parameter passes when the answer is NO, and "only"
passes only when the answer is yes.<br>
It doesn't really makes sense to ever say true, since you might just as well
ommit it. "building false" means the spell won't work on buildings. "building
only" will make a spell that works only on buildings (can't think of any though).
This syntax is used for more that "building"
</dd>
<dt>"coward", "true" or "false" or "only"</dt>
<dd>This is a bool parameter too, just like building. I specifies the behaviour
for cowards, unit's that don't attack by themselves. For example you should not
cast an offensive buff (like bloodlust) on non-combat units.
</dd>
<dt>"alliance", "true" or "false" or "only"</dt>
<dd>This is a bool parameter too, just like building. I specifies the behaviour
for allied units. Your own units are considered allied too.
ommit it. "alliance false" means the spell won't work on allied units. "alliance
only" will make a spell that works only on allied units (can't think of any though).
Your own units are considered allied too.
</dd>
<dt>"opponent", "true" or "false" or "only"</dt>
<dd>This is a bool parameter too, just like building. I specifies the behaviour
<dd>This is a bool parameter too, just like alliance. I specifies the behaviour
for opponent units. Neutral units are neither allied unit nor opponent units.
</dd>
<dt>"self", "true" or "false" or "only"</dt>
<dd>This is a bool parameter too, just like building. I it a bit more special,
<dd>This is a bool parameter too, just like alliance. I it a bit more special,
since it specifies the behaviour for casting on yourself. <b>A LOT</b> of
spells specify "self false", to disallow casting on yourself.
</dd>

View file

@ -122,8 +122,15 @@ DefineAnimations("animations-footman",
Define boolean unit flags. Examples are organic, mechanical, undead, etc.
Spells use these to determine who to hit, and units can be restricted too.
Try to avoid using names with other meanings (nothing from unit definitions
or spell condition definition.)
Try to avoid using names with other meanings (nothing from spell condition definition.)
Some Flags are already defined in the engine : the UnitType flags.
So following flags are the value of the unitType :
"Building", "BuilderOutSide", "BuilderLost", "ShoreBuilding",
"Coward", "Harvester", "Revealer",
"LandUnit", "AirUnit", "SeaUnit",
"ExplodeWhenKilled", "VisibleUnderFog", "PermanentCloack", "AttackFromTransporter",
"GroundAttack", "CanAttack", "CanHarvest",
"Vanishes", "Flip"
<h4>Example</h4>

View file

@ -214,16 +214,11 @@ typedef struct ConditionInfo {
#define CONDITION_FALSE 1
#define CONDITION_TRUE 0
#define CONDITION_ONLY 2
char Coward; ///< Target is coward. Don't bloodlust them.
char Alliance; ///< Target is allied. (neutral is neither allied, nor opponent)
char Opponent; ///< Target is opponent. (neutral is neither allied, nor opponent)
char Building; ///< Target is a building.
char TargetSelf; ///< Target is the same as the caster.
char* BoolFlag; ///< User defined boolean flag.
#if 0
// TODO: NOT IMPLEMENTED:
char UnitBuffed; ///< Target is buffed(haste/slow/bloodlust). Dispel magic?
#endif
//
// Conditions related to vitals:
//

View file

@ -631,6 +631,30 @@ typedef struct _variable_type_ {
char Enable; ///< True if the unit doesn't have this variable. (f.e shield)
} VariableType;
// Index for boolflag aready defined
#define COWARD_INDEX 0
#define BUILDING_INDEX 1
#define FLIP_INDEX 2
#define REVEALER_INDEX 3
#define LANDUNIT_INDEX 4
#define AIRUNIT_INDEX 5
#define SEAUNIT_INDEX 6
#define EXPLODEWHENKILLED_INDEX 7
#define VISIBLEUNDERFOG_INDEX 8
#define PERMANENTCLOAK_INDEX 9
#define DETECTCLOAK_INDEX 10
#define ATTACKFROMTRANSPORTER_INDEX 11
#define VANISHES_INDEX 12
#define GROUNDATTACK_INDEX 13
#define SHOREBUILDING_INDEX 14
#define CANATTACK_INDEX 15
#define BUILDEROUTSIDE_INDEX 16
#define BUILDERLOST_INDEX 17
#define CANHARVEST_INDEX 18
#define HARVESTER_INDEX 19
#define NBOOLALREADYDEFINED HARVESTER_INDEX + 1 // Hardcoded boolflag
// Index for variable already defined.
#define HP_INDEX 0
#define BUILD_INDEX 1
@ -781,7 +805,7 @@ struct _building_restrictions_ {
} Data;
BuildRestriction* Next;
};
/**
** Base structure of unit-type

View file

@ -541,11 +541,7 @@ static void CclSpellCondition(lua_State* l, ConditionInfo* condition)
value = LuaToString(l, -1);
lua_pop(l, 1);
++j;
if (!strcmp(value, "coward")) {
lua_rawgeti(l, -1, j + 1);
condition->Coward = Ccl2Condition(l, LuaToString(l, -1));
lua_pop(l, 1);
} else if (!strcmp(value, "alliance")) {
if (!strcmp(value, "alliance")) {
lua_rawgeti(l, -1, j + 1);
condition->Alliance = Ccl2Condition(l, LuaToString(l, -1));
lua_pop(l, 1);
@ -553,10 +549,6 @@ static void CclSpellCondition(lua_State* l, ConditionInfo* condition)
lua_rawgeti(l, -1, j + 1);
condition->Opponent = Ccl2Condition(l, LuaToString(l, -1));
lua_pop(l, 1);
} else if (!strcmp(value, "building")) {
lua_rawgeti(l, -1, j + 1);
condition->Building = Ccl2Condition(l, LuaToString(l, -1));
lua_pop(l, 1);
} else if (!strcmp(value, "self")) {
lua_rawgeti(l, -1, j + 1);
condition->TargetSelf = Ccl2Condition(l, LuaToString(l, -1));
@ -981,15 +973,9 @@ static void SaveSpellCondition(CLFile* file, ConditionInfo* condition)
// First save data related to flags.
// NOTE: (int) is there to keep compilers happy.
//
if (condition->Coward != CONDITION_TRUE) {
CLprintf(file, "coward %s ", condstrings[(int)condition->Coward]);
}
if (condition->Alliance != CONDITION_TRUE) {
CLprintf(file, "alliance %s ", condstrings[(int)condition->Alliance]);
}
if (condition->Building != CONDITION_TRUE) {
CLprintf(file, "building %s ", condstrings[(int)condition->Building]);
}
if (condition->TargetSelf != CONDITION_TRUE) {
CLprintf(file, "self %s ", condstrings[(int)condition->TargetSelf]);
}

View file

@ -837,16 +837,6 @@ static int PassCondition(const Unit* caster, const SpellType* spell, const Unit*
if (!target) {
return 1;
}
if (condition->Building != CONDITION_TRUE) {
if ((condition->Building == CONDITION_ONLY) ^ (target->Type->Building)) {
return 0;
}
}
if (condition->Coward != CONDITION_TRUE) {
if ((condition->Coward == CONDITION_ONLY) ^ (target->Type->Coward)) {
return 0;
}
}
for (i = 0; i < UnitTypeVar.NumberBoolFlag; i++) { // User defined flags
if (condition->BoolFlag[i] != CONDITION_TRUE) {
if ((condition->BoolFlag[i] == CONDITION_ONLY) ^ (target->Type->BoolFlag[i])) {

View file

@ -1698,6 +1698,7 @@ static int CclDefineDecorations(lua_State* l)
void UpdateUnitVariables(const Unit* unit)
{
int i;
const UnitType* type; // unit->Type.
for (i = 0; i < NVARALREADYDEFINED; i++) { // default values
unit->Variable[i].Value = 0;
@ -1831,6 +1832,29 @@ void UpdateUnitVariables(const Unit* unit)
unit->Variable[i].Enable &= unit->Variable[i].Max > 0;
Assert(unit->Variable[i].Value <= unit->Variable[i].Max);
}
// BoolFlag
type = unit->Type;
type->BoolFlag[COWARD_INDEX] = type->Coward;
type->BoolFlag[BUILDING_INDEX] = type->Building;
type->BoolFlag[FLIP_INDEX] = type->Flip;
type->BoolFlag[REVEALER_INDEX] = type->Revealer;
type->BoolFlag[LANDUNIT_INDEX] = type->LandUnit;
type->BoolFlag[AIRUNIT_INDEX] = type->AirUnit;
type->BoolFlag[SEAUNIT_INDEX] = type->SeaUnit;
type->BoolFlag[EXPLODEWHENKILLED_INDEX] = type->ExplodeWhenKilled;
type->BoolFlag[VISIBLEUNDERFOG_INDEX] = type->VisibleUnderFog;
type->BoolFlag[PERMANENTCLOAK_INDEX] = type->PermanentCloak;
type->BoolFlag[DETECTCLOAK_INDEX] = type->DetectCloak;
type->BoolFlag[ATTACKFROMTRANSPORTER_INDEX] = type->AttackFromTransporter;
type->BoolFlag[VANISHES_INDEX] = type->Vanishes;
type->BoolFlag[GROUNDATTACK_INDEX] = type->GroundAttack;
type->BoolFlag[SHOREBUILDING_INDEX] = type->ShoreBuilding;
type->BoolFlag[CANATTACK_INDEX] = type->CanAttack;
type->BoolFlag[BUILDEROUTSIDE_INDEX] = type->BuilderOutside;
type->BoolFlag[BUILDERLOST_INDEX] = type->BuilderLost;
type->BoolFlag[CANHARVEST_INDEX] = type->CanHarvest;
type->BoolFlag[HARVESTER_INDEX] = type->Harvester;
}
/**
@ -1844,14 +1868,23 @@ void InitDefinedVariables()
"AttackRange", "PiercingDamage", "BasicDamage", "Damage", "ExtraDamage",
"PosX", "PosY", "Slot"
}; // names of the variable.
int i;
const char* boolflag = "DefineBoolFlags(\"Coward\", \"Building\", \"Flip\","
"\"Revealer\", \"LandUnit\", \"AirUnit\", \"SeaUnit\", \"ExplodeWhenKilled\","
"\"VisibleUnderFog\", \"PermanentCloack\", \"AttackFromTransporter\","
"\"Vanishes\", \"GroundAttack\", \"ShoreBuilding\", \"CanAttack\","
"\"BuilderOutSide\", \"BuilderLost\", \"CanHarvest\", \"Harvester\")";
int i; // iterator for var and boolflag.
// Variables.
UnitTypeVar.VariableName = calloc(NVARALREADYDEFINED, sizeof(*UnitTypeVar.VariableName));
for (i = 0; i < NVARALREADYDEFINED; i++) {
UnitTypeVar.VariableName[i] = strdup(var[i]);
}
UnitTypeVar.Variable = calloc(i, sizeof(*UnitTypeVar.Variable));
UnitTypeVar.NumberVariable = i;
// Boolflags.
CclCommand(boolflag);
}
/**