forked from 0ad/0ad
Reduce drastically the number of mirages by making fogging conditional: entities will be miraged only if their health/resource amount is modified, or if they have a non-gaia owner.
Fixes the animals hidden in the FoW, and adds the missing status bars for mirages. Also small cleanup of the code. Refs #2913 This was SVN commit r16281.
This commit is contained in:
parent
b66465de73
commit
da0f33f137
@ -164,7 +164,7 @@ function displaySingle(entState, template)
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = sprintf(translate("Gain: %(amount)s"), { amount: getTradingTooltip(entState.trader.goods.amount) });
|
||||
}
|
||||
// And for number of workers
|
||||
else if (entState.foundation && !entState.mirage)
|
||||
else if (entState.foundation && entState.visibility == "visible")
|
||||
{
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
|
||||
@ -172,7 +172,7 @@ function displaySingle(entState, template)
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").caption = entState.foundation.numBuilders + " ";
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").tooltip = sprintf(translate("Number of builders.\nTasking another to this foundation would speed construction up by %(numb)s%%"), { numb : Math.round((Math.pow((entState.foundation.numBuilders+1)/entState.foundation.numBuilders, 0.7) - 1.0)*100) });
|
||||
}
|
||||
else if (entState.resourceSupply && (!entState.resourceSupply.killBeforeGather || !entState.hitpoints) && !entState.mirage)
|
||||
else if (entState.resourceSupply && (!entState.resourceSupply.killBeforeGather || !entState.hitpoints) && entState.visibility == "visible")
|
||||
{
|
||||
Engine.GetGUIObjectByName("resourceCarryingIcon").hidden = false;
|
||||
Engine.GetGUIObjectByName("resourceCarryingText").hidden = false;
|
||||
|
@ -5,17 +5,18 @@ const VIS_VISIBLE = 2;
|
||||
function Fogging() {}
|
||||
|
||||
Fogging.prototype.Schema =
|
||||
"<a:help>Allows this entity to be replaced by mirages entities in the fog-of-war.</a:help>" +
|
||||
"<a:help>Allows this entity to be replaced by mirage entities in the fog-of-war.</a:help>" +
|
||||
"<empty/>";
|
||||
|
||||
Fogging.prototype.Init = function()
|
||||
{
|
||||
this.activated = false;
|
||||
this.mirages = [];
|
||||
this.miraged = [];
|
||||
this.seen = [];
|
||||
|
||||
var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
||||
for (var player = 0; player < cmpPlayerManager.GetNumPlayers(); ++player)
|
||||
let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
||||
for (let player = 0; player < cmpPlayerManager.GetNumPlayers(); ++player)
|
||||
{
|
||||
this.mirages.push(INVALID_ENTITY);
|
||||
this.miraged.push(false);
|
||||
@ -23,8 +24,36 @@ Fogging.prototype.Init = function()
|
||||
}
|
||||
};
|
||||
|
||||
Fogging.prototype.Activate = function()
|
||||
{
|
||||
let mustUpdate = !this.activated;
|
||||
this.activated = true;
|
||||
|
||||
if (mustUpdate)
|
||||
{
|
||||
// Load a mirage for each player who has already seen the entity
|
||||
let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager);
|
||||
for (let player = 0; player < cmpPlayerManager.GetNumPlayers(); ++player)
|
||||
{
|
||||
if (this.seen[player])
|
||||
this.LoadMirage(player);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Fogging.prototype.IsActivated = function()
|
||||
{
|
||||
return this.activated;
|
||||
}
|
||||
|
||||
Fogging.prototype.LoadMirage = function(player)
|
||||
{
|
||||
if (!this.activated)
|
||||
{
|
||||
error("LoadMirage called for an entity with fogging deactivated");
|
||||
return;
|
||||
}
|
||||
|
||||
this.miraged[player] = true;
|
||||
|
||||
if (this.mirages[player] == INVALID_ENTITY)
|
||||
@ -108,10 +137,17 @@ Fogging.prototype.LoadMirage = function(player)
|
||||
// Notify the GUI the entity has been replaced by a mirage, in case it is selected at this moment
|
||||
var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
cmpGuiInterface.AddMiragedEntity(player, this.entity, this.mirages[player]);
|
||||
|
||||
// Notify the range manager the visibility of this entity must be updated
|
||||
let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);
|
||||
cmpRangeManager.RequestVisibilityUpdate(this.entity);
|
||||
};
|
||||
|
||||
Fogging.prototype.ForceMiraging = function(player)
|
||||
{
|
||||
if (!this.activated)
|
||||
return;
|
||||
|
||||
this.seen[player] = true;
|
||||
this.LoadMirage(player);
|
||||
};
|
||||
@ -140,21 +176,6 @@ Fogging.prototype.WasSeen = function(player)
|
||||
return this.seen[player];
|
||||
};
|
||||
|
||||
Fogging.prototype.OnVisibilityChanged = function(msg)
|
||||
{
|
||||
if (msg.player >= this.mirages.length)
|
||||
return;
|
||||
|
||||
if (msg.newVisibility == VIS_VISIBLE)
|
||||
{
|
||||
this.miraged[msg.player] = false;
|
||||
this.seen[msg.player] = true;
|
||||
}
|
||||
|
||||
if (msg.newVisibility == VIS_FOGGED)
|
||||
this.LoadMirage(msg.player);
|
||||
};
|
||||
|
||||
Fogging.prototype.OnDestroy = function(msg)
|
||||
{
|
||||
for (var player = 0; player < this.mirages.length; ++player)
|
||||
@ -172,4 +193,26 @@ Fogging.prototype.OnDestroy = function(msg)
|
||||
}
|
||||
};
|
||||
|
||||
Fogging.prototype.OnOwnershipChanged = function(msg)
|
||||
{
|
||||
// Always activate fogging for non-Gaia entities
|
||||
if (msg.to > 0)
|
||||
this.Activate();
|
||||
};
|
||||
|
||||
Fogging.prototype.OnVisibilityChanged = function(msg)
|
||||
{
|
||||
if (msg.player >= this.mirages.length)
|
||||
return;
|
||||
|
||||
if (msg.newVisibility == VIS_VISIBLE)
|
||||
{
|
||||
this.miraged[msg.player] = false;
|
||||
this.seen[msg.player] = true;
|
||||
}
|
||||
|
||||
if (msg.newVisibility == VIS_FOGGED && this.activated)
|
||||
this.LoadMirage(msg.player);
|
||||
};
|
||||
|
||||
Engine.RegisterComponentType(IID_Fogging, "Fogging", Fogging);
|
||||
|
@ -70,6 +70,11 @@ Health.prototype.SetHitpoints = function(value)
|
||||
if (this.hitpoints == 0)
|
||||
return;
|
||||
|
||||
// Before changing the value, activate Fogging if necessary to hide changes
|
||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
|
||||
if (cmpFogging)
|
||||
cmpFogging.Activate();
|
||||
|
||||
var old = this.hitpoints;
|
||||
this.hitpoints = Math.max(1, Math.min(this.GetMaxHitpoints(), value));
|
||||
|
||||
@ -150,6 +155,11 @@ Health.prototype.Kill = function()
|
||||
*/
|
||||
Health.prototype.Reduce = function(amount)
|
||||
{
|
||||
// Before changing the value, activate Fogging if necessary to hide changes
|
||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
|
||||
if (cmpFogging)
|
||||
cmpFogging.Activate();
|
||||
|
||||
var state = { "killed": false };
|
||||
if (amount >= 0 && this.hitpoints == this.GetMaxHitpoints())
|
||||
{
|
||||
@ -208,6 +218,11 @@ Health.prototype.Reduce = function(amount)
|
||||
|
||||
Health.prototype.Increase = function(amount)
|
||||
{
|
||||
// Before changing the value, activate Fogging if necessary to hide changes
|
||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
|
||||
if (cmpFogging)
|
||||
cmpFogging.Activate();
|
||||
|
||||
if (this.hitpoints == this.GetMaxHitpoints())
|
||||
return {"old": this.hitpoints, "new":this.hitpoints};
|
||||
|
||||
|
@ -97,6 +97,11 @@ ResourceSupply.prototype.GetDiminishingReturns = function()
|
||||
|
||||
ResourceSupply.prototype.TakeResources = function(rate)
|
||||
{
|
||||
// Before changing the amount, activate Fogging if necessary to hide changes
|
||||
let cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
|
||||
if (cmpFogging)
|
||||
cmpFogging.Activate();
|
||||
|
||||
if (this.infinite)
|
||||
return { "amount": rate, "exhausted": false };
|
||||
|
||||
|
@ -101,23 +101,23 @@ StatusBars.prototype.RegenerateSprites = function()
|
||||
yoffset -= height * 1.2;
|
||||
};
|
||||
|
||||
var cmpMirage = Engine.QueryInterface(this.entity, IID_Mirage);
|
||||
|
||||
var cmpPack = Engine.QueryInterface(this.entity, IID_Pack);
|
||||
if (cmpPack && cmpPack.IsPacking())
|
||||
{
|
||||
AddBar("pack", cmpPack.GetProgress());
|
||||
}
|
||||
|
||||
var cmpHealth = Engine.QueryInterface(this.entity, IID_Health);
|
||||
if (cmpHealth && cmpHealth.GetHitpoints() > 0)
|
||||
{
|
||||
AddBar("health", cmpHealth.GetHitpoints() / cmpHealth.GetMaxHitpoints());
|
||||
}
|
||||
else if (cmpMirage && cmpMirage.Health())
|
||||
AddBar("health", cmpMirage.GetHitpoints() / cmpMirage.GetMaxHitpoints());
|
||||
|
||||
var cmpResourceSupply = Engine.QueryInterface(this.entity, IID_ResourceSupply);
|
||||
if (cmpResourceSupply)
|
||||
{
|
||||
AddBar("supply", cmpResourceSupply.IsInfinite() ? 1 : cmpResourceSupply.GetCurrentAmount() / cmpResourceSupply.GetMaxAmount());
|
||||
}
|
||||
else if (cmpMirage && cmpMirage.ResourceSupply())
|
||||
AddBar("supply", cmpMirage.IsInfinite() ? 1 : cmpMirage.GetAmount() / cmpMirage.GetMaxAmount());
|
||||
|
||||
/*
|
||||
// Rank icon disabled for now - see discussion around
|
||||
|
@ -433,8 +433,11 @@ void CTemplateLoader::CopyMirageSubset(CParamNode& out, const CParamNode& in)
|
||||
permittedComponentTypes.insert("Footprint");
|
||||
permittedComponentTypes.insert("Minimap");
|
||||
permittedComponentTypes.insert("Ownership");
|
||||
permittedComponentTypes.insert("OverlayRenderer");
|
||||
permittedComponentTypes.insert("Position");
|
||||
permittedComponentTypes.insert("Selectable");
|
||||
permittedComponentTypes.insert("StatusBars");
|
||||
permittedComponentTypes.insert("Visibility");
|
||||
permittedComponentTypes.insert("VisualActor");
|
||||
|
||||
CParamNode::LoadXMLString(out, "<Entity/>");
|
||||
@ -456,7 +459,6 @@ void CTemplateLoader::CopyMirageSubset(CParamNode& out, const CParamNode& in)
|
||||
|
||||
// Set the entity as mirage entity
|
||||
CParamNode::LoadXMLString(out, "<Entity><Mirage/></Entity>");
|
||||
CParamNode::LoadXMLString(out, "<Entity><Visibility><RetainInFog>true</RetainInFog><AlwaysVisible>false</AlwaysVisible><Preview>false</Preview></Visibility></Entity>");
|
||||
}
|
||||
|
||||
void CTemplateLoader::CopyFoundationSubset(CParamNode& out, const CParamNode& in)
|
||||
|
@ -1454,12 +1454,15 @@ public:
|
||||
return VIS_HIDDEN;
|
||||
}
|
||||
|
||||
// Fogged entities must not disappear while the mirage is not ready
|
||||
// Fogged entities are hidden in two cases:
|
||||
// - They were not scouted
|
||||
// - A mirage replaces them
|
||||
CmpPtr<ICmpFogging> cmpFogging(ent);
|
||||
if (cmpFogging && cmpFogging->WasSeen(player) && !cmpFogging->IsMiraged(player))
|
||||
return VIS_FOGGED;
|
||||
if (cmpFogging && cmpFogging->IsActivated() &&
|
||||
(!cmpFogging->WasSeen(player) || cmpFogging->IsMiraged(player)))
|
||||
return VIS_HIDDEN;
|
||||
|
||||
return VIS_HIDDEN;
|
||||
return VIS_FOGGED;
|
||||
}
|
||||
|
||||
ELosVisibility ComputeLosVisibility(entity_id_t ent, player_id_t player)
|
||||
@ -1557,13 +1560,21 @@ public:
|
||||
|
||||
for (std::vector<entity_id_t>::iterator it = m_ModifiedEntities.begin(); it != m_ModifiedEntities.end(); ++it)
|
||||
{
|
||||
UpdateVisibility(*it);
|
||||
// Don't bother updating if we already did it in a global update
|
||||
if (!m_GlobalVisibilityUpdate)
|
||||
UpdateVisibility(*it);
|
||||
}
|
||||
m_ModifiedEntities.clear();
|
||||
|
||||
m_GlobalVisibilityUpdate = false;
|
||||
}
|
||||
|
||||
virtual void RequestVisibilityUpdate(entity_id_t ent)
|
||||
{
|
||||
if (std::find(m_ModifiedEntities.begin(), m_ModifiedEntities.end(), ent) == m_ModifiedEntities.end())
|
||||
m_ModifiedEntities.push_back(ent);
|
||||
}
|
||||
|
||||
void UpdateVisibility(entity_id_t ent)
|
||||
{
|
||||
// Warning: Code related to fogging (like posting VisibilityChanged messages)
|
||||
@ -1594,10 +1605,6 @@ public:
|
||||
{
|
||||
if (oldVisibilities[player-1] == newVisibilities[player-1])
|
||||
continue;
|
||||
|
||||
// Another visibility update can be necessary to take in account new mirages
|
||||
if (std::find(m_ModifiedEntities.begin(), m_ModifiedEntities.end(), ent) == m_ModifiedEntities.end())
|
||||
m_ModifiedEntities.push_back(ent);
|
||||
|
||||
CMessageVisibilityChanged msg(player, ent, oldVisibilities[player-1], newVisibilities[player-1]);
|
||||
GetSimContext().GetComponentManager().PostMessage(ent, msg);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2014 Wildfire Games.
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -30,6 +30,11 @@ class CCmpFoggingScripted : public ICmpFogging
|
||||
public:
|
||||
DEFAULT_SCRIPT_WRAPPER(FoggingScripted)
|
||||
|
||||
virtual bool IsActivated()
|
||||
{
|
||||
return m_Script.Call<bool>("IsActivated");
|
||||
}
|
||||
|
||||
virtual bool WasSeen(player_id_t player)
|
||||
{
|
||||
return m_Script.Call<bool>("WasSeen", player);
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2014 Wildfire Games.
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -30,6 +30,7 @@
|
||||
class ICmpFogging : public IComponent
|
||||
{
|
||||
public:
|
||||
virtual bool IsActivated() = 0;
|
||||
virtual bool WasSeen(player_id_t player) = 0;
|
||||
virtual bool IsMiraged(player_id_t player) = 0;
|
||||
virtual void ForceMiraging(player_id_t player) = 0;
|
||||
|
@ -52,6 +52,7 @@ DEFINE_INTERFACE_METHOD_2("SetLosRevealAll", void, ICmpRangeManager, SetLosRevea
|
||||
DEFINE_INTERFACE_METHOD_1("GetLosRevealAll", bool, ICmpRangeManager, GetLosRevealAll, player_id_t)
|
||||
DEFINE_INTERFACE_METHOD_5("GetElevationAdaptedRange", entity_pos_t, ICmpRangeManager, GetElevationAdaptedRange, CFixedVector3D, CFixedVector3D, entity_pos_t, entity_pos_t, entity_pos_t)
|
||||
DEFINE_INTERFACE_METHOD_2("GetLosVisibility", std::string, ICmpRangeManager, GetLosVisibility_wrapper, entity_id_t, player_id_t)
|
||||
DEFINE_INTERFACE_METHOD_1("RequestVisibilityUpdate", void, ICmpRangeManager, RequestVisibilityUpdate, entity_id_t)
|
||||
DEFINE_INTERFACE_METHOD_1("SetLosCircular", void, ICmpRangeManager, SetLosCircular, bool)
|
||||
DEFINE_INTERFACE_METHOD_0("GetLosCircular", bool, ICmpRangeManager, GetLosCircular)
|
||||
DEFINE_INTERFACE_METHOD_2("SetSharedLos", void, ICmpRangeManager, SetSharedLos, player_id_t, std::vector<player_id_t>)
|
||||
|
@ -323,6 +323,12 @@ public:
|
||||
virtual ELosVisibility GetLosVisibility(CEntityHandle ent, player_id_t player) = 0;
|
||||
virtual ELosVisibility GetLosVisibility(entity_id_t ent, player_id_t player) = 0;
|
||||
|
||||
/**
|
||||
* Request the update of the visibility cache of ent at next turn.
|
||||
* Typically used for fogging.
|
||||
*/
|
||||
virtual void RequestVisibilityUpdate(entity_id_t ent) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* GetLosVisibility wrapped for script calls.
|
||||
|
Loading…
Reference in New Issue
Block a user