1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2020 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "nel/misc/path.h"
22 #include "nel/misc/file.h"
23 #include "nel/misc/common.h"
24 #include "nel/misc/algo.h"
28 using namespace NLMISC
;
31 // ***************************************************************************
32 void buildRaceAnimNames(std::vector
<string
> &raceAnimNames
, const std::string
&animName
)
34 if(animName
.compare(0, 3, "fy_")!=0)
36 nlwarning("ERROR: all .anim must begin with fy_");
40 raceAnimNames
.resize(4);
41 raceAnimNames
[0]= animName
;
42 raceAnimNames
[1]= animName
;
43 raceAnimNames
[2]= animName
;
44 raceAnimNames
[3]= animName
;
45 raceAnimNames
[0].replace(0, 3, "fy_");
46 raceAnimNames
[1].replace(0, 3, "ma_");
47 raceAnimNames
[2].replace(0, 3, "tr_");
48 raceAnimNames
[3].replace(0, 3, "zo_");
51 for(uint i
=0;i
<raceAnimNames
.size();i
++)
53 raceAnimNames
[i
]= string("\"") + raceAnimNames
[i
] + string("\"");
57 // ***************************************************************************
58 string::size_type
findAnimName(const string
&lineLwr
, const std::vector
<string
> &raceAnimNames
)
60 // line Must contains Name="filename", else CAN BE A LOAD CHAR ANIMATION!!!!
61 if(lineLwr
.find("name=\"filename\"")==string::npos
)
64 // in the animset, the original file can be a "tr_" ... Not necessarily a "fy_"
65 for(uint i
=0;i
<raceAnimNames
.size();i
++)
67 string::size_type pos
= lineLwr
.find(raceAnimNames
[i
]);
74 // ***************************************************************************
75 void appendRaceAnim(vector
<string
> &animSetText
, uint startBlock
, const vector
<string
> ©Text
, uint nameLineInBlock
, uint nameIndexInLine
, const string
&raceAnimName
)
78 animSetText
.insert(animSetText
.begin()+startBlock
, copyText
.size(), string());
81 for(uint i
=0;i
<copyText
.size();i
++)
83 string line
= copyText
[i
];
85 // If this is the line we have to change the anim name
86 if(i
==nameLineInBlock
)
87 line
.replace(nameIndexInLine
, raceAnimName
.size(), raceAnimName
);
89 // If this is the line we have to specify the race node
90 if(i
==copyText
.size()-2)
93 if(raceAnimName
.compare(1,3,"fy_")==0)
95 else if(raceAnimName
.compare(1,3,"ma_")==0)
97 else if(raceAnimName
.compare(1,3,"tr_")==0)
99 else if(raceAnimName
.compare(1,3,"zo_")==0)
103 nlwarning("ERROR: generated anim can be only fy_, ma_, zo_, tr_. Ask a coder");
106 line
=toString(" <ATOM Name=\"Race Restriction\" Value=\"%s\"/>", peopleEnum
.c_str());
110 animSetText
[startBlock
+i
]= line
;
114 // ***************************************************************************
115 void makeAnimByRace(const std::string
&animSetFile
, const std::vector
<string
> &animList
)
117 // *** Read the animset file.
119 iFile
.open(animSetFile
, true);
121 static vector
<string
> animSetText
;
126 iFile
.getline(tmp
, 50000);
127 animSetText
.push_back(tmp
);
132 bool someChangeDone
= false;
134 // *** For each possible anim
135 for(uint i
=0;i
<animList
.size();i
++)
137 // get the possible anim file name (lowered)
138 static vector
<string
> raceAnimNames
;
139 raceAnimNames
.clear();
140 buildRaceAnimNames(raceAnimNames
, toLowerAscii(CFile::getFilename(animList
[i
])));
142 // For each line of the animSet
143 uint lastStructLine
= 0;
144 bool raceRestrictionFound
= false;
145 for(uint j
=0;j
<animSetText
.size();)
147 string line
= animSetText
[j
];
148 string lineLwr
= toLowerAscii(line
);
150 // Find <LOG> TAg? => stop
151 if(line
.find("<LOG>")!=string::npos
)
154 // Find a STRUCT start?
155 if(line
.find("<STRUCT>")!=string::npos
)
158 raceRestrictionFound
= false;
161 // Find a RaceRestriction?
162 if( line
.find("Name=\"Race Restriction\"")!=string::npos
)
163 raceRestrictionFound
= true;
165 // Find the anim name?
166 string::size_type nameIndexInLine
= findAnimName(lineLwr
, raceAnimNames
);
167 if(nameIndexInLine
!=string::npos
)
169 // Find the enclosing struct
170 nlassert(lastStructLine
!=0);
171 uint startBlock
= lastStructLine
;
172 uint nameLineInBlock
= j
-startBlock
;
174 for(uint k
=j
+1;k
<animSetText
.size();k
++)
176 string line
= animSetText
[k
];
178 // Find a RaceRestriction?
179 if( line
.find("Name=\"Race Restriction\"")!=string::npos
)
180 raceRestrictionFound
= true;
183 if(line
.find("</STRUCT>")!=string::npos
)
185 // endBlock is exclusive
191 // if not found, abort
195 // if a raceRestriction has been found, no op (already done)
196 if(raceRestrictionFound
)
203 InfoLog
->displayRawNL("%s: Specifying %s by race",
204 CFile::getFilename(animSetFile
).c_str(),
205 CFile::getFilename(animList
[i
]).c_str());
207 // *** Start a copy paste ^^
209 static vector
<string
> copyText
;
211 for(uint k
=startBlock
;k
<endBlock
;k
++)
213 // add an empty line before </STRUCT>, for race selection node (filled later)
215 copyText
.push_back(string());
216 copyText
.push_back(animSetText
[k
]);
220 animSetText
.erase(animSetText
.begin()+startBlock
, animSetText
.begin()+endBlock
);
221 uint nextBlock
= startBlock
;
223 // Append for each race
224 for(uint k
=0;k
<raceAnimNames
.size();k
++)
226 appendRaceAnim(animSetText
, nextBlock
, copyText
, nameLineInBlock
, (uint
)nameIndexInLine
, raceAnimNames
[k
]);
227 // nextBlock is then shifted
228 nextBlock
+= (uint
)copyText
.size();
231 someChangeDone
= true;
233 // *** then let j point to next block
244 // *** Write the animset file.
248 oFile
.open(animSetFile
, false, true);
250 for(uint i
=0;i
<animSetText
.size();i
++)
252 string str
= animSetText
[i
];
254 oFile
.serialBuffer((uint8
*)str
.c_str(), (uint
)str
.size());
261 // ***************************************************************************
264 printf("Usage: make_anim_by_race new_anim_dir animset_dir");
269 // ***************************************************************************
270 int main(int argc
, char *argv
[])
272 NLMISC::createDebug();
274 // make_anim_by_race new_anim_dir animset_dir
277 string animDir
= argv
[1];
278 string animSetDir
= argv
[2];
280 // Get the list of .anim to make by race
281 vector
<string
> files
;
282 CPath::getPathContent(animDir
, false, false, true, files
);
284 vector
<string
> animList
;
285 InfoLog
->displayRawNL("");
286 InfoLog
->displayRawNL("********************");
287 InfoLog
->displayRawNL("**** .anim list ****");
288 InfoLog
->displayRawNL("********************");
289 for(uint i
=0;i
<files
.size();i
++)
291 if(testWildCard(files
[i
], "*.anim"))
293 animList
.push_back(files
[i
]);
294 InfoLog
->displayRawNL(animList
.back().c_str());
299 // Get the list of .animset to make by race
301 CPath::getPathContent(animSetDir
, true, false, true, files
);
302 vector
<string
> animSetList
;
303 InfoLog
->displayRawNL("");
304 InfoLog
->displayRawNL("*****************************");
305 InfoLog
->displayRawNL("**** .animation_set list ****");
306 InfoLog
->displayRawNL("*****************************");
307 for(uint i
=0;i
<files
.size();i
++)
309 if(testWildCard(files
[i
], "*.animation_set"))
311 animSetList
.push_back(files
[i
]);
312 InfoLog
->displayRawNL(animSetList
.back().c_str());
316 InfoLog
->displayRawNL("");
317 InfoLog
->displayRawNL("**************************");
318 InfoLog
->displayRawNL("**** Starting Process ****");
319 InfoLog
->displayRawNL("**************************");
320 // For each animset, test if can replace some anim
321 for(uint i
=0;i
<animSetList
.size();i
++)
323 makeAnimByRace(animSetList
[i
], animList
);