Add a new Visibility component that will eventually allow scripted components and mods to influence an entity's visibility.

This first commit only refactors code and does not add any new feature.

Refs #2913 (see this ticket for more information about the change)

This was SVN commit r15925.
This commit is contained in:
Nicolas Auvray 2014-11-04 20:53:25 +00:00
parent 0855c1169b
commit d07d1a17f3
9 changed files with 165 additions and 36 deletions

View File

@ -0,0 +1,59 @@
const VIS_HIDDEN = 0;
const VIS_FOGGED = 1;
const VIS_VISIBLE = 2;
function Visibility() {}
Visibility.prototype.Schema =
"<empty/>";
Visibility.prototype.Init = function()
{
};
/**
* This function is called for entities in explored territory.
* isOutsideFog: true if we're in the vision range of a unit, false otherwise
* forceRetainInFog: useful for previewed entities, see the RangeManager system component documentation
*/
Visibility.prototype.GetLosVisibility = function(player, isOutsideFog, forceRetainInFog)
{
if (isOutsideFog)
return VIS_VISIBLE;
// Fogged if the 'retain in fog' flag is set, and in a non-visible explored region
var cmpVision = Engine.QueryInterface(this.entity, IID_Vision);
if (!forceRetainInFog && !(cmpVision && cmpVision.GetRetainInFog()))
return VIS_HIDDEN;
var cmpMirage = Engine.QueryInterface(this.entity, IID_Mirage);
if (cmpMirage && cmpMirage.GetPlayer() == player)
return VIS_FOGGED;
var cmpOwnership = Engine.QueryInterface(this.entity, IID_Ownership);
if (!cmpOwnership)
return VIS_FOGGED;
if (cmpOwnership.GetOwner() == player)
{
var cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
if (!cmpFogging)
return VIS_FOGGED;
// Fogged entities must not disappear while the mirage is not ready
if (!cmpFogging.IsMiraged(player))
return VIS_FOGGED;
return VIS_HIDDEN;
}
// Fogged entities must not disappear while the mirage is not ready
var cmpFogging = Engine.QueryInterface(this.entity, IID_Fogging);
if (cmpFogging && cmpFogging.WasSeen(player) && !cmpFogging.IsMiraged(player))
return VIS_FOGGED;
return VIS_HIDDEN;
};
Engine.RegisterComponentType(IID_Visibility, "Visibility", Visibility);

View File

@ -20,6 +20,7 @@
<BarHeight>0.333</BarHeight>
<HeightOffset>5.0</HeightOffset>
</StatusBars>
<Visibility/>
<Vision>
<Range>0</Range>
<RetainInFog>true</RetainInFog>

View File

@ -101,6 +101,7 @@
<TerritoryDecay>
<HealthDecayRate>5</HealthDecayRate>
</TerritoryDecay>
<Visibility/>
<Vision>
<Range>40</Range>
<RetainInFog>true</RetainInFog>

View File

@ -104,6 +104,7 @@
<PassabilityClass>default</PassabilityClass>
<CostClass>default</CostClass>
</UnitMotion>
<Visibility/>
<Vision>
<Range>10</Range>
<RetainInFog>false</RetainInFog>

View File

