mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-17 22:03:56 -07:00
Add a time multiplier for AI levels
Differential Revision: https://code.wildfiregames.com/D1350 This was SVN commit r21423.
This commit is contained in:
parent
a8a29271ce
commit
5b314fc0ac
9 changed files with 61 additions and 57 deletions
|
|
@ -45,7 +45,7 @@ Cost.prototype.GetPopBonus = function()
|
|||
Cost.prototype.GetBuildTime = function()
|
||||
{
|
||||
var cmpPlayer = QueryOwnerInterface(this.entity);
|
||||
var buildTime = (+this.template.BuildTime) * cmpPlayer.cheatTimeMultiplier;
|
||||
var buildTime = (+this.template.BuildTime) * cmpPlayer.GetTimeMultiplier();
|
||||
return ApplyValueModificationsToEntity("Cost/BuildTime", buildTime, this.entity);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -98,8 +98,7 @@ Pack.prototype.GetPackTime = function()
|
|||
{
|
||||
let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
|
||||
|
||||
return ApplyValueModificationsToEntity("Pack/Time", +this.template.Time, this.entity) *
|
||||
cmpPlayer.GetCheatTimeMultiplier();
|
||||
return ApplyValueModificationsToEntity("Pack/Time", +this.template.Time, this.entity) * cmpPlayer.GetTimeMultiplier();
|
||||
};
|
||||
|
||||
Pack.prototype.GetElapsedTime = function()
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ Player.prototype.Init = function()
|
|||
this.startCam = undefined;
|
||||
this.controlAllUnits = false;
|
||||
this.isAI = false;
|
||||
this.timeMultiplier = 1;
|
||||
this.gatherRateMultiplier = 1;
|
||||
this.tradeRateMultiplier = 1;
|
||||
this.cheatsEnabled = false;
|
||||
|
|
@ -89,7 +90,7 @@ Player.prototype.Init = function()
|
|||
this.resourceCount[res] = 300;
|
||||
this.resourceNames[res] = Resources.GetResource(res).name;
|
||||
this.tradingGoods.push({
|
||||
"goods": res,
|
||||
"goods": res,
|
||||
"proba": 5 * (quotient + (+i < remainder ? 1 : 0))
|
||||
});
|
||||
}
|
||||
|
|
@ -223,19 +224,14 @@ Player.prototype.GetBarterMultiplier = function()
|
|||
return this.barterMultiplier;
|
||||
};
|
||||
|
||||
Player.prototype.SetGatherRateMultiplier = function(value)
|
||||
{
|
||||
this.gatherRateMultiplier = value;
|
||||
};
|
||||
|
||||
Player.prototype.GetGatherRateMultiplier = function()
|
||||
{
|
||||
return this.gatherRateMultiplier;
|
||||
return this.gatherRateMultiplier / this.cheatTimeMultiplier;
|
||||
};
|
||||
|
||||
Player.prototype.SetTradeRateMultiplier = function(value)
|
||||
Player.prototype.GetTimeMultiplier = function()
|
||||
{
|
||||
this.tradeRateMultiplier = value;
|
||||
return this.timeMultiplier * this.cheatTimeMultiplier;
|
||||
};
|
||||
|
||||
Player.prototype.GetTradeRateMultiplier = function()
|
||||
|
|
@ -248,6 +244,24 @@ Player.prototype.GetSpyCostMultiplier = function()
|
|||
return this.spyCostMultiplier;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setters currently used by the AI to set the difficulty level
|
||||
*/
|
||||
Player.prototype.SetGatherRateMultiplier = function(value)
|
||||
{
|
||||
this.gatherRateMultiplier = value;
|
||||
};
|
||||
|
||||
Player.prototype.SetTimeMultiplier = function(value)
|
||||
{
|
||||
this.timeMultiplier = value;
|
||||
};
|
||||
|
||||
Player.prototype.SetTradeRateMultiplier = function(value)
|
||||
{
|
||||
this.tradeRateMultiplier = value;
|
||||
};
|
||||
|
||||
Player.prototype.GetPanelEntities = function()
|
||||
{
|
||||
return this.panelEntities;
|
||||
|
|
|
|||
|
|
@ -191,9 +191,7 @@ ProductionQueue.prototype.GetTechnologiesList = function()
|
|||
{
|
||||
var tech = techList[i];
|
||||
while (this.IsTechnologyResearchedOrInProgress(tech))
|
||||
{
|
||||
tech = superseded[tech];
|
||||
}
|
||||
|
||||
techList[i] = tech;
|
||||
}
|
||||
|
|
@ -212,7 +210,7 @@ ProductionQueue.prototype.GetTechnologiesList = function()
|
|||
|
||||
let template = TechnologyTemplates.Get(tech);
|
||||
if (template.top)
|
||||
ret[i] = {"pair": true, "top": template.top, "bottom": template.bottom};
|
||||
ret[i] = { "pair": true, "top": template.top, "bottom": template.bottom };
|
||||
else
|
||||
ret[i] = tech;
|
||||
}
|
||||
|
|
@ -237,14 +235,10 @@ ProductionQueue.prototype.IsTechnologyResearchedOrInProgress = function(tech)
|
|||
|
||||
let template = TechnologyTemplates.Get(tech);
|
||||
if (template.top)
|
||||
{
|
||||
return (cmpTechnologyManager.IsTechnologyResearched(template.top) || cmpTechnologyManager.IsInProgress(template.top)
|
||||
|| cmpTechnologyManager.IsTechnologyResearched(template.bottom) || cmpTechnologyManager.IsInProgress(template.bottom));
|
||||
}
|
||||
else
|
||||
{
|
||||
return (cmpTechnologyManager.IsTechnologyResearched(tech) || cmpTechnologyManager.IsInProgress(tech));
|
||||
}
|
||||
return cmpTechnologyManager.IsTechnologyResearched(template.top) || cmpTechnologyManager.IsInProgress(template.top) ||
|
||||
cmpTechnologyManager.IsTechnologyResearched(template.bottom) || cmpTechnologyManager.IsInProgress(template.bottom);
|
||||
|
||||
return cmpTechnologyManager.IsTechnologyResearched(tech) || cmpTechnologyManager.IsInProgress(tech);
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
@ -300,7 +294,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
totalCosts[res] = Math.floor(count * costs[res]);
|
||||
}
|
||||
|
||||
var population = ApplyValueModificationsToTemplate("Cost/Population", +template.Cost.Population, cmpPlayer.GetPlayerID(), template);
|
||||
var population = ApplyValueModificationsToTemplate("Cost/Population", +template.Cost.Population, cmpPlayer.GetPlayerID(), template);
|
||||
|
||||
// TrySubtractResources should report error to player (they ran out of resources)
|
||||
if (!cmpPlayer.TrySubtractResources(totalCosts))
|
||||
|
|
@ -329,7 +323,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
|
||||
// Call the related trigger event
|
||||
var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
|
||||
cmpTrigger.CallEvent("TrainingQueued", {"playerid": cmpPlayer.GetPlayerID(), "unitTemplate": templateName, "count": count, "metadata": metadata, "trainerEntity": this.entity});
|
||||
cmpTrigger.CallEvent("TrainingQueued", { "playerid": cmpPlayer.GetPlayerID(), "unitTemplate": templateName, "count": count, "metadata": metadata, "trainerEntity": this.entity });
|
||||
}
|
||||
else if (type == "technology")
|
||||
{
|
||||
|
|
@ -348,7 +342,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
|
||||
let template = TechnologyTemplates.Get(templateName);
|
||||
let techCostMultiplier = this.GetTechCostMultiplier();
|
||||
let time = techCostMultiplier.time * template.researchTime * cmpPlayer.GetCheatTimeMultiplier();
|
||||
let time = techCostMultiplier.time * template.researchTime * cmpPlayer.GetTimeMultiplier();
|
||||
|
||||
let cost = {};
|
||||
for (let res in template.cost)
|
||||
|
|
@ -378,7 +372,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
|
||||
// Call the related trigger event
|
||||
var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
|
||||
cmpTrigger.CallEvent("ResearchQueued", {"playerid": cmpPlayer.GetPlayerID(), "technologyTemplate": templateName, "researcherEntity": this.entity});
|
||||
cmpTrigger.CallEvent("ResearchQueued", { "playerid": cmpPlayer.GetPlayerID(), "technologyTemplate": templateName, "researcherEntity": this.entity });
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -397,7 +391,7 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
}
|
||||
else
|
||||
{
|
||||
var notification = {"players": [cmpPlayer.GetPlayerID()], "message": markForTranslation("The production queue is full."), "translateMessage": true };
|
||||
var notification = { "players": [cmpPlayer.GetPlayerID()], "message": markForTranslation("The production queue is full."), "translateMessage": true };
|
||||
var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
cmpGUIInterface.PushNotification(notification);
|
||||
}
|
||||
|
|
@ -410,10 +404,9 @@ ProductionQueue.prototype.AddBatch = function(templateName, type, count, metadat
|
|||
ProductionQueue.prototype.RemoveBatch = function(id)
|
||||
{
|
||||
// Destroy any cached entities (those which didn't spawn for some reason)
|
||||
for (var i = 0; i < this.entityCache.length; ++i)
|
||||
{
|
||||
Engine.DestroyEntity(this.entityCache[i]);
|
||||
}
|
||||
for (let ent of this.entityCache)
|
||||
Engine.DestroyEntity(ent);
|
||||
|
||||
this.entityCache = [];
|
||||
|
||||
for (var i = 0; i < this.queue.length; ++i)
|
||||
|
|
@ -486,7 +479,7 @@ ProductionQueue.prototype.GetQueue = function()
|
|||
"technologyTemplate": item.technologyTemplate,
|
||||
"count": item.count,
|
||||
"neededSlots": item.neededSlots,
|
||||
"progress": 1 - ( item.timeRemaining / (item.timeTotal || 1) ),
|
||||
"progress": 1 - (item.timeRemaining / (item.timeTotal || 1)),
|
||||
"timeRemaining": item.timeRemaining,
|
||||
"metadata": item.metadata,
|
||||
});
|
||||
|
|
@ -517,7 +510,7 @@ ProductionQueue.prototype.GetBatchTime = function(batchSize)
|
|||
var batchTimeModifier = ApplyValueModificationsToEntity("ProductionQueue/BatchTimeModifier", +this.template.BatchTimeModifier, this.entity);
|
||||
|
||||
// TODO: work out what equation we should use here.
|
||||
return Math.pow(batchSize, batchTimeModifier) * cmpPlayer.GetCheatTimeMultiplier();
|
||||
return Math.pow(batchSize, batchTimeModifier) * cmpPlayer.GetTimeMultiplier();
|
||||
};
|
||||
|
||||
ProductionQueue.prototype.OnOwnershipChanged = function(msg)
|
||||
|
|
@ -588,7 +581,7 @@ ProductionQueue.prototype.SpawnUnits = function(templateName, count, metadata)
|
|||
{
|
||||
var unitCategory = cmpTrainingRestrictions.GetCategory();
|
||||
var cmpPlayerEntityLimits = QueryOwnerInterface(this.entity, IID_EntityLimits);
|
||||
cmpPlayerEntityLimits.ChangeCount(unitCategory,-1);
|
||||
cmpPlayerEntityLimits.ChangeCount(unitCategory, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -701,7 +694,7 @@ ProductionQueue.prototype.ProgressTimeout = function(data)
|
|||
{
|
||||
// If something change population cost
|
||||
var template = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager).GetTemplate(item.unitTemplate);
|
||||
item.population = ApplyValueModificationsToTemplate("Cost/Population", +template.Cost.Population, item.player, template);
|
||||
item.population = ApplyValueModificationsToTemplate("Cost/Population", +template.Cost.Population, item.player, template);
|
||||
|
||||
// Batch's training hasn't started yet.
|
||||
// Try to reserve the necessary population slots
|
||||
|
|
@ -729,7 +722,7 @@ ProductionQueue.prototype.ProgressTimeout = function(data)
|
|||
|
||||
item.productionStarted = true;
|
||||
if (item.unitTemplate)
|
||||
Engine.PostMessage(this.entity, MT_TrainingStarted, {"entity": this.entity});
|
||||
Engine.PostMessage(this.entity, MT_TrainingStarted, { "entity": this.entity });
|
||||
}
|
||||
|
||||
// If we won't finish the batch now, just update its timer
|
||||
|
|
|
|||
|
|
@ -69,9 +69,7 @@ ResourceGatherer.prototype.GetCarryingStatus = function()
|
|||
ResourceGatherer.prototype.GiveResources = function(resources)
|
||||
{
|
||||
for (let resource of resources)
|
||||
{
|
||||
this.carrying[resource.type] = +(resource.amount);
|
||||
}
|
||||
|
||||
Engine.PostMessage(this.entity, MT_ResourceCarryingChanged, { "to": this.GetCarryingStatus() });
|
||||
};
|
||||
|
|
@ -98,8 +96,8 @@ ResourceGatherer.prototype.GetLastCarriedType = function()
|
|||
{
|
||||
if (this.lastCarriedType && this.lastCarriedType.generic in this.carrying)
|
||||
return this.lastCarriedType;
|
||||
else
|
||||
return undefined;
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
// Since this code is very performancecritical and applying technologies quite slow, cache it.
|
||||
|
|
@ -179,7 +177,7 @@ ResourceGatherer.prototype.TryInstantGather = function(target)
|
|||
|
||||
let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
|
||||
if (cmpTrigger && cmpPlayer)
|
||||
cmpTrigger.CallEvent("TreasureCollected", {"player": cmpPlayer.GetPlayerID(), "type": type.specific, "amount": status.amount });
|
||||
cmpTrigger.CallEvent("TreasureCollected", { "player": cmpPlayer.GetPlayerID(), "type": type.specific, "amount": status.amount });
|
||||
|
||||
return true;
|
||||
};
|
||||
|
|
@ -248,10 +246,6 @@ ResourceGatherer.prototype.GetTargetGatherRate = function(target)
|
|||
if (rate == 0 && type.generic)
|
||||
rate = this.GetGatherRate(type.generic);
|
||||
|
||||
let cmpPlayer = QueryOwnerInterface(this.entity, IID_Player);
|
||||
let cheatMultiplier = cmpPlayer ? cmpPlayer.GetCheatTimeMultiplier() : 1;
|
||||
rate = rate / cheatMultiplier;
|
||||
|
||||
if ("Mirages" in cmpResourceSupply)
|
||||
return rate;
|
||||
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ Upgrade.prototype.GetUpgradeTime = function(templateArg)
|
|||
|
||||
let cmpPlayer = QueryPlayerIDInterface(this.owner, IID_Player);
|
||||
return ApplyValueModificationsToEntity("Upgrade/Time", +this.template[choice].Time, this.entity) *
|
||||
cmpPlayer.GetCheatTimeMultiplier();
|
||||
cmpPlayer.GetTimeMultiplier();
|
||||
};
|
||||
|
||||
Upgrade.prototype.GetElapsedTime = function()
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ AddMock(SYSTEM_ENTITY, IID_PlayerManager, {
|
|||
});
|
||||
|
||||
AddMock(11, IID_Player, {
|
||||
"GetCheatTimeMultiplier": () => 1
|
||||
"GetTimeMultiplier": () => 1
|
||||
});
|
||||
|
||||
AddMock(ent, IID_Sound, {
|
||||
|
|
@ -127,11 +127,11 @@ TS_ASSERT_EQUALS(cmpPack.GetElapsedTime(), 400);
|
|||
TS_ASSERT_EQUALS(cmpPack.timer, 7);
|
||||
TS_ASSERT(timerActivated);
|
||||
|
||||
// Cancel
|
||||
// Cancel
|
||||
cmpPack.CancelPack();
|
||||
|
||||
TS_ASSERT(!cmpPack.IsPacking());
|
||||
TS_ASSERT_EQUALS(cmpPack.GetElapsedTime(), 0)
|
||||
TS_ASSERT_EQUALS(cmpPack.GetElapsedTime(), 0);
|
||||
TS_ASSERT_EQUALS(cmpPack.GetProgress(), 0);
|
||||
TS_ASSERT_EQUALS(cmpPack.timer, undefined);
|
||||
TS_ASSERT(!timerActivated);
|
||||
|
|
|
|||
|
|
@ -63,14 +63,14 @@ let templateTechModifications = {
|
|||
};
|
||||
let entityTechModifications = {
|
||||
"without": {
|
||||
'Upgrade/Cost/stone': { 20: { "origValue": 100, "newValue": 100 } },
|
||||
'Upgrade/Cost/wood': { 20: { "origValue": 50, "newValue": 50 } },
|
||||
'Upgrade/Time': { 20: { "origValue": 100, "newValue": 100 } }
|
||||
'Upgrade/Cost/stone': { "20": { "origValue": 100, "newValue": 100 } },
|
||||
'Upgrade/Cost/wood': { "20": { "origValue": 50, "newValue": 50 } },
|
||||
'Upgrade/Time': { "20": { "origValue": 100, "newValue": 100 } }
|
||||
},
|
||||
"with": {
|
||||
'Upgrade/Cost/stone': { 20: { "origValue": 100, "newValue": 160 } },
|
||||
'Upgrade/Cost/wood': { 20: { "origValue": 50, "newValue": 25 } },
|
||||
'Upgrade/Time': { 20: { "origValue": 100, "newValue": 90 } }
|
||||
'Upgrade/Cost/stone': { "20": { "origValue": 100, "newValue": 160 } },
|
||||
'Upgrade/Cost/wood': { "20": { "origValue": 50, "newValue": 25 } },
|
||||
'Upgrade/Time': { "20": { "origValue": 100, "newValue": 90 } }
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ AddMock(SYSTEM_ENTITY, IID_Timer, {
|
|||
AddMock(10, IID_Player, {
|
||||
"AddResources": () => {}, // Called in components/Upgrade.js::CancelUpgrade().
|
||||
"GetPlayerID": () => playerID, // Called in helpers/Player.js::QueryOwnerInterface() (and several times below).
|
||||
"GetCheatTimeMultiplier": () => 1.0, // Called in components/Upgrade.js::GetUpgradeTime().
|
||||
"GetTimeMultiplier": () => 1.0, // Called in components/Upgrade.js::GetUpgradeTime().
|
||||
"TrySubtractResources": () => true // Called in components/Upgrade.js::Upgrade().
|
||||
});
|
||||
AddMock(10, IID_TechnologyManager, {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,10 @@ function InitGame(settings)
|
|||
}
|
||||
|
||||
// Sandbox, Very Easy, Easy, Medium, Hard, Very Hard
|
||||
// rate apply on resource stockpiling as gathering and trading
|
||||
// time apply on building, upgrading, packing, training and technologies
|
||||
let rate = [ 0.42, 0.56, 0.75, 1.00, 1.25, 1.56 ];
|
||||
let time = [ 1.30, 1.15, 1.00, 1.00, 1.00, 1.00 ];
|
||||
let cmpAIManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_AIManager);
|
||||
for (let i = 0; i < settings.PlayerData.length; ++i)
|
||||
{
|
||||
|
|
@ -56,6 +59,7 @@ function InitGame(settings)
|
|||
AIDiff = Math.min(AIDiff, rate.length - 1);
|
||||
cmpPlayer.SetGatherRateMultiplier(rate[AIDiff]);
|
||||
cmpPlayer.SetTradeRateMultiplier(rate[AIDiff]);
|
||||
cmpPlayer.SetTimeMultiplier(time[AIDiff]);
|
||||
}
|
||||
if (settings.PopulationCap)
|
||||
cmpPlayer.SetMaxPopulation(settings.PopulationCap);
|
||||
|
|
|
|||
Loading…
Reference in a new issue