+void doTutorial()
+{
+ if (tutorialstagetime > tutorialmaxtime) {
+ tutorialstage++;
+ tutorialsuccess = 0;
+ if (tutorialstage <= 1) {
+ canattack = 0;
+ cananger = 0;
+ reversaltrain = 0;
+ }
+ switch (tutorialstage) {
+ case 1:
+ tutorialmaxtime = 5;
+ break;
+ case 2:
+ tutorialmaxtime = 2;
+ break;
+ case 3:
+ tutorialmaxtime = 600;
+ break;
+ case 4:
+ tutorialmaxtime = 1000;
+ break;
+ case 5:
+ tutorialmaxtime = 600;
+ break;
+ case 6:
+ tutorialmaxtime = 600;
+ break;
+ case 7:
+ tutorialmaxtime = 600;
+ break;
+ case 8:
+ tutorialmaxtime = 600;
+ break;
+ case 9:
+ tutorialmaxtime = 600;
+ break;
+ case 10:
+ tutorialmaxtime = 2;
+ break;
+ case 11:
+ tutorialmaxtime = 1000;
+ break;
+ case 12:
+ tutorialmaxtime = 1000;
+ break;
+ case 13:
+ tutorialmaxtime = 2;
+ break;
+ case 14: {
+ tutorialmaxtime = 3;
+
+ XYZ temp, temp2;
+
+ temp.x = 1011;
+ temp.y = 84;
+ temp.z = 491;
+ temp2.x = 1025;
+ temp2.y = 75;
+ temp2.z = 447;
+
+ player[1].coords = (temp + temp2) / 2;
+
+ emit_sound_at(fireendsound, player[1].coords);
+
+ for (int i = 0; i < player[1].skeleton.num_joints; i++) {
+ if (Random() % 2 == 0) {
+ if (!player[1].skeleton.free)
+ temp2 = (player[1].coords - player[1].oldcoords) / multiplier / 2; //velocity/2;
+ if (player[1].skeleton.free)
+ temp2 = player[1].skeleton.joints[i].velocity * player[1].scale / 2;
+ if (!player[1].skeleton.free)
+ temp = DoRotation(DoRotation(DoRotation(player[1].skeleton.joints[i].position, 0, 0, player[1].tilt), player[1].tilt2, 0, 0), 0, player[1].yaw, 0) * player[1].scale + player[1].coords;
+ if (player[1].skeleton.free)
+ temp = player[1].skeleton.joints[i].position * player[1].scale + player[1].coords;
+ Sprite::MakeSprite(breathsprite, temp, temp2, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
+ }
+ }
+ }
+ break;
+ case 15:
+ tutorialmaxtime = 500;
+ break;
+ case 16:
+ tutorialmaxtime = 500;
+ break;
+ case 17:
+ tutorialmaxtime = 500;
+ break;
+ case 18:
+ tutorialmaxtime = 500;
+ break;
+ case 19:
+ tutorialstage = 20;
+ //tutorialmaxtime=500;
+ break;
+ case 20:
+ tutorialmaxtime = 500;
+ break;
+ case 21:
+ tutorialmaxtime = 500;
+ if (bonus == cannon) {
+ bonus = Slicebonus;
+ againbonus = 1;
+ } else
+ againbonus = 0;
+ break;
+ case 22:
+ tutorialmaxtime = 500;
+ break;
+ case 23:
+ tutorialmaxtime = 500;
+ break;
+ case 24:
+ tutorialmaxtime = 500;
+ break;
+ case 25:
+ tutorialmaxtime = 500;
+ break;
+ case 26:
+ tutorialmaxtime = 2;
+ break;
+ case 27:
+ tutorialmaxtime = 4;
+ reversaltrain = 1;
+ cananger = 1;
+ player[1].aitype = attacktypecutoff;
+ break;
+ case 28:
+ tutorialmaxtime = 400;
+ break;
+ case 29:
+ tutorialmaxtime = 400;
+ player[0].escapednum = 0;
+ break;
+ case 30:
+ tutorialmaxtime = 4;
+ reversaltrain = 0;
+ cananger = 0;
+ player[1].aitype = passivetype;
+ break;
+ case 31:
+ tutorialmaxtime = 13;
+ break;
+ case 32:
+ tutorialmaxtime = 8;
+ break;
+ case 33:
+ tutorialmaxtime = 400;
+ cananger = 1;
+ canattack = 1;
+ player[1].aitype = attacktypecutoff;
+ break;
+ case 34:
+ tutorialmaxtime = 400;
+ break;
+ case 35:
+ tutorialmaxtime = 400;
+ break;
+ case 36:
+ tutorialmaxtime = 2;
+ reversaltrain = 0;
+ cananger = 0;
+ player[1].aitype = passivetype;
+ break;
+ case 37:
+ damagedealt = 0;
+ damagetaken = 0;
+ tutorialmaxtime = 50;
+ cananger = 1;
+ canattack = 1;
+ player[1].aitype = attacktypecutoff;
+ break;
+ case 38:
+ tutorialmaxtime = 4;
+ canattack = 0;
+ cananger = 0;
+ player[1].aitype = passivetype;
+ break;
+ case 39: {
+ XYZ temp, temp2;
+
+ temp.x = 1011;
+ temp.y = 84;
+ temp.z = 491;
+ temp2.x = 1025;
+ temp2.y = 75;
+ temp2.z = 447;
+
+ Weapon w(knife, -1);
+ w.position = (temp + temp2) / 2;
+ w.tippoint = (temp + temp2) / 2;
+
+ w.velocity = 0.1;
+ w.tipvelocity = 0.1;
+ w.missed = 1;
+ w.hitsomething = 0;
+ w.freetime = 0;
+ w.firstfree = 1;
+ w.physics = 1;
+
+ weapons.push_back(w);
+ }
+ break;
+ case 40:
+ tutorialmaxtime = 300;
+ break;
+ case 41:
+ tutorialmaxtime = 300;
+ break;
+ case 42:
+ tutorialmaxtime = 8;
+ break;
+ case 43:
+ tutorialmaxtime = 300;
+ break;
+ case 44:
+ weapons[0].owner = 1;
+ player[0].weaponactive = -1;
+ player[0].num_weapons = 0;
+ player[1].weaponactive = 0;
+ player[1].num_weapons = 1;
+ player[1].weaponids[0] = 0;
+
+ cananger = 1;
+ canattack = 1;
+ player[1].aitype = attacktypecutoff;
+
+ tutorialmaxtime = 300;
+ break;
+ case 45:
+ weapons[0].owner = 1;
+ player[0].weaponactive = -1;
+ player[0].num_weapons = 0;
+ player[1].weaponactive = 0;
+ player[1].num_weapons = 1;
+ player[1].weaponids[0] = 0;
+
+ tutorialmaxtime = 300;
+ break;
+ case 46:
+ weapons[0].owner = 1;
+ player[0].weaponactive = -1;
+ player[0].num_weapons = 0;
+ player[1].weaponactive = 0;
+ player[1].num_weapons = 1;
+ player[1].weaponids[0] = 0;
+
+ weapons[0].setType(sword);
+
+ tutorialmaxtime = 300;
+ break;
+ case 47: {
+ tutorialmaxtime = 10;
+
+ XYZ temp, temp2;
+
+ temp.x = 1011;
+ temp.y = 84;
+ temp.z = 491;
+ temp2.x = 1025;
+ temp2.y = 75;
+ temp2.z = 447;
+
+ Weapon w(sword, -1);
+ w.position = (temp + temp2) / 2;
+ w.tippoint = (temp + temp2) / 2;
+
+ w.velocity = 0.1;
+ w.tipvelocity = 0.1;
+ w.missed = 1;
+ w.hitsomething = 0;
+ w.freetime = 0;
+ w.firstfree = 1;
+ w.physics = 1;
+
+ weapons.push_back(w);
+
+ weapons[0].owner = 1;
+ weapons[1].owner = 0;
+ player[0].weaponactive = 0;
+ player[0].num_weapons = 1;
+ player[0].weaponids[0] = 1;
+ player[1].weaponactive = 0;
+ player[1].num_weapons = 1;
+ player[1].weaponids[0] = 0;
+
+ }
+ break;
+ case 48:
+ canattack = 0;
+ cananger = 0;
+ player[1].aitype = passivetype;
+
+ tutorialmaxtime = 15;
+
+ weapons[0].owner = 1;
+ weapons[1].owner = 0;
+ player[0].weaponactive = 0;
+ player[0].num_weapons = 1;
+ player[0].weaponids[0] = 1;
+ player[1].weaponactive = 0;
+ player[1].num_weapons = 1;
+ player[1].weaponids[0] = 0;
+
+ if (player[0].weaponactive != -1)
+ weapons[player[0].weaponids[player[0].weaponactive]].setType(staff);
+ else
+ weapons[0].setType(staff);
+ break;
+ case 49:
+ canattack = 0;
+ cananger = 0;
+ player[1].aitype = passivetype;
+
+ tutorialmaxtime = 200;
+
+ weapons[1].position = 1000;
+ weapons[1].tippoint = 1000;
+
+ weapons[0].setType(knife);
+
+ weapons[0].owner = 0;
+ player[1].weaponactive = -1;
+ player[1].num_weapons = 0;
+ player[0].weaponactive = 0;
+ player[0].num_weapons = 1;
+ player[0].weaponids[0] = 0;
+
+ break;
+ case 50: {
+ tutorialmaxtime = 8;
+
+ XYZ temp, temp2;
+ emit_sound_at(fireendsound, player[1].coords);
+
+ for (int i = 0; i < player[1].skeleton.num_joints; i++) {
+ if (Random() % 2 == 0) {
+ if (!player[1].skeleton.free)
+ temp2 = (player[1].coords - player[1].oldcoords) / multiplier / 2; //velocity/2;
+ if (player[1].skeleton.free)
+ temp2 = player[1].skeleton.joints[i].velocity * player[1].scale / 2;
+ if (!player[1].skeleton.free)
+ temp = DoRotation(DoRotation(DoRotation(player[1].skeleton.joints[i].position, 0, 0, player[1].tilt), player[1].tilt2, 0, 0), 0, player[1].yaw, 0) * player[1].scale + player[1].coords;
+ if (player[1].skeleton.free)
+ temp = player[1].skeleton.joints[i].position * player[1].scale + player[1].coords;
+ Sprite::MakeSprite(breathsprite, temp, temp2, 1, 1, 1, .6 + (float)abs(Random() % 100) / 200 - .25, 1);
+ }
+ }
+
+ player[1].num_weapons = 0;
+ player[1].weaponstuck = -1;
+ player[1].weaponactive = -1;
+
+ weapons.clear();
+ }
+ break;
+ case 51:
+ tutorialmaxtime = 80000;
+ break;
+ default:
+ break;
+ }
+ if (tutorialstage <= 51)
+ tutorialstagetime = 0;
+ }
+
+ //Tutorial success
+ if (tutorialstagetime < tutorialmaxtime - 3) {
+ switch (tutorialstage) {
+ case 3:
+ if (deltah || deltav)
+ tutorialsuccess += multiplier;
+ break;
+ case 4:
+ if (player[0].forwardkeydown || player[0].backkeydown || player[0].leftkeydown || player[0].rightkeydown)
+ tutorialsuccess += multiplier;
+ break;
+ case 5:
+ if (player[0].jumpkeydown)
+ tutorialsuccess = 1;
+ break;
+ case 6:
+ if (player[0].isCrouch())
+ tutorialsuccess = 1;
+ break;
+ case 7:
+ if (player[0].animTarget == rollanim)
+ tutorialsuccess = 1;
+ break;
+ case 8:
+ if (player[0].animTarget == sneakanim)
+ tutorialsuccess += multiplier;
+ break;
+ case 9:
+ if (player[0].animTarget == rabbitrunninganim || player[0].animTarget == wolfrunninganim)
+ tutorialsuccess += multiplier;
+ break;
+ case 11:
+ if (player[0].isWallJump())
+ tutorialsuccess = 1;
+ break;
+ case 12:
+ if (player[0].animTarget == flipanim)
+ tutorialsuccess = 1;
+ break;
+ case 15:
+ if (player[0].animTarget == upunchanim || player[0].animTarget == winduppunchanim)
+ tutorialsuccess = 1;
+ break;
+ case 16:
+ if (player[0].animTarget == winduppunchanim)
+ tutorialsuccess = 1;
+ break;
+ case 17:
+ if (player[0].animTarget == spinkickanim)
+ tutorialsuccess = 1;
+ break;
+ case 18:
+ if (player[0].animTarget == sweepanim)
+ tutorialsuccess = 1;
+ break;
+ case 19:
+ if (player[0].animTarget == dropkickanim)
+ tutorialsuccess = 1;
+ break;
+ case 20:
+ if (player[0].animTarget == rabbitkickanim)
+ tutorialsuccess = 1;
+ break;
+ case 21:
+ if (bonus == cannon)
+ tutorialsuccess = 1;
+ break;
+ case 22:
+ if (bonus == spinecrusher)
+ tutorialsuccess = 1;
+ break;
+ case 23:
+ if (player[0].animTarget == walljumprightkickanim || player[0].animTarget == walljumpleftkickanim)
+ tutorialsuccess = 1;
+ break;
+ case 24:
+ if (player[0].animTarget == rabbittacklinganim)
+ tutorialsuccess = 1;
+ break;
+ case 25:
+ if (player[0].animTarget == backhandspringanim)
+ tutorialsuccess = 1;
+ break;
+ case 28:
+ if (animation[player[0].animTarget].attack == reversed && player[0].feint)
+ tutorialsuccess = 1;
+ break;
+ case 29:
+ if (player[0].escapednum == 2) {
+ tutorialsuccess = 1;
+ reversaltrain = 0;
+ cananger = 0;
+ player[1].aitype = passivetype;
+ }
+ break;
+ case 33:
+ if (animation[player[0].animTarget].attack == reversal)
+ tutorialsuccess = 1;
+ break;
+ case 34:
+ if (animation[player[0].animTarget].attack == reversal)
+ tutorialsuccess = 1;
+ break;
+ case 35:
+ if (animation[player[0].animTarget].attack == reversal) {
+ tutorialsuccess = 1;
+ reversaltrain = 0;
+ cananger = 0;
+ player[1].aitype = passivetype;
+ }
+ break;
+ case 40:
+ if (player[0].num_weapons > 0)
+ tutorialsuccess = 1;
+ break;
+ case 41:
+ if (player[0].weaponactive == -1 && player[0].num_weapons > 0)
+ tutorialsuccess = 1;
+ break;
+ case 43:
+ if (player[0].animTarget == knifeslashstartanim)
+ tutorialsuccess = 1;
+ break;
+ case 44:
+ if (animation[player[0].animTarget].attack == reversal)
+ tutorialsuccess = 1;
+ break;
+ case 45:
+ if (animation[player[0].animTarget].attack == reversal)
+ tutorialsuccess = 1;
+ break;
+ case 46:
+ if (animation[player[0].animTarget].attack == reversal)
+ tutorialsuccess = 1;
+ break;
+ case 49:
+ if (player[1].weaponstuck != -1)
+ tutorialsuccess = 1;
+ break;
+ default:
+ break;
+ }
+ if (tutorialsuccess >= 1)
+ tutorialstagetime = tutorialmaxtime - 3;
+
+
+ if (tutorialstagetime == tutorialmaxtime - 3) {
+ emit_sound_np(consolesuccesssound);
+ }
+
+ if (tutorialsuccess >= 1) {
+ if (tutorialstage == 34 || tutorialstage == 35)
+ tutorialstagetime = tutorialmaxtime - 1;
+ }
+ }
+
+ if (tutorialstage < 14 || tutorialstage >= 50) {
+ player[1].coords.y = 300;
+ player[1].velocity = 0;
+ }
+}
+
+void doDebugKeys()
+{
+ float headprop, bodyprop, armprop, legprop;
+ if (debugmode) {
+ if (Input::isKeyPressed(SDLK_h)) {
+ player[0].damagetolerance = 200000;
+ player[0].damage = 0;
+ player[0].burnt = 0;
+ player[0].permanentdamage = 0;
+ player[0].superpermanentdamage = 0;
+ }
+
+ if (Input::isKeyPressed(SDLK_j)) {
+ environment++;
+ if (environment > 2)
+ environment = 0;
+ Setenvironment(environment);
+ }
+
+ if (Input::isKeyPressed(SDLK_c)) {
+ cameramode = 1 - cameramode;
+ }
+
+ if (Input::isKeyPressed(SDLK_x) && !Input::isKeyDown(SDLK_LSHIFT)) {
+ if (player[0].num_weapons > 0) {
+ if (weapons[player[0].weaponids[0]].getType() == sword)
+ weapons[player[0].weaponids[0]].setType(staff);
+ else if (weapons[player[0].weaponids[0]].getType() == staff)
+ weapons[player[0].weaponids[0]].setType(knife);
+ else
+ weapons[player[0].weaponids[0]].setType(sword);
+ }
+ }
+
+ if (Input::isKeyPressed(SDLK_x) && Input::isKeyDown(SDLK_LSHIFT)) {
+ int closest = findClosestPlayer();
+ if (closest >= 0) {
+ if (player[closest].num_weapons) {
+ if (weapons[player[closest].weaponids[0]].getType() == sword)
+ weapons[player[closest].weaponids[0]].setType(staff);
+ else if (weapons[player[closest].weaponids[0]].getType() == staff)
+ weapons[player[closest].weaponids[0]].setType(knife);
+ else
+ weapons[player[closest].weaponids[0]].setType(sword);
+ }
+ if (!player[closest].num_weapons) {
+ player[closest].weaponids[0] = weapons.size();
+
+ weapons.push_back(Weapon(knife, closest));
+
+ player[closest].num_weapons = 1;
+ }
+ }
+ }
+
+ if (Input::isKeyDown(SDLK_u)) {
+ int closest = findClosestPlayer();
+ if (closest >= 0) {
+ player[closest].yaw += multiplier * 50;
+ player[closest].targetyaw = player[closest].yaw;
+ }
+ }
+
+
+ if (Input::isKeyPressed(SDLK_o) && !Input::isKeyDown(SDLK_LSHIFT)) {
+ int closest = findClosestPlayer();
+ if (Input::isKeyDown(SDLK_LCTRL))
+ closest = 0;
+
+ if (closest >= 0) {
+ player[closest].whichskin++;
+ if (player[closest].whichskin > 9)
+ player[closest].whichskin = 0;
+ if (player[closest].whichskin > 2 && player[closest].creature == wolftype)
+ player[closest].whichskin = 0;
+
+ player[closest].skeleton.drawmodel.textureptr.load(creatureskin[player[closest].creature][player[closest].whichskin], 1,
+ &player[closest].skeleton.skinText[0], &player[closest].skeleton.skinsize);
+ }
+
+ if (player[closest].numclothes) {
+ for (int i = 0; i < player[closest].numclothes; i++) {
+ tintr = player[closest].clothestintr[i];
+ tintg = player[closest].clothestintg[i];
+ tintb = player[closest].clothestintb[i];
+ AddClothes((char *)player[closest].clothes[i], &player[closest].skeleton.skinText[0]);
+ }
+ player[closest].DoMipmaps();
+ }
+ }
+
+ if (Input::isKeyPressed(SDLK_o) && Input::isKeyDown(SDLK_LSHIFT)) {
+ int closest = findClosestPlayer();
+ if (closest >= 0) {
+ if (player[closest].creature == wolftype) {
+ headprop = player[closest].proportionhead.x / 1.1;
+ bodyprop = player[closest].proportionbody.x / 1.1;
+ armprop = player[closest].proportionarms.x / 1.1;
+ legprop = player[closest].proportionlegs.x / 1.1;
+ }
+
+ if (player[closest].creature == rabbittype) {
+ headprop = player[closest].proportionhead.x / 1.2;
+ bodyprop = player[closest].proportionbody.x / 1.05;
+ armprop = player[closest].proportionarms.x / 1.00;
+ legprop = player[closest].proportionlegs.x / 1.1;
+ }
+
+
+ if (player[closest].creature == rabbittype) {
+ player[closest].skeleton.id = closest;
+ player[closest].skeleton.Load((char *)":Data:Skeleton:Basic Figure Wolf", (char *)":Data:Skeleton:Basic Figure Wolf Low", (char *)":Data:Skeleton:Rabbitbelt", (char *)":Data:Models:Wolf.solid", (char *)":Data:Models:Wolf2.solid", (char *)":Data:Models:Wolf3.solid", (char *)":Data:Models:Wolf4.solid", (char *)":Data:Models:Wolf5.solid", (char *)":Data:Models:Wolf6.solid", (char *)":Data:Models:Wolf7.solid", (char *)":Data:Models:Wolflow.solid", (char *)":Data:Models:Belt.solid", 0);
+ player[closest].skeleton.drawmodel.textureptr.load(":Data:Textures:Wolf.jpg", 1, &player[closest].skeleton.skinText[closest], &player[closest].skeleton.skinsize);
+ player[closest].whichskin = 0;
+ player[closest].creature = wolftype;
+
+ player[closest].proportionhead = 1.1;
+ player[closest].proportionbody = 1.1;
+ player[closest].proportionarms = 1.1;
+ player[closest].proportionlegs = 1.1;
+ player[closest].proportionlegs.y = 1.1;
+ player[closest].scale = .23 * 5 * player[0].scale;
+
+ player[closest].damagetolerance = 300;
+ } else {
+ player[closest].skeleton.id = closest;
+ player[closest].skeleton.Load((char *)":Data:Skeleton:Basic Figure", (char *)":Data:Skeleton:Basic Figurelow", (char *)":Data:Skeleton:Rabbitbelt", (char *)":Data:Models:Body.solid", (char *)":Data:Models:Body2.solid", (char *)":Data:Models:Body3.solid", (char *)":Data:Models:Body4.solid", (char *)":Data:Models:Body5.solid", (char *)":Data:Models:Body6.solid", (char *)":Data:Models:Body7.solid", (char *)":Data:Models:Bodylow.solid", (char *)":Data:Models:Belt.solid", 1);
+ player[closest].skeleton.drawmodel.textureptr.load(":Data:Textures:Fur3.jpg", 1, &player[closest].skeleton.skinText[0], &player[closest].skeleton.skinsize);
+ player[closest].whichskin = 0;
+ player[closest].creature = rabbittype;
+
+ player[closest].proportionhead = 1.2;
+ player[closest].proportionbody = 1.05;
+ player[closest].proportionarms = 1.00;
+ player[closest].proportionlegs = 1.1;
+ player[closest].proportionlegs.y = 1.05;
+ player[closest].scale = .2 * 5 * player[0].scale;
+
+ player[closest].damagetolerance = 200;
+ }
+
+ if (player[closest].creature == wolftype) {
+ player[closest].proportionhead = 1.1 * headprop;
+ player[closest].proportionbody = 1.1 * bodyprop;
+ player[closest].proportionarms = 1.1 * armprop;
+ player[closest].proportionlegs = 1.1 * legprop;
+ }
+
+ if (player[closest].creature == rabbittype) {
+ player[closest].proportionhead = 1.2 * headprop;
+ player[closest].proportionbody = 1.05 * bodyprop;
+ player[closest].proportionarms = 1.00 * armprop;
+ player[closest].proportionlegs = 1.1 * legprop;
+ player[closest].proportionlegs.y = 1.05 * legprop;
+ }
+
+ }
+ }
+
+ if (Input::isKeyPressed(SDLK_b) && !Input::isKeyDown(SDLK_LSHIFT)) {
+ slomo = 1 - slomo;
+ slomodelay = 1000;
+ }
+
+
+ if (((Input::isKeyPressed(SDLK_i) && !Input::isKeyDown(SDLK_LSHIFT)))) {
+ int closest = -1;
+ float closestdist = std::numeric_limits<float>::max();
+
+ for (int i = 1; i < numplayers; i++) {
+ float distance = distsq(&player[i].coords, &player[0].coords);
+ if (!player[i].headless)
+ if (distance < closestdist) {
+ closestdist = distance;
+ closest = i;
+ }
+ }
+
+ XYZ flatfacing2, flatvelocity2;
+ XYZ blah;
+ if (closest != -1 && distsq(&player[closest].coords, &player[0].coords) < 144) {