FRESH AND RAW
[potpourri.git] / src / core / Actor.cpp
blob5ee63e34401d1bef2a4aaeb19d7f7c50acaf4e03
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 actor class.
23 #include <iostream>
24 #include <string>
25 #include <stdexcept>
27 #include <chipmunk.h> // will this work?
29 #include "../../include/core/Actor.h"
30 #include "../../include/core/parseactor.h"
31 #include "../../include/core/XmlExtra.h"
33 using namespace fragrant;
35 ActorPair fragrant::makePair(float x, float y)
37 ActorPair results;
38 results.x = x;
39 results.y = y;
41 return results;
44 void clearStringToVariantMap(std::map<std::string, Variant*> params)
46 std::map<std::string, Variant*>::iterator iter;
48 for (iter = params.begin(); iter != params.end(); iter++)
49 delete iter->second;
51 return;
54 std::map<std::string, Variant*>
55 stringToVariantMap(std::map<std::string, Pair<std::string> > params)
57 std::map<std::string, Variant*> results;
58 std::map<std::string, Pair<std::string> >::iterator iter;
60 for (iter = params.begin(); iter != params.end(); iter++)
62 results[iter->first] = new Variant;
64 if (iter->second.x == "std::string")
66 *(results[iter->first]) = iter->second.y;
67 continue;
70 if (iter->second.x == "bool")
72 *(results[iter->first]) = fromString<bool>(iter->second.y);
73 continue;
76 if (iter->second.x == "int")
78 *(results[iter->first]) = fromString<int>(iter->second.y);
79 continue;
82 if (iter->second.x == "float")
84 *(results[iter->first]) = fromString<float>(iter->second.y);
85 continue;
88 delete results[iter->first];
89 results.erase(results.find(iter->first));
91 std::cerr << "stringToVariantMap(): failed "
92 "to identify type, \""
93 << iter->second.x << "\"" << std::endl;
96 return results;
99 Actor::Actor(ActorData data)
101 persistent = false; // debug
102 initial_params = data;
104 int cur;
106 for (cur = 0; cur < data.graphics.size(); cur++)
108 ActorGraphics c_graphics = data.graphics.at(cur);
110 ActorGraphic ngraphic;
111 ngraphic.position.x = static_cast<int>(c_graphics.pos.x);
112 ngraphic.position.y = static_cast<int>(c_graphics.pos.y);
113 ngraphic.angle = c_graphics.angle;
114 ngraphic.name = c_graphics.sauce;
116 std::map<std::string, Variant*> params =
117 stringToVariantMap(c_graphics.params);
118 ngraphic.graphic = data.game->getGraphics(c_graphics.sauce, params);
119 clearStringToVariantMap(params);
121 sprites.push_back(ngraphic);
124 data.physics.base_position.x = data.position.x;
125 data.physics.base_position.y = INV_Y - data.position.y;
127 physics_object = new PhysicsObject(data.physics);
128 physics_object->setPosition(makePair(
129 data.position.x, INV_Y - data.position.y));
130 data.simulation->addPhysicsObject(physics_object);
133 Actor::~Actor()
135 delete physics_object;
138 void Actor::draw(Target* target, LevelPair offset)
140 int cur;
141 for (cur = 0; cur < sprites.size(); cur++)
143 ActorGraphic cur_graphic = sprites.at(cur);
145 ActorPair physics_pos = physics_object->Object2World(
146 makePair(cur_graphic.position.x, -cur_graphic.position.y));
148 GraphicsRect src;
149 src.xy.x = physics_pos.x - offset.x;
150 src.xy.y = (INV_Y - physics_pos.y) - offset.y;
152 cur_graphic.graphic->draw(dynamic_cast<Target*>(target), &src,
153 static_cast<GraphicsPair*>(0), cur_graphic.angle +
154 physics_object->getAngle());
157 return;
160 void Actor::setAngle(float nangle)
162 physics_object->setAngle(nangle);
163 return;
166 float Actor::getAngle()
168 return physics_object->getAngle();
171 std::string Actor::getName()
173 return initial_params.name;
176 void Actor::raiseEvent(Event event)
178 std::map<std::string, std::string>::iterator iter;
180 for (iter = initial_params.scripts.begin();
181 iter != initial_params.scripts.end();
182 iter++)
183 if (matchEvent(iter->first, event))
185 std::string script_data;
189 script_data = initial_params.game->getFile(iter->second);
192 catch (std::runtime_error& e)
194 std::cerr << "Actor::raiseEvent(): error with getting "
195 "script:\n\t" << e.what() << std::endl;
196 continue;
199 ScriptVM::caller = this;
200 cur_event = event;
201 initial_params.script_vm->execString(script_data);
204 return;
207 func Actor::getConstructor()
209 return 0; // not going to implement yet
212 void Actor::destroy()
214 return; // probably not going to implement in the first place
217 std::string Actor::getClassName() { return "Actor"; }
219 std::vector<std::string> Actor::getClassFunctions()
221 std::vector<std::string> results;
223 results.push_back("getPosition");
224 results.push_back("setPosition");
226 results.push_back("getAngle");
227 results.push_back("setAngle");
229 results.push_back("getVariable");
230 results.push_back("setVariable");
232 results.push_back("applyImpulse");
234 results.push_back("getCurrentEvent");
236 results.push_back("getVelocity");
237 results.push_back("setVelocity");
239 results.push_back("getAngularVelocity");
240 results.push_back("setAngularVelocity");
242 results.push_back("removeGraphic"); // actor.removeGraphic(idx)
243 results.push_back("addGraphic"); // actor.addGraphic(name, pos, angle)
245 results.push_back("getGraphicIndex");
246 results.push_back("getGraphicListSize");
248 results.push_back("setGraphicPosition");
249 results.push_back("getGraphicPosition");
251 results.push_back("setGraphicAngle");
252 results.push_back("getGraphicAngle");
254 return results;
257 Variant* Actor::callFunction(std::string funcname,
258 std::vector<Variant*> params, ScriptVM* script_vm)
260 Variant* results = new Variant;
262 if (funcname == "getPosition")
264 std::vector<Variant*> pos;
265 Variant* var;
267 var = new Variant;
268 *var = physics_object->getPosition().x;
269 pos.push_back(var);
271 var = new Variant;
272 *var = physics_object->getPosition().y;
273 pos.push_back(var);
275 *results = pos;
278 if (funcname == "setPosition")
280 ActorPair npos;
282 if (params.size() < 2)
284 std::cout
285 << "Actor::callFunction(funcname=\"setPosition\"): wrong params"
286 << std::endl;
287 return results;
292 npos.x = (params.at(0)->verifyType<int>() ?
293 params.at(0)->get<int>() :
294 params.at(0)->get<float>());
295 npos.y = (params.at(1)->verifyType<int>() ?
296 params.at(1)->get<int>() :
297 params.at(1)->get<float>());
300 catch (...)
302 std::cout
303 << "Actor::callFunction(funcname=\"setPosition\"): wrong params"
304 << std::endl;
305 return results;
308 physics_object->setPosition(npos);
311 if (funcname == "getAngle")
312 *results = physics_object->getAngle();
314 if (funcname == "setAngle")
316 if (params.size() < 1)
318 std::cout
319 << "Actor::callFunction(funcname=\"setAngle\"): wrong params"
320 << std::endl;
321 return results;
326 float data = (params.at(0)->verifyType<int>() ?
327 static_cast<float>(params.at(0)->get<int>()) :
328 params.at(0)->get<float>());
329 physics_object->setAngle(data);
332 catch (...)
334 std::cout
335 << "Actor::callFunction(funcname=\"setAngle\"): wrong params"
336 << std::endl;
337 return results;
341 if (funcname == "getVariable")
343 if (params.size() < 1)
345 std::cout
346 << "Actor::callFunction(funcname=\"getVariable\"): wrong params"
347 << std::endl;
348 return results;
351 std::string key;
355 key = params.at(0)->get<std::string>();
358 catch(...)
360 std::cout
361 << "Actor::callFunction(funcname=\"getVariable\"): wrong params"
362 << std::endl;
363 return results;
366 if (!key.size() || ldata.find(key) == ldata.end())
368 *results = std::string("");
369 return results;
372 *results = ldata[key];
375 if (funcname == "setVariable")
377 if (params.size() < 2)
379 std::cout
380 << "Actor::callFunction(funcname=\"setVariable\"): wrong params"
381 << std::endl;
382 return results;
385 std::string key;
386 std::string value;
390 key = params.at(0)->get<std::string>();
391 value = params.at(1)->get<std::string>();
394 catch(...)
396 std::cout
397 << "Actor::callFunction(funcname=\"setVariable\"): wrong params"
398 << std::endl;
399 return results;
402 if (!key.size())
404 std::cout
405 << "Actor::callFunction(funcname=\"setVariable\"): wrong params"
406 << std::endl;
407 return results;
410 ldata[key] = value;
413 if (funcname == "applyImpulse")
415 ActorPair impulse;
416 ActorPair offset = makePair(0,0);
418 if (params.size() < 2)
420 std::cout
421 << "Actor::callFunction(funcname=\"applyImpulse\"):"
422 << " wrong params" << std::endl;
423 return results;
428 impulse.x = (params.at(0)->verifyType<int>() ?
429 params.at(0)->get<int>() :
430 params.at(0)->get<float>());
431 impulse.y = (params.at(1)->verifyType<int>() ?
432 params.at(1)->get<int>() :
433 params.at(1)->get<float>());
435 catch (...)
437 std::cout
438 << "Actor::callFunction(funcname=\"applyImpulse\"): "
439 << "wrong params" << std::endl;
440 return results;
443 if (params.size() > 3)
447 offset.x = (params.at(2)->verifyType<int>() ?
448 params.at(2)->get<int>() :
449 params.at(2)->get<float>());
450 offset.y = (params.at(3)->verifyType<int>() ?
451 params.at(3)->get<int>() :
452 params.at(3)->get<float>());
454 catch (...)
456 std::cout
457 << "Actor::callFunction(funcname=\"applyImpulse\"): "
458 << "wrong params" << std::endl;
459 return results;
463 physics_object->applyImpulse(impulse, offset);
466 if (funcname == "getCurrentEvent")
468 std::vector<Variant*> event;
469 event.push_back(new Variant);
471 *(event.at(0)) = cur_event.name;
473 std::map<std::string, Variant*>::iterator iter;
474 for (iter = cur_event.data.begin();
475 iter != cur_event.data.end();
476 iter++)
478 Variant* nv = duplicateVariant(iter->second);
480 if (nv)
482 event.push_back(new Variant);
483 event.push_back(nv);
485 *(event.at(event.size() - 2)) = iter->first;
489 *results = event;
492 if (funcname == "getVelocity")
494 std::vector<Variant*> velocity;
495 Variant* var;
497 var = new Variant;
498 *var = physics_object->getVelocity().x;
499 velocity.push_back(var);
501 var = new Variant;
502 *var = physics_object->getVelocity().y;
503 velocity.push_back(var);
505 *results = velocity;
508 if (funcname == "setVelocity")
510 ActorPair nvelocity;
512 if (params.size() < 2)
514 std::cout
515 << "Actor::callFunction(funcname=\"setVelocity\"): wrong params"
516 << std::endl;
517 return results;
522 nvelocity.x = (params.at(0)->verifyType<int>() ?
523 params.at(0)->get<int>() :
524 params.at(0)->get<float>());
525 nvelocity.y = (params.at(1)->verifyType<int>() ?
526 params.at(1)->get<int>() :
527 params.at(1)->get<float>());
529 catch (...)
531 std::cout
532 << "Actor::callFunction(funcname=\"setVelocity\"): wrong params"
533 << std::endl;
534 return results;
537 physics_object->setVelocity(nvelocity);
540 if (funcname == "getAngularVelocity")
541 *results = physics_object->getVelocity();
543 if (funcname == "setAngularVelocity")
545 float nvelocity;
547 if (params.size() < 1)
549 std::cout
550 << "Actor::callFunction(funcname=\"setAngularVelocity\")"
551 ": wrong params"
552 << std::endl;
553 return results;
558 nvelocity = (params.at(0)->verifyType<int>() ?
559 params.at(0)->get<int>() :
560 params.at(0)->get<float>());
562 catch (...)
564 std::cout
565 << "Actor::callFunction(funcname=\"setAngularVelocity\"):"
566 " wrong params"
567 << std::endl;
568 return results;
571 physics_object->setAngularVelocity(nvelocity);
574 if (funcname == "removeGraphic")
576 if (params.size() < 1 || !params.at(0)->verifyType<int>())
578 std::cout
579 << "Actor::callFunction(funcname=\"removeGraphic\")"
580 ": wrong params"
581 << std::endl;
582 return results;
585 int idx = params.at(0)->get<int>();
587 if (idx >= sprites.size())
589 std::cout
590 << "Actor::callFunction(funcname=\"removeGraphic\")"
591 ": wrong params"
592 << std::endl;
593 return results;
596 sprites.erase(sprites.begin() + idx);
599 if (funcname == "addGraphic")
601 if (params.size() < 1 ||
602 !params.at(0)->verifyType<std::string>())
604 std::cout
605 << "Actor::callFunction(funcname=\"addGraphic\")"
606 ": wrong params"
607 << std::endl;
608 return results;
611 std::string name = params.at(0)->get<std::string>();
612 ActorPair pos = makePair(0,0);
613 float angle = 0;
617 if (params.size() > 2)
619 pos.x = (params.at(1)->verifyType<float>()) ?
620 (params.at(1)->get<float>()) :
621 (params.at(1)->get<int>());
622 pos.y = (params.at(2)->verifyType<float>()) ?
623 (params.at(2)->get<float>()) :
624 (params.at(2)->get<int>());
628 catch (...)
630 std::cout
631 << "Actor::callFunction(funcname=\"addGraphic\"): wrong params"
632 << std::endl;
633 return results;
636 if (params.size() > 3)
640 angle = (params.at(3)->verifyType<float>()) ?
641 (params.at(3)->get<float>()) :
642 (params.at(3)->get<int>());
645 catch (...)
647 std::cout
648 << "Actor::callFunction(funcname=\"addGraphic\")"
649 ": wrong params"
650 << std::endl;
651 return results;
655 std::map<std::string, Variant*> nparams;
657 if (params.size() > 5)
659 int cur;
660 int cap = (params.size() % 2) ? -1 : -2;
661 for (cur = 4; cur < params.size()+cap; cur+=2)
663 if (!params.at(cur)->verifyType<std::string>())
665 std::cout
666 << "Actor::callFunction(funcname=\"addGraphic\")"
667 ": wrong params"
668 << std::endl;
669 return results;
672 nparams[params.at(cur)->get<std::string>()] =
673 params.at(cur + 1);
677 ActorGraphic ngraphic;
678 ngraphic.name = name;
679 ngraphic.position.x = pos.x;
680 ngraphic.position.y = pos.y;
681 ngraphic.angle = angle;
683 ngraphic.graphic = initial_params.game->
684 getGraphics(ngraphic.name, nparams);
686 if (ngraphic.graphic)
688 sprites.push_back(ngraphic);
689 *results = sprites.size() - 1;
692 else
694 std::cout
695 << "Actor::callFunction(funcname=\"addGraphic\")"
696 ": failed to make graphic"
697 << std::endl;
698 return results;
702 if (funcname == "getGraphicIndex")
704 if (params.size() < 1 || !params.at(0)->verifyType<std::string>())
706 std::cout
707 << "Actor::callFunction(funcname=\"getGraphicIndex\")"
708 ": wrong params"
709 << std::endl;
710 return results;
713 std::string name = params.at(0)->get<std::string>();
714 int cur;
716 for (cur = 0; cur < sprites.size(); cur++)
717 if (sprites.at(cur).name == name)
718 break;
720 if (cur >= sprites.size())
722 std::cout
723 << "Actor::callFunction(funcname=\"getGraphicIndex\")"
724 ": no such sprite"
725 << std::endl;
726 cur = -1;
729 *results = cur;
732 if (funcname == "getGraphicListSize")
733 *results = sprites.size();
735 if (funcname == "setGraphicPosition")
737 if (params.size() < 3 ||
738 !params.at(0)->verifyType<int>())
740 std::cout
741 << "Actor::callFunction(funcname=\"setGraphicPosition\")"
742 ": wrong params"
743 << std::endl;
744 return results;
747 int idx = params.at(0)->get<int>();
748 ActorPair pos;
750 if (idx >= sprites.size() || idx < 0)
752 std::cout
753 << "Actor::callFunction(funcname=\"setGraphicPosition\")"
754 ": bad index"
755 << std::endl;
756 return results;
761 pos.x = (params.at(1)->verifyType<float>()) ?
762 (params.at(1)->get<float>()) :
763 (params.at(1)->get<int>());
764 pos.y = (params.at(2)->verifyType<float>()) ?
765 (params.at(2)->get<float>()) :
766 (params.at(2)->get<int>());
769 catch (...)
771 std::cout
772 << "Actor::callFunction(funcname=\"setGraphicPosition\")"
773 ": wrong params"
774 << std::endl;
775 return results;
778 sprites.at(idx).position.x = pos.x;
779 sprites.at(idx).position.y = pos.y;
782 if (funcname == "getGraphicPosition")
784 if (params.size() < 1 ||
785 !params.at(0)->verifyType<int>())
787 std::cout
788 << "Actor::callFunction(funcname=\"getGraphicPosition\")"
789 ": wrong params"
790 << std::endl;
791 return results;
794 int idx = params.at(0)->get<int>();
796 if (idx >= sprites.size() || idx < 0)
798 std::cout
799 << "Actor::callFunction(funcname=\"getGraphicPosition\")"
800 ": bad index"
801 << std::endl;
802 return results;
805 std::vector<Variant*> dresults;
807 dresults.push_back(new Variant);
808 dresults.push_back(new Variant);
810 *(dresults.at(0)) = sprites.at(idx).position.x;
811 *(dresults.at(1)) = sprites.at(idx).position.y;
813 *results = dresults;
816 if (funcname == "setGraphicAngle")
818 if (params.size() < 2 ||
819 !params.at(0)->verifyType<int>())
821 std::cout
822 << "Actor::callFunction(funcname=\"setGraphicAngle\")"
823 ": wrong params"
824 << std::endl;
825 return results;
828 int idx = params.at(0)->get<int>();
829 float angle;
831 if (idx >= sprites.size() || idx < 0)
833 std::cout
834 << "Actor::callFunction(funcname=\"setGraphicAngle\")"
835 ": bad index"
836 << std::endl;
837 return results;
842 angle = (params.at(1)->verifyType<float>()) ?
843 (params.at(1)->get<float>()) :
844 (params.at(1)->get<int>());
847 catch (...)
849 std::cout
850 << "Actor::callFunction(funcname=\"setGraphicAngle\")"
851 ": wrong params"
852 << std::endl;
853 return results;
856 sprites.at(idx).angle = angle;
859 if (funcname == "getGraphicAngle")
861 if (params.size() < 1 ||
862 !params.at(0)->verifyType<int>())
864 std::cout
865 << "Actor::callFunction(funcname=\"getGraphicAngle\")"
866 ": wrong params"
867 << std::endl;
868 return results;
871 int idx = params.at(0)->get<int>();
873 if (idx >= sprites.size() || idx < 0)
875 std::cout
876 << "Actor::callFunction(funcname=\"getGraphicAngle\")"
877 ": bad index"
878 << std::endl;
879 return results;
882 *results = sprites.at(idx).angle;
885 return results;
888 ActorData Actor::parseXML(std::string source, MediaLoader& media_loader)
890 std::string temp = source; // debug
892 std::string buffer = media_loader.loadMedia(temp);
894 XMLParser::parseactor::actor actor =
895 XMLParser::parseactor::parseactorFromBuffer(buffer);
897 ActorData results;
898 results.media_loader = &media_loader;
900 results.name = actor.m_name;
902 int cur;
903 for (cur = 0; cur < actor.m_graphics.size(); cur++)
905 ActorGraphics graphics;
906 XMLParser::parseactor::graphics cur_graphics = actor.m_graphics.at(cur);
908 graphics.sauce = cur_graphics.m_source;
909 graphics.pos = parsePair(cur_graphics.m_pos.m_pair);
910 graphics.angle = cur_graphics.m_angle; // fix'd
912 int tcur;
913 for (tcur = 0; tcur < cur_graphics.m_params.size(); tcur++)
915 std::string param_name = cur_graphics.m_params.at(tcur).name;
916 std::string param_value = cur_graphics.m_params.at(tcur).value;
917 std::string param_type = cur_graphics.m_params.at(tcur).type;
919 graphics.params[param_name] = Pair<std::string>();
921 graphics.params[param_name].x = param_type;
922 graphics.params[param_name].y = param_value;
925 results.graphics.push_back(graphics);
928 results.physics.mass = actor.m_physics.m_body.m_mass;
929 results.physics.inertia = actor.m_physics.m_body.m_inertia;
930 results.physics.fixed = actor.m_physics.m_body.m_fixed;
932 for (cur = 0; cur < actor.m_physics.m_poly.size(); cur++)
934 XMLParser::parseactor::poly cur_poly = actor.m_physics.m_poly.at(cur);
936 PhysicsShape nshape;
937 nshape.offset = parsePair(cur_poly.m_offset.m_pair);
938 nshape.shape = S_Poly;
940 nshape.elasticity = cur_poly.m_elasticity;
941 nshape.friction = cur_poly.m_friction;
943 int subcur;
944 for (subcur = 0; subcur < cur_poly.m_data.m_pair.size(); subcur++)
946 std::string cur_item = cur_poly.m_data.m_pair.at(subcur);
947 nshape.data.push_back(parsePair(cur_item));
950 results.physics.shapes.push_back(nshape);
953 for (cur = 0; cur < actor.m_physics.m_circle.size(); cur++)
955 XMLParser::parseactor::circle cur_circle =
956 actor.m_physics.m_circle.at(cur);
958 PhysicsShape nshape;
959 nshape.offset = parsePair(cur_circle.m_offset.m_pair);
960 nshape.shape = S_Circle;
962 nshape.elasticity = cur_circle.m_elasticity;
963 nshape.friction = cur_circle.m_friction;
965 ActorPair pair; // bender should grow this
966 pair.x = cur_circle.m_radius;
968 nshape.data.push_back(pair);
970 results.physics.shapes.push_back(nshape);
973 for (cur = 0; cur < actor.m_physics.m_line.size(); cur++)
975 XMLParser::parseactor::line cur_line =
976 actor.m_physics.m_line.at(cur);
978 PhysicsShape nshape;
979 nshape.shape = S_Line;
981 nshape.elasticity = cur_line.m_elasticity;
982 nshape.friction = cur_line.m_friction;
984 nshape.data.push_back(parsePair(cur_line.m_a));
985 nshape.data.push_back(parsePair(cur_line.m_b));
987 ActorPair pair;
988 pair.x = cur_line.m_radius;
990 nshape.data.push_back(pair);
992 results.physics.shapes.push_back(nshape);
995 for (cur = 0; cur < actor.m_reaction.size(); cur++)
997 std::string event = actor.m_reaction.at(cur).m_event;
998 std::string script = actor.m_reaction.at(cur).m_script;
1000 results.scripts[event] = script;
1003 return results;