1 /*-------------------------------------------------------------------------------
2
3 BARONY
4 File: stat.cpp
5 Desc: functions for the Stat struct
6
7 Copyright 2013-2016 (c) Turning Wheel LLC, all rights reserved.
8 See LICENSE for details.
9
10 -------------------------------------------------------------------------------*/
11
12
13 #include "main.hpp"
14 #include "game.hpp"
15 #include "stat.hpp"
16 #include "entity.hpp"
17 #include "items.hpp"
18 #include "magic/magic.hpp"
19 #include "net.hpp"
20
21 Stat* stats[MAXPLAYERS];
22
23
24 //Destructor
~Stat()25 Stat::~Stat()
26 {
27 if (this->helmet != NULL)
28 {
29 if (this->helmet->node == NULL)
30 {
31 free(this->helmet);
32 }
33 else
34 {
35 list_RemoveNode(this->helmet->node);
36 }
37 this->helmet = NULL;
38 }
39 if (this->breastplate != NULL)
40 {
41 if (this->breastplate->node == NULL)
42 {
43 free(this->breastplate);
44 }
45 else
46 {
47 list_RemoveNode(this->breastplate->node);
48 }
49 this->breastplate = NULL;
50 }
51 if (this->gloves != NULL)
52 {
53 if (this->gloves->node == NULL)
54 {
55 free(this->gloves);
56 }
57 else
58 {
59 list_RemoveNode(this->gloves->node);
60 }
61 this->gloves = NULL;
62 }
63 if (this->shoes != NULL)
64 {
65 if (this->shoes->node == NULL)
66 {
67 free(this->shoes);
68 }
69 else
70 {
71 list_RemoveNode(this->shoes->node);
72 }
73 this->shoes = NULL;
74 }
75 if (this->shield != NULL)
76 {
77 if (this->shield->node == NULL)
78 {
79 free(this->shield);
80 }
81 else
82 {
83 list_RemoveNode(this->shield->node);
84 }
85 this->shield = NULL;
86 }
87 if (this->weapon != NULL)
88 {
89 if (this->weapon->node == NULL)
90 {
91 free(this->weapon);
92 }
93 else
94 {
95 list_RemoveNode(this->weapon->node);
96 }
97 this->weapon = NULL;
98 }
99 if (this->cloak != NULL)
100 {
101 if (this->cloak->node == NULL)
102 {
103 free(this->cloak);
104 }
105 else
106 {
107 list_RemoveNode(this->cloak->node);
108 }
109 this->cloak = NULL;
110 }
111 if (this->amulet != NULL)
112 {
113 if (this->amulet->node == NULL)
114 {
115 free(this->amulet);
116 }
117 else
118 {
119 list_RemoveNode(this->amulet->node);
120 }
121 this->amulet = NULL;
122 }
123 if (this->ring != NULL)
124 {
125 if (this->ring->node == NULL)
126 {
127 free(this->ring);
128 }
129 else
130 {
131 list_RemoveNode(this->ring->node);
132 }
133 this->ring = NULL;
134 }
135 if (this->mask != NULL)
136 {
137 if (this->mask->node == NULL)
138 {
139 free(this->mask);
140 }
141 else
142 {
143 list_RemoveNode(this->mask->node);
144 }
145 this->mask = NULL;
146 }
147 //Free memory for magic effects.
148 node_t* spellnode;
149 spellnode = this->magic_effects.first;
150 while (spellnode)
151 {
152 node_t* oldnode = spellnode;
153 spellnode = spellnode->next;
154 spell_t* spell = (spell_t*)oldnode->element;
155 spell->magic_effects_node = NULL;
156 }
157 list_FreeAll(&this->magic_effects);
158 list_FreeAll(&this->inventory);
159 }
160
clearStats()161 void Stat::clearStats()
162 {
163 int x;
164
165 strcpy(this->obituary, language[1500]);
166 this->poisonKiller = 0;
167 this->HP = DEFAULT_HP;
168 this->MAXHP = DEFAULT_HP;
169 this->OLDHP = this->HP;
170 this->MP = DEFAULT_MP;
171 this->MAXMP = DEFAULT_MP;
172 this->STR = 0;
173 this->DEX = 0;
174 this->CON = 0;
175 this->INT = 0;
176 this->PER = 0;
177 this->CHR = 0;
178 this->GOLD = 0;
179 this->HUNGER = 1000;
180 this->LVL = 1;
181 this->EXP = 0;
182 list_FreeAll(&this->FOLLOWERS);
183 for (x = 0; x < std::max(NUMPROFICIENCIES, NUMEFFECTS); x++)
184 {
185 if (x < NUMPROFICIENCIES)
186 {
187 this->PROFICIENCIES[x] = 0;
188 }
189 if (x < NUMEFFECTS)
190 {
191 this->EFFECTS[x] = false;
192 this->EFFECTS_TIMERS[x] = 0;
193 }
194 }
195
196 for ( x = 0; x < ITEM_SLOT_NUM; x = x + ITEM_SLOT_NUMPROPERTIES )
197 {
198 this->EDITOR_ITEMS[x] = 0;
199 this->EDITOR_ITEMS[x + 1] = 0;
200 this->EDITOR_ITEMS[x + 2] = 10;
201 this->EDITOR_ITEMS[x + 3] = 1;
202 this->EDITOR_ITEMS[x + 4] = 1;
203 this->EDITOR_ITEMS[x + 5] = 1;
204 this->EDITOR_ITEMS[x + 6] = 0;
205 }
206
207 for ( x = 0; x < 32; x++ )
208 {
209 if ( x != 4 ) // MISC_FLAGS[4] is playerRace, don't reset, same as ->sex
210 {
211 this->MISC_FLAGS[x] = 0;
212 }
213 }
214
215 for ( x = 0; x < NUMSTATS; x++ )
216 {
217 this->PLAYER_LVL_STAT_BONUS[x] = -1;
218 }
219
220 for ( x = 0; x < NUMSTATS * 2; x++ )
221 {
222 this->PLAYER_LVL_STAT_TIMER[x] = -1;
223 }
224
225 list_FreeAll(&this->inventory);
226 this->helmet = NULL;
227 this->breastplate = NULL;
228 this->gloves = NULL;
229 this->shoes = NULL;
230 this->shield = NULL;
231 this->weapon = NULL;
232 this->cloak = NULL;
233 this->amulet = NULL;
234 this->ring = NULL;
235 this->mask = NULL;
236 }
237
238 /*-------------------------------------------------------------------------------
239
240 freePlayerEquipment
241
242 frees all the malloc'd data for the given player's equipment
243
244 -------------------------------------------------------------------------------*/
245
freePlayerEquipment()246 void Stat::freePlayerEquipment()
247 {
248 if (this->helmet != NULL)
249 {
250 if (this->helmet->node)
251 {
252 list_RemoveNode(this->helmet->node);
253 }
254 else
255 {
256 free(this->helmet);
257 }
258 this->helmet = NULL;
259 }
260 if (this->breastplate != NULL)
261 {
262 if (this->breastplate->node)
263 {
264 list_RemoveNode(this->breastplate->node);
265 }
266 else
267 {
268 free(this->breastplate);
269 }
270 this->breastplate = NULL;
271 }
272 if (this->gloves != NULL)
273 {
274 if (this->gloves->node)
275 {
276 list_RemoveNode(this->gloves->node);
277 }
278 else
279 {
280 free(this->gloves);
281 }
282 this->gloves = NULL;
283 }
284 if (this->shoes != NULL)
285 {
286 if (this->shoes->node)
287 {
288 list_RemoveNode(this->shoes->node);
289 }
290 else
291 {
292 free(this->shoes);
293 }
294 this->shoes = NULL;
295 }
296 if (this->shield != NULL)
297 {
298 if (this->shield->node)
299 {
300 list_RemoveNode(this->shield->node);
301 }
302 else
303 {
304 free(this->shield);
305 }
306 this->shield = NULL;
307 }
308 if (this->weapon != NULL)
309 {
310 if (this->weapon->node)
311 {
312 list_RemoveNode(this->weapon->node);
313 }
314 else
315 {
316 free(this->weapon);
317 }
318 this->weapon = NULL;
319 }
320 if (this->cloak != NULL)
321 {
322 if (this->cloak->node)
323 {
324 list_RemoveNode(this->cloak->node);
325 }
326 else
327 {
328 free(this->cloak);
329 }
330 this->cloak = NULL;
331 }
332 if (this->amulet != NULL)
333 {
334 if (this->amulet->node)
335 {
336 list_RemoveNode(this->amulet->node);
337 }
338 else
339 {
340 free(this->amulet);
341 }
342 this->amulet = NULL;
343 }
344 if (this->ring != NULL)
345 {
346 if (this->ring->node)
347 {
348 list_RemoveNode(this->ring->node);
349 }
350 else
351 {
352 free(this->ring);
353 }
354 this->ring = NULL;
355 }
356 if (this->mask != NULL)
357 {
358 if (this->mask->node)
359 {
360 list_RemoveNode(this->mask->node);
361 }
362 else
363 {
364 free(this->mask);
365 }
366 this->mask = NULL;
367 }
368 }
369
370
371 /*-------------------------------------------------------------------------------
372
373 copyStats
374
375 Returns a pointer to a new instance of the Stats class
376
377 -------------------------------------------------------------------------------*/
378
copyStats()379 Stat* Stat::copyStats()
380 {
381 node_t* node;
382 int c;
383
384 // create new stat, using the type (HUMAN, SKELETON) as a reference.
385 // this is handled in stat_shared.cpp by adding 1000 to the type.
386 Stat* newStat = new Stat(this->type + 1000);
387
388 newStat->type = this->type;
389 newStat->sex = this->sex;
390 newStat->appearance = this->appearance;
391 strcpy(newStat->name, this->name);
392 strcpy(newStat->obituary, this->obituary);
393
394 newStat->HP = this->HP;
395 newStat->MAXHP = this->MAXHP;
396 newStat->OLDHP = this->OLDHP;
397
398 newStat->MP = this->MP;
399 newStat->MAXMP = this->MAXMP;
400 newStat->STR = this->STR;
401 newStat->DEX = this->DEX;
402 newStat->CON = this->CON;
403 newStat->INT = this->INT;
404 newStat->PER = this->PER;
405 newStat->CHR = this->CHR;
406 newStat->EXP = this->EXP;
407 newStat->LVL = this->LVL;
408 newStat->GOLD = this->GOLD;
409 newStat->HUNGER = this->HUNGER;
410
411 for (c = 0; c < NUMPROFICIENCIES; c++)
412 {
413 newStat->PROFICIENCIES[c] = this->PROFICIENCIES[c];
414 }
415 for (c = 0; c < NUMEFFECTS; c++)
416 {
417 newStat->EFFECTS[c] = this->EFFECTS[c];
418 newStat->EFFECTS_TIMERS[c] = this->EFFECTS_TIMERS[c];
419 }
420
421 for ( c = 0; c < ITEM_SLOT_NUM; c++ )
422 {
423 newStat->EDITOR_ITEMS[c] = this->EDITOR_ITEMS[c];
424 }
425
426 for ( c = 0; c < 32; c++ )
427 {
428 newStat->MISC_FLAGS[c] = this->MISC_FLAGS[c];
429 }
430
431 for ( c = 0; c < NUMSTATS; c++ )
432 {
433 newStat->PLAYER_LVL_STAT_BONUS[c] = this->PLAYER_LVL_STAT_BONUS[c];
434 }
435
436 for ( c = 0; c < NUMSTATS * 2; c++ )
437 {
438 newStat->PLAYER_LVL_STAT_TIMER[c] = this->PLAYER_LVL_STAT_TIMER[c];
439 }
440
441 newStat->defending = this->defending;
442 newStat->leader_uid = this->leader_uid;
443 newStat->FOLLOWERS.first = NULL;
444 newStat->FOLLOWERS.last = NULL;
445 list_Copy(&newStat->FOLLOWERS, &this->FOLLOWERS);
446 newStat->stache_x1 = this->stache_x1;
447 newStat->stache_x2 = this->stache_x2;
448 newStat->stache_y1 = this->stache_y1;
449 newStat->stache_y2 = this->stache_y2;
450
451 newStat->inventory.first = NULL;
452 newStat->inventory.last = NULL;
453 list_Copy(&newStat->inventory, &this->inventory);
454 for (node = newStat->inventory.first; node != NULL; node = node->next)
455 {
456 Item* item = (Item*)node->element;
457 item->node = node;
458 }
459
460 if (this->helmet)
461 {
462 if (this->helmet->node)
463 {
464 node_t* node = list_Node(&newStat->inventory, list_Index(this->helmet->node));
465 newStat->helmet = (Item*)node->element;
466 }
467 else
468 {
469 newStat->helmet = (Item*)malloc(sizeof(Item));
470 memcpy(newStat->helmet, this->helmet, sizeof(Item));
471 }
472 }
473 else
474 {
475 newStat->helmet = NULL;
476 }
477 if (this->breastplate)
478 {
479 if (this->breastplate->node)
480 {
481 node_t* node = list_Node(&newStat->inventory, list_Index(this->breastplate->node));
482 newStat->breastplate = (Item*)node->element;
483 }
484 else
485 {
486 newStat->breastplate = (Item*)malloc(sizeof(Item));
487 memcpy(newStat->breastplate, this->breastplate, sizeof(Item));
488 }
489 }
490 else
491 {
492 newStat->breastplate = NULL;
493 }
494 if (this->gloves)
495 {
496 if (this->gloves->node)
497 {
498 node_t* node = list_Node(&newStat->inventory, list_Index(this->gloves->node));
499 newStat->gloves = (Item*)node->element;
500 }
501 else
502 {
503 newStat->gloves = (Item*)malloc(sizeof(Item));
504 memcpy(newStat->gloves, this->gloves, sizeof(Item));
505 }
506 }
507 else
508 {
509 newStat->gloves = NULL;
510 }
511 if (this->shoes)
512 {
513 if (this->shoes->node)
514 {
515 node_t* node = list_Node(&newStat->inventory, list_Index(this->shoes->node));
516 newStat->shoes = (Item*)node->element;
517 }
518 else
519 {
520 newStat->shoes = (Item*)malloc(sizeof(Item));
521 memcpy(newStat->shoes, this->shoes, sizeof(Item));
522 }
523 }
524 else
525 {
526 newStat->shoes = NULL;
527 }
528 if (this->shield)
529 {
530 if (this->shield->node)
531 {
532 node_t* node = list_Node(&newStat->inventory, list_Index(this->shield->node));
533 newStat->shield = (Item*)node->element;
534 }
535 else
536 {
537 newStat->shield = (Item*)malloc(sizeof(Item));
538 memcpy(newStat->shield, this->shield, sizeof(Item));
539 }
540 }
541 else
542 {
543 newStat->shield = NULL;
544 }
545 if (this->weapon)
546 {
547 if (this->weapon->node)
548 {
549 node_t* node = list_Node(&newStat->inventory, list_Index(this->weapon->node));
550 newStat->weapon = (Item*)node->element;
551 }
552 else
553 {
554 newStat->weapon = (Item*)malloc(sizeof(Item));
555 memcpy(newStat->weapon, this->weapon, sizeof(Item));
556 }
557 }
558 else
559 {
560 newStat->weapon = NULL;
561 }
562 if (this->cloak)
563 {
564 if (this->cloak->node)
565 {
566 node_t* node = list_Node(&newStat->inventory, list_Index(this->cloak->node));
567 newStat->cloak = (Item*)node->element;
568 }
569 else
570 {
571 newStat->cloak = (Item*)malloc(sizeof(Item));
572 memcpy(newStat->cloak, this->cloak, sizeof(Item));
573 }
574 }
575 else
576 {
577 newStat->cloak = NULL;
578 }
579 if (this->amulet)
580 {
581 if (this->amulet->node)
582 {
583 node_t* node = list_Node(&newStat->inventory, list_Index(this->amulet->node));
584 newStat->amulet = (Item*)node->element;
585 }
586 else
587 {
588 newStat->amulet = (Item*)malloc(sizeof(Item));
589 memcpy(newStat->amulet, this->amulet, sizeof(Item));
590 }
591 }
592 else
593 {
594 newStat->amulet = NULL;
595 }
596 if (this->ring)
597 {
598 if (this->ring->node)
599 {
600 node_t* node = list_Node(&newStat->inventory, list_Index(this->ring->node));
601 newStat->ring = (Item*)node->element;
602 }
603 else
604 {
605 newStat->ring = (Item*)malloc(sizeof(Item));
606 memcpy(newStat->ring, this->ring, sizeof(Item));
607 }
608 }
609 else
610 {
611 newStat->ring = NULL;
612 }
613 if (this->mask)
614 {
615 if (this->mask->node)
616 {
617 node_t* node = list_Node(&newStat->inventory, list_Index(this->mask->node));
618 newStat->mask = (Item*)node->element;
619 }
620 else
621 {
622 newStat->mask = (Item*)malloc(sizeof(Item));
623 memcpy(newStat->mask, this->mask, sizeof(Item));
624 }
625 }
626 else
627 {
628 newStat->mask = NULL;
629 }
630
631 #if defined(USE_FMOD) || defined(USE_OPENAL)
632 newStat->monster_sound = NULL;
633 #endif
634 newStat->monster_idlevar = this->monster_idlevar;
635 newStat->magic_effects.first = NULL;
636 newStat->magic_effects.last = NULL;
637
638 return newStat;
639 }
640
printStats()641 void Stat::printStats()
642 {
643 printlog("type = %d\n", this->type);
644 printlog("sex = %d\n", this->sex);
645 printlog("appearance = %d\n", this->appearance);
646 printlog("name = \"%s\"\n", this->name);
647 printlog("HP = %d\n", this->HP);
648 printlog("MAXHP = %d\n", this->MAXHP);
649 printlog("MP = %d\n", this->MP);
650 printlog("MAXMP = %d\n", this->MAXMP);
651 printlog("STR = %d\n", this->STR);
652 printlog("DEX = %d\n", this->DEX);
653 printlog("CON = %d\n", this->CON);
654 printlog("INT = %d\n", this->INT);
655 printlog("PER = %d\n", this->PER);
656 printlog("CHR = %d\n", this->CHR);
657 printlog("EXP = %d\n", this->EXP);
658 printlog("LVL = %d\n", this->LVL);
659 printlog("GOLD = %d\n", this->GOLD);
660 printlog("HUNGER = %d\n", this->HUNGER);
661
662 printlog("Proficiencies:");
663 for (int i = 0; i < NUMPROFICIENCIES; ++i)
664 {
665 printlog("[%d] = %d%s", i, this->PROFICIENCIES[i], ((i == NUMPROFICIENCIES - 1) ? "\n" : ", "));
666 }
667
668 printlog("Effects & timers: ");
669 for (int i = 0; i < NUMEFFECTS; ++i)
670 {
671 printlog("[%d] = %s. timer[%d] = %d", i, (this->EFFECTS[i]) ? "true" : "false", i, this->EFFECTS_TIMERS[i]);
672 }
673 }
674
675
pickRandomEquippedItem(Item ** returnItem,bool excludeWeapon,bool excludeShield,bool excludeArmor,bool excludeJewelry)676 int Stat::pickRandomEquippedItem(Item** returnItem, bool excludeWeapon, bool excludeShield, bool excludeArmor, bool excludeJewelry)
677 {
678 int numEquippedItems = 0;
679 int equipNum[10] = { 0 };// index of equipment piece to update the client, defined in net.cpp "ARMR"
680 for ( int i = 0; i < 10; ++i )
681 {
682 equipNum[i] = -1;
683 }
684
685 if ( !excludeArmor )
686 {
687 if ( this->helmet != nullptr && this->helmet->status > BROKEN )
688 {
689 equipNum[numEquippedItems] = 0;
690 ++numEquippedItems;
691 }
692 if ( this->breastplate != nullptr && this->breastplate->status > BROKEN )
693 {
694 equipNum[numEquippedItems] = 1;
695 ++numEquippedItems;
696 }
697 if ( this->gloves != nullptr && this->gloves->status > BROKEN )
698 {
699 equipNum[numEquippedItems] = 2;
700 ++numEquippedItems;
701 }
702 if ( this->shoes != nullptr && this->shoes->status > BROKEN )
703 {
704 equipNum[numEquippedItems] = 3;
705 ++numEquippedItems;
706 }
707 if ( this->cloak != nullptr && this->cloak->status > BROKEN )
708 {
709 equipNum[numEquippedItems] = 6;
710 ++numEquippedItems;
711 }
712 if ( this->mask != nullptr && this->mask->status > BROKEN )
713 {
714 equipNum[numEquippedItems] = 9;
715 ++numEquippedItems;
716 }
717 }
718
719 if ( !excludeWeapon )
720 {
721 if ( this->weapon != nullptr && this->weapon->status > BROKEN )
722 {
723 equipNum[numEquippedItems] = 5;
724 ++numEquippedItems;
725 }
726 }
727
728 if ( !excludeShield )
729 {
730 if ( this->shield != nullptr && this->shield->status > BROKEN )
731 {
732 equipNum[numEquippedItems] = 4;
733 ++numEquippedItems;
734 }
735 }
736
737 if ( !excludeJewelry )
738 {
739 if ( this->amulet != nullptr && this->amulet->status > BROKEN )
740 {
741 equipNum[numEquippedItems] = 7;
742 ++numEquippedItems;
743 }
744 if ( this->ring != nullptr && this->ring->status > BROKEN )
745 {
746 equipNum[numEquippedItems] = 8;
747 ++numEquippedItems;
748 }
749 }
750
751 if ( numEquippedItems == 0 )
752 {
753 *returnItem = nullptr;
754 return -1;
755 }
756
757 int roll = rand() % numEquippedItems;
758
759 switch ( equipNum[roll] )
760 {
761 case 0:
762 *returnItem = this->helmet;
763 break;
764 case 1:
765 *returnItem = this->breastplate;
766 break;
767 case 2:
768 *returnItem = this->gloves;
769 break;
770 case 3:
771 *returnItem = this->shoes;
772 break;
773 case 4:
774 *returnItem = this->shield;
775 break;
776 case 5:
777 *returnItem = this->weapon;
778 break;
779 case 6:
780 *returnItem = this->cloak;
781 break;
782 case 7:
783 *returnItem = this->amulet;
784 break;
785 case 8:
786 *returnItem = this->ring;
787 break;
788 case 9:
789 *returnItem = this->mask;
790 break;
791 default:
792 *returnItem = nullptr;
793 break;
794 }
795
796 return equipNum[roll];
797 }
798
getSkillLangEntry(int skill)799 char* getSkillLangEntry(int skill)
800 {
801 int langEntry = 236 + skill;
802 if ( skill == PRO_UNARMED )
803 {
804 langEntry = 3204;
805 }
806 else if ( skill == PRO_ALCHEMY )
807 {
808 langEntry = 3340;
809 }
810 return language[langEntry];
811 }
812
copyNPCStatsAndInventoryFrom(Stat & src)813 void Stat::copyNPCStatsAndInventoryFrom(Stat& src)
814 {
815 int player = -1;
816 if ( multiplayer == CLIENT )
817 {
818 return;
819 }
820 for ( int c = 0; c < MAXPLAYERS; ++c )
821 {
822 if ( stats[c] == this )
823 {
824 player = c;
825 break;
826 }
827 }
828
829 //this->type = src.type;
830
831 this->HP = src.HP;
832 this->MAXHP = src.MAXHP;
833 this->OLDHP = src.HP;
834 this->MP = src.MP;
835 this->MAXMP = src.MAXMP;
836
837 this->STR = src.STR;
838 this->DEX = src.DEX;
839 this->CON = src.CON;
840 this->INT = src.INT;
841 this->PER = src.PER;
842 this->CHR = src.CHR;
843 this->EXP = src.EXP;
844 this->LVL = src.LVL;
845
846 this->GOLD = src.GOLD;
847 bool oldIntro = intro;
848 if ( player == clientnum )
849 {
850 intro = true;
851 }
852 if ( src.helmet )
853 {
854 if ( player >= 0 )
855 {
856 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
857 copyItem(item, src.helmet);
858 item->identified = true;
859 if ( player == clientnum )
860 {
861 Item* pickedUp = itemPickup(player, item);
862 useItem(pickedUp, player);
863 free(item);
864 }
865 else
866 {
867 serverSendItemToPickupAndEquip(player, item);
868 useItem(item, player);
869 }
870 }
871 else
872 {
873 if ( !this->helmet )
874 {
875 this->helmet = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
876 }
877 copyItem(this->helmet, src.helmet);
878 }
879 }
880 else
881 {
882 this->helmet = NULL;
883 }
884 if ( src.breastplate )
885 {
886 if ( player >= 0 )
887 {
888 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
889 copyItem(item, src.breastplate);
890 item->identified = true;
891 if ( player == clientnum )
892 {
893 Item* pickedUp = itemPickup(player, item);
894 useItem(pickedUp, player);
895 free(item);
896 }
897 else
898 {
899 serverSendItemToPickupAndEquip(player, item);
900 useItem(item, player);
901 }
902 }
903 else
904 {
905 if ( !this->breastplate )
906 {
907 this->breastplate = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
908 }
909 copyItem(this->breastplate, src.breastplate);
910 }
911 }
912 else
913 {
914 this->breastplate = NULL;
915 }
916 if ( src.gloves )
917 {
918 if ( player >= 0 )
919 {
920 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
921 copyItem(item, src.gloves);
922 item->identified = true;
923 if ( player == clientnum )
924 {
925 Item* pickedUp = itemPickup(player, item);
926 useItem(pickedUp, player);
927 free(item);
928 }
929 else
930 {
931 serverSendItemToPickupAndEquip(player, item);
932 useItem(item, player);
933 }
934 }
935 else
936 {
937 if ( !this->gloves )
938 {
939 this->gloves = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
940 }
941 copyItem(this->gloves, src.gloves);
942 }
943 }
944 else
945 {
946 this->gloves = NULL;
947 }
948 if ( src.shoes )
949 {
950 if ( player >= 0 )
951 {
952 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
953 copyItem(item, src.shoes);
954 item->identified = true;
955 if ( player == clientnum )
956 {
957 Item* pickedUp = itemPickup(player, item);
958 useItem(pickedUp, player);
959 free(item);
960 }
961 else
962 {
963 serverSendItemToPickupAndEquip(player, item);
964 useItem(item, player);
965 }
966 }
967 else
968 {
969 if ( !this->shoes )
970 {
971 this->shoes = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
972 }
973 copyItem(this->shoes, src.shoes);
974 }
975 }
976 else
977 {
978 this->shoes = NULL;
979 }
980 if ( src.shield )
981 {
982 if ( player >= 0 )
983 {
984 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
985 copyItem(item, src.shield);
986 item->identified = true;
987 if ( player == clientnum )
988 {
989 Item* pickedUp = itemPickup(player, item);
990 useItem(pickedUp, player);
991 free(item);
992 }
993 else
994 {
995 serverSendItemToPickupAndEquip(player, item);
996 useItem(item, player);
997 }
998 }
999 else
1000 {
1001 if ( !this->shield )
1002 {
1003 this->shield = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1004 }
1005 copyItem(this->shield, src.shield);
1006 }
1007 }
1008 else
1009 {
1010 this->shield = NULL;
1011 }
1012 if ( src.weapon )
1013 {
1014 if ( player >= 0 )
1015 {
1016 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1017 copyItem(item, src.weapon);
1018 item->identified = true;
1019 if ( player == clientnum )
1020 {
1021 Item* pickedUp = itemPickup(player, item);
1022 useItem(pickedUp, player);
1023 free(item);
1024 }
1025 else
1026 {
1027 serverSendItemToPickupAndEquip(player, item);
1028 useItem(item, player);
1029 }
1030 }
1031 else
1032 {
1033 if ( !this->weapon )
1034 {
1035 this->weapon = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1036 }
1037 copyItem(this->weapon, src.weapon);
1038 }
1039 }
1040 else
1041 {
1042 this->weapon = NULL;
1043 }
1044 if ( src.cloak )
1045 {
1046 if ( player >= 0 )
1047 {
1048 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1049 copyItem(item, src.cloak);
1050 item->identified = true;
1051 if ( player == clientnum )
1052 {
1053 Item* pickedUp = itemPickup(player, item);
1054 useItem(pickedUp, player);
1055 free(item);
1056 }
1057 else
1058 {
1059 serverSendItemToPickupAndEquip(player, item);
1060 useItem(item, player);
1061 }
1062 }
1063 else
1064 {
1065 if ( !this->cloak )
1066 {
1067 this->cloak = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1068 }
1069 copyItem(this->cloak, src.cloak);
1070 }
1071 }
1072 else
1073 {
1074 this->cloak = NULL;
1075 }
1076 if ( src.amulet )
1077 {
1078 if ( player >= 0 )
1079 {
1080 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1081 copyItem(item, src.amulet);
1082 item->identified = true;
1083 if ( player == clientnum )
1084 {
1085 Item* pickedUp = itemPickup(player, item);
1086 useItem(pickedUp, player);
1087 free(item);
1088 }
1089 else
1090 {
1091 serverSendItemToPickupAndEquip(player, item);
1092 useItem(item, player);
1093 }
1094 }
1095 else
1096 {
1097 if ( !this->amulet )
1098 {
1099 this->amulet = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1100 }
1101 copyItem(this->amulet, src.amulet);
1102 }
1103 }
1104 else
1105 {
1106 this->amulet = NULL;
1107 }
1108 if ( src.ring )
1109 {
1110 if ( player >= 0 )
1111 {
1112 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1113 copyItem(item, src.ring);
1114 item->identified = true;
1115 if ( player == clientnum )
1116 {
1117 Item* pickedUp = itemPickup(player, item);
1118 useItem(pickedUp, player);
1119 free(item);
1120 }
1121 else
1122 {
1123 serverSendItemToPickupAndEquip(player, item);
1124 useItem(item, player);
1125 }
1126 }
1127 else
1128 {
1129 if ( !this->ring )
1130 {
1131 this->ring = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1132 }
1133 copyItem(this->ring, src.ring);
1134 }
1135 }
1136 else
1137 {
1138 this->ring = NULL;
1139 }
1140 if ( src.mask )
1141 {
1142 if ( player >= 0 )
1143 {
1144 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1145 copyItem(item, src.mask);
1146 item->identified = true;
1147 if ( player == clientnum )
1148 {
1149 Item* pickedUp = itemPickup(player, item);
1150 useItem(pickedUp, player);
1151 free(item);
1152 }
1153 else
1154 {
1155 serverSendItemToPickupAndEquip(player, item);
1156 useItem(item, player);
1157 }
1158 }
1159 else
1160 {
1161 if ( !this->mask )
1162 {
1163 this->mask = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1164 }
1165 copyItem(this->mask, src.mask);
1166 }
1167 }
1168 else
1169 {
1170 this->mask = NULL;
1171 }
1172
1173 for ( node_t* node = src.inventory.first; node; node = node->next )
1174 {
1175 Item* invItem = (Item*)node->element;
1176 if ( invItem )
1177 {
1178 if ( player >= 0 )
1179 {
1180 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, nullptr);
1181 copyItem(item, invItem);
1182 item->identified = true;
1183 Item* pickedUp = itemPickup(player, item);
1184 if ( pickedUp )
1185 {
1186 if ( player == clientnum )
1187 {
1188 free(item);
1189 }
1190 else
1191 {
1192 free(pickedUp);
1193 }
1194 }
1195 }
1196 else
1197 {
1198 Item* item = newItem(GEM_ROCK, EXCELLENT, 0, 1, 0, true, &inventory);
1199 copyItem(item, invItem);
1200 }
1201 }
1202 }
1203 intro = oldIntro;
1204 }