1 /*-------------------------------------------------------------------------------
2
3 BARONY
4 File: actHandMagic.cpp
5 Desc: the spellcasting animations
6
7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 See LICENSE for details.
9
10 -------------------------------------------------------------------------------*/
11
12 #include "../main.hpp"
13 #include "../game.hpp"
14 #include "../stat.hpp"
15 #include "../entity.hpp"
16 #include "../interface/interface.hpp"
17 #include "../sound.hpp"
18 #include "../items.hpp"
19 #include "../player.hpp"
20 #include "magic.hpp"
21 #include "../net.hpp"
22 #include "../scores.hpp"
23
24 //The spellcasting animation stages:
25 #define CIRCLE 0 //One circle
26 #define THROW 1 //Throw spell!
27
28 spellcasting_animation_manager_t cast_animation;
29 bool overDrawDamageNotify = false;
30 Entity* magicLeftHand = NULL;
31 Entity* magicRightHand = NULL;
32
33 #define HANDMAGIC_INIT my->skill[0]
34 #define HANDMAGIC_TESTVAR my->skill[1]
35 #define HANDMAGIC_PLAYERNUM my->skill[2]
36 #define HANDMAGIC_YAW my->fskill[3]
37 #define HANDMAGIC_PITCH my->fskill[4]
38 #define HANDMAGIC_ROLL my->fskill[5]
39 #define HANDMAGIC_PARTICLESPRAY1 my->skill[3]
40 #define HANDMAGIC_CIRCLE_RADIUS 0.8
41 #define HANDMAGIC_CIRCLE_SPEED 0.3
42
fireOffSpellAnimation(spellcasting_animation_manager_t * animation_manager,Uint32 caster_uid,spell_t * spell,bool usingSpellbook)43 void fireOffSpellAnimation(spellcasting_animation_manager_t* animation_manager, Uint32 caster_uid, spell_t* spell, bool usingSpellbook)
44 {
45 //This function triggers the spellcasting animation and sets up everything.
46
47 if (!animation_manager)
48 {
49 return;
50 }
51 Entity* caster = uidToEntity(caster_uid);
52 if (!caster)
53 {
54 return;
55 }
56 if (!spell)
57 {
58 return;
59 }
60 if (!magicLeftHand)
61 {
62 return;
63 }
64 if (!magicRightHand)
65 {
66 return;
67 }
68
69 playSoundEntity(caster, 170, 128 );
70 Stat* stat = caster->getStats();
71
72 //Save these two very important pieces of data.
73 animation_manager->caster = caster->getUID();
74 animation_manager->spell = spell;
75
76 if ( !usingSpellbook )
77 {
78 animation_manager->active = true;
79 }
80 else
81 {
82 animation_manager->active_spellbook = true;
83 }
84 animation_manager->stage = CIRCLE;
85
86 //Make the HUDWEAPON disappear, or somesuch?
87 if ( stat->type != RAT )
88 {
89 if ( !usingSpellbook )
90 {
91 magicLeftHand->flags[INVISIBLE] = false;
92 }
93 magicRightHand->flags[INVISIBLE] = false;
94 }
95
96 animation_manager->lefthand_angle = 0;
97 animation_manager->lefthand_movex = 0;
98 animation_manager->lefthand_movey = 0;
99 int spellCost = getCostOfSpell(spell, caster);
100 animation_manager->circle_count = 0;
101 animation_manager->times_to_circle = (spellCost / 10) + 1; //Circle once for every 10 mana the spell costs.
102 animation_manager->mana_left = spellCost;
103 animation_manager->consumeMana = true;
104 if ( spell->ID == SPELL_FORCEBOLT && caster->skillCapstoneUnlockedEntity(PRO_SPELLCASTING) )
105 {
106 animation_manager->consumeMana = false;
107 }
108
109 if (stat->PROFICIENCIES[PRO_SPELLCASTING] < SPELLCASTING_BEGINNER) //There's a chance that caster is newer to magic (and thus takes longer to cast a spell).
110 {
111 int chance = rand() % 10;
112 if (chance >= stat->PROFICIENCIES[PRO_SPELLCASTING] / 15)
113 {
114 int amount = (rand() % 50) / std::max(stat->PROFICIENCIES[PRO_SPELLCASTING] + statGetINT(stat, caster), 1);
115 amount = std::min(amount, CASTING_EXTRA_TIMES_CAP);
116 animation_manager->times_to_circle += amount;
117 }
118 }
119 if ( usingSpellbook && stat->shield && itemCategory(stat->shield) == SPELLBOOK )
120 {
121 if ( !playerLearnedSpellbook(stat->shield) || (stat->shield->beatitude < 0 && !shouldInvertEquipmentBeatitude(stat)) )
122 {
123 // for every tier below the spell you are, add 3 circle for 1 tier, or add 2 for every additional tier.
124 int casterAbility = std::min(100, std::max(0, stat->PROFICIENCIES[PRO_SPELLCASTING] + statGetINT(stat, caster))) / 20;
125 if ( stat->shield->beatitude < 0 )
126 {
127 casterAbility = 0; // cursed book has cast penalty.
128 }
129 int difficulty = spell->difficulty / 20;
130 if ( difficulty > casterAbility )
131 {
132 animation_manager->times_to_circle += (std::min(5, 1 + 2 * (difficulty - casterAbility)));
133 }
134 }
135 else if ( stat->PROFICIENCIES[PRO_SPELLCASTING] >= SPELLCASTING_BEGINNER )
136 {
137 animation_manager->times_to_circle = (spellCost / 20) + 1; //Circle once for every 20 mana the spell costs.
138 }
139 }
140 animation_manager->consume_interval = (animation_manager->times_to_circle * ((2 * PI) / HANDMAGIC_CIRCLE_SPEED)) / spellCost;
141 animation_manager->consume_timer = animation_manager->consume_interval;
142 }
143
spellcastingAnimationManager_deactivate(spellcasting_animation_manager_t * animation_manager)144 void spellcastingAnimationManager_deactivate(spellcasting_animation_manager_t* animation_manager)
145 {
146 animation_manager->caster = -1;
147 animation_manager->spell = NULL;
148 animation_manager->active = false;
149 animation_manager->active_spellbook = false;
150 animation_manager->stage = 0;
151
152 //Make the hands invisible (should probably fall away or something, but whatever. That's another project for another day)
153 if ( magicLeftHand )
154 {
155 magicLeftHand->flags[INVISIBLE] = true;
156 }
157 if ( magicRightHand )
158 {
159 magicRightHand->flags[INVISIBLE] = true;
160 }
161 }
162
spellcastingAnimationManager_completeSpell(spellcasting_animation_manager_t * animation_manager)163 void spellcastingAnimationManager_completeSpell(spellcasting_animation_manager_t* animation_manager)
164 {
165 castSpell(animation_manager->caster, animation_manager->spell, false, false, animation_manager->active_spellbook); //Actually cast the spell.
166
167 spellcastingAnimationManager_deactivate(animation_manager);
168 }
169
170 /*
171 [12:48:29 PM] Sheridan Kane Rathbun: you can move the entities about by modifying their x, y, z, yaw, pitch, and roll parameters.
172 [12:48:43 PM] Sheridan Kane Rathbun: everything's relative to the camera since the OVERDRAW flag is on.
173 [12:49:05 PM] Sheridan Kane Rathbun: so adding x will move it forward, adding y will move it sideways (forget which way) and adding z will move it up and down.
174 [12:49:46 PM] Sheridan Kane Rathbun: the first step is to get the hands visible on the screen when you cast. worry about moving them when that critical part is done.
175 */
176
actLeftHandMagic(Entity * my)177 void actLeftHandMagic(Entity* my)
178 {
179 //int c = 0;
180 if (intro == true)
181 {
182 my->flags[INVISIBLE] = true;
183 return;
184 }
185
186 //Initialize
187 if (!HANDMAGIC_INIT)
188 {
189 HANDMAGIC_INIT = 1;
190 HANDMAGIC_TESTVAR = 0;
191 my->focalz = -1.5;
192 }
193
194 if (players[clientnum] == nullptr || players[clientnum]->entity == nullptr
195 || (players[clientnum]->entity && players[clientnum]->entity->playerCreatedDeathCam != 0) )
196 {
197 magicLeftHand = nullptr;
198 spellcastingAnimationManager_deactivate(&cast_animation);
199 list_RemoveNode(my->mynode);
200 return;
201 }
202
203 //Set the initial values. (For the particle spray)
204 my->x = 8;
205 my->y = -3;
206 my->z = (cameras[HANDMAGIC_PLAYERNUM].z * .5 - players[clientnum]->entity->z) + 7;
207 my->z -= 4;
208 my->yaw = HANDMAGIC_YAW - cameravars[HANDMAGIC_PLAYERNUM].shakex2;
209 double defaultpitch = (0 - 2.2);
210 my->pitch = defaultpitch + HANDMAGIC_PITCH - cameravars[HANDMAGIC_PLAYERNUM].shakey2 / 200.f;
211 my->roll = HANDMAGIC_ROLL;
212 my->scalex = 0.5f;
213 my->scaley = 0.5f;
214 my->scalez = 0.5f;
215 my->z -= 0.75;
216
217 //Sprite
218 Monster playerRace = players[clientnum]->entity->getMonsterFromPlayerRace(stats[clientnum]->playerRace);
219 int playerAppearance = stats[clientnum]->appearance;
220 if ( players[clientnum]->entity->effectShapeshift != NOTHING )
221 {
222 playerRace = static_cast<Monster>(players[clientnum]->entity->effectShapeshift);
223 }
224 else if ( players[clientnum]->entity->effectPolymorph != NOTHING )
225 {
226 if ( players[clientnum]->entity->effectPolymorph > NUMMONSTERS )
227 {
228 playerRace = HUMAN;
229 playerAppearance = players[clientnum]->entity->effectPolymorph - 100;
230 }
231 else
232 {
233 playerRace = static_cast<Monster>(players[clientnum]->entity->effectPolymorph);
234 }
235 }
236
237 bool noGloves = false;
238 if ( stats[clientnum]->gloves == NULL
239 || playerRace == SPIDER
240 || playerRace == RAT
241 || playerRace == CREATURE_IMP
242 || playerRace == TROLL )
243 {
244 noGloves = true;
245 }
246 else
247 {
248 if ( stats[clientnum]->gloves->type == GLOVES || stats[clientnum]->gloves->type == GLOVES_DEXTERITY )
249 {
250 my->sprite = 659;
251 }
252 else if ( stats[clientnum]->gloves->type == BRACERS || stats[clientnum]->gloves->type == BRACERS_CONSTITUTION )
253 {
254 my->sprite = 660;
255 }
256 else if ( stats[clientnum]->gloves->type == GAUNTLETS || stats[clientnum]->gloves->type == GAUNTLETS_STRENGTH )
257 {
258 my->sprite = 661;
259 }
260 else if ( stats[clientnum]->gloves->type == BRASS_KNUCKLES )
261 {
262 my->sprite = 662;
263 }
264 else if ( stats[clientnum]->gloves->type == IRON_KNUCKLES )
265 {
266 my->sprite = 663;
267 }
268 else if ( stats[clientnum]->gloves->type == SPIKED_GAUNTLETS )
269 {
270 my->sprite = 664;
271 }
272 else if ( stats[clientnum]->gloves->type == CRYSTAL_GLOVES )
273 {
274 my->sprite = 666;
275 }
276 else if ( stats[clientnum]->gloves->type == ARTIFACT_GLOVES )
277 {
278 my->sprite = 665;
279 }
280 else if ( stats[clientnum]->gloves->type == SUEDE_GLOVES )
281 {
282 my->sprite = 803;
283 }
284 }
285
286
287 if ( noGloves )
288 {
289
290 switch ( playerRace )
291 {
292 case SKELETON:
293 my->sprite = 773;
294 break;
295 case INCUBUS:
296 my->sprite = 775;
297 break;
298 case SUCCUBUS:
299 my->sprite = 777;
300 break;
301 case GOBLIN:
302 my->sprite = 779;
303 break;
304 case AUTOMATON:
305 my->sprite = 781;
306 break;
307 case INSECTOID:
308 if ( stats[clientnum]->sex == FEMALE )
309 {
310 my->sprite = 785;
311 }
312 else
313 {
314 my->sprite = 783;
315 }
316 break;
317 case GOATMAN:
318 my->sprite = 787;
319 break;
320 case VAMPIRE:
321 my->sprite = 789;
322 break;
323 case HUMAN:
324 if ( playerAppearance / 6 == 0 )
325 {
326 my->sprite = 656;
327 }
328 else if ( playerAppearance / 6 == 1 )
329 {
330 my->sprite = 657;
331 }
332 else
333 {
334 my->sprite = 658;
335 }
336 break;
337 case TROLL:
338 my->sprite = 856;
339 break;
340 case SPIDER:
341 my->sprite = 854;
342 break;
343 case CREATURE_IMP:
344 my->sprite = 858;
345 break;
346 default:
347 my->sprite = 656;
348 break;
349 }
350 /*}
351 else if ( playerAppearance / 6 == 0 )
352 {
353 my->sprite = 656;
354 }
355 else if ( playerAppearance / 6 == 1 )
356 {
357 my->sprite = 657;
358 }
359 else
360 {
361 my->sprite = 658;
362 }*/
363 }
364
365 if ( playerRace == RAT )
366 {
367 my->flags[INVISIBLE] = true;
368 my->y = 0;
369 my->z += 1;
370 }
371 if ( playerRace == SPIDER && hudarm && players[clientnum]->entity->bodyparts.at(0) )
372 {
373 my->x = hudarm->x;
374 my->y = -hudarm->y;
375 //my->z = hudArm->z;
376 my->pitch = hudarm->pitch;
377 my->roll = -hudarm->roll;
378 my->yaw = -players[clientnum]->entity->bodyparts.at(0)->yaw;
379 my->scalex = hudarm->scalex;
380 my->scaley = hudarm->scaley;
381 my->scalez = hudarm->scalez;
382 my->focalz = hudarm->focalz;
383 }
384 else
385 {
386 my->focalz = -1.5;
387 }
388
389 bool wearingring = false;
390
391 //Select model
392 if (stats[clientnum]->ring != NULL)
393 {
394 if (stats[clientnum]->ring->type == RING_INVISIBILITY)
395 {
396 wearingring = true;
397 }
398 }
399 if (stats[clientnum]->cloak != NULL)
400 {
401 if (stats[clientnum]->cloak->type == CLOAK_INVISIBILITY)
402 {
403 wearingring = true;
404 }
405 }
406 if (players[clientnum]->entity->skill[3] == 1 || players[clientnum]->entity->isInvisible() ) // debug cam or player invisible
407 {
408 my->flags[INVISIBLE] = true;
409 }
410
411 if ( (cast_animation.active || cast_animation.active_spellbook) )
412 {
413 switch (cast_animation.stage)
414 {
415 case CIRCLE:
416 if ( ticks % 5 == 0 && !(players[clientnum]->entity->skill[3] == 1) )
417 {
418 Entity* entity = spawnGib(my);
419 entity->flags[INVISIBLE] = false;
420 entity->flags[SPRITE] = true;
421 entity->flags[NOUPDATE] = true;
422 entity->flags[UPDATENEEDED] = false;
423 entity->flags[OVERDRAW] = true;
424 entity->flags[BRIGHT] = true;
425 entity->scalex = 0.25f; //MAKE 'EM SMALL PLEASE!
426 entity->scaley = 0.25f;
427 entity->scalez = 0.25f;
428 entity->sprite = 16; //TODO: Originally. 22. 16 -- spark sprite instead?
429 if ( cast_animation.active_spellbook )
430 {
431 entity->y -= 1.5;
432 entity->z += 1;
433 }
434 entity->yaw = ((rand() % 6) * 60) * PI / 180.0;
435 entity->pitch = (rand() % 360) * PI / 180.0;
436 entity->roll = (rand() % 360) * PI / 180.0;
437 entity->vel_x = cos(entity->yaw) * .1;
438 entity->vel_y = sin(entity->yaw) * .1;
439 entity->vel_z = -.15;
440 entity->fskill[3] = 0.01;
441 }
442 cast_animation.consume_timer--;
443 if ( cast_animation.consume_timer < 0 && cast_animation.mana_left > 0 )
444 {
445 //Time to consume mana and reset the ticker!
446 cast_animation.consume_timer = cast_animation.consume_interval;
447 if ( multiplayer == SINGLE && cast_animation.consumeMana )
448 {
449 int HP = stats[clientnum]->HP;
450 players[clientnum]->entity->drainMP(1, false); // don't notify otherwise we'll get spammed each 1 mp
451 if ( (HP > stats[clientnum]->HP) && !overDrawDamageNotify )
452 {
453 overDrawDamageNotify = true;
454 cameravars[HANDMAGIC_PLAYERNUM].shakex += 0.1;
455 cameravars[HANDMAGIC_PLAYERNUM].shakey += 10;
456 playSoundPlayer(clientnum, 28, 92);
457 Uint32 color = SDL_MapRGB(mainsurface->format, 255, 255, 0);
458 messagePlayerColor(clientnum, color, language[621]);
459 }
460 }
461 --cast_animation.mana_left;
462 }
463
464 cast_animation.lefthand_angle += HANDMAGIC_CIRCLE_SPEED;
465 cast_animation.lefthand_movex = cos(cast_animation.lefthand_angle) * HANDMAGIC_CIRCLE_RADIUS;
466 cast_animation.lefthand_movey = sin(cast_animation.lefthand_angle) * HANDMAGIC_CIRCLE_RADIUS;
467 if (cast_animation.lefthand_angle >= 2 * PI) //Completed one loop.
468 {
469 cast_animation.lefthand_angle = 0;
470 cast_animation.circle_count++;
471 if (cast_animation.circle_count >= cast_animation.times_to_circle)
472 //Finished circling. Time to move on!
473 {
474 cast_animation.stage++;
475 }
476 }
477 break;
478 case THROW:
479 //messagePlayer(clientnum, "IN THROW");
480 //TODO: Throw animation! Or something.
481 cast_animation.stage++;
482 break;
483 default:
484 //messagePlayer(clientnum, "DEFAULT CASE");
485 spellcastingAnimationManager_completeSpell(&cast_animation);
486 break;
487 }
488 }
489 else
490 {
491 overDrawDamageNotify = false;
492 }
493
494 //Final position code.
495 if (players[clientnum] == nullptr || players[clientnum]->entity == nullptr)
496 {
497 return;
498 }
499 //double defaultpitch = PI / 8.f;
500 //double defaultpitch = 0;
501 //double defaultpitch = PI / (0-4.f);
502 //defaultpitch = (0 - 2.8);
503 //my->x = 6 + HUDWEAPON_MOVEX;
504
505 if ( playerRace == SPIDER && hudarm && players[clientnum]->entity->bodyparts.at(0) )
506 {
507 my->x = hudarm->x;
508 my->y = -hudarm->y;
509 my->z = hudarm->z;
510 my->pitch = hudarm->pitch;
511 my->roll = -hudarm->roll;
512 my->yaw = -players[clientnum]->entity->bodyparts.at(0)->yaw;
513 my->scalex = hudarm->scalex;
514 my->scaley = hudarm->scaley;
515 my->scalez = hudarm->scalez;
516 my->focalz = hudarm->focalz;
517 }
518 else
519 {
520 my->y = -3;
521 my->z = (cameras[HANDMAGIC_PLAYERNUM].z * .5 - players[clientnum]->entity->z) + 7;
522 my->z -= 4;
523 my->yaw = HANDMAGIC_YAW - cameravars[HANDMAGIC_PLAYERNUM].shakex2;
524 my->pitch = defaultpitch + HANDMAGIC_PITCH - cameravars[HANDMAGIC_PLAYERNUM].shakey2 / 200.f;
525 my->roll = HANDMAGIC_ROLL;
526 my->focalz = -1.5;
527 }
528
529 //my->y = 3 + HUDWEAPON_MOVEY;
530 //my->z = (camera.z*.5-players[clientnum]->z)+7+HUDWEAPON_MOVEZ; //TODO: NOT a PLAYERSWAP
531 my->x += cast_animation.lefthand_movex;
532 my->y += cast_animation.lefthand_movey;
533 }
534
actRightHandMagic(Entity * my)535 void actRightHandMagic(Entity* my)
536 {
537 if (intro == true)
538 {
539 my->flags[INVISIBLE] = true;
540 return;
541 }
542
543 //Initialize
544 if ( !HANDMAGIC_INIT )
545 {
546 HANDMAGIC_INIT = 1;
547 my->focalz = -1.5;
548 }
549
550 if (players[clientnum] == nullptr || players[clientnum]->entity == nullptr
551 || (players[clientnum]->entity && players[clientnum]->entity->playerCreatedDeathCam != 0) )
552 {
553 magicRightHand = nullptr;
554 list_RemoveNode(my->mynode);
555 return;
556 }
557
558 my->x = 8;
559 my->y = 3;
560 my->z = (cameras[HANDMAGIC_PLAYERNUM].z * .5 - players[clientnum]->entity->z) + 7;
561 my->z -= 4;
562 my->yaw = HANDMAGIC_YAW - cameravars[HANDMAGIC_PLAYERNUM].shakex2;
563 double defaultpitch = (0 - 2.2);
564 my->pitch = defaultpitch + HANDMAGIC_PITCH - cameravars[HANDMAGIC_PLAYERNUM].shakey2 / 200.f;
565 my->roll = HANDMAGIC_ROLL;
566 my->scalex = 0.5f;
567 my->scaley = 0.5f;
568 my->scalez = 0.5f;
569 my->z -= 0.75;
570
571 //Sprite
572 Monster playerRace = players[clientnum]->entity->getMonsterFromPlayerRace(stats[clientnum]->playerRace);
573 int playerAppearance = stats[clientnum]->appearance;
574 if ( players[clientnum]->entity->effectShapeshift != NOTHING )
575 {
576 playerRace = static_cast<Monster>(players[clientnum]->entity->effectShapeshift);
577 }
578 else if ( players[clientnum]->entity->effectPolymorph != NOTHING )
579 {
580 if ( players[clientnum]->entity->effectPolymorph > NUMMONSTERS )
581 {
582 playerRace = HUMAN;
583 playerAppearance = players[clientnum]->entity->effectPolymorph - 100;
584 }
585 else
586 {
587 playerRace = static_cast<Monster>(players[clientnum]->entity->effectPolymorph);
588 }
589 }
590
591 bool noGloves = false;
592 if ( stats[clientnum]->gloves == NULL
593 || playerRace == SPIDER
594 || playerRace == RAT
595 || playerRace == CREATURE_IMP
596 || playerRace == TROLL )
597 {
598 noGloves = true;
599 }
600 else
601 {
602 if ( stats[clientnum]->gloves->type == GLOVES || stats[clientnum]->gloves->type == GLOVES_DEXTERITY )
603 {
604 my->sprite = 637;
605 }
606 else if ( stats[clientnum]->gloves->type == BRACERS || stats[clientnum]->gloves->type == BRACERS_CONSTITUTION )
607 {
608 my->sprite = 638;
609 }
610 else if ( stats[clientnum]->gloves->type == GAUNTLETS || stats[clientnum]->gloves->type == GAUNTLETS_STRENGTH )
611 {
612 my->sprite = 639;
613 }
614 else if ( stats[clientnum]->gloves->type == BRASS_KNUCKLES )
615 {
616 my->sprite = 640;
617 }
618 else if ( stats[clientnum]->gloves->type == IRON_KNUCKLES )
619 {
620 my->sprite = 641;
621 }
622 else if ( stats[clientnum]->gloves->type == SPIKED_GAUNTLETS )
623 {
624 my->sprite = 642;
625 }
626 else if ( stats[clientnum]->gloves->type == CRYSTAL_GLOVES )
627 {
628 my->sprite = 591;
629 }
630 else if ( stats[clientnum]->gloves->type == ARTIFACT_GLOVES )
631 {
632 my->sprite = 590;
633 }
634 else if ( stats[clientnum]->gloves->type == SUEDE_GLOVES )
635 {
636 my->sprite = 802;
637 }
638 }
639
640 if ( noGloves )
641 {
642 switch ( playerRace )
643 {
644 case SKELETON:
645 my->sprite = 774;
646 break;
647 case INCUBUS:
648 my->sprite = 776;
649 break;
650 case SUCCUBUS:
651 my->sprite = 778;
652 break;
653 case GOBLIN:
654 my->sprite = 780;
655 break;
656 case AUTOMATON:
657 my->sprite = 782;
658 break;
659 case INSECTOID:
660 if ( stats[clientnum]->sex == FEMALE )
661 {
662 my->sprite = 786;
663 }
664 else
665 {
666 my->sprite = 784;
667 }
668 break;
669 case GOATMAN:
670 my->sprite = 788;
671 break;
672 case VAMPIRE:
673 my->sprite = 790;
674 break;
675 case HUMAN:
676 if ( playerAppearance / 6 == 0 )
677 {
678 my->sprite = 634;
679 }
680 else if ( playerAppearance / 6 == 1 )
681 {
682 my->sprite = 635;
683 }
684 else
685 {
686 my->sprite = 636;
687 }
688 break;
689 case TROLL:
690 my->sprite = 855;
691 break;
692 case SPIDER:
693 my->sprite = 853;
694 break;
695 case CREATURE_IMP:
696 my->sprite = 857;
697 break;
698 default:
699 my->sprite = 634;
700 break;
701 }
702 /*else if ( playerAppearance / 6 == 0 )
703 {
704 my->sprite = 634;
705 }
706 else if ( playerAppearance / 6 == 1 )
707 {
708 my->sprite = 635;
709 }
710 else
711 {
712 my->sprite = 636;
713 }*/
714 }
715
716 if ( playerRace == RAT )
717 {
718 my->flags[INVISIBLE] = true;
719 my->y = 0;
720 my->z += 1;
721 }
722 if ( playerRace == SPIDER && hudarm && players[clientnum]->entity->bodyparts.at(0) )
723 {
724 my->x = hudarm->x;
725 my->y = hudarm->y;
726 //my->z = hudArm->z;
727 my->pitch = hudarm->pitch;
728 my->roll = hudarm->roll;
729 my->yaw = players[clientnum]->entity->bodyparts.at(0)->yaw;
730 my->scalex = hudarm->scalex;
731 my->scaley = hudarm->scaley;
732 my->scalez = hudarm->scalez;
733 my->focalz = hudarm->focalz;
734 }
735 else
736 {
737 my->focalz = -1.5;
738 }
739
740 bool wearingring = false;
741
742 //Select model
743 if (stats[clientnum]->ring != NULL)
744 {
745 if (stats[clientnum]->ring->type == RING_INVISIBILITY)
746 {
747 wearingring = true;
748 }
749 }
750 if (stats[clientnum]->cloak != NULL)
751 {
752 if (stats[clientnum]->cloak->type == CLOAK_INVISIBILITY)
753 {
754 wearingring = true;
755 }
756 }
757 if ( players[clientnum]->entity->skill[3] == 1 || players[clientnum]->entity->isInvisible() ) // debug cam or player invisible
758 {
759 my->flags[INVISIBLE] = true;
760 }
761
762 if ( (cast_animation.active || cast_animation.active_spellbook) )
763 {
764 switch (cast_animation.stage)
765 {
766 case CIRCLE:
767 if ( ticks % 5 == 0 && !(players[clientnum]->entity->skill[3] == 1) )
768 {
769 //messagePlayer(0, "Pingas!");
770 Entity* entity = spawnGib(my);
771 entity->flags[INVISIBLE] = false;
772 entity->flags[SPRITE] = true;
773 entity->flags[NOUPDATE] = true;
774 entity->flags[UPDATENEEDED] = false;
775 entity->flags[OVERDRAW] = true;
776 entity->flags[BRIGHT] = true;
777 //entity->sizex = 1; //MAKE 'EM SMALL PLEASE!
778 //entity->sizey = 1;
779 entity->scalex = 0.25f; //MAKE 'EM SMALL PLEASE!
780 entity->scaley = 0.25f;
781 entity->scalez = 0.25f;
782 entity->sprite = 16; //TODO: Originally. 22. 16 -- spark sprite instead?
783 entity->yaw = ((rand() % 6) * 60) * PI / 180.0;
784 entity->pitch = (rand() % 360) * PI / 180.0;
785 entity->roll = (rand() % 360) * PI / 180.0;
786 entity->vel_x = cos(entity->yaw) * .1;
787 entity->vel_y = sin(entity->yaw) * .1;
788 entity->vel_z = -.15;
789 entity->fskill[3] = 0.01;
790 }
791 break;
792 case THROW:
793 break;
794 default:
795 break;
796 }
797 }
798
799 //Final position code.
800 if (players[clientnum] == nullptr || players[clientnum]->entity == nullptr)
801 {
802 return;
803 }
804
805 if ( playerRace == SPIDER && hudarm && players[clientnum]->entity->bodyparts.at(0) )
806 {
807 my->x = hudarm->x;
808 my->y = hudarm->y;
809 my->z = hudarm->z;
810 my->pitch = hudarm->pitch;
811 my->roll = hudarm->roll;
812 my->yaw = players[clientnum]->entity->bodyparts.at(0)->yaw;
813 my->scalex = hudarm->scalex;
814 my->scaley = hudarm->scaley;
815 my->scalez = hudarm->scalez;
816 my->focalz = hudarm->focalz;
817 }
818 else
819 {
820 my->x = 8;
821 my->y = 3;
822 my->z = (cameras[HANDMAGIC_PLAYERNUM].z * .5 - players[clientnum]->entity->z) + 7;
823 my->z -= 4;
824 my->yaw = HANDMAGIC_YAW - cameravars[HANDMAGIC_PLAYERNUM].shakex2;
825 my->pitch = defaultpitch + HANDMAGIC_PITCH - cameravars[HANDMAGIC_PLAYERNUM].shakey2 / 200.f;
826 my->roll = HANDMAGIC_ROLL;
827 my->focalz = -1.5;
828 }
829
830 my->x += cast_animation.lefthand_movex;
831 my->y -= cast_animation.lefthand_movey;
832 }
833