00001 #include <string.h>
00002 #include <iostream>
00003 #include <math.h>
00004
00005 #include "main_char.h"
00006 #include "objmgr.h"
00007 #include "nncmath.h"
00008
00009 MainChar::MainChar(ObjectManager &om) : GameObject(om, "Main Character")
00010 {
00011 vector <Surface *> v = Util_parseImage(MAIN_CHAR_IMG_FILE);
00012
00013
00014 sprite = new Sprite(v, "Main Character");
00015
00016
00017 SetDamagable (true);
00018 SetDamage (100);
00019
00020
00021 sprite->SetFrame(0);
00022
00023 sprite->SetAnimateTime(170);
00024
00025 walk_velocity.dx = walk_velocity.dy = 7.5;
00026 walk_velocity.pertime.msecs = 25;
00027 walk_velocity.pertime.secs = 0;
00028
00029
00030 SetWeaponStrength(1);
00031
00032
00033 shooting = 0;
00034 msshoot_delay = 250;
00035 }
00036
00037 MainChar::~MainChar()
00038 {
00039
00040 }
00041
00042 void MainChar::think()
00043 {
00044 int count;
00045
00046 if (shooting &&
00047 Util_TimePassed(&lastshoot, (Uint32)msshoot_delay) > 0) {
00048 shooting = 0;
00049
00050 if (walkDirection == NO_DIRECTION)
00051 setLook ( OM.GetCrosshair()->GetXint(), OM.GetCrosshair()->GetYint() );
00052 else {
00053 int wd = walkDirection;
00054
00055 setWalking ((wd & 0x01) ? true : false,
00056 (wd & 0x02) ? true : false,
00057 (wd & 0x04) ? true : false,
00058 (wd & 0x08) ? true : false, true);
00059 }
00060 }
00061
00062 if(walkDirection != NO_DIRECTION &&
00063 (count = Util_TimePassed(&lastwalk, walk_velocity.pertime.msecs)) > 0) {
00064 double ddx = count * walk_velocity.dx;
00065 double ddy = count * walk_velocity.dy;
00066 double nx = GetX(), ny = GetY();
00067 switch(walkDirection) {
00068 case NORTH:
00069 ny -= ddy;
00070 break;
00071 case SOUTH:
00072 ny += ddy;
00073 break;
00074 case NORTHEAST:
00075 ny -= ddy;
00076 nx += ddx;
00077 break;
00078 case EAST:
00079 nx += ddx;
00080 break;
00081 case NORTHWEST:
00082 ny -= ddy;
00083 nx -= ddx;
00084 break;
00085 case WEST:
00086 nx -= ddx;
00087 break;
00088 case SOUTHEAST:
00089 ny += ddy;
00090 nx += ddx;
00091 break;
00092 case SOUTHWEST:
00093 ny += ddy;
00094 nx -= ddx;
00095 break;
00096 }
00097 if(nx < min_x) nx = min_x;
00098 if(ny < min_y) ny = min_y;
00099 if(nx >= max_x) nx = max_x - 1;
00100 if(ny >= max_y) ny = max_y - 1;
00101 SetPosition(nx, ny);
00102 }
00103 }
00104
00105 void MainChar::ChangeDirection(direction direction2)
00106 {
00107 charDirection = direction2;
00108 int add;
00109
00110 if (shooting == 0) add = 0;
00111 else if (shooting == 1) add = FRM_SHOOT_RIGHT01;
00112 else if (shooting == 2) add = FRM_SHOOT_RIGHT01;
00113
00114 sprite->SetFrame((int)direction2 + add);
00115 }
00116
00117 void MainChar::setLook(int CursorX, int CursorY)
00118 {
00119 if (walkDirection != NO_DIRECTION)
00120 return;
00121
00122 double den = (CursorX - (sprite->GetX() + sprite->GetWidth() / 2));
00123 double angle;
00124 if ((int)(den * 1000) == 0) {
00125 if (CursorY < (sprite->GetY() + sprite->GetHeight() / 2))
00126 angle = 270;
00127 else
00128 angle = 90;
00129 } else {
00130 radian rad =
00131 NNCMath::ArcTan((CursorY - (sprite->GetY() + sprite->GetHeight() / 2)) / (den));
00132
00133 angle = rad.value * 180.0 / NNCMath::PI;
00134
00135
00136 }
00137
00138 if (angle < 0 && (CursorX > (sprite->GetX() + (sprite->GetWidth() / 2)))) {
00139 angle = 360 - -angle;
00140 } else if (angle >= 0 && (CursorX > (sprite->GetX() + (sprite->GetWidth() / 2)))) {
00141
00142 } else if (angle >= 0 && (CursorX < (sprite->GetX() + (sprite->GetWidth() / 2)))) {
00143 angle = 180.0 + angle;
00144 } else if (angle < 0 && (CursorX < (sprite->GetX() + (sprite->GetWidth() / 2)))) {
00145 angle = 180 - -angle;
00146 }
00147
00148 if (angle < 22.5) {
00149 ChangeDirection(EAST);
00150 } else if (angle < 67.5) {
00151 ChangeDirection(NORTHEAST);
00152 } else if (angle < 112.5) {
00153 ChangeDirection(NORTH);
00154 } else if (angle < 157.5) {
00155 ChangeDirection(NORTHWEST);
00156 } else if (angle < 202.5) {
00157 ChangeDirection(WEST);
00158 } else if (angle < 247.5) {
00159 ChangeDirection(SOUTHWEST);
00160 } else if (angle < 292.5) {
00161 ChangeDirection(SOUTH);
00162 } else if (angle < 337.5) {
00163 ChangeDirection(SOUTHEAST);
00164 } else {
00165 ChangeDirection(EAST);
00166 }
00167 }
00168
00169
00170 void MainChar::setWalking(bool e, bool s, bool w, bool n, bool shoot_change)
00171 {
00172 int sum = (e ? 1 : 0) |
00173 ((s ? 1 : 0) << 1) | ((w ? 1 : 0) << 2) | ((n ? 1 : 0) << 3);
00174 int add;
00175
00176 if (shooting == 0) add = 0;
00177 else if (shooting == 1) add = FRM_SHOOT_RIGHT01;
00178 else if (shooting == 2) add = FRM_SHOOT_RIGHT01;
00179
00180 direction dirs[16] = {
00181 NO_DIRECTION,
00182 EAST,
00183 SOUTH,
00184 SOUTHEAST,
00185 WEST,
00186 NO_DIRECTION,
00187 SOUTHWEST,
00188 SOUTH,
00189 NORTH,
00190 NORTHEAST,
00191 NO_DIRECTION,
00192 EAST,
00193 NORTHWEST,
00194 NORTH,
00195 WEST,
00196 NO_DIRECTION
00197 };
00198
00199 direction nd = dirs[sum];
00200 if ((walkDirection != nd) || shoot_change) {
00201 walking = true;
00202 int offset = 0;
00203
00204 if (walkDirection != NO_DIRECTION) {
00205 offset = sprite->GetFrame();
00206
00207 if (offset <= FRM_SHOOT_RIGHT01) offset -= 8;
00208
00209 else if (offset <= FRM_SHOOT_LEFT01) offset -= 48;
00210
00211 else offset -= 88;
00212
00213 if (offset < 0) offset = 0;
00214
00215 offset = offset % FRAME_WALK_COUNT;
00216 } else lastwalk = Util_GetTime();
00217
00218 walkDirection = dirs[sum];
00219 if (walkDirection == NORTH) {
00220 sprite->SetFrame(36 + add + offset);
00221 sprite->ReverseAnimation(false);
00222 sprite->SetAnimationStartFrame(36 + add);
00223 sprite->SetAnimationEndFrame(40 + add);
00224 sprite->EnableAnimation(true);
00225 } else if (walkDirection == NORTHEAST) {
00226 sprite->SetFrame(24 + add + offset);
00227 sprite->ReverseAnimation(false);
00228 sprite->SetAnimationStartFrame(24 + add);
00229 sprite->SetAnimationEndFrame(28 + add);
00230 sprite->EnableAnimation(true);
00231 } else if (walkDirection == SOUTHWEST) {
00232 sprite->SetFrame(12 + add + offset);
00233 sprite->ReverseAnimation(false);
00234 sprite->SetAnimationStartFrame(12 + add);
00235 sprite->SetAnimationEndFrame(16 + add);
00236 sprite->EnableAnimation(true);
00237 } else if (walkDirection == SOUTH) {
00238 sprite->SetFrame(8 + add + offset);
00239 sprite->ReverseAnimation(false);
00240 sprite->SetAnimationStartFrame(8 + add);
00241 sprite->SetAnimationEndFrame(12 + add);
00242 sprite->EnableAnimation(true);
00243 } else if (walkDirection == SOUTHEAST) {
00244 sprite->SetFrame(16 + add + offset);
00245 sprite->ReverseAnimation(false);
00246 sprite->SetAnimationStartFrame(16 + add);
00247 sprite->SetAnimationEndFrame(20 + add);
00248 sprite->EnableAnimation(true);
00249 } else if (walkDirection == NORTHWEST) {
00250 sprite->SetFrame(20 + add + offset);
00251 sprite->ReverseAnimation(false);
00252 sprite->SetAnimationStartFrame(20 + add);
00253 sprite->SetAnimationEndFrame(24 + add);
00254 sprite->EnableAnimation(true);
00255 } else if (walkDirection == WEST) {
00256 sprite->SetFrame(28 + add + offset);
00257 sprite->ReverseAnimation(false);
00258 sprite->SetAnimationStartFrame(28 + add);
00259 sprite->SetAnimationEndFrame(32 + add);
00260 sprite->EnableAnimation(true);
00261 } else if (walkDirection == EAST) {
00262 sprite->SetFrame(32 + add + offset);
00263 sprite->ReverseAnimation(false);
00264 sprite->SetAnimationStartFrame(32 + add);
00265 sprite->SetAnimationEndFrame(36 + add);
00266 sprite->EnableAnimation(true);
00267 } else {
00268 sprite->EnableAnimation(false);
00269 walking = false;
00270 }
00271
00272 }
00273 }
00274
00275 bool MainChar::isWalking() {
00276 if (walking) return true;
00277 return false;
00278 }
00279
00280 int MainChar::FireWeapon()
00281 {
00282 float newx, newy;
00283 radian r;
00284
00285 r.value = Util_Random((int)(NNCMath::TWO_PI * 1000)) / 1000.0;
00286 double apl = Util_Random( OM.GetCrosshair()->getSprite()->GetWidth() ) * 1;
00287
00288 newx = (float) (apl * NNCMath::Cos(r) + OM.GetCrosshair()->GetX());
00289 newy = (float) (apl * NNCMath::Sin(r) + OM.GetCrosshair()->GetY());
00290
00291
00292
00293 OM.GetSubWorld()->ScreenToSubWorld (newx, newy);
00294
00295
00296 ExplodeObject *obj = (ExplodeObject *)OM.AddObject(OT_EXPLODE);
00297 obj->SetPosition(newx, newy);
00298 obj->SetStrength(GetWeaponStrength());
00299
00300 float crossx = (float)OM.GetCrosshair()->GetX();
00301 float crossy = (float)OM.GetCrosshair()->GetY();
00302
00303
00304 if (walkDirection == NO_DIRECTION)
00305 setLook ( (int)(crossx + 0.5) , (int)(crossy + 0.5) );
00306 else {
00307 if (shooting == 0) {
00308 shooting = 1;
00309
00310 int wd = walkDirection;
00311
00312 setWalking ((wd & 0x01) ? true : false,
00313 (wd & 0x02) ? true : false,
00314 (wd & 0x04) ? true : false,
00315 (wd & 0x08) ? true : false,
00316 true);
00317
00318 lastshoot = Util_GetTime();
00319 return 0;
00320 }
00321 }
00322
00323 lastshoot = Util_GetTime();
00324 if (shooting == 1) shooting = 2;
00325 else shooting = 1;
00326
00327 return 0;
00328 }
00329
00330 void MainChar::SetWeaponStrength(double s)
00331 {
00332 weapon_strength = s;
00333 }
00334
00335
00336 int MainChar::Recenter()
00337 {
00338 Background &BKG = OM.GetSubWorld()->GetBackground();
00339
00340 if (sprite) {
00341 return sprite->SetPosition (BKG.GetScreenWidth()/2-sprite->GetWidth()/2,
00342 BKG.GetScreenHeight()/2-sprite->GetHeight()/2);
00343 }
00344 return 0;
00345 }