forked from 0ad/0ad
Fix an OOS on rejoin when a ptolemian lighthouse revealing the shoreline was built prior. Patch by Itms and wraitii, fixes #4277.
Serialize the mapsize in the pathfinder and the reveal shoreline flag in
the range manager.
Reload the rangemanager data after other components have been
deserialized.
Use the SerializeCommon pattern in the pathfinder to avoid code
duplication.
Move the shoreline logic from the Vision component to the range manager.
Remove unused interface mocks from the rangemanager test following
b05879e151
.
This was SVN commit r18879.
This commit is contained in:
parent
b70af394df
commit
5a384f4eaf
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -135,22 +135,26 @@ struct SerializeShortRequest
|
||||
}
|
||||
};
|
||||
|
||||
void CCmpPathfinder::Serialize(ISerializer& serialize)
|
||||
template<typename S>
|
||||
void CCmpPathfinder::SerializeCommon(S& serialize)
|
||||
{
|
||||
SerializeVector<SerializeLongRequest>()(serialize, "long requests", m_AsyncLongPathRequests);
|
||||
SerializeVector<SerializeShortRequest>()(serialize, "short requests", m_AsyncShortPathRequests);
|
||||
serialize.NumberU32_Unbounded("next ticket", m_NextAsyncTicket);
|
||||
serialize.NumberU16_Unbounded("same turn moves count", m_SameTurnMovesCount);
|
||||
serialize.NumberU16_Unbounded("map size", m_MapSize);
|
||||
}
|
||||
|
||||
void CCmpPathfinder::Serialize(ISerializer& serialize)
|
||||
{
|
||||
SerializeCommon(serialize);
|
||||
}
|
||||
|
||||
void CCmpPathfinder::Deserialize(const CParamNode& paramNode, IDeserializer& deserialize)
|
||||
{
|
||||
Init(paramNode);
|
||||
|
||||
SerializeVector<SerializeLongRequest>()(deserialize, "long requests", m_AsyncLongPathRequests);
|
||||
SerializeVector<SerializeShortRequest>()(deserialize, "short requests", m_AsyncShortPathRequests);
|
||||
deserialize.NumberU32_Unbounded("next ticket", m_NextAsyncTicket);
|
||||
deserialize.NumberU16_Unbounded("same turn moves count", m_SameTurnMovesCount);
|
||||
SerializeCommon(deserialize);
|
||||
}
|
||||
|
||||
void CCmpPathfinder::HandleMessage(const CMessage& msg, bool UNUSED(global))
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -193,6 +193,9 @@ public:
|
||||
|
||||
virtual void Deinit();
|
||||
|
||||
template<typename S>
|
||||
void SerializeCommon(S& serialize);
|
||||
|
||||
virtual void Serialize(ISerializer& serialize);
|
||||
|
||||
virtual void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize);
|
||||
|
@ -170,14 +170,19 @@ static std::map<entity_id_t, EntityParabolicRangeOutline> ParabolicRangesOutline
|
||||
*/
|
||||
struct EntityData
|
||||
{
|
||||
EntityData() : visibilities(0), size(0), retainInFog(0), owner(-1), inWorld(0), flags(1), scriptedVisibility(0) { }
|
||||
EntityData() :
|
||||
visibilities(0), size(0),
|
||||
owner(-1), retainInFog(0), inWorld(0), revealShore(0),
|
||||
flags(1), scriptedVisibility(0)
|
||||
{ }
|
||||
entity_pos_t x, z;
|
||||
entity_pos_t visionRange;
|
||||
u32 visibilities; // 2-bit visibility, per player
|
||||
u32 size;
|
||||
u8 retainInFog; // boolean
|
||||
i8 owner;
|
||||
u8 retainInFog; // boolean
|
||||
u8 inWorld; // boolean
|
||||
u8 revealShore; // boolean
|
||||
u8 flags; // See GetEntityFlagMask
|
||||
u8 scriptedVisibility; // boolean, see ComputeLosVisibility
|
||||
};
|
||||
@ -236,11 +241,12 @@ struct SerializeEntityData
|
||||
serialize.NumberFixed_Unbounded("vision", value.visionRange);
|
||||
serialize.NumberU32_Unbounded("visibilities", value.visibilities);
|
||||
serialize.NumberU32_Unbounded("size", value.size);
|
||||
serialize.NumberU8("retain in fog", value.retainInFog, 0, 1);
|
||||
serialize.NumberI8_Unbounded("owner", value.owner);
|
||||
serialize.NumberU8("retain in fog", value.retainInFog, 0, 1);
|
||||
serialize.NumberU8("in world", value.inWorld, 0, 1);
|
||||
serialize.NumberU8("reveal shore", value.revealShore, 0, 1);
|
||||
serialize.NumberU8_Unbounded("flags", value.flags);
|
||||
serialize.NumberU8_Unbounded("scripted visibility", value.scriptedVisibility);
|
||||
serialize.NumberU8("scripted visibility", value.scriptedVisibility, 0, 1);
|
||||
}
|
||||
};
|
||||
|
||||
@ -293,6 +299,8 @@ public:
|
||||
componentManager.SubscribeGloballyToMessageType(MT_Destroy);
|
||||
componentManager.SubscribeGloballyToMessageType(MT_VisionRangeChanged);
|
||||
|
||||
componentManager.SubscribeToMessageType(MT_Deserialized);
|
||||
|
||||
componentManager.SubscribeToMessageType(MT_Update);
|
||||
|
||||
componentManager.SubscribeToMessageType(MT_RenderSubmit); // for debug overlays
|
||||
@ -440,17 +448,21 @@ public:
|
||||
Init(paramNode);
|
||||
|
||||
SerializeCommon(deserialize);
|
||||
|
||||
// Reinitialise subdivisions and LOS data
|
||||
m_Deserializing = true;
|
||||
ResetDerivedData();
|
||||
m_Deserializing = false;
|
||||
}
|
||||
|
||||
virtual void HandleMessage(const CMessage& msg, bool UNUSED(global))
|
||||
{
|
||||
switch (msg.GetType())
|
||||
{
|
||||
case MT_Deserialized:
|
||||
{
|
||||
// Reinitialize subdivisions and LOS data after all
|
||||
// other components have been deserialized.
|
||||
m_Deserializing = true;
|
||||
ResetDerivedData();
|
||||
m_Deserializing = false;
|
||||
break;
|
||||
}
|
||||
case MT_Create:
|
||||
{
|
||||
const CMessageCreate& msgData = static_cast<const CMessageCreate&> (msg);
|
||||
@ -473,7 +485,10 @@ public:
|
||||
// Store the LOS data, if any
|
||||
CmpPtr<ICmpVision> cmpVision(GetSimContext(), ent);
|
||||
if (cmpVision)
|
||||
{
|
||||
entdata.visionRange = cmpVision->GetRange();
|
||||
entdata.revealShore = cmpVision->GetRevealShore() ? 1 : 0;
|
||||
}
|
||||
CmpPtr<ICmpVisibility> cmpVisibility(GetSimContext(), ent);
|
||||
if (cmpVisibility)
|
||||
entdata.retainInFog = (cmpVisibility->GetRetainInFog() ? 1 : 0);
|
||||
@ -561,6 +576,12 @@ public:
|
||||
CFixedVector2D pos(it->second.x, it->second.z);
|
||||
LosRemove(it->second.owner, it->second.visionRange, pos);
|
||||
LosAdd(msgData.to, it->second.visionRange, pos);
|
||||
|
||||
if (it->second.revealShore)
|
||||
{
|
||||
RevealShore(it->second.owner, false);
|
||||
RevealShore(msgData.to, true);
|
||||
}
|
||||
}
|
||||
|
||||
ENSURE(-128 <= msgData.to && msgData.to <= 127);
|
||||
@ -751,6 +772,9 @@ public:
|
||||
{
|
||||
LosAdd(it->second.owner, it->second.visionRange, CFixedVector2D(it->second.x, it->second.z));
|
||||
AddToTile(PosToLosTilesHelper(it->second.x, it->second.z), it->first);
|
||||
|
||||
if (it->second.revealShore)
|
||||
RevealShore(it->second.owner, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,9 @@ public:
|
||||
// Template state:
|
||||
|
||||
entity_pos_t m_Range, m_BaseRange;
|
||||
|
||||
// TODO: The reveal shore system should be replaced by a general
|
||||
// system of "special" vision methods that are not ranges.
|
||||
bool m_RevealShore;
|
||||
|
||||
static std::string GetSchema()
|
||||
@ -90,12 +93,6 @@ public:
|
||||
break;
|
||||
|
||||
ReloadRange();
|
||||
|
||||
if (!m_RevealShore)
|
||||
break;
|
||||
CmpPtr<ICmpRangeManager> cmpRangeManager(GetSystemEntity());
|
||||
cmpRangeManager->RevealShore(msgData.from, false);
|
||||
cmpRangeManager->RevealShore(msgData.to, true);
|
||||
break;
|
||||
}
|
||||
case MT_ValueModification:
|
||||
@ -137,6 +134,11 @@ public:
|
||||
{
|
||||
return m_Range;
|
||||
}
|
||||
|
||||
virtual bool GetRevealShore()
|
||||
{
|
||||
return m_RevealShore;
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_COMPONENT_TYPE(Vision)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2014 Wildfire Games.
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -29,6 +29,7 @@ class ICmpVision : public IComponent
|
||||
{
|
||||
public:
|
||||
virtual entity_pos_t GetRange() = 0;
|
||||
virtual bool GetRevealShore() = 0;
|
||||
|
||||
DECLARE_INTERFACE_TYPE(Vision)
|
||||
};
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2015 Wildfire Games.
|
||||
/* Copyright (C) 2016 Wildfire Games.
|
||||
* This file is part of 0 A.D.
|
||||
*
|
||||
* 0 A.D. is free software: you can redistribute it and/or modify
|
||||
@ -31,8 +31,7 @@ public:
|
||||
DEFAULT_MOCK_COMPONENT()
|
||||
|
||||
virtual entity_pos_t GetRange() { return entity_pos_t::FromInt(66); }
|
||||
virtual bool GetRetainInFog() { return false; }
|
||||
virtual bool GetAlwaysVisible() { return false; }
|
||||
virtual bool GetRevealShore() { return false; }
|
||||
};
|
||||
|
||||
class MockPosition : public ICmpPosition
|
||||
@ -85,6 +84,9 @@ public:
|
||||
CXeromyces::Terminate();
|
||||
}
|
||||
|
||||
// TODO It would be nice to call Verify() with the shore revealing system
|
||||
// but that means testing on an actual map, with water and land.
|
||||
|
||||
void test_basic()
|
||||
{
|
||||
ComponentTestHelper test(g_ScriptRuntime);
|
||||
|
Loading…
Reference in New Issue
Block a user