2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
5 This file is part of Lugaru.
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.
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.
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/>.
21 // Enable full math definitions
22 #define _USE_MATH_DEFINES
26 #include "Animation/Animation.hpp"
27 #include "Audio/openal_wrapper.hpp"
28 #include "Devtools/ConsoleCmds.hpp"
29 #include "Level/Awards.hpp"
30 #include "Level/Campaign.hpp"
31 #include "Level/Dialog.hpp"
32 #include "Level/Hotspot.hpp"
33 #include "Menu/Menu.hpp"
34 #include "User/Settings.hpp"
35 #include "Utils/Folders.hpp"
36 #include "Utils/Input.hpp"
40 #include <sys/types.h>
56 // Added more evilness needed for MSVC
58 #define strncasecmp(s1, s2, n) _strnicmp(s1, s2, n)
59 #define snprintf(buf, size, format, ...) _sprintf_p(buf, size, format)
63 extern float multiplier;
65 extern int environment;
66 extern Terrain terrain;
67 extern float screenwidth, screenheight;
70 extern float texdetail;
72 extern float slomodelay;
73 extern bool floatjump;
76 extern float camerashake;
78 extern float blackout;
79 extern bool cellophane;
80 extern bool musictoggle;
81 extern int difficulty;
82 extern int bloodtoggle;
83 extern bool invertmouse;
85 extern float precipdelay;
86 extern XYZ viewerfacing;
87 extern bool ambientsound;
88 extern bool mousejump;
89 extern float viewdistance;
91 extern XYZ windvector;
95 extern int oldmainmenu;
96 extern bool visibleloading;
97 extern XYZ envsound[30];
98 extern float envsoundvol[30];
99 extern int numenvsounds;
100 extern float envsoundlife[30];
101 extern float usermousesensitivity;
102 extern bool ismotionblur;
103 extern bool showdamagebar; // (des)activate the damage bar
105 extern bool skyboxtexture;
106 extern float skyboxr;
107 extern float skyboxg;
108 extern float skyboxb;
109 extern float skyboxlightr;
110 extern float skyboxlightg;
111 extern float skyboxlightb;
112 extern float fadestart;
113 extern float slomospeed;
114 extern float slomofreq;
115 extern int tutoriallevel;
116 extern float smoketex;
117 extern float tutorialstagetime;
118 extern int tutorialstage;
119 extern float tutorialmaxtime;
120 extern float tutorialsuccess;
121 extern bool againbonus;
122 extern bool reversaltrain;
123 extern bool canattack;
124 extern bool cananger;
125 extern float damagedealt;
127 extern int editoractive;
128 extern int editorpathtype;
130 extern float hostiletime;
132 extern bool gamestarted;
136 extern bool stillloading;
137 extern bool winfreeze;
139 extern bool campaign;
141 extern void toggleFullscreen();
145 bool winhotspot = false;
146 bool windialogue = false;
149 float cameradist = 0;
150 bool oldattackkey = 0;
152 float musicvolume[4] = {};
153 float oldmusicvolume[4] = {};
154 int musicselected = 0;
156 const char *rabbitskin[] = {
161 "Textures/Otter.jpg",
163 "Textures/Sable.jpg",
164 "Textures/Chocolate.jpg",
169 const char *wolfskin[] = {
171 "Textures/DarkWolf.jpg",
172 "Textures/SnowWolf.jpg"
175 const char **creatureskin[] = {rabbitskin, wolfskin};
177 #define STATIC_ASSERT(x) extern int s_a_dummy[2 * (!!(x)) - 1];
178 STATIC_ASSERT (rabbittype == 0 && wolftype == 1)
182 // TODO: this is slightly incorrect
183 inline float roughDirection(XYZ vec)
186 float angle = -asin(-vec.x) * 180 / M_PI;
191 inline float roughDirectionTo(XYZ start, XYZ end)
193 return roughDirection(end - start);
195 inline float pitchOf(XYZ vec)
198 return -asin(vec.y) * 180 / M_PI;
200 inline float pitchTo(XYZ start, XYZ end)
202 return pitchOf(end - start);
204 inline float sq(float n)
208 inline float stepTowardf(float from, float to, float by)
210 if (fabs(from - to) < by)
218 void Game::playdialoguescenesound()
221 temppos = Person::players[Dialog::currentScene().participantfocus]->coords;
222 temppos = temppos - viewer;
227 switch (Dialog::currentScene().sound) {
232 sound = consolefailsound;
235 sound = consolesuccesssound;
238 sound = firestartsound;
241 sound = fireendsound;
244 sound = rabbitchitter;
247 sound = rabbitchitter2;
250 sound = rabbitpainsound;
253 sound = rabbitpain1sound;
256 sound = rabbitattacksound;
259 sound = rabbitattack2sound;
262 sound = rabbitattack3sound;
265 sound = rabbitattack4sound;
289 sound = barkgrowlsound;
295 emit_sound_at(sound, temppos);
298 // ================================================================
300 int Game::findClosestPlayer()
303 float closestdist = std::numeric_limits<float>::max();
305 for (unsigned i = 1; i < Person::players.size(); i++) {
306 float distance = distsq(&Person::players[i]->coords, &Person::players[0]->coords);
307 if (distance < closestdist) {
308 closestdist = distance;
315 static int findClosestObject()
318 float closestdist = std::numeric_limits<float>::max();
320 for (int i = 0; i < Object::objects.size(); i++) {
321 float distance = distsq(&Object::objects[i]->position, &Person::players[0]->coords);
322 if (distance < closestdist) {
323 closestdist = distance;
330 static void cmd_dispatch(const string cmd)
332 int i, n_cmds = sizeof(cmd_names) / sizeof(cmd_names[0]);
334 for (i = 0; i < n_cmds; i++)
335 if (cmd.substr(0, cmd.find(' ')) == string(cmd_names[i])) {
336 cout << "|" << cmd.substr(cmd.find(' ') + 1) << "|" << endl;
337 cmd_handlers[i](cmd.substr(cmd.find(' ') + 1).c_str());
340 emit_sound_np(i < n_cmds ? consolesuccesssound : consolefailsound);
343 /********************> Tick() <*****/
344 extern bool save_screenshot(const char * fname);
345 void Screenshot (void)
348 time_t t = time(NULL);
349 struct tm *tme = localtime(&t);
350 sprintf(filename, "Screenshot-%04d%02d%02d-%02d%02d%02d.png",
351 tme->tm_year + 1900, tme->tm_mon + 1, tme->tm_mday, tme->tm_hour, tme->tm_min, tme->tm_sec);
353 save_screenshot(filename);
356 void Game::SetUpLighting()
358 if (environment == snowyenvironment)
359 light.setColors(.65, .65, .7, .4, .4, .44);
360 if (environment == desertenvironment)
361 light.setColors(.95, .95, .95, .4, .35, .3);
362 if (environment == grassyenvironment)
363 light.setColors(.95, .95, 1, .4, .4, .44);
365 light.setColors(1, 1, 1, .4, .4, .4);
367 average = (skyboxlightr + skyboxlightg + skyboxlightb) / 3;
368 light.color[0] *= (skyboxlightr + average) / 2;
369 light.color[1] *= (skyboxlightg + average) / 2;
370 light.color[2] *= (skyboxlightb + average) / 2;
371 light.ambient[0] *= (skyboxlightr + average) / 2;
372 light.ambient[1] *= (skyboxlightg + average) / 2;
373 light.ambient[2] *= (skyboxlightb + average) / 2;
376 int findPathDist(int start, int end)
378 int smallestcount, count, connected;
379 int last, last2, last3, last4;
382 smallestcount = 1000;
383 for (int i = 0; i < 50; i++) {
389 while (last != end && count < 30) {
391 for (int j = 0; j < numpathpoints; j++) {
392 if (j != last && j != last2 && j != last3 && j != last4) {
394 if (numpathpointconnect[j])
395 for (int k = 0; k < numpathpointconnect[j]; k++) {
396 if (pathpointconnect[j][k] == last)connected = 1;
399 if (numpathpointconnect[last])
400 for (int k = 0; k < numpathpointconnect[last]; k++) {
401 if (pathpointconnect[last][k] == j)connected = 1;
404 if (closest == -1 || Random() % 2 == 0) {
415 if (count < smallestcount)
416 smallestcount = count;
418 return smallestcount;
421 int Game::checkcollide(XYZ startpoint, XYZ endpoint)
423 static XYZ colpoint, colviewer, coltarget;
424 static float minx, minz, maxx, maxz, miny, maxy;
426 minx = min(startpoint.x, endpoint.x) - 1;
427 miny = min(startpoint.y, endpoint.y) - 1;
428 minz = min(startpoint.z, endpoint.z) - 1;
429 maxx = max(startpoint.x, endpoint.x) + 1;
430 maxy = max(startpoint.y, endpoint.y) + 1;
431 maxz = max(startpoint.z, endpoint.z) + 1;
433 for (int i = 0; i < Object::objects.size(); i++) {
434 if ( Object::objects[i]->position.x > minx - Object::objects[i]->model.boundingsphereradius &&
435 Object::objects[i]->position.x < maxx + Object::objects[i]->model.boundingsphereradius &&
436 Object::objects[i]->position.y > miny - Object::objects[i]->model.boundingsphereradius &&
437 Object::objects[i]->position.y < maxy + Object::objects[i]->model.boundingsphereradius &&
438 Object::objects[i]->position.z > minz - Object::objects[i]->model.boundingsphereradius &&
439 Object::objects[i]->position.z < maxz + Object::objects[i]->model.boundingsphereradius) {
440 if ( Object::objects[i]->type != treeleavestype &&
441 Object::objects[i]->type != bushtype &&
442 Object::objects[i]->type != firetype) {
443 colviewer = startpoint;
444 coltarget = endpoint;
445 if (Object::objects[i]->model.LineCheck(&colviewer, &coltarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
454 int Game::checkcollide(XYZ startpoint, XYZ endpoint, int what)
456 static XYZ colpoint, colviewer, coltarget;
457 static float minx, minz, maxx, maxz, miny, maxy;
458 static int i; //FIXME: see below
460 minx = min(startpoint.x, endpoint.x) - 1;
461 miny = min(startpoint.y, endpoint.y) - 1;
462 minz = min(startpoint.z, endpoint.z) - 1;
463 maxx = max(startpoint.x, endpoint.x) + 1;
464 maxy = max(startpoint.y, endpoint.y) + 1;
465 maxz = max(startpoint.z, endpoint.z) + 1;
468 if ( Object::objects[what]->position.x > minx - Object::objects[what]->model.boundingsphereradius &&
469 Object::objects[what]->position.x < maxx + Object::objects[what]->model.boundingsphereradius &&
470 Object::objects[what]->position.y > miny - Object::objects[what]->model.boundingsphereradius &&
471 Object::objects[what]->position.y < maxy + Object::objects[what]->model.boundingsphereradius &&
472 Object::objects[what]->position.z > minz - Object::objects[what]->model.boundingsphereradius &&
473 Object::objects[what]->position.z < maxz + Object::objects[what]->model.boundingsphereradius) {
474 if ( Object::objects[what]->type != treeleavestype &&
475 Object::objects[what]->type != bushtype &&
476 Object::objects[what]->type != firetype) {
477 colviewer = startpoint;
478 coltarget = endpoint;
480 if (Object::objects[what]->model.LineCheck(&colviewer, &coltarget, &colpoint, &Object::objects[what]->position, &Object::objects[what]->yaw) != -1)
487 if (terrain.lineTerrain(startpoint, endpoint, &colpoint) != -1)
493 void Setenvironment(int which)
497 LOG(" Setting environment...");
502 pause_sound(stream_snowtheme);
503 pause_sound(stream_grasstheme);
504 pause_sound(stream_deserttheme);
505 pause_sound(stream_wind);
506 pause_sound(stream_desertambient);
509 if (environment == snowyenvironment) {
513 emit_stream_np(stream_wind);
515 Object::treetextureptr.load("Textures/SnowTree.png", 0);
516 Object::bushtextureptr.load("Textures/BushSnow.png", 0);
517 Object::rocktextureptr.load("Textures/BoulderSnow.jpg", 1);
518 Object::boxtextureptr.load("Textures/SnowBox.jpg", 1);
520 footstepsound = footstepsn1;
521 footstepsound2 = footstepsn2;
522 footstepsound3 = footstepst1;
523 footstepsound4 = footstepst2;
525 terraintexture.load("Textures/Snow.jpg", 1);
526 terraintexture2.load("Textures/Rock.jpg", 1);
529 temptexdetail = texdetail;
532 skybox->load( "Textures/Skybox(snow)/Front.jpg",
533 "Textures/Skybox(snow)/Left.jpg",
534 "Textures/Skybox(snow)/Back.jpg",
535 "Textures/Skybox(snow)/Right.jpg",
536 "Textures/Skybox(snow)/Up.jpg",
537 "Textures/Skybox(snow)/Down.jpg");
542 texdetail = temptexdetail;
543 } else if (environment == desertenvironment) {
546 Object::treetextureptr.load("Textures/DesertTree.png", 0);
547 Object::bushtextureptr.load("Textures/BushDesert.png", 0);
548 Object::rocktextureptr.load("Textures/BoulderDesert.jpg", 1);
549 Object::boxtextureptr.load("Textures/DesertBox.jpg", 1);
553 emit_stream_np(stream_desertambient);
555 footstepsound = footstepsn1;
556 footstepsound2 = footstepsn2;
557 footstepsound3 = footstepsn1;
558 footstepsound4 = footstepsn2;
560 terraintexture.load("Textures/Sand.jpg", 1);
561 terraintexture2.load("Textures/SandSlope.jpg", 1);
564 temptexdetail = texdetail;
567 skybox->load( "Textures/Skybox(sand)/Front.jpg",
568 "Textures/Skybox(sand)/Left.jpg",
569 "Textures/Skybox(sand)/Back.jpg",
570 "Textures/Skybox(sand)/Right.jpg",
571 "Textures/Skybox(sand)/Up.jpg",
572 "Textures/Skybox(sand)/Down.jpg");
577 texdetail = temptexdetail;
578 } else if (environment == grassyenvironment) {
581 Object::treetextureptr.load("Textures/Tree.png", 0);
582 Object::bushtextureptr.load("Textures/Bush.png", 0);
583 Object::rocktextureptr.load("Textures/Boulder.jpg", 1);
584 Object::boxtextureptr.load("Textures/GrassBox.jpg", 1);
587 emit_stream_np(stream_wind, 100.);
589 footstepsound = footstepgr1;
590 footstepsound2 = footstepgr2;
591 footstepsound3 = footstepst1;
592 footstepsound4 = footstepst2;
594 terraintexture.load("Textures/GrassDirt.jpg", 1);
595 terraintexture2.load("Textures/MossRock.jpg", 1);
598 temptexdetail = texdetail;
601 skybox->load( "Textures/Skybox(grass)/Front.jpg",
602 "Textures/Skybox(grass)/Left.jpg",
603 "Textures/Skybox(grass)/Back.jpg",
604 "Textures/Skybox(grass)/Right.jpg",
605 "Textures/Skybox(grass)/Up.jpg",
606 "Textures/Skybox(grass)/Down.jpg");
610 texdetail = temptexdetail;
612 temptexdetail = texdetail;
614 terrain.load("Textures/HeightMap.png");
616 texdetail = temptexdetail;
619 void Game::Loadlevel(int which)
626 Loadlevel("tutorial");
627 } else if (which >= 0 && which <= 15) {
629 snprintf(buf, 32, "map%d", which + 1); // challenges
632 Loadlevel("mapsave");
635 void Game::Loadlevel(const std::string& name)
637 int indemo; // FIXME this should be removed
643 LOG(std::string("Loading level...") + name);
655 if (tutoriallevel != -1)
660 if (tutoriallevel == 1)
662 if (tutorialstage == 0) {
663 tutorialstagetime = 0;
666 pause_sound(whooshsound);
667 pause_sound(stream_firesound);
672 tfile = Folders::openMandatoryFile( Folders::getResourcePath("Maps/"+name), "rb" );
674 pause_sound(stream_firesound);
680 //~ Animation::animations[bounceidleanim].Load("Idle", middleheight, neutral);
682 Dialog::dialogs.clear();
684 Dialog::indialogue = -1;
690 if (Account::hasActive()) {
691 difficulty = Account::active().getDifficulty();
694 Hotspot::hotspots.clear();
695 Hotspot::current = -1;
706 for (int i = 0; i < 100; i++)
715 numunarmedattack = 0;
726 bonustotal = startbonustotal;
731 emit_sound_np(consolesuccesssound);
736 if (!stealthloading) {
737 terrain.numdecals = 0;
738 Sprite::deleteSprites();
740 for (int i = 0; i < subdivision; i++) {
741 for (int j = 0; j < subdivision; j++) {
742 terrain.patchobjectnum[i][j] = 0;
750 Person::players.resize(1);
752 funpackf(tfile, "Bi", &mapvers);
754 cerr << name << " has obsolete map version " << mapvers << endl;
757 funpackf(tfile, "Bi", &indemo);
761 funpackf(tfile, "Bi", &maptype);
763 maptype = mapkilleveryone;
765 funpackf(tfile, "Bi", &hostile);
769 funpackf(tfile, "Bf Bf", &viewdistance, &fadestart);
775 funpackf(tfile, "Bb Bf Bf Bf", &skyboxtexture, &skyboxr, &skyboxg, &skyboxb);
783 funpackf(tfile, "Bf Bf Bf", &skyboxlightr, &skyboxlightg, &skyboxlightb);
785 skyboxlightr = skyboxr;
786 skyboxlightg = skyboxg;
787 skyboxlightb = skyboxb;
789 /* TODO - This should be done in an other way so that we can rebuild main player as well (so coords would need to be copied from old ones after rebuilding) */
790 if (stealthloading) {
791 funpackf(tfile, "Bf Bf Bf Bf Bf Bi", &lamefloat, &lamefloat, &lamefloat, &lamefloat, &lamefloat, &Person::players[0]->num_weapons);
793 funpackf(tfile, "Bf Bf Bf Bf Bf Bi", &Person::players[0]->coords.x, &Person::players[0]->coords.y, &Person::players[0]->coords.z, &Person::players[0]->yaw, &Person::players[0]->targetyaw, &Person::players[0]->num_weapons);
795 if (Person::players[0]->num_weapons > 0 && Person::players[0]->num_weapons < 5)
796 for (int j = 0; j < Person::players[0]->num_weapons; j++) {
797 Person::players[0]->weaponids[j] = weapons.size();
799 funpackf(tfile, "Bi", &type);
800 weapons.push_back(Weapon(type, 0));
806 funpackf(tfile, "Bf Bf Bf", &Person::players[0]->armorhead, &Person::players[0]->armorhigh, &Person::players[0]->armorlow);
807 funpackf(tfile, "Bf Bf Bf", &Person::players[0]->protectionhead, &Person::players[0]->protectionhigh, &Person::players[0]->protectionlow);
808 funpackf(tfile, "Bf Bf Bf", &Person::players[0]->metalhead, &Person::players[0]->metalhigh, &Person::players[0]->metallow);
809 funpackf(tfile, "Bf Bf", &Person::players[0]->power, &Person::players[0]->speedmult);
811 funpackf(tfile, "Bi", &Person::players[0]->numclothes);
814 funpackf(tfile, "Bi Bi", &Person::players[0]->whichskin, &Person::players[0]->creature);
816 Person::players[0]->whichskin = 0;
817 Person::players[0]->creature = rabbittype;
820 Person::players[0]->lastattack = -1;
821 Person::players[0]->lastattack2 = -1;
822 Person::players[0]->lastattack3 = -1;
826 Dialog::loadDialogs(tfile);
829 for (int k = 0; k < Person::players[0]->numclothes; k++) {
830 funpackf(tfile, "Bi", &templength);
831 for (int l = 0; l < templength; l++)
832 funpackf(tfile, "Bb", &Person::players[0]->clothes[k][l]);
833 Person::players[0]->clothes[k][templength] = '\0';
834 funpackf(tfile, "Bf Bf Bf", &Person::players[0]->clothestintr[k], &Person::players[0]->clothestintg[k], &Person::players[0]->clothestintb[k]);
837 funpackf(tfile, "Bi", &environment);
839 Object::LoadObjectsFromFile(tfile, stealthloading);
843 funpackf(tfile, "Bi", &numhotspots);
844 if (numhotspots < 0) {
845 cerr << "Map " << name << " have an invalid number of hotspots" << endl;
848 Hotspot::hotspots.resize(numhotspots);
849 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
850 funpackf(tfile, "Bi Bf Bf Bf Bf", &Hotspot::hotspots[i].type, &Hotspot::hotspots[i].size, &Hotspot::hotspots[i].position.x, &Hotspot::hotspots[i].position.y, &Hotspot::hotspots[i].position.z);
851 funpackf(tfile, "Bi", &templength);
853 for (int l = 0; l < templength; l++)
854 funpackf(tfile, "Bb", &Hotspot::hotspots[i].text[l]);
855 Hotspot::hotspots[i].text[templength] = '\0';
856 if (Hotspot::hotspots[i].type == -111)
860 Hotspot::hotspots.clear();
866 if (!stealthloading) {
867 Object::ComputeCenter();
872 Object::ComputeRadius();
879 funpackf(tfile, "Bi", &numplayers);
880 if (numplayers > maxplayers) {
881 cout << "Warning: this level contains more players than allowed" << endl;
884 for (int i = 1; i < numplayers; i++) {
886 Person::players.push_back(shared_ptr<Person>(new Person(tfile, mapvers, j)));
888 } catch (InvalidPersonException e) {
889 cerr << "Invalid Person found in " << name << endl;
895 funpackf(tfile, "Bi", &numpathpoints);
896 if (numpathpoints > 30 || numpathpoints < 0)
898 for (int j = 0; j < numpathpoints; j++) {
899 funpackf(tfile, "Bf Bf Bf Bi", &pathpoint[j].x, &pathpoint[j].y, &pathpoint[j].z, &numpathpointconnect[j]);
900 for (int k = 0; k < numpathpointconnect[j]; k++) {
901 funpackf(tfile, "Bi", &pathpointconnect[j][k]);
907 funpackf(tfile, "Bf Bf Bf Bf", &mapcenter.x, &mapcenter.y, &mapcenter.z, &mapradius);
910 if (environment != oldenvironment)
911 Setenvironment(environment);
912 oldenvironment = environment;
914 if (!stealthloading) {
915 Object::AddObjectsToTerrain();
926 for (unsigned i = 0; i < Person::players.size(); i++) {
930 Person::players[i]->burnt = 0;
931 Person::players[i]->bled = 0;
932 Person::players[i]->onfire = 0;
933 Person::players[i]->scale = .2;
935 Person::players[i]->creature = rabbittype;
938 Person::players[i]->skeleton.free = 0;
940 Person::players[i]->skeletonLoad();
942 Person::players[i]->addClothes();
945 Person::players[i]->animCurrent = bounceidleanim;
946 Person::players[i]->animTarget = bounceidleanim;
947 Person::players[i]->frameCurrent = 0;
948 Person::players[i]->frameTarget = 1;
949 Person::players[i]->target = 0;
951 Person::players[i]->speed = 1 + (float)(Random() % 100) / 1000;
953 Person::players[i]->speed -= .2;
955 Person::players[i]->speed -= .1;
958 Person::players[i]->velocity = 0;
959 Person::players[i]->oldcoords = Person::players[i]->coords;
960 Person::players[i]->realoldcoords = Person::players[i]->coords;
962 Person::players[i]->id = i;
963 Person::players[i]->updatedelay = 0;
964 Person::players[i]->normalsupdatedelay = 0;
966 Person::players[i]->proportionhead = 1.2;
967 Person::players[i]->proportionbody = 1.05;
968 Person::players[i]->proportionarms = 1.00;
969 Person::players[i]->proportionlegs = 1.1;
970 Person::players[i]->proportionlegs.y = 1.05;
971 Person::players[i]->headless = 0;
972 Person::players[i]->currentoffset = 0;
973 Person::players[i]->targetoffset = 0;
974 if (Person::players[i]->creature == wolftype) {
975 Person::players[i]->scale = .23;
976 Person::players[i]->damagetolerance = 300;
978 Person::players[i]->damagetolerance = 200;
987 Person::players[i]->proportionhead.z = 0;
988 Person::players[i]->proportionbody.z = 0;
989 Person::players[i]->proportionarms.z = 0;
990 Person::players[i]->proportionlegs.z = 0;
993 Person::players[i]->tempanimation = Animation("Tempanim", lowheight, neutral);
996 Person::players[i]->headmorphness = 0;
997 Person::players[i]->targetheadmorphness = 1;
998 Person::players[i]->headmorphstart = 0;
999 Person::players[i]->headmorphend = 0;
1001 Person::players[i]->pausetime = 0;
1003 Person::players[i]->dead = 0;
1004 Person::players[i]->jumppower = 5;
1005 Person::players[i]->damage = 0;
1006 Person::players[i]->permanentdamage = 0;
1007 Person::players[i]->superpermanentdamage = 0;
1009 Person::players[i]->forwardkeydown = 0;
1010 Person::players[i]->leftkeydown = 0;
1011 Person::players[i]->backkeydown = 0;
1012 Person::players[i]->rightkeydown = 0;
1013 Person::players[i]->jumpkeydown = 0;
1014 Person::players[i]->crouchkeydown = 0;
1015 Person::players[i]->throwkeydown = 0;
1017 Person::players[i]->collided = -10;
1018 Person::players[i]->loaded = 1;
1019 Person::players[i]->bloodloss = 0;
1020 Person::players[i]->weaponactive = -1;
1021 Person::players[i]->weaponstuck = -1;
1022 Person::players[i]->bleeding = 0;
1023 Person::players[i]->deathbleeding = 0;
1024 Person::players[i]->stunned = 0;
1025 Person::players[i]->hasvictim = 0;
1026 Person::players[i]->wentforweapon = 0;
1030 Person::players[0]->aitype = playercontrolled;
1032 if (difficulty == 1) {
1033 Person::players[0]->power = 1 / .9;
1034 Person::players[0]->damagetolerance = 250;
1035 } else if (difficulty == 0) {
1036 Person::players[0]->power = 1 / .8;
1037 Person::players[0]->damagetolerance = 300;
1038 Person::players[0]->armorhead *= 1.5;
1039 Person::players[0]->armorhigh *= 1.5;
1040 Person::players[0]->armorlow *= 1.5;
1043 cameraloc = Person::players[0]->coords;
1045 yaw = Person::players[0]->yaw;
1047 hawkcoords = Person::players[0]->coords;
1053 LOG("Starting background music...");
1055 OPENAL_StopSound(OPENAL_ALL);
1057 if (environment == snowyenvironment) {
1058 emit_stream_np(stream_wind);
1059 } else if (environment == desertenvironment) {
1060 emit_stream_np(stream_desertambient);
1061 } else if (environment == grassyenvironment) {
1062 emit_stream_np(stream_wind, 100.);
1065 oldmusicvolume[0] = 0;
1066 oldmusicvolume[1] = 0;
1067 oldmusicvolume[2] = 0;
1068 oldmusicvolume[3] = 0;
1080 if (tutorialstagetime > tutorialmaxtime) {
1082 tutorialsuccess = 0;
1083 if (tutorialstage <= 1) {
1088 switch (tutorialstage) {
1090 tutorialmaxtime = 5;
1093 tutorialmaxtime = 2;
1096 tutorialmaxtime = 600;
1099 tutorialmaxtime = 1000;
1102 tutorialmaxtime = 600;
1105 tutorialmaxtime = 600;
1108 tutorialmaxtime = 600;
1111 tutorialmaxtime = 600;
1114 tutorialmaxtime = 600;
1117 tutorialmaxtime = 2;
1120 tutorialmaxtime = 1000;
1123 tutorialmaxtime = 1000;
1126 tutorialmaxtime = 2;
1129 tutorialmaxtime = 3;
1140 Person::players[1]->coords = (temp + temp2) / 2;
1142 emit_sound_at(fireendsound, Person::players[1]->coords);
1144 for (unsigned i = 0; i < Person::players[1]->skeleton.joints.size(); i++) {
1145 if (Random() % 2 == 0) {
1146 if (!Person::players[1]->skeleton.free)
1147 temp2 = (Person::players[1]->coords - Person::players[1]->oldcoords) / multiplier / 2; //velocity/2;
1148 if (Person::players[1]->skeleton.free)
1149 temp2 = Person::players[1]->skeleton.joints[i].velocity * Person::players[1]->scale / 2;
1150 if (!Person::players[1]->skeleton.free)
1151 temp = DoRotation(DoRotation(DoRotation(Person::players[1]->skeleton.joints[i].position, 0, 0, Person::players[1]->tilt), Person::players[1]->tilt2, 0, 0), 0, Person::players[1]->yaw, 0) * Person::players[1]->scale + Person::players[1]->coords;
1152 if (Person::players[1]->skeleton.free)
1153 temp = Person::players[1]->skeleton.joints[i].position * Person::players[1]->scale + Person::players[1]->coords;
1154 Sprite::MakeSprite(breathsprite, temp, temp2, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
1160 tutorialmaxtime = 500;
1163 tutorialmaxtime = 500;
1166 tutorialmaxtime = 500;
1169 tutorialmaxtime = 500;
1175 tutorialmaxtime = 500;
1178 tutorialmaxtime = 500;
1179 if (bonus == cannon) {
1186 tutorialmaxtime = 500;
1189 tutorialmaxtime = 500;
1192 tutorialmaxtime = 500;
1195 tutorialmaxtime = 500;
1198 tutorialmaxtime = 2;
1201 tutorialmaxtime = 4;
1204 Person::players[1]->aitype = attacktypecutoff;
1207 tutorialmaxtime = 400;
1210 tutorialmaxtime = 400;
1211 Person::players[0]->escapednum = 0;
1214 tutorialmaxtime = 4;
1217 Person::players[1]->aitype = passivetype;
1220 tutorialmaxtime = 13;
1223 tutorialmaxtime = 8;
1226 tutorialmaxtime = 400;
1229 Person::players[1]->aitype = attacktypecutoff;
1232 tutorialmaxtime = 400;
1235 tutorialmaxtime = 400;
1238 tutorialmaxtime = 2;
1241 Person::players[1]->aitype = passivetype;
1246 tutorialmaxtime = 50;
1249 Person::players[1]->aitype = attacktypecutoff;
1252 tutorialmaxtime = 4;
1255 Person::players[1]->aitype = passivetype;
1267 Weapon w(knife, -1);
1268 w.position = (temp + temp2) / 2;
1269 w.tippoint = (temp + temp2) / 2;
1272 w.tipvelocity = 0.1;
1279 weapons.push_back(w);
1283 tutorialmaxtime = 300;
1286 tutorialmaxtime = 300;
1289 tutorialmaxtime = 8;
1292 tutorialmaxtime = 300;
1295 weapons[0].owner = 1;
1296 Person::players[0]->weaponactive = -1;
1297 Person::players[0]->num_weapons = 0;
1298 Person::players[1]->weaponactive = 0;
1299 Person::players[1]->num_weapons = 1;
1300 Person::players[1]->weaponids[0] = 0;
1304 Person::players[1]->aitype = attacktypecutoff;
1306 tutorialmaxtime = 300;
1309 weapons[0].owner = 1;
1310 Person::players[0]->weaponactive = -1;
1311 Person::players[0]->num_weapons = 0;
1312 Person::players[1]->weaponactive = 0;
1313 Person::players[1]->num_weapons = 1;
1314 Person::players[1]->weaponids[0] = 0;
1316 tutorialmaxtime = 300;
1319 weapons[0].owner = 1;
1320 Person::players[0]->weaponactive = -1;
1321 Person::players[0]->num_weapons = 0;
1322 Person::players[1]->weaponactive = 0;
1323 Person::players[1]->num_weapons = 1;
1324 Person::players[1]->weaponids[0] = 0;
1326 weapons[0].setType(sword);
1328 tutorialmaxtime = 300;
1331 tutorialmaxtime = 10;
1342 Weapon w(sword, -1);
1343 w.position = (temp + temp2) / 2;
1344 w.tippoint = (temp + temp2) / 2;
1347 w.tipvelocity = 0.1;
1354 weapons.push_back(w);
1356 weapons[0].owner = 1;
1357 weapons[1].owner = 0;
1358 Person::players[0]->weaponactive = 0;
1359 Person::players[0]->num_weapons = 1;
1360 Person::players[0]->weaponids[0] = 1;
1361 Person::players[1]->weaponactive = 0;
1362 Person::players[1]->num_weapons = 1;
1363 Person::players[1]->weaponids[0] = 0;
1370 Person::players[1]->aitype = passivetype;
1372 tutorialmaxtime = 15;
1374 weapons[0].owner = 1;
1375 weapons[1].owner = 0;
1376 Person::players[0]->weaponactive = 0;
1377 Person::players[0]->num_weapons = 1;
1378 Person::players[0]->weaponids[0] = 1;
1379 Person::players[1]->weaponactive = 0;
1380 Person::players[1]->num_weapons = 1;
1381 Person::players[1]->weaponids[0] = 0;
1383 if (Person::players[0]->weaponactive != -1)
1384 weapons[Person::players[0]->weaponids[Person::players[0]->weaponactive]].setType(staff);
1386 weapons[0].setType(staff);
1391 Person::players[1]->aitype = passivetype;
1393 tutorialmaxtime = 200;
1395 weapons[1].position = 1000;
1396 weapons[1].tippoint = 1000;
1398 weapons[0].setType(knife);
1400 weapons[0].owner = 0;
1401 Person::players[1]->weaponactive = -1;
1402 Person::players[1]->num_weapons = 0;
1403 Person::players[0]->weaponactive = 0;
1404 Person::players[0]->num_weapons = 1;
1405 Person::players[0]->weaponids[0] = 0;
1409 tutorialmaxtime = 8;
1412 emit_sound_at(fireendsound, Person::players[1]->coords);
1414 for (unsigned i = 0; i < Person::players[1]->skeleton.joints.size(); i++) {
1415 if (Random() % 2 == 0) {
1416 if (!Person::players[1]->skeleton.free)
1417 temp2 = (Person::players[1]->coords - Person::players[1]->oldcoords) / multiplier / 2; //velocity/2;
1418 if (Person::players[1]->skeleton.free)
1419 temp2 = Person::players[1]->skeleton.joints[i].velocity * Person::players[1]->scale / 2;
1420 if (!Person::players[1]->skeleton.free)
1421 temp = DoRotation(DoRotation(DoRotation(Person::players[1]->skeleton.joints[i].position, 0, 0, Person::players[1]->tilt), Person::players[1]->tilt2, 0, 0), 0, Person::players[1]->yaw, 0) * Person::players[1]->scale + Person::players[1]->coords;
1422 if (Person::players[1]->skeleton.free)
1423 temp = Person::players[1]->skeleton.joints[i].position * Person::players[1]->scale + Person::players[1]->coords;
1424 Sprite::MakeSprite(breathsprite, temp, temp2, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
1428 Person::players[1]->num_weapons = 0;
1429 Person::players[1]->weaponstuck = -1;
1430 Person::players[1]->weaponactive = -1;
1436 tutorialmaxtime = 80000;
1441 if (tutorialstage <= 51)
1442 tutorialstagetime = 0;
1446 if (tutorialstagetime < tutorialmaxtime - 3) {
1447 switch (tutorialstage) {
1449 if (deltah || deltav)
1450 tutorialsuccess += multiplier;
1453 if (Person::players[0]->forwardkeydown || Person::players[0]->backkeydown || Person::players[0]->leftkeydown || Person::players[0]->rightkeydown)
1454 tutorialsuccess += multiplier;
1457 if (Person::players[0]->jumpkeydown)
1458 tutorialsuccess = 1;
1461 if (Person::players[0]->isCrouch())
1462 tutorialsuccess = 1;
1465 if (Person::players[0]->animTarget == rollanim)
1466 tutorialsuccess = 1;
1469 if (Person::players[0]->animTarget == sneakanim)
1470 tutorialsuccess += multiplier;
1473 if (Person::players[0]->animTarget == rabbitrunninganim || Person::players[0]->animTarget == wolfrunninganim)
1474 tutorialsuccess += multiplier;
1477 if (Person::players[0]->isWallJump())
1478 tutorialsuccess = 1;
1481 if (Person::players[0]->animTarget == flipanim)
1482 tutorialsuccess = 1;
1485 if (Person::players[0]->animTarget == upunchanim || Person::players[0]->animTarget == winduppunchanim)
1486 tutorialsuccess = 1;
1489 if (Person::players[0]->animTarget == winduppunchanim)
1490 tutorialsuccess = 1;
1493 if (Person::players[0]->animTarget == spinkickanim)
1494 tutorialsuccess = 1;
1497 if (Person::players[0]->animTarget == sweepanim)
1498 tutorialsuccess = 1;
1501 if (Person::players[0]->animTarget == dropkickanim)
1502 tutorialsuccess = 1;
1505 if (Person::players[0]->animTarget == rabbitkickanim)
1506 tutorialsuccess = 1;
1509 if (bonus == cannon)
1510 tutorialsuccess = 1;
1513 if (bonus == spinecrusher)
1514 tutorialsuccess = 1;
1517 if (Person::players[0]->animTarget == walljumprightkickanim || Person::players[0]->animTarget == walljumpleftkickanim)
1518 tutorialsuccess = 1;
1521 if (Person::players[0]->animTarget == rabbittacklinganim)
1522 tutorialsuccess = 1;
1525 if (Person::players[0]->animTarget == backhandspringanim)
1526 tutorialsuccess = 1;
1529 if (Animation::animations[Person::players[0]->animTarget].attack == reversed && Person::players[0]->feint)
1530 tutorialsuccess = 1;
1533 if (Person::players[0]->escapednum == 2) {
1534 tutorialsuccess = 1;
1537 Person::players[1]->aitype = passivetype;
1541 if (Animation::animations[Person::players[0]->animTarget].attack == reversal)
1542 tutorialsuccess = 1;
1545 if (Animation::animations[Person::players[0]->animTarget].attack == reversal)
1546 tutorialsuccess = 1;
1549 if (Animation::animations[Person::players[0]->animTarget].attack == reversal) {
1550 tutorialsuccess = 1;
1553 Person::players[1]->aitype = passivetype;
1557 if (Person::players[0]->num_weapons > 0)
1558 tutorialsuccess = 1;
1561 if (Person::players[0]->weaponactive == -1 && Person::players[0]->num_weapons > 0)
1562 tutorialsuccess = 1;
1565 if (Person::players[0]->animTarget == knifeslashstartanim)
1566 tutorialsuccess = 1;
1569 if (Animation::animations[Person::players[0]->animTarget].attack == reversal)
1570 tutorialsuccess = 1;
1573 if (Animation::animations[Person::players[0]->animTarget].attack == reversal)
1574 tutorialsuccess = 1;
1577 if (Animation::animations[Person::players[0]->animTarget].attack == reversal)
1578 tutorialsuccess = 1;
1581 if (Person::players[1]->weaponstuck != -1)
1582 tutorialsuccess = 1;
1587 if (tutorialsuccess >= 1)
1588 tutorialstagetime = tutorialmaxtime - 3;
1591 if (tutorialstagetime == tutorialmaxtime - 3) {
1592 emit_sound_np(consolesuccesssound);
1595 if (tutorialsuccess >= 1) {
1596 if (tutorialstage == 34 || tutorialstage == 35)
1597 tutorialstagetime = tutorialmaxtime - 1;
1601 if (tutorialstage < 14 || tutorialstage >= 50) {
1602 Person::players[1]->coords.y = 300;
1603 Person::players[1]->velocity = 0;
1609 float headprop, bodyprop, armprop, legprop;
1614 if (Input::isKeyDown(SDL_SCANCODE_LALT)) {
1616 if (Input::isKeyPressed(SDL_SCANCODE_H)) {
1617 Person::players[0]->damagetolerance = 200000;
1618 Person::players[0]->damage = 0;
1619 Person::players[0]->burnt = 0;
1620 Person::players[0]->permanentdamage = 0;
1621 Person::players[0]->superpermanentdamage = 0;
1624 /* Change environment */
1625 if (Input::isKeyPressed(SDL_SCANCODE_J)) {
1627 if (environment > 2)
1629 Setenvironment(environment);
1633 if (Input::isKeyPressed(SDL_SCANCODE_C)) {
1634 cameramode = !cameramode;
1637 /* Toggle Slow motion */
1638 if (Input::isKeyPressed(SDL_SCANCODE_B)) {
1644 if (Input::isKeyPressed(SDL_SCANCODE_N)) {
1645 Person::players[0]->RagDoll(0);
1647 emit_sound_at(whooshsound, Person::players[0]->coords, 128.);
1650 /* Grow tree leaves?? */
1651 if (Input::isKeyPressed(SDL_SCANCODE_Y)) {
1652 for (int i = 0; i < Object::objects.size(); i++) {
1653 if (Object::objects[i]->type == treeleavestype) {
1654 Object::objects[i]->scale *= .9;
1659 /* Change (or add) weapon */
1660 if (Input::isKeyPressed(SDL_SCANCODE_X)) {
1662 if (!Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
1663 closest = findClosestPlayer();
1667 if (Person::players[closest]->num_weapons > 0) {
1668 if (weapons[Person::players[closest]->weaponids[0]].getType() == sword)
1669 weapons[Person::players[closest]->weaponids[0]].setType(staff);
1670 else if (weapons[Person::players[closest]->weaponids[0]].getType() == staff)
1671 weapons[Person::players[closest]->weaponids[0]].setType(knife);
1673 weapons[Person::players[closest]->weaponids[0]].setType(sword);
1675 Person::players[closest]->weaponids[0] = weapons.size();
1677 weapons.push_back(Weapon(knife, closest));
1679 Person::players[closest]->num_weapons = 1;
1685 if (Input::isKeyDown(SDL_SCANCODE_U)) {
1687 if (!Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
1688 closest = findClosestPlayer();
1692 Person::players[closest]->yaw += multiplier * 50;
1693 Person::players[closest]->targetyaw = Person::players[closest]->yaw;
1698 if (Input::isKeyPressed(SDL_SCANCODE_F)) {
1699 Person::players[0]->onfire = 1 - Person::players[0]->onfire;
1700 if (Person::players[0]->onfire) {
1701 Person::players[0]->CatchFire();
1703 if (!Person::players[0]->onfire) {
1704 emit_sound_at(fireendsound, Person::players[0]->coords);
1705 pause_sound(stream_firesound);
1710 if (Input::isKeyPressed(SDL_SCANCODE_O) && !Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
1712 if (!Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
1713 closest = findClosestPlayer();
1717 Person::players[closest]->whichskin++;
1718 if (Person::players[closest]->whichskin > 9)
1719 Person::players[closest]->whichskin = 0;
1720 if (Person::players[closest]->whichskin > 2 && Person::players[closest]->creature == wolftype)
1721 Person::players[closest]->whichskin = 0;
1723 Person::players[closest]->skeleton.drawmodel.textureptr.load(creatureskin[Person::players[closest]->creature][Person::players[closest]->whichskin], 1,
1724 &Person::players[closest]->skeleton.skinText[0], &Person::players[closest]->skeleton.skinsize);
1727 Person::players[closest]->addClothes();
1730 /* Change creature type */
1731 if (Input::isKeyPressed(SDL_SCANCODE_O) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
1733 if (!Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
1734 closest = findClosestPlayer();
1738 if (Person::players[closest]->creature == wolftype) {
1739 headprop = Person::players[closest]->proportionhead.x / 1.1;
1740 bodyprop = Person::players[closest]->proportionbody.x / 1.1;
1741 armprop = Person::players[closest]->proportionarms.x / 1.1;
1742 legprop = Person::players[closest]->proportionlegs.x / 1.1;
1745 headprop = Person::players[closest]->proportionhead.x / 1.2;
1746 bodyprop = Person::players[closest]->proportionbody.x / 1.05;
1747 armprop = Person::players[closest]->proportionarms.x / 1.00;
1748 legprop = Person::players[closest]->proportionlegs.x / 1.1;
1752 if (Person::players[closest]->creature == rabbittype) {
1753 Person::players[closest]->creature = wolftype;
1754 Person::players[closest]->whichskin = 0;
1755 Person::players[closest]->skeletonLoad();
1757 Person::players[closest]->proportionhead = 1.1;
1758 Person::players[closest]->proportionbody = 1.1;
1759 Person::players[closest]->proportionarms = 1.1;
1760 Person::players[closest]->proportionlegs = 1.1;
1761 Person::players[closest]->proportionlegs.y = 1.1;
1762 Person::players[closest]->scale = .23 * 5 * Person::players[0]->scale;
1764 Person::players[closest]->damagetolerance = 300;
1766 Person::players[closest]->creature = rabbittype;
1767 Person::players[closest]->whichskin = 0;
1768 Person::players[closest]->skeletonLoad(true);
1770 Person::players[closest]->proportionhead = 1.2;
1771 Person::players[closest]->proportionbody = 1.05;
1772 Person::players[closest]->proportionarms = 1.00;
1773 Person::players[closest]->proportionlegs = 1.1;
1774 Person::players[closest]->proportionlegs.y = 1.05;
1775 Person::players[closest]->scale = .2 * 5 * Person::players[0]->scale;
1777 Person::players[closest]->damagetolerance = 200;
1780 if (Person::players[closest]->creature == wolftype) {
1781 Person::players[closest]->proportionhead = 1.1 * headprop;
1782 Person::players[closest]->proportionbody = 1.1 * bodyprop;
1783 Person::players[closest]->proportionarms = 1.1 * armprop;
1784 Person::players[closest]->proportionlegs = 1.1 * legprop;
1787 if (Person::players[closest]->creature == rabbittype) {
1788 Person::players[closest]->proportionhead = 1.2 * headprop;
1789 Person::players[closest]->proportionbody = 1.05 * bodyprop;
1790 Person::players[closest]->proportionarms = 1.00 * armprop;
1791 Person::players[closest]->proportionlegs = 1.1 * legprop;
1792 Person::players[closest]->proportionlegs.y = 1.05 * legprop;
1799 if (((Input::isKeyPressed(SDL_SCANCODE_I) && !Input::isKeyDown(SDL_SCANCODE_LSHIFT)))) {
1801 float closestdist = std::numeric_limits<float>::max();
1803 for (unsigned i = 1; i < Person::players.size(); i++) {
1804 float distance = distsq(&Person::players[i]->coords, &Person::players[0]->coords);
1805 if (!Person::players[i]->headless)
1806 if (distance < closestdist) {
1807 closestdist = distance;
1812 XYZ flatfacing2, flatvelocity2;
1814 if (closest != -1 && distsq(&Person::players[closest]->coords, &Person::players[0]->coords) < 144) {
1815 blah = Person::players[closest]->coords;
1816 XYZ headspurtdirection;
1817 //int i = Person::players[closest]->skeleton.jointlabels[head];
1818 Joint& headjoint = Person::players[closest]->joint(head);
1819 for (unsigned k = 0; k < Person::players[closest]->skeleton.joints.size(); k++) {
1820 if (!Person::players[closest]->skeleton.free)
1821 flatvelocity2 = Person::players[closest]->velocity;
1822 if (Person::players[closest]->skeleton.free)
1823 flatvelocity2 = headjoint.velocity;
1824 if (!Person::players[closest]->skeleton.free)
1825 flatfacing2 = DoRotation(DoRotation(DoRotation(headjoint.position, 0, 0, Person::players[closest]->tilt), Person::players[closest]->tilt2, 0, 0), 0, Person::players[closest]->yaw, 0) * Person::players[closest]->scale + Person::players[closest]->coords;
1826 if (Person::players[closest]->skeleton.free)
1827 flatfacing2 = headjoint.position * Person::players[closest]->scale + Person::players[closest]->coords;
1828 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1829 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1830 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1831 headspurtdirection = headjoint.position - Person::players[closest]->jointPos(neck);
1832 Normalise(&headspurtdirection);
1833 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, .6, 1);
1834 flatvelocity2 += headspurtdirection * 8;
1835 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2 / 2, 1, 1, 1, .16, 1);
1837 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1839 emit_sound_at(splattersound, blah);
1840 emit_sound_at(breaksound2, blah, 100.);
1842 if (Person::players[closest]->skeleton.free == 2)
1843 Person::players[closest]->skeleton.free = 0;
1844 Person::players[closest]->RagDoll(0);
1845 Person::players[closest]->dead = 2;
1846 Person::players[closest]->headless = 1;
1847 Person::players[closest]->DoBloodBig(3, 165);
1854 if (((Input::isKeyPressed(SDL_SCANCODE_I) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)))) {
1855 int closest = findClosestPlayer();
1856 XYZ flatfacing2, flatvelocity2;
1858 if (closest >= 0 && distsq(&Person::players[closest]->coords, &Person::players[0]->coords) < 144) {
1859 blah = Person::players[closest]->coords;
1860 emit_sound_at(splattersound, blah);
1861 emit_sound_at(breaksound2, blah);
1863 for (unsigned i = 0; i < Person::players[closest]->skeleton.joints.size(); i++) {
1864 if (!Person::players[closest]->skeleton.free)
1865 flatvelocity2 = Person::players[closest]->velocity;
1866 if (Person::players[closest]->skeleton.free)
1867 flatvelocity2 = Person::players[closest]->skeleton.joints[i].velocity;
1868 if (!Person::players[closest]->skeleton.free)
1869 flatfacing2 = DoRotation(DoRotation(DoRotation(Person::players[closest]->skeleton.joints[i].position, 0, 0, Person::players[closest]->tilt), Person::players[closest]->tilt2, 0, 0), 0, Person::players[closest]->yaw, 0) * Person::players[closest]->scale + Person::players[closest]->coords;
1870 if (Person::players[closest]->skeleton.free)
1871 flatfacing2 = Person::players[closest]->skeleton.joints[i].position * Person::players[closest]->scale + Person::players[closest]->coords;
1872 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1873 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1874 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1875 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1876 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .3, 1);
1877 Sprite::MakeSprite(cloudsprite, flatfacing2, flatvelocity2 * 0, .6, 0, 0, 1, .5);
1880 for (unsigned i = 0; i < Person::players[closest]->skeleton.joints.size(); i++) {
1881 if (!Person::players[closest]->skeleton.free)
1882 flatvelocity2 = Person::players[closest]->velocity;
1883 if (Person::players[closest]->skeleton.free)
1884 flatvelocity2 = Person::players[closest]->skeleton.joints[i].velocity;
1885 if (!Person::players[closest]->skeleton.free)
1886 flatfacing2 = DoRotation(DoRotation(DoRotation(Person::players[closest]->skeleton.joints[i].position, 0, 0, Person::players[closest]->tilt), Person::players[closest]->tilt2, 0, 0), 0, Person::players[closest]->yaw, 0) * Person::players[closest]->scale + Person::players[closest]->coords;
1887 if (Person::players[closest]->skeleton.free)
1888 flatfacing2 = Person::players[closest]->skeleton.joints[i].position * Person::players[closest]->scale + Person::players[closest]->coords;
1889 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1890 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1891 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1892 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2, 1, 1, 1, 3, 1);
1893 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2, 1, 1, 1, .4, 1);
1896 for (unsigned i = 0; i < Person::players[closest]->skeleton.joints.size(); i++) {
1897 if (!Person::players[closest]->skeleton.free)
1898 flatvelocity2 = Person::players[closest]->velocity;
1899 if (Person::players[closest]->skeleton.free)
1900 flatvelocity2 = Person::players[closest]->skeleton.joints[i].velocity;
1901 if (!Person::players[closest]->skeleton.free)
1902 flatfacing2 = DoRotation(DoRotation(DoRotation(Person::players[closest]->skeleton.joints[i].position, 0, 0, Person::players[closest]->tilt), Person::players[closest]->tilt2, 0, 0), 0, Person::players[closest]->yaw, 0) * Person::players[closest]->scale + Person::players[closest]->coords;
1903 if (Person::players[closest]->skeleton.free)
1904 flatfacing2 = Person::players[closest]->skeleton.joints[i].position * Person::players[closest]->scale + Person::players[closest]->coords;
1905 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1906 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1907 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1908 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2 * 2, 1, 1, 1, 3, 1);
1909 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2 * 2, 1, 1, 1, .4, 1);
1912 for (unsigned i = 0; i < Person::players[closest]->skeleton.joints.size(); i++) {
1913 if (!Person::players[closest]->skeleton.free)
1914 flatvelocity2 = Person::players[closest]->velocity;
1915 if (Person::players[closest]->skeleton.free)
1916 flatvelocity2 = Person::players[closest]->skeleton.joints[i].velocity;
1917 if (!Person::players[closest]->skeleton.free)
1918 flatfacing2 = DoRotation(DoRotation(DoRotation(Person::players[closest]->skeleton.joints[i].position, 0, 0, Person::players[closest]->tilt), Person::players[closest]->tilt2, 0, 0), 0, Person::players[closest]->yaw, 0) * Person::players[closest]->scale + Person::players[closest]->coords;
1919 if (Person::players[closest]->skeleton.free)
1920 flatfacing2 = Person::players[closest]->skeleton.joints[i].position * Person::players[closest]->scale + Person::players[closest]->coords;
1921 flatvelocity2.x += (float)(abs(Random() % 100) - 50) / 10;
1922 flatvelocity2.y += (float)(abs(Random() % 100) - 50) / 10;
1923 flatvelocity2.z += (float)(abs(Random() % 100) - 50) / 10;
1924 Sprite::MakeSprite(bloodflamesprite, flatfacing2, flatvelocity2 * 2, 1, 1, 1, 3, 1);
1925 Sprite::MakeSprite(bloodsprite, flatfacing2, flatvelocity2 * 2, 1, 1, 1, .4, 1);
1929 for (unsigned j = 0; j < Person::players.size(); j++) {
1930 if (int(j) != closest) {
1931 if (distsq(&Person::players[j]->coords, &Person::players[closest]->coords) < 25) {
1932 Person::players[j]->DoDamage((25 - distsq(&Person::players[j]->coords, &Person::players[closest]->coords)) * 60);
1933 if (Person::players[j]->skeleton.free == 2)
1934 Person::players[j]->skeleton.free = 1;
1935 Person::players[j]->skeleton.longdead = 0;
1936 Person::players[j]->RagDoll(0);
1937 for (unsigned i = 0; i < Person::players[j]->skeleton.joints.size(); i++) {
1938 temppos = Person::players[j]->skeleton.joints[i].position + Person::players[j]->coords;
1939 if (distsq(&temppos, &Person::players[closest]->coords) < 25) {
1940 flatvelocity2 = temppos - Person::players[closest]->coords;
1941 Normalise(&flatvelocity2);
1942 Person::players[j]->skeleton.joints[i].velocity += flatvelocity2 * ((20 - distsq(&temppos, &Person::players[closest]->coords)) * 20);
1949 Person::players[closest]->DoDamage(10000);
1950 Person::players[closest]->RagDoll(0);
1951 Person::players[closest]->dead = 2;
1952 Person::players[closest]->coords = 20;
1953 Person::players[closest]->skeleton.free = 2;
1961 if (Input::isKeyPressed(SDL_SCANCODE_M) && !Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
1962 editorenabled = !editorenabled;
1963 if (editorenabled) {
1964 Person::players[0]->damagetolerance = 100000;
1966 Person::players[0]->damagetolerance = 200;
1968 Person::players[0]->damage = 0; // these lines were in both if and else, but I think they would better fit in the if
1969 Person::players[0]->permanentdamage = 0;
1970 Person::players[0]->superpermanentdamage = 0;
1971 Person::players[0]->bloodloss = 0;
1972 Person::players[0]->deathbleeding = 0;
1977 if (whichlevel != -2 && Input::isKeyPressed(SDL_SCANCODE_K) && Input::isKeyDown(SDL_SCANCODE_LSHIFT) && !editorenabled) {
1979 if (targetlevel > numchallengelevels - 1)
1985 if (editorenabled) {
1986 if (Input::isKeyPressed(SDL_SCANCODE_DELETE) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
1987 int closest = findClosestPlayer();
1989 Person::players.erase(Person::players.begin()+closest);
1993 if (Input::isKeyPressed(SDL_SCANCODE_DELETE) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
1994 int closest = findClosestObject();
1996 Object::objects[closest]->position.y -= 500;
2000 if (Input::isKeyPressed(SDL_SCANCODE_M) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
2001 if (Object::objects.size() < max_objects - 1) {
2003 scenecoords.x = Person::players[0]->coords.x;
2004 scenecoords.z = Person::players[0]->coords.z;
2005 scenecoords.y = Person::players[0]->coords.y - 3;
2006 if (editortype == bushtype)
2007 scenecoords.y = Person::players[0]->coords.y - .5;
2008 if (editortype == firetype)
2009 scenecoords.y = Person::players[0]->coords.y - .5;
2010 float temprotat, temprotat2;
2011 temprotat = editoryaw;
2012 temprotat2 = editorpitch;
2013 if (temprotat < 0 || editortype == bushtype)
2014 temprotat = Random() % 360;
2016 temprotat2 = Random() % 360;
2018 Object::MakeObject(editortype, scenecoords, (int)temprotat - ((int)temprotat) % 30, (int)temprotat2, editorsize);
2019 if (editortype == treetrunktype)
2020 Object::MakeObject(treeleavestype, scenecoords, Random() % 360 * (temprotat2 < 2) + (int)editoryaw - ((int)editoryaw) % 30, editorpitch, editorsize);
2024 if (Input::isKeyPressed(SDL_SCANCODE_P) && Input::isKeyDown(SDL_SCANCODE_LSHIFT) && !Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2025 Person::players.push_back(shared_ptr<Person>(new Person()));
2027 Person::players.back()->id = Person::players.size()-1;
2029 Person::players.back()->scale = Person::players[0]->scale;
2030 Person::players.back()->creature = rabbittype;
2031 Person::players.back()->howactive = editoractive;
2033 int k = abs(Random() % 2) + 1;
2035 Person::players.back()->whichskin = 0;
2036 } else if (k == 1) {
2037 Person::players.back()->whichskin = 1;
2039 Person::players.back()->whichskin = 2;
2042 Person::players.back()->skeletonLoad(true);
2044 Person::players.back()->skeleton.drawmodelclothes.textureptr.load("Textures/Belt.png", 1);
2045 Person::players.back()->speed = 1 + (float)(Random() % 100) / 1000;
2047 Person::players.back()->targetyaw = Person::players[0]->targetyaw;
2048 Person::players.back()->yaw = Person::players[0]->yaw;
2050 Person::players.back()->coords = Person::players[0]->coords;
2051 Person::players.back()->oldcoords = Person::players.back()->coords;
2052 Person::players.back()->realoldcoords = Person::players.back()->coords;
2054 if (Person::players[0]->creature == wolftype) {
2055 headprop = Person::players[0]->proportionhead.x / 1.1;
2056 bodyprop = Person::players[0]->proportionbody.x / 1.1;
2057 armprop = Person::players[0]->proportionarms.x / 1.1;
2058 legprop = Person::players[0]->proportionlegs.x / 1.1;
2061 headprop = Person::players[0]->proportionhead.x / 1.2;
2062 bodyprop = Person::players[0]->proportionbody.x / 1.05;
2063 armprop = Person::players[0]->proportionarms.x / 1.00;
2064 legprop = Person::players[0]->proportionlegs.x / 1.1;
2067 if (Person::players.back()->creature == wolftype) {
2068 Person::players.back()->proportionhead = 1.1 * headprop;
2069 Person::players.back()->proportionbody = 1.1 * bodyprop;
2070 Person::players.back()->proportionarms = 1.1 * armprop;
2071 Person::players.back()->proportionlegs = 1.1 * legprop;
2074 if (Person::players.back()->creature == rabbittype) {
2075 Person::players.back()->proportionhead = 1.2 * headprop;
2076 Person::players.back()->proportionbody = 1.05 * bodyprop;
2077 Person::players.back()->proportionarms = 1.00 * armprop;
2078 Person::players.back()->proportionlegs = 1.1 * legprop;
2079 Person::players.back()->proportionlegs.y = 1.05 * legprop;
2083 Person::players.back()->proportionhead.z = 0;
2084 Person::players.back()->proportionbody.z = 0;
2085 Person::players.back()->proportionarms.z = 0;
2086 Person::players.back()->proportionlegs.z = 0;
2089 Person::players.back()->tempanimation = Animation("Tempanim", lowheight, neutral);
2091 Person::players.back()->damagetolerance = 200;
2093 Person::players.back()->protectionhead = Person::players[0]->protectionhead;
2094 Person::players.back()->protectionhigh = Person::players[0]->protectionhigh;
2095 Person::players.back()->protectionlow = Person::players[0]->protectionlow;
2096 Person::players.back()->armorhead = Person::players[0]->armorhead;
2097 Person::players.back()->armorhigh = Person::players[0]->armorhigh;
2098 Person::players.back()->armorlow = Person::players[0]->armorlow;
2099 Person::players.back()->metalhead = Person::players[0]->metalhead;
2100 Person::players.back()->metalhigh = Person::players[0]->metalhigh;
2101 Person::players.back()->metallow = Person::players[0]->metallow;
2103 Person::players.back()->immobile = Person::players[0]->immobile;
2105 Person::players.back()->numclothes = Person::players[0]->numclothes;
2106 for (int i = 0; i < Person::players.back()->numclothes; i++) {
2107 strcpy(Person::players.back()->clothes[i], Person::players[0]->clothes[i]);
2108 Person::players.back()->clothestintr[i] = Person::players[0]->clothestintr[i];
2109 Person::players.back()->clothestintg[i] = Person::players[0]->clothestintg[i];
2110 Person::players.back()->clothestintb[i] = Person::players[0]->clothestintb[i];
2112 Person::players.back()->addClothes();
2114 Person::players.back()->power = Person::players[0]->power;
2115 Person::players.back()->speedmult = Person::players[0]->speedmult;
2117 Person::players.back()->loaded = true;
2120 if (Input::isKeyPressed(SDL_SCANCODE_P) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
2121 if (Person::players.back()->numwaypoints < 90) {
2122 Person::players.back()->waypoints[Person::players.back()->numwaypoints] = Person::players[0]->coords;
2123 Person::players.back()->waypointtype[Person::players.back()->numwaypoints] = editorpathtype;
2124 Person::players.back()->numwaypoints++;
2128 if (Input::isKeyPressed(SDL_SCANCODE_P) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2129 if (numpathpoints < 30) {
2130 bool connected, alreadyconnected;
2132 if (numpathpoints > 1)
2133 for (int i = 0; i < numpathpoints; i++) {
2134 if (distsq(&pathpoint[i], &Person::players[0]->coords) < .5 && i != pathpointselected && !connected) {
2135 alreadyconnected = 0;
2136 for (int j = 0; j < numpathpointconnect[pathpointselected]; j++) {
2137 if (pathpointconnect[pathpointselected][j] == i)
2138 alreadyconnected = 1;
2140 if (!alreadyconnected) {
2141 numpathpointconnect[pathpointselected]++;
2143 pathpointconnect[pathpointselected][numpathpointconnect[pathpointselected] - 1] = i;
2149 pathpoint[numpathpoints - 1] = Person::players[0]->coords;
2150 numpathpointconnect[numpathpoints - 1] = 0;
2151 if (numpathpoints > 1 && pathpointselected != -1) {
2152 numpathpointconnect[pathpointselected]++;
2153 pathpointconnect[pathpointselected][numpathpointconnect[pathpointselected] - 1] = numpathpoints - 1;
2155 pathpointselected = numpathpoints - 1;
2160 if (Input::isKeyPressed(SDL_SCANCODE_PERIOD)) {
2161 pathpointselected++;
2162 if (pathpointselected >= numpathpoints)
2163 pathpointselected = -1;
2166 if (Input::isKeyPressed(SDL_SCANCODE_COMMA) && !Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
2167 pathpointselected--;
2168 if (pathpointselected <= -2)
2169 pathpointselected = numpathpoints - 1;
2172 if (Input::isKeyPressed(SDL_SCANCODE_COMMA) && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
2173 if (pathpointselected != -1) {
2175 pathpoint[pathpointselected] = pathpoint[numpathpoints];
2176 numpathpointconnect[pathpointselected] = numpathpointconnect[numpathpoints];
2177 for (int i = 0; i < numpathpointconnect[pathpointselected]; i++) {
2178 pathpointconnect[pathpointselected][i] = pathpointconnect[numpathpoints][i];
2180 for (int i = 0; i < numpathpoints; i++) {
2181 for (int j = 0; j < numpathpointconnect[i]; j++) {
2182 if (pathpointconnect[i][j] == pathpointselected) {
2183 pathpointconnect[i][j] = pathpointconnect[i][numpathpointconnect[i] - 1];
2184 numpathpointconnect[i]--;
2186 if (pathpointconnect[i][j] == numpathpoints) {
2187 pathpointconnect[i][j] = pathpointselected;
2191 pathpointselected = numpathpoints - 1;
2195 if (Input::isKeyPressed(SDL_SCANCODE_LEFT) && Input::isKeyDown(SDL_SCANCODE_LSHIFT) && !Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2197 if (editortype == treeleavestype || editortype == 10)
2200 editortype = firetype;
2203 if (Input::isKeyPressed(SDL_SCANCODE_RIGHT) && Input::isKeyDown(SDL_SCANCODE_LSHIFT) && !Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2205 if (editortype == treeleavestype || editortype == 10)
2207 if (editortype > firetype)
2211 if (Input::isKeyDown(SDL_SCANCODE_LEFT) && !Input::isKeyDown(SDL_SCANCODE_LSHIFT) && !Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2212 editoryaw -= multiplier * 100;
2213 if (editoryaw < -.01)
2217 if (Input::isKeyDown(SDL_SCANCODE_RIGHT) && !Input::isKeyDown(SDL_SCANCODE_LSHIFT) && !Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2218 editoryaw += multiplier * 100;
2221 if (Input::isKeyDown(SDL_SCANCODE_UP) && !Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2222 editorsize += multiplier;
2225 if (Input::isKeyDown(SDL_SCANCODE_DOWN) && !Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2226 editorsize -= multiplier;
2227 if (editorsize < .1)
2232 if (Input::isKeyPressed(SDL_SCANCODE_LEFT) && Input::isKeyDown(SDL_SCANCODE_LSHIFT) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2233 mapradius -= multiplier * 10;
2236 if (Input::isKeyPressed(SDL_SCANCODE_RIGHT) && Input::isKeyDown(SDL_SCANCODE_LSHIFT) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2237 mapradius += multiplier * 10;
2240 if (Input::isKeyDown(SDL_SCANCODE_UP) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2241 editorpitch += multiplier * 100;
2244 if (Input::isKeyDown(SDL_SCANCODE_DOWN) && Input::isKeyDown(SDL_SCANCODE_LCTRL)) {
2245 editorpitch -= multiplier * 100;
2246 if (editorpitch < -.01)
2250 if (Input::isKeyPressed(SDL_SCANCODE_DELETE) && Object::objects.size() && Input::isKeyDown(SDL_SCANCODE_LSHIFT)) {
2251 int closest = findClosestObject();
2253 Object::DeleteObject(closest);
2259 void doJumpReversals()
2261 for (unsigned k = 0; k < Person::players.size(); k++)
2262 for (unsigned i = k; i < Person::players.size(); i++) {
2265 if ( Person::players[k]->skeleton.free == 0 &&
2266 Person::players[i]->skeleton.oldfree == 0 &&
2267 (Person::players[i]->animTarget == jumpupanim ||
2268 Person::players[k]->animTarget == jumpupanim) &&
2269 (Person::players[i]->aitype == playercontrolled ||
2270 Person::players[k]->aitype == playercontrolled) &&
2271 ((Person::players[i]->aitype == attacktypecutoff && Person::players[i]->stunned <= 0) ||
2272 (Person::players[k]->aitype == attacktypecutoff && Person::players[k]->stunned <= 0))) {
2273 if ( distsq(&Person::players[i]->coords, &Person::players[k]->coords) < 10 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5) &&
2274 distsqflat(&Person::players[i]->coords, &Person::players[k]->coords) < 2 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5)) {
2275 //TODO: refactor two huge similar ifs
2276 if (Person::players[i]->animTarget == jumpupanim &&
2277 Person::players[k]->animTarget != getupfrombackanim &&
2278 Person::players[k]->animTarget != getupfromfrontanim &&
2279 Animation::animations[Person::players[k]->animTarget].height == middleheight &&
2280 normaldotproduct(Person::players[i]->velocity, Person::players[k]->coords - Person::players[i]->coords) < 0 &&
2281 ((Person::players[k]->aitype == playercontrolled && Person::players[k]->attackkeydown) ||
2282 Person::players[k]->aitype != playercontrolled)) {
2283 Person::players[i]->victim = Person::players[k];
2284 Person::players[i]->velocity = 0;
2285 Person::players[i]->animCurrent = jumpreversedanim;
2286 Person::players[i]->animTarget = jumpreversedanim;
2287 Person::players[i]->frameCurrent = 0;
2288 Person::players[i]->frameTarget = 1;
2289 Person::players[i]->targettilt2 = 0;
2290 Person::players[k]->victim = Person::players[i];
2291 Person::players[k]->velocity = 0;
2292 Person::players[k]->animCurrent = jumpreversalanim;
2293 Person::players[k]->animTarget = jumpreversalanim;
2294 Person::players[k]->frameCurrent = 0;
2295 Person::players[k]->frameTarget = 1;
2296 Person::players[k]->targettilt2 = 0;
2297 if (Person::players[i]->coords.y < Person::players[k]->coords.y + 1) {
2298 Person::players[i]->animCurrent = rabbitkickreversedanim;
2299 Person::players[i]->animTarget = rabbitkickreversedanim;
2300 Person::players[i]->frameCurrent = 1;
2301 Person::players[i]->frameTarget = 2;
2302 Person::players[k]->animCurrent = rabbitkickreversalanim;
2303 Person::players[k]->animTarget = rabbitkickreversalanim;
2304 Person::players[k]->frameCurrent = 1;
2305 Person::players[k]->frameTarget = 2;
2307 Person::players[i]->target = 0;
2308 Person::players[k]->oldcoords = Person::players[k]->coords;
2309 Person::players[i]->coords = Person::players[k]->coords;
2310 Person::players[k]->targetyaw = Person::players[i]->targetyaw;
2311 Person::players[k]->yaw = Person::players[i]->targetyaw;
2312 if (Person::players[k]->aitype == attacktypecutoff)
2313 Person::players[k]->stunned = .5;
2315 if (Person::players[k]->animTarget == jumpupanim &&
2316 Person::players[i]->animTarget != getupfrombackanim &&
2317 Person::players[i]->animTarget != getupfromfrontanim &&
2318 Animation::animations[Person::players[i]->animTarget].height == middleheight &&
2319 normaldotproduct(Person::players[k]->velocity, Person::players[i]->coords - Person::players[k]->coords) < 0 &&
2320 ((Person::players[i]->aitype == playercontrolled && Person::players[i]->attackkeydown) ||
2321 Person::players[i]->aitype != playercontrolled)) {
2322 Person::players[k]->victim = Person::players[i];
2323 Person::players[k]->velocity = 0;
2324 Person::players[k]->animCurrent = jumpreversedanim;
2325 Person::players[k]->animTarget = jumpreversedanim;
2326 Person::players[k]->frameCurrent = 0;
2327 Person::players[k]->frameTarget = 1;
2328 Person::players[k]->targettilt2 = 0;
2329 Person::players[i]->victim = Person::players[k];
2330 Person::players[i]->velocity = 0;
2331 Person::players[i]->animCurrent = jumpreversalanim;
2332 Person::players[i]->animTarget = jumpreversalanim;
2333 Person::players[i]->frameCurrent = 0;
2334 Person::players[i]->frameTarget = 1;
2335 Person::players[i]->targettilt2 = 0;
2336 if (Person::players[k]->coords.y < Person::players[i]->coords.y + 1) {
2337 Person::players[k]->animTarget = rabbitkickreversedanim;
2338 Person::players[k]->animCurrent = rabbitkickreversedanim;
2339 Person::players[i]->animCurrent = rabbitkickreversalanim;
2340 Person::players[i]->animTarget = rabbitkickreversalanim;
2341 Person::players[k]->frameCurrent = 1;
2342 Person::players[k]->frameTarget = 2;
2343 Person::players[i]->frameCurrent = 1;
2344 Person::players[i]->frameTarget = 2;
2346 Person::players[k]->target = 0;
2347 Person::players[i]->oldcoords = Person::players[i]->coords;
2348 Person::players[k]->coords = Person::players[i]->coords;
2349 Person::players[i]->targetyaw = Person::players[k]->targetyaw;
2350 Person::players[i]->yaw = Person::players[k]->targetyaw;
2351 if (Person::players[i]->aitype == attacktypecutoff)
2352 Person::players[i]->stunned = .5;
2359 void doAerialAcrobatics()
2361 static XYZ facing, flatfacing;
2362 for (unsigned k = 0; k < Person::players.size(); k++) {
2363 Person::players[k]->turnspeed = 500;
2365 if ((Person::players[k]->isRun() &&
2366 ((Person::players[k]->targetyaw != rabbitrunninganim &&
2367 Person::players[k]->targetyaw != wolfrunninganim) ||
2368 Person::players[k]->frameTarget == 4)) ||
2369 Person::players[k]->animTarget == removeknifeanim ||
2370 Person::players[k]->animTarget == crouchremoveknifeanim ||
2371 Person::players[k]->animTarget == flipanim ||
2372 Person::players[k]->animTarget == fightsidestep ||
2373 Person::players[k]->animTarget == walkanim) {
2374 Person::players[k]->yaw = stepTowardf(Person::players[k]->yaw, Person::players[k]->targetyaw, multiplier * Person::players[k]->turnspeed);
2378 if (Person::players[k]->isStop() ||
2379 Person::players[k]->isLanding() ||
2380 Person::players[k]->animTarget == staggerbackhighanim ||
2381 (Person::players[k]->animTarget == sneakanim && Person::players[k]->animCurrent == sneakanim) ||
2382 Person::players[k]->animTarget == staggerbackhardanim ||
2383 Person::players[k]->animTarget == backhandspringanim ||
2384 Person::players[k]->animTarget == dodgebackanim ||
2385 Person::players[k]->animTarget == rollanim ||
2386 (Animation::animations[Person::players[k]->animTarget].attack &&
2387 Person::players[k]->animTarget != rabbitkickanim &&
2388 (Person::players[k]->animTarget != crouchstabanim || Person::players[k]->hasvictim) &&
2389 (Person::players[k]->animTarget != swordgroundstabanim || Person::players[k]->hasvictim))) {
2390 Person::players[k]->yaw = stepTowardf(Person::players[k]->yaw, Person::players[k]->targetyaw, multiplier * Person::players[k]->turnspeed * 2);
2393 if (Person::players[k]->animTarget == sneakanim && Person::players[k]->animCurrent != sneakanim) {
2394 Person::players[k]->yaw = stepTowardf(Person::players[k]->yaw, Person::players[k]->targetyaw, multiplier * Person::players[k]->turnspeed * 4);
2397 Person::players[k]->DoStuff();
2398 if (Person::players[k]->immobile && k != 0)
2399 Person::players[k]->coords = Person::players[k]->realoldcoords;
2401 //if player's position has changed (?)
2402 if (distsq(&Person::players[k]->coords, &Person::players[k]->realoldcoords) > 0 &&
2403 !Person::players[k]->skeleton.free &&
2404 Person::players[k]->animTarget != climbanim &&
2405 Person::players[k]->animTarget != hanganim) {
2406 XYZ lowpoint, lowpointtarget, lowpoint2, lowpointtarget2, lowpoint3, lowpointtarget3, lowpoint4, lowpointtarget4, lowpoint5, lowpointtarget5, lowpoint6, lowpointtarget6, lowpoint7, lowpointtarget7, colpoint, colpoint2;
2408 bool tempcollide = 0;
2410 if (Person::players[k]->collide < -.3)
2411 Person::players[k]->collide = -.3;
2412 if (Person::players[k]->collide > 1)
2413 Person::players[k]->collide = 1;
2414 Person::players[k]->collide -= multiplier * 30;
2417 Person::players[k]->coords.y = max(Person::players[k]->coords.y, terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z));
2419 for (int l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
2420 int i = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
2421 if (Object::objects[i]->type != rocktype ||
2422 Object::objects[i]->scale > .5 && Person::players[k]->aitype == playercontrolled ||
2423 Object::objects[i]->position.y > Person::players[k]->coords.y) {
2424 lowpoint = Person::players[k]->coords;
2425 if (Person::players[k]->animTarget != jumpupanim &&
2426 Person::players[k]->animTarget != jumpdownanim &&
2427 !Person::players[k]->isFlip())
2431 if ( Person::players[k]->coords.y < terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z) &&
2432 Person::players[k]->coords.y > terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z) - .1)
2433 Person::players[k]->coords.y = terrain.getHeight(Person::players[k]->coords.x, Person::players[k]->coords.z);
2434 if (Person::players[k]->SphereCheck(&lowpoint, 1.3, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw, &Object::objects[i]->model) != -1) {
2435 flatfacing = lowpoint - Person::players[k]->coords;
2436 Person::players[k]->coords = lowpoint;
2437 Person::players[k]->coords.y -= 1.3;
2438 Person::players[k]->collide = 1;
2441 //TODO: refactor four similar blocks
2442 if (Person::players[k]->aitype == playercontrolled &&
2443 (Person::players[k]->animTarget == jumpupanim ||
2444 Person::players[k]->animTarget == jumpdownanim ||
2445 Person::players[k]->isFlip()) &&
2446 !Person::players[k]->jumptogglekeydown &&
2447 Person::players[k]->jumpkeydown) {
2448 lowpointtarget = lowpoint + DoRotation(Person::players[k]->facing, 0, -90, 0) * 1.5;
2449 XYZ tempcoords1 = lowpoint;
2450 whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
2451 if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
2452 Person::players[k]->setAnimation(walljumpleftanim);
2453 emit_sound_at(movewhooshsound, Person::players[k]->coords);
2455 pause_sound(whooshsound);
2457 lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
2458 Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
2459 if (lowpointtarget.z < 0)
2460 Person::players[k]->yaw = 180 - Person::players[k]->yaw;
2461 Person::players[k]->targetyaw = Person::players[k]->yaw;
2462 Person::players[k]->lowyaw = Person::players[k]->yaw;
2466 lowpoint = tempcoords1;
2467 lowpointtarget = lowpoint + DoRotation(Person::players[k]->facing, 0, 90, 0) * 1.5;
2468 whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
2469 if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
2470 Person::players[k]->setAnimation(walljumprightanim);
2471 emit_sound_at(movewhooshsound, Person::players[k]->coords);
2473 pause_sound(whooshsound);
2475 lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
2476 Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
2477 if (lowpointtarget.z < 0)
2478 Person::players[k]->yaw = 180 - Person::players[k]->yaw;
2479 Person::players[k]->targetyaw = Person::players[k]->yaw;
2480 Person::players[k]->lowyaw = Person::players[k]->yaw;
2484 lowpoint = tempcoords1;
2485 lowpointtarget = lowpoint + Person::players[k]->facing * 2;
2486 whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
2487 if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
2488 Person::players[k]->setAnimation(walljumpbackanim);
2489 emit_sound_at(movewhooshsound, Person::players[k]->coords);
2491 pause_sound(whooshsound);
2493 lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
2494 Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
2495 if (lowpointtarget.z < 0)
2496 Person::players[k]->yaw = 180 - Person::players[k]->yaw;
2497 Person::players[k]->targetyaw = Person::players[k]->yaw;
2498 Person::players[k]->lowyaw = Person::players[k]->yaw;
2502 lowpoint = tempcoords1;
2503 lowpointtarget = lowpoint - Person::players[k]->facing * 2;
2504 whichhit = Object::objects[i]->model.LineCheck(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
2505 if (whichhit != -1 && fabs(Object::objects[i]->model.facenormals[whichhit].y) < .3) {
2506 Person::players[k]->setAnimation(walljumpfrontanim);
2507 emit_sound_at(movewhooshsound, Person::players[k]->coords);
2509 pause_sound(whooshsound);
2511 lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
2512 Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
2513 if (lowpointtarget.z < 0)
2514 Person::players[k]->yaw = 180 - Person::players[k]->yaw;
2515 Person::players[k]->yaw += 180;
2516 Person::players[k]->targetyaw = Person::players[k]->yaw;
2517 Person::players[k]->lowyaw = Person::players[k]->yaw;
2526 } else if (Object::objects[i]->type == rocktype) {
2527 lowpoint2 = Person::players[k]->coords;
2528 lowpoint = Person::players[k]->coords;
2530 if (Object::objects[i]->model.LineCheck(&lowpoint, &lowpoint2, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1) {
2531 Person::players[k]->coords = colpoint;
2532 Person::players[k]->collide = 1;
2535 if (Person::players[k]->animTarget == jumpdownanim || Person::players[k]->isFlip()) {
2536 //flipped into a rock
2537 if (Person::players[k]->isFlip() && Person::players[k]->targetFrame().label == 7)
2538 Person::players[k]->RagDoll(0);
2540 if (Person::players[k]->animTarget == jumpupanim) {
2541 Person::players[k]->jumppower = -4;
2542 Person::players[k]->animTarget = Person::players[k]->getIdle();
2544 Person::players[k]->target = 0;
2545 Person::players[k]->frameTarget = 0;
2546 Person::players[k]->onterrain = 1;
2548 if (Person::players[k]->id == 0) {
2549 pause_sound(whooshsound);
2550 OPENAL_SetVolume(channels[whooshsound], 0);
2554 if ((Person::players[k]->animTarget == jumpdownanim || Person::players[k]->isFlip()) && !Person::players[k]->wasLanding()) {
2555 if (Person::players[k]->isFlip())
2556 Person::players[k]->jumppower = -4;
2557 Person::players[k]->animTarget = Person::players[k]->getLanding();
2558 emit_sound_at(landsound, Person::players[k]->coords, 128.);
2560 addEnvSound(Person::players[k]->coords);
2569 for (int l = 0; l < terrain.patchobjectnum[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz]; l++) {
2570 int i = terrain.patchobjects[Person::players[k]->whichpatchx][Person::players[k]->whichpatchz][l];
2571 lowpoint = Person::players[k]->coords;
2573 if (Object::objects[i]->type != rocktype)
2574 if (Person::players[k]->SphereCheck(&lowpoint, 1.33, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw, &Object::objects[i]->model) != -1) {
2575 if (Person::players[k]->animTarget != jumpupanim &&
2576 Person::players[k]->animTarget != jumpdownanim &&
2577 Person::players[k]->onterrain)
2578 Person::players[k]->avoidcollided = 1;
2579 Person::players[k]->coords = lowpoint;
2580 Person::players[k]->coords.y -= 1.35;
2581 Person::players[k]->collide = 1;
2583 if ((Person::players[k]->grabdelay <= 0 || Person::players[k]->aitype != playercontrolled) &&
2584 (Person::players[k]->animCurrent != climbanim &&
2585 Person::players[k]->animCurrent != hanganim &&
2586 !Person::players[k]->isWallJump() ||
2587 Person::players[k]->animTarget == jumpupanim ||
2588 Person::players[k]->animTarget == jumpdownanim)) {
2589 lowpoint = Person::players[k]->coords;
2590 Object::objects[i]->model.SphereCheckPossible(&lowpoint, 1.5, &Object::objects[i]->position, &Object::objects[i]->yaw);
2591 lowpoint = Person::players[k]->coords;
2595 facing = DoRotation(facing, 0, Person::players[k]->targetyaw + 180, 0);
2596 lowpointtarget = lowpoint + facing * 1.4;
2597 whichhit = Object::objects[i]->model.LineCheckPossible(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
2598 if (whichhit != -1) {
2599 lowpoint = Person::players[k]->coords;
2601 lowpointtarget = lowpoint + facing * 1.4;
2602 lowpoint2 = lowpoint;
2603 lowpointtarget2 = lowpointtarget;
2604 lowpoint3 = lowpoint;
2605 lowpointtarget3 = lowpointtarget;
2606 lowpoint4 = lowpoint;
2607 lowpointtarget4 = lowpointtarget;
2608 lowpoint5 = lowpoint;
2609 lowpointtarget5 = lowpointtarget;
2610 lowpoint6 = lowpoint;
2611 lowpointtarget6 = lowpointtarget;
2612 lowpoint7 = lowpoint;
2613 lowpointtarget7 = lowpoint;
2615 lowpointtarget2.x += .1;
2617 lowpointtarget3.z += .1;
2619 lowpointtarget4.x -= .1;
2621 lowpointtarget5.z -= .1;
2622 lowpoint6.y += 45 / 13;
2623 lowpointtarget6.y += 45 / 13;
2624 lowpointtarget6 += facing * .6;
2625 lowpointtarget7.y += 90 / 13;
2626 whichhit = Object::objects[i]->model.LineCheckPossible(&lowpoint, &lowpointtarget, &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw);
2627 if (Object::objects[i]->friction > .5)
2628 if (whichhit != -1) {
2629 if (whichhit != -1 && Person::players[k]->animTarget != jumpupanim && Person::players[k]->animTarget != jumpdownanim)
2630 Person::players[k]->collided = 1;
2631 if (checkcollide(lowpoint7, lowpointtarget7) == -1)
2632 if (checkcollide(lowpoint6, lowpointtarget6) == -1)
2633 if ( Object::objects[i]->model.LineCheckPossible(&lowpoint2, &lowpointtarget2,
2634 &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1 &&
2635 Object::objects[i]->model.LineCheckPossible(&lowpoint3, &lowpointtarget3,
2636 &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1 &&
2637 Object::objects[i]->model.LineCheckPossible(&lowpoint4, &lowpointtarget4,
2638 &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1 &&
2639 Object::objects[i]->model.LineCheckPossible(&lowpoint5, &lowpointtarget5,
2640 &colpoint, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
2641 for (int j = 0; j < 45; j++) {
2642 lowpoint = Person::players[k]->coords;
2643 lowpoint.y += (float)j / 13;
2644 lowpointtarget = lowpoint + facing * 1.4;
2645 if (Object::objects[i]->model.LineCheckPossible(&lowpoint, &lowpointtarget,
2646 &colpoint2, &Object::objects[i]->position, &Object::objects[i]->yaw) == -1) {
2647 if (j <= 6 || j <= 25 && Person::players[k]->animTarget == jumpdownanim)
2649 if (Person::players[k]->animTarget == jumpupanim || Person::players[k]->animTarget == jumpdownanim) {
2650 lowpoint = Person::players[k]->coords;
2651 lowpoint.y += (float)j / 13;
2652 lowpointtarget = lowpoint + facing * 1.3;
2653 flatfacing = Person::players[k]->coords;
2654 Person::players[k]->coords = colpoint - DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[k]->yaw, 0) * .01;
2655 Person::players[k]->coords.y = lowpointtarget.y - .07;
2656 Person::players[k]->currentoffset = (flatfacing - Person::players[k]->coords) / Person::players[k]->scale;
2658 if (j > 10 || !Person::players[k]->isRun()) {
2659 if (Person::players[k]->animTarget == jumpdownanim || Person::players[k]->animTarget == jumpupanim) {
2661 pause_sound(whooshsound);
2663 emit_sound_at(jumpsound, Person::players[k]->coords, 128.);
2665 lowpointtarget = DoRotation(Object::objects[i]->model.facenormals[whichhit], 0, Object::objects[i]->yaw, 0);
2666 Person::players[k]->yaw = -asin(0 - lowpointtarget.x) * 180 / M_PI;
2667 if (lowpointtarget.z < 0)
2668 Person::players[k]->yaw = 180 - Person::players[k]->yaw;
2669 Person::players[k]->targetyaw = Person::players[k]->yaw;
2670 Person::players[k]->lowyaw = Person::players[k]->yaw;
2672 //Person::players[k]->velocity=lowpointtarget*.03;
2673 Person::players[k]->velocity = 0;
2676 if (Person::players[k]->animTarget == jumpupanim) {
2677 Person::players[k]->animTarget = climbanim;
2678 Person::players[k]->jumppower = 0;
2679 Person::players[k]->jumpclimb = 1;
2681 Person::players[k]->transspeed = 6;
2682 Person::players[k]->target = 0;
2683 Person::players[k]->frameTarget = 1;
2686 Person::players[k]->setAnimation(hanganim);
2687 Person::players[k]->jumppower = 0;
2699 if (Person::players[k]->collide <= 0) {
2701 if (!Person::players[k]->onterrain &&
2702 Person::players[k]->animTarget != jumpupanim &&
2703 Person::players[k]->animTarget != jumpdownanim &&
2704 Person::players[k]->animTarget != climbanim &&
2705 Person::players[k]->animTarget != hanganim &&
2706 !Person::players[k]->isWallJump() &&
2707 !Person::players[k]->isFlip()) {
2708 if (Person::players[k]->animCurrent != climbanim &&
2709 Person::players[k]->animCurrent != tempanim &&
2710 Person::players[k]->animTarget != backhandspringanim &&
2711 (Person::players[k]->animTarget != rollanim ||
2712 Person::players[k]->frameTarget < 2 ||
2713 Person::players[k]->frameTarget > 6)) {
2714 //stagger off ledge (?)
2715 if (Person::players[k]->animTarget == staggerbackhighanim || Person::players[k]->animTarget == staggerbackhardanim)
2716 Person::players[k]->RagDoll(0);
2717 Person::players[k]->setAnimation(jumpdownanim);
2720 emit_sound_at(whooshsound, Person::players[k]->coords, 128.);
2723 Person::players[k]->velocity.y += gravity;
2727 Person::players[k]->realoldcoords = Person::players[k]->coords;
2733 static int randattack;
2734 static bool playerrealattackkeydown = 0;
2736 if (!Input::isKeyDown(attackkey))
2739 Person::players[0]->attackkeydown = 0;
2741 playerrealattackkeydown = 0;
2743 playerrealattackkeydown = Input::isKeyDown(attackkey);
2744 if ((Person::players[0]->parriedrecently <= 0 ||
2745 Person::players[0]->weaponactive == -1) &&
2748 Person::players[0]->lastattack != swordslashanim &&
2749 Person::players[0]->lastattack != knifeslashstartanim &&
2750 Person::players[0]->lastattack != staffhitanim &&
2751 Person::players[0]->lastattack != staffspinhitanim)))
2752 Person::players[0]->attackkeydown = Input::isKeyDown(attackkey);
2753 if (Input::isKeyDown(attackkey) &&
2755 !Person::players[0]->backkeydown) {
2756 for (unsigned k = 0; k < Person::players.size(); k++) {
2757 if ((Person::players[k]->animTarget == swordslashanim ||
2758 Person::players[k]->animTarget == staffhitanim ||
2759 Person::players[k]->animTarget == staffspinhitanim) &&
2760 Person::players[0]->animCurrent != dodgebackanim &&
2761 !Person::players[k]->skeleton.free)
2762 Person::players[k]->Reverse();
2766 if (!hostile || Dialog::inDialog())
2767 Person::players[0]->attackkeydown = 0;
2769 for (unsigned k = 0; k < Person::players.size(); k++) {
2770 if (Dialog::inDialog())
2771 Person::players[k]->attackkeydown = 0;
2772 if (Person::players[k]->animTarget != rabbitrunninganim && Person::players[k]->animTarget != wolfrunninganim) {
2773 if (Person::players[k]->aitype != playercontrolled)
2774 Person::players[k]->victim = Person::players[0];
2775 //attack key pressed
2776 if (Person::players[k]->attackkeydown) {
2778 if (Person::players[k]->backkeydown &&
2779 Person::players[k]->animTarget != backhandspringanim &&
2780 (Person::players[k]->isIdle() ||
2781 Person::players[k]->isStop() ||
2782 Person::players[k]->isRun() ||
2783 Person::players[k]->animTarget == walkanim)) {
2784 if (Person::players[k]->jumppower <= 1) {
2785 Person::players[k]->jumppower -= 2;
2787 for (unsigned i = 0; i < Person::players.size(); i++) {
2790 if (Person::players[i]->animTarget == swordslashanim ||
2791 Person::players[i]->animTarget == knifeslashstartanim ||
2792 Person::players[i]->animTarget == staffhitanim ||
2793 Person::players[i]->animTarget == staffspinhitanim)
2794 if (distsq(&Person::players[k]->coords, &Person::players[i]->coords) < 6.5 && !Person::players[i]->skeleton.free) {
2795 Person::players[k]->setAnimation(dodgebackanim);
2796 Person::players[k]->targetyaw = roughDirectionTo(Person::players[k]->coords, Person::players[i]->coords);
2797 Person::players[k]->targettilt2 = pitchTo(Person::players[k]->coords, Person::players[i]->coords);
2800 if (Person::players[k]->animTarget != dodgebackanim) {
2803 Person::players[k]->setAnimation(backhandspringanim);
2804 Person::players[k]->targetyaw = -yaw + 180;
2805 if (Person::players[k]->leftkeydown)
2806 Person::players[k]->targetyaw -= 45;
2807 if (Person::players[k]->rightkeydown)
2808 Person::players[k]->targetyaw += 45;
2809 Person::players[k]->yaw = Person::players[k]->targetyaw;
2810 Person::players[k]->jumppower -= 2;
2815 if (!Animation::animations[Person::players[k]->animTarget].attack &&
2816 !Person::players[k]->backkeydown &&
2817 (Person::players[k]->isIdle() ||
2818 Person::players[k]->isRun() ||
2819 Person::players[k]->animTarget == walkanim ||
2820 Person::players[k]->animTarget == sneakanim ||
2821 Person::players[k]->isCrouch())) {
2822 const int attackweapon = Person::players[k]->weaponactive == -1 ? 0 : weapons[Person::players[k]->weaponids[Person::players[k]->weaponactive]].getType();
2823 //normal attacks (?)
2824 Person::players[k]->hasvictim = 0;
2825 if (Person::players.size() > 1)
2826 for (unsigned i = 0; i < Person::players.size(); i++) {
2827 if (i == k || !(k == 0 || i == 0))
2829 if (!Person::players[k]->hasvictim)
2830 if (Animation::animations[Person::players[k]->animTarget].attack != reversal) {
2832 const float distance = distsq(&Person::players[k]->coords, &Person::players[i]->coords);
2833 if (distance < 4.5 &&
2834 !Person::players[i]->skeleton.free &&
2835 Person::players[i]->howactive < typedead1 &&
2836 Person::players[i]->animTarget != jumpreversedanim &&
2837 Person::players[i]->animTarget != rabbitkickreversedanim &&
2838 Person::players[i]->animTarget != rabbitkickanim &&
2839 Person::players[k]->animTarget != rabbitkickanim &&
2840 Person::players[i]->animTarget != getupfrombackanim &&
2841 (Person::players[i]->animTarget != staggerbackhighanim &&
2842 (Person::players[i]->animTarget != staggerbackhardanim || Person::players[i]->targetFrame().label == 6)) &&
2843 Person::players[i]->animTarget != jumpdownanim &&
2844 Person::players[i]->animTarget != jumpupanim &&
2845 Person::players[i]->animTarget != getupfromfrontanim) {
2846 Person::players[k]->victim = Person::players[i];
2847 Person::players[k]->hasvictim = 1;
2848 if (Person::players[k]->aitype == playercontrolled) { //human player
2850 if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2851 Person::players[k]->crouchkeydown &&
2852 Animation::animations[Person::players[i]->animTarget].height != lowheight)
2853 Person::players[k]->animTarget = sweepanim;
2855 else if (distance < 1.5 * sq(Person::players[k]->scale * 5) &&
2856 Animation::animations[Person::players[i]->animTarget].height != lowheight &&
2857 !Person::players[k]->forwardkeydown &&
2858 !Person::players[k]->leftkeydown &&
2859 !Person::players[k]->rightkeydown &&
2860 !Person::players[k]->crouchkeydown &&
2863 Person::players[k]->animTarget = winduppunchanim;
2865 else if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2866 Animation::animations[Person::players[i]->animTarget].height != lowheight &&
2867 !Person::players[k]->forwardkeydown &&
2868 !Person::players[k]->leftkeydown &&
2869 !Person::players[k]->rightkeydown &&
2870 !Person::players[k]->crouchkeydown &&
2872 Person::players[k]->animTarget = upunchanim;
2874 else if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2875 Person::players[i]->staggerdelay > 0 &&
2876 attackweapon == knife &&
2877 Person::players[i]->bloodloss > Person::players[i]->damagetolerance / 2)
2878 Person::players[k]->animTarget = knifefollowanim;
2880 else if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2881 Animation::animations[Person::players[i]->animTarget].height != lowheight &&
2882 !Person::players[k]->forwardkeydown &&
2883 !Person::players[k]->leftkeydown &&
2884 !Person::players[k]->rightkeydown &&
2885 !Person::players[k]->crouchkeydown &&
2886 attackweapon == knife &&
2887 Person::players[k]->weaponmissdelay <= 0)
2888 Person::players[k]->animTarget = knifeslashstartanim;
2890 else if (distance < 4.5 * sq(Person::players[k]->scale * 5) &&
2891 Animation::animations[Person::players[i]->animTarget].height != lowheight &&
2892 !Person::players[k]->crouchkeydown &&
2893 attackweapon == sword &&
2894 Person::players[k]->weaponmissdelay <= 0)
2895 Person::players[k]->animTarget = swordslashanim;
2897 else if (distance < 4.5 * sq(Person::players[k]->scale * 5) &&
2898 Animation::animations[Person::players[i]->animTarget].height != lowheight &&
2899 !Person::players[k]->crouchkeydown &&
2900 attackweapon == staff &&
2901 Person::players[k]->weaponmissdelay <= 0 &&
2902 !Person::players[k]->leftkeydown &&
2903 !Person::players[k]->rightkeydown &&
2904 !Person::players[k]->forwardkeydown)
2905 Person::players[k]->animTarget = staffhitanim;
2907 else if (distance < 4.5 * sq(Person::players[k]->scale * 5) &&
2908 Animation::animations[Person::players[i]->animTarget].height != lowheight &&
2909 !Person::players[k]->crouchkeydown &&
2910 attackweapon == staff &&
2911 Person::players[k]->weaponmissdelay <= 0)
2912 Person::players[k]->animTarget = staffspinhitanim;
2914 else if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2915 Animation::animations[Person::players[i]->animTarget].height != lowheight)
2916 Person::players[k]->animTarget = spinkickanim;
2918 else if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2919 Animation::animations[Person::players[i]->animTarget].height == lowheight &&
2920 Animation::animations[Person::players[k]->animTarget].attack != normalattack)
2921 Person::players[k]->animTarget = lowkickanim;
2922 } else { //AI player
2923 if (distance < 4.5 * sq(Person::players[k]->scale * 5)) {
2924 randattack = abs(Random() % 5);
2925 if (!attackweapon && distance < 2.5 * sq(Person::players[k]->scale * 5)) {
2927 if (randattack == 0 && Animation::animations[Person::players[i]->animTarget].height != lowheight)
2928 Person::players[k]->animTarget = sweepanim;
2930 else if (randattack == 1 && Animation::animations[Person::players[i]->animTarget].height != lowheight &&
2932 Person::players[k]->animTarget = upunchanim;
2934 else if (randattack == 2 && Animation::animations[Person::players[i]->animTarget].height != lowheight)
2935 Person::players[k]->animTarget = spinkickanim;
2937 else if (Animation::animations[Person::players[i]->animTarget].height == lowheight)
2938 Person::players[k]->animTarget = lowkickanim;
2942 if ((tutoriallevel != 1 || !attackweapon) &&
2943 distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2945 Animation::animations[Person::players[i]->animTarget].height != lowheight)
2946 Person::players[k]->animTarget = sweepanim;
2948 else if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2949 attackweapon == knife &&
2950 Person::players[k]->weaponmissdelay <= 0)
2951 Person::players[k]->animTarget = knifeslashstartanim;
2953 else if (!(Person::players[0]->victim == Person::players[i] &&
2954 Person::players[0]->hasvictim &&
2955 Person::players[0]->animTarget == swordslashanim) &&
2956 attackweapon == sword &&
2957 Person::players[k]->weaponmissdelay <= 0)
2958 Person::players[k]->animTarget = swordslashanim;
2960 else if (!(Person::players[0]->victim == Person::players[i] &&
2961 Person::players[0]->hasvictim &&
2962 Person::players[0]->animTarget == swordslashanim) &&
2963 attackweapon == staff &&
2964 Person::players[k]->weaponmissdelay <= 0 &&
2966 Person::players[k]->animTarget = staffhitanim;
2968 else if (!(Person::players[0]->victim == Person::players[i] &&
2969 Person::players[0]->hasvictim &&
2970 Person::players[0]->animTarget == swordslashanim) &&
2971 attackweapon == staff &&
2972 Person::players[k]->weaponmissdelay <= 0 &&
2974 Person::players[k]->animTarget = staffspinhitanim;
2976 else if ((tutoriallevel != 1 || !attackweapon) &&
2977 distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2979 Animation::animations[Person::players[i]->animTarget].height != lowheight)
2980 Person::players[k]->animTarget = spinkickanim;
2982 else if (distance < 2.5 * sq(Person::players[k]->scale * 5) &&
2983 Animation::animations[Person::players[i]->animTarget].height == lowheight &&
2984 Animation::animations[Person::players[k]->animTarget].attack != normalattack)
2985 Person::players[k]->animTarget = lowkickanim;
2989 //upunch becomes wolfslap
2990 if (Person::players[k]->animTarget == upunchanim && Person::players[k]->creature == wolftype)
2991 Person::players[k]->animTarget = wolfslapanim;
2994 if ((k == 0) && (tutoriallevel != 1 || tutorialstage == 22) &&
2995 Person::players[i]->howactive < typedead1 &&
2996 distance < 1.5 * sq(Person::players[k]->scale * 5) &&
2997 !Person::players[i]->skeleton.free &&
2998 Person::players[i]->animTarget != getupfrombackanim &&
2999 Person::players[i]->animTarget != getupfromfrontanim &&
3000 (Person::players[i]->surprised > 0 ||
3001 Person::players[i]->aitype == passivetype ||
3002 attackweapon && Person::players[i]->stunned > 0) &&
3003 normaldotproduct(Person::players[i]->facing, Person::players[i]->coords - Person::players[k]->coords) > 0) {
3005 if (!attackweapon) {
3006 Person::players[k]->animCurrent = sneakattackanim;
3007 Person::players[k]->animTarget = sneakattackanim;
3008 Person::players[i]->animCurrent = sneakattackedanim;
3009 Person::players[i]->animTarget = sneakattackedanim;
3010 Person::players[k]->oldcoords = Person::players[k]->coords;
3011 Person::players[k]->coords = Person::players[i]->coords;
3014 if (attackweapon == knife) {
3015 Person::players[k]->animCurrent = knifesneakattackanim;
3016 Person::players[k]->animTarget = knifesneakattackanim;
3017 Person::players[i]->animCurrent = knifesneakattackedanim;
3018 Person::players[i]->animTarget = knifesneakattackedanim;
3019 Person::players[i]->oldcoords = Person::players[i]->coords;
3020 Person::players[i]->coords = Person::players[k]->coords;
3023 if (attackweapon == sword) {
3024 Person::players[k]->animCurrent = swordsneakattackanim;
3025 Person::players[k]->animTarget = swordsneakattackanim;
3026 Person::players[i]->animCurrent = swordsneakattackedanim;
3027 Person::players[i]->animTarget = swordsneakattackedanim;
3028 Person::players[i]->oldcoords = Person::players[i]->coords;
3029 Person::players[i]->coords = Person::players[k]->coords;
3031 if (attackweapon != staff) {
3032 Person::players[k]->victim = Person::players[i];
3033 Person::players[k]->hasvictim = 1;
3034 Person::players[i]->targettilt2 = 0;
3035 Person::players[i]->frameTarget = 1;
3036 Person::players[i]->frameCurrent = 0;
3037 Person::players[i]->target = 0;
3038 Person::players[i]->velocity = 0;
3039 Person::players[k]->targettilt2 = Person::players[i]->targettilt2;
3040 Person::players[k]->frameCurrent = Person::players[i]->frameCurrent;
3041 Person::players[k]->frameTarget = Person::players[i]->frameTarget;
3042 Person::players[k]->target = Person::players[i]->target;
3043 Person::players[k]->velocity = 0;
3044 Person::players[k]->targetyaw = Person::players[i]->yaw;
3045 Person::players[k]->yaw = Person::players[i]->yaw;
3046 Person::players[i]->targetyaw = Person::players[i]->yaw;
3049 if (Animation::animations[Person::players[k]->animTarget].attack == normalattack &&
3050 Person::players[k]->victim == Person::players[i] &&
3051 (!Person::players[i]->skeleton.free)) {
3053 Person::players[k]->frameTarget = 0;
3054 Person::players[k]->target = 0;
3056 Person::players[k]->targetyaw = roughDirectionTo(Person::players[k]->coords, Person::players[i]->coords);
3057 Person::players[k]->targettilt2 = pitchTo(Person::players[k]->coords, Person::players[i]->coords);
3058 Person::players[k]->lastattack3 = Person::players[k]->lastattack2;
3059 Person::players[k]->lastattack2 = Person::players[k]->lastattack;
3060 Person::players[k]->lastattack = Person::players[k]->animTarget;
3062 if (Person::players[k]->animTarget == knifefollowanim &&
3063 Person::players[k]->victim == Person::players[i]) {
3065 Person::players[k]->targetyaw = roughDirectionTo(Person::players[k]->coords, Person::players[i]->coords);
3066 Person::players[k]->targettilt2 = pitchTo(Person::players[k]->coords, Person::players[i]->coords);
3067 Person::players[k]->victim = Person::players[i];
3068 Person::players[k]->hasvictim = 1;
3069 Person::players[i]->animTarget = knifefollowedanim;
3070 Person::players[i]->animCurrent = knifefollowedanim;
3071 Person::players[i]->targettilt2 = 0;
3072 Person::players[i]->targettilt2 = Person::players[k]->targettilt2;
3073 Person::players[i]->frameTarget = 1;
3074 Person::players[i]->frameCurrent = 0;
3075 Person::players[i]->target = 0;
3076 Person::players[i]->velocity = 0;
3077 Person::players[k]->animCurrent = knifefollowanim;
3078 Person::players[k]->animTarget = knifefollowanim;
3079 Person::players[k]->targettilt2 = Person::players[i]->targettilt2;
3080 Person::players[k]->frameCurrent = Person::players[i]->frameCurrent;
3081 Person::players[k]->frameTarget = Person::players[i]->frameTarget;
3082 Person::players[k]->target = Person::players[i]->target;
3083 Person::players[k]->velocity = 0;
3084 Person::players[k]->oldcoords = Person::players[k]->coords;
3085 Person::players[i]->coords = Person::players[k]->coords;
3086 Person::players[i]->targetyaw = Person::players[k]->targetyaw;
3087 Person::players[i]->yaw = Person::players[k]->targetyaw;
3088 Person::players[k]->yaw = Person::players[k]->targetyaw;
3089 Person::players[i]->yaw = Person::players[k]->targetyaw;
3093 const bool hasstaff = attackweapon == staff;
3094 if (k == 0 && Person::players.size() > 1)
3095 for (unsigned i = 0; i < Person::players.size(); i++) {
3098 if ((playerrealattackkeydown || Person::players[i]->dead || !hasstaff) &&
3099 Animation::animations[Person::players[k]->animTarget].attack == neutral) {
3100 const float distance = distsq(&Person::players[k]->coords, &Person::players[i]->coords);
3101 if (!Person::players[i]->dead || !realthreat || (!attackweapon && Person::players[k]->crouchkeydown))
3102 if (Person::players[i]->skeleton.free)
3103 if (distance < 3.5 * sq(Person::players[k]->scale * 5) &&
3104 (Person::players[i]->dead ||
3105 Person::players[i]->skeleton.longdead > 1000 ||
3106 Person::players[k]->isRun() ||
3109 (Person::players[i]->skeleton.longdead > 2000 ||
3110 Person::players[i]->damage > Person::players[i]->damagetolerance / 8 ||
3111 Person::players[i]->bloodloss > Person::players[i]->damagetolerance / 2) &&
3112 distance < 1.5 * sq(Person::players[k]->scale * 5)))) {
3113 Person::players[k]->victim = Person::players[i];
3114 Person::players[k]->hasvictim = 1;
3115 if (attackweapon && tutoriallevel != 1) {
3117 if (Person::players[k]->crouchkeydown && attackweapon == knife && distance < 1.5 * sq(Person::players[k]->scale * 5))
3118 Person::players[k]->animTarget = crouchstabanim;
3120 if (Person::players[k]->crouchkeydown && distance < 1.5 * sq(Person::players[k]->scale * 5) && attackweapon == sword)
3121 Person::players[k]->animTarget = swordgroundstabanim;
3123 if (distance < 3.5 * sq(Person::players[k]->scale * 5) && attackweapon == staff)
3124 Person::players[k]->animTarget = staffgroundsmashanim;
3126 if (distance < 2.5 &&
3127 Person::players[k]->crouchkeydown &&
3128 Person::players[k]->animTarget != crouchstabanim &&
3130 Person::players[i]->dead &&
3131 Person::players[i]->skeleton.free &&
3132 Person::players[i]->skeleton.longdead > 1000) {
3133 Person::players[k]->animTarget = killanim;
3134 //TODO: refactor this out, what does it do?
3135 for (int j = 0; j < terrain.numdecals; j++) {
3136 if ((terrain.decaltype[j] == blooddecal || terrain.decaltype[j] == blooddecalslow) &&
3137 terrain.decalalivetime[j] < 2)
3138 terrain.DeleteDecal(j);
3140 for (int l = 0; l < Object::objects.size(); l++) {
3141 if (Object::objects[l]->model.type == decalstype)
3142 for (int j = 0; j < Object::objects[l]->model.numdecals; j++) {
3143 if ((Object::objects[l]->model.decaltype[j] == blooddecal ||
3144 Object::objects[l]->model.decaltype[j] == blooddecalslow) &&
3145 Object::objects[l]->model.decalalivetime[j] < 2)
3146 Object::objects[l]->model.DeleteDecal(j);
3150 if (!Person::players[i]->dead || musictype != 2)
3151 if (distance < 3.5 &&
3152 (Person::players[k]->isRun() || Person::players[k]->isIdle() && Person::players[k]->attackkeydown) &&
3153 Person::players[k]->staggerdelay <= 0 &&
3154 (Person::players[i]->dead ||
3155 Person::players[i]->skeleton.longdead < 300 &&
3156 Person::players[k]->lastattack != spinkickanim &&
3157 Person::players[i]->skeleton.free) &&
3158 (!Person::players[i]->dead || musictype != stream_fighttheme)) {
3159 Person::players[k]->animTarget = dropkickanim;
3160 for (int j = 0; j < terrain.numdecals; j++) {
3161 if ((terrain.decaltype[j] == blooddecal || terrain.decaltype[j] == blooddecalslow) &&
3162 terrain.decalalivetime[j] < 2) {
3163 terrain.DeleteDecal(j);
3166 for (int l = 0; l < Object::objects.size(); l++) {
3167 if (Object::objects[l]->model.type == decalstype)
3168 for (int j = 0; j < Object::objects[l]->model.numdecals; j++) {
3169 if ((Object::objects[l]->model.decaltype[j] == blooddecal ||
3170 Object::objects[l]->model.decaltype[j] == blooddecalslow) &&
3171 Object::objects[l]->model.decalalivetime[j] < 2) {
3172 Object::objects[l]->model.DeleteDecal(j);
3178 if (Animation::animations[Person::players[k]->animTarget].attack == normalattack &&
3179 Person::players[k]->victim == Person::players[i] &&
3180 (!Person::players[i]->skeleton.free ||
3181 Person::players[k]->animTarget == killanim ||
3182 Person::players[k]->animTarget == crouchstabanim ||
3183 Person::players[k]->animTarget == swordgroundstabanim ||
3184 Person::players[k]->animTarget == staffgroundsmashanim ||
3185 Person::players[k]->animTarget == dropkickanim)) {
3187 Person::players[k]->frameTarget = 0;
3188 Person::players[k]->target = 0;
3190 XYZ targetpoint = Person::players[i]->coords;
3191 if (Person::players[k]->animTarget == crouchstabanim ||
3192 Person::players[k]->animTarget == swordgroundstabanim ||
3193 Person::players[k]->animTarget == staffgroundsmashanim) {
3194 targetpoint += (Person::players[i]->jointPos(abdomen) +
3195 Person::players[i]->jointPos(neck)) / 2 *
3196 Person::players[i]->scale;
3198 Person::players[k]->targetyaw = roughDirectionTo(Person::players[k]->coords, targetpoint);
3199 Person::players[k]->targettilt2 = pitchTo(Person::players[k]->coords, targetpoint);
3201 if (Person::players[k]->animTarget == crouchstabanim || Person::players[k]->animTarget == swordgroundstabanim) {
3202 Person::players[k]->targetyaw += (float)(abs(Random() % 100) - 50) / 4;
3205 if (Person::players[k]->animTarget == staffgroundsmashanim)
3206 Person::players[k]->targettilt2 += 10;
3208 Person::players[k]->lastattack3 = Person::players[k]->lastattack2;
3209 Person::players[k]->lastattack2 = Person::players[k]->lastattack;
3210 Person::players[k]->lastattack = Person::players[k]->animTarget;
3212 if (Person::players[k]->animTarget == swordgroundstabanim) {
3213 Person::players[k]->targetyaw += 30;
3218 if (!Person::players[k]->hasvictim) {
3220 for (unsigned i = 0; i < Person::players.size(); i++) {
3221 if (i == k || !(i == 0 || k == 0))
3223 if (!Person::players[i]->skeleton.free) {
3224 if (Person::players[k]->hasvictim) {
3225 if (distsq(&Person::players[k]->coords, &Person::players[i]->coords) <
3226 distsq(&Person::players[k]->coords, &Person::players[k]->victim->coords))
3227 Person::players[k]->victim = Person::players[i];
3229 Person::players[k]->victim = Person::players[i];
3230 Person::players[k]->hasvictim = 1;
3235 if (Person::players[k]->aitype == playercontrolled)
3237 if (Person::players[k]->attackkeydown &&
3238 Person::players[k]->isRun() &&
3239 Person::players[k]->wasRun() &&
3240 ((Person::players[k]->hasvictim &&
3241 distsq(&Person::players[k]->coords, &Person::players[k]->victim->coords) < 12 * sq(Person::players[k]->scale * 5) &&
3242 distsq(&Person::players[k]->coords, &Person::players[k]->victim->coords) > 7 * sq(Person::players[k]->scale * 5) &&
3243 !Person::players[k]->victim->skeleton.free &&
3244 Person::players[k]->victim->animTarget != getupfrombackanim &&
3245 Person::players[k]->victim->animTarget != getupfromfrontanim &&
3246 Animation::animations[Person::players[k]->victim->animTarget].height != lowheight &&
3247 Person::players[k]->aitype != playercontrolled && //wat???
3248 normaldotproduct(Person::players[k]->facing, Person::players[k]->victim->coords - Person::players[k]->coords) > 0 &&
3249 Person::players[k]->rabbitkickenabled) ||
3250 Person::players[k]->jumpkeydown)) {
3252 Person::players[k]->setAnimation(rabbitkickanim);
3255 if (Animation::animations[Person::players[k]->animTarget].attack && k == 0) {
3257 switch (attackweapon) {
3278 void doPlayerCollisions()
3280 static XYZ rotatetarget;
3281 static float collisionradius;
3282 if (Person::players.size() > 1)
3283 for (unsigned k = 0; k < Person::players.size(); k++)
3284 for (unsigned i = k + 1; i < Person::players.size(); i++) {
3285 //neither player is part of a reversal
3286 if ((Animation::animations[Person::players[i]->animTarget].attack != reversed &&
3287 Animation::animations[Person::players[i]->animTarget].attack != reversal &&
3288 Animation::animations[Person::players[k]->animTarget].attack != reversed &&
3289 Animation::animations[Person::players[k]->animTarget].attack != reversal) || (i != 0 && k != 0))
3290 if ((Animation::animations[Person::players[i]->animCurrent].attack != reversed &&
3291 Animation::animations[Person::players[i]->animCurrent].attack != reversal &&
3292 Animation::animations[Person::players[k]->animCurrent].attack != reversed &&
3293 Animation::animations[Person::players[k]->animCurrent].attack != reversal) || (i != 0 && k != 0))
3294 //neither is sleeping
3295 if (Person::players[i]->howactive <= typesleeping && Person::players[k]->howactive <= typesleeping)
3296 if (Person::players[i]->howactive != typesittingwall && Person::players[k]->howactive != typesittingwall)
3297 //in same patch, neither is climbing
3298 if (Person::players[i]->whichpatchx == Person::players[k]->whichpatchx &&
3299 Person::players[i]->whichpatchz == Person::players[k]->whichpatchz &&
3300 Person::players[k]->skeleton.oldfree == Person::players[k]->skeleton.free &&
3301 Person::players[i]->skeleton.oldfree == Person::players[i]->skeleton.free &&
3302 Person::players[i]->animTarget != climbanim &&
3303 Person::players[i]->animTarget != hanganim &&
3304 Person::players[k]->animTarget != climbanim &&
3305 Person::players[k]->animTarget != hanganim)
3306 //players are close (bounding box test)
3307 if (Person::players[i]->coords.y > Person::players[k]->coords.y - 3)
3308 if (Person::players[i]->coords.y < Person::players[k]->coords.y + 3)
3309 if (Person::players[i]->coords.x > Person::players[k]->coords.x - 3)
3310 if (Person::players[i]->coords.x < Person::players[k]->coords.x + 3)
3311 if (Person::players[i]->coords.z > Person::players[k]->coords.z - 3)
3312 if (Person::players[i]->coords.z < Person::players[k]->coords.z + 3) {
3313 //spread fire from player to player
3314 if (distsq(&Person::players[i]->coords, &Person::players[k]->coords)
3315 < 3 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5)) {
3316 if (Person::players[i]->onfire || Person::players[k]->onfire) {
3317 if (!Person::players[i]->onfire)
3318 Person::players[i]->CatchFire();
3319 if (!Person::players[k]->onfire)
3320 Person::players[k]->CatchFire();
3324 XYZ tempcoords1 = Person::players[i]->coords;
3325 XYZ tempcoords2 = Person::players[k]->coords;
3326 if (!Person::players[i]->skeleton.oldfree)
3327 tempcoords1.y += Person::players[i]->jointPos(abdomen).y * Person::players[i]->scale;
3328 if (!Person::players[k]->skeleton.oldfree)
3329 tempcoords2.y += Person::players[k]->jointPos(abdomen).y * Person::players[k]->scale;
3330 collisionradius = 1.2 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5);
3331 if (Person::players[0]->hasvictim)
3332 if (Person::players[0]->animTarget == rabbitkickanim && (k == 0 || i == 0) && !Person::players[0]->victim->skeleton.free)
3333 collisionradius = 3;
3334 if ((!Person::players[i]->skeleton.oldfree || !Person::players[k]->skeleton.oldfree) &&
3335 (distsq(&tempcoords1, &tempcoords2) < collisionradius ||
3336 distsq(&Person::players[i]->coords, &Person::players[k]->coords) < collisionradius)) {
3337 //jump down on a dead body
3338 if (k == 0 || i == 0) {
3340 if (Person::players[0]->animTarget == jumpdownanim &&
3341 !Person::players[0]->skeleton.oldfree &&
3342 !Person::players[0]->skeleton.free &&
3343 Person::players[l]->skeleton.oldfree &&
3344 Person::players[l]->skeleton.free &&
3345 Person::players[l]->dead &&
3346 Person::players[0]->lastcollide <= 0 &&
3347 fabs(Person::players[l]->coords.y - Person::players[0]->coords.y) < .2 &&
3348 distsq(&Person::players[0]->coords, &Person::players[l]->coords) < .7 * sq((Person::players[l]->scale + Person::players[0]->scale) * 2.5)) {
3349 Person::players[0]->coords.y = Person::players[l]->coords.y;
3350 Person::players[l]->velocity = Person::players[0]->velocity;
3351 Person::players[l]->skeleton.free = 0;
3352 Person::players[l]->yaw = 0;
3353 Person::players[l]->RagDoll(0);
3354 Person::players[l]->DoDamage(20);
3356 Person::players[l]->skeleton.longdead = 0;
3357 Person::players[0]->lastcollide = 1;
3361 if ( (Person::players[i]->skeleton.oldfree == 1 && findLengthfast(&Person::players[i]->velocity) > 1) ||
3362 (Person::players[k]->skeleton.oldfree == 1 && findLengthfast(&Person::players[k]->velocity) > 1) ||
3363 (Person::players[i]->skeleton.oldfree == 0 && Person::players[k]->skeleton.oldfree == 0)) {
3364 rotatetarget = Person::players[k]->velocity - Person::players[i]->velocity;
3365 if ((Person::players[i]->animTarget != getupfrombackanim && Person::players[i]->animTarget != getupfromfrontanim ||
3366 Person::players[i]->skeleton.free) &&
3367 (Person::players[k]->animTarget != getupfrombackanim && Person::players[k]->animTarget != getupfromfrontanim ||
3368 Person::players[k]->skeleton.free))
3369 if ((((k != 0 && findLengthfast(&rotatetarget) > 150 ||
3370 k == 0 && findLengthfast(&rotatetarget) > 50 && Person::players[0]->rabbitkickragdoll) &&
3371 normaldotproduct(rotatetarget, Person::players[k]->coords - Person::players[i]->coords) > 0) &&
3373 k != 0 && Person::players[i]->skeleton.oldfree == 1 && Animation::animations[Person::players[k]->animCurrent].attack == neutral ||
3374 /*i!=0&&*/Person::players[k]->skeleton.oldfree == 1 && Animation::animations[Person::players[i]->animCurrent].attack == neutral)) ||
3375 (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim || Person::players[i]->isFlip()) &&
3376 (Person::players[k]->animTarget == jumpupanim || Person::players[k]->animTarget == jumpdownanim || Person::players[k]->isFlip()) &&
3377 k == 0 && !Person::players[i]->skeleton.oldfree && !Person::players[k]->skeleton.oldfree) {
3379 if ( (i != 0 || Person::players[i]->skeleton.free) &&
3380 (k != 0 || Person::players[k]->skeleton.free) ||
3381 (Animation::animations[Person::players[i]->animTarget].height == highheight &&
3382 Animation::animations[Person::players[k]->animTarget].height == highheight)) {
3383 if (tutoriallevel != 1) {
3384 emit_sound_at(heavyimpactsound, Person::players[i]->coords);
3387 Person::players[i]->RagDoll(0);
3388 if (Person::players[i]->damage > Person::players[i]->damagetolerance - findLengthfast(&rotatetarget) / 4 && !Person::players[i]->dead) {
3389 award_bonus(0, aimbonus);
3391 Person::players[i]->DoDamage(findLengthfast(&rotatetarget) / 4);
3392 Person::players[k]->RagDoll(0);
3393 if (Person::players[k]->damage > Person::players[k]->damagetolerance - findLengthfast(&rotatetarget) / 4 && !Person::players[k]->dead) {
3394 award_bonus(0, aimbonus); // Huh, again?
3396 Person::players[k]->DoDamage(findLengthfast(&rotatetarget) / 4);
3398 for (unsigned j = 0; j < Person::players[i]->skeleton.joints.size(); j++) {
3399 Person::players[i]->skeleton.joints[j].velocity = Person::players[i]->skeleton.joints[j].velocity / 5 + Person::players[k]->velocity;
3401 for (unsigned j = 0; j < Person::players[k]->skeleton.joints.size(); j++) {
3402 Person::players[k]->skeleton.joints[j].velocity = Person::players[k]->skeleton.joints[j].velocity / 5 + Person::players[i]->velocity;
3407 if ( (Animation::animations[Person::players[i]->animTarget].attack == neutral ||
3408 Animation::animations[Person::players[i]->animTarget].attack == normalattack) &&
3409 (Animation::animations[Person::players[k]->animTarget].attack == neutral ||
3410 Animation::animations[Person::players[k]->animTarget].attack == normalattack)) {
3412 if (Person::players[i]->skeleton.oldfree == 0 && Person::players[k]->skeleton.oldfree == 0) {
3413 if (distsq(&Person::players[k]->coords, &Person::players[i]->coords) < .5 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5)) {
3414 rotatetarget = Person::players[k]->coords - Person::players[i]->coords;
3415 Normalise(&rotatetarget);
3416 Person::players[k]->coords = (Person::players[k]->coords + Person::players[i]->coords) / 2;
3417 Person::players[i]->coords = Person::players[k]->coords - rotatetarget * fast_sqrt(.6) / 2
3418 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5);
3419 Person::players[k]->coords += rotatetarget * fast_sqrt(.6) / 2 * sq((Person::players[i]->scale + Person::players[k]->scale) * 2.5);
3420 if (Person::players[k]->howactive == typeactive || hostile)
3421 if (Person::players[k]->isIdle()) {
3422 if (Person::players[k]->howactive < typesleeping)
3423 Person::players[k]->setAnimation(Person::players[k]->getStop());
3424 else if (Person::players[k]->howactive == typesleeping)
3425 Person::players[k]->setAnimation(getupfromfrontanim);
3427 Person::players[k]->howactive = typeactive;
3429 if (Person::players[i]->howactive == typeactive || hostile)
3430 if (Person::players[i]->isIdle()) {
3431 if (Person::players[i]->howactive < typesleeping)
3432 Person::players[i]->setAnimation(Person::players[k]->getStop());
3434 Person::players[i]->setAnimation(getupfromfrontanim);
3436 Person::players[i]->howactive = typeactive;
3439 //jump down on player
3441 if (k == 0 && i != 0 && Person::players[k]->animTarget == jumpdownanim &&
3442 !Person::players[i]->isCrouch() &&
3443 Person::players[i]->animTarget != rollanim &&
3444 !Person::players[k]->skeleton.oldfree && !
3445 Person::players[k]->skeleton.free &&
3446 Person::players[k]->lastcollide <= 0 &&
3447 Person::players[k]->velocity.y < -10) {
3448 Person::players[i]->velocity = Person::players[k]->velocity;
3449 Person::players[k]->velocity = Person::players[k]->velocity * -.5;
3450 Person::players[k]->velocity.y = Person::players[i]->velocity.y;
3451 Person::players[i]->DoDamage(20);
3452 Person::players[i]->RagDoll(0);
3453 Person::players[k]->lastcollide = 1;
3454 award_bonus(k, AboveBonus);
3456 if (i == 0 && k != 0 && Person::players[i]->animTarget == jumpdownanim &&
3457 !Person::players[k]->isCrouch() &&
3458 Person::players[k]->animTarget != rollanim &&
3459 !Person::players[i]->skeleton.oldfree &&
3460 !Person::players[i]->skeleton.free &&
3461 Person::players[i]->lastcollide <= 0 &&
3462 Person::players[i]->velocity.y < -10) {
3463 Person::players[k]->velocity = Person::players[i]->velocity;
3464 Person::players[i]->velocity = Person::players[i]->velocity * -.3;
3465 Person::players[i]->velocity.y = Person::players[k]->velocity.y;
3466 Person::players[k]->DoDamage(20);
3467 Person::players[k]->RagDoll(0);
3468 Person::players[i]->lastcollide = 1;
3469 award_bonus(i, AboveBonus);
3475 Person::players[i]->CheckKick();
3476 Person::players[k]->CheckKick();
3482 void doAI(unsigned i)
3484 static bool connected;
3485 if (Person::players[i]->aitype != playercontrolled && !Dialog::inDialog()) {
3486 Person::players[i]->jumpclimb = 0;
3487 //disable movement in editor
3489 Person::players[i]->stunned = 1;
3491 Person::players[i]->pause = 0;
3492 if (distsqflat(&Person::players[0]->coords, &Person::players[i]->coords) < 30 &&
3493 Person::players[0]->coords.y > Person::players[i]->coords.y + 2 &&
3494 !Person::players[0]->onterrain)
3495 Person::players[i]->pause = 1;
3498 if (Person::players[i]->aitype == pathfindtype) {
3499 if (Person::players[i]->finalpathfindpoint == -1) {
3500 float closestdistance;
3505 closestdistance = -1;
3506 for (int j = 0; j < numpathpoints; j++) {
3507 if (closest == -1 || distsq(&Person::players[i]->finalfinaltarget, &pathpoint[j]) < closestdistance) {
3508 closestdistance = distsq(&Person::players[i]->finalfinaltarget, &pathpoint[j]);
3510 Person::players[i]->finaltarget = pathpoint[j];
3513 Person::players[i]->finalpathfindpoint = closest;
3514 for (int j = 0; j < numpathpoints; j++) {
3515 for (int k = 0; k < numpathpointconnect[j]; k++) {
3516 DistancePointLine(&Person::players[i]->finalfinaltarget, &pathpoint[j], &pathpoint[pathpointconnect[j][k]], &tempdist, &colpoint);
3517 if (sq(tempdist) < closestdistance)
3518 if (findDistance(&colpoint, &pathpoint[j]) + findDistance(&colpoint, &pathpoint[pathpointconnect[j][k]]) <
3519 findDistance(&pathpoint[j], &pathpoint[pathpointconnect[j][k]]) + .1) {
3520 closestdistance = sq(tempdist);
3522 Person::players[i]->finaltarget = colpoint;
3526 Person::players[i]->finalpathfindpoint = closest;
3529 if (Person::players[i]->targetpathfindpoint == -1) {
3530 float closestdistance;
3535 closestdistance = -1;
3536 if (Person::players[i]->lastpathfindpoint == -1) {
3537 for (int j = 0; j < numpathpoints; j++) {
3538 if (j != Person::players[i]->lastpathfindpoint)
3539 if (closest == -1 || (distsq(&Person::players[i]->coords, &pathpoint[j]) < closestdistance)) {
3540 closestdistance = distsq(&Person::players[i]->coords, &pathpoint[j]);
3544 Person::players[i]->targetpathfindpoint = closest;
3545 for (int j = 0; j < numpathpoints; j++)
3546 if (j != Person::players[i]->lastpathfindpoint)
3547 for (int k = 0; k < numpathpointconnect[j]; k++) {
3548 DistancePointLine(&Person::players[i]->coords, &pathpoint[j], &pathpoint[pathpointconnect[j][k]], &tempdist, &colpoint );
3549 if (sq(tempdist) < closestdistance) {
3550 if (findDistance(&colpoint, &pathpoint[j]) + findDistance(&colpoint, &pathpoint[pathpointconnect[j][k]]) <
3551 findDistance(&pathpoint[j], &pathpoint[pathpointconnect[j][k]]) + .1) {
3552 closestdistance = sq(tempdist);
3557 Person::players[i]->targetpathfindpoint = closest;
3559 for (int j = 0; j < numpathpoints; j++)
3560 if (j != Person::players[i]->lastpathfindpoint &&
3561 j != Person::players[i]->lastpathfindpoint2 &&
3562 j != Person::players[i]->lastpathfindpoint3 &&
3563 j != Person::players[i]->lastpathfindpoint4) {
3565 if (numpathpointconnect[j])
3566 for (int k = 0; k < numpathpointconnect[j]; k++)
3567 if (pathpointconnect[j][k] == Person::players[i]->lastpathfindpoint)
3570 if (numpathpointconnect[Person::players[i]->lastpathfindpoint])
3571 for (int k = 0; k < numpathpointconnect[Person::players[i]->lastpathfindpoint]; k++)
3572 if (pathpointconnect[Person::players[i]->lastpathfindpoint][k] == j)
3575 tempdist = findPathDist(j, Person::players[i]->finalpathfindpoint);
3576 if (closest == -1 || tempdist < closestdistance) {
3577 closestdistance = tempdist;
3582 Person::players[i]->targetpathfindpoint = closest;
3585 Person::players[i]->losupdatedelay -= multiplier;
3587 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, pathpoint[Person::players[i]->targetpathfindpoint]);
3588 Person::players[i]->lookyaw = Person::players[i]->targetyaw;
3590 //reached target point
3591 if (distsqflat(&Person::players[i]->coords, &pathpoint[Person::players[i]->targetpathfindpoint]) < .6) {
3592 Person::players[i]->lastpathfindpoint4 = Person::players[i]->lastpathfindpoint3;
3593 Person::players[i]->lastpathfindpoint3 = Person::players[i]->lastpathfindpoint2;
3594 Person::players[i]->lastpathfindpoint2 = Person::players[i]->lastpathfindpoint;
3595 Person::players[i]->lastpathfindpoint = Person::players[i]->targetpathfindpoint;
3596 if (Person::players[i]->lastpathfindpoint2 == -1)
3597 Person::players[i]->lastpathfindpoint2 = Person::players[i]->lastpathfindpoint;
3598 if (Person::players[i]->lastpathfindpoint3 == -1)
3599 Person::players[i]->lastpathfindpoint3 = Person::players[i]->lastpathfindpoint2;
3600 if (Person::players[i]->lastpathfindpoint4 == -1)
3601 Person::players[i]->lastpathfindpoint4 = Person::players[i]->lastpathfindpoint3;
3602 Person::players[i]->targetpathfindpoint = -1;
3604 if ( distsqflat(&Person::players[i]->coords, &Person::players[i]->finalfinaltarget) <
3605 distsqflat(&Person::players[i]->coords, &Person::players[i]->finaltarget) ||
3606 distsqflat(&Person::players[i]->coords, &Person::players[i]->finaltarget) < .6 * sq(Person::players[i]->scale * 5) ||
3607 Person::players[i]->lastpathfindpoint == Person::players[i]->finalpathfindpoint) {
3608 Person::players[i]->aitype = passivetype;
3611 Person::players[i]->forwardkeydown = 1;
3612 Person::players[i]->leftkeydown = 0;
3613 Person::players[i]->backkeydown = 0;
3614 Person::players[i]->rightkeydown = 0;
3615 Person::players[i]->crouchkeydown = 0;
3616 Person::players[i]->attackkeydown = 0;
3617 Person::players[i]->throwkeydown = 0;
3619 if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8)
3620 Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1);
3622 if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim)
3623 Person::players[i]->jumpkeydown = 0;
3624 if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5))
3625 Person::players[i]->jumpkeydown = 1;
3627 if ((tutoriallevel != 1 || cananger) &&
3629 !Person::players[0]->dead &&
3630 distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400 &&
3631 Person::players[i]->occluded < 25) {
3632 if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 12 &&
3633 Animation::animations[Person::players[0]->animTarget].height != lowheight &&
3635 (Person::players[0]->coords.y < Person::players[i]->coords.y + 5 || Person::players[0]->onterrain))
3636 Person::players[i]->aitype = attacktypecutoff;
3637 if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 30 &&
3638 Animation::animations[Person::players[0]->animTarget].height == highheight &&
3640 Person::players[i]->aitype = attacktypecutoff;
3642 if (Person::players[i]->losupdatedelay < 0 && !editorenabled && Person::players[i]->occluded < 2) {
3643 Person::players[i]->losupdatedelay = .2;
3644 for (unsigned j = 0; j < Person::players.size(); j++)
3645 if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype)
3646 if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0)
3647 if (distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 400)
3648 if (normaldotproduct(Person::players[i]->facing, Person::players[j]->coords - Person::players[i]->coords) > 0)
3649 if (Person::players[j]->coords.y < Person::players[i]->coords.y + 5 || Person::players[j]->onterrain)
3650 if (!Person::players[j]->isWallJump() && -1 == checkcollide(
3651 DoRotation(Person::players[i]->jointPos(head), 0, Person::players[i]->yaw, 0)
3652 *Person::players[i]->scale + Person::players[i]->coords,
3653 DoRotation(Person::players[j]->jointPos(head), 0, Person::players[j]->yaw, 0)
3654 *Person::players[j]->scale + Person::players[j]->coords) ||
3655 (Person::players[j]->animTarget == hanganim &&
3656 normaldotproduct(Person::players[j]->facing, Person::players[i]->coords - Person::players[j]->coords) < 0)) {
3657 Person::players[i]->aitype = searchtype;
3658 Person::players[i]->lastchecktime = 12;
3659 Person::players[i]->lastseen = Person::players[j]->coords;
3660 Person::players[i]->lastseentime = 12;
3664 if (Person::players[i]->aitype == attacktypecutoff && musictype != 2)
3665 if (Person::players[i]->creature != wolftype) {
3666 Person::players[i]->stunned = .6;
3667 Person::players[i]->surprised = .6;
3671 if (Person::players[i]->aitype != passivetype && leveltime > .5)
3672 Person::players[i]->howactive = typeactive;
3674 if (Person::players[i]->aitype == passivetype) {
3675 Person::players[i]->aiupdatedelay -= multiplier;
3676 Person::players[i]->losupdatedelay -= multiplier;
3677 Person::players[i]->lastseentime += multiplier;
3678 Person::players[i]->pausetime -= multiplier;
3679 if (Person::players[i]->lastseentime > 1)
3680 Person::players[i]->lastseentime = 1;
3682 if (Person::players[i]->aiupdatedelay < 0) {
3683 if (Person::players[i]->numwaypoints > 1 && Person::players[i]->howactive == typeactive && Person::players[i]->pausetime <= 0) {
3684 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[i]->waypoints[Person::players[i]->waypoint]);
3685 Person::players[i]->lookyaw = Person::players[i]->targetyaw;
3686 Person::players[i]->aiupdatedelay = .05;
3688 if (distsqflat(&Person::players[i]->coords, &Person::players[i]->waypoints[Person::players[i]->waypoint]) < 1) {
3689 if (Person::players[i]->waypointtype[Person::players[i]->waypoint] == wppause)
3690 Person::players[i]->pausetime = 4;
3691 Person::players[i]->waypoint++;
3692 if (Person::players[i]->waypoint > Person::players[i]->numwaypoints - 1)
3693 Person::players[i]->waypoint = 0;
3698 if (Person::players[i]->numwaypoints > 1 && Person::players[i]->howactive == typeactive && Person::players[i]->pausetime <= 0)
3699 Person::players[i]->forwardkeydown = 1;
3701 Person::players[i]->forwardkeydown = 0;
3702 Person::players[i]->leftkeydown = 0;
3703 Person::players[i]->backkeydown = 0;
3704 Person::players[i]->rightkeydown = 0;
3705 Person::players[i]->crouchkeydown = 0;
3706 Person::players[i]->attackkeydown = 0;
3707 Person::players[i]->throwkeydown = 0;
3709 if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) {
3710 if (!Person::players[i]->avoidsomething)
3711 Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1);
3713 XYZ leftpos, rightpos;
3714 float leftdist, rightdist;
3715 leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0);
3716 rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0);
3717 leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere);
3718 rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere);
3719 if (leftdist < rightdist)
3720 Person::players[i]->targetyaw += 90;
3722 Person::players[i]->targetyaw -= 90;
3726 if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim)
3727 Person::players[i]->jumpkeydown = 0;
3728 if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5))
3729 Person::players[i]->jumpkeydown = 1;
3733 if (!editorenabled) {
3734 if (Person::players[i]->howactive <= typesleeping)
3735 if (numenvsounds > 0 && (tutoriallevel != 1 || cananger) && hostile)
3736 for (int j = 0; j < numenvsounds; j++) {
3737 float vol = Person::players[i]->howactive == typesleeping ? envsoundvol[j] - 14 : envsoundvol[j];
3738 if (vol > 0 && distsq(&Person::players[i]->coords, &envsound[j]) <
3739 2 * (vol + vol * (Person::players[i]->creature == rabbittype) * 3))
3740 Person::players[i]->aitype = attacktypecutoff;
3743 if (Person::players[i]->aitype != passivetype) {
3744 if (Person::players[i]->howactive == typesleeping)
3745 Person::players[i]->setAnimation(getupfromfrontanim);
3746 Person::players[i]->howactive = typeactive;
3750 if (Person::players[i]->howactive < typesleeping &&
3751 ((tutoriallevel != 1 || cananger) && hostile) &&
3752 !Person::players[0]->dead &&
3753 distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400 &&
3754 Person::players[i]->occluded < 25) {
3755 if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 12 &&
3756 Animation::animations[Person::players[0]->animTarget].height != lowheight && !editorenabled)
3757 Person::players[i]->aitype = attacktypecutoff;
3758 if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 30 &&
3759 Animation::animations[Person::players[0]->animTarget].height == highheight && !editorenabled)
3760 Person::players[i]->aitype = attacktypecutoff;
3763 if (Person::players[i]->creature == wolftype) {
3765 for (unsigned j = 0; j < Person::players.size(); j++) {
3766 if (j == 0 || (Person::players[j]->dead && Person::players[j]->bloodloss > 0)) {
3767 float smelldistance = 50;
3768 if (j == 0 && Person::players[j]->num_weapons > 0) {
3769 if (weapons[Person::players[j]->weaponids[0]].bloody)
3770 smelldistance = 100;
3771 if (Person::players[j]->num_weapons == 2)
3772 if (weapons[Person::players[j]->weaponids[1]].bloody)
3773 smelldistance = 100;
3776 smelldistance = 100;
3777 windsmell = windvector;
3778 Normalise(&windsmell);
3779 windsmell = windsmell * 2 + Person::players[j]->coords;
3780 if (distsq(&Person::players[i]->coords, &windsmell) < smelldistance && !editorenabled)
3781 Person::players[i]->aitype = attacktypecutoff;
3786 if (Person::players[i]->howactive < typesleeping && Person::players[i]->losupdatedelay < 0 && !editorenabled && Person::players[i]->occluded < 2) {
3787 Person::players[i]->losupdatedelay = .2;
3788 for (unsigned j = 0; j < Person::players.size(); j++) {
3789 if (j == 0 || Person::players[j]->skeleton.free || Person::players[j]->aitype != passivetype) {
3790 if (abs(Random() % 2) || Animation::animations[Person::players[j]->animTarget].height != lowheight || j != 0)
3791 if (distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 400)
3792 if (normaldotproduct(Person::players[i]->facing, Person::players[j]->coords - Person::players[i]->coords) > 0)
3793 if ((-1 == checkcollide(
3794 DoRotation(Person::players[i]->jointPos(head), 0, Person::players[i]->yaw, 0)*
3795 Person::players[i]->scale + Person::players[i]->coords,
3796 DoRotation(Person::players[j]->jointPos(head), 0, Person::players[j]->yaw, 0)*
3797 Person::players[j]->scale + Person::players[j]->coords) &&
3798 !Person::players[j]->isWallJump()) ||
3799 (Person::players[j]->animTarget == hanganim &&
3800 normaldotproduct(Person::players[j]->facing, Person::players[i]->coords - Person::players[j]->coords) < 0)) {
3801 Person::players[i]->lastseentime -= .2;
3802 if (j == 0 && Animation::animations[Person::players[j]->animTarget].height == lowheight)
3803 Person::players[i]->lastseentime -= .4;
3805 Person::players[i]->lastseentime -= .6;
3807 if (Person::players[i]->lastseentime <= 0) {
3808 Person::players[i]->aitype = searchtype;
3809 Person::players[i]->lastchecktime = 12;
3810 Person::players[i]->lastseen = Person::players[j]->coords;
3811 Person::players[i]->lastseentime = 12;
3818 if (Person::players[i]->aitype == attacktypecutoff && musictype != 2) {
3819 if (Person::players[i]->creature != wolftype) {
3820 Person::players[i]->stunned = .6;
3821 Person::players[i]->surprised = .6;
3823 if (Person::players[i]->creature == wolftype) {
3824 Person::players[i]->stunned = .47;
3825 Person::players[i]->surprised = .47;
3833 if (Person::players[i]->aitype == searchtype) {
3834 Person::players[i]->aiupdatedelay -= multiplier;
3835 Person::players[i]->losupdatedelay -= multiplier;
3836 if (!Person::players[i]->pause)
3837 Person::players[i]->lastseentime -= multiplier;
3838 Person::players[i]->lastchecktime -= multiplier;
3840 if (Person::players[i]->isRun() && !Person::players[i]->onground) {
3841 if (Person::players[i]->coords.y > terrain.getHeight(Person::players[i]->coords.x, Person::players[i]->coords.z) + 10) {
3842 XYZ test2 = Person::players[i]->coords + Person::players[i]->facing;
3844 XYZ test = Person::players[i]->coords + Person::players[i]->facing;
3846 j = checkcollide(test2, test, Person::players[i]->laststanding);
3848 j = checkcollide(test2, test);
3850 Person::players[i]->velocity = 0;
3851 Person::players[i]->setAnimation(Person::players[i]->getStop());
3852 Person::players[i]->targetyaw += 180;
3853 Person::players[i]->stunned = .5;
3854 //Person::players[i]->aitype=passivetype;
3855 Person::players[i]->aitype = pathfindtype;
3856 Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint];
3857 Person::players[i]->finalpathfindpoint = -1;
3858 Person::players[i]->targetpathfindpoint = -1;
3859 Person::players[i]->lastpathfindpoint = -1;
3860 Person::players[i]->lastpathfindpoint2 = -1;
3861 Person::players[i]->lastpathfindpoint3 = -1;
3862 Person::players[i]->lastpathfindpoint4 = -1;
3864 Person::players[i]->laststanding = j;
3867 //check out last seen location
3868 if (Person::players[i]->aiupdatedelay < 0) {
3869 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[i]->lastseen);
3870 Person::players[i]->lookyaw = Person::players[i]->targetyaw;
3871 Person::players[i]->aiupdatedelay = .05;
3872 Person::players[i]->forwardkeydown = 1;
3874 if (distsqflat(&Person::players[i]->coords, &Person::players[i]->lastseen) < 1 * sq(Person::players[i]->scale * 5) || Person::players[i]->lastchecktime < 0) {
3875 Person::players[i]->forwardkeydown = 0;
3876 Person::players[i]->aiupdatedelay = 1;
3877 Person::players[i]->lastseen.x += (float(Random() % 100) - 50) / 25;
3878 Person::players[i]->lastseen.z += (float(Random() % 100) - 50) / 25;
3879 Person::players[i]->lastchecktime = 3;
3882 Person::players[i]->leftkeydown = 0;
3883 Person::players[i]->backkeydown = 0;
3884 Person::players[i]->rightkeydown = 0;
3885 Person::players[i]->crouchkeydown = 0;
3886 Person::players[i]->attackkeydown = 0;
3887 Person::players[i]->throwkeydown = 0;
3889 if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) {
3890 if (!Person::players[i]->avoidsomething)
3891 Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1);
3893 XYZ leftpos, rightpos;
3894 float leftdist, rightdist;
3895 leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0);
3896 rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0);
3897 leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere);
3898 rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere);
3899 if (leftdist < rightdist)
3900 Person::players[i]->targetyaw += 90;
3902 Person::players[i]->targetyaw -= 90;
3906 if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim)
3907 Person::players[i]->jumpkeydown = 0;
3908 if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5))
3909 Person::players[i]->jumpkeydown = 1;
3911 if (numenvsounds > 0 && ((tutoriallevel != 1 || cananger) && hostile))
3912 for (int k = 0; k < numenvsounds; k++) {
3913 if (distsq(&Person::players[i]->coords, &envsound[k]) < 2 * (envsoundvol[k] + envsoundvol[k] * (Person::players[i]->creature == rabbittype) * 3)) {
3914 Person::players[i]->aitype = attacktypecutoff;
3918 if (!Person::players[0]->dead &&
3919 Person::players[i]->losupdatedelay < 0 &&
3921 Person::players[i]->occluded < 2 &&
3922 ((tutoriallevel != 1 || cananger) && hostile)) {
3923 Person::players[i]->losupdatedelay = .2;
3924 if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 4 && Animation::animations[Person::players[i]->animTarget].height != lowheight) {
3925 Person::players[i]->aitype = attacktypecutoff;
3926 Person::players[i]->lastseentime = 1;
3928 if (abs(Random() % 2) || Animation::animations[Person::players[i]->animTarget].height != lowheight)
3929 //TODO: factor out canSeePlayer()
3930 if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 400)
3931 if (normaldotproduct(Person::players[i]->facing, Person::players[0]->coords - Person::players[i]->coords) > 0)
3933 DoRotation(Person::players[i]->jointPos(head), 0, Person::players[i]->yaw, 0)*
3934 Person::players[i]->scale + Person::players[i]->coords,
3935 DoRotation(Person::players[0]->jointPos(head), 0, Person::players[0]->yaw, 0)*
3936 Person::players[0]->scale + Person::players[0]->coords) == -1) ||
3937 (Person::players[0]->animTarget == hanganim && normaldotproduct(
3938 Person::players[0]->facing, Person::players[i]->coords - Person::players[0]->coords) < 0)) {
3939 /* //TODO: changed j to 0 on a whim, make sure this is correct
3940 (Person::players[j]->animTarget==hanganim&&normaldotproduct(
3941 Person::players[j]->facing,Person::players[i]->coords-Person::players[j]->coords)<0)
3943 Person::players[i]->aitype = attacktypecutoff;
3944 Person::players[i]->lastseentime = 1;
3948 if (Person::players[i]->lastseentime < 0) {
3949 //Person::players[i]->aitype=passivetype;
3951 Person::players[i]->aitype = pathfindtype;
3952 Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint];
3953 Person::players[i]->finalpathfindpoint = -1;
3954 Person::players[i]->targetpathfindpoint = -1;
3955 Person::players[i]->lastpathfindpoint = -1;
3956 Person::players[i]->lastpathfindpoint2 = -1;
3957 Person::players[i]->lastpathfindpoint3 = -1;
3958 Person::players[i]->lastpathfindpoint4 = -1;
3962 if (Person::players[i]->aitype != gethelptype)
3963 Person::players[i]->runninghowlong = 0;
3965 //get help from buddies
3966 if (Person::players[i]->aitype == gethelptype) {
3967 Person::players[i]->runninghowlong += multiplier;
3968 Person::players[i]->aiupdatedelay -= multiplier;
3970 if (Person::players[i]->aiupdatedelay < 0 || Person::players[i]->ally == 0) {
3971 Person::players[i]->aiupdatedelay = .2;
3974 //TODO: factor out closest search somehow
3975 if (!Person::players[i]->ally) {
3977 float closestdist = -1;
3978 for (unsigned k = 0; k < Person::players.size(); k++) {
3979 if (k != i && k != 0 && !Person::players[k]->dead &&
3980 Person::players[k]->howactive < typedead1 &&
3981 !Person::players[k]->skeleton.free &&
3982 Person::players[k]->aitype == passivetype) {
3983 float distance = distsq(&Person::players[i]->coords, &Person::players[k]->coords);
3984 if (closestdist == -1 || distance < closestdist) {
3985 closestdist = distance;
3992 Person::players[i]->ally = closest;
3994 Person::players[i]->ally = 0;
3995 Person::players[i]->lastseen = Person::players[0]->coords;
3996 Person::players[i]->lastseentime = 12;
4000 Person::players[i]->lastchecktime = 12;
4002 XYZ facing = Person::players[i]->coords;
4003 XYZ flatfacing = Person::players[Person::players[i]->ally]->coords;
4004 facing.y += Person::players[i]->jointPos(head).y * Person::players[i]->scale;
4005 flatfacing.y += Person::players[Person::players[i]->ally]->jointPos(head).y * Person::players[Person::players[i]->ally]->scale;
4006 if (-1 != checkcollide(facing, flatfacing))
4007 Person::players[i]->lastseentime -= .1;
4009 //no available ally, run back to player
4010 if (Person::players[i]->ally <= 0 ||
4011 Person::players[Person::players[i]->ally]->skeleton.free ||
4012 Person::players[Person::players[i]->ally]->aitype != passivetype ||
4013 Person::players[i]->lastseentime <= 0) {
4014 Person::players[i]->aitype = searchtype;
4015 Person::players[i]->lastseentime = 12;
4019 if (Person::players[i]->ally > 0) {
4020 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[Person::players[i]->ally]->coords);
4021 Person::players[i]->lookyaw = Person::players[i]->targetyaw;
4022 Person::players[i]->aiupdatedelay = .05;
4023 Person::players[i]->forwardkeydown = 1;
4025 if (distsqflat(&Person::players[i]->coords, &Person::players[Person::players[i]->ally]->coords) < 3) {
4026 Person::players[i]->aitype = searchtype;
4027 Person::players[i]->lastseentime = 12;
4028 Person::players[Person::players[i]->ally]->aitype = searchtype;
4029 if (Person::players[Person::players[i]->ally]->lastseentime < Person::players[i]->lastseentime) {
4030 Person::players[Person::players[i]->ally]->lastseen = Person::players[i]->lastseen;
4031 Person::players[Person::players[i]->ally]->lastseentime = Person::players[i]->lastseentime;
4032 Person::players[Person::players[i]->ally]->lastchecktime = Person::players[i]->lastchecktime;
4036 if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) {
4037 if (!Person::players[i]->avoidsomething)
4038 Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1);
4040 XYZ leftpos, rightpos;
4041 float leftdist, rightdist;
4042 leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0);
4043 rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0);
4044 leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere);
4045 rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere);
4046 if (leftdist < rightdist)
4047 Person::players[i]->targetyaw += 90;
4049 Person::players[i]->targetyaw -= 90;
4054 Person::players[i]->leftkeydown = 0;
4055 Person::players[i]->backkeydown = 0;
4056 Person::players[i]->rightkeydown = 0;
4057 Person::players[i]->crouchkeydown = 0;
4058 Person::players[i]->attackkeydown = 0;
4060 if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim)
4061 Person::players[i]->jumpkeydown = 0;
4062 if (Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5)
4063 Person::players[i]->jumpkeydown = 1;
4066 //retreiving a weapon on the ground
4067 if (Person::players[i]->aitype == getweapontype) {
4068 Person::players[i]->aiupdatedelay -= multiplier;
4069 Person::players[i]->lastchecktime -= multiplier;
4071 if (Person::players[i]->aiupdatedelay < 0) {
4072 Person::players[i]->aiupdatedelay = .2;
4075 if (Person::players[i]->ally < 0) {
4077 float closestdist = -1;
4078 for (unsigned k = 0; k < weapons.size(); k++)
4079 if (weapons[k].owner == -1) {
4080 float distance = distsq(&Person::players[i]->coords, &weapons[k].position);
4081 if (closestdist == -1 || distance < closestdist) {
4082 closestdist = distance;
4088 Person::players[i]->ally = closest;
4090 Person::players[i]->ally = -1;
4093 Person::players[i]->lastseentime = 12;
4095 if (!Person::players[0]->dead && ((tutoriallevel != 1 || cananger) && hostile))
4096 if (Person::players[i]->ally < 0 || Person::players[i]->weaponactive != -1 || Person::players[i]->lastchecktime <= 0) {
4097 Person::players[i]->aitype = attacktypecutoff;
4098 Person::players[i]->lastseentime = 1;
4100 if (!Person::players[0]->dead)
4101 if (Person::players[i]->ally >= 0) {
4102 if (weapons[Person::players[i]->ally].owner != -1 ||
4103 distsq(&Person::players[i]->coords, &weapons[Person::players[i]->ally].position) > 16) {
4104 Person::players[i]->aitype = attacktypecutoff;
4105 Person::players[i]->lastseentime = 1;
4107 //TODO: factor these out as moveToward()
4108 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, weapons[Person::players[i]->ally].position);
4109 Person::players[i]->lookyaw = Person::players[i]->targetyaw;
4110 Person::players[i]->aiupdatedelay = .05;
4111 Person::players[i]->forwardkeydown = 1;
4114 if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8) {
4115 if (!Person::players[i]->avoidsomething)
4116 Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1);
4118 XYZ leftpos, rightpos;
4119 float leftdist, rightdist;
4120 leftpos = Person::players[i]->coords + DoRotation(Person::players[i]->facing, 0, 90, 0);
4121 rightpos = Person::players[i]->coords - DoRotation(Person::players[i]->facing, 0, 90, 0);
4122 leftdist = distsq(&leftpos, &Person::players[i]->avoidwhere);
4123 rightdist = distsq(&rightpos, &Person::players[i]->avoidwhere);
4124 if (leftdist < rightdist)
4125 Person::players[i]->targetyaw += 90;
4127 Person::players[i]->targetyaw -= 90;
4132 Person::players[i]->leftkeydown = 0;
4133 Person::players[i]->backkeydown = 0;
4134 Person::players[i]->rightkeydown = 0;
4135 Person::players[i]->attackkeydown = 0;
4136 Person::players[i]->throwkeydown = 1;
4137 Person::players[i]->crouchkeydown = 0;
4138 if (Person::players[i]->animTarget != crouchremoveknifeanim &&
4139 Person::players[i]->animTarget != removeknifeanim)
4140 Person::players[i]->throwtogglekeydown = 0;
4141 Person::players[i]->drawkeydown = 0;
4143 if (Person::players[i]->collided < 1 || Person::players[i]->animTarget != jumpupanim)
4144 Person::players[i]->jumpkeydown = 0;
4145 if ((Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5))
4146 Person::players[i]->jumpkeydown = 1;
4149 if (Person::players[i]->aitype == attacktypecutoff) {
4150 Person::players[i]->aiupdatedelay -= multiplier;
4151 //dodge or reverse rabbit kicks, knife throws, flips
4152 if (Person::players[i]->damage < Person::players[i]->damagetolerance * 2 / 3)
4153 if ((Person::players[0]->animTarget == rabbitkickanim ||
4154 Person::players[0]->animTarget == knifethrowanim ||
4155 (Person::players[0]->isFlip() &&
4156 normaldotproduct(Person::players[0]->facing, Person::players[0]->coords - Person::players[i]->coords) < 0)) &&
4157 !Person::players[0]->skeleton.free &&
4158 (Person::players[i]->aiupdatedelay < .1)) {
4159 Person::players[i]->attackkeydown = 0;
4160 if (Person::players[i]->isIdle())
4161 Person::players[i]->crouchkeydown = 1;
4162 if (Person::players[0]->animTarget != rabbitkickanim && Person::players[0]->weaponactive != -1) {
4163 if (weapons[Person::players[0]->weaponids[0]].getType() == knife) {
4164 if (Person::players[i]->isIdle() || Person::players[i]->isCrouch() || Person::players[i]->isRun() || Person::players[i]->isFlip()) {
4165 if (abs(Random() % 2) == 0)
4166 Person::players[i]->setAnimation(backhandspringanim);
4168 Person::players[i]->setAnimation(rollanim);
4169 Person::players[i]->targetyaw += 90 * (abs(Random() % 2) * 2 - 1);
4170 Person::players[i]->wentforweapon = 0;
4172 if (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim)
4173 Person::players[i]->setAnimation(flipanim);
4176 Person::players[i]->forwardkeydown = 0;
4177 Person::players[i]->aiupdatedelay = .02;
4179 //get confused by flips
4180 if (Person::players[0]->isFlip() &&
4181 !Person::players[0]->skeleton.free &&
4182 Person::players[0]->animTarget != walljumprightkickanim &&
4183 Person::players[0]->animTarget != walljumpleftkickanim) {
4184 if (distsq(&Person::players[0]->coords, &Person::players[i]->coords) < 25)
4185 if ((1 - Person::players[i]->damage / Person::players[i]->damagetolerance) > .5)
4186 Person::players[i]->stunned = 1;
4188 //go for weapon on the ground
4189 if (Person::players[i]->wentforweapon < 3)
4190 for (unsigned k = 0; k < weapons.size(); k++)
4191 if (Person::players[i]->creature != wolftype)
4192 if (Person::players[i]->num_weapons == 0 &&
4193 weapons[k].owner == -1 &&
4194 weapons[i].velocity.x == 0 &&
4195 weapons[i].velocity.z == 0 &&
4196 weapons[i].velocity.y == 0) {
4197 if (distsq(&Person::players[i]->coords, &weapons[k].position) < 16) {
4198 Person::players[i]->wentforweapon++;
4199 Person::players[i]->lastchecktime = 6;
4200 Person::players[i]->aitype = getweapontype;
4201 Person::players[i]->ally = -1;
4204 //dodge/reverse walljump kicks
4205 if (Person::players[i]->damage < Person::players[i]->damagetolerance / 2)
4206 if (Animation::animations[Person::players[i]->animTarget].height != highheight)
4207 if (Person::players[i]->damage < Person::players[i]->damagetolerance * .5 &&
4208 ((Person::players[0]->animTarget == walljumprightkickanim ||
4209 Person::players[0]->animTarget == walljumpleftkickanim) &&
4210 ((Person::players[i]->aiupdatedelay < .15 &&
4212 (Person::players[i]->aiupdatedelay < .08 &&
4213 difficulty != 2)))) {
4214 Person::players[i]->crouchkeydown = 1;
4216 //walked off a ledge (?)
4217 if (Person::players[i]->isRun() && !Person::players[i]->onground)
4218 if (Person::players[i]->coords.y > terrain.getHeight(Person::players[i]->coords.x, Person::players[i]->coords.z) + 10) {
4219 XYZ test2 = Person::players[i]->coords + Person::players[i]->facing;
4221 XYZ test = Person::players[i]->coords + Person::players[i]->facing;
4223 j = checkcollide(test2, test, Person::players[i]->laststanding);
4225 j = checkcollide(test2, test);
4227 Person::players[i]->velocity = 0;
4228 Person::players[i]->setAnimation(Person::players[i]->getStop());
4229 Person::players[i]->targetyaw += 180;
4230 Person::players[i]->stunned = .5;
4231 Person::players[i]->aitype = pathfindtype;
4232 Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint];
4233 Person::players[i]->finalpathfindpoint = -1;
4234 Person::players[i]->targetpathfindpoint = -1;
4235 Person::players[i]->lastpathfindpoint = -1;
4236 Person::players[i]->lastpathfindpoint2 = -1;
4237 Person::players[i]->lastpathfindpoint3 = -1;
4238 Person::players[i]->lastpathfindpoint4 = -1;
4240 Person::players[i]->laststanding = j;
4242 //lose sight of player in the air (?)
4243 if (Person::players[0]->coords.y > Person::players[i]->coords.y + 5 &&
4244 Animation::animations[Person::players[0]->animTarget].height != highheight &&
4245 !Person::players[0]->onterrain) {
4246 Person::players[i]->aitype = pathfindtype;
4247 Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint];
4248 Person::players[i]->finalpathfindpoint = -1;
4249 Person::players[i]->targetpathfindpoint = -1;
4250 Person::players[i]->lastpathfindpoint = -1;
4251 Person::players[i]->lastpathfindpoint2 = -1;
4252 Person::players[i]->lastpathfindpoint3 = -1;
4253 Person::players[i]->lastpathfindpoint4 = -1;
4255 //it's time to think (?)
4256 if (Person::players[i]->aiupdatedelay < 0 &&
4257 !Animation::animations[Person::players[i]->animTarget].attack &&
4258 Person::players[i]->animTarget != staggerbackhighanim &&
4259 Person::players[i]->animTarget != staggerbackhardanim &&
4260 Person::players[i]->animTarget != backhandspringanim &&
4261 Person::players[i]->animTarget != dodgebackanim) {
4263 if (Person::players[i]->weaponactive == -1 && Person::players[i]->num_weapons > 0)
4264 Person::players[i]->drawkeydown = Random() % 2;
4266 Person::players[i]->drawkeydown = 0;
4267 Person::players[i]->rabbitkickenabled = Random() % 2;
4269 XYZ rotatetarget = Person::players[0]->coords + Person::players[0]->velocity;
4270 XYZ targetpoint = Person::players[0]->coords;
4271 if (distsq(&Person::players[0]->coords, &Person::players[i]->coords) <
4272 distsq(&rotatetarget, &Person::players[i]->coords))
4273 targetpoint += Person::players[0]->velocity *
4274 findDistance(&Person::players[0]->coords, &Person::players[i]->coords) / findLength(&Person::players[i]->velocity);
4275 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, targetpoint);
4276 Person::players[i]->lookyaw = Person::players[i]->targetyaw;
4277 Person::players[i]->aiupdatedelay = .2 + fabs((float)(Random() % 100) / 1000);
4279 if (distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 5 && (Person::players[0]->weaponactive == -1 || Person::players[i]->weaponactive != -1))
4280 Person::players[i]->forwardkeydown = 1;
4281 else if ((distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 16 ||
4282 distsq(&Person::players[i]->coords, &Person::players[0]->coords) < 9) &&
4283 Person::players[0]->weaponactive != -1)
4284 Person::players[i]->forwardkeydown = 1;
4285 else if (Random() % 6 == 0 || (Person::players[i]->creature == wolftype && Random() % 3 == 0))
4286 Person::players[i]->forwardkeydown = 1;
4288 Person::players[i]->forwardkeydown = 0;
4289 //chill out around the corpse
4290 if (Person::players[0]->dead) {
4291 Person::players[i]->forwardkeydown = 0;
4292 if (Random() % 10 == 0)
4293 Person::players[i]->forwardkeydown = 1;
4294 if (Random() % 100 == 0) {
4295 Person::players[i]->aitype = pathfindtype;
4296 Person::players[i]->finalfinaltarget = Person::players[i]->waypoints[Person::players[i]->waypoint];
4297 Person::players[i]->finalpathfindpoint = -1;
4298 Person::players[i]->targetpathfindpoint = -1;
4299 Person::players[i]->lastpathfindpoint = -1;
4300 Person::players[i]->lastpathfindpoint2 = -1;
4301 Person::players[i]->lastpathfindpoint3 = -1;
4302 Person::players[i]->lastpathfindpoint4 = -1;
4305 Person::players[i]->leftkeydown = 0;
4306 Person::players[i]->backkeydown = 0;
4307 Person::players[i]->rightkeydown = 0;
4308 Person::players[i]->crouchkeydown = 0;
4309 Person::players[i]->throwkeydown = 0;
4311 if (Person::players[i]->avoidcollided > .8 && !Person::players[i]->jumpkeydown && Person::players[i]->collided < .8)
4312 Person::players[i]->targetyaw += 90 * (Person::players[i]->whichdirection * 2 - 1);
4314 if (Random() % 2 == 0 || Person::players[i]->weaponactive != -1 || Person::players[i]->creature == wolftype)
4315 Person::players[i]->attackkeydown = 1;
4317 Person::players[i]->attackkeydown = 0;
4318 if (Person::players[i]->isRun() && Random() % 6 && distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 7)
4319 Person::players[i]->attackkeydown = 0;
4322 if (Person::players[i]->aitype != playercontrolled &&
4323 (Person::players[i]->isIdle() ||
4324 Person::players[i]->isCrouch() ||
4325 Person::players[i]->isRun())) {
4327 for (unsigned j = 0; j < Person::players.size(); j++)
4328 if (j != i && !Person::players[j]->skeleton.free &&
4329 Person::players[j]->hasvictim &&
4330 (tutoriallevel == 1 && reversaltrain ||
4331 Random() % 2 == 0 && difficulty == 2 ||
4332 Random() % 4 == 0 && difficulty == 1 ||
4333 Random() % 8 == 0 && difficulty == 0 ||
4334 Person::players[j]->lastattack2 == Person::players[j]->animTarget &&
4335 Person::players[j]->lastattack3 == Person::players[j]->animTarget &&
4336 (Random() % 2 == 0 || difficulty == 2) ||
4337 (Person::players[i]->isIdle() || Person::players[i]->isRun()) &&
4338 Person::players[j]->weaponactive != -1 ||
4339 Person::players[j]->animTarget == swordslashanim &&
4340 Person::players[i]->weaponactive != -1 ||
4341 Person::players[j]->animTarget == staffhitanim ||
4342 Person::players[j]->animTarget == staffspinhitanim))
4343 if (distsq(&Person::players[j]->coords, &Person::players[j]->victim->coords) < 4 &&
4344 Person::players[j]->victim == Person::players[i] &&
4345 (Person::players[j]->animTarget == sweepanim ||
4346 Person::players[j]->animTarget == spinkickanim ||
4347 Person::players[j]->animTarget == staffhitanim ||
4348 Person::players[j]->animTarget == staffspinhitanim ||
4349 Person::players[j]->animTarget == winduppunchanim ||
4350 Person::players[j]->animTarget == upunchanim ||
4351 Person::players[j]->animTarget == wolfslapanim ||
4352 Person::players[j]->animTarget == knifeslashstartanim ||
4353 Person::players[j]->animTarget == swordslashanim &&
4354 (distsq(&Person::players[j]->coords, &Person::players[i]->coords) < 2 ||
4355 Person::players[i]->weaponactive != -1))) {
4362 Person::players[target]->Reverse();
4365 if (Person::players[i]->collided < 1)
4366 Person::players[i]->jumpkeydown = 0;
4367 if (Person::players[i]->collided > .8 && Person::players[i]->jumppower >= 5 ||
4368 distsq(&Person::players[i]->coords, &Person::players[0]->coords) > 400 &&
4369 Person::players[i]->onterrain &&
4370 Person::players[i]->creature == rabbittype)
4371 Person::players[i]->jumpkeydown = 1;
4372 //TODO: why are we controlling the human?
4373 if (normaldotproduct(Person::players[i]->facing, Person::players[0]->coords - Person::players[i]->coords) > 0)
4374 Person::players[0]->jumpkeydown = 0;
4375 if (Person::players[0]->animTarget == jumpdownanim &&
4376 distsq(&Person::players[0]->coords, &Person::players[i]->coords) < 40)
4377 Person::players[i]->crouchkeydown = 1;
4378 if (Person::players[i]->jumpkeydown)
4379 Person::players[i]->attackkeydown = 0;
4381 if (tutoriallevel == 1)
4383 Person::players[i]->attackkeydown = 0;
4386 XYZ facing = Person::players[i]->coords;
4387 XYZ flatfacing = Person::players[0]->coords;
4388 facing.y += Person::players[i]->jointPos(head).y * Person::players[i]->scale;
4389 flatfacing.y += Person::players[0]->jointPos(head).y * Person::players[0]->scale;
4390 if (Person::players[i]->occluded >= 2)
4391 if (-1 != checkcollide(facing, flatfacing)) {
4392 if (!Person::players[i]->pause)
4393 Person::players[i]->lastseentime -= .2;
4394 if (Person::players[i]->lastseentime <= 0 &&
4395 (Person::players[i]->creature != wolftype ||
4396 Person::players[i]->weaponstuck == -1)) {
4397 Person::players[i]->aitype = searchtype;
4398 Person::players[i]->lastchecktime = 12;
4399 Person::players[i]->lastseen = Person::players[0]->coords;
4400 Person::players[i]->lastseentime = 12;
4403 Person::players[i]->lastseentime = 1;
4406 if (Animation::animations[Person::players[0]->animTarget].height == highheight &&
4407 (Person::players[i]->aitype == attacktypecutoff ||
4408 Person::players[i]->aitype == searchtype))
4409 if (Person::players[0]->coords.y > terrain.getHeight(Person::players[0]->coords.x, Person::players[0]->coords.z) + 10) {
4410 XYZ test = Person::players[0]->coords;
4412 if (-1 == checkcollide(Person::players[0]->coords, test))
4413 Person::players[i]->stunned = 1;
4416 if (Person::players[i]->aitype == passivetype && !(Person::players[i]->numwaypoints > 1) ||
4417 Person::players[i]->stunned > 0 ||
4418 Person::players[i]->pause && Person::players[i]->damage > Person::players[i]->superpermanentdamage) {
4419 if (Person::players[i]->pause)
4420 Person::players[i]->lastseentime = 1;
4421 Person::players[i]->targetyaw = Person::players[i]->yaw;
4422 Person::players[i]->forwardkeydown = 0;
4423 Person::players[i]->leftkeydown = 0;
4424 Person::players[i]->backkeydown = 0;
4425 Person::players[i]->rightkeydown = 0;
4426 Person::players[i]->jumpkeydown = 0;
4427 Person::players[i]->attackkeydown = 0;
4428 Person::players[i]->crouchkeydown = 0;
4429 Person::players[i]->throwkeydown = 0;
4437 XYZ flatfacing = DoRotation(facing, 0, Person::players[i]->yaw + 180, 0);
4438 facing = flatfacing;
4440 if (Person::players[i]->aitype == attacktypecutoff) {
4441 Person::players[i]->targetheadyaw = 180 - roughDirectionTo(Person::players[i]->coords, Person::players[0]->coords);
4442 Person::players[i]->targetheadpitch = pitchTo(Person::players[i]->coords, Person::players[0]->coords);
4443 } else if (Person::players[i]->howactive >= typesleeping) {
4444 Person::players[i]->targetheadyaw = Person::players[i]->targetyaw;
4445 Person::players[i]->targetheadpitch = 0;
4447 if (Person::players[i]->interestdelay <= 0) {
4448 Person::players[i]->interestdelay = .7 + (float)(abs(Random() % 100)) / 100;
4449 Person::players[i]->headtarget = Person::players[i]->coords;
4450 Person::players[i]->headtarget.x += (float)(abs(Random() % 200) - 100) / 100;
4451 Person::players[i]->headtarget.z += (float)(abs(Random() % 200) - 100) / 100;
4452 Person::players[i]->headtarget.y += (float)(abs(Random() % 200) - 100) / 300;
4453 Person::players[i]->headtarget += Person::players[i]->facing * 1.5;
4455 Person::players[i]->targetheadyaw = 180 - roughDirectionTo(Person::players[i]->coords, Person::players[i]->headtarget);
4456 Person::players[i]->targetheadpitch = pitchTo(Person::players[i]->coords, Person::players[i]->headtarget);
4463 static XYZ facing, flatfacing;
4468 if (Input::isKeyPressed(SDL_SCANCODE_F6)) {
4469 if (Input::isKeyDown(SDL_SCANCODE_LSHIFT))
4470 stereoreverse = true;
4472 stereoreverse = false;
4475 printf("Stereo reversed\n");
4477 printf("Stereo unreversed\n");
4480 if (Input::isKeyDown(SDL_SCANCODE_F7)) {
4481 if (Input::isKeyDown(SDL_SCANCODE_LSHIFT))
4482 stereoseparation -= 0.001;
4484 stereoseparation -= 0.010;
4485 printf("Stereo decreased increased to %f\n", stereoseparation);
4488 if (Input::isKeyDown(SDL_SCANCODE_F8)) {
4489 if (Input::isKeyDown(SDL_SCANCODE_LSHIFT))
4490 stereoseparation += 0.001;
4492 stereoseparation += 0.010;
4493 printf("Stereo separation increased to %f\n", stereoseparation);
4497 if (Input::isKeyPressed(SDL_SCANCODE_TAB) && tutoriallevel) {
4498 if (tutorialstage != 51)
4499 tutorialstagetime = tutorialmaxtime;
4500 emit_sound_np(consolefailsound, 128.);
4504 Values of mainmenu :
4506 2 Menu pause (resume/end game)
4508 4 Controls configuration menu
4509 5 Main game menu (choose level or challenge)
4510 6 Deleting user menu
4511 7 User managment menu (select/add)
4512 8 Choose difficulty menu
4513 9 Challenge level selection menu
4514 10 End of the campaign congratulation (is that really a menu?)
4515 11 Same that 9 ??? => unused
4516 18 stereo configuration
4521 if (mainmenu && endgame == 1)
4523 //go to level select after completing a campaign level
4524 if (campaign && winfreeze && mainmenu == 0 && campaignlevels[actuallevel].choosenext == 1) {
4531 OPENAL_SetFrequency(OPENAL_ALL);
4532 emit_stream_np(stream_menutheme);
4533 pause_sound(leveltheme);
4537 //escape key pressed
4538 if (Input::isKeyPressed(SDL_SCANCODE_ESCAPE) &&
4539 (gameon || mainmenu == 0)) {
4541 if (mainmenu == 0 && !winfreeze)
4542 mainmenu = 2; //pause
4543 else if (mainmenu == 1 || mainmenu == 2) {
4544 mainmenu = 0; //unpause
4547 if (musictoggle && (mainmenu == 1 || mainmenu == 2)) {
4548 OPENAL_SetFrequency(OPENAL_ALL);
4549 emit_stream_np(stream_menutheme);
4550 pause_sound(leveltheme);
4552 //on resume, play level music
4554 pause_sound(stream_menutheme);
4555 resume_stream(leveltheme);
4566 hostiletime += multiplier;
4570 leveltime += multiplier;
4573 if (Input::isKeyDown(SDL_SCANCODE_LALT) && Input::isKeyPressed(SDL_SCANCODE_V) && devtools) {
4576 OPENAL_SetFrequency(OPENAL_ALL);
4580 if (Input::isKeyPressed(consolekey) && devtools) {
4583 OPENAL_SetFrequency(OPENAL_ALL);
4592 if (console && !Input::isKeyDown(SDL_SCANCODE_LGUI)) {
4593 inputText(consoletext[0], &consoleselected);
4595 if (!consoletext[0].empty()) {
4596 cmd_dispatch(consoletext[0]);
4597 for (int k = 14; k >= 1; k--) {
4598 consoletext[k] = consoletext[k - 1];
4600 consoletext[0].clear();
4601 consoleselected = 0;
4605 consoleblinkdelay -= multiplier;
4606 if (consoleblinkdelay <= 0) {
4607 consoleblinkdelay = .3;
4608 consoleblink = !consoleblink;
4612 static int oldwinfreeze;
4613 if (winfreeze && !oldwinfreeze) {
4614 OPENAL_SetFrequency(OPENAL_ALL);
4615 emit_sound_np(consolesuccesssound);
4618 oldwinfreeze = winfreeze;
4622 if ((Input::isKeyPressed(jumpkey) || Input::isKeyPressed(SDL_SCANCODE_SPACE)) && !campaign)
4625 if ((Input::isKeyDown(SDL_SCANCODE_ESCAPE)) && !campaign && gameon) {
4629 } else if (winfreeze) {
4637 if (!freeze && !winfreeze && !(mainmenu && gameon) && (gameon || !gamestarted)) {
4640 static float talkdelay = 0;
4642 if (Dialog::inDialog())
4644 talkdelay -= multiplier;
4646 if (talkdelay <= 0 && !Dialog::inDialog() && Animation::animations[Person::players[0]->animTarget].height != highheight) {
4647 for (unsigned i = 0; i < Dialog::dialogs.size(); i++) {
4648 Dialog::dialogs[i].tick(i);
4652 windvar += multiplier;
4653 smoketex += multiplier;
4654 tutorialstagetime += multiplier;
4657 static float hotspotvisual[40];
4658 if (Hotspot::hotspots.size()) {
4660 if (editorenabled) {
4661 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
4662 hotspotvisual[i] -= multiplier / 320;
4666 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
4667 while (hotspotvisual[i] < 0) {
4669 hotspotsprite.x = float(abs(Random() % 100000)) / 100000 * Hotspot::hotspots[i].size;
4670 hotspotsprite = DoRotation(hotspotsprite, 0, 0, Random() % 360);
4671 hotspotsprite = DoRotation(hotspotsprite, 0, Random() % 360, 0);
4672 hotspotsprite += Hotspot::hotspots[i].position;
4673 Sprite::MakeSprite(breathsprite, hotspotsprite, hotspotsprite * 0, 1, 0.5, 0, 7, 0.4);
4674 hotspotvisual[i] += 0.1 / Hotspot::hotspots[i].size / Hotspot::hotspots[i].size / Hotspot::hotspots[i].size;
4678 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
4679 if (Hotspot::hotspots[i].type <= 10 && Hotspot::hotspots[i].type > 0) {
4680 Hotspot::hotspots[i].position = Person::players[Hotspot::hotspots[i].type]->coords;
4686 if (tutoriallevel) {
4691 if (tutoriallevel != 1) {
4692 if (bonustime == 0 &&
4693 bonus != solidhit &&
4694 bonus != spinecrusher &&
4695 bonus != tracheotomy &&
4696 bonus != backstab &&
4698 emit_sound_np(consolesuccesssound);
4700 } else if (bonustime == 0) {
4701 emit_sound_np(fireendsound);
4703 if (bonustime == 0) {
4704 if (bonus != solidhit &&
4705 bonus != twoxcombo &&
4706 bonus != threexcombo &&
4707 bonus != fourxcombo &&
4711 bonusnum[bonus] += 0.15;
4714 bonusvalue /= bonusnum[bonus];
4715 bonustotal += bonusvalue;
4717 bonustime += multiplier;
4720 if (environment == snowyenvironment) {
4721 precipdelay -= multiplier;
4722 while (precipdelay < 0) {
4726 XYZ footvel, footpoint;
4729 footpoint = viewer + viewerfacing * 6;
4730 footpoint.y += ((float)abs(Random() % 1200)) / 100 - 6;
4731 footpoint.x += ((float)abs(Random() % 1200)) / 100 - 6;
4732 footpoint.z += ((float)abs(Random() % 1200)) / 100 - 6;
4733 Sprite::MakeSprite(snowsprite, footpoint, footvel, 1, 1, 1, .1, 1);
4738 doAerialAcrobatics();
4741 static XYZ oldviewer;
4744 if (!Dialog::inDialog()) {
4745 Person::players[0]->forwardkeydown = Input::isKeyDown(forwardkey);
4746 Person::players[0]->leftkeydown = Input::isKeyDown(leftkey);
4747 Person::players[0]->backkeydown = Input::isKeyDown(backkey);
4748 Person::players[0]->rightkeydown = Input::isKeyDown(rightkey);
4749 Person::players[0]->jumpkeydown = Input::isKeyDown(jumpkey);
4750 Person::players[0]->crouchkeydown = Input::isKeyDown(crouchkey);
4751 Person::players[0]->drawkeydown = Input::isKeyDown(drawkey);
4752 Person::players[0]->throwkeydown = Input::isKeyDown(throwkey);
4754 Person::players[0]->forwardkeydown = 0;
4755 Person::players[0]->leftkeydown = 0;
4756 Person::players[0]->backkeydown = 0;
4757 Person::players[0]->rightkeydown = 0;
4758 Person::players[0]->jumpkeydown = 0;
4759 Person::players[0]->crouchkeydown = 0;
4760 Person::players[0]->drawkeydown = 0;
4761 Person::players[0]->throwkeydown = 0;
4764 if (!Person::players[0]->jumpkeydown)
4765 Person::players[0]->jumpclimb = 0;
4768 if (Dialog::inDialog()) {
4770 if (Dialog::directing) {
4774 facing = DoRotation(facing, -pitch, 0, 0);
4775 facing = DoRotation(facing, 0, 0 - yaw, 0);
4780 flatfacing = DoRotation(flatfacing, 0, -yaw, 0);
4782 if (Input::isKeyDown(forwardkey))
4783 viewer += facing * multiplier * 4;
4784 if (Input::isKeyDown(backkey))
4785 viewer -= facing * multiplier * 4;
4786 if (Input::isKeyDown(leftkey))
4787 viewer += DoRotation(flatfacing * multiplier, 0, 90, 0) * 4;
4788 if (Input::isKeyDown(rightkey))
4789 viewer += DoRotation(flatfacing * multiplier, 0, -90, 0) * 4;
4790 if (Input::isKeyDown(jumpkey))
4791 viewer.y += multiplier * 4;
4792 if (Input::isKeyDown(crouchkey))
4793 viewer.y -= multiplier * 4;
4794 if ( Input::isKeyPressed(SDL_SCANCODE_1) ||
4795 Input::isKeyPressed(SDL_SCANCODE_2) ||
4796 Input::isKeyPressed(SDL_SCANCODE_3) ||
4797 Input::isKeyPressed(SDL_SCANCODE_4) ||
4798 Input::isKeyPressed(SDL_SCANCODE_5) ||
4799 Input::isKeyPressed(SDL_SCANCODE_6) ||
4800 Input::isKeyPressed(SDL_SCANCODE_7) ||
4801 Input::isKeyPressed(SDL_SCANCODE_8) ||
4802 Input::isKeyPressed(SDL_SCANCODE_9) ||
4803 Input::isKeyPressed(SDL_SCANCODE_0) ||
4804 Input::isKeyPressed(SDL_SCANCODE_MINUS)) {
4806 if (Input::isKeyPressed(SDL_SCANCODE_1)) whichend = 1;
4807 if (Input::isKeyPressed(SDL_SCANCODE_2)) whichend = 2;
4808 if (Input::isKeyPressed(SDL_SCANCODE_3)) whichend = 3;
4809 if (Input::isKeyPressed(SDL_SCANCODE_4)) whichend = 4;
4810 if (Input::isKeyPressed(SDL_SCANCODE_5)) whichend = 5;
4811 if (Input::isKeyPressed(SDL_SCANCODE_6)) whichend = 6;
4812 if (Input::isKeyPressed(SDL_SCANCODE_7)) whichend = 7;
4813 if (Input::isKeyPressed(SDL_SCANCODE_8)) whichend = 8;
4814 if (Input::isKeyPressed(SDL_SCANCODE_9)) whichend = 9;
4815 if (Input::isKeyPressed(SDL_SCANCODE_0)) whichend = 0;
4816 if (Input::isKeyPressed(SDL_SCANCODE_MINUS))
4818 if (whichend != -1) {
4819 Dialog::currentScene().participantfocus = whichend;
4820 Dialog::currentDialog().participantlocation[whichend] = Person::players[whichend]->coords;
4821 Dialog::currentDialog().participantyaw[whichend] = Person::players[whichend]->yaw;
4823 if (whichend == -1) {
4824 Dialog::currentScene().participantfocus = -1;
4826 /* FIXME: potentially accessing -1 in Person::players! */
4827 if (Person::players[Dialog::currentScene().participantfocus]->dead) {
4828 Dialog::indialogue = -1;
4829 Dialog::directing = false;
4832 Dialog::currentScene().camera = viewer;
4833 Dialog::currentScene().camerayaw = yaw;
4834 Dialog::currentScene().camerapitch = pitch;
4835 Dialog::indialogue++;
4836 if (Dialog::indialogue < int(Dialog::currentDialog().scenes.size())) {
4837 if (Dialog::currentScene().sound != 0) {
4838 playdialoguescenesound();
4842 for (unsigned j = 0; j < Person::players.size(); j++) {
4843 Dialog::currentScene().participantfacing[j] = Dialog::currentDialog().scenes[Dialog::indialogue - 1].participantfacing[j];
4846 //TODO: should these be KeyDown or KeyPressed?
4847 if ( Input::isKeyDown(SDL_SCANCODE_KP_1) ||
4848 Input::isKeyDown(SDL_SCANCODE_KP_2) ||
4849 Input::isKeyDown(SDL_SCANCODE_KP_3) ||
4850 Input::isKeyDown(SDL_SCANCODE_KP_4) ||
4851 Input::isKeyDown(SDL_SCANCODE_KP_5) ||
4852 Input::isKeyDown(SDL_SCANCODE_KP_6) ||
4853 Input::isKeyDown(SDL_SCANCODE_KP_7) ||
4854 Input::isKeyDown(SDL_SCANCODE_KP_8) ||
4855 Input::isKeyDown(SDL_SCANCODE_KP_9) ||
4856 Input::isKeyDown(SDL_SCANCODE_KP_0)) {
4858 if (Input::isKeyDown(SDL_SCANCODE_KP_1)) whichend = 1;
4859 if (Input::isKeyDown(SDL_SCANCODE_KP_2)) whichend = 2;
4860 if (Input::isKeyDown(SDL_SCANCODE_KP_3)) whichend = 3;
4861 if (Input::isKeyDown(SDL_SCANCODE_KP_4)) whichend = 4;
4862 if (Input::isKeyDown(SDL_SCANCODE_KP_5)) whichend = 5;
4863 if (Input::isKeyDown(SDL_SCANCODE_KP_6)) whichend = 6;
4864 if (Input::isKeyDown(SDL_SCANCODE_KP_7)) whichend = 7;
4865 if (Input::isKeyDown(SDL_SCANCODE_KP_8)) whichend = 8;
4866 if (Input::isKeyDown(SDL_SCANCODE_KP_9)) whichend = 9;
4867 if (Input::isKeyDown(SDL_SCANCODE_KP_0)) whichend = 0;
4868 Dialog::currentScene().participantfacing[whichend] = facing;
4870 if (Dialog::indialogue >= int(Dialog::currentDialog().scenes.size())) {
4871 Dialog::indialogue = -1;
4872 Dialog::directing = false;
4876 if (!Dialog::directing) {
4877 pause_sound(whooshsound);
4878 viewer = Dialog::currentScene().camera;
4879 viewer.y = max((double)viewer.y, terrain.getHeight(viewer.x, viewer.z) + .1);
4880 yaw = Dialog::currentScene().camerayaw;
4881 pitch = Dialog::currentScene().camerapitch;
4882 if (Dialog::dialoguetime > 0.5) {
4883 if (Input::isKeyPressed(attackkey)) {
4884 Dialog::indialogue++;
4885 if (Dialog::indialogue < int(Dialog::currentDialog().scenes.size())) {
4886 if (Dialog::currentScene().sound != 0) {
4887 playdialoguescenesound();
4888 if (Dialog::currentScene().sound == -5) {
4889 Hotspot::hotspots.emplace_back(Person::players[0]->coords, -1, 10);
4891 if (Dialog::currentScene().sound == -6) {
4895 if (Person::players[Dialog::currentScene().participantfocus]->dead) {
4896 Dialog::indialogue = -1;
4897 Dialog::directing = false;
4904 if (Dialog::indialogue >= int(Dialog::currentDialog().scenes.size())) {
4905 Dialog::indialogue = -1;
4906 Dialog::directing = false;
4908 if (Dialog::currentDialog().type > 19 && Dialog::currentDialog().type < 30) {
4911 if (Dialog::currentDialog().type > 29 && Dialog::currentDialog().type < 40) {
4914 if (Dialog::currentDialog().type > 49 && Dialog::currentDialog().type < 60) {
4916 for (unsigned i = 1; i < Person::players.size(); i++) {
4917 Person::players[i]->aitype = attacktypecutoff;
4924 if (!Person::players[0]->jumpkeydown) {
4925 Person::players[0]->jumptogglekeydown = 0;
4927 if (Person::players[0]->jumpkeydown &&
4928 Person::players[0]->animTarget != jumpupanim &&
4929 Person::players[0]->animTarget != jumpdownanim &&
4930 !Person::players[0]->isFlip())
4931 Person::players[0]->jumptogglekeydown = 1;
4934 Dialog::dialoguetime += multiplier;
4935 hawkyaw += multiplier * 25;
4937 realhawkcoords.x = 25;
4938 realhawkcoords = DoRotation(realhawkcoords, 0, hawkyaw, 0) + hawkcoords;
4939 hawkcalldelay -= multiplier / 2;
4941 if (hawkcalldelay <= 0) {
4942 emit_sound_at(hawksound, realhawkcoords);
4944 hawkcalldelay = 16 + abs(Random() % 8);
4951 doPlayerCollisions();
4955 for (unsigned k = 0; k < Person::players.size(); k++)
4956 if (k != 0 && Person::players[k]->immobile)
4957 Person::players[k]->coords = Person::players[k]->realoldcoords;
4959 for (unsigned k = 0; k < Person::players.size(); k++) {
4960 if (!isnormal(Person::players[k]->coords.x) || !isnormal(Person::players[k]->coords.y) || !isnormal(Person::players[k]->coords.z)) {
4961 if (!isnormal(Person::players[k]->coords.x) || !isnormal(Person::players[k]->coords.y) || !isnormal(Person::players[k]->coords.z)) {
4962 Person::players[k]->DoDamage(1000);
4968 static bool respawnkeydown;
4969 if (!editorenabled &&
4970 (whichlevel != -2 &&
4971 (Input::isKeyDown(SDL_SCANCODE_Z) &&
4972 Input::isKeyDown(SDL_SCANCODE_LGUI) &&
4974 (Input::isKeyDown(jumpkey) &&
4977 Person::players[0]->dead))) {
4978 targetlevel = whichlevel;
4982 respawnkeydown = Input::isKeyDown(jumpkey);
4985 static bool movekey;
4988 for (unsigned i = 0; i < Person::players.size(); i++) {
4989 static float oldtargetyaw;
4990 if (!Person::players[i]->skeleton.free) {
4991 oldtargetyaw = Person::players[i]->targetyaw;
4992 if (i == 0 && !Dialog::inDialog()) {
4993 //TODO: refactor repetitive code
4994 if (!Animation::animations[Person::players[0]->animTarget].attack &&
4995 Person::players[0]->animTarget != staggerbackhighanim &&
4996 Person::players[0]->animTarget != staggerbackhardanim &&
4997 Person::players[0]->animTarget != crouchremoveknifeanim &&
4998 Person::players[0]->animTarget != removeknifeanim &&
4999 Person::players[0]->animTarget != backhandspringanim &&
5000 Person::players[0]->animTarget != dodgebackanim &&
5001 Person::players[0]->animTarget != walljumprightkickanim &&
5002 Person::players[0]->animTarget != walljumpleftkickanim) {
5004 Person::players[0]->targetyaw = 0;
5006 Person::players[0]->targetyaw = -yaw + 180;
5012 flatfacing = DoRotation(facing, 0, Person::players[i]->yaw + 180, 0);
5014 facing = flatfacing;
5016 facing = DoRotation(facing, -pitch, 0, 0);
5017 facing = DoRotation(facing, 0, 0 - yaw, 0);
5020 Person::players[0]->lookyaw = -yaw;
5022 Person::players[i]->targetheadyaw = yaw;
5023 Person::players[i]->targetheadpitch = pitch;
5025 if (i != 0 && Person::players[i]->aitype == playercontrolled && !Dialog::inDialog()) {
5026 if (!Animation::animations[Person::players[i]->animTarget].attack &&
5027 Person::players[i]->animTarget != staggerbackhighanim &&
5028 Person::players[i]->animTarget != staggerbackhardanim &&
5029 Person::players[i]->animTarget != crouchremoveknifeanim &&
5030 Person::players[i]->animTarget != removeknifeanim &&
5031 Person::players[i]->animTarget != backhandspringanim &&
5032 Person::players[i]->animTarget != dodgebackanim &&
5033 Person::players[i]->animTarget != walljumprightkickanim &&
5034 Person::players[i]->animTarget != walljumpleftkickanim) {
5035 Person::players[i]->targetyaw = -Person::players[i]->lookyaw + 180;
5041 flatfacing = DoRotation(facing, 0, Person::players[i]->yaw + 180, 0);
5043 facing = DoRotation(facing, -Person::players[i]->lookpitch, 0, 0);
5044 facing = DoRotation(facing, 0, 0 - Person::players[i]->lookyaw, 0);
5046 Person::players[i]->targetheadyaw = Person::players[i]->lookyaw;
5047 Person::players[i]->targetheadpitch = Person::players[i]->lookpitch;
5049 if (Dialog::inDialog()) {
5050 Person::players[i]->targetheadyaw = 180 - roughDirection(Dialog::currentScene().participantfacing[i]);
5051 Person::players[i]->targetheadpitch = pitchOf(Dialog::currentScene().participantfacing[i]);
5057 Person::players[i]->avoidsomething = 0;
5059 //avoid flaming things
5060 for (int j = 0; j < Object::objects.size(); j++)
5061 if (Object::objects[j]->onfire)
5062 if (distsq(&Person::players[i]->coords, &Object::objects[j]->position) < sq(Object::objects[j]->scale) * 200)
5063 if ( distsq(&Person::players[i]->coords, &Object::objects[j]->position) <
5064 distsq(&Person::players[i]->coords, &Person::players[0]->coords)) {
5065 Person::players[i]->collided = 0;
5066 Person::players[i]->avoidcollided = 1;
5067 if (Person::players[i]->avoidsomething == 0 ||
5068 distsq(&Person::players[i]->coords, &Object::objects[j]->position) <
5069 distsq(&Person::players[i]->coords, &Person::players[i]->avoidwhere)) {
5070 Person::players[i]->avoidwhere = Object::objects[j]->position;
5071 Person::players[i]->avoidsomething = 1;
5075 //avoid flaming players
5076 for (unsigned j = 0; j < Person::players.size(); j++)
5077 if (Person::players[j]->onfire)
5078 if (distsq(&Person::players[j]->coords, &Person::players[i]->coords) < sq(0.3) * 200)
5079 if ( distsq(&Person::players[i]->coords, &Person::players[j]->coords) <
5080 distsq(&Person::players[i]->coords, &Person::players[0]->coords)) {
5081 Person::players[i]->collided = 0;
5082 Person::players[i]->avoidcollided = 1;
5083 if (Person::players[i]->avoidsomething == 0 ||
5084 distsq(&Person::players[i]->coords, &Person::players[j]->coords) <
5085 distsq(&Person::players[i]->coords, &Person::players[i]->avoidwhere)) {
5086 Person::players[i]->avoidwhere = Person::players[j]->coords;
5087 Person::players[i]->avoidsomething = 1;
5091 if (Person::players[i]->collided > .8)
5092 Person::players[i]->avoidcollided = 0;
5096 if (Animation::animations[Person::players[i]->animTarget].attack == reversed) {
5097 //Person::players[i]->targetyaw=Person::players[i]->yaw;
5098 Person::players[i]->forwardkeydown = 0;
5099 Person::players[i]->leftkeydown = 0;
5100 Person::players[i]->backkeydown = 0;
5101 Person::players[i]->rightkeydown = 0;
5102 Person::players[i]->jumpkeydown = 0;
5103 Person::players[i]->attackkeydown = 0;
5104 //Person::players[i]->crouchkeydown=0;
5105 Person::players[i]->throwkeydown = 0;
5108 if (Dialog::inDialog()) {
5109 Person::players[i]->forwardkeydown = 0;
5110 Person::players[i]->leftkeydown = 0;
5111 Person::players[i]->backkeydown = 0;
5112 Person::players[i]->rightkeydown = 0;
5113 Person::players[i]->jumpkeydown = 0;
5114 Person::players[i]->crouchkeydown = 0;
5115 Person::players[i]->drawkeydown = 0;
5116 Person::players[i]->throwkeydown = 0;
5119 if (Person::players[i]->collided < -.3)
5120 Person::players[i]->collided = -.3;
5121 if (Person::players[i]->collided > 1)
5122 Person::players[i]->collided = 1;
5123 Person::players[i]->collided -= multiplier * 4;
5124 Person::players[i]->whichdirectiondelay -= multiplier;
5125 if (Person::players[i]->avoidcollided < -.3 || Person::players[i]->whichdirectiondelay <= 0) {
5126 Person::players[i]->avoidcollided = -.3;
5127 Person::players[i]->whichdirection = abs(Random() % 2);
5128 Person::players[i]->whichdirectiondelay = .4;
5130 if (Person::players[i]->avoidcollided > 1)
5131 Person::players[i]->avoidcollided = 1;
5132 Person::players[i]->avoidcollided -= multiplier / 4;
5133 if (!Person::players[i]->skeleton.free) {
5134 Person::players[i]->stunned -= multiplier;
5135 Person::players[i]->surprised -= multiplier;
5137 if (i != 0 && Person::players[i]->surprised <= 0 &&
5138 Person::players[i]->aitype == attacktypecutoff &&
5139 !Person::players[i]->dead &&
5140 !Person::players[i]->skeleton.free &&
5141 Animation::animations[Person::players[i]->animTarget].attack == neutral)
5144 if (!Person::players[i]->throwkeydown)
5145 Person::players[i]->throwtogglekeydown = 0;
5148 if (Person::players[i]->throwkeydown && !Person::players[i]->throwtogglekeydown) {
5149 if (Person::players[i]->weaponactive == -1 &&
5150 Person::players[i]->num_weapons < 2 &&
5151 (Person::players[i]->isIdle() ||
5152 Person::players[i]->isCrouch() ||
5153 Person::players[i]->animTarget == sneakanim ||
5154 Person::players[i]->animTarget == rollanim ||
5155 Person::players[i]->animTarget == backhandspringanim ||
5156 Person::players[i]->isFlip() ||
5157 Person::players[i]->aitype != playercontrolled)) {
5158 for (unsigned j = 0; j < weapons.size(); j++) {
5159 if ((weapons[j].velocity.x == 0 && weapons[j].velocity.y == 0 && weapons[j].velocity.z == 0 ||
5160 Person::players[i]->aitype == playercontrolled) &&
5161 weapons[j].owner == -1 &&
5162 Person::players[i]->weaponactive == -1)
5163 if (distsqflat(&Person::players[i]->coords, &weapons[j].position) < 2) {
5164 if (distsq(&Person::players[i]->coords, &weapons[j].position) < 2) {
5165 if (Person::players[i]->isCrouch() ||
5166 Person::players[i]->animTarget == sneakanim ||
5167 Person::players[i]->isRun() ||
5168 Person::players[i]->isIdle() ||
5169 Person::players[i]->aitype != playercontrolled) {
5170 Person::players[i]->throwtogglekeydown = 1;
5171 Person::players[i]->setAnimation(crouchremoveknifeanim);
5172 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, weapons[j].position);
5173 Person::players[i]->hasvictim = 0;
5175 if (Person::players[i]->animTarget == rollanim || Person::players[i]->animTarget == backhandspringanim) {
5176 Person::players[i]->throwtogglekeydown = 1;
5177 Person::players[i]->hasvictim = 0;
5179 if ((weapons[j].velocity.x == 0 && weapons[j].velocity.y == 0 && weapons[j].velocity.z == 0 ||
5180 Person::players[i]->aitype == playercontrolled) &&
5181 weapons[j].owner == -1 ||
5182 Person::players[i]->victim &&
5183 weapons[j].owner == int(Person::players[i]->victim->id))
5184 if (distsqflat(&Person::players[i]->coords, &weapons[j].position) < 2 && Person::players[i]->weaponactive == -1)
5185 if (distsq(&Person::players[i]->coords, &weapons[j].position) < 1 || Person::players[i]->victim) {
5186 if (weapons[j].getType() != staff)
5187 emit_sound_at(knifedrawsound, Person::players[i]->coords, 128.);
5189 Person::players[i]->takeWeapon(j);
5192 } else if ((Person::players[i]->isIdle() ||
5193 Person::players[i]->isFlip() ||
5194 Person::players[i]->aitype != playercontrolled) &&
5195 distsq(&Person::players[i]->coords, &weapons[j].position) < 5 &&
5196 Person::players[i]->coords.y < weapons[j].position.y) {
5197 if (!Person::players[i]->isFlip()) {
5198 Person::players[i]->throwtogglekeydown = 1;
5199 Person::players[i]->setAnimation(removeknifeanim);
5200 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, weapons[j].position);
5202 if (Person::players[i]->isFlip()) {
5203 Person::players[i]->throwtogglekeydown = 1;
5204 Person::players[i]->hasvictim = 0;
5206 for (unsigned k = 0; k < weapons.size(); k++) {
5207 if (Person::players[i]->weaponactive == -1)
5208 if ((weapons[k].velocity.x == 0 && weapons[k].velocity.y == 0 && weapons[k].velocity.z == 0 ||
5209 Person::players[i]->aitype == playercontrolled) &&
5210 weapons[k].owner == -1 ||
5211 Person::players[i]->victim &&
5212 weapons[k].owner == int(Person::players[i]->victim->id))
5213 if (distsqflat(&Person::players[i]->coords, &weapons[k].position) < 3 &&
5214 Person::players[i]->weaponactive == -1) {
5215 if (weapons[k].getType() != staff)
5216 emit_sound_at(knifedrawsound, Person::players[i]->coords, 128.);
5218 Person::players[i]->takeWeapon(k);
5225 if (Person::players[i]->isCrouch() ||
5226 Person::players[i]->animTarget == sneakanim ||
5227 Person::players[i]->isRun() ||
5228 Person::players[i]->isIdle() || Person::players[i]->animTarget == rollanim ||
5229 Person::players[i]->animTarget == backhandspringanim) {
5230 if (Person::players.size() > 1)
5231 for (unsigned j = 0; j < Person::players.size(); j++) {
5232 if (Person::players[i]->weaponactive == -1)
5234 if (Person::players[j]->num_weapons &&
5235 Person::players[j]->skeleton.free &&
5236 distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 2/*&&Person::players[j]->dead*/ &&
5237 (((Person::players[j]->skeleton.forward.y < 0 &&
5238 Person::players[j]->weaponstuckwhere == 0) ||
5239 (Person::players[j]->skeleton.forward.y > 0 &&
5240 Person::players[j]->weaponstuckwhere == 1)) ||
5241 Person::players[j]->weaponstuck == -1 ||
5242 Person::players[j]->num_weapons > 1)) {
5243 if (Person::players[i]->animTarget != rollanim && Person::players[i]->animTarget != backhandspringanim) {
5244 Person::players[i]->throwtogglekeydown = 1;
5245 Person::players[i]->victim = Person::players[j];
5246 Person::players[i]->hasvictim = 1;
5247 Person::players[i]->setAnimation(crouchremoveknifeanim);
5248 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[j]->coords);
5250 if (Person::players[i]->animTarget == rollanim || Person::players[i]->animTarget == backhandspringanim) {
5251 Person::players[i]->throwtogglekeydown = 1;
5252 Person::players[i]->victim = Person::players[j];
5253 Person::players[i]->hasvictim = 1;
5254 int k = Person::players[j]->weaponids[0];
5255 if (Person::players[i]->hasvictim) {
5258 if (Person::players[i]->victim->weaponstuck != -1) {
5259 if (Person::players[i]->victim->weaponids[Person::players[i]->victim->weaponstuck] == k) {
5264 if (weapons[k].getType() != staff)
5265 emit_sound_at(knifedrawsound, Person::players[i]->coords, 128.);
5268 emit_sound_at(fleshstabremovesound, Person::players[i]->coords, 128.);
5270 if (weapons[k].owner != -1) {
5271 if (Person::players[i]->victim->num_weapons == 1)
5272 Person::players[i]->victim->num_weapons = 0;
5274 Person::players[i]->victim->num_weapons = 1;
5276 Person::players[i]->victim->skeleton.longdead = 0;
5277 Person::players[i]->victim->skeleton.free = 1;
5278 Person::players[i]->victim->skeleton.broken = 0;
5280 for (unsigned l = 0; l < Person::players[i]->victim->skeleton.joints.size(); l++) {
5281 Person::players[i]->victim->skeleton.joints[l].velchange = 0;
5282 Person::players[i]->victim->skeleton.joints[l].locked = 0;
5288 Normalise(&relative);
5289 XYZ footvel, footpoint;
5291 footpoint = weapons[k].position;
5292 if (Person::players[i]->victim->weaponstuck != -1) {
5293 if (Person::players[i]->victim->weaponids[Person::players[i]->victim->weaponstuck] == k) {
5295 Sprite::MakeSprite(cloudimpactsprite, footpoint, footvel, 1, 0, 0, .8, .3);
5296 weapons[k].bloody = 2;
5297 weapons[k].blooddrip = 5;
5298 Person::players[i]->victim->weaponstuck = -1;
5299 Person::players[i]->victim->bloodloss += 2000;
5300 Person::players[i]->victim->DoDamage(2000);
5303 if (Person::players[i]->victim->num_weapons > 0) {
5304 if (Person::players[i]->victim->weaponstuck != 0 && Person::players[i]->victim->weaponstuck != -1)
5305 Person::players[i]->victim->weaponstuck = 0;
5306 if (Person::players[i]->victim->weaponids[0] == k)
5307 Person::players[i]->victim->weaponids[0] = Person::players[i]->victim->weaponids[Person::players[i]->victim->num_weapons];
5310 Person::players[i]->victim->weaponactive = -1;
5312 Person::players[i]->victim->jointVel(abdomen) += relative * 6;
5313 Person::players[i]->victim->jointVel(neck) += relative * 6;
5314 Person::players[i]->victim->jointVel(rightshoulder) += relative * 6;
5315 Person::players[i]->victim->jointVel(leftshoulder) += relative * 6;
5317 Person::players[i]->takeWeapon(k);
5324 if (Person::players[i]->weaponactive != -1 && Person::players[i]->aitype == playercontrolled) {
5325 if (weapons[Person::players[i]->weaponids[0]].getType() == knife) {
5326 if (Person::players[i]->isIdle() ||
5327 Person::players[i]->isRun() ||
5328 Person::players[i]->isCrouch() ||
5329 Person::players[i]->animTarget == sneakanim ||
5330 Person::players[i]->isFlip())
5331 if (Person::players.size() > 1)
5332 for (unsigned j = 0; j < Person::players.size(); j++) {
5334 if (tutoriallevel != 1 || tutorialstage == 49)
5336 if (normaldotproduct(Person::players[i]->facing, Person::players[i]->coords - Person::players[j]->coords) < 0 &&
5337 distsq(&Person::players[i]->coords, &Person::players[j]->coords) < 100 &&
5338 distsq(&Person::players[i]->coords, &Person::players[j]->coords) > 1.5 &&
5339 !Person::players[j]->skeleton.free &&
5340 -1 == checkcollide(DoRotation(Person::players[j]->jointPos(head), 0, Person::players[j]->yaw, 0)*Person::players[j]->scale + Person::players[j]->coords, DoRotation(Person::players[i]->jointPos(head), 0, Person::players[i]->yaw, 0)*Person::players[i]->scale + Person::players[i]->coords)) {
5341 if (!Person::players[i]->isFlip()) {
5342 Person::players[i]->throwtogglekeydown = 1;
5343 Person::players[i]->victim = Person::players[j];
5344 Person::players[i]->setAnimation(knifethrowanim);
5345 Person::players[i]->targetyaw = roughDirectionTo(Person::players[i]->coords, Person::players[j]->coords);
5346 Person::players[i]->targettilt2 = pitchTo(Person::players[i]->coords, Person::players[j]->coords);
5348 if (Person::players[i]->isFlip()) {
5349 if (Person::players[i]->weaponactive != -1) {
5350 Person::players[i]->throwtogglekeydown = 1;
5351 Person::players[i]->victim = Person::players[j];
5353 aim = Person::players[i]->victim->coords + DoRotation(Person::players[i]->victim->jointPos(abdomen), 0, Person::players[i]->victim->yaw, 0) * Person::players[i]->victim->scale + Person::players[i]->victim->velocity * findDistance(&Person::players[i]->victim->coords, &Person::players[i]->coords) / 50 - (Person::players[i]->coords + DoRotation(Person::players[i]->jointPos(righthand), 0, Person::players[i]->yaw, 0) * Person::players[i]->scale);
5356 aim = DoRotation(aim, (float)abs(Random() % 30) - 15, (float)abs(Random() % 30) - 15, 0);
5358 weapons[Person::players[i]->weaponids[0]].thrown(aim * 50, false);
5359 Person::players[i]->num_weapons--;
5360 if (Person::players[i]->num_weapons) {
5361 Person::players[i]->weaponids[0] = Person::players[i]->weaponids[Person::players[i]->num_weapons];
5363 Person::players[i]->weaponactive = -1;
5370 if (Person::players[i]->weaponactive != -1 && Person::players[i]->aitype == playercontrolled) {
5371 if (Person::players[i]->isCrouch() || Person::players[i]->animTarget == sneakanim) {
5372 Person::players[i]->throwtogglekeydown = 1;
5373 XYZ tempVelocity = Person::players[i]->velocity * .2;
5374 if (tempVelocity.x == 0)
5375 tempVelocity.x = .1;
5376 weapons[Person::players[i]->weaponids[0]].drop(tempVelocity, tempVelocity, false);
5377 Person::players[i]->num_weapons--;
5378 if (Person::players[i]->num_weapons) {
5379 Person::players[i]->weaponids[0] = Person::players[i]->weaponids[Person::players[i]->num_weapons];
5380 if (Person::players[i]->weaponstuck == Person::players[i]->num_weapons)
5381 Person::players[i]->weaponstuck = 0;
5384 Person::players[i]->weaponactive = -1;
5385 for (unsigned j = 0; j < Person::players.size(); j++) {
5386 Person::players[j]->wentforweapon = 0;
5394 if (i == 0 || !Person::players[0]->dead || (Person::players[i]->weaponactive != -1)) {
5395 if (Person::players[i]->drawkeydown && !Person::players[i]->drawtogglekeydown ||
5396 (Person::players[i]->num_weapons == 2) &&
5397 (Person::players[i]->weaponactive == -1) &&
5398 Person::players[i]->isIdle() ||
5399 Person::players[0]->dead &&
5400 (Person::players[i]->weaponactive != -1) &&
5403 if (Person::players[i]->weaponactive != -1)
5404 if (weapons[Person::players[i]->weaponids[Person::players[i]->weaponactive]].getType() == staff)
5406 if (isgood && Person::players[i]->creature != wolftype) {
5407 if (Person::players[i]->isIdle() && Person::players[i]->num_weapons && weapons[Person::players[i]->weaponids[0]].getType() == knife) {
5408 Person::players[i]->setAnimation(drawrightanim);
5409 Person::players[i]->drawtogglekeydown = 1;
5411 if ((Person::players[i]->isIdle() ||
5412 (Person::players[i]->aitype != playercontrolled &&
5413 Person::players[0]->weaponactive != -1 &&
5414 Person::players[i]->isRun())) &&
5415 Person::players[i]->num_weapons &&
5416 weapons[Person::players[i]->weaponids[0]].getType() == sword) {
5417 Person::players[i]->setAnimation(drawleftanim);
5418 Person::players[i]->drawtogglekeydown = 1;
5420 if (Person::players[i]->isCrouch() && Person::players[i]->num_weapons && weapons[Person::players[i]->weaponids[0]].getType() == knife) {
5421 Person::players[i]->setAnimation(crouchdrawrightanim);
5422 Person::players[i]->drawtogglekeydown = 1;
5429 if (Person::players[i]->weaponactive != -1) {
5430 if (Person::players[i]->isCrouch() &&
5431 weapons[Person::players[i]->weaponids[Person::players[i]->weaponactive]].bloody &&
5433 Person::players[i]->onterrain &&
5434 Person::players[i]->num_weapons &&
5435 Person::players[i]->attackkeydown &&
5436 musictype != stream_fighttheme) {
5437 if (weapons[Person::players[i]->weaponids[Person::players[i]->weaponactive]].getType() == knife)
5438 Person::players[i]->setAnimation(crouchstabanim);
5439 if (weapons[Person::players[i]->weaponids[Person::players[i]->weaponactive]].getType() == sword)
5440 Person::players[i]->setAnimation(swordgroundstabanim);
5441 Person::players[i]->hasvictim = 0;
5445 if (!Person::players[i]->drawkeydown)
5446 Person::players[i]->drawtogglekeydown = 0;
5451 absflatfacing.z = -1;
5453 absflatfacing = DoRotation(absflatfacing, 0, -yaw, 0);
5455 absflatfacing = flatfacing;
5457 if (Dialog::inDialog()) {
5458 Person::players[i]->forwardkeydown = 0;
5459 Person::players[i]->leftkeydown = 0;
5460 Person::players[i]->backkeydown = 0;
5461 Person::players[i]->rightkeydown = 0;
5462 Person::players[i]->jumpkeydown = 0;
5463 Person::players[i]->crouchkeydown = 0;
5464 Person::players[i]->drawkeydown = 0;
5465 Person::players[i]->throwkeydown = 0;
5469 if (!Animation::animations[Person::players[i]->animTarget].attack &&
5470 Person::players[i]->animTarget != staggerbackhighanim &&
5471 Person::players[i]->animTarget != staggerbackhardanim &&
5472 Person::players[i]->animTarget != backhandspringanim &&
5473 Person::players[i]->animTarget != dodgebackanim) {
5474 if (!Person::players[i]->forwardkeydown)
5475 Person::players[i]->forwardstogglekeydown = 0;
5476 if (Person::players[i]->crouchkeydown) {
5480 Person::players[i]->superruntoggle = 1;
5481 if (Person::players.size() > 1)
5482 for (unsigned j = 0; j < Person::players.size(); j++)
5483 if (j != i && !Person::players[j]->skeleton.free && Person::players[j]->aitype == passivetype)
5484 if (distsq(&Person::players[j]->coords, &Person::players[i]->coords) < 16)
5485 Person::players[i]->superruntoggle = 0;
5488 if (Person::players.size() > 1)
5489 for (unsigned j = 0; j < Person::players.size(); j++) {
5490 if (j != i && !Person::players[j]->skeleton.free && Person::players[j]->victim && Person::players[i]->lowreversaldelay <= 0) {
5491 if (distsq(&Person::players[j]->coords, &Person::players[j]->victim->coords) < 3 &&
5492 Person::players[j]->victim == Person::players[i] &&
5493 (Person::players[j]->animTarget == sweepanim ||
5494 Person::players[j]->animTarget == upunchanim ||
5495 Person::players[j]->animTarget == wolfslapanim ||
5496 ((Person::players[j]->animTarget == swordslashanim ||
5497 Person::players[j]->animTarget == knifeslashstartanim ||
5498 Person::players[j]->animTarget == staffhitanim ||
5499 Person::players[j]->animTarget == staffspinhitanim) &&
5500 distsq(&Person::players[j]->coords, &Person::players[i]->coords) < 2))) {
5509 Person::players[target]->Reverse();
5510 Person::players[i]->lowreversaldelay = .5;
5512 if (Person::players[i]->isIdle()) {
5513 Person::players[i]->setAnimation(Person::players[i]->getCrouch());
5514 Person::players[i]->transspeed = 10;
5516 if (Person::players[i]->isRun() ||
5517 (Person::players[i]->isStop() &&
5518 (Person::players[i]->leftkeydown ||
5519 Person::players[i]->rightkeydown ||
5520 Person::players[i]->forwardkeydown ||
5521 Person::players[i]->backkeydown))) {
5522 Person::players[i]->setAnimation(rollanim);
5523 Person::players[i]->transspeed = 20;
5526 if (!Person::players[i]->crouchkeydown) {
5528 if (!Person::players[i]->isRun() && Person::players[i]->animTarget != sneakanim && i == 0)
5529 Person::players[i]->superruntoggle = 0;
5531 if (Person::players[i]->isCrouch()) {
5532 if (Person::players.size() > 1)
5533 for (unsigned j = 0; j < Person::players.size(); j++) {
5535 !Person::players[j]->skeleton.free &&
5536 Person::players[j]->victim &&
5537 Person::players[i]->highreversaldelay <= 0) {
5538 if (distsq(&Person::players[j]->coords, &Person::players[j]->victim->coords) < 3 &&
5539 Person::players[j]->victim == Person::players[i] &&
5540 (Person::players[j]->animTarget == spinkickanim) &&
5541 Person::players[i]->isCrouch()) {
5550 Person::players[target]->Reverse();
5551 Person::players[i]->highreversaldelay = .5;
5553 if (Person::players[i]->isCrouch()) {
5554 if (!Person::players[i]->wasCrouch()) {
5555 Person::players[i]->animCurrent = Person::players[i]->getCrouch();
5556 Person::players[i]->frameCurrent = 0;
5558 Person::players[i]->setAnimation(Person::players[i]->getIdle());
5559 Person::players[i]->transspeed = 10;
5562 if (Person::players[i]->animTarget == sneakanim) {
5563 Person::players[i]->setAnimation(Person::players[i]->getIdle());
5564 Person::players[i]->transspeed = 10;
5567 if (Person::players[i]->forwardkeydown) {
5568 if (Person::players[i]->isIdle() ||
5569 (Person::players[i]->isStop() &&
5570 Person::players[i]->targetyaw == Person::players[i]->yaw) ||
5571 (Person::players[i]->isLanding() &&
5572 Person::players[i]->frameTarget > 0 &&
5573 !Person::players[i]->jumpkeydown) ||
5574 (Person::players[i]->isLandhard() &&
5575 Person::players[i]->frameTarget > 0 &&
5576 !Person::players[i]->jumpkeydown &&
5577 Person::players[i]->crouchkeydown)) {
5578 if (Person::players[i]->aitype == passivetype)
5579 Person::players[i]->setAnimation(walkanim);
5581 Person::players[i]->setAnimation(Person::players[i]->getRun());
5583 if (Person::players[i]->isCrouch()) {
5584 Person::players[i]->animTarget = sneakanim;
5585 if (Person::players[i]->wasCrouch())
5586 Person::players[i]->target = 0;
5587 Person::players[i]->frameTarget = 0;
5589 if (Person::players[i]->animTarget == hanganim/*&&(!Person::players[i]->forwardstogglekeydown||Person::players[i]->aitype!=playercontrolled)*/) {
5590 Person::players[i]->setAnimation(climbanim);
5591 Person::players[i]->frameTarget = 1;
5592 Person::players[i]->jumpclimb = 1;
5594 if (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim || Person::players[i]->isFlip()) {
5595 Person::players[i]->velocity += absflatfacing * 5 * multiplier;
5597 Person::players[i]->forwardstogglekeydown = 1;
5600 if (Person::players[i]->rightkeydown) {
5601 if (Person::players[i]->isIdle() ||
5602 (Person::players[i]->isStop() &&
5603 Person::players[i]->targetyaw == Person::players[i]->yaw) ||
5604 (Person::players[i]->isLanding() &&
5605 Person::players[i]->frameTarget > 0 &&
5606 !Person::players[i]->jumpkeydown) ||
5607 (Person::players[i]->isLandhard() &&
5608 Person::players[i]->frameTarget > 0 &&
5609 !Person::players[i]->jumpkeydown &&
5610 Person::players[i]->crouchkeydown)) {
5611 Person::players[i]->setAnimation(Person::players[i]->getRun());
5613 if (Person::players[i]->isCrouch()) {
5614 Person::players[i]->animTarget = sneakanim;
5615 if (Person::players[i]->wasCrouch())
5616 Person::players[i]->target = 0;
5617 Person::players[i]->frameTarget = 0;
5619 if (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim || Person::players[i]->isFlip()) {
5620 Person::players[i]->velocity += DoRotation(absflatfacing * 5 * multiplier, 0, -90, 0);
5622 Person::players[i]->targetyaw -= 90;
5623 if (Person::players[i]->forwardkeydown)
5624 Person::players[i]->targetyaw += 45;
5625 if (Person::players[i]->backkeydown)
5626 Person::players[i]->targetyaw -= 45;
5629 if ( Person::players[i]->leftkeydown) {
5630 if (Person::players[i]->isIdle() ||
5631 (Person::players[i]->isStop() &&
5632 Person::players[i]->targetyaw == Person::players[i]->yaw) ||
5633 (Person::players[i]->isLanding() &&
5634 Person::players[i]->frameTarget > 0 &&
5635 !Person::players[i]->jumpkeydown) ||
5636 (Person::players[i]->isLandhard() &&
5637 Person::players[i]->frameTarget > 0 &&
5638 !Person::players[i]->jumpkeydown &&
5639 Person::players[i]->crouchkeydown)) {
5640 Person::players[i]->setAnimation(Person::players[i]->getRun());
5642 if (Person::players[i]->isCrouch()) {
5643 Person::players[i]->animTarget = sneakanim;
5644 if (Person::players[i]->wasCrouch())
5645 Person::players[i]->target = 0;
5646 Person::players[i]->frameTarget = 0;
5648 if (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim || Person::players[i]->isFlip()) {
5649 Person::players[i]->velocity -= DoRotation(absflatfacing * 5 * multiplier, 0, -90, 0);
5651 Person::players[i]->targetyaw += 90;
5652 if (Person::players[i]->forwardkeydown)
5653 Person::players[i]->targetyaw -= 45;
5654 if (Person::players[i]->backkeydown)
5655 Person::players[i]->targetyaw += 45;
5658 if (Person::players[i]->backkeydown) {
5659 if (Person::players[i]->isIdle() ||
5660 (Person::players[i]->isStop() &&
5661 Person::players[i]->targetyaw == Person::players[i]->yaw) ||
5662 (Person::players[i]->isLanding() &&
5663 Person::players[i]->frameTarget > 0 &&
5664 !Person::players[i]->jumpkeydown) ||
5665 (Person::players[i]->isLandhard() &&
5666 Person::players[i]->frameTarget > 0 &&
5667 !Person::players[i]->jumpkeydown &&
5668 Person::players[i]->crouchkeydown)) {
5669 Person::players[i]->setAnimation(Person::players[i]->getRun());
5671 if (Person::players[i]->isCrouch()) {
5672 Person::players[i]->animTarget = sneakanim;
5673 if (Person::players[i]->wasCrouch())
5674 Person::players[i]->target = 0;
5675 Person::players[i]->frameTarget = 0;
5677 if (Person::players[i]->animTarget == jumpupanim || Person::players[i]->animTarget == jumpdownanim || Person::players[i]->isFlip()) {
5678 Person::players[i]->velocity -= absflatfacing * 5 * multiplier;
5680 if (Person::players[i]->animTarget == hanganim) {
5681 Person::players[i]->animCurrent = jumpdownanim;
5682 Person::players[i]->animTarget = jumpdownanim;
5683 Person::players[i]->target = 0;
5684 Person::players[i]->frameCurrent = 0;
5685 Person::players[i]->frameTarget = 1;
5686 Person::players[i]->velocity = 0;
5687 Person::players[i]->velocity.y += gravity;
5688 Person::players[i]->coords.y -= 1.4;
5689 Person::players[i]->grabdelay = 1;
5691 if ( !Person::players[i]->leftkeydown && !Person::players[i]->rightkeydown)
5692 Person::players[i]->targetyaw += 180;
5695 if ((Person::players[i]->jumpkeydown && !Person::players[i]->jumpclimb) || Person::players[i]->jumpstart) {
5696 if ((((Person::players[i]->isLanding() && Person::players[i]->frameTarget >= 3) ||
5697 Person::players[i]->isRun() ||
5698 Person::players[i]->animTarget == walkanim ||
5699 Person::players[i]->isCrouch() ||
5700 Person::players[i]->animTarget == sneakanim) &&
5701 Person::players[i]->jumppower > 1) &&
5702 ((Person::players[i]->animTarget != rabbitrunninganim &&
5703 Person::players[i]->animTarget != wolfrunninganim) || i != 0)) {
5704 Person::players[i]->jumpstart = 0;
5705 Person::players[i]->setAnimation(jumpupanim);
5706 Person::players[i]->yaw = Person::players[i]->targetyaw;
5707 Person::players[i]->transspeed = 20;
5708 Person::players[i]->FootLand(leftfoot, 1);
5709 Person::players[i]->FootLand(rightfoot, 1);
5713 flatfacing = DoRotation(facing, 0, Person::players[i]->targetyaw + 180, 0);
5716 Person::players[i]->velocity = flatfacing * Person::players[i]->speed * 45 * Person::players[i]->scale;
5718 Person::players[i]->velocity = 0;
5722 if (Person::players.size() > 1)
5723 for (unsigned j = 0; j < Person::players.size(); j++) {
5724 if (j != i && !Person::players[j]->skeleton.free && Person::players[j]->victim) {
5725 if (distsq(&Person::players[j]->coords, &Person::players[j]->victim->coords) < 3 &&
5726 (Person::players[j]->victim == Person::players[i]) &&
5727 (Person::players[j]->animTarget == sweepanim)) {
5736 Person::players[i]->velocity.y = 1;
5738 if (Person::players[i]->crouchkeydown || Person::players[i]->aitype != playercontrolled) {
5739 Person::players[i]->velocity.y = 7;
5740 Person::players[i]->crouchtogglekeydown = 1;
5741 } else Person::players[i]->velocity.y = 5;
5743 if (mousejump && i == 0 && devtools) {
5744 if (!Person::players[i]->isLanding())
5745 Person::players[i]->tempdeltav = deltav;
5746 if (Person::players[i]->tempdeltav < 0)
5747 Person::players[i]->velocity.y -= (float)(Person::players[i]->tempdeltav) / multiplier / 1000;
5750 Person::players[i]->coords.y += .2;
5751 Person::players[i]->jumppower -= 1;
5754 emit_sound_at(whooshsound, Person::players[i]->coords, 128.);
5756 emit_sound_at(jumpsound, Person::players[i]->coords, 128.);
5758 if ((Person::players[i]->isIdle()) && Person::players[i]->jumppower > 1) {
5759 Person::players[i]->setAnimation(Person::players[i]->getLanding());
5760 Person::players[i]->frameTarget = 2;
5761 Person::players[i]->landhard = 0;
5762 Person::players[i]->jumpstart = 1;
5763 Person::players[i]->tempdeltav = deltav;
5765 if (Person::players[i]->animTarget == jumpupanim &&
5769 Person::players[i]->aitype != playercontrolled)) {
5770 if (Person::players[i]->jumppower > multiplier * 6) {
5771 Person::players[i]->velocity.y += multiplier * 6;
5772 Person::players[i]->jumppower -= multiplier * 6;
5774 if (Person::players[i]->jumppower <= multiplier * 6) {
5775 Person::players[i]->velocity.y += Person::players[i]->jumppower;
5776 Person::players[i]->jumppower = 0;
5779 if (((floatjump || editorenabled) && devtools) && i == 0)
5780 Person::players[i]->velocity.y += multiplier * 30;
5784 if (Person::players[i]->isRun() || Person::players[i]->animTarget == walkanim)
5785 Person::players[i]->setAnimation(Person::players[i]->getStop());
5786 if (Person::players[i]->animTarget == sneakanim) {
5787 Person::players[i]->animTarget = Person::players[i]->getCrouch();
5788 if (Person::players[i]->animCurrent == sneakanim)
5789 Person::players[i]->target = 0;
5790 Person::players[i]->frameTarget = 0;
5793 if (Person::players[i]->animTarget == walkanim &&
5794 (Person::players[i]->aitype == attacktypecutoff ||
5795 Person::players[i]->aitype == searchtype ||
5796 (Person::players[i]->aitype == passivetype &&
5797 Person::players[i]->numwaypoints <= 1)))
5798 Person::players[i]->setAnimation(Person::players[i]->getStop());
5799 if (Person::players[i]->isRun() && (Person::players[i]->aitype == passivetype))
5800 Person::players[i]->setAnimation(Person::players[i]->getStop());
5803 if (Person::players[i]->animTarget == rollanim)
5804 Person::players[i]->targetyaw = oldtargetyaw;
5808 for (unsigned k = 0; k < Person::players.size(); k++) {
5809 if (fabs(Person::players[k]->yaw - Person::players[k]->targetyaw) > 180) {
5810 if (Person::players[k]->yaw > Person::players[k]->targetyaw)
5811 Person::players[k]->yaw -= 360;
5813 Person::players[k]->yaw += 360;
5816 //stop to turn in right direction
5817 if (fabs(Person::players[k]->yaw - Person::players[k]->targetyaw) > 90 && (Person::players[k]->isRun() || Person::players[k]->animTarget == walkanim))
5818 Person::players[k]->setAnimation(Person::players[k]->getStop());
5820 if (Person::players[k]->animTarget == backhandspringanim || Person::players[k]->animTarget == dodgebackanim)
5821 Person::players[k]->targettilt = 0;
5823 if (Person::players[k]->animTarget != jumpupanim &&
5824 Person::players[k]->animTarget != backhandspringanim &&
5825 Person::players[k]->animTarget != jumpdownanim &&
5826 !Person::players[k]->isFlip()) {
5827 Person::players[k]->targettilt = 0;
5828 if (Person::players[k]->jumppower < 0 && !Person::players[k]->jumpkeydown)
5829 Person::players[k]->jumppower = 0;
5830 Person::players[k]->jumppower += multiplier * 7;
5831 if (Person::players[k]->isCrouch())
5832 Person::players[k]->jumppower += multiplier * 7;
5833 if (Person::players[k]->jumppower > 5)
5834 Person::players[k]->jumppower = 5;
5837 if (Person::players[k]->isRun())
5838 Person::players[k]->targettilt = (Person::players[k]->yaw - Person::players[k]->targetyaw) / 4;
5840 Person::players[k]->tilt = stepTowardf(Person::players[k]->tilt, Person::players[k]->targettilt, multiplier * 150);
5841 Person::players[k]->grabdelay -= multiplier;
5845 for (unsigned k = 0; k < Person::players.size(); k++) {
5846 Person::players[k]->DoAnimations();
5847 Person::players[k]->whichpatchx = Person::players[k]->coords.x / (terrain.size / subdivision * terrain.scale);
5848 Person::players[k]->whichpatchz = Person::players[k]->coords.z / (terrain.size / subdivision * terrain.scale);
5854 for (int j = numenvsounds - 1; j >= 0; j--) {
5855 envsoundlife[j] -= multiplier;
5856 if (envsoundlife[j] < 0) {
5858 envsoundlife[j] = envsoundlife[numenvsounds];
5859 envsound[j] = envsound[numenvsounds];
5862 OPENAL_SetFrequency(OPENAL_ALL, slomo);
5864 if (tutoriallevel == 1) {
5881 if (tutorialstage >= 51)
5882 if (distsq(&temp, &Person::players[0]->coords) >= distsq(&temp, &temp2) - 1 || distsq(&temp3, &Person::players[0]->coords) < 4) {
5883 OPENAL_StopSound(OPENAL_ALL); // hack...OpenAL renderer isn't stopping music after tutorial goes to level menu...
5884 OPENAL_SetFrequency(OPENAL_ALL);
5886 emit_stream_np(stream_menutheme);
5895 if (tutorialstage < 51)
5896 if (distsq(&temp, &Person::players[0]->coords) >= distsq(&temp, &temp2) - 1 || distsq(&temp3, &Person::players[0]->coords) < 4) {
5897 emit_sound_at(fireendsound, Person::players[0]->coords);
5899 Person::players[0]->coords = (oldtemp + oldtemp2) / 2;
5903 if (tutorialstage >= 14 && tutorialstage < 50)
5904 if (distsq(&temp, &Person::players[1]->coords) >= distsq(&temp, &temp2) - 1 || distsq(&temp3, &Person::players[1]->coords) < 4) {
5905 emit_sound_at(fireendsound, Person::players[1]->coords);
5907 for (unsigned i = 0; i < Person::players[1]->skeleton.joints.size(); i++) {
5908 if (Random() % 2 == 0) {
5909 if (!Person::players[1]->skeleton.free)
5910 temp2 = (Person::players[1]->coords - Person::players[1]->oldcoords) / multiplier / 2; //velocity/2;
5911 if (Person::players[1]->skeleton.free)
5912 temp2 = Person::players[1]->skeleton.joints[i].velocity * Person::players[1]->scale / 2;
5913 if (!Person::players[1]->skeleton.free)
5914 temp = DoRotation(DoRotation(DoRotation(Person::players[1]->skeleton.joints[i].position, 0, 0, Person::players[1]->tilt), Person::players[1]->tilt2, 0, 0), 0, Person::players[1]->yaw, 0) * Person::players[1]->scale + Person::players[1]->coords;
5915 if (Person::players[1]->skeleton.free)
5916 temp = Person::players[1]->skeleton.joints[i].position * Person::players[1]->scale + Person::players[1]->coords;
5917 Sprite::MakeSprite(breathsprite, temp, temp2, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
5921 Person::players[1]->coords = (oldtemp + oldtemp2) / 2;
5922 for (unsigned i = 0; i < Person::players[1]->skeleton.joints.size(); i++) {
5923 Person::players[1]->skeleton.joints[i].velocity = 0;
5924 if (Random() % 2 == 0) {
5925 if (!Person::players[1]->skeleton.free)
5926 temp2 = (Person::players[1]->coords - Person::players[1]->oldcoords) / multiplier / 2; //velocity/2;
5927 if (Person::players[1]->skeleton.free)
5928 temp2 = Person::players[1]->skeleton.joints[i].velocity * Person::players[1]->scale / 2;
5929 if (!Person::players[1]->skeleton.free)
5930 temp = DoRotation(DoRotation(DoRotation(Person::players[1]->skeleton.joints[i].position, 0, 0, Person::players[1]->tilt), Person::players[1]->tilt2, 0, 0), 0, Person::players[1]->yaw, 0) * Person::players[1]->scale + Person::players[1]->coords;
5931 if (Person::players[1]->skeleton.free)
5932 temp = Person::players[1]->skeleton.joints[i].position * Person::players[1]->scale + Person::players[1]->coords;
5933 Sprite::MakeSprite(breathsprite, temp, temp2, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
5941 static float gLoc[3];
5945 static float vel[3];
5946 vel[0] = (viewer.x - oldviewer.x) / multiplier;
5947 vel[1] = (viewer.y - oldviewer.y) / multiplier;
5948 vel[2] = (viewer.z - oldviewer.z) / multiplier;
5950 //Set orientation with forward and up vectors
5951 static XYZ upvector;
5955 upvector = DoRotation(upvector, -pitch + 90, 0, 0);
5956 upvector = DoRotation(upvector, 0, 0 - yaw, 0);
5961 facing = DoRotation(facing, -pitch, 0, 0);
5962 facing = DoRotation(facing, 0, 0 - yaw, 0);
5965 static float ori[6];
5969 ori[3] = -upvector.x;
5970 ori[4] = upvector.y;
5971 ori[5] = -upvector.z;
5973 OPENAL_3D_Listener_SetAttributes(&gLoc[0], &vel[0], ori[0], ori[1], ori[2], ori[3], ori[4], ori[5]);
5980 if (Input::isKeyPressed(SDL_SCANCODE_F1))
5984 void Game::TickOnce()
5987 yaw += multiplier * 5;
5988 } else if (Dialog::directing || !Dialog::inDialog()) {
5991 pitch -= deltav * .7;
5993 pitch += deltav * .7;
6002 void Game::TickOnceAfter()
6004 static XYZ colviewer;
6005 static XYZ coltarget;
6009 static float changedelay;
6010 static bool alldead;
6011 static float unseendelay;
6012 static float cameraspeed;
6015 static int oldmusictype = musictype;
6017 if (environment == snowyenvironment)
6018 leveltheme = stream_snowtheme;
6019 if (environment == grassyenvironment)
6020 leveltheme = stream_grasstheme;
6021 if (environment == desertenvironment)
6022 leveltheme = stream_deserttheme;
6026 musictype = leveltheme;
6027 for (unsigned i = 0; i < Person::players.size(); i++) {
6028 if ((Person::players[i]->aitype == attacktypecutoff ||
6029 Person::players[i]->aitype == getweapontype ||
6030 Person::players[i]->aitype == gethelptype ||
6031 Person::players[i]->aitype == searchtype) &&
6032 !Person::players[i]->dead/*&&Person::players[i]->surprised<=0*/ &&
6033 (Person::players[i]->animTarget != sneakattackedanim &&
6034 Person::players[i]->animTarget != knifesneakattackedanim &&
6035 Person::players[i]->animTarget != swordsneakattackedanim)) {
6036 musictype = stream_fighttheme;
6040 if (Person::players[0]->dead)
6041 musictype = stream_menutheme;
6044 if (musictype == stream_fighttheme)
6047 if (oldmusictype == stream_fighttheme && musictype != stream_fighttheme) {
6048 unseendelay -= multiplier;
6049 if (unseendelay > 0)
6050 musictype = stream_fighttheme;
6055 musictype = stream_menutheme;
6056 musicvolume[2] = 512;
6063 if (musictype != oldmusictype && musictype == stream_fighttheme)
6064 emit_sound_np(alarmsound);
6065 musicselected = musictype;
6067 if (musicselected == leveltheme)
6068 musicvolume[0] += multiplier * 450;
6070 musicvolume[0] -= multiplier * 450;
6071 if (musicselected == stream_fighttheme)
6072 musicvolume[1] += multiplier * 450;
6074 musicvolume[1] -= multiplier * 450;
6075 if (musicselected == stream_menutheme)
6076 musicvolume[2] += multiplier * 450;
6078 musicvolume[2] -= multiplier * 450;
6080 for (int i = 0; i < 3; i++) {
6081 if (musicvolume[i] < 0)
6083 if (musicvolume[i] > 512)
6084 musicvolume[i] = 512;
6087 if (musicvolume[2] > 128 && !loading && !mainmenu)
6088 musicvolume[2] = 128;
6091 if (musicvolume[0] > 0 && oldmusicvolume[0] <= 0)
6092 emit_stream_np(leveltheme, musicvolume[0]);
6093 if (musicvolume[1] > 0 && oldmusicvolume[1] <= 0)
6094 emit_stream_np(stream_fighttheme, musicvolume[1]);
6095 if (musicvolume[2] > 0 && oldmusicvolume[2] <= 0)
6096 emit_stream_np(stream_menutheme, musicvolume[2]);
6097 if (musicvolume[0] <= 0 && oldmusicvolume[0] > 0)
6098 pause_sound(leveltheme);
6099 if (musicvolume[1] <= 0 && oldmusicvolume[1] > 0)
6100 pause_sound(stream_fighttheme);
6101 if (musicvolume[2] <= 0 && oldmusicvolume[2] > 0)
6102 pause_sound(stream_menutheme);
6104 if (musicvolume[0] != oldmusicvolume[0])
6105 OPENAL_SetVolume(channels[leveltheme], musicvolume[0]);
6106 if (musicvolume[1] != oldmusicvolume[1])
6107 OPENAL_SetVolume(channels[stream_fighttheme], musicvolume[1]);
6108 if (musicvolume[2] != oldmusicvolume[2])
6109 OPENAL_SetVolume(channels[stream_menutheme], musicvolume[2]);
6111 for (int i = 0; i < 3; i++)
6112 oldmusicvolume[i] = musicvolume[i];
6114 pause_sound(leveltheme);
6115 pause_sound(stream_fighttheme);
6116 pause_sound(stream_menutheme);
6118 for (int i = 0; i < 4; i++) {
6119 oldmusicvolume[i] = 0;
6124 Hotspot::killhotspot = 2;
6125 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
6126 if (Hotspot::hotspots[i].type > 10 && Hotspot::hotspots[i].type < 20) {
6127 if (Person::players[Hotspot::hotspots[i].type - 10]->dead == 0)
6128 Hotspot::killhotspot = 0;
6129 else if (Hotspot::killhotspot == 2)
6130 Hotspot::killhotspot = 1;
6133 if (Hotspot::killhotspot == 2)
6134 Hotspot::killhotspot = 0;
6138 for (unsigned i = 0; i < Hotspot::hotspots.size(); i++) {
6139 if (Hotspot::hotspots[i].type == -1) {
6140 if (distsq(&Person::players[0]->coords, &Hotspot::hotspots[i].position) < Hotspot::hotspots[i].size) {
6147 for (unsigned i = 1; i < Person::players.size(); i++) {
6148 if (!Person::players[i]->dead && Person::players[i]->aitype == attacktypecutoff && Person::players[i]->surprised <= 0) {
6152 if (numalarmed > maxalarmed) {
6153 maxalarmed = numalarmed;
6156 if (changedelay <= 0 && !loading && !editorenabled && gameon && !tutoriallevel && changedelay != -999 && !won) {
6157 if (Person::players[0]->dead && changedelay <= 0) {
6159 targetlevel = whichlevel;
6162 for (unsigned i = 1; i < Person::players.size(); i++) {
6163 if (!Person::players[i]->dead && Person::players[i]->howactive < typedead1) {
6170 if (alldead && !Person::players[0]->dead && maptype == mapkilleveryone) {
6172 targetlevel = whichlevel + 1;
6173 if (targetlevel > numchallengelevels - 1)
6176 if (winhotspot || windialogue) {
6178 targetlevel = whichlevel + 1;
6179 if (targetlevel > numchallengelevels - 1)
6184 if (Hotspot::killhotspot) {
6186 targetlevel = whichlevel + 1;
6187 if (targetlevel > numchallengelevels - 1)
6191 if (changedelay > 0 && !Person::players[0]->dead && !won) {
6192 //high scores, awards, win
6194 Account::active().winCampaignLevel(whichchoice, bonustotal, leveltime);
6197 wonleveltime = leveltime;
6198 Account::active().winLevel(whichlevel, bonustotal - startbonustotal, leveltime);
6201 Account::saveFile(Folders::getUserSavePath());
6207 if (leveltime < 1) {
6212 Hotspot::killhotspot = 0;
6215 if (!editorenabled && gameon && !mainmenu) {
6216 if (changedelay != -999)
6217 changedelay -= multiplier / 7;
6218 if (Person::players[0]->dead)
6219 targetlevel = whichlevel;
6220 if (loading == 2 && !campaign) {
6223 fireSound(firestartsound);
6225 if (!Person::players[0]->dead && targetlevel != whichlevel)
6226 startbonustotal = bonustotal;
6227 if (Person::players[0]->dead)
6228 Loadlevel(whichlevel);
6230 Loadlevel(targetlevel);
6236 if (loading == 2 && targetlevel == whichlevel) {
6240 fireSound(firestartsound);
6242 Loadlevel(campaignlevels[Account::active().getCampaignChoicesMade()].mapname.c_str());
6248 if (changedelay <= -999 &&
6251 (Person::players[0]->dead ||
6252 (alldead && maptype == mapkilleveryone) ||
6254 (Hotspot::killhotspot)))
6256 if ((Person::players[0]->dead ||
6257 (alldead && maptype == mapkilleveryone) ||
6260 (Hotspot::killhotspot)) &&
6262 if (whichlevel != -2 && !loading && !Person::players[0]->dead) {
6266 if (Person::players[0]->dead)
6272 // campaignchoosenext determines what to do when the level is complete:
6273 // 0 = load next level
6274 // 1 = go back to level select screen
6275 // 2 = stealthload next level
6276 if (mainmenu == 0 && winfreeze && (campaignlevels[actuallevel].choosenext) == 1) {
6277 if (campaignlevels[actuallevel].nextlevel.empty())
6279 } else if (mainmenu == 0 && winfreeze) {
6280 stealthloading = (campaignlevels[actuallevel].choosenext == 2);
6282 if (!stealthloading) {
6283 fireSound(firestartsound);
6288 startbonustotal = 0;
6298 actuallevel = campaignlevels[actuallevel].nextlevel.front();
6301 Loadlevel(campaignlevels[actuallevel].mapname.c_str());
6305 pause_sound(stream_menutheme);
6316 oldmusictype = musictype;
6322 facing = DoRotation(facing, -pitch, 0, 0);
6323 facing = DoRotation(facing, 0, 0 - yaw, 0);
6324 viewerfacing = facing;
6327 if ((Animation::animations[Person::players[0]->animTarget].attack != 3 && Animation::animations[Person::players[0]->animCurrent].attack != 3) || Person::players[0]->skeleton.free)
6328 target = Person::players[0]->coords + Person::players[0]->currentoffset * (1 - Person::players[0]->target) * Person::players[0]->scale + Person::players[0]->targetoffset * Person::players[0]->target * Person::players[0]->scale - Person::players[0]->facing * .05;
6330 target = Person::players[0]->oldcoords + Person::players[0]->currentoffset * (1 - Person::players[0]->target) * Person::players[0]->scale + Person::players[0]->targetoffset * Person::players[0]->target * Person::players[0]->scale - Person::players[0]->facing * .05;
6332 if (Person::players[0]->skeleton.free) {
6333 for (unsigned i = 0; i < Person::players[0]->skeleton.joints.size(); i++) {
6334 if (Person::players[0]->skeleton.joints[i].position.y * Person::players[0]->scale + Person::players[0]->coords.y > target.y)
6335 target.y = Person::players[0]->skeleton.joints[i].position.y * Person::players[0]->scale + Person::players[0]->coords.y;
6339 if (Person::players[0]->skeleton.free != 2) {
6341 if (findLengthfast(&Person::players[0]->velocity) > 400) {
6342 cameraspeed = 20 + (findLength(&Person::players[0]->velocity) - 20) * .96;
6344 if (Person::players[0]->skeleton.free == 0 && Person::players[0]->animTarget != hanganim && Person::players[0]->animTarget != climbanim)
6346 coltarget = target - cameraloc;
6347 if (findLengthfast(&coltarget) < multiplier * multiplier * 400)
6350 Normalise(&coltarget);
6351 if (Person::players[0]->animTarget != hanganim && Person::players[0]->animTarget != climbanim && Person::players[0]->animCurrent != climbanim && Person::players[0]->currentoffset.x == 0)
6352 cameraloc = cameraloc + coltarget * multiplier * cameraspeed;
6354 cameraloc = cameraloc + coltarget * multiplier * 8;
6358 cameradist += multiplier * 5;
6359 if (cameradist > 2.3)
6361 viewer = cameraloc - facing * cameradist;
6363 coltarget = cameraloc;
6364 Object::SphereCheckPossible(&colviewer, findDistance(&colviewer, &coltarget));
6365 if (terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz])
6366 for (int j = 0; j < terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz]; j++) {
6367 int i = terrain.patchobjects[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz][j];
6369 coltarget = cameraloc;
6370 if (Object::objects[i]->model.LineCheckPossible(&colviewer, &coltarget, &col, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1)
6373 if (terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz])
6374 for (int j = 0; j < terrain.patchobjectnum[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz]; j++) {
6375 int i = terrain.patchobjects[Person::players[0]->whichpatchx][Person::players[0]->whichpatchz][j];
6377 if (Object::objects[i]->model.SphereCheck(&colviewer, .15, &col, &Object::objects[i]->position, &Object::objects[i]->yaw) != -1) {
6381 cameradist = findDistance(&viewer, &target);
6382 viewer.y = max((double)viewer.y, terrain.getHeight(viewer.x, viewer.z) + .6);
6383 if (cameraloc.y < terrain.getHeight(cameraloc.x, cameraloc.z)) {
6384 cameraloc.y = terrain.getHeight(cameraloc.x, cameraloc.z);
6387 if (camerashake > .8)
6389 woozy += multiplier;
6390 if (Person::players[0]->dead)
6392 if (Person::players[0]->dead)
6394 camerashake -= multiplier * 2;
6395 blackout -= multiplier * 2;
6396 if (camerashake < 0)
6401 viewer.x += (float)(Random() % 100) * .0005 * camerashake;
6402 viewer.y += (float)(Random() % 100) * .0005 * camerashake;
6403 viewer.z += (float)(Random() % 100) * .0005 * camerashake;