@ -352,6 +352,7 @@ void CTemplateLoader::CopyPreviewSubset(CParamNode& out, const CParamNode& in, b
permittedComponentTypes.insert("Identity");
permittedComponentTypes.insert("Ownership");
permittedComponentTypes.insert("Position");
permittedComponentTypes.insert("Visibility");
permittedComponentTypes.insert("VisualActor");
permittedComponentTypes.insert("Footprint");
permittedComponentTypes.insert("Obstruction");
@ -408,6 +409,7 @@ void CTemplateLoader::CopyMirageSubset(CParamNode& out, const CParamNode& in)
permittedComponentTypes.insert("Ownership");
permittedComponentTypes.insert("Position");
permittedComponentTypes.insert("Selectable");
permittedComponentTypes.insert("Visibility");
permittedComponentTypes.insert("VisualActor");
CParamNode::LoadXMLString(out, "<Entity/>");
@ -454,6 +456,7 @@ void CTemplateLoader::CopyFoundationSubset(CParamNode& out, const CParamNode& in
permittedComponentTypes.insert("Decay");
permittedComponentTypes.insert("Cost");
permittedComponentTypes.insert("Sound");
permittedComponentTypes.insert("Visibility");
permittedComponentTypes.insert("Vision");
permittedComponentTypes.insert("AIProxy");
permittedComponentTypes.insert("RallyPoint");

View File

@ -174,6 +174,9 @@ COMPONENT(UnitMotionScripted)
INTERFACE(UnitRenderer)
COMPONENT(UnitRenderer)
INTERFACE(Visibility)
COMPONENT(VisibilityScripted)
INTERFACE(Vision)
COMPONENT(Vision)

View File

@ -28,6 +28,7 @@
#include "simulation2/components/ICmpOwnership.h"
#include "simulation2/components/ICmpPosition.h"
#include "simulation2/components/ICmpTerritoryManager.h"
#include "simulation2/components/ICmpVisibility.h"
#include "simulation2/components/ICmpVision.h"
#include "simulation2/components/ICmpWaterManager.h"
#include "simulation2/helpers/Render.h"
@ -1377,10 +1378,6 @@ public:
virtual ELosVisibility GetLosVisibility(CEntityHandle ent, player_id_t player, bool forceRetainInFog)
{
// This function provides the real visibility of any entity (even local ones) at any time.
// The m_EntityData visibility is updated at most once per turn with this function's return value
// and must not be used for rendering
// Entities not with positions in the world are never visible
if (ent.GetId() == INVALID_ENTITY)
return VIS_HIDDEN;
@ -1409,42 +1406,21 @@ public:
// Visible if within a visible region
CLosQuerier los(GetSharedLosMask(player), m_LosState, m_TerrainVerticesPerSide);
if (!los.IsExplored(i, j))
return VIS_HIDDEN;
// Try to ask the Visibility component of the entity, if any
CmpPtr<ICmpVisibility> cmpVisibility(ent);
if (cmpVisibility)
return cmpVisibility->GetLosVisibility(player, los.IsVisible(i, j), forceRetainInFog);
// Default behaviour
if (los.IsVisible(i, j))
return VIS_VISIBLE;
if (!los.IsExplored(i, j))
return VIS_HIDDEN;
// Fogged if the 'retain in fog' flag is set, and in a non-visible explored region
CmpPtr<ICmpVision> cmpVision(ent);
if (!forceRetainInFog && !(cmpVision && cmpVision->GetRetainInFog()))
return VIS_HIDDEN;
if (cmpMirage && cmpMirage->GetPlayer() == player)
return VIS_FOGGED;
CmpPtr<ICmpOwnership> cmpOwnership(ent);
if (!cmpOwnership)
return VIS_VISIBLE;
if (cmpOwnership->GetOwner() == player)
{
CmpPtr<ICmpFogging> cmpFogging(ent);
if (!cmpFogging)
return VIS_VISIBLE;
// Fogged entities must not disappear while the mirage is not ready
if (!cmpFogging->IsMiraged(player))
return VIS_FOGGED;
return VIS_HIDDEN;
}
// Fogged entities must not disappear while the mirage is not ready
CmpPtr<ICmpFogging> cmpFogging(ent);
if (cmpFogging && cmpFogging->WasSeen(player) && !cmpFogging->IsMiraged(player))
if (forceRetainInFog)
return VIS_FOGGED;
return VIS_HIDDEN;
}

View File

@ -0,0 +1,52 @@
/* Copyright (C) 2014 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#include "precompiled.h"
#include "ICmpVisibility.h"
#include "simulation2/scripting/ScriptComponent.h"
#include "simulation2/system/InterfaceScripted.h"
BEGIN_INTERFACE_WRAPPER(Visibility)
END_INTERFACE_WRAPPER(Visibility)
class CCmpVisibilityScripted : public ICmpVisibility
{
public:
DEFAULT_SCRIPT_WRAPPER(VisibilityScripted)
virtual ICmpRangeManager::ELosVisibility GetLosVisibility(player_id_t player, bool isOutsideFog, bool forceRetainInFog)
{
int visibility = m_Script.Call<int, player_id_t, bool, bool>("GetLosVisibility", player, isOutsideFog, forceRetainInFog);
switch (visibility)
{
case ICmpRangeManager::VIS_HIDDEN:
return ICmpRangeManager::VIS_HIDDEN;
case ICmpRangeManager::VIS_FOGGED:
return ICmpRangeManager::VIS_FOGGED;
case ICmpRangeManager::VIS_VISIBLE:
return ICmpRangeManager::VIS_VISIBLE;
default:
LOGERROR(L"Received the invalid visibility value %d from the Visibility scripted component!", visibility);
return ICmpRangeManager::VIS_HIDDEN;
}
}
};
REGISTER_COMPONENT_SCRIPT_WRAPPER(VisibilityScripted)

View File

@ -0,0 +1,33 @@
/* Copyright (C) 2014 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef INCLUDED_ICMPVISIBILITY
#define INCLUDED_ICMPVISIBILITY
#include "simulation2/system/Interface.h"
#include "simulation2/components/ICmpRangeManager.h"
class ICmpVisibility : public IComponent
{
public:
virtual ICmpRangeManager::ELosVisibility GetLosVisibility(player_id_t player, bool isOutsideFog, bool forceRetainInFog) = 0;
DECLARE_INTERFACE_TYPE(Visibility)
};
#endif // INCLUDED_ICMPVISIBILITY