1 /* 2 Copyright (C) 2003, 2010 - Wolfire Games 3 Copyright (C) 2010-2017 - Lugaru contributors (see AUTHORS file) 4 5 This file is part of Lugaru. 6 7 Lugaru is free software; you can redistribute it and/or modify 8 it under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2 of the License, or 10 (at your option) any later version. 11 12 Lugaru is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Lugaru. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 #ifndef _PERSON_HPP_ 22 #define _PERSON_HPP_ 23 24 #include "Animation/Animation.hpp" 25 #include "Animation/Skeleton.hpp" 26 #include "Environment/Terrain.hpp" 27 #include "Graphic/Models.hpp" 28 #include "Graphic/Sprite.hpp" 29 #include "Graphic/gamegl.hpp" 30 #include "Math/XYZ.hpp" 31 #include "Objects/PersonType.hpp" 32 #include "Objects/Weapons.hpp" 33 34 #include <cmath> 35 #include <memory> 36 37 #define passivetype 0 38 #define guardtype 1 39 #define searchtype 2 40 #define attacktype 3 41 #define attacktypecutoff 4 42 #define playercontrolled 5 43 #define gethelptype 6 44 #define getweapontype 7 45 #define pathfindtype 8 46 47 struct InvalidPersonException : public exception 48 { whatInvalidPersonException49 const char* what() const throw() 50 { 51 return "Invalid weapon number"; 52 } 53 }; 54 55 class Person : public enable_shared_from_this<Person> 56 { 57 private: 58 float proportions[4]; 59 60 public: 61 static std::vector<std::shared_ptr<Person>> players; 62 63 int whichpatchx; 64 int whichpatchz; 65 66 // animCurrent and animTarget are used to interpolate between different animations 67 // (and for a bunch of other things). 68 // animations interpolate with one another at various speeds. 69 // animTarget seems to determine the combat state? 70 int animCurrent; 71 int animTarget; 72 73 // frameCurrent and frameTarget are used to interpolate between the frames of an animation 74 // (e.g. the crouched animation has only two frames, lerped back and forth slowly). 75 // animations advance at various speeds. 76 int frameCurrent; 77 int frameTarget; 78 79 int oldanimCurrent; 80 int oldanimTarget; 81 int oldframeCurrent; 82 int oldframeTarget; 83 84 int howactive; 85 86 float parriedrecently; 87 88 bool superruntoggle; 89 90 int lastattack, lastattack2, lastattack3; 91 92 XYZ currentoffset, targetoffset, offset; 93 float target; 94 float transspeed; 95 96 XYZ realoldcoords; 97 XYZ oldcoords; 98 XYZ coords; 99 XYZ velocity; 100 101 float unconscioustime; 102 103 bool immobile; 104 105 float velspeed; 106 float targetyaw; 107 float targetrot; 108 float rot; 109 float oldrot; 110 float lookyaw; 111 float lookpitch; 112 float yaw; 113 float pitch; 114 float lowyaw; 115 float tilt; 116 float targettilt; 117 float tilt2; 118 float targettilt2; 119 bool rabbitkickenabled; 120 121 float bloodloss; 122 float bleeddelay; 123 float skiddelay; 124 float skiddingdelay; 125 float deathbleeding; 126 float tempdeltav; 127 128 float damagetolerance; 129 float damage; 130 float permanentdamage; 131 float superpermanentdamage; 132 float lastcollide; 133 /* Seems to be 0 = alive, 1 = unconscious, 2 = dead */ 134 int dead; 135 136 float jumppower; 137 bool onground; 138 139 int wentforweapon; 140 141 bool calcrot; 142 143 XYZ facing; 144 145 float bleeding; 146 float bleedx, bleedy; 147 int direction; 148 float texupdatedelay; 149 150 float headyaw, headpitch; 151 float targetheadyaw, targetheadpitch; 152 153 bool onterrain; 154 bool pause; 155 156 float grabdelay; 157 158 std::shared_ptr<Person> victim; 159 bool hasvictim; 160 161 float updatedelay; 162 float normalsupdatedelay; 163 164 bool jumpstart; 165 166 bool forwardkeydown; 167 bool forwardstogglekeydown; 168 bool rightkeydown; 169 bool leftkeydown; 170 bool backkeydown; 171 bool jumpkeydown; 172 bool jumptogglekeydown; 173 bool crouchkeydown; 174 bool crouchtogglekeydown; 175 bool drawkeydown; 176 bool drawtogglekeydown; 177 bool throwkeydown; 178 bool throwtogglekeydown; 179 bool attackkeydown; 180 bool feint; 181 bool lastfeint; 182 bool headless; 183 184 float crouchkeydowntime; 185 float jumpkeydowntime; 186 bool freefall; 187 188 float turnspeed; 189 190 int aitype; 191 float aiupdatedelay; 192 float losupdatedelay; 193 int ally; 194 float collide; 195 float collided; 196 float avoidcollided; 197 bool loaded; 198 bool whichdirection; 199 float whichdirectiondelay; 200 bool avoidsomething; 201 XYZ avoidwhere; 202 float blooddimamount; 203 204 float staggerdelay; 205 float blinkdelay; 206 float twitchdelay; 207 float twitchdelay2; 208 float twitchdelay3; 209 float lefthandmorphness; 210 float righthandmorphness; 211 float headmorphness; 212 float chestmorphness; 213 float tailmorphness; 214 float targetlefthandmorphness; 215 float targetrighthandmorphness; 216 float targetheadmorphness; 217 float targetchestmorphness; 218 float targettailmorphness; 219 int lefthandmorphstart, lefthandmorphend; 220 int righthandmorphstart, righthandmorphend; 221 int headmorphstart, headmorphend; 222 int chestmorphstart, chestmorphend; 223 int tailmorphstart, tailmorphend; 224 225 float weaponmissdelay; 226 float highreversaldelay; 227 float lowreversaldelay; 228 229 int creature; 230 231 unsigned id; 232 233 Skeleton skeleton; 234 235 float speed; 236 float scale; 237 float power; 238 float speedmult; 239 240 float protectionhead; 241 float protectionhigh; 242 float protectionlow; 243 float armorhead; 244 float armorhigh; 245 float armorlow; 246 bool metalhead; 247 bool metalhigh; 248 bool metallow; 249 250 int numclothes; 251 char clothes[10][256]; 252 float clothestintr[10]; 253 float clothestintg[10]; 254 float clothestintb[10]; 255 256 bool landhard; 257 bool bled; 258 bool spurt; 259 bool onfire; 260 float onfiredelay; 261 float burnt; 262 263 float flamedelay; 264 265 int playerdetail; 266 267 int num_weapons; 268 int weaponids[4]; 269 /* Key of weaponids which is the weapon in hand, if any. -1 otherwise. 270 * Always 0 or -1 as activeweapon is moved to position 0 when taken */ 271 int weaponactive; 272 int weaponstuck; 273 /* 0 or 1 to say if weapon is stuck in the front or the back */ 274 int weaponstuckwhere; 275 276 int numwaypoints; 277 XYZ waypoints[90]; 278 int waypointtype[90]; 279 float pausetime; 280 281 XYZ headtarget; 282 float interestdelay; 283 284 XYZ finalfinaltarget; 285 XYZ finaltarget; 286 int finalpathfindpoint; 287 int targetpathfindpoint; 288 int lastpathfindpoint; 289 int lastpathfindpoint2; 290 int lastpathfindpoint3; 291 int lastpathfindpoint4; 292 293 int waypoint; 294 295 XYZ lastseen; 296 float lastseentime; 297 float lastchecktime; 298 float stunned; 299 float surprised; 300 float runninghowlong; 301 int occluded; 302 int lastoccluded; 303 int laststanding; 304 int escapednum; 305 306 float speechdelay; 307 float neckspurtdelay; 308 float neckspurtparticledelay; 309 float neckspurtamount; 310 311 int whichskin; 312 bool rabbitkickragdoll; 313 314 Animation tempanimation; 315 316 bool jumpclimb; 317 318 Person(); 319 Person(FILE*, int, unsigned); 320 321 void skeletonLoad(bool clothes = false); 322 323 // convenience functions joint(int bodypart)324 inline Joint& joint(int bodypart) { return skeleton.joints[skeleton.jointlabels[bodypart]]; } jointPos(int bodypart)325 inline XYZ& jointPos(int bodypart) { return joint(bodypart).position; } jointVel(int bodypart)326 inline XYZ& jointVel(int bodypart) { return joint(bodypart).velocity; } currentFrame()327 AnimationFrame& currentFrame() { 328 /* FIXME - try/catch is a temporary fix to avoid crashes but game logic should be fixed instead */ 329 try { 330 return Animation::animations.at(animCurrent).frames.at(frameCurrent); 331 } catch (const std::exception& error) { 332 /* Most likely frameCurrent is too big, work around */ 333 if ((unsigned)frameCurrent >= 334 Animation::animations.at(animCurrent).frames.size()) { 335 frameCurrent = Animation::animations.at(animCurrent).frames.size() - 1; 336 } 337 return Animation::animations.at(animCurrent).frames.back(); 338 } 339 } targetFrame()340 AnimationFrame& targetFrame() { 341 /* FIXME - try/catch is a temporary fix to avoid crashes but game logic should be fixed instead */ 342 try { 343 return Animation::animations.at(animTarget).frames.at(frameTarget); 344 } catch (const std::exception& error) { 345 /* Most likely frameTarget is too big, work around */ 346 if ((unsigned)frameTarget >= 347 Animation::animations.at(animTarget).frames.size()) { 348 frameTarget = Animation::animations.at(animTarget).frames.size() - 1; 349 } 350 return Animation::animations.at(animTarget).frames.back(); 351 } 352 } 353 354 void setProportions(float head, float body, float arms, float legs); 355 float getProportion(int part) const; 356 XYZ getProportionXYZ(int part) const; 357 358 void CheckKick(); 359 void CatchFire(); 360 void DoBlood(float howmuch, int which); 361 void DoBloodBig(float howmuch, int which); 362 bool DoBloodBigWhere(float howmuch, int which, XYZ where); 363 wasIdle()364 bool wasIdle() { return animation_bits[animCurrent] & ab_idle; } isIdle()365 bool isIdle() { return animation_bits[animTarget] & ab_idle; } 366 int getIdle(); 367 isSitting()368 bool isSitting() { return animation_bits[animTarget] & ab_sit; } 369 isSleeping()370 bool isSleeping() { return animation_bits[animTarget] & ab_sleep; } 371 wasCrouch()372 bool wasCrouch() { return animation_bits[animCurrent] & ab_crouch; } isCrouch()373 bool isCrouch() { return animation_bits[animTarget] & ab_crouch; } 374 int getCrouch(); 375 wasStop()376 bool wasStop() { return animation_bits[animCurrent] & ab_stop; } isStop()377 bool isStop() { return animation_bits[animTarget] & ab_stop; } 378 int getStop(); 379 380 bool wasSneak(); 381 bool isSneak(); 382 int getSneak(); 383 wasRun()384 bool wasRun() { return animation_bits[animCurrent] & ab_run; } isRun()385 bool isRun() { return animation_bits[animTarget] & ab_run; } 386 int getRun(); 387 wasLanding()388 bool wasLanding() { return animation_bits[animCurrent] & ab_land; } isLanding()389 bool isLanding() { return animation_bits[animTarget] & ab_land; } 390 int getLanding(); 391 wasLandhard()392 bool wasLandhard() { return animation_bits[animCurrent] & ab_landhard; } isLandhard()393 bool isLandhard() { return animation_bits[animTarget] & ab_landhard; } 394 int getLandhard(); 395 wasFlip()396 bool wasFlip() { return animation_bits[animCurrent] & ab_flip; } isFlip()397 bool isFlip() { return animation_bits[animTarget] & ab_flip; } 398 isWallJump()399 bool isWallJump() { return animation_bits[animTarget] & ab_walljump; } 400 void Reverse(); 401 void DoDamage(float howmuch); 402 void DoHead(); DoMipmaps()403 void DoMipmaps() 404 { 405 skeleton.drawmodel.textureptr.bind(); 406 glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); 407 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, skeleton.skinsize, skeleton.skinsize, 0, GL_RGB, GL_UNSIGNED_BYTE, &skeleton.skinText[0]); 408 } 409 410 int SphereCheck(XYZ* p1, float radius, XYZ* p, XYZ* move, float* rotate, Model* model); 411 int DrawSkeleton(); 412 void Puff(int whichlabel); 413 void FootLand(bodypart whichfoot, float opacity); 414 void DoStuff(); 415 void setTargetAnimation(int); 416 void DoAnimations(); 417 void RagDoll(bool checkcollision); 418 419 void takeWeapon(int weaponId); 420 421 bool addClothes(const int& clothesId); 422 void addClothes(); 423 424 void doAI(); 425 }; 426 427 const int maxplayers = 10; 428 429 #endif 430