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