Added angle modification for static graphics in levels.
[potpourri.git] / src / core / Level.cpp
blobf161793b10541cb844b0b0c35a7f6915fbc1390b
1 // Copyright 2008 Brian Caine
3 // This file is part of Potpourri.
5 // Potpourri is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // Potpourri is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTIBILITY of FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with Potpourri. If not, see <http://www.gnu.org/licenses/>.
19 // NOTES:
21 // The source for the level class.
23 #include <iostream>
24 #include <string>
25 #include <stdexcept>
26 #include <algorithm>
28 #include "../../include/core/Level.h"
29 #include "../../include/core/parselevel.h"
30 #include "../../include/core/common.h"
32 using namespace fragrant;
34 LevelSlice LevelData::getSlice(std::string presentation)
36 LevelSlice results;
38 if (!presentation.size() ||
39 (presentations.size() == 1 && !presentations.at(0).size()))
40 results = slices[presentations.at(0)];
42 else
44 if (slices.find(presentation) == slices.end())
45 throw std::runtime_error(
46 ("LevelData::getSlice(): Level does not support "
47 "presentation, \"" + presentation + "\"").c_str());
48 results = slices[presentation];
51 results.presentation = presentation;
52 return results;
55 std::string LevelData::toString()
57 std::string results;
59 results += "\tName: " + name + "\n";
60 results += "\tPresentations: ";
62 int cur;
63 for (cur = 0; cur < presentations.size(); cur++)
64 if (presentations.at(cur).size())
65 results += "\"" + presentations.at(cur) +
66 std::string((cur < presentations.size() - 1) ? ("\", ") : ("\""));
68 if (presentations.size() == 1)
69 results += "All";
71 results += "\n";
73 std::map<std::string, LevelSlice>::iterator iter;
74 for (iter = slices.begin(); iter != slices.end(); iter++)
76 results += std::string("\tLevelSlice for \"") + iter->first +
77 std::string("\"\n");
78 results += std::string("\t* Startup: ") +
79 std::string(iter->second.startup ? "True" : "False") +
80 "\n";
81 results += "\t* Rest of data truncated...\n";
84 return results;
87 Level::Level(LevelSlice data, Game& dgame)
88 : level_data(data), presentation(data.presentation), game(dgame)
90 simulation = new PhysicsSimulation;
93 Level::Level(LevelSlice data, Level& old_level, Game& dgame) : game(dgame)
95 throw std::runtime_error(std::string("Level::Level(LevelData, Level&): ")
96 + std::string("Not implemented yet"));
99 Level::~Level()
101 int cur;
102 for (cur = 0; cur < actors.size(); cur++)
104 delete actors.at(cur).actor;
106 std::vector<EventReceiver*>& target_vector =
107 pipeline->getTargetVector();
108 target_vector.erase(find(target_vector.begin(),
109 target_vector.end(), actors.at(cur).actor));
112 delete simulation;
114 actors.clear();
115 static_graphics.clear();
118 void Level::init(std::vector<ActorData> nactor_defs,
119 EventPipeline* npipeline, Audio& naudio, ScriptVM* nscript_vm)
121 this->actor_defs = nactor_defs;
122 this->pipeline = npipeline;
123 this->audio = naudio;
124 this->script_vm = nscript_vm;
126 viewport = level_data.viewport;
128 int cur;
129 std::vector<LevelActor> actor_pos = level_data.actors;
130 for (cur = 0; cur < actor_pos.size(); cur++)
132 int ncur;
133 LevelActor temp_level_actor = actor_pos.at(cur);
134 for (ncur = 0; ncur < actor_defs.size(); ncur++)
135 if (actor_defs.at(ncur).name == temp_level_actor.source)
137 ActorData cur_data = actor_defs.at(ncur);
138 cur_data.position = temp_level_actor.position;
139 cur_data.simulation = simulation;
141 LActor ngraphic;
142 ngraphic.zindex = temp_level_actor.zindex;
143 ngraphic.actor = new Actor(cur_data);
144 ngraphic.actor->setAngle(temp_level_actor.angle);
145 npipeline->getTargetVector().push_back(
146 dynamic_cast<EventReceiver*>(ngraphic.actor));
148 actors.push_back(ngraphic);
152 std::vector<LevelGraphic> level_graphics =
153 level_data.static_graphics;
155 for (cur = 0; cur < level_graphics.size(); cur++)
157 std::map<std::string, Variant*> params;
158 Drawable* drawable = game.getGraphics(
159 level_graphics.at(cur).source, params);
161 StaticGraphic graphic;
162 graphic.position = level_graphics.at(cur).position;
163 graphic.drawable = drawable;
164 graphic.zindex = level_graphics.at(cur).zindex;
165 graphic.angle = level_graphics.at(cur).angle;
167 static_graphics.push_back(graphic);
170 return;
173 struct drawable_item // throwaway struct for drawing
175 LActor actor;
176 StaticGraphic graphic;
177 float depth;
179 bool is_actor;
182 void Level::cycle(Display* dest)
184 // do physics stuff
186 int cur = getticks();
187 simulation->process(PROCESS_TIME, PROCESS_PIECE);
188 int tickcount = PROCESS_TIME - (getticks() - cur);
189 dosleep(tickcount > 0 ? tickcount : 0);
191 // do drawing stuff
193 std::multimap<float, drawable_item> drawable_items;
195 for (cur = 0; cur < static_graphics.size(); cur++)
197 drawable_item item;
198 item.graphic = static_graphics.at(cur);
199 item.is_actor = false;
200 item.depth = item.graphic.zindex;
202 drawable_items.insert(
203 std::pair<float, drawable_item>(item.depth, item));
206 for (cur = 0; cur < actors.size(); cur++)
208 drawable_item item;
209 item.actor = actors.at(cur);
210 item.is_actor = true;
211 item.depth = actors.at(cur).zindex;
213 drawable_items.insert(
214 std::pair<float, drawable_item>(item.depth, item));
217 std::multimap<float, drawable_item>::iterator iter;
218 for (iter = drawable_items.begin(); iter != drawable_items.end(); iter++)
220 if (iter->second.is_actor)
221 iter->second.actor.actor->draw(dest, viewport);
223 else
225 GraphicsRect src;
226 src.xy.x = iter->second.graphic.position.x - viewport.x;
227 src.xy.y = iter->second.graphic.position.y - viewport.y;
229 iter->second.graphic.drawable->draw(dest, &src,
230 static_cast<GraphicsPair*>(0), iter->second.graphic.angle);
234 return;
237 func Level::getConstructor() { return 0; }
238 void Level::destroy() { return; }
240 std::string Level::getClassName() { return "Level"; }
242 std::vector<std::string> Level::getClassFunctions()
244 std::vector<std::string> results;
246 results.push_back("getViewport");
247 results.push_back("setViewport");
249 results.push_back("getActorIndicesByName");
250 results.push_back("getActor");
252 results.push_back("getActorZIndex");
253 results.push_back("setActorZIndex");
255 results.push_back("deleteActor");
256 results.push_back("makeActor");
258 // results.push_back("");
260 return results;
263 template<class TYPE>
264 struct find_actordata : public std::unary_function<TYPE, void>
266 void operator() (TYPE& x)
268 if (x.name == to_find)
269 *data = x;
272 std::string to_find;
273 ActorData* data;
274 bool found;
277 Variant* Level::callFunction(std::string funcname,
278 std::vector<Variant*> params, ScriptVM* script_vm)
280 Variant* results = new Variant;
282 if (funcname == "getViewport")
284 std::vector<Variant*> viewport_data;
286 Variant* value = new Variant;
287 *value = viewport.x;
288 viewport_data.push_back(value);
290 value = new Variant;
291 *value = viewport.x;
292 viewport_data.push_back(value);
294 *results = viewport_data;
297 if (funcname == "setViewport")
299 LevelPair nviewport = viewport;
303 nviewport.x = (params.at(0)->verifyType<float>() ?
304 params.at(0)->get<float>() :
305 params.at(0)->get<int>());
306 nviewport.y = (params.at(1)->verifyType<float>() ?
307 params.at(1)->get<float>() :
308 params.at(1)->get<int>());
311 catch (...)
313 std::cout
314 << "Level::callFunction(funcname=\"setViewport\"): wrong params"
315 << std::endl;
316 return results;
319 viewport = nviewport;
322 if (funcname == "getActorIndicesByName")
324 if (params.size() < 1 || !params.at(0)->verifyType<std::string>())
326 std::cout
327 << "Level::callFunction(funcname=\"getActorIndicesByName\"):"
328 " wrong params"
329 << std::endl;
330 return results;
333 std::vector<Variant*> nresults;
334 std::string name = params.at(0)->get<std::string>();
336 int cur;
337 for (cur = 0; cur < actors.size(); cur++)
338 if (actors.at(cur).actor->getName() == name)
340 nresults.push_back(new Variant);
341 *(nresults.at(nresults.size() - 1)) = cur;
344 *results = nresults;
347 if (funcname == "getActor")
349 if (params.size() < 1 || !params.at(0)->verifyType<int>())
351 std::cout
352 << "Level::callFunction(funcname=\"getActor\"):"
353 " wrong params"
354 << std::endl;
355 return results;
358 int idx = params.at(0)->get<int>();
360 if (idx < 0 || idx >= actors.size())
362 std::cout
363 << "Level::callFunction(funcname=\"getActor\"):"
364 " invalid index"
365 << std::endl;
366 return results;
369 *results = dynamic_cast<ScriptedClass*>(actors.at(idx).actor);
372 if (funcname == "getActorZIndex")
374 if (params.size() < 1 || !params.at(0)->verifyType<int>())
376 std::cout
377 << "Level::callFunction(funcname=\"getActorZIndex\"):"
378 " wrong params"
379 << std::endl;
380 return results;
383 int idx = params.at(0)->get<int>();
385 if (idx < 0 || idx >= actors.size())
387 std::cout
388 << "Level::callFunction(funcname=\"getActorZIndex\"):"
389 " invalid index"
390 << std::endl;
391 return results;
394 *results = actors.at(idx).zindex;
397 if (funcname == "setActorZIndex")
399 if (params.size() < 2 || !params.at(0)->verifyType<int>())
401 std::cout
402 << "Level::callFunction(funcname=\"setActorZIndex\"):"
403 " wrong params"
404 << std::endl;
405 return results;
408 int idx = params.at(0)->get<int>();
409 float nzindex;
413 nzindex = params.at(1)->verifyType<int>() ?
414 params.at(1)->get<int>():
415 params.at(1)->get<float>();
418 catch(...)
420 std::cout
421 << "Level::callFunction(funcname=\"setActorZIndex\"):"
422 " wrong params"
423 << std::endl;
424 return results;
427 if (idx < 0 || idx >= actors.size())
429 std::cout
430 << "Level::callFunction(funcname=\"setActorZIndex\"):"
431 " invalid index"
432 << std::endl;
433 return results;
436 actors.at(idx).zindex = nzindex;
439 if (funcname == "deleteActor")
441 if (params.size() < 1 || !params.at(0)->verifyType<int>())
443 std::cout
444 << "Level::callFunction(funcname=\"deleteActor\"):"
445 " wrong params"
446 << std::endl;
447 return results;
450 int idx = params.at(0)->get<int>();
452 if (idx < 0 || idx >= actors.size())
454 std::cout
455 << "Level::callFunction(funcname=\"deleteActor\"):"
456 " invalid index"
457 << std::endl;
458 return results;
461 delete actors.at(idx).actor;
462 actors.erase(actors.begin() + idx);
465 if (funcname == "makeActor")
467 if (params.size() < 2 ||
468 !params.at(0)->verifyType<std::string>() ||
469 !params.at(1)->verifyType<std::string>())
471 std::cout
472 << "Level::callFunction(funcname=\"makeActor\"):"
473 " wrong params"
474 << std::endl;
475 return results;
478 std::string name = params.at(0)->get<std::string>();
479 std::string source = params.at(0)->get<std::string>();
481 ActorData data;
483 find_actordata<ActorData> search;
484 search.data = &data;
485 search.to_find = source;
486 search.found = false;
488 std::for_each(actor_defs.begin(), actor_defs.end(), search);
490 if (!search.found)
492 std::cout
493 << "Level::callFunction(funcname=\"makeActor\"):"
494 " failed to find source"
495 << std::endl;
496 *results = -1;
497 return results;
500 Actor* nactor = new Actor(data);
502 LActor ngraphic;
503 ngraphic.actor = nactor;
504 ngraphic.zindex = 0.0;
506 pipeline->getTargetVector().push_back(
507 dynamic_cast<EventReceiver*>(ngraphic.actor));
508 actors.push_back(ngraphic);
510 *results = actors.size() - 1;
513 return results;
516 LevelData Level::parseXML(std::string source, MediaLoader& media_loader)
518 return XMLParser::parselevel::parselevelFromBuffer(
519 media_loader.loadMedia(source));
521 // lolwut