00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <map>
00022 #include <iostream>
00023 #include "member.h"
00024 #include "../game/game_loop.h"
00025 #include "../team/teams_list.h"
00026 #include "../tool/math_tools.h"
00027 #include "../tool/xml_document.h"
00028 #include "../tool/string_tools.h"
00029
00030 Member::Member(xmlpp::Element *xml, Profile* res)
00031 {
00032 parent = NULL;
00033 if(xml == NULL) return;
00034 name="";
00035 XmlReader::ReadStringAttr( xml, "name", name);
00036 assert(name!="");
00037
00038
00039 spr = resource_manager.LoadSprite( res, name);
00040
00041
00042
00043
00044
00045 type="";
00046 XmlReader::ReadStringAttr( xml, "type", type);
00047 assert(type!="");
00048
00049 xmlpp::Element *el = XmlReader::GetMarker(xml, "anchor");
00050 if(el != 0)
00051 {
00052 int dx,dy;
00053 dx = dy = 0;
00054 XmlReader::ReadIntAttr(el, "dx", dx);
00055 XmlReader::ReadIntAttr(el, "dy", dy);
00056 anchor = Point2f((float)dx,(float)dy);
00057 spr->SetRotation_HotSpot(Point2i(dx,dy));
00058 }
00059
00060 go_through_ground = false;
00061 XmlReader::ReadBoolAttr(xml, "go_through_ground", go_through_ground);
00062
00063 xmlpp::Node::NodeList nodes = xml -> get_children("attached");
00064 xmlpp::Node::NodeList::iterator
00065 it=nodes.begin(),
00066 end=nodes.end();
00067
00068 for (; it != end; ++it)
00069 {
00070 xmlpp::Element *elem = dynamic_cast<xmlpp::Element*> (*it);
00071 assert (elem != NULL);
00072 std::string att_type;
00073 if (!XmlReader::ReadStringAttr(elem, "member_type", att_type))
00074 {
00075 std::cerr << "Malformed attached member definition" << std::endl;
00076 continue;
00077 }
00078
00079 int dx,dy;
00080 dx = dy = 0;
00081 XmlReader::ReadIntAttr(elem, "dx", dx);
00082 XmlReader::ReadIntAttr(elem, "dy", dy);
00083 Point2f d((float)dx, (float)dy);
00084
00085 std::string frame_str;
00086 XmlReader::ReadStringAttr(elem, "frame", frame_str);
00087 if (frame_str == "*")
00088 {
00089 v_attached rot_spot;
00090 rot_spot.assign (spr->GetFrameCount(), d);
00091 attached_members[att_type] = rot_spot;
00092 }
00093 else
00094 {
00095 int frame;
00096 if (!str2int (frame_str, frame) || frame < 0 || frame >= (int)spr->GetFrameCount())
00097 {
00098 std::cerr << "Malformed attached member definition (wrong frame number)" << std::endl;
00099 continue;
00100 }
00101 if(attached_members.find(att_type) == attached_members.end())
00102 {
00103 v_attached rot_spot;
00104 rot_spot.resize(spr->GetFrameCount(), Point2f(0.0,0.0));
00105 attached_members[att_type] = rot_spot;
00106 }
00107 (attached_members.find(att_type)->second)[frame] = d;
00108 }
00109 }
00110 ResetMovement();
00111 }
00112
00113 Member::Member(Member* m)
00114 {
00115 parent = NULL;
00116 name = m->name;
00117 spr = new Sprite(*m->spr);
00118 type = m->type;
00119 anchor = m->anchor;
00120 Point2i rot = Point2i((int)anchor.x, (int)anchor.y);
00121 spr->SetRotation_HotSpot(rot);
00122 go_through_ground = m->go_through_ground;
00123
00124 for(std::map<std::string, v_attached>::iterator it = m->attached_members.begin();
00125 it != m->attached_members.end();
00126 ++it)
00127 {
00128 attached_members[it->first] = it->second;
00129 }
00130 ResetMovement();
00131 }
00132
00133 Member::~Member()
00134 {
00135 delete spr;
00136 attached_members.clear();
00137 }
00138
00139 void Member::RotateSprite()
00140 {
00141 spr->SetRotation_rad(angle_rad);
00142 spr->Scale(scale.x, scale.y);
00143 spr->RefreshSurface();
00144 }
00145
00146 void Member::Draw(const Point2i & _pos, int flip_center, int direction)
00147 {
00148 assert(name != "weapon" && type!="weapon");
00149
00150 Point2i posi((int)pos.x, (int)pos.y);
00151 posi += _pos;
00152
00153 if(direction == 1)
00154 {
00155 spr->SetRotation_rad(angle_rad);
00156 spr->Scale(scale.x,scale.y);
00157 }
00158 else
00159 {
00160 spr->Scale(-scale.x,scale.y);
00161 spr->SetRotation_rad(-angle_rad);
00162 posi.x = 2 * flip_center - posi.x - spr->GetWidth();
00163 }
00164
00165 if(parent == NULL && type != "body")
00166 {
00167 std::cerr << "Error : Member " << name << " have no parent member!" << std::endl;
00168 return;
00169 }
00170
00171 spr->SetAlpha(alpha);
00172 spr->Update();
00173 spr->Draw(posi);
00174 }
00175
00176 void Member::ResetMovement()
00177 {
00178 pos.x = 0;
00179 pos.y = 0;
00180 angle_rad = 0;
00181 alpha = 1.0;
00182 scale.x = 1.0;
00183 scale.y = 1.0;
00184 }
00185
00186 void Member::ApplySqueleton(Member* parent_member)
00187 {
00188
00189 if(parent_member == NULL)
00190 {
00191 std::cerr << "Member " << name << " have no parent member!" << std::endl;
00192 return;
00193 }
00194 parent = parent_member;
00195
00196 assert(parent->name != "weapon" && parent->type != "weapon");
00197
00198
00199 pos = parent->pos;
00200 pos = pos - anchor;
00201
00202 if(parent->attached_members.find(type) != parent->attached_members.end())
00203 pos = pos + parent->attached_members.find(type)->second[parent->spr->GetCurrentFrame()];
00204 }
00205
00206 void Member::ApplyMovement(member_mvt &mvt, std::vector<junction>& squel_lst)
00207 {
00208
00209
00210
00211 uint frame;
00212 if(spr!=NULL)
00213 frame = spr->GetCurrentFrame();
00214 else
00215 frame = 0;
00216
00217
00218 for(std::map<std::string, v_attached>::iterator child = attached_members.begin();
00219 child != attached_members.end();
00220 child++ )
00221 {
00222
00223 for(std::vector<junction>::iterator member = squel_lst.begin();
00224 member != squel_lst.end();
00225 member++)
00226 {
00227 if(member->member->type == child->first)
00228 {
00229
00230 member_mvt child_mvt;
00231 child_mvt.SetAngle(mvt.GetAngle());
00232 child_mvt.pos = mvt.pos;
00233 float radius = anchor.Distance(child->second[frame]);
00234
00235 if(radius != 0.0)
00236 {
00237 float angle_init;
00238
00239 if(child->second[frame].x > anchor.x)
00240 {
00241 if(child->second[frame].y > anchor.y)
00242 angle_init = acos( (child->second[frame].x - anchor.x) / radius );
00243 else
00244 angle_init = -acos( (child->second[frame].x - anchor.x) / radius );
00245 }
00246 else
00247 {
00248 if(child->second[frame].y > anchor.y)
00249 angle_init = acos( (child->second[frame].x - anchor.x) / radius );
00250 else
00251 angle_init = M_PI + acos( -(child->second[frame].x - anchor.x) / radius );
00252 }
00253
00254 child_mvt.pos.x += radius * (cos(angle_init + angle_rad + mvt.GetAngle()) - cos(angle_init + angle_rad));
00255 child_mvt.pos.y += radius * (sin(angle_init + angle_rad + mvt.GetAngle()) - sin(angle_init + angle_rad));
00256 }
00257
00258 member->member->ApplyMovement(child_mvt, squel_lst);
00259 }
00260 }
00261 }
00262
00263
00264 SetAngle(angle_rad + mvt.GetAngle());
00265 pos += mvt.pos;
00266 alpha *= mvt.alpha;
00267 scale = scale * mvt.scale;
00268 }
00269
00270 const Point2i Member::GetPos()
00271 {
00272 Point2i posi((int)pos.x, (int)pos.y);
00273 return posi;
00274 }
00275
00276 WeaponMember::WeaponMember() : Member(NULL, NULL)
00277 {
00278 name = "weapon";
00279 type = "weapon";
00280 spr = NULL;
00281 anchor = Point2f(0.0,0.0);
00282 }
00283
00284 WeaponMember::~WeaponMember()
00285 {
00286 }
00287
00288 void WeaponMember::Draw(const Point2i & _pos, int flip_center, int direction)
00289 {
00290
00291 }