예제 #1
0
파일: stats.cpp 프로젝트: astrellon/Rouge
	void Stats::deserialise(LoadingState *state, data::IData *data)
	{
		base::Handle<data::Table> dataMap(data::Table::checkDataType(data, "stats"));
		if (!dataMap)
		{
			return;
		}

		base::Handle<data::Table> baseStats(dataMap->at<data::Table>("baseStats"));
		if (baseStats)
		{
			for (auto iter = baseStats->beginMap(); iter != baseStats->endMap(); ++iter)
			{
				Stat::StatType type = Stat::getStatType(iter->first.c_str());
				if (type == Stat::MAX_STAT_LENGTH)
				{
					std::stringstream ss;
					ss << "Unknown stat '" << iter->first << '\'';
					am_log("LOADERR", ss);
					continue;
				}
				base::Handle<data::Number> num(dynamic_cast<data::Number *>(iter->second.get()));
				if (num)
				{
					setBaseStat(type, num->value<float>());
				}
				else
				{
					std::stringstream ss;
					ss << "Cannot load base stat '" << iter->first << "' from a '";
					ss << iter->second->typeName() << "'";
					am_log("LOADERR", ss);
					continue;
				}
			}
		}

		base::Handle<data::IData> tempData(dataMap->at("modifiers"));
		if (tempData)
		{
			mModifiers->deserialise(state, tempData);
		}
	}
예제 #2
0
void initHuman(Entity* my, Stat* myStats)
{
	int c;
	node_t* node;

	my->initMonster(113);

	if ( multiplayer != CLIENT )
	{
		MONSTER_SPOTSND = -1;
		MONSTER_SPOTVAR = 1;
		MONSTER_IDLESND = -1;
		MONSTER_IDLEVAR = 1;
	}
	if ( multiplayer != CLIENT && !MONSTER_INIT )
	{
		if ( myStats != nullptr )
		{
			if ( !myStats->leader_uid )
			{
				myStats->leader_uid = 0;
			}

			my->createPathBoundariesNPC();

			Stat baseStats(HUMAN);
			bool isDefaultStats = isMonsterStatsDefault(*myStats);

			// apply random stat increases if set in stat_shared.cpp or editor
			setRandomMonsterStats(myStats);

			// generate 6 items max, less if there are any forced items from boss variants
			int customItemsToGenerate = ITEM_CUSTOM_SLOT_LIMIT;

			// special human variant (named or Zap Brigadier), do not generate any other items
			int specialMonsterVariant = 0;

			// boss variants
			// generate special loadout
			if ( my->monsterSpecialTimer == 0 )
			{
				if ( rand() % 25 == 0 )
				{
					specialMonsterVariant = 1;
					int specialMonsterType = rand() % 10;
					if ( !strncmp(map.name, "Hamlet", 6) )
					{
						while ( specialMonsterType == 6 ) // 2 spiders that spawn cause aggro issues in Hamlet.
						{
							specialMonsterType = rand() % 10;
						}
					}
					switch ( rand() % 10 )
					{
						case 0:
							// red riding hood
							strcpy(myStats->name, "Red Riding Hood");
							myStats->appearance = 2;
							myStats->sex = FEMALE;
							myStats->LVL = 1;
							myStats->HP = 10;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 10;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 0;
							myStats->DEX = 0;
							myStats->CON = 0;
							myStats->INT = -2;
							myStats->PER = -2;
							myStats->CHR = 4;
							myStats->helmet = newItem(HAT_PHRYGIAN, EXCELLENT, 1, 1, rand(), false, nullptr);
							myStats->cloak = newItem(CLOAK, EXCELLENT, 1, 1, 2, false, nullptr);
							myStats->weapon = newItem(QUARTERSTAFF, EXCELLENT, 1, 1, rand(), false, nullptr);
							break;
						case 1:
							// king arthur
							strcpy(myStats->name, "King Arthur");
							myStats->appearance = 0;
							myStats->sex = MALE;
							myStats->LVL = 10;
							myStats->HP = 100;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 100;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 5;
							myStats->DEX = 5;
							myStats->CON = 5;
							myStats->INT = 5;
							myStats->PER = 5;
							myStats->CHR = 5;
							myStats->breastplate = newItem(STEEL_BREASTPIECE, EXCELLENT, 1, 1, 1, true, nullptr);
							myStats->gloves = newItem(GAUNTLETS, EXCELLENT, 1, 1, 1, true, nullptr);
							myStats->shoes = newItem(STEEL_BOOTS, EXCELLENT, 1, 1, 1, true, nullptr);
							myStats->cloak = newItem(CLOAK, EXCELLENT, 2, 1, 2, true, nullptr);
							myStats->weapon = newItem(ARTIFACT_SWORD, EXCELLENT, 1, 1, rand(), true, nullptr);
							myStats->shield = newItem(STEEL_SHIELD_RESISTANCE, EXCELLENT, 1, 1, 1, true, nullptr);
							break;
						case 2:
							// merlin
							strcpy(myStats->name, "Merlin");
							myStats->appearance = 5;
							myStats->sex = MALE;
							myStats->LVL = 10;
							myStats->HP = 60;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 200;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 2;
							myStats->DEX = 2;
							myStats->CON = 3;
							myStats->INT = 11;
							myStats->PER = 10;
							myStats->CHR = 2;
							myStats->helmet = newItem(HAT_WIZARD, EXCELLENT, 2, 1, 2, false, nullptr);
							myStats->shoes = newItem(LEATHER_BOOTS_SPEED, EXCELLENT, 2, 1, 2, false, nullptr);
							myStats->cloak = newItem(CLOAK_PROTECTION, EXCELLENT, 5, 1, 3, false, nullptr);
							myStats->weapon = newItem(MAGICSTAFF_LIGHTNING, EXCELLENT, 2, 1, 2, false, nullptr);
							myStats->amulet = newItem(AMULET_MAGICREFLECTION, EXCELLENT, 2, 1, 2, false, nullptr);
							break;
						case 3:
							// robin hood
							strcpy(myStats->name, "Robin Hood");
							myStats->appearance = 1;
							myStats->sex = MALE;
							myStats->LVL = 5;
							myStats->HP = 70;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 50;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 3;
							myStats->DEX = 5;
							myStats->CON = 3;
							myStats->INT = 2;
							myStats->PER = 3;
							myStats->CHR = 5;
							myStats->gloves = newItem(GLOVES, EXCELLENT, 1, 1, 3, true, nullptr);
							myStats->shoes = newItem(LEATHER_BOOTS, SERVICABLE, 1, 1, 3, true, nullptr);
							myStats->cloak = newItem(CLOAK, EXCELLENT, 1, 1, 0, true, nullptr);
							myStats->weapon = newItem(SHORTBOW, EXCELLENT, 1, 1, 3, true, nullptr);
							break;
						case 4:
							// conan
							strcpy(myStats->name, "Conan the Barbarian");
							myStats->appearance = 7;
							myStats->sex = MALE;
							myStats->LVL = 10;
							myStats->HP = 100;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 20;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 10;
							myStats->DEX = 5;
							myStats->CON = 10;
							myStats->INT = 3;
							myStats->PER = 3;
							myStats->CHR = 20;
							myStats->helmet = newItem(LEATHER_HELM, EXCELLENT, 2, 1, rand(), false, nullptr);
							myStats->shield = newItem(WOODEN_SHIELD, EXCELLENT, 2, 1, rand(), false, nullptr);
							myStats->weapon = newItem(STEEL_AXE, EXCELLENT, 2, 1, rand(), false, nullptr);
							break;
						case 5:
							// othello
							strcpy(myStats->name, "Othello");
							myStats->appearance = 14;
							myStats->sex = MALE;
							myStats->LVL = 10;
							myStats->HP = 50;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 20;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 3;
							myStats->DEX = 3;
							myStats->CON = 3;
							myStats->INT = 3;
							myStats->PER = 0;
							myStats->CHR = 30;
							myStats->gloves = newItem(BRACERS, EXCELLENT, -1, 1, rand(), false, nullptr);
							myStats->breastplate = newItem(IRON_BREASTPIECE, EXCELLENT, 1, 1, rand(), false, nullptr);
							myStats->weapon = newItem(STEEL_SWORD, EXCELLENT, 2, 1, rand(), false, nullptr);
							myStats->cloak = newItem(CLOAK, EXCELLENT, 0, 1, 2, false, nullptr);
							break;
						case 6:
							// anansi
							strcpy(myStats->name, "Anansi");
							myStats->appearance = 15;
							myStats->sex = MALE;
							myStats->LVL = 20;
							myStats->HP = 100;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 100;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 5;
							myStats->DEX = 8;
							myStats->CON = 5;
							myStats->INT = 20;
							myStats->PER = 20;
							myStats->CHR = 10;
							myStats->helmet = newItem(HAT_JESTER, EXCELLENT, 5, 1, rand(), false, nullptr);
							myStats->weapon = newItem(ARTIFACT_MACE, EXCELLENT, 1, 1, rand(), false, nullptr);
							int c;
							for ( c = 0; c < 2; c++ )
							{
								Entity* entity = summonMonster(SPIDER, my->x, my->y);
								if ( entity )
								{
									entity->parent = my->getUID();
									entity->flags[USERFLAG2] = true;
								}
							}
							break;
						case 7:
							// oya
							strcpy(myStats->name, "Oya");
							myStats->appearance = 13;
							myStats->sex = FEMALE;
							myStats->LVL = 20;
							myStats->HP = 100;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 100;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 4;
							myStats->DEX = 10;
							myStats->CON = 2;
							myStats->INT = 20;
							myStats->PER = 10;
							myStats->CHR = 10;
							myStats->cloak = newItem(CLOAK_PROTECTION, EXCELLENT, 3, 1, 1, false, nullptr);
							myStats->helmet = newItem(HAT_HOOD, EXCELLENT, 3, 1, 1, false, nullptr);
							break;
						case 8:
							// vishpala
							strcpy(myStats->name, "Vishpala");
							myStats->appearance = 17;
							myStats->sex = FEMALE;
							myStats->LVL = 10;
							myStats->HP = 70;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 20;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 5;
							myStats->DEX = 5;
							myStats->CON = 5;
							myStats->INT = 5;
							myStats->PER = 5;
							myStats->CHR = 10;
							myStats->cloak = newItem(CLOAK, EXCELLENT, 0, 1, 2, false, nullptr);
							myStats->breastplate = newItem(IRON_BREASTPIECE, EXCELLENT, 0, 1, rand(), false, nullptr);
							myStats->shoes = newItem(IRON_BOOTS, EXCELLENT, 0, 1, rand(), false, nullptr);
							myStats->weapon = newItem(ARTIFACT_SPEAR, EXCELLENT, 1, 1, rand(), false, nullptr);
							myStats->shield = newItem(BRONZE_SHIELD, EXCELLENT, 1, 1, rand(), false, nullptr);
							break;
						case 9:
							// kali
							strcpy(myStats->name, "Kali");
							myStats->appearance = 15;
							myStats->sex = FEMALE;
							myStats->LVL = 20;
							myStats->HP = 200;
							myStats->MAXHP = myStats->HP;
							myStats->MP = 200;
							myStats->MAXMP = myStats->MP;
							myStats->STR = 5;
							myStats->DEX = 5;
							myStats->CON = 5;
							myStats->INT = 20;
							myStats->PER = 20;
							myStats->CHR = 20;
							myStats->cloak = newItem(CLOAK_MAGICREFLECTION, EXCELLENT, 1, 1, 2, false, nullptr);
							myStats->shoes = newItem(LEATHER_BOOTS_SPEED, EXCELLENT, 1, 1, rand(), false, nullptr);
							myStats->weapon = newItem(SPELLBOOK_FIREBALL, EXCELLENT, 1, 1, rand(), false, nullptr);
							break;
						default:
							break;
					}
				}
			}
			else
			{
				specialMonsterVariant = 1;
				// zap brigadier
				strcpy(myStats->name, "ZAP Brigadier");
				myStats->appearance = 1;
				myStats->sex = static_cast<sex_t>(rand() % 2);
				myStats->LVL = 10;
				myStats->HP = 100;
				myStats->MAXHP = myStats->HP;
				myStats->MP = 200;
				myStats->MAXMP = myStats->MP;
				myStats->STR = 3;
				myStats->DEX = 3;
				myStats->CON = 3;
				myStats->INT = 3;
				myStats->PER = 10;
				myStats->CHR = 10;
				myStats->helmet = newItem(HAT_HOOD, EXCELLENT, 2, 1, 3, false, nullptr);
				myStats->gloves = newItem(GLOVES, EXCELLENT, 0, 1, 2, false, nullptr);
				myStats->shoes = newItem(LEATHER_BOOTS_SPEED, EXCELLENT, 0, 1, 2, false, nullptr);
				myStats->breastplate = newItem(LEATHER_BREASTPIECE, EXCELLENT, 0, 1, 2, false, nullptr);
				myStats->cloak = newItem(CLOAK_PROTECTION, EXCELLENT, 2, 1, 3, false, nullptr);
				myStats->weapon = newItem(MAGICSTAFF_LIGHTNING, EXCELLENT, 1, 1, 2, false, nullptr);
				myStats->amulet = newItem(AMULET_MAGICREFLECTION, EXCELLENT, 1, 1, 2, false, nullptr);
			}

			// random effects
			if ( rand() % 10 == 0 )
			{
				myStats->EFFECTS[EFF_ASLEEP] = true;
				myStats->EFFECTS_TIMERS[EFF_ASLEEP] = 1800 + rand() % 1800;
			}

			// generates equipment and weapons if available from editor
			createMonsterEquipment(myStats);

			// create any custom inventory items from editor if available
			createCustomInventory(myStats, customItemsToGenerate);

			// count if any custom inventory items from editor
			int customItems = countCustomItems(myStats);
			//max limit of 6 custom items per entity.

			// count any inventory items set to default in edtior
			int defaultItems = countDefaultItems(myStats);

			if ( specialMonsterVariant == 0 && my->monsterStoreType > 0 && isDefaultStats )
			{
				myStats->EXP += 100 * my->monsterStoreType; // apply experience to level up the humans with floor depth.
			}

			// generate the default inventory items for the monster, provided the editor sprite allowed enough default slots
			switch ( defaultItems )
			{
				case 6:
				case 5:
				case 4:
				case 3:
				case 2:
				case 1:
					break;
				default:
					break;
			}

			if ( specialMonsterVariant == 0 )
			{
				// generate random equipment if not a named special human

				//give shield
				if ( myStats->shield == nullptr && myStats->EDITOR_ITEMS[ITEM_SLOT_SHIELD] == 1 )
				{
					switch ( rand() % 10 )
					{
						case 0:
						case 1:
						case 2:
							myStats->shield = newItem(TOOL_TORCH, SERVICABLE, 0, 1, rand(), false, nullptr);
							break;
						case 3:
						case 4:
							break;
						case 5:
						case 6:
							myStats->shield = newItem(WOODEN_SHIELD, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 7:
						case 8:
							myStats->shield = newItem(BRONZE_SHIELD, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 9:
							myStats->shield = newItem(IRON_SHIELD, WORN, 0, 1, rand(), false, nullptr);
							break;
					}
				}

				//give weapon
				if ( myStats->weapon == nullptr && myStats->EDITOR_ITEMS[ITEM_SLOT_WEAPON] == 1 )
				{
					switch ( rand() % 10 )
					{
						case 0:
						case 1:
							myStats->weapon = newItem(SHORTBOW, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 2:
						case 3:
							myStats->weapon = newItem(BRONZE_AXE, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 4:
						case 5:
							myStats->weapon = newItem(BRONZE_SWORD, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 6:
							myStats->weapon = newItem(IRON_SPEAR, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 7:
							myStats->weapon = newItem(IRON_AXE, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 8:
							myStats->weapon = newItem(IRON_SWORD, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 9:
							myStats->weapon = newItem(CROSSBOW, WORN, 0, 1, rand(), false, nullptr);
							break;
					}
				}

				// give helmet
				if ( myStats->helmet == nullptr && myStats->EDITOR_ITEMS[ITEM_SLOT_HELM] == 1 )
				{
					switch ( rand() % 10 )
					{
						case 0:
						case 1:
						case 2:
							break;
						case 3:
							myStats->helmet = newItem(HAT_HOOD, WORN, 0, 1, rand() % 4, false, nullptr);
							break;
						case 4:
							myStats->helmet = newItem(HAT_PHRYGIAN, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 5:
							myStats->helmet = newItem(HAT_WIZARD, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 6:
						case 7:
							myStats->helmet = newItem(LEATHER_HELM, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 8:
						case 9:
							myStats->helmet = newItem(IRON_HELM, WORN, 0, 1, rand(), false, nullptr);
							break;
					}
				}

				// give cloak
				if ( myStats->cloak == nullptr && myStats->EDITOR_ITEMS[ITEM_SLOT_CLOAK] == 1 )
				{
					switch ( rand() % 10 )
					{
						case 0:
						case 1:
						case 2:
						case 3:
						case 4:
						case 5:
							break;
						case 6:
						case 7:
						case 8:
							myStats->cloak = newItem(CLOAK, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 9:
							myStats->cloak = newItem(CLOAK_MAGICREFLECTION, WORN, 0, 1, rand(), false, nullptr);
							break;
					}
				}

				// give armor
				if ( myStats->breastplate == nullptr && myStats->EDITOR_ITEMS[ITEM_SLOT_ARMOR] == 1 )
				{
					switch ( rand() % 10 )
					{
						case 0:
						case 1:
						case 2:
						case 3:
						case 4:
							break;
						case 5:
						case 6:
						case 7:
							myStats->breastplate = newItem(LEATHER_BREASTPIECE, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 8:
						case 9:
							myStats->breastplate = newItem(IRON_BREASTPIECE, WORN, 0, 1, rand(), false, nullptr);
							break;
					}
				}

				// give gloves
				if ( myStats->gloves == nullptr && myStats->EDITOR_ITEMS[ITEM_SLOT_GLOVES] == 1 )
				{
					switch ( rand() % 10 )
					{
						case 0:
						case 1:
						case 2:
						case 3:
						case 4:
							break;
						case 5:
						case 6:
						case 7:
							myStats->gloves = newItem(GLOVES, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 8:
						case 9:
							myStats->gloves = newItem(GAUNTLETS, WORN, 0, 1, rand(), false, nullptr);
							break;
					}
				}

				// give boots
				if ( myStats->shoes == nullptr && myStats->EDITOR_ITEMS[ITEM_SLOT_BOOTS] == 1 )
				{
					switch ( rand() % 10 )
					{
						case 0:
						case 1:
						case 2:
						case 3:
						case 4:
							break;
						case 5:
						case 6:
						case 7:
							myStats->shoes = newItem(LEATHER_BOOTS, WORN, 0, 1, rand(), false, nullptr);
							break;
						case 8:
						case 9:
							myStats->shoes = newItem(IRON_BOOTS, WORN, 0, 1, rand(), false, nullptr);
							break;
					}
				}
			}
		}
	}

	// torso
	Entity* entity = newEntity(106, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][1][0]; // 0
	entity->focaly = limbs[HUMAN][1][1]; // 0
	entity->focalz = limbs[HUMAN][1][2]; // 0
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// right leg
	entity = newEntity(107, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][2][0]; // 0
	entity->focaly = limbs[HUMAN][2][1]; // 0
	entity->focalz = limbs[HUMAN][2][2]; // 2
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// left leg
	entity = newEntity(108, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][3][0]; // 0
	entity->focaly = limbs[HUMAN][3][1]; // 0
	entity->focalz = limbs[HUMAN][3][2]; // 2
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// right arm
	entity = newEntity(109, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][4][0]; // 0
	entity->focaly = limbs[HUMAN][4][1]; // 0
	entity->focalz = limbs[HUMAN][4][2]; // 1.5
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// left arm
	entity = newEntity(110, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][5][0]; // 0
	entity->focaly = limbs[HUMAN][5][1]; // 0
	entity->focalz = limbs[HUMAN][5][2]; // 1.5
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// world weapon
	entity = newEntity(-1, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][6][0]; // 1.5
	entity->focaly = limbs[HUMAN][6][1]; // 0
	entity->focalz = limbs[HUMAN][6][2]; // -.5
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	entity->pitch = .25;
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// shield
	entity = newEntity(-1, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][7][0]; // 2
	entity->focaly = limbs[HUMAN][7][1]; // 0
	entity->focalz = limbs[HUMAN][7][2]; // 0
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// cloak
	entity = newEntity(-1, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->scalex = 1.01;
	entity->scaley = 1.01;
	entity->scalez = 1.01;
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][8][0]; // 0
	entity->focaly = limbs[HUMAN][8][1]; // 0
	entity->focalz = limbs[HUMAN][8][2]; // 4
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// helmet
	entity = newEntity(-1, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->scalex = 1.01;
	entity->scaley = 1.01;
	entity->scalez = 1.01;
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][9][0]; // 0
	entity->focaly = limbs[HUMAN][9][1]; // 0
	entity->focalz = limbs[HUMAN][9][2]; // -1.75
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	// mask
	entity = newEntity(-1, 0, map.entities, nullptr); //Limb entity.
	entity->sizex = 4;
	entity->sizey = 4;
	entity->skill[2] = my->getUID();
	entity->scalex = .99;
	entity->scaley = .99;
	entity->scalez = .99;
	entity->flags[PASSABLE] = true;
	entity->flags[NOUPDATE] = true;
	entity->flags[USERFLAG2] = my->flags[USERFLAG2];
	entity->focalx = limbs[HUMAN][10][0]; // 0
	entity->focaly = limbs[HUMAN][10][1]; // 0
	entity->focalz = limbs[HUMAN][10][2]; // .5
	entity->behavior = &actHumanLimb;
	entity->parent = my->getUID();
	node = list_AddNodeLast(&my->children);
	node->element = entity;
	node->deconstructor = &emptyDeconstructor;
	node->size = sizeof(Entity*);
	my->bodyparts.push_back(entity);

	if ( multiplayer == CLIENT )
	{
		my->sprite = 113; // human head model
		return;
	}

	// set head model
	if ( myStats->appearance < 5 )
	{
		my->sprite = 113 + 12 * myStats->sex + myStats->appearance;
	}
	else if ( myStats->appearance == 5 )
	{
		my->sprite = 332 + myStats->sex;
	}
	else if ( myStats->appearance >= 6 && myStats->appearance < 12 )
	{
		my->sprite = 341 + myStats->sex * 13 + myStats->appearance - 6;
	}
	else if ( myStats->appearance >= 12 )
	{
		my->sprite = 367 + myStats->sex * 13 + myStats->appearance - 12;
	}
	else
	{
		my->sprite = 113; // default
	}
}