Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "simulation2/system/Component.h"
21 : #include "ICmpWaterManager.h"
22 :
23 : #include "graphics/RenderableObject.h"
24 : #include "graphics/Terrain.h"
25 : #include "renderer/Renderer.h"
26 : #include "renderer/SceneRenderer.h"
27 : #include "renderer/WaterManager.h"
28 : #include "simulation2/MessageTypes.h"
29 : #include "tools/atlas/GameInterface/GameLoop.h"
30 :
31 9 : class CCmpWaterManager final : public ICmpWaterManager
32 : {
33 : public:
34 116 : static void ClassInit(CComponentManager& componentManager)
35 : {
36 : // No need to subscribe to WaterChanged since we're actually the one sending those.
37 116 : componentManager.SubscribeToMessageType(MT_Interpolate);
38 116 : componentManager.SubscribeToMessageType(MT_TerrainChanged);
39 116 : }
40 :
41 6 : DEFAULT_COMPONENT_ALLOCATOR(WaterManager)
42 :
43 : // Dynamic state:
44 :
45 : entity_pos_t m_WaterHeight;
46 :
47 116 : static std::string GetSchema()
48 : {
49 116 : return "<a:component type='system'/><empty/>";
50 : }
51 :
52 3 : void Init(const CParamNode& UNUSED(paramNode)) override
53 : {
54 3 : }
55 :
56 3 : void Deinit() override
57 : {
58 : // Clear the map size & data.
59 3 : if (CRenderer::IsInitialised())
60 0 : g_Renderer.GetSceneRenderer().GetWaterManager().SetMapSize(0);
61 3 : }
62 :
63 0 : void Serialize(ISerializer& serialize) override
64 : {
65 0 : serialize.NumberFixed_Unbounded("height", m_WaterHeight);
66 0 : }
67 :
68 0 : void Deserialize(const CParamNode& paramNode, IDeserializer& deserialize) override
69 : {
70 0 : Init(paramNode);
71 :
72 0 : deserialize.NumberFixed_Unbounded("height", m_WaterHeight);
73 :
74 0 : if (CRenderer::IsInitialised())
75 0 : g_Renderer.GetSceneRenderer().GetWaterManager().SetMapSize(GetSimContext().GetTerrain().GetVerticesPerSide());
76 :
77 0 : RecomputeWaterData();
78 0 : }
79 :
80 0 : void HandleMessage(const CMessage& msg, bool UNUSED(global)) override
81 : {
82 0 : switch (msg.GetType())
83 : {
84 0 : case MT_Interpolate:
85 : {
86 0 : const CMessageInterpolate& msgData = static_cast<const CMessageInterpolate&> (msg);
87 0 : if (CRenderer::IsInitialised())
88 0 : g_Renderer.GetSceneRenderer().GetWaterManager().m_WaterTexTimer += msgData.deltaSimTime;
89 0 : break;
90 : }
91 0 : case MT_TerrainChanged:
92 : {
93 : // Tell the renderer to redraw part of the map.
94 0 : if (CRenderer::IsInitialised())
95 : {
96 0 : const CMessageTerrainChanged& msgData = static_cast<const CMessageTerrainChanged&> (msg);
97 0 : GetSimContext().GetTerrain().MakeDirty(msgData.i0,msgData.j0,msgData.i1,msgData.j1,RENDERDATA_UPDATE_VERTICES);
98 : }
99 0 : break;
100 : }
101 : }
102 0 : }
103 :
104 0 : void RecomputeWaterData() override
105 : {
106 0 : if (CRenderer::IsInitialised())
107 : {
108 0 : g_Renderer.GetSceneRenderer().GetWaterManager().RecomputeWaterData();
109 0 : g_Renderer.GetSceneRenderer().GetWaterManager().m_WaterHeight = m_WaterHeight.ToFloat();
110 : }
111 :
112 : // Tell the terrain it'll need to recompute its cached render data
113 0 : GetSimContext().GetTerrain().MakeDirty(RENDERDATA_UPDATE_VERTICES);
114 0 : }
115 :
116 0 : void SetWaterLevel(entity_pos_t h) override
117 : {
118 0 : if (m_WaterHeight == h)
119 0 : return;
120 :
121 0 : m_WaterHeight = h;
122 :
123 0 : RecomputeWaterData();
124 :
125 0 : CMessageWaterChanged msg;
126 0 : GetSimContext().GetComponentManager().BroadcastMessage(msg);
127 : }
128 :
129 0 : entity_pos_t GetWaterLevel(entity_pos_t UNUSED(x), entity_pos_t UNUSED(z)) const override
130 : {
131 0 : return m_WaterHeight;
132 : }
133 :
134 0 : float GetExactWaterLevel(float UNUSED(x), float UNUSED(z)) const override
135 : {
136 0 : return m_WaterHeight.ToFloat();
137 : }
138 : };
139 :
140 119 : REGISTER_COMPONENT_TYPE(WaterManager)
|