khanat-opennel-code/code/ryzom/client/src/client_sheets/plant_sheet.cpp

278 lines
8 KiB
C++

// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//////////////
// INCLUDES //
//////////////
#include "stdpch.h" // First include for pre-compiled headers.
// Application
#include "plant_sheet.h"
// Nel
#include "nel/georges/u_form_elm.h"
#include "nel/misc/common.h"
using namespace NLMISC;
//=======================================================
void CSeasonFXSheet::build(const NLGEORGES::UFormElm &item, NLMISC::CSheetId parentId, const std::string &prefix)
{
bool ok = true;
ok &= item.getValueByName(FXName, (prefix + "FXName").c_str());
if (FXName.empty()) return;
uint32 fxMode = 0;
ok &= item.getValueByName(fxMode, (prefix + "Mode").c_str());
Mode = (TMode) fxMode;
ok &= item.getValueByName(CycleDuration, (prefix + "CycleDuration").c_str());
ok &= item.getValueByName(StartHourMin, (prefix + "StartHourMin").c_str());
ok &= item.getValueByName(StartHourMax, (prefix + "StartHourMax").c_str());
ok &= item.getValueByName(EndHourMin, (prefix + "EndHourMin").c_str());
ok &= item.getValueByName(EndHourMax, (prefix + "EndHourMax").c_str());
ok &= item.getValueByName(InheritScale, (prefix + "InheritScale").c_str());
ok &= item.getValueByName(InheritRot, (prefix + "InheritRot").c_str());
ok &= item.getValueByName(AngleMin, (prefix + "AngleMin").c_str());
ok &= item.getValueByName(AngleMax, (prefix + "AngleMax").c_str());
ok &= item.getValueByName(DontRotate, (prefix + "DontRotate").c_str());
ok &= item.getValueByName(DontRotateAroundLocalZ, (prefix + "DontRotateAroundLocalZ").c_str());
ok &= item.getValueByName(ScaleMin.x, (prefix + "ScaleMinX").c_str());
ok &= item.getValueByName(ScaleMin.y, (prefix + "ScaleMinY").c_str());
ok &= item.getValueByName(ScaleMin.z, (prefix + "ScaleMinZ").c_str());
ok &= item.getValueByName(ScaleMax.x, (prefix + "ScaleMaxX").c_str());
ok &= item.getValueByName(ScaleMax.y, (prefix + "ScaleMaxY").c_str());
ok &= item.getValueByName(ScaleMax.z, (prefix + "ScaleMaxZ").c_str());
ok &= item.getValueByName(UniformScale, (prefix + "UniformScale").c_str());
ok &= item.getValueByName(WantScaling, (prefix + "WantScaling").c_str());
ok &= item.getValueByName(AlignOnWater, (prefix + "AlignOnWater").c_str());
ok &= item.getValueByName(ZOffset, (prefix + "ZOffset").c_str());
// Anti Crash
if(CycleDuration<=0)
{
nlwarning("FX: CPlantSheet '%s' has a season with a CycleDuration<=0: %f !!!!! setting it to 0.1.",
parentId.toString().c_str(), CycleDuration);
CycleDuration= 0.1f;
}
StartHourMin = fmodf(StartHourMin, CycleDuration);
StartHourMax = fmodf(StartHourMax, CycleDuration);
EndHourMin = fmodf(EndHourMin, CycleDuration);
EndHourMax = fmodf(EndHourMax, CycleDuration);
nlassert(isValidDouble(StartHourMin));
nlassert(isValidDouble(StartHourMax));
nlassert(isValidDouble(EndHourMin));
nlassert(isValidDouble(EndHourMax));
nlassert(isValidDouble(CycleDuration));
for(uint k = 0; k < 4; ++k)
{
ok &= item.getValueByName(UserParamsMin[k], (prefix + NLMISC::toString("UserParam%dMin", (int) k)).c_str());
ok &= item.getValueByName(UserParamsMax[k], (prefix + NLMISC::toString("UserParam%dMax", (int) k)).c_str());
}
ok &= item.getValueByName(MinDuration, (prefix + "MinDuration").c_str());
ok &= item.getValueByName(MaxDuration, (prefix + "MaxDuration").c_str());
// prevent from overlapping interval
if (Mode != AlwaysStarted && Mode != UseDuration && Mode != Spawn)
{
float startHourMin = StartHourMin;
float startHourMax = StartHourMax;
if (startHourMax < startHourMin)
{
startHourMax += CycleDuration;
}
float endHourMin = EndHourMin;
float endHourMax = EndHourMax;
if (endHourMax < endHourMin)
{
endHourMax += CycleDuration;
}
if (!(startHourMax <= endHourMin || startHourMin >= endHourMax))
{
// intervals overlap -> bad
nlwarning("Overlapping time intervals for fx spawn.");
if (startHourMin <= endHourMin)
{
float inter = endHourMin;
if (inter >= CycleDuration)
{
inter -= CycleDuration;
}
StartHourMax = inter;
}
else
{
float inter = startHourMin;
if (inter >= CycleDuration)
{
inter -= CycleDuration;
}
EndHourMax = inter;
}
}
}
// compute duration of start interval
float startHourMaxInterval;
if (StartHourMin <= StartHourMax)
{
startHourMaxInterval = StartHourMax - StartHourMin;
}
else
{
startHourMaxInterval = CycleDuration - StartHourMin + StartHourMax;
}
NLMISC::clamp(MinDuration, 0.f, CycleDuration /*- startHourMaxInterval*/);
NLMISC::clamp(MaxDuration, 0.f, CycleDuration /*- startHourMaxInterval*/);
if (!ok)
{
nldebug("Key not found.");
}
}
//=======================================================
void CSeasonFXSheet::serial(class NLMISC::IStream &f) throw(NLMISC::EStream)
{
f.serial(FXName);
f.serialEnum(Mode);
f.serial(CycleDuration);
f.serial(StartHourMin);
f.serial(StartHourMax);
f.serial(EndHourMin);
f.serial(EndHourMax);
f.serial(MinDuration);
f.serial(MaxDuration);
for(uint k = 0; k < 4; ++k)
{
f.serial(UserParamsMin[k]);
f.serial(UserParamsMax[k]);
}
f.serial(InheritScale);
f.serial(InheritRot);
f.serial(AngleMin);
f.serial(AngleMax);
f.serial(DontRotate);
f.serial(DontRotateAroundLocalZ);
f.serial(ScaleMin);
f.serial(ScaleMax);
f.serial(UniformScale);
f.serial(WantScaling);
f.serial(AlignOnWater);
f.serial(ZOffset);
// Anti Crash. you may recompute the plant.packed_sheets if those assert trigger.
nlassert(isValidDouble(CycleDuration));
nlassert(isValidDouble(StartHourMin));
nlassert(isValidDouble(StartHourMax));
nlassert(isValidDouble(EndHourMin));
nlassert(isValidDouble(EndHourMax));
nlassert(isValidDouble(MinDuration));
nlassert(isValidDouble(MaxDuration));
nlassert(isValidDouble(UserParamsMin[0]));
nlassert(isValidDouble(UserParamsMax[0]));
nlassert(isValidDouble(UserParamsMin[1]));
nlassert(isValidDouble(UserParamsMax[1]));
nlassert(isValidDouble(UserParamsMin[2]));
nlassert(isValidDouble(UserParamsMax[2]));
nlassert(isValidDouble(UserParamsMin[3]));
nlassert(isValidDouble(UserParamsMax[3]));
nlassert(isValidDouble(AngleMin));
nlassert(isValidDouble(AngleMax));
nlassert(isValidDouble(ScaleMin.x) && isValidDouble(ScaleMin.y) && isValidDouble(ScaleMin.z));
nlassert(isValidDouble(ScaleMax.x) && isValidDouble(ScaleMax.y) && isValidDouble(ScaleMax.z));
nlassert(isValidDouble(ZOffset));
}
//=======================================================
CPlantSheet::CPlantSheet() : _MaxDist(-1), _CoarseMeshDist(-1)
{
Type = PLANT;
_MaxDist = 0.0f;
_CoarseMeshDist = 0.0f;
}
//=======================================================
void CPlantSheet::build(const NLGEORGES::UFormElm &item)
{
if(!(item.getValueByName(_ShapeName, "3D.Shape") &&
item.getValueByName(_MaxDist, "3D.MaxDist") &&
item.getValueByName(_CoarseMeshDist, "3D.CoarseMeshDist")))
{
nldebug("Key not found.");
}
// serial fxs by season
SeasonFX[EGSPD::CSeason::Spring].build(item, Id, "3D.SpringFX.");
SeasonFX[EGSPD::CSeason::Summer].build(item, Id, "3D.SummerFX.");
SeasonFX[EGSPD::CSeason::Autumn].build(item, Id, "3D.AutomnFX.");
SeasonFX[EGSPD::CSeason::Winter].build(item, Id, "3D.WinterFX.");
}
//=======================================================
void CPlantSheet::serial(class NLMISC::IStream &f) throw(NLMISC::EStream)
{
f.serial(_ShapeName, _MaxDist, _CoarseMeshDist);
for(uint k = 0; k < EGSPD::CSeason::Invalid; ++k)
{
f.serial(SeasonFX[k]);
}
}