SetUnitVariable can now add individual upgrades to units, and GetUnitVariable can now get whether they have an individual upgrade

GetUnitVariable can now also check whether a unit is idle or not
This commit is contained in:
Andrettin 2015-11-24 20:25:27 +01:00
parent 6adaccfd9f
commit b664bcceff
8 changed files with 188 additions and 14 deletions

View file

@ -720,22 +720,24 @@ Returns the current player. Usefull mostly in for AI scripts.
</pre>
<a name="GetUnitVariable"></a>
<h3>GetUnitVariable(unit, VariableName)</h3>
<h3>GetUnitVariable(unit, VariableName, third_element)</h3>
Get a unit's mana.
Get a unit's variable.
<dl>
<dt>unit</dt>
<dd>Unit to get info for.</dd>
<dt>VariableName</dt>
<dd>Name of the variable to get info for.</dd>
<dd>Name of the variable to get info for. Also takes "IndividualUpgrade" instead of a variable name, to get whether the unit has acquired a particular individual upgrade. Alternatively, takes "Idle" to check whether the unit is idle or not.</dd>
<dt>third_element</dt>
<dd>Used if getting whether the unit has an individual upgrade, taking the upgrade's ident.</dd>
</dl>
<h4>Example</h4>
<pre>
-- Get mana of the unit (slot #11).
GetUnitMana(11, "Mana");
GetUnitVariable(11, "Mana");
</pre>
<a name="Group"></a>
@ -1401,15 +1403,17 @@ Set ThisPlayer.
</pre>
<a name="SetUnitVariable"></a>
<h3>SetUnitVariable(unit, VariableName, amount)</h3>
<h3>SetUnitVariable(unit, VariableName, amount, fourth_element)</h3>
Set the amount of VariableName of the unit.
<dl>
<dt>unit</dt>
<dd>Unit to set the info for.</dd>
<dt>VariableName</dt>
<dd>Variable to set.</dd>
<dd>Variable to set. Also takes "IndividualUpgrade" instead of a variable name, to make the unit acquire or lose an individual upgrade.</dd>
<dt>amount</dt>
<dd>New amount of VariableName for the unit.</dd>
<dd>New amount of VariableName for the unit. Alternatively, if setting an individual upgrade for the unit, this field takes the ident of the upgrade.</dd>
<dt>fourth_element</dt>
<dd>Used if setting an individual upgrade for the unit. Use a boolean value for whether the unit will acquire or lose the individual upgrade.</dd>
</dl>
<h4>Example</h4>

View file

@ -10,7 +10,7 @@
//
/**@name interface.h - The user interface header file. */
//
// (c) Copyright 1998-2006 by Lutz Sammer and Jimmy Salmon
// (c) Copyright 1998-2015 by Lutz Sammer, Jimmy Salmon and Andrettin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -398,6 +398,8 @@ extern bool ButtonCheckTrue(const CUnit &unit, const ButtonAction &button);
extern bool ButtonCheckFalse(const CUnit &unit, const ButtonAction &button);
/// Check if allowed upgrade is ready
extern bool ButtonCheckUpgrade(const CUnit &unit, const ButtonAction &button);
/// Check if unit has an individual upgrade
extern bool ButtonCheckIndividualUpgrade(const CUnit &unit, const ButtonAction &button);
/// Check if unit's variables pass the condition check
extern bool ButtonCheckUnitVariable(const CUnit &unit, const ButtonAction &button);
/// Check if allowed units exists

View file

@ -10,7 +10,8 @@
//
/**@name upgrade.h - The upgrades headerfile. */
//
// (c) Copyright 1999-2006 by Vladi Belperchinov-Shabanski and Jimmy Salmon
// (c) Copyright 1999-2015 by Vladi Belperchinov-Shabanski, Jimmy Salmon
// and Andrettin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -79,6 +80,10 @@ extern void UpgradeLost(CPlayer &player, int id);
/// Apply researched upgrades when map is loading
extern void ApplyUpgrades();
extern void ApplyIndividualUpgradeModifier(CUnit &unit, const CUpgradeModifier *um); /// Apply upgrade modifier of an individual upgrade
extern void IndividualUpgradeAcquire(CUnit &unit, const CUpgrade *upgrade); /// Make a unit acquire in individual upgrade
extern void IndividualUpgradeLost(CUnit &unit, const CUpgrade *upgrade); /// Make a unit lose in individual upgrade
/*----------------------------------------------------------------------------
-- Allow(s)
----------------------------------------------------------------------------*/

View file

@ -10,7 +10,8 @@
//
/**@name button_checks.cpp - The button checks. */
//
// (c) Copyright 1999-2006 by Lutz Sammer, Vladi Belperchinov-Shabanski
// (c) Copyright 1999-2015 by Lutz Sammer, Vladi Belperchinov-Shabanski
// and Andrettin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -90,6 +91,19 @@ bool ButtonCheckUpgrade(const CUnit &unit, const ButtonAction &button)
return UpgradeIdentAllowed(*unit.Player, button.AllowStr) == 'R';
}
/**
** Check for button enabled, if unit has an individual upgrade.
**
** @param unit Pointer to unit for button.
** @param button Pointer to button to check/enable.
**
** @return True if enabled.
*/
bool ButtonCheckIndividualUpgrade(const CUnit &unit, const ButtonAction &button)
{
return unit.IndividualUpgrades[UpgradeIdByIdent(button.AllowStr)];
}
/**
** Check for button enabled, if unit's variables pass the condition check.
**

View file

@ -10,7 +10,8 @@
//
/**@name script_ui.cpp - The ui ccl functions. */
//
// (c) Copyright 1999-2007 by Lutz Sammer, Jimmy Salmon, Martin Renold
// (c) Copyright 1999-2015 by Lutz Sammer, Jimmy Salmon, Martin Renold
// and Andrettin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -1003,6 +1004,8 @@ static int CclDefineButton(lua_State *l)
ba.Allowed = ButtonCheckFalse;
} else if (!strcmp(value, "check-upgrade")) {
ba.Allowed = ButtonCheckUpgrade;
} else if (!strcmp(value, "check-individual-upgrade")) {
ba.Allowed = ButtonCheckIndividualUpgrade;
} else if (!strcmp(value, "check-unit-variable")) {
ba.Allowed = ButtonCheckUnitVariable;
} else if (!strcmp(value, "check-units-or")) {

View file

@ -1099,6 +1099,18 @@ static int CclGetUnitVariable(lua_State *l)
lua_pushstring(l, unit->Type->Name.c_str());
} else if (!strcmp(value, "PlayerType")) {
lua_pushinteger(l, unit->Player->Type);
} else if (!strcmp(value, "IndividualUpgrade")) {
LuaCheckArgs(l, 3);
std::string upgrade_ident = LuaToString(l, 3);
if (CUpgrade::Get(upgrade_ident)) {
lua_pushboolean(l, unit->IndividualUpgrades[CUpgrade::Get(upgrade_ident)->ID]);
} else {
LuaError(l, "Individual upgrade \"%s\" doesn't exist." _C_ upgrade_ident.c_str());
}
return 1;
} else if (!strcmp(value, "Idle")) {
lua_pushboolean(l, unit->IsIdle());
return 1;
} else {
int index = UnitTypeVar.VariableNameLookup[value];// User variables
if (index == -1) {
@ -1143,10 +1155,22 @@ static int CclSetUnitVariable(lua_State *l)
int value;
if (!strcmp(name, "Player")) {
unit->AssignToPlayer(Players[LuaToNumber(l, 3)]);
}
if (!strcmp(name, "RegenerationRate")) {
} else if (!strcmp(name, "RegenerationRate")) {
value = LuaToNumber(l, 3);
unit->Variable[HP_INDEX].Increase = std::min(unit->Variable[HP_INDEX].Max, value);
} else if (!strcmp(name, "IndividualUpgrade")) {
LuaCheckArgs(l, 4);
std::string upgrade_ident = LuaToString(l, 3);
bool has_upgrade = LuaToBoolean(l, 4);
if (CUpgrade::Get(upgrade_ident)) {
if (has_upgrade && unit->IndividualUpgrades[CUpgrade::Get(upgrade_ident)->ID] == false) {
IndividualUpgradeAcquire(*unit, CUpgrade::Get(upgrade_ident));
} else if (!has_upgrade && unit->IndividualUpgrades[CUpgrade::Get(upgrade_ident)->ID]) {
IndividualUpgradeLost(*unit, CUpgrade::Get(upgrade_ident));
}
} else {
LuaError(l, "Individual upgrade \"%s\" doesn't exist." _C_ upgrade_ident.c_str());
}
} else {
const int index = UnitTypeVar.VariableNameLookup[name];// User variables
if (index == -1) {

View file

@ -10,7 +10,7 @@
//
/**@name unit.cpp - The units. */
//
// (c) Copyright 1998-2008 by Lutz Sammer and Jimmy Salmon
// (c) Copyright 1998-2015 by Lutz Sammer, Jimmy Salmon and Andrettin
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -472,6 +472,7 @@ void CUnit::Init()
SpellCoolDownTimers = NULL;
AutoRepair = 0;
Goal = NULL;
memset(IndividualUpgrades, 0, sizeof(IndividualUpgrades));
}
@ -598,6 +599,8 @@ void CUnit::Init(const CUnitType &type)
Variable = NULL;
}
memset(IndividualUpgrades, 0, sizeof(IndividualUpgrades));
// Set a heading for the unit if it Handles Directions
// Don't set a building heading, as only 1 construction direction
// is allowed.
@ -1776,6 +1779,13 @@ void CUnit::ChangeOwner(CPlayer &newplayer)
}
newplayer.UnitTypesCount[Type->Slot]++;
//apply the upgrades of the new player, if the old one doesn't have that upgrade
for (int z = 0; z < NumUpgradeModifiers; ++z) {
if (oldplayer->Allow.Upgrades[UpgradeModifiers[z]->UpgradeId] != 'R' && UpgradeModifiers[z]->ApplyTo[Type->Slot] == 'X') { //if the old player doesn't have the modifier's upgrade, and the upgrade is applicable to the unit
ApplyIndividualUpgradeModifier(*this, UpgradeModifiers[z]); //apply the upgrade to this unit only
}
}
UpdateForNewUnit(*this, 1);
}

View file

@ -752,6 +752,78 @@ static void RemoveUpgradeModifier(CPlayer &player, const CUpgradeModifier *um)
}
}
/**
** Apply the modifiers of an individual upgrade.
**
** @param unit Unit that will get the modifier applied
** @param um Upgrade modifier that does the effects
*/
void ApplyIndividualUpgradeModifier(CUnit &unit, const CUpgradeModifier *um)
{
Assert(um);
if (um->Modifier.Variables[SIGHTRANGE_INDEX].Value) {
if (!unit.Removed) {
MapUnmarkUnitSight(unit);
unit.CurrentSightRange = unit.Variable[SIGHTRANGE_INDEX].Value +
um->Modifier.Variables[SIGHTRANGE_INDEX].Value;
UpdateUnitSightRange(unit);
MapMarkUnitSight(unit);
}
}
for (unsigned int j = 0; j < UnitTypeVar.GetNumberVariable(); j++) {
unit.Variable[j].Enable |= um->Modifier.Variables[j].Enable;
if (um->ModifyPercent[j]) {
unit.Variable[j].Value += unit.Variable[j].Value * um->ModifyPercent[j] / 100;
unit.Variable[j].Max += unit.Variable[j].Max * um->ModifyPercent[j] / 100;
} else {
unit.Variable[j].Value += um->Modifier.Variables[j].Value;
unit.Variable[j].Increase += um->Modifier.Variables[j].Increase;
}
unit.Variable[j].Max += um->Modifier.Variables[j].Max;
unit.Variable[j].Max = std::max(unit.Variable[j].Max, 0);
if (unit.Variable[j].Max > 0) {
clamp(&unit.Variable[j].Value, 0, unit.Variable[j].Max);
}
}
if (um->ConvertTo) {
CommandTransformIntoType(unit, *um->ConvertTo);
}
}
static void RemoveIndividualUpgradeModifier(CUnit &unit, const CUpgradeModifier *um)
{
Assert(um);
if (um->Modifier.Variables[SIGHTRANGE_INDEX].Value) {
if (!unit.Removed) {
MapUnmarkUnitSight(unit);
unit.CurrentSightRange = unit.Variable[SIGHTRANGE_INDEX].Value -
um->Modifier.Variables[SIGHTRANGE_INDEX].Value;
UpdateUnitSightRange(unit);
MapMarkUnitSight(unit);
}
}
for (unsigned int j = 0; j < UnitTypeVar.GetNumberVariable(); j++) {
unit.Variable[j].Enable |= um->Modifier.Variables[j].Enable;
if (um->ModifyPercent[j]) {
unit.Variable[j].Value = unit.Variable[j].Value * 100 / (100 + um->ModifyPercent[j]);
unit.Variable[j].Max = unit.Variable[j].Max * 100 / (100 + um->ModifyPercent[j]);
} else {
unit.Variable[j].Value -= um->Modifier.Variables[j].Value;
unit.Variable[j].Increase -= um->Modifier.Variables[j].Increase;
}
unit.Variable[j].Max -= um->Modifier.Variables[j].Max;
unit.Variable[j].Max = std::max(unit.Variable[j].Max, 0);
if (unit.Variable[j].Max > 0) {
clamp(&unit.Variable[j].Value, 0, unit.Variable[j].Max);
}
}
}
/**
** Handle that an upgrade was acquired.
**
@ -830,6 +902,46 @@ void ApplyUpgrades()
}
}
void IndividualUpgradeAcquire(CUnit &unit, const CUpgrade *upgrade)
{
int id = upgrade->ID;
unit.Player->UpgradeTimers.Upgrades[id] = upgrade->Costs[TimeCost];
unit.IndividualUpgrades[id] = true;
for (int z = 0; z < NumUpgradeModifiers; ++z) {
if (UpgradeModifiers[z]->UpgradeId == id) {
ApplyIndividualUpgradeModifier(unit, UpgradeModifiers[z]);
}
}
//
// Upgrades could change the buttons displayed.
//
if (unit.Player == ThisPlayer) {
SelectedUnitChanged();
}
}
void IndividualUpgradeLost(CUnit &unit, const CUpgrade *upgrade)
{
int id = upgrade->ID;
unit.Player->UpgradeTimers.Upgrades[id] = 0;
unit.IndividualUpgrades[id] = false;
for (int z = 0; z < NumUpgradeModifiers; ++z) {
if (UpgradeModifiers[z]->UpgradeId == id) {
RemoveIndividualUpgradeModifier(unit, UpgradeModifiers[z]);
}
}
//
// Upgrades could change the buttons displayed.
//
if (unit.Player == ThisPlayer) {
SelectedUnitChanged();
}
}
/*----------------------------------------------------------------------------
-- Allow(s)
----------------------------------------------------------------------------*/