Add DefineVariables (with associated stuff) and DefineDecorations
This commit is contained in:
parent
44a9d3eb25
commit
5a29400daf
12 changed files with 1150 additions and 515 deletions
|
@ -305,6 +305,7 @@ local void HandleRegenerations(Unit* unit)
|
|||
local void HandleBuffs(Unit* unit, int amount)
|
||||
{
|
||||
int deadunit;
|
||||
int i;
|
||||
|
||||
deadunit = 0;
|
||||
//
|
||||
|
@ -360,6 +361,18 @@ local void HandleBuffs(Unit* unit, int amount)
|
|||
unit->UnholyArmor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// User defined variables
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) {
|
||||
if (unit->Variable[i].Enable && unit->Variable[i].Increase) {
|
||||
unit->Variable[i].Value += unit->Variable[i].Increase;
|
||||
if (unit->Variable[i].Value <= 0) {
|
||||
unit->Variable[i].Value = 0;
|
||||
} else if (unit->Variable[i].Value > unit->Variable[i].Max) {
|
||||
unit->Variable[i].Value = unit->Variable[i].Max;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -69,6 +69,8 @@
|
|||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
void InitDefinedVariables();
|
||||
|
||||
/**
|
||||
** Cleanup modules.
|
||||
**
|
||||
|
@ -111,6 +113,7 @@ global void CleanModules(void)
|
|||
MapSplitterClean();
|
||||
#endif
|
||||
FreeAStar();
|
||||
InitDefinedVariables(); // internal script. should be to a better place, don't find for restart.
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -136,6 +136,27 @@ struct _spell_action_type_ {
|
|||
#define BUFF_NOT_AFFECTED 0xC0FF33 ///< Don't like the value? The value doesn't like you!
|
||||
} AdjustBuffs;
|
||||
|
||||
struct {
|
||||
int Index; ///< index of the variable to modify.
|
||||
|
||||
int Enable; ///< Value to affect to this field.
|
||||
int Value; ///< Value to affect to this field.
|
||||
int Max; ///< Value to affect to this field.
|
||||
int Increase; ///< Value to affect to this field.
|
||||
|
||||
char ModifEnable; ///< true if we modify this field.
|
||||
char ModifValue; ///< true if we modify this field.
|
||||
char ModifMax; ///< true if we modify this field.
|
||||
char ModifIncrease; ///< true if we modify this field.
|
||||
|
||||
char InvertEnable; ///< true if we invert this field.
|
||||
int AddValue; ///< Add this value to this field.
|
||||
int AddMax; ///< Add this value to this field.
|
||||
int AddIncrease; ///< Add this value to this field.
|
||||
int IncreaseTime; ///< How many time increase the Value field.
|
||||
char TargetIsCaster; ///< true if the target is the caster.
|
||||
} AdjustVariable;
|
||||
|
||||
struct {
|
||||
int HP; ///< Target HP gain.(can be negative)
|
||||
int Mana; ///< Target Mana gain.(can be negative)
|
||||
|
@ -216,6 +237,19 @@ typedef struct ConditionInfo {
|
|||
int MaxBloodlustTicks; ///< Target must less bloodlust ticks left.
|
||||
int MaxInvisibilityTicks; ///< Target must less bloodlust ticks left.
|
||||
int MaxInvincibilityTicks; ///< Target must less bloodlust ticks left.
|
||||
|
||||
struct {
|
||||
char Enable; /// Target is 'user defined variable'.
|
||||
|
||||
int MinValue; /// Target must have more Value than that.
|
||||
int MinMax; /// Target must have more Max than that.
|
||||
int MinValuePercent; /// Target must have more (100 * Value / Max) than that.
|
||||
int MaxValuePercent; /// Target must have less (100 * Value / Max) than that.
|
||||
|
||||
char ConditionApplyOnCaster; /// true if these condition are for caster.
|
||||
// FIXME : More (increase, MaxValue, MaxMax) ?
|
||||
|
||||
} *Variable;
|
||||
//
|
||||
// @todo more? feel free to add, here and to
|
||||
// @todo PassCondition, CclSpellParseCondition, SaveSpells
|
||||
|
@ -335,6 +369,7 @@ extern char Ccl2Condition(lua_State* l, const char* value);
|
|||
SpellFunc CastAreaAdjustVitals;
|
||||
SpellFunc CastAdjustVitals;
|
||||
SpellFunc CastAdjustBuffs;
|
||||
SpellFunc CastAdjustVariable;
|
||||
SpellFunc CastPolymorph;
|
||||
SpellFunc CastAreaBombardment;
|
||||
SpellFunc CastSummon;
|
||||
|
|
|
@ -568,6 +568,7 @@ struct _unit_ {
|
|||
int HP; ///< hit points
|
||||
int XP; ///< experience points
|
||||
int Kills; ///< how many unit has this unit killed
|
||||
VariableType *Variable; /// array of User Defined variables.
|
||||
|
||||
unsigned long TTL; ///< time to live
|
||||
int Bloodlust; ///< ticks bloodlust
|
||||
|
@ -706,15 +707,6 @@ extern int NumUnits; ///< Number of units used
|
|||
|
||||
// in unit_draw.c
|
||||
/// @todo could be moved into the user interface ?
|
||||
extern int ShowHealthBar; ///< Flag: show health bar
|
||||
extern int ShowHealthDot; ///< Flag: show health dot
|
||||
extern int ShowManaBar; ///< Flag: show mana bar
|
||||
extern int ShowManaDot; ///< Flag: show mana dot
|
||||
extern int ShowHealthHorizontal; ///< Flag: show health bar horizontal
|
||||
extern int ShowManaHorizontal; ///< Flag: show mana bar horizontal
|
||||
extern int ShowNoFull; ///< Flag: show no full health or mana
|
||||
extern int ShowEnergySelectedOnly; ///< Flag: show energy only for selected
|
||||
extern int DecorationOnTop; ///< Flag: show health and mana on top
|
||||
extern int ShowSightRange; ///< Flag: show right range
|
||||
extern int ShowReactionRange; ///< Flag: show reaction range
|
||||
extern int ShowAttackRange; ///< Flag: show attack range
|
||||
|
|
|
@ -629,6 +629,84 @@ typedef struct _resource_info_ {
|
|||
#endif
|
||||
} ResourceInfo;
|
||||
|
||||
/**
|
||||
** User defined variable type.
|
||||
**
|
||||
** It is used to define variables and use it after
|
||||
** to manage magic, energy, shield or other stuff.
|
||||
*/
|
||||
typedef struct {
|
||||
int Max; ///< Maximum for the variable. (Assume min is 0.)
|
||||
int Value; ///< Current (or initial) value of the variable (or initial value).
|
||||
char Increase; ///< Number to increase(decrease) Value by second.
|
||||
char Enable; ///< True if the unit doesn't have this variable. (f.e shield)
|
||||
} VariableType;
|
||||
|
||||
struct _decovartype_;
|
||||
struct _unit_;
|
||||
|
||||
typedef void DrawDecoFunc(int x, int y, const struct _unit_* unit, const struct _decovartype_* Deco);
|
||||
|
||||
/**
|
||||
** Decoration for userdefined variable.
|
||||
**
|
||||
** It is used to show variables graphicly.
|
||||
** @todo add more stuff in this struct.
|
||||
*/
|
||||
typedef struct _decovartype_{
|
||||
int Index; ///< Index of the variable. @see DefineVariables
|
||||
|
||||
int OffsetX; ///< Offset in X coord.
|
||||
int OffsetY; ///< Offset in Y coord.
|
||||
|
||||
int OffsetXPercent; ///< Percent offset (TileWidth) in X coord.
|
||||
int OffsetYPercent; ///< Percent offset (TileHeight) in Y coord.
|
||||
|
||||
char IsCenteredInX; ///< if true, use center of deco instead of left border
|
||||
char IsCenteredInY; ///< if true, use center of deco instead of upper border
|
||||
|
||||
char ShowIfNotEnable; ///< if false, Show only if var is enable
|
||||
char ShowWhenNull; ///< if false, don't show if var is null (F.E poison)
|
||||
char HideHalf; ///< if true, don't show when 0 < var < max.
|
||||
char ShowWhenMax; ///< if false, don't show if var is to max. (Like mana)
|
||||
char ShowOnlySelected; ///< if true, show only for selected units.
|
||||
|
||||
char HideNeutral; ///< if true, don't show for neutral unit.
|
||||
char HideAllied; ///< if true, don't show for allied unit. (but show own units)
|
||||
char ShowOpponent; ///< if true, show for opponent unit.
|
||||
|
||||
DrawDecoFunc *f; ///< fonction to draw the decorations.
|
||||
union {
|
||||
struct {
|
||||
char IsVertical; ///< if true, vertical bar, else horizontal.
|
||||
char SEToNW; ///< (SouthEastToNorthWest), if false value 0 is on the left or up of the bar.
|
||||
int Height; ///< Height of the bar.
|
||||
int Width; ///< Width of the bar.
|
||||
char ShowFullBackground; ///< if true, show background like value equal to max.
|
||||
char BorderSize; ///< Size of the border, 0 for no border.
|
||||
// FIXME color depend of percent (red, Orange, Yellow, Green...)
|
||||
Uint32 Color; ///< Color of bar.
|
||||
Uint32 BColor; ///< Color of background.
|
||||
} Bar; ///< Use for Horizontal and vertical Bar.
|
||||
|
||||
struct {
|
||||
// FIXME : Add Color, font, format
|
||||
} Text;
|
||||
|
||||
struct {
|
||||
char NSprite; ///< 0 for ManaSprite, 1 for HealthSprite.
|
||||
// FIXME Sprite info. better way ?
|
||||
} SpriteBar;
|
||||
|
||||
struct {
|
||||
// FIXME Sprite info. and Replace n with more appropriate var.
|
||||
int n; ///< identifiant in SpellSprite
|
||||
} StaticSprite;
|
||||
// FIXME : other method here.
|
||||
} Data; ///< More Datas, depend of showing method
|
||||
|
||||
} DecoVarType;
|
||||
|
||||
/**
|
||||
** Typedef of base structure of unit-type
|
||||
*/
|
||||
|
@ -744,6 +822,7 @@ struct _unit_type_ {
|
|||
unsigned CanHarvest : 1; ///< Resource can be harvested.
|
||||
unsigned Harvester : 1; ///< unit is a resource harvester.
|
||||
unsigned char *BoolFlag; ///< User defined flag. Used for (dis)allow target.
|
||||
VariableType *Variable; ///< Array of user defined variables.
|
||||
unsigned char *CanTargetFlag; ///< Flag needed to target with missile.
|
||||
|
||||
unsigned SelectableByRectangle : 1; ///< Selectable with mouse rectangle.
|
||||
|
@ -797,8 +876,18 @@ extern UnitType*UnitTypeOrcWall; ///< Orc wall
|
|||
|
||||
extern char** UnitTypeWcNames; ///< Mapping wc-number 2 symbol
|
||||
|
||||
extern char **BoolFlagName; ///< Array of name of user defined bool flag.
|
||||
extern int NumberBoolFlag; ///< Number of user defined bool flag.
|
||||
extern struct _UnitTypeVar_{
|
||||
char **BoolFlagName; ///< Array of name of user defined bool flag.
|
||||
int NumberBoolFlag; ///< Number of user defined bool flag.
|
||||
|
||||
char **VariableName; ///< Array of names of user defined variables.
|
||||
VariableType *Variable; ///< Array of user defined variables (default value for unittype).
|
||||
// EventType *Event; ///< Array of functions sets to call when en event occurs.
|
||||
int NumberVariable; ///< Number of defined variables.
|
||||
|
||||
DecoVarType *DecoVar; ///< Array to describe how showing variable.
|
||||
int NumberDeco; ///< Size of DecoVar.
|
||||
} UnitTypeVar;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
|
@ -812,6 +901,7 @@ extern void UpdateStats(int reset_to_default); ///< Update unit stats
|
|||
extern void ParsePudUDTA(const char*,int); ///< Parse pud udta table
|
||||
extern UnitType* UnitTypeByIdent(const char*); ///< Get unit-type by ident
|
||||
extern UnitType* UnitTypeByWcNum(unsigned); ///< Get unit-type by wc number
|
||||
extern int GetVariableIndex(const char *VarName); ///< Get index of the variable
|
||||
|
||||
/// Get the animations structure by ident
|
||||
extern Animations* AnimationsByIdent(const char* ident);
|
||||
|
|
|
@ -263,6 +263,65 @@ local void CclSpellAction(lua_State* l, SpellActionType* spellaction)
|
|||
LuaError(l, "Unsupported demolish tag: %s" _C_ value);
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(value, "adjust-variable")) {
|
||||
spellaction->CastFunction = CastAdjustVariable;
|
||||
spellaction->Data.AdjustVariable.Index = -1; // Invalid index
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
lua_pushnil(l);
|
||||
Assert(lua_istable(l, -2));
|
||||
while (lua_next(l, -2)) {
|
||||
const char *key;
|
||||
|
||||
key = LuaToString(l, -2);
|
||||
if (!strcmp(key, "Index")) {
|
||||
int i;
|
||||
|
||||
value = LuaToString(l, -1);
|
||||
spellaction->Data.AdjustVariable.Index = -1; // Invalid index
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) {
|
||||
if (!strcmp(value, UnitTypeVar.VariableName[i])) {
|
||||
spellaction->Data.AdjustVariable.Index = i;
|
||||
}
|
||||
}
|
||||
} else if (!strcmp(key, "Enable")) {
|
||||
spellaction->Data.AdjustVariable.Enable = LuaToBoolean(l, -1);
|
||||
spellaction->Data.AdjustVariable.ModifEnable = 1;
|
||||
} else if (!strcmp(key, "Value")) {
|
||||
spellaction->Data.AdjustVariable.Value = LuaToNumber(l, -1);
|
||||
spellaction->Data.AdjustVariable.ModifValue = 1;
|
||||
} else if (!strcmp(key, "Max")) {
|
||||
spellaction->Data.AdjustVariable.Max = LuaToNumber(l, -1);
|
||||
spellaction->Data.AdjustVariable.ModifMax = 1;
|
||||
} else if (!strcmp(key, "Increase")) {
|
||||
spellaction->Data.AdjustVariable.Increase = LuaToNumber(l, -1);
|
||||
spellaction->Data.AdjustVariable.ModifIncrease = 1;
|
||||
} else if (!strcmp(key, "InvertEnable")) {
|
||||
spellaction->Data.AdjustVariable.InvertEnable = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "AddValue")) {
|
||||
spellaction->Data.AdjustVariable.AddValue = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "AddMax")) {
|
||||
spellaction->Data.AdjustVariable.AddMax = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "AddIncrease")) {
|
||||
spellaction->Data.AdjustVariable.AddIncrease = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "IncreaseTime")) {
|
||||
spellaction->Data.AdjustVariable.IncreaseTime = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "TargetIsCaster")) {
|
||||
value = LuaToString(l, -1);
|
||||
if (!strcmp(value, "caster")) {
|
||||
spellaction->Data.AdjustVariable.TargetIsCaster = 1;
|
||||
} else if (!strcmp(value, "target")) {
|
||||
spellaction->Data.AdjustVariable.TargetIsCaster = 0;
|
||||
} else { // Error
|
||||
lua_pushfstring(l, "key '%s' not valid for TargetIsCaster in adjustvariable", value);
|
||||
lua_error(l);
|
||||
}
|
||||
} else { // Error
|
||||
lua_pushfstring(l, "key '%s' not valid for adjustvariable", key);
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 1); // Pop the value.
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
} else if (!strcmp(value, "adjust-buffs")) {
|
||||
spellaction->CastFunction = CastAdjustBuffs;
|
||||
spellaction->Data.AdjustBuffs.HasteTicks = BUFF_NOT_AFFECTED;
|
||||
|
@ -456,7 +515,8 @@ local void CclSpellCondition(lua_State* l, ConditionInfo* condition)
|
|||
// Set everything to 0:
|
||||
memset(condition, 0, sizeof(ConditionInfo));
|
||||
// Flags are defaulted to 0(CONDITION_TRUE)
|
||||
condition->BoolFlag = calloc(NumberBoolFlag, sizeof (*condition->BoolFlag));
|
||||
condition->BoolFlag = calloc(UnitTypeVar.NumberBoolFlag, sizeof (*condition->BoolFlag));
|
||||
condition->Variable = calloc(UnitTypeVar.NumberVariable, sizeof (*condition->Variable));
|
||||
// Initialize min/max stuff to values with no effect.
|
||||
condition->MinHpPercent = -10;
|
||||
condition->MaxHpPercent = 1000;
|
||||
|
@ -468,6 +528,12 @@ local void CclSpellCondition(lua_State* l, ConditionInfo* condition)
|
|||
condition->MaxBloodlustTicks = 0xFFFFFFF;
|
||||
condition->MaxInvisibilityTicks = 0xFFFFFFF;
|
||||
condition->MaxInvincibilityTicks = 0xFFFFFFF;
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) {
|
||||
condition->Variable[i].MinValue = -1;
|
||||
condition->Variable[i].MinMax = -1;
|
||||
condition->Variable[i].MinValuePercent = -8;
|
||||
condition->Variable[i].MaxValuePercent = 1024;
|
||||
}
|
||||
// Now parse the list and set values.
|
||||
if (!lua_istable(l, -1)) {
|
||||
LuaError(l, "incorrect argument");
|
||||
|
@ -535,15 +601,54 @@ local void CclSpellCondition(lua_State* l, ConditionInfo* condition)
|
|||
condition->MaxInvincibilityTicks = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
} else {
|
||||
for (i = 0; i < NumberBoolFlag; i++) { // User defined flags
|
||||
if (!strcmp(value, BoolFlagName[i])) {
|
||||
for (i = 0; i < UnitTypeVar.NumberBoolFlag; i++) { // User defined flags
|
||||
if (!strcmp(value, UnitTypeVar.BoolFlagName[i])) {
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
condition->BoolFlag[i] = Ccl2Condition(l, LuaToString(l, -1));
|
||||
lua_pop(l, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != NumberBoolFlag) {
|
||||
if (i != UnitTypeVar.NumberBoolFlag) {
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) { // User defined flags
|
||||
if (!strcmp(value, UnitTypeVar.VariableName[i])) {
|
||||
lua_rawgeti(l, -1, j + 1);
|
||||
if (lua_istable(l, -1)) {
|
||||
lua_pushnil(l);
|
||||
while (lua_next(l, -2)) {
|
||||
const char *key;
|
||||
|
||||
key = LuaToString(l, -2);
|
||||
if (!strcmp(key, "Enable")) {
|
||||
condition->Variable[i].Enable = Ccl2Condition(l, LuaToString(l, -1));
|
||||
} else if (!strcmp(key, "MinValue")) {
|
||||
condition->Variable[i].MinValue = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "MinMax")) {
|
||||
condition->Variable[i].MinMax = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "MinValuePercent")) {
|
||||
condition->Variable[i].MinValuePercent = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "MaxValuePercent")) {
|
||||
condition->Variable[i].MaxValuePercent = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "ConditionApplyOnCaster")) {
|
||||
condition->Variable[i].ConditionApplyOnCaster = LuaToBoolean(l, -1);
|
||||
} else { // Error
|
||||
lua_pushfstring(l, "%s invalid for Variable in condition", key);
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 1); // Pop value.
|
||||
}
|
||||
lua_pop(l, 1); // lua_rawgeti()
|
||||
break;
|
||||
} else { // Error
|
||||
lua_pushstring(l, "Table expected in variable in condition");
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 1); // lua_rawgeti()
|
||||
}
|
||||
}
|
||||
if (i != UnitTypeVar.NumberVariable) {
|
||||
continue;
|
||||
}
|
||||
LuaError(l, "Unsuported condition tag: %s" _C_ value);
|
||||
|
@ -893,10 +998,10 @@ local void SaveSpellCondition(CLFile* file, ConditionInfo* condition)
|
|||
if (condition->TargetSelf != CONDITION_TRUE) {
|
||||
CLprintf(file, "self %s ", condstrings[(int)condition->TargetSelf]);
|
||||
}
|
||||
for (i = 0; i < NumberBoolFlag; i++) { // User defined flags
|
||||
for (i = 0; i < UnitTypeVar.NumberBoolFlag; i++) { // User defined flags
|
||||
if (condition->BoolFlag[i] != CONDITION_TRUE) {
|
||||
CLprintf(file, "%s %s ",
|
||||
BoolFlagName[i], condstrings[(int)condition->BoolFlag[i]]);
|
||||
UnitTypeVar.BoolFlagName[i], condstrings[(int)condition->BoolFlag[i]]);
|
||||
}
|
||||
}
|
||||
//
|
||||
|
|
|
@ -450,6 +450,66 @@ global int CastAdjustBuffs(Unit* caster, const SpellType* spell,
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Adjust User Variables
|
||||
**
|
||||
** @param caster Unit that casts the spell
|
||||
** @param spell Spell-type pointer
|
||||
** @param target Target unit that spell is addressed to
|
||||
** @param x X coord of target spot when/if target does not exist
|
||||
** @param y Y coord of target spot when/if target does not exist
|
||||
**
|
||||
** @return =!0 if spell should be repeated, 0 if not
|
||||
*/
|
||||
global int CastAdjustVariable(Unit* caster, const SpellType* spell,
|
||||
const SpellActionType* action, Unit* target, int x, int y)
|
||||
{
|
||||
int index;
|
||||
Unit* unit;
|
||||
|
||||
Assert(action);
|
||||
|
||||
index = action->Data.AdjustVariable.Index;
|
||||
Assert(0 <= index && index < UnitTypeVar.NumberVariable);
|
||||
unit = (action->Data.AdjustVariable.TargetIsCaster) ? caster : target;
|
||||
Assert(unit);
|
||||
|
||||
// Enable flag.
|
||||
if (action->Data.AdjustVariable.ModifEnable) {
|
||||
unit->Variable[index].Enable = action->Data.AdjustVariable.Enable;
|
||||
}
|
||||
unit->Variable[index].Enable ^= action->Data.AdjustVariable.InvertEnable;
|
||||
|
||||
// Max field
|
||||
if (action->Data.AdjustVariable.ModifMax) {
|
||||
unit->Variable[index].Max = action->Data.AdjustVariable.Max;
|
||||
}
|
||||
unit->Variable[index].Max += action->Data.AdjustVariable.AddMax;
|
||||
|
||||
// Increase field
|
||||
if (action->Data.AdjustVariable.ModifIncrease) {
|
||||
unit->Variable[index].Increase = action->Data.AdjustVariable.Increase;
|
||||
}
|
||||
unit->Variable[index].Increase += action->Data.AdjustVariable.AddIncrease;
|
||||
|
||||
// Value field
|
||||
if (action->Data.AdjustVariable.ModifValue) {
|
||||
unit->Variable[index].Value = action->Data.AdjustVariable.Value;
|
||||
}
|
||||
unit->Variable[index].Value += action->Data.AdjustVariable.AddValue;
|
||||
unit->Variable[index].Value += action->Data.AdjustVariable.IncreaseTime
|
||||
* unit->Variable[index].Increase;
|
||||
|
||||
if (unit->Variable[index].Value <= 0) {
|
||||
unit->Variable[index].Value = 0;
|
||||
} else if (unit->Variable[index].Value > unit->Variable[index].Max) {
|
||||
unit->Variable[index].Value = unit->Variable[index].Max;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
** Cast healing. (or exorcism)
|
||||
**
|
||||
|
@ -753,6 +813,36 @@ local int PassCondition(const Unit* caster, const SpellType* spell, const Unit*
|
|||
if (!condition) { // no condition, pass.
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) {
|
||||
const Unit *unit;
|
||||
|
||||
unit = (condition->Variable[i].ConditionApplyOnCaster) ? caster : target;
|
||||
Assert(unit);
|
||||
if (condition->Variable[i].Enable != CONDITION_TRUE) {
|
||||
if ((condition->Variable[i].Enable == CONDITION_ONLY) ^ (unit->Variable[i].Enable)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
// Value and Max
|
||||
if (condition->Variable[i].MinValue >= unit->Variable[i].Value) {
|
||||
return 0;
|
||||
}
|
||||
if (condition->Variable[i].MinMax >= unit->Variable[i].Max) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Percent
|
||||
if (condition->Variable[i].MinValuePercent * unit->Variable[i].Max
|
||||
> 100 * unit->Variable[i].Value) {
|
||||
return 0;
|
||||
}
|
||||
if (condition->Variable[i].MaxValuePercent * unit->Variable[i].Max
|
||||
< 100 * unit->Variable[i].Value) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!target) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -766,7 +856,7 @@ local int PassCondition(const Unit* caster, const SpellType* spell, const Unit*
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < NumberBoolFlag; i++) { // User defined flags
|
||||
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])) {
|
||||
return 0;
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
|
||||
/// Get resource by name
|
||||
extern unsigned CclGetResourceByName(lua_State* l);
|
||||
/// Parse User Variables field.
|
||||
extern void DefineVariableField(lua_State *l, int var_index, int lua_index);
|
||||
|
||||
/**
|
||||
** Set xp damage
|
||||
|
@ -915,6 +917,11 @@ local int CclUnit(lua_State* l)
|
|||
}
|
||||
unit->AutoCastSpell[SpellTypeByIdent(s)->Slot] = 1;
|
||||
} else {
|
||||
i = GetVariableIndex(value); // User variables
|
||||
if (i != -1) { // Valid index
|
||||
DefineVariableField(l, i, j + 1);
|
||||
continue;
|
||||
}
|
||||
// FIXME: this leaves a half initialized unit
|
||||
LuaError(l, "Unsupported tag: %s" _C_ value);
|
||||
}
|
||||
|
|
|
@ -60,13 +60,19 @@ extern int NoWarningUnitType; /// quiet ident lookup.
|
|||
|
||||
global _AnimationsHash AnimationsHash; /// Animations hash table
|
||||
|
||||
global char** BoolFlagName; /// Name of user defined flag
|
||||
global int NumberBoolFlag; /// Number of defined flags.
|
||||
global struct _UnitTypeVar_ UnitTypeVar;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Functions
|
||||
----------------------------------------------------------------------------*/
|
||||
|
||||
void DefineVariableField(lua_State *l, int var_index, int lua_index);
|
||||
|
||||
DrawDecoFunc DrawBar;
|
||||
DrawDecoFunc PrintValue;
|
||||
DrawDecoFunc DrawSpriteBar;
|
||||
DrawDecoFunc DrawStaticSprite;
|
||||
|
||||
/**
|
||||
** Get the resource ID from a SCM object.
|
||||
**
|
||||
|
@ -126,8 +132,11 @@ local int CclDefineUnitType(lua_State* l)
|
|||
redefine = 1;
|
||||
} else {
|
||||
type = NewUnitTypeSlot(str);
|
||||
type->BoolFlag = calloc(NumberBoolFlag, sizeof(*type->BoolFlag));
|
||||
type->CanTargetFlag = calloc(NumberBoolFlag, sizeof(*type->CanTargetFlag));
|
||||
type->BoolFlag = calloc(UnitTypeVar.NumberBoolFlag, sizeof(*type->BoolFlag));
|
||||
type->CanTargetFlag = calloc(UnitTypeVar.NumberBoolFlag, sizeof(*type->CanTargetFlag));
|
||||
type->Variable = calloc(UnitTypeVar.NumberVariable, sizeof(*type->Variable));
|
||||
memcpy(type->Variable, UnitTypeVar.Variable,
|
||||
UnitTypeVar.NumberVariable * sizeof(*type->Variable));
|
||||
redefine = 0;
|
||||
}
|
||||
|
||||
|
@ -670,8 +679,8 @@ local int CclDefineUnitType(lua_State* l)
|
|||
value = LuaToString(l, -1);
|
||||
lua_pop(l, 1);
|
||||
++k;
|
||||
for (i = 0; i < NumberBoolFlag; ++i) {
|
||||
if (!strcmp(value, BoolFlagName[i])) {
|
||||
for (i = 0; i < UnitTypeVar.NumberBoolFlag; ++i) {
|
||||
if (!strcmp(value, UnitTypeVar.BoolFlagName[i])) {
|
||||
lua_rawgeti(l, -1, k + 1);
|
||||
value = LuaToString(l, -1);
|
||||
lua_pop(l, 1);
|
||||
|
@ -679,7 +688,7 @@ local int CclDefineUnitType(lua_State* l)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i != NumberBoolFlag) {
|
||||
if (i != UnitTypeVar.NumberBoolFlag) {
|
||||
continue;
|
||||
}
|
||||
printf("\n%s\n", type->Name);
|
||||
|
@ -776,13 +785,30 @@ local int CclDefineUnitType(lua_State* l)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < NumberBoolFlag; ++i) { // User defined bool flags
|
||||
if (!strcmp(value, BoolFlagName[i])) {
|
||||
i = GetVariableIndex(value);
|
||||
if (i != -1) { // valid index
|
||||
if (lua_isboolean(l, -1)) {
|
||||
type->Variable[i].Enable = LuaToBoolean(l, -1);
|
||||
} else if (lua_istable(l, -1)) {
|
||||
DefineVariableField(l, i, -1);
|
||||
} else if (lua_isnumber(l, -1)) {
|
||||
type->Variable[i].Enable = 1;
|
||||
type->Variable[i].Value = LuaToNumber(l, -1);
|
||||
type->Variable[i].Max = LuaToNumber(l, -1);
|
||||
} else { // Error
|
||||
lua_pushstring(l, "incorrect argument for the variable in unittype");
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 1);
|
||||
continue;
|
||||
}
|
||||
for (i = 0; i < UnitTypeVar.NumberBoolFlag; ++i) { // User defined bool flags
|
||||
if (!strcmp(value, UnitTypeVar.BoolFlagName[i])) {
|
||||
type->BoolFlag[i] = LuaToBoolean(l, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == NumberBoolFlag) {
|
||||
if (i == UnitTypeVar.NumberBoolFlag) {
|
||||
printf("\n%s\n",type->Name);
|
||||
LuaError(l, "Unsupported tag: %s" _C_ value);
|
||||
}
|
||||
|
@ -1187,6 +1213,102 @@ local int CclDefineAnimations(lua_State* l)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Define the field of the UserDefined variables
|
||||
**
|
||||
** @param l lua_state.
|
||||
** @param var_index index of variable to set.
|
||||
** @param var_index index of the table where are the infos
|
||||
**
|
||||
** @internal Use to not duplicate code.
|
||||
*/
|
||||
global void DefineVariableField(lua_State *l, int var_index, int lua_index)
|
||||
{
|
||||
if (lua_index < 0) { // relative index
|
||||
lua_index--;
|
||||
}
|
||||
lua_pushnil(l);
|
||||
while(lua_next(l, lua_index)) {
|
||||
const char *key;
|
||||
|
||||
key = LuaToString(l, -2);
|
||||
if (!strcmp(key, "Value")) {
|
||||
UnitTypeVar.Variable[var_index].Value = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "Max")) {
|
||||
UnitTypeVar.Variable[var_index].Max = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "Increase")) {
|
||||
UnitTypeVar.Variable[var_index].Increase = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "Enable")) {
|
||||
UnitTypeVar.Variable[var_index].Enable = LuaToBoolean(l, -1);
|
||||
} else { // Error.
|
||||
lua_pushfstring(l, "incorrect field '%s' for the variable '%s'",
|
||||
key, UnitTypeVar.VariableName[var_index]);
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 1); // pop the value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** return the index of the variable named VarName.
|
||||
**
|
||||
** @param VarName name of the variable
|
||||
**
|
||||
** @return index of the variable.
|
||||
*/
|
||||
global int GetVariableIndex(const char *VarName)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) {
|
||||
if (!strcmp(VarName, UnitTypeVar.VariableName[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
DebugPrint("Unknow variable \"%s\", use DefineVariables() before." _C_ VarName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
** Define user variables.
|
||||
**
|
||||
** @param l :
|
||||
** @return 0.
|
||||
*/
|
||||
local int CclDefineVariables(lua_State* l)
|
||||
{
|
||||
const char *str;
|
||||
int i;
|
||||
int args;
|
||||
int j;
|
||||
|
||||
args = lua_gettop(l);
|
||||
for (j = 0; j < args; ++j) {
|
||||
str = LuaToString(l, j + 1);
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; ++i) {
|
||||
if (!strcmp(str, UnitTypeVar.VariableName[i])) {
|
||||
DebugPrint("Warning, User Variable \"%s\" redefined\n" _C_ str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == UnitTypeVar.NumberVariable) { // new variable.
|
||||
UnitTypeVar.VariableName = realloc(UnitTypeVar.VariableName,
|
||||
(i + 1) * sizeof(*UnitTypeVar.VariableName));
|
||||
UnitTypeVar.VariableName[i] = strdup(str);
|
||||
UnitTypeVar.Variable = realloc(UnitTypeVar.Variable,
|
||||
(i + 1) * sizeof(*UnitTypeVar.Variable));
|
||||
memset(UnitTypeVar.Variable + i, 0, sizeof (*UnitTypeVar.Variable));
|
||||
UnitTypeVar.NumberVariable++;
|
||||
}
|
||||
if (!lua_istable(l, j + 2)) { // No change => default value.
|
||||
continue;
|
||||
}
|
||||
j++;
|
||||
DefineVariableField(l, i, j + 1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Define boolean flag.
|
||||
**
|
||||
|
@ -1200,40 +1322,205 @@ local int CclDefineBoolFlags(lua_State* l)
|
|||
int j;
|
||||
int old;
|
||||
|
||||
old = NumberBoolFlag;
|
||||
old = UnitTypeVar.NumberBoolFlag;
|
||||
args = lua_gettop(l);
|
||||
for (j = 0; j < args; ++j) {
|
||||
str = LuaToString(l, j + 1);
|
||||
for (i = 0; i < NumberBoolFlag; ++i) {
|
||||
if (!strcmp(str, BoolFlagName[i])) {
|
||||
for (i = 0; i < UnitTypeVar.NumberBoolFlag; ++i) {
|
||||
if (!strcmp(str, UnitTypeVar.BoolFlagName[i])) {
|
||||
DebugPrint("Warning, Bool flags already defined\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i != NumberBoolFlag) {
|
||||
DebugPrint("Warning, Bool flags '%s' already defined\n" _C_ BoolFlagName[i]);
|
||||
if (i != UnitTypeVar.NumberBoolFlag) {
|
||||
DebugPrint("Warning, Bool flags '%s' already defined\n" _C_ UnitTypeVar.BoolFlagName[i]);
|
||||
continue;
|
||||
}
|
||||
BoolFlagName = realloc(BoolFlagName, (NumberBoolFlag + 1) * sizeof(*BoolFlagName));
|
||||
BoolFlagName[NumberBoolFlag++] = strdup(str);
|
||||
UnitTypeVar.BoolFlagName = realloc(UnitTypeVar.BoolFlagName,
|
||||
(UnitTypeVar.NumberBoolFlag + 1) * sizeof(*UnitTypeVar.BoolFlagName));
|
||||
UnitTypeVar.BoolFlagName[UnitTypeVar.NumberBoolFlag++] = strdup(str);
|
||||
}
|
||||
if (0 < old && old != NumberBoolFlag) {
|
||||
if (0 < old && old != UnitTypeVar.NumberBoolFlag) {
|
||||
for (i = 0; i < NumUnitTypes; i++) { // adjust array for unit already defined
|
||||
UnitTypes[i]->BoolFlag = realloc(UnitTypes[i]->BoolFlag,
|
||||
NumberBoolFlag * sizeof((*UnitTypes)->BoolFlag));
|
||||
UnitTypeVar.NumberBoolFlag * sizeof((*UnitTypes)->BoolFlag));
|
||||
UnitTypes[i]->CanTargetFlag = realloc(UnitTypes[i]->CanTargetFlag,
|
||||
NumberBoolFlag * sizeof((*UnitTypes)->CanTargetFlag));
|
||||
UnitTypeVar.NumberBoolFlag * sizeof((*UnitTypes)->CanTargetFlag));
|
||||
memset(UnitTypes[i]->BoolFlag + old, 0,
|
||||
(NumberBoolFlag - old) * sizeof((*UnitTypes)->BoolFlag));
|
||||
(UnitTypeVar.NumberBoolFlag - old) * sizeof((*UnitTypes)->BoolFlag));
|
||||
memset(UnitTypes[i]->CanTargetFlag + old, 0,
|
||||
(NumberBoolFlag - old) * sizeof((*UnitTypes)->CanTargetFlag));
|
||||
(UnitTypeVar.NumberBoolFlag - old) * sizeof((*UnitTypes)->CanTargetFlag));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
** Define Decorations for user variables
|
||||
**
|
||||
** @param list : lua_state.
|
||||
** @return 0;
|
||||
** @todo modify Assert with luastate with User Error.
|
||||
** @todo continue to add configuration.
|
||||
*/
|
||||
local int CclDefineDecorations(lua_State* l)
|
||||
{
|
||||
int i;
|
||||
int nargs;
|
||||
int j;
|
||||
const char *key;
|
||||
DecoVarType DecoVar;
|
||||
|
||||
nargs = lua_gettop(l);
|
||||
for (i = 0; i < nargs; i++) {
|
||||
Assert(lua_istable(l, i + 1));
|
||||
memset(&DecoVar, 0, sizeof(DecoVar));
|
||||
lua_pushnil(l);
|
||||
while (lua_next(l, i + 1)) {
|
||||
key = LuaToString(l, -2);
|
||||
if (!strcmp(key, "Index")) {
|
||||
DecoVar.Index = GetVariableIndex(LuaToString(l, -1));
|
||||
} else if (!strcmp(key, "Offset")) {
|
||||
Assert(lua_istable(l, -1));
|
||||
lua_rawgeti(l, -1, 1); // X
|
||||
lua_rawgeti(l, -2, 2); // Y
|
||||
DecoVar.OffsetX = LuaToNumber(l, -2);
|
||||
DecoVar.OffsetY = LuaToNumber(l, -1);
|
||||
lua_pop(l, 2); // Pop X and Y
|
||||
} else if (!strcmp(key, "OffsetPercent")) {
|
||||
Assert(lua_istable(l, -1));
|
||||
lua_rawgeti(l, -1, 1); // X
|
||||
lua_rawgeti(l, -2, 2); // Y
|
||||
DecoVar.OffsetXPercent = LuaToNumber(l, -2);
|
||||
DecoVar.OffsetYPercent = LuaToNumber(l, -1);
|
||||
lua_pop(l, 2); // Pop X and Y
|
||||
} else if (!strcmp(key, "CenterX")) {
|
||||
DecoVar.IsCenteredInX = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "CenterY")) {
|
||||
DecoVar.IsCenteredInY = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "ShowIfNotEnable")) {
|
||||
DecoVar.ShowIfNotEnable = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "ShowWhenNull")) {
|
||||
DecoVar.ShowWhenNull = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "HideHalf")) {
|
||||
DecoVar.HideHalf = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "ShowWhenMax")) {
|
||||
DecoVar.ShowWhenMax = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "ShowOnlySelected")) {
|
||||
DecoVar.ShowOnlySelected = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "HideNeutral")) {
|
||||
DecoVar.HideNeutral = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "HideAllied")) {
|
||||
DecoVar.HideAllied = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "ShowOpponent")) {
|
||||
DecoVar.ShowOpponent = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "Method")) {
|
||||
Assert(lua_istable(l, -1));
|
||||
lua_rawgeti(l, -1, 1); // MethodName
|
||||
lua_rawgeti(l, -2, 2); // Data
|
||||
Assert(lua_istable(l, -1));
|
||||
key = LuaToString(l, -2);
|
||||
if (!strcmp(key, "bar")) {
|
||||
DecoVar.f = DrawBar;
|
||||
lua_pushnil(l);
|
||||
while (lua_next(l, -2)) {
|
||||
key = LuaToString(l, -2);
|
||||
if (!strcmp(key, "Height")) {
|
||||
DecoVar.Data.Bar.Height = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "Width")) {
|
||||
DecoVar.Data.Bar.Width = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "Orientation")) {
|
||||
key = LuaToString(l, -1);;
|
||||
if (!strcmp(key, "horizontal")) {
|
||||
DecoVar.Data.Bar.IsVertical = 0;
|
||||
} else if (!strcmp(key, "vertical")) {
|
||||
DecoVar.Data.Bar.IsVertical = 1;
|
||||
} else { // Error
|
||||
lua_pushfstring(l, "invalid Orientation '%s' for bar in DefineDecorations", key);
|
||||
lua_error(l);
|
||||
}
|
||||
} else if (!strcmp(key, "SEToNW")) {
|
||||
DecoVar.Data.Bar.SEToNW = LuaToBoolean(l, -1);
|
||||
} else if (!strcmp(key, "BorderSize")) {
|
||||
DecoVar.Data.Bar.BorderSize = LuaToNumber(l, -1);
|
||||
} else if (!strcmp(key, "ShowFullBackground")) {
|
||||
DecoVar.Data.Bar.ShowFullBackground = LuaToBoolean(l, -1);
|
||||
#if 0 // FIXME Color configuration
|
||||
} else if (!strcmp(key, "Color")) {
|
||||
DecoVar.Data.Bar.Color = // FIXME
|
||||
} else if (!strcmp(key, "BColor")) {
|
||||
DecoVar.Data.Bar.BColor = // FIXME
|
||||
#endif
|
||||
} else {
|
||||
lua_pushfstring(l, "'%s' invalid for Method bar", key);
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 1); // Pop value
|
||||
}
|
||||
|
||||
} else if (!strcmp(key, "text")) {
|
||||
DecoVar.f = PrintValue;
|
||||
// FIXME : More arguments ? Font, color...
|
||||
} else if (!strcmp(key, "sprite")) {
|
||||
DecoVar.f = DrawSpriteBar;
|
||||
lua_rawgeti(l, -1, 1);
|
||||
DecoVar.Data.SpriteBar.NSprite = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
// FIXME : More arguments ?
|
||||
} else if (!strcmp(key, "static-sprite")) {
|
||||
DecoVar.f = DrawStaticSprite;
|
||||
lua_rawgeti(l, -1, 1);
|
||||
DecoVar.Data.StaticSprite.n = LuaToNumber(l, -1);
|
||||
lua_pop(l, 1);
|
||||
} else { // Error
|
||||
lua_pushfstring(l, "invalid method '%s' for Method in DefineDecorations", key);
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 2); // MethodName and data
|
||||
} else { // Error
|
||||
lua_pushfstring(l, "invalid key '%s' for DefineDecorations", key);
|
||||
lua_error(l);
|
||||
}
|
||||
lua_pop(l, 1); // Pop the value
|
||||
}
|
||||
for (j = 0; j < UnitTypeVar.NumberDeco; j++) {
|
||||
if (DecoVar.Index == UnitTypeVar.DecoVar[j].Index) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (j == UnitTypeVar.NumberDeco) {
|
||||
UnitTypeVar.NumberDeco++;
|
||||
UnitTypeVar.DecoVar = realloc(UnitTypeVar.DecoVar,
|
||||
UnitTypeVar.NumberDeco * sizeof (*UnitTypeVar.DecoVar));
|
||||
}
|
||||
UnitTypeVar.DecoVar[j] = DecoVar;
|
||||
}
|
||||
Assert(lua_gettop(l));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
** Define already variables, usefull for drawing now.
|
||||
*/
|
||||
global void InitDefinedVariables()
|
||||
{
|
||||
#define NVARALREADYDEFINED 7
|
||||
const char *var[NVARALREADYDEFINED] = {"HitPoints", "Mana", "Transport",
|
||||
"Research", "Training", "UpgradeTo", "Ressource"};
|
||||
int i;
|
||||
|
||||
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;
|
||||
#undef NVARALREADYDEFINED
|
||||
}
|
||||
|
||||
/**
|
||||
** Register CCL features for unit-type.
|
||||
*/
|
||||
|
@ -1242,6 +1529,10 @@ global void UnitTypeCclRegister(void)
|
|||
lua_register(Lua, "DefineUnitType", CclDefineUnitType);
|
||||
lua_register(Lua, "DefineUnitStats", CclDefineUnitStats);
|
||||
lua_register(Lua, "DefineBoolFlags", CclDefineBoolFlags);
|
||||
lua_register(Lua, "DefineVariables", CclDefineVariables);
|
||||
lua_register(Lua, "DefineDecorations", CclDefineDecorations);
|
||||
|
||||
InitDefinedVariables();
|
||||
|
||||
lua_register(Lua, "UnitType", CclUnitType);
|
||||
lua_register(Lua, "UnitTypeArray", CclUnitTypeArray);
|
||||
|
|
|
@ -311,6 +311,11 @@ global void InitUnit(Unit* unit, UnitType* type)
|
|||
(type->Building ? 0 : type->NumDirections / 2 + 1 - 1);
|
||||
}
|
||||
|
||||
if (UnitTypeVar.NumberVariable) {
|
||||
unit->Variable = malloc(UnitTypeVar.NumberVariable * sizeof(*unit->Variable));
|
||||
memcpy(unit->Variable, unit->Type->Variable, UnitTypeVar.NumberVariable * sizeof(*unit->Variable));
|
||||
}
|
||||
|
||||
if (!type->Building && type->Sprite &&
|
||||
VideoGraphicFrames(type->Sprite) > 5) {
|
||||
unit->Direction = (MyRand() >> 8) & 0xFF; // random heading
|
||||
|
@ -3049,7 +3054,7 @@ global int CanTarget(const UnitType* source, const UnitType* dest)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NumberBoolFlag; i++) {
|
||||
for (i = 0; i < UnitTypeVar.NumberBoolFlag; i++) {
|
||||
if (source->CanTargetFlag[i] != CONDITION_TRUE) {
|
||||
if ((source->CanTargetFlag[i] == CONDITION_ONLY) ^ (dest->BoolFlag[i])) {
|
||||
return 0;
|
||||
|
@ -3320,6 +3325,12 @@ global void SaveUnit(const Unit* unit, CLFile* file)
|
|||
CLprintf(file, "\"flame-shield\", %d, ", unit->FlameShield);
|
||||
CLprintf(file, "\"unholy-armor\", %d,\n ", unit->UnholyArmor);
|
||||
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) {
|
||||
CLprintf(file, "\"%s\", {Value = %d, Max = %d, Increase = %d, Enable = %s},\n ",
|
||||
UnitTypeVar.VariableName[i], unit->Variable[i].Value, unit->Variable[i].Max,
|
||||
unit->Variable[i].Increase, unit->Variable[i].Enable ? "true" : "false");
|
||||
}
|
||||
|
||||
CLprintf(file, "\"group-id\", %d,\n ", unit->GroupId);
|
||||
CLprintf(file, "\"last-group\", %d,\n ", unit->LastGroup);
|
||||
|
||||
|
@ -3580,6 +3591,7 @@ global void CleanUnits(void)
|
|||
//
|
||||
for (table = Units; table < &Units[NumUnits]; ++table) {
|
||||
free((*table)->AutoCastSpell);
|
||||
free((*table)->Variable);
|
||||
free(*table);
|
||||
*table = NULL;
|
||||
}
|
||||
|
@ -3591,7 +3603,6 @@ global void CleanUnits(void)
|
|||
ReleasedHead = unit->Next;
|
||||
free(unit);
|
||||
}
|
||||
|
||||
InitUnitsMemory();
|
||||
|
||||
XpDamage = 0;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -927,6 +927,7 @@ global void CleanUnitTypes(void)
|
|||
Assert(type->Name);
|
||||
free(type->Name);
|
||||
|
||||
free(type->Variable);
|
||||
free(type->BoolFlag);
|
||||
free(type->CanTargetFlag);
|
||||
|
||||
|
@ -1016,12 +1017,17 @@ global void CleanUnitTypes(void)
|
|||
}
|
||||
NumUnitTypes = 0;
|
||||
|
||||
for (i = 0; i < NumberBoolFlag; i++) { // User defined flags
|
||||
free(BoolFlagName[i]);
|
||||
for (i = 0; i < UnitTypeVar.NumberBoolFlag; i++) { // User defined flags
|
||||
free(UnitTypeVar.BoolFlagName[i]);
|
||||
}
|
||||
free(BoolFlagName);
|
||||
BoolFlagName = NULL;
|
||||
NumberBoolFlag = 0;
|
||||
for (i = 0; i < UnitTypeVar.NumberVariable; i++) { // User defined variables
|
||||
free(UnitTypeVar.VariableName[i]);
|
||||
}
|
||||
free(UnitTypeVar.BoolFlagName);
|
||||
free(UnitTypeVar.VariableName);
|
||||
free(UnitTypeVar.Variable);
|
||||
free(UnitTypeVar.DecoVar);
|
||||
memset(&UnitTypeVar, 0, sizeof (UnitTypeVar));
|
||||
|
||||
//
|
||||
// Clean hardcoded unit types.
|
||||
|
|
Loading…
Add table
Reference in a new issue