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 }