[+] Applied Andrettin's patch for SetPlayerData, https://bugs.launchpad.net/stratagus/+bug/1331628
This commit is contained in:
parent
51647d9be9
commit
65487e9e2a
4 changed files with 167 additions and 15 deletions
|
@ -89,6 +89,7 @@ extern void UpgradeLost(CPlayer &player, int id);
|
|||
// id -- unit type id, af -- `A'llow/`F'orbid
|
||||
|
||||
extern int UnitIdAllowed(const CPlayer &player, int id);
|
||||
extern void AllowUpgradeId(CPlayer &player, int id, char af);
|
||||
|
||||
extern char UpgradeIdAllowed(const CPlayer &player, int id);
|
||||
extern char UpgradeIdentAllowed(const CPlayer &player, const std::string &ident);
|
||||
|
|
|
@ -180,7 +180,7 @@ public:
|
|||
class CUpgradeModifier
|
||||
{
|
||||
public:
|
||||
CUpgradeModifier() : UpgradeId(0), ModifyPercent(NULL), ConvertTo(NULL)
|
||||
CUpgradeModifier() : UpgradeId(0), ModifyPercent(NULL), SpeedResearch(0), ConvertTo(NULL)
|
||||
{
|
||||
memset(ChangeUnits, 0, sizeof(ChangeUnits));
|
||||
memset(ChangeUpgrades, 0, sizeof(ChangeUpgrades));
|
||||
|
@ -194,7 +194,8 @@ public:
|
|||
int UpgradeId; /// used to filter required modifier
|
||||
|
||||
CUnitStats Modifier; /// modifier of unit stats.
|
||||
int *ModifyPercent; /// use for percent modifiers
|
||||
int *ModifyPercent; /// use for percent modifiers
|
||||
int SpeedResearch; /// speed factor for researching
|
||||
|
||||
// allow/forbid bitmaps -- used as chars for example:
|
||||
// `?' -- leave as is, `F' -- forbid, `A' -- allow
|
||||
|
|
|
@ -842,6 +842,23 @@ static int CclSetPlayerData(lua_State *l)
|
|||
p->SpeedUpgrade = LuaToNumber(l, 3);
|
||||
} else if (!strcmp(data, "SpeedResearch")) {
|
||||
p->SpeedResearch = LuaToNumber(l, 3);
|
||||
} else if (!strcmp(data, "Allow")) {
|
||||
LuaCheckArgs(l, 4);
|
||||
const char *ident = LuaToString(l, 3);
|
||||
const std::string acquire = LuaToString(l, 4);
|
||||
|
||||
if (!strncmp(ident, "upgrade-", 8)) {
|
||||
if (acquire == "R" && UpgradeIdentAllowed(*p, ident) != 'R') {
|
||||
UpgradeAcquire(*p, CUpgrade::Get(ident));
|
||||
} else if (acquire == "F" || acquire == "A") {
|
||||
if (UpgradeIdentAllowed(*p, ident) == 'R') {
|
||||
UpgradeLost(*p, CUpgrade::Get(ident)->ID);
|
||||
}
|
||||
AllowUpgradeId(*p, UpgradeIdByIdent(ident), acquire[0]);
|
||||
}
|
||||
} else {
|
||||
LuaError(l, " wrong ident %s\n" _C_ ident);
|
||||
}
|
||||
} else {
|
||||
LuaError(l, "Invalid field: %s" _C_ data);
|
||||
}
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
----------------------------------------------------------------------------*/
|
||||
|
||||
static void AllowUnitId(CPlayer &player, int id, int units);
|
||||
static void AllowUpgradeId(CPlayer &player, int id, char af);
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Variables
|
||||
|
@ -314,6 +313,8 @@ static int CclDefineModifier(lua_State *l)
|
|||
} else if (!strcmp(key, "convert-to")) {
|
||||
const char *value = LuaToString(l, j + 1, 2);
|
||||
um->ConvertTo = UnitTypeByIdent(value);
|
||||
} else if (!strcmp(key, "research-speed")) {
|
||||
um->SpeedResearch = LuaToNumber(l, j + 1, 2);
|
||||
} else {
|
||||
int index = UnitTypeVar.VariableNameLookup[key]; // variable index;
|
||||
if (index != -1) {
|
||||
|
@ -621,6 +622,135 @@ static void ApplyUpgradeModifier(CPlayer &player, const CUpgradeModifier *um)
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Remove the modifiers of an upgrade.
|
||||
**
|
||||
** This function will unmark upgrade as done and undo all required modifications
|
||||
** to unit types and will modify allow/forbid maps back
|
||||
**
|
||||
** @param player Player that get all the upgrades.
|
||||
** @param um Upgrade modifier that do the effects
|
||||
*/
|
||||
static void RemoveUpgradeModifier(CPlayer &player, const CUpgradeModifier *um)
|
||||
{
|
||||
Assert(um);
|
||||
|
||||
int pn = player.Index;
|
||||
|
||||
if (um->SpeedResearch != 0) {
|
||||
player.SpeedResearch -= um->SpeedResearch;
|
||||
}
|
||||
|
||||
for (int z = 0; z < UpgradeMax; ++z) {
|
||||
// allow/forbid upgrades for player. only if upgrade is not acquired
|
||||
|
||||
// FIXME: check if modify is allowed
|
||||
|
||||
if (player.Allow.Upgrades[z] != 'R') {
|
||||
if (um->ChangeUpgrades[z] == 'A') {
|
||||
player.Allow.Upgrades[z] = 'F';
|
||||
}
|
||||
if (um->ChangeUpgrades[z] == 'F') {
|
||||
player.Allow.Upgrades[z] = 'A';
|
||||
}
|
||||
// we can even have upgrade acquired w/o costs
|
||||
if (um->ChangeUpgrades[z] == 'R') {
|
||||
player.Allow.Upgrades[z] = 'A';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t z = 0; z < UnitTypes.size(); ++z) {
|
||||
CUnitStats &stat = UnitTypes[z]->Stats[pn];
|
||||
// add/remove allowed units
|
||||
|
||||
// FIXME: check if modify is allowed
|
||||
|
||||
player.Allow.Units[z] -= um->ChangeUnits[z];
|
||||
|
||||
Assert(um->ApplyTo[z] == '?' || um->ApplyTo[z] == 'X');
|
||||
|
||||
// this modifier should be applied to unittype id == z
|
||||
if (um->ApplyTo[z] == 'X') {
|
||||
|
||||
// If Sight range is upgraded, we need to change EVERY unit
|
||||
// to the new range, otherwise the counters get confused.
|
||||
if (um->Modifier.Variables[SIGHTRANGE_INDEX].Value) {
|
||||
std::vector<CUnit *> unitupgrade;
|
||||
|
||||
FindUnitsByType(*UnitTypes[z], unitupgrade);
|
||||
for (size_t j = 0; j != unitupgrade.size(); ++j) {
|
||||
CUnit &unit = *unitupgrade[j];
|
||||
if (unit.Player->Index == pn && !unit.Removed) {
|
||||
MapUnmarkUnitSight(unit);
|
||||
unit.CurrentSightRange = stat.Variables[SIGHTRANGE_INDEX].Max -
|
||||
um->Modifier.Variables[SIGHTRANGE_INDEX].Value;
|
||||
MapMarkUnitSight(unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
// upgrade costs :)
|
||||
for (unsigned int j = 0; j < MaxCosts; ++j) {
|
||||
stat.Costs[j] -= um->Modifier.Costs[j];
|
||||
stat.Storing[j] -= um->Modifier.Storing[j];
|
||||
}
|
||||
|
||||
int varModified = 0;
|
||||
for (unsigned int j = 0; j < UnitTypeVar.GetNumberVariable(); j++) {
|
||||
varModified |= um->Modifier.Variables[j].Value
|
||||
| um->Modifier.Variables[j].Max
|
||||
| um->Modifier.Variables[j].Increase
|
||||
| um->Modifier.Variables[j].Enable
|
||||
| um->ModifyPercent[j];
|
||||
stat.Variables[j].Enable |= um->Modifier.Variables[j].Enable;
|
||||
if (um->ModifyPercent[j]) {
|
||||
stat.Variables[j].Value = stat.Variables[j].Value * 100 / (100 + um->ModifyPercent[j]);
|
||||
stat.Variables[j].Max = stat.Variables[j].Max * 100 / (100 + um->ModifyPercent[j]);
|
||||
} else {
|
||||
stat.Variables[j].Value -= um->Modifier.Variables[j].Value;
|
||||
stat.Variables[j].Max -= um->Modifier.Variables[j].Max;
|
||||
stat.Variables[j].Increase -= um->Modifier.Variables[j].Increase;
|
||||
}
|
||||
|
||||
stat.Variables[j].Max = std::max(stat.Variables[j].Max, 0);
|
||||
clamp(&stat.Variables[j].Value, 0, stat.Variables[j].Max);
|
||||
}
|
||||
|
||||
// And now modify ingame units
|
||||
if (varModified) {
|
||||
std::vector<CUnit *> unitupgrade;
|
||||
|
||||
FindUnitsByType(*UnitTypes[z], unitupgrade, true);
|
||||
for (size_t j = 0; j != unitupgrade.size(); ++j) {
|
||||
CUnit &unit = *unitupgrade[j];
|
||||
|
||||
if (unit.Player->Index != player.Index) {
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
|
||||
clamp(&unit.Variable[j].Value, 0, unit.Variable[j].Max);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (um->ConvertTo) {
|
||||
ConvertUnitTypeTo(player, *um->ConvertTo, *UnitTypes[z]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
** Handle that an upgrade was acquired.
|
||||
**
|
||||
|
@ -647,20 +777,23 @@ void UpgradeAcquire(CPlayer &player, const CUpgrade *upgrade)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0 // UpgradeLost not implemented.
|
||||
/**
|
||||
** for now it will be empty?
|
||||
** perhaps acquired upgrade can be lost if (for example) a building is lost
|
||||
** (lumber mill? stronghold?)
|
||||
** this function will apply all modifiers in reverse way
|
||||
*/
|
||||
void UpgradeLost(Player &player, int id)
|
||||
void UpgradeLost(CPlayer &player, int id)
|
||||
{
|
||||
player.UpgradeTimers.Upgrades[id] = 0;
|
||||
AllowUpgradeId(player, id, 'A'); // research is lost i.e. available
|
||||
// FIXME: here we should reverse apply upgrade...
|
||||
|
||||
for (int z = 0; z < NumUpgradeModifiers; ++z) {
|
||||
if (UpgradeModifiers[z]->UpgradeId == id) {
|
||||
RemoveUpgradeModifier(player, UpgradeModifiers[z]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Upgrades could change the buttons displayed.
|
||||
//
|
||||
if (&player == ThisPlayer) {
|
||||
SelectedUnitChanged();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
-- Allow(s)
|
||||
|
@ -687,7 +820,7 @@ static void AllowUnitId(CPlayer &player, int id, int units)
|
|||
** @param id upgrade id
|
||||
** @param af `A'llow/`F'orbid/`R'eseached
|
||||
*/
|
||||
static void AllowUpgradeId(CPlayer &player, int id, char af)
|
||||
void AllowUpgradeId(CPlayer &player, int id, char af)
|
||||
{
|
||||
Assert(af == 'A' || af == 'F' || af == 'R');
|
||||
player.Allow.Upgrades[id] = af;
|
||||
|
|
Loading…
Reference in a new issue