1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program 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 Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "stdpch.h" // First include for pre-compiled headers.
25 #include "plant_sheet.h"
27 #include "nel/georges/u_form_elm.h"
28 #include "nel/misc/common.h"
31 using namespace NLMISC
;
33 //=======================================================
34 void CSeasonFXSheet::build(const NLGEORGES::UFormElm
&item
, NLMISC::CSheetId parentId
, const std::string
&prefix
)
37 ok
&= item
.getValueByName(FXName
, (prefix
+ "FXName").c_str());
38 if (FXName
.empty()) return;
40 ok
&= item
.getValueByName(fxMode
, (prefix
+ "Mode").c_str());
41 Mode
= (TMode
) fxMode
;
42 ok
&= item
.getValueByName(CycleDuration
, (prefix
+ "CycleDuration").c_str());
43 ok
&= item
.getValueByName(StartHourMin
, (prefix
+ "StartHourMin").c_str());
44 ok
&= item
.getValueByName(StartHourMax
, (prefix
+ "StartHourMax").c_str());
45 ok
&= item
.getValueByName(EndHourMin
, (prefix
+ "EndHourMin").c_str());
46 ok
&= item
.getValueByName(EndHourMax
, (prefix
+ "EndHourMax").c_str());
47 ok
&= item
.getValueByName(InheritScale
, (prefix
+ "InheritScale").c_str());
48 ok
&= item
.getValueByName(InheritRot
, (prefix
+ "InheritRot").c_str());
49 ok
&= item
.getValueByName(AngleMin
, (prefix
+ "AngleMin").c_str());
50 ok
&= item
.getValueByName(AngleMax
, (prefix
+ "AngleMax").c_str());
51 ok
&= item
.getValueByName(DontRotate
, (prefix
+ "DontRotate").c_str());
52 ok
&= item
.getValueByName(DontRotateAroundLocalZ
, (prefix
+ "DontRotateAroundLocalZ").c_str());
53 ok
&= item
.getValueByName(ScaleMin
.x
, (prefix
+ "ScaleMinX").c_str());
54 ok
&= item
.getValueByName(ScaleMin
.y
, (prefix
+ "ScaleMinY").c_str());
55 ok
&= item
.getValueByName(ScaleMin
.z
, (prefix
+ "ScaleMinZ").c_str());
56 ok
&= item
.getValueByName(ScaleMax
.x
, (prefix
+ "ScaleMaxX").c_str());
57 ok
&= item
.getValueByName(ScaleMax
.y
, (prefix
+ "ScaleMaxY").c_str());
58 ok
&= item
.getValueByName(ScaleMax
.z
, (prefix
+ "ScaleMaxZ").c_str());
59 ok
&= item
.getValueByName(UniformScale
, (prefix
+ "UniformScale").c_str());
60 ok
&= item
.getValueByName(WantScaling
, (prefix
+ "WantScaling").c_str());
61 ok
&= item
.getValueByName(AlignOnWater
, (prefix
+ "AlignOnWater").c_str());
62 ok
&= item
.getValueByName(ZOffset
, (prefix
+ "ZOffset").c_str());
67 nlwarning("FX: CPlantSheet '%s' has a season with a CycleDuration<=0: %f !!!!! setting it to 0.1.",
68 parentId
.toString().c_str(), CycleDuration
);
72 StartHourMin
= fmodf(StartHourMin
, CycleDuration
);
73 StartHourMax
= fmodf(StartHourMax
, CycleDuration
);
74 EndHourMin
= fmodf(EndHourMin
, CycleDuration
);
75 EndHourMax
= fmodf(EndHourMax
, CycleDuration
);
77 nlassert(isValidDouble(StartHourMin
));
78 nlassert(isValidDouble(StartHourMax
));
79 nlassert(isValidDouble(EndHourMin
));
80 nlassert(isValidDouble(EndHourMax
));
81 nlassert(isValidDouble(CycleDuration
));
83 for(uint k
= 0; k
< 4; ++k
)
85 ok
&= item
.getValueByName(UserParamsMin
[k
], (prefix
+ NLMISC::toString("UserParam%dMin", (int) k
)).c_str());
86 ok
&= item
.getValueByName(UserParamsMax
[k
], (prefix
+ NLMISC::toString("UserParam%dMax", (int) k
)).c_str());
88 ok
&= item
.getValueByName(MinDuration
, (prefix
+ "MinDuration").c_str());
89 ok
&= item
.getValueByName(MaxDuration
, (prefix
+ "MaxDuration").c_str());
90 // prevent from overlapping interval
91 if (Mode
!= AlwaysStarted
&& Mode
!= UseDuration
&& Mode
!= Spawn
)
93 float startHourMin
= StartHourMin
;
94 float startHourMax
= StartHourMax
;
95 if (startHourMax
< startHourMin
)
97 startHourMax
+= CycleDuration
;
99 float endHourMin
= EndHourMin
;
100 float endHourMax
= EndHourMax
;
101 if (endHourMax
< endHourMin
)
103 endHourMax
+= CycleDuration
;
105 if (!(startHourMax
<= endHourMin
|| startHourMin
>= endHourMax
))
107 // intervals overlap -> bad
108 nlwarning("Overlapping time intervals for fx spawn.");
109 if (startHourMin
<= endHourMin
)
111 float inter
= endHourMin
;
112 if (inter
>= CycleDuration
)
114 inter
-= CycleDuration
;
116 StartHourMax
= inter
;
120 float inter
= startHourMin
;
121 if (inter
>= CycleDuration
)
123 inter
-= CycleDuration
;
129 // compute duration of start interval
130 float startHourMaxInterval
;
131 if (StartHourMin
<= StartHourMax
)
133 startHourMaxInterval
= StartHourMax
- StartHourMin
;
137 startHourMaxInterval
= CycleDuration
- StartHourMin
+ StartHourMax
;
139 NLMISC::clamp(MinDuration
, 0.f
, CycleDuration
/*- startHourMaxInterval*/);
140 NLMISC::clamp(MaxDuration
, 0.f
, CycleDuration
/*- startHourMaxInterval*/);
144 nldebug("Key not found.");
148 //=======================================================
149 void CSeasonFXSheet::serial(NLMISC::IStream
&f
)
153 f
.serial(CycleDuration
);
154 f
.serial(StartHourMin
);
155 f
.serial(StartHourMax
);
156 f
.serial(EndHourMin
);
157 f
.serial(EndHourMax
);
158 f
.serial(MinDuration
);
159 f
.serial(MaxDuration
);
160 for(uint k
= 0; k
< 4; ++k
)
162 f
.serial(UserParamsMin
[k
]);
163 f
.serial(UserParamsMax
[k
]);
165 f
.serial(InheritScale
);
166 f
.serial(InheritRot
);
169 f
.serial(DontRotate
);
170 f
.serial(DontRotateAroundLocalZ
);
173 f
.serial(UniformScale
);
174 f
.serial(WantScaling
);
175 f
.serial(AlignOnWater
);
179 // Anti Crash. you may recompute the plant.packed_sheets if those assert trigger.
180 nlassert(isValidDouble(CycleDuration
));
181 nlassert(isValidDouble(StartHourMin
));
182 nlassert(isValidDouble(StartHourMax
));
183 nlassert(isValidDouble(EndHourMin
));
184 nlassert(isValidDouble(EndHourMax
));
185 nlassert(isValidDouble(MinDuration
));
186 nlassert(isValidDouble(MaxDuration
));
187 nlassert(isValidDouble(UserParamsMin
[0]));
188 nlassert(isValidDouble(UserParamsMax
[0]));
189 nlassert(isValidDouble(UserParamsMin
[1]));
190 nlassert(isValidDouble(UserParamsMax
[1]));
191 nlassert(isValidDouble(UserParamsMin
[2]));
192 nlassert(isValidDouble(UserParamsMax
[2]));
193 nlassert(isValidDouble(UserParamsMin
[3]));
194 nlassert(isValidDouble(UserParamsMax
[3]));
195 nlassert(isValidDouble(AngleMin
));
196 nlassert(isValidDouble(AngleMax
));
197 nlassert(isValidDouble(ScaleMin
.x
) && isValidDouble(ScaleMin
.y
) && isValidDouble(ScaleMin
.z
));
198 nlassert(isValidDouble(ScaleMax
.x
) && isValidDouble(ScaleMax
.y
) && isValidDouble(ScaleMax
.z
));
199 nlassert(isValidDouble(ZOffset
));
202 //=======================================================
203 CPlantSheet::CPlantSheet() : _MaxDist(-1), _CoarseMeshDist(-1)
208 _CoarseMeshDist
= 0.0f
;
211 //=======================================================
212 void CPlantSheet::build(const NLGEORGES::UFormElm
&item
)
214 if(!(item
.getValueByName(_ShapeName
, "3D.Shape") &&
215 item
.getValueByName(_MaxDist
, "3D.MaxDist") &&
216 item
.getValueByName(_CoarseMeshDist
, "3D.CoarseMeshDist")))
218 nldebug("Key not found.");
221 // serial fxs by season
222 SeasonFX
[EGSPD::CSeason::Spring
].build(item
, Id
, "3D.SpringFX.");
223 SeasonFX
[EGSPD::CSeason::Summer
].build(item
, Id
, "3D.SummerFX.");
224 SeasonFX
[EGSPD::CSeason::Autumn
].build(item
, Id
, "3D.AutomnFX.");
225 SeasonFX
[EGSPD::CSeason::Winter
].build(item
, Id
, "3D.WinterFX.");
228 //=======================================================
229 void CPlantSheet::serial(NLMISC::IStream
&f
)
231 f
.serial(_ShapeName
, _MaxDist
, _CoarseMeshDist
);
232 for(uint k
= 0; k
< EGSPD::CSeason::Invalid
; ++k
)
234 f
.serial(SeasonFX
[k
]);