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/>.
21 // The source for the actor class.
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
)
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
++)
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
;
70 if (iter
->second
.x
== "bool")
72 *(results
[iter
->first
]) = fromString
<bool>(iter
->second
.y
);
76 if (iter
->second
.x
== "int")
78 *(results
[iter
->first
]) = fromString
<int>(iter
->second
.y
);
82 if (iter
->second
.x
== "float")
84 *(results
[iter
->first
]) = fromString
<float>(iter
->second
.y
);
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
;
99 Actor::Actor(ActorData data
)
101 persistent
= false; // debug
102 initial_params
= data
;
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
);
135 delete physics_object
;
138 void Actor::draw(Target
* target
, LevelPair offset
)
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
));
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());
160 void Actor::setAngle(float nangle
)
162 physics_object
->setAngle(nangle
);
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();
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
;
199 ScriptVM::caller
= this;
201 initial_params
.script_vm
->execString(script_data
);
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");
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
;
268 *var
= physics_object
->getPosition().x
;
272 *var
= physics_object
->getPosition().y
;
278 if (funcname
== "setPosition")
282 if (params
.size() < 2)
285 << "Actor::callFunction(funcname=\"setPosition\"): wrong params"
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>());
303 << "Actor::callFunction(funcname=\"setPosition\"): wrong params"
308 physics_object
->setPosition(npos
);
311 if (funcname
== "getAngle")
312 *results
= physics_object
->getAngle();
314 if (funcname
== "setAngle")
316 if (params
.size() < 1)
319 << "Actor::callFunction(funcname=\"setAngle\"): wrong params"
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
);
335 << "Actor::callFunction(funcname=\"setAngle\"): wrong params"
341 if (funcname
== "getVariable")
343 if (params
.size() < 1)
346 << "Actor::callFunction(funcname=\"getVariable\"): wrong params"
355 key
= params
.at(0)->get
<std::string
>();
361 << "Actor::callFunction(funcname=\"getVariable\"): wrong params"
366 if (!key
.size() || ldata
.find(key
) == ldata
.end())
368 *results
= std::string("");
372 *results
= ldata
[key
];
375 if (funcname
== "setVariable")
377 if (params
.size() < 2)
380 << "Actor::callFunction(funcname=\"setVariable\"): wrong params"
390 key
= params
.at(0)->get
<std::string
>();
391 value
= params
.at(1)->get
<std::string
>();
397 << "Actor::callFunction(funcname=\"setVariable\"): wrong params"
405 << "Actor::callFunction(funcname=\"setVariable\"): wrong params"
413 if (funcname
== "applyImpulse")
416 ActorPair offset
= makePair(0,0);
418 if (params
.size() < 2)
421 << "Actor::callFunction(funcname=\"applyImpulse\"):"
422 << " wrong params" << std::endl
;
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>());
438 << "Actor::callFunction(funcname=\"applyImpulse\"): "
439 << "wrong params" << std::endl
;
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>());
457 << "Actor::callFunction(funcname=\"applyImpulse\"): "
458 << "wrong params" << std::endl
;
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();
478 Variant
* nv
= duplicateVariant(iter
->second
);
482 event
.push_back(new Variant
);
485 *(event
.at(event
.size() - 2)) = iter
->first
;
492 if (funcname
== "getVelocity")
494 std::vector
<Variant
*> velocity
;
498 *var
= physics_object
->getVelocity().x
;
499 velocity
.push_back(var
);
502 *var
= physics_object
->getVelocity().y
;
503 velocity
.push_back(var
);
508 if (funcname
== "setVelocity")
512 if (params
.size() < 2)
515 << "Actor::callFunction(funcname=\"setVelocity\"): wrong params"
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>());
532 << "Actor::callFunction(funcname=\"setVelocity\"): wrong params"
537 physics_object
->setVelocity(nvelocity
);
540 if (funcname
== "getAngularVelocity")
541 *results
= physics_object
->getVelocity();
543 if (funcname
== "setAngularVelocity")
547 if (params
.size() < 1)
550 << "Actor::callFunction(funcname=\"setAngularVelocity\")"
558 nvelocity
= (params
.at(0)->verifyType
<int>() ?
559 params
.at(0)->get
<int>() :
560 params
.at(0)->get
<float>());
565 << "Actor::callFunction(funcname=\"setAngularVelocity\"):"
571 physics_object
->setAngularVelocity(nvelocity
);
574 if (funcname
== "removeGraphic")
576 if (params
.size() < 1 || !params
.at(0)->verifyType
<int>())
579 << "Actor::callFunction(funcname=\"removeGraphic\")"
585 int idx
= params
.at(0)->get
<int>();
587 if (idx
>= sprites
.size())
590 << "Actor::callFunction(funcname=\"removeGraphic\")"
596 sprites
.erase(sprites
.begin() + idx
);
599 if (funcname
== "addGraphic")
601 if (params
.size() < 1 ||
602 !params
.at(0)->verifyType
<std::string
>())
605 << "Actor::callFunction(funcname=\"addGraphic\")"
611 std::string name
= params
.at(0)->get
<std::string
>();
612 ActorPair pos
= makePair(0,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>());
631 << "Actor::callFunction(funcname=\"addGraphic\"): wrong params"
636 if (params
.size() > 3)
640 angle
= (params
.at(3)->verifyType
<float>()) ?
641 (params
.at(3)->get
<float>()) :
642 (params
.at(3)->get
<int>());
648 << "Actor::callFunction(funcname=\"addGraphic\")"
655 std::map
<std::string
, Variant
*> nparams
;
657 if (params
.size() > 5)
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
>())
666 << "Actor::callFunction(funcname=\"addGraphic\")"
672 nparams
[params
.at(cur
)->get
<std::string
>()] =
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;
695 << "Actor::callFunction(funcname=\"addGraphic\")"
696 ": failed to make graphic"
702 if (funcname
== "getGraphicIndex")
704 if (params
.size() < 1 || !params
.at(0)->verifyType
<std::string
>())
707 << "Actor::callFunction(funcname=\"getGraphicIndex\")"
713 std::string name
= params
.at(0)->get
<std::string
>();
716 for (cur
= 0; cur
< sprites
.size(); cur
++)
717 if (sprites
.at(cur
).name
== name
)
720 if (cur
>= sprites
.size())
723 << "Actor::callFunction(funcname=\"getGraphicIndex\")"
732 if (funcname
== "getGraphicListSize")
733 *results
= sprites
.size();
735 if (funcname
== "setGraphicPosition")
737 if (params
.size() < 3 ||
738 !params
.at(0)->verifyType
<int>())
741 << "Actor::callFunction(funcname=\"setGraphicPosition\")"
747 int idx
= params
.at(0)->get
<int>();
750 if (idx
>= sprites
.size() || idx
< 0)
753 << "Actor::callFunction(funcname=\"setGraphicPosition\")"
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>());
772 << "Actor::callFunction(funcname=\"setGraphicPosition\")"
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>())
788 << "Actor::callFunction(funcname=\"getGraphicPosition\")"
794 int idx
= params
.at(0)->get
<int>();
796 if (idx
>= sprites
.size() || idx
< 0)
799 << "Actor::callFunction(funcname=\"getGraphicPosition\")"
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
;
816 if (funcname
== "setGraphicAngle")
818 if (params
.size() < 2 ||
819 !params
.at(0)->verifyType
<int>())
822 << "Actor::callFunction(funcname=\"setGraphicAngle\")"
828 int idx
= params
.at(0)->get
<int>();
831 if (idx
>= sprites
.size() || idx
< 0)
834 << "Actor::callFunction(funcname=\"setGraphicAngle\")"
842 angle
= (params
.at(1)->verifyType
<float>()) ?
843 (params
.at(1)->get
<float>()) :
844 (params
.at(1)->get
<int>());
850 << "Actor::callFunction(funcname=\"setGraphicAngle\")"
856 sprites
.at(idx
).angle
= angle
;
859 if (funcname
== "getGraphicAngle")
861 if (params
.size() < 1 ||
862 !params
.at(0)->verifyType
<int>())
865 << "Actor::callFunction(funcname=\"getGraphicAngle\")"
871 int idx
= params
.at(0)->get
<int>();
873 if (idx
>= sprites
.size() || idx
< 0)
876 << "Actor::callFunction(funcname=\"getGraphicAngle\")"
882 *results
= sprites
.at(idx
).angle
;
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
);
898 results
.media_loader
= &media_loader
;
900 results
.name
= actor
.m_name
;
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
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
);
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
;
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
);
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
);
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
));
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
;