Resolve "Toggle Free Look with Hotkey"
[ryzomcore.git] / ryzom / client / src / client_sheets / race_stats_sheet.cpp
blobcad6a0c8d1529d886028d387c42c551d4d833714
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
20 /////////////
21 // INCLUDE //
22 /////////////
23 #include "stdpch.h" // First include for pre-compiled headers.
24 // Application
25 #include "race_stats_sheet.h"
26 // Game Share
27 #include "game_share/characs_build.h"
28 // Georges
29 #include "nel/georges/u_form_elm.h"
32 ///////////
33 // USING //
34 ///////////
35 using namespace std;
38 /////////////
39 // METHODS //
40 /////////////
41 const string CGenderInfo::UnknownItemName;
43 // description of a visual slot that must be read by CGenderInfo
44 struct CSlotInfo
46 SLOTTYPE::EVisualSlot Slot;
47 const char *Suffix; // suffix in the sheet
50 static const CSlotInfo UsedVisualSlots[] =
52 { SLOTTYPE::CHEST_SLOT, "DefaultChest" },
53 { SLOTTYPE::LEGS_SLOT, "DefaultLegs" },
54 { SLOTTYPE::HEAD_SLOT, "DefaultHair" },
55 { SLOTTYPE::ARMS_SLOT, "DefaultArms" },
56 { SLOTTYPE::FACE_SLOT, "DefaultFace" },
57 { SLOTTYPE::HANDS_SLOT, "DefaultHands" },
58 { SLOTTYPE::FEET_SLOT, "DefaultFeet" }
60 static const uint NumUsedVisualSlots = sizeof(UsedVisualSlots) / sizeof(UsedVisualSlots[0]);
63 /////////////////
64 // CGenderInfo //
65 /////////////////
66 //===============================================================
67 CGenderInfo::CGenderInfo()
69 CharacterScalePos = 1;
70 for (uint32 i = 0; i < 8; ++i)
72 BlendShapeMin[i] = 0.0f;
73 BlendShapeMax[i] = 100.0f;
75 NamePosZLow = 0.f;
76 NamePosZNormal = 0.f;
77 NamePosZHigh = 0.f;
80 //===============================================================
81 void CGenderInfo::build(const NLGEORGES::UFormElm &item, const std::string &prefix)
83 // Get equipment items
84 // get slots
85 for(uint k = 0; k < NumUsedVisualSlots; ++k)
87 if (!item.getValueByName(Items[UsedVisualSlots[k].Slot], (prefix + UsedVisualSlots[k].Suffix).c_str()))
89 nlwarning("Can't get %s from race_stats sheet", UsedVisualSlots[k].Suffix);
92 // Get skeleton
93 if (!item.getValueByName(Skelfilename, (prefix + "Skel").c_str()))
95 nlwarning("Can't get skeleton");
97 // get base animation name
98 if (!item.getValueByName(AnimSetBaseName, (prefix + "AnimSetBaseName").c_str()))
100 nlwarning("Can't get AnimSetBaseName");
104 // Load Lod character name
105 if(!item.getValueByName(LodCharacterName, (prefix + "LodCharacterName").c_str()))
106 nlwarning("CGenderInfo::build: Key 'LodCharacterName' not found.");
108 // Load Lod character apparition distance
109 if(!item.getValueByName(LodCharacterDistance, (prefix + "LodCharacterDistance").c_str()))
110 nlwarning("CGenderInfo::build: Key 'LodCharacterDistance' not found.");
113 // value to scale the "pos" channel of the animation of the player.
114 if(!item.getValueByName(CharacterScalePos, (prefix + "CharacterScalePos").c_str()))
115 nlwarning("CGenderInfo::build: Key 'CharacterScalePos' not found.");
116 for (uint32 i = 0; i < 8; ++i)
118 if(!item.getValueByName(BlendShapeMin[i], (prefix+"MorphTargetMin"+NLMISC::toString(i)).c_str()))
119 nlwarning("CGenderInfo::build: Key 'MorphTargetMin%d' not found.",i);
120 if(!item.getValueByName(BlendShapeMax[i], (prefix+"MorphTargetMax"+NLMISC::toString(i)).c_str()))
121 nlwarning("CGenderInfo::build: Key 'MorphTargetMax%d' not found.",i);
124 if(!item.getValueByName(NamePosZLow, (prefix + "NamePosZLow").c_str()))
125 nlwarning("CGenderInfo::build: Key 'NamePosZLow' not found.");
126 if(!item.getValueByName(NamePosZNormal, (prefix + "NamePosZNormal").c_str()))
127 nlwarning("CGenderInfo::build: Key 'NamePosZNormal' not found.");
128 if(!item.getValueByName(NamePosZHigh, (prefix + "NamePosZHigh").c_str()))
129 nlwarning("CGenderInfo::build: Key 'NamePosZHigh' not found.");
132 //===============================================================
133 void CGenderInfo::serial(NLMISC::IStream &f)
135 // serial used slots
136 for(uint k = 0; k < NumUsedVisualSlots; ++k)
138 f.serial(Items[UsedVisualSlots[k].Slot]);
140 f.serial(Skelfilename);
141 f.serial(AnimSetBaseName);
142 f.serial(LodCharacterName);
143 f.serial(LodCharacterDistance);
144 f.serial(CharacterScalePos);
145 f.serialCont(GroundFX);
146 for (uint32 i = 0; i < 8; ++i)
148 f.serial(BlendShapeMin[i]);
149 f.serial(BlendShapeMax[i]);
151 f.serial(NamePosZLow);
152 f.serial(NamePosZNormal);
153 f.serial(NamePosZHigh);
157 //-----------------------------------------------
158 // getItemName :
159 // Get the item name for a given slot.
160 //-----------------------------------------------
161 const string &CGenderInfo::getItemName(SLOTTYPE::EVisualSlot slot) const
163 // Check the slot.
164 if(slot >= SLOTTYPE::NB_SLOT)
166 // Bad Slot.
167 nlwarning("CGenderInfo::getItemName: slot '%d' invalid.", slot);
168 return UnknownItemName;
171 // Return the name of the default item for this slot.
172 return Items[slot];
173 }// getItemName //
179 /////////////////////
180 // CRaceStatsSheet //
181 /////////////////////
182 //===============================================================
183 CRaceStatsSheet::CRaceStatsSheet()
185 std::fill(CharacStartValue, CharacStartValue + CHARACTERISTICS::NUM_CHARACTERISTICS, 0);
186 // Initialize the type.
187 Type = CEntitySheet::RACE_STATS;
190 //===============================================================
191 void CRaceStatsSheet::build(const NLGEORGES::UFormElm &item)
193 GenderInfos[0].build(item, "DefaultEquipment.Male equipment.");
194 GenderInfos[1].build(item, "DefaultEquipment.Female equipment.");
195 // build base characs
196 loadCharacteristicsFromSheet(item, "Characteristics.", CharacStartValue);
197 // Get race
198 std::string race;
199 item.getValueByName(race, "Race");
200 People = EGSPD::CPeople::fromString(race);
202 // Get the skin to use.
203 if(!item.getValueByName(Skin, "Skin"))
204 nlwarning("CRaceStatsSheet::build: Cannot find the key 'Skin'.");
206 buildGroundFXs(item, "GroundFXMale", GenderInfos[0].GroundFX);
207 buildGroundFXs(item, "GroundFXFemale", GenderInfos[1].GroundFX);
208 // get Automaton Type
209 if(!item.getValueByName(Automaton, "Automaton"))
210 nlwarning("CRaceStatsSheet::build: Can't get 'Automaton'.");
211 BodyToBone.build(item, "Localisation.");
212 // Attack lists
213 for(uint k = 0; k < NumAttackLists; ++k)
215 std::string attackListName;
216 if(item.getValueByName(attackListName, NLMISC::toString("attack_list%d", (int) k).c_str()) && !attackListName.empty())
218 AttackLists.push_back(ClientSheetsStrings.add(attackListName));
224 //===============================================================
225 void CRaceStatsSheet::buildGroundFXs(const NLGEORGES::UFormElm &item, const std::string &name, std::vector<CGroundFXSheet> &dest)
227 // ground fxs
228 const NLGEORGES::UFormElm *elm;
229 if(item.getNodeByName(&elm, name) && elm)
231 // Check array.
232 if(elm->isArray())
234 // Get Array Size
235 uint groundFXArraySize;
236 if(elm->getArraySize(groundFXArraySize))
238 if(groundFXArraySize > 0)
240 // Adjust the array size.
241 dest.reserve(groundFXArraySize);
243 // Get values.
244 for(uint i=0; i< groundFXArraySize; ++i)
246 const NLGEORGES::UFormElm *node;
247 if (elm->getArrayNode(&node, i) && node != NULL)
249 CGroundFXSheet gfs;
250 if (!gfs.build(*node))
252 nlwarning("Error while building node %d", (int) i);
254 else
256 uint k;
257 for(k = 0; k < dest.size(); ++k)
259 if (dest[k].GroundID == gfs.GroundID)
261 debug("Duplicated material");
262 dest[k] = gfs;
263 break;
266 if (k == dest.size())
268 dest.push_back(gfs);
275 else
276 debug(NLMISC::toString("'%s' cannot get the array size.", name.c_str()));
278 else
279 debug(NLMISC::toString("'%s' is not an array.", name.c_str()));
281 else
282 debug(NLMISC::toString("'%s' key not found.", name.c_str()));
283 // sort fxs by ground type
284 std::sort(dest.begin(), dest.end());
287 //===============================================================
288 void CRaceStatsSheet::serial(NLMISC::IStream &f)
290 for(uint k = 0; k < CHARACTERISTICS::NUM_CHARACTERISTICS; ++k)
292 f.serial(CharacStartValue[k]);
294 f.serial(GenderInfos[0], GenderInfos[1]);
296 if(f.isReading())
298 uint8 people;
299 f.serial(people);
300 People = (EGSPD::CPeople::TPeople)people;
302 else
304 uint8 people = (uint8)People;
305 f.serial(people);
308 f.serial(Skin); // The skin
309 f.serial(Automaton);
310 f.serial(BodyToBone);
311 // attack list
312 uint32 size = (uint32)AttackLists.size();
313 f.serial(size);
314 AttackLists.resize(size);
316 for(uint k = 0; k < size; ++k)
318 ClientSheetsStrings.serial(f, AttackLists[k]);