Пример #1
0
void humanMoveBodyparts(Entity* my, Stat* myStats, double dist)
{
	node_t* node;
	Entity* entity = nullptr, *entity2 = nullptr;
	Entity* rightbody = nullptr;
	Entity* weaponarm = nullptr;
	int bodypart;
	bool wearingring = false;

	// set invisibility //TODO: isInvisible()?
	if ( multiplayer != CLIENT )
	{
		if ( myStats->ring != nullptr )
			if ( myStats->ring->type == RING_INVISIBILITY )
			{
				wearingring = true;
			}
		if ( myStats->cloak != nullptr )
			if ( myStats->cloak->type == CLOAK_INVISIBILITY )
			{
				wearingring = true;
			}
		if ( myStats->EFFECTS[EFF_INVISIBLE] == true || wearingring == true )
		{
			my->flags[INVISIBLE] = true;
			my->flags[BLOCKSIGHT] = false;
			bodypart = 0;
			for (node = my->children.first; node != nullptr; node = node->next)
			{
				if ( bodypart < 2 )
				{
					bodypart++;
					continue;
				}
				if ( bodypart >= 7 )
				{
					break;
				}
				entity = (Entity*)node->element;
				if ( !entity->flags[INVISIBLE] )
				{
					entity->flags[INVISIBLE] = true;
					serverUpdateEntityBodypart(my, bodypart);
				}
				bodypart++;
			}
		}
		else
		{
			my->flags[INVISIBLE] = false;
			my->flags[BLOCKSIGHT] = true;
			bodypart = 0;
			for (node = my->children.first; node != nullptr; node = node->next)
			{
				if ( bodypart < 2 )
				{
					bodypart++;
					continue;
				}
				if ( bodypart >= 7 )
				{
					break;
				}
				entity = (Entity*)node->element;
				if ( entity->flags[INVISIBLE] )
				{
					entity->flags[INVISIBLE] = false;
					serverUpdateEntityBodypart(my, bodypart);
					serverUpdateEntityFlag(my, INVISIBLE);
				}
				bodypart++;
			}
		}

		// sleeping
		if ( myStats->EFFECTS[EFF_ASLEEP] )
		{
			my->z = 1.5;
			my->pitch = PI / 4;
		}
		else
		{
			my->z = -1;
			if ( my->monsterAttack == 0 )
			{
				my->pitch = 0;
			}
		}

		// levitation
		bool levitating = isLevitating(myStats);
		if ( levitating )
		{
			my->z -= 1; // floating
		}
	}

	Entity* shieldarm = nullptr;

	// move bodyparts
	for (bodypart = 0, node = my->children.first; node != nullptr; node = node->next, bodypart++)
	{
		if ( bodypart < 2 )
		{
			if ( multiplayer == CLIENT )
			{
				for ( int i = LIMB_HUMANOID_TORSO; i <= LIMB_HUMANOID_LEFTARM; i++ )
				{
					my->humanSetLimbsClient(i);
				}
			}
			continue;
		}
		entity = (Entity*)node->element;
		entity->x = my->x;
		entity->y = my->y;
		entity->z = my->z;
		if ( MONSTER_ATTACK == MONSTER_POSE_MAGIC_WINDUP1 && bodypart == LIMB_HUMANOID_RIGHTARM )
		{
			// don't let the creatures's yaw move the casting arm
		}
		else
		{
			entity->yaw = my->yaw;
		}
		if ( bodypart == LIMB_HUMANOID_RIGHTLEG || bodypart == LIMB_HUMANOID_LEFTARM )
		{
			my->humanoidAnimateWalk(entity, node, bodypart, HUMANWALKSPEED, dist, 0.4);
		}
		else if ( bodypart == LIMB_HUMANOID_LEFTLEG || bodypart == LIMB_HUMANOID_RIGHTARM || bodypart == LIMB_HUMANOID_CLOAK )
		{
			// left leg, right arm, cloak.
			if ( bodypart == LIMB_HUMANOID_RIGHTARM )
			{
				weaponarm = entity;
				if ( my->monsterAttack > 0 )
				{
					my->handleWeaponArmAttack(weaponarm);
				}
			}
			else if ( bodypart == LIMB_HUMANOID_CLOAK )
			{
				entity->pitch = entity->fskill[0];
			}

			my->humanoidAnimateWalk(entity, node, bodypart, HUMANWALKSPEED, dist, 0.4);

			if ( bodypart == LIMB_HUMANOID_CLOAK )
			{
				entity->fskill[0] = entity->pitch;
				entity->roll = my->roll - fabs(entity->pitch) / 2;
				entity->pitch = 0;
			}
		}
		switch ( bodypart )
		{
			// torso
			case LIMB_HUMANOID_TORSO:
				if ( multiplayer != CLIENT )
				{
					if ( myStats->breastplate == nullptr )
					{
						switch ( myStats->appearance / 6 )
						{
							case 1:
								entity->sprite = 334 + 13 * myStats->sex;
								break;
							case 2:
								entity->sprite = 360 + 13 * myStats->sex;
								break;
							default:
								entity->sprite = 106 + 12 * myStats->sex;
								break;
						}
					}
					else
					{
						entity->sprite = itemModel(myStats->breastplate);
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}

				entity->x -= .25 * cos(my->yaw);
				entity->y -= .25 * sin(my->yaw);
				entity->z += 2.5;
				break;
			// right leg
			case LIMB_HUMANOID_RIGHTLEG:
				if ( multiplayer != CLIENT )
				{
					if ( myStats->shoes == nullptr )
					{
						switch ( myStats->appearance / 6 )
						{
							case 1:
								entity->sprite = 335 + 13 * myStats->sex;
								break;
							case 2:
								entity->sprite = 361 + 13 * myStats->sex;
								break;
							default:
								entity->sprite = 107 + 12 * myStats->sex;
								break;
						}
					}
					else
					{
						my->setBootSprite(entity, SPRITE_BOOT_RIGHT_OFFSET);
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}
				entity->x += 1 * cos(my->yaw + PI / 2) + .25 * cos(my->yaw);
				entity->y += 1 * sin(my->yaw + PI / 2) + .25 * sin(my->yaw);
				entity->z += 5;
				if ( my->z >= 1.4 && my->z <= 1.6 )
				{
					entity->yaw += PI / 8;
					entity->pitch = -PI / 2;
				}
				break;
			// left leg
			case LIMB_HUMANOID_LEFTLEG:
				if ( multiplayer != CLIENT )
				{
					if ( myStats->shoes == nullptr )
					{
						switch ( myStats->appearance / 6 )
						{
							case 1:
								entity->sprite = 336 + 13 * myStats->sex;
								break;
							case 2:
								entity->sprite = 362 + 13 * myStats->sex;
								break;
							default:
								entity->sprite = 108 + 12 * myStats->sex;
								break;
						}
					}
					else
					{
						my->setBootSprite(entity, SPRITE_BOOT_LEFT_OFFSET);
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}
				entity->x -= 1 * cos(my->yaw + PI / 2) - .25 * cos(my->yaw);
				entity->y -= 1 * sin(my->yaw + PI / 2) - .25 * sin(my->yaw);
				entity->z += 5;
				if ( my->z >= 1.4 && my->z <= 1.6 )
				{
					entity->yaw -= PI / 8;
					entity->pitch = -PI / 2;
				}
				break;
			// right arm
			case LIMB_HUMANOID_RIGHTARM:
			{
				if ( multiplayer != CLIENT )
				{
					if ( myStats->gloves == nullptr )
					{
						switch ( myStats->appearance / 6 )
						{
							case 1:
								entity->sprite = 337 + 13 * myStats->sex;
								break;
							case 2:
								entity->sprite = 363 + 13 * myStats->sex;
								break;
							default:
								entity->sprite = 109 + 12 * myStats->sex;
								break;
						}
					}
					else
					{
						if ( setGloveSprite(myStats, entity, SPRITE_GLOVE_RIGHT_OFFSET) != 0 )
						{
							// successfully set sprite for the human model
						}
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}

				if ( multiplayer == CLIENT )
				{
					if ( entity->skill[7] == 0 )
					{
						if ( entity->sprite >= 109 && entity->sprite <= 110 )
						{
							// these are the default arms.
							// chances are they may be wrong if sent by the server, 
						}
						else
						{
							// otherwise we're being sent gloves armor etc so it's probably right.
							entity->skill[7] = entity->sprite;
						}
					}
					if ( entity->skill[7] == 0 )
					{
						// we set this ourselves until proper initialisation.
						my->humanSetLimbsClient(bodypart);
					}
					else
					{
						entity->sprite = entity->skill[7];
					}
				}

				node_t* tempNode = list_Node(&my->children, LIMB_HUMANOID_WEAPON);
				if ( tempNode )
				{
					Entity* weapon = (Entity*)tempNode->element;
					if ( MONSTER_ARMBENDED || (weapon->flags[INVISIBLE] && my->monsterState != MONSTER_STATE_ATTACK) )
					{
						// if weapon invisible and I'm not attacking, relax arm.
						entity->focalx = limbs[HUMAN][4][0]; // 0
						entity->focaly = limbs[HUMAN][4][1]; // 0
						entity->focalz = limbs[HUMAN][4][2]; // 1.5
					}
					else
					{
						// else flex arm.
						entity->focalx = limbs[HUMAN][4][0] + 0.75;
						entity->focaly = limbs[HUMAN][4][1];
						entity->focalz = limbs[HUMAN][4][2] - 0.75;
						entity->sprite += 2;
					}
				}

				entity->x += 2.5 * cos(my->yaw + PI / 2) - .20 * cos(my->yaw);
				entity->y += 2.5 * sin(my->yaw + PI / 2) - .20 * sin(my->yaw);
				entity->z += 1.5;
				entity->yaw += MONSTER_WEAPONYAW;
				if ( my->z >= 1.4 && my->z <= 1.6 )
				{
					entity->pitch = 0;
				}
				break;
			}
			// left arm
			case LIMB_HUMANOID_LEFTARM:
			{
				shieldarm = entity;
				if ( multiplayer != CLIENT )
				{
					if ( myStats->gloves == nullptr )
					{
						switch ( myStats->appearance / 6 )
						{
							case 1:
								entity->sprite = 338 + 13 * myStats->sex;
								break;
							case 2:
								entity->sprite = 364 + 13 * myStats->sex;
								break;
							default:
								entity->sprite = 110 + 12 * myStats->sex;
								break;
						}
					}
					else
					{
						if ( setGloveSprite(myStats, entity, SPRITE_GLOVE_LEFT_OFFSET) != 0 )
						{
							// successfully set sprite for the human model
						}
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}

				if ( multiplayer == CLIENT )
				{
					if ( entity->skill[7] == 0 )
					{
						if ( entity->sprite >= 109 && entity->sprite <= 110 )
						{
							// these are the default arms.
							// chances are they may be wrong if sent by the server, 
						}
						else
						{
							// otherwise we're being sent gloves armor etc so it's probably right.
							entity->skill[7] = entity->sprite;
						}
					}
					if ( entity->skill[7] == 0 )
					{
						// we set this ourselves until proper initialisation.
						my->humanSetLimbsClient(bodypart);
					}
					else
					{
						entity->sprite = entity->skill[7];
					}
				}

				node_t* tempNode = list_Node(&my->children, LIMB_HUMANOID_SHIELD);
				if ( tempNode )
				{
					Entity* shield = (Entity*)tempNode->element;
					if ( shield->flags[INVISIBLE] && (my->monsterState != MONSTER_STATE_ATTACK) )
					{
						// if shield invisible and I'm not attacking, relax arm.
						entity->focalx = limbs[HUMAN][5][0]; // 0
						entity->focaly = limbs[HUMAN][5][1]; // 0
						entity->focalz = limbs[HUMAN][5][2]; // 1.5
					}
					else
					{
						// else flex arm.
						entity->focalx = limbs[HUMAN][5][0] + 0.75;
						entity->focaly = limbs[HUMAN][5][1];
						entity->focalz = limbs[HUMAN][5][2] - 0.75;
						entity->sprite += 2;
					}
				}
				entity->x -= 2.5 * cos(my->yaw + PI / 2) + .20 * cos(my->yaw);
				entity->y -= 2.5 * sin(my->yaw + PI / 2) + .20 * sin(my->yaw);
				entity->z += 1.5;
				if ( my->z >= 1.4 && my->z <= 1.6 )
				{
					entity->pitch = 0;
				}
				if ( my->monsterDefend && my->monsterAttack == 0 )
				{
					MONSTER_SHIELDYAW = PI / 5;
				}
				else
				{
					MONSTER_SHIELDYAW = 0;
				}
				entity->yaw += MONSTER_SHIELDYAW;
				break;
			}
			// weapon
			case LIMB_HUMANOID_WEAPON:
				if ( multiplayer != CLIENT )
				{
					if ( myStats->weapon == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()?
					{
						entity->flags[INVISIBLE] = true;
					}
					else
					{
						entity->sprite = itemModel(myStats->weapon);
						if ( itemCategory(myStats->weapon) == SPELLBOOK )
						{
							entity->flags[INVISIBLE] = true;
						}
						else
						{
							entity->flags[INVISIBLE] = false;
						}
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->skill[11] != entity->flags[INVISIBLE] )
						{
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}
				else
				{
					if ( entity->sprite <= 0 )
					{
						entity->flags[INVISIBLE] = true;
					}
				}
				if ( weaponarm != nullptr )
				{
					my->handleHumanoidWeaponLimb(entity, weaponarm);
				}
				break;
			// shield
			case LIMB_HUMANOID_SHIELD:
				if ( multiplayer != CLIENT )
				{
					if ( myStats->shield == nullptr )
					{
						entity->flags[INVISIBLE] = true;
						entity->sprite = 0;
					}
					else
					{
						entity->flags[INVISIBLE] = false;
						entity->sprite = itemModel(myStats->shield);
					}
					if ( myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()?
					{
						entity->flags[INVISIBLE] = true;
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->skill[11] != entity->flags[INVISIBLE] )
						{
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}
				else
				{
					if ( entity->sprite <= 0 )
					{
						entity->flags[INVISIBLE] = true;
					}
				}
				entity->x -= 2.5 * cos(my->yaw + PI / 2) + .20 * cos(my->yaw);
				entity->y -= 2.5 * sin(my->yaw + PI / 2) + .20 * sin(my->yaw);
				entity->z += 2.5;
				entity->yaw = shieldarm->yaw;
				entity->roll = 0;
				entity->pitch = 0;
				if ( entity->sprite == items[TOOL_TORCH].index )
				{
					entity2 = spawnFlame(entity, SPRITE_FLAME);
					entity2->x += 2 * cos(entity->yaw);
					entity2->y += 2 * sin(entity->yaw);
					entity2->z -= 2;
				}
				else if ( entity->sprite == items[TOOL_CRYSTALSHARD].index )
				{
					entity2 = spawnFlame(entity, SPRITE_CRYSTALFLAME);
					entity2->x += 2 * cos(entity->yaw);
					entity2->y += 2 * sin(entity->yaw);
					entity2->z -= 2;
				}
				else if ( entity->sprite == items[TOOL_LANTERN].index )
				{
					entity->z += 2;
					entity2 = spawnFlame(entity, SPRITE_FLAME);
					entity2->x += 2 * cos(entity->yaw);
					entity2->y += 2 * sin(entity->yaw);
					entity2->z += 1;
				}
				if ( MONSTER_SHIELDYAW > PI / 32 )
				{
					if ( entity->sprite != items[TOOL_TORCH].index && entity->sprite != items[TOOL_LANTERN].index && entity->sprite != items[TOOL_CRYSTALSHARD].index )
					{
						// shield, so rotate a little.
						entity->roll += PI / 64;
					}
					else
					{
						entity->x += 0.25 * cos(my->yaw);
						entity->y += 0.25 * sin(my->yaw);
						entity->pitch += PI / 16;
						if ( entity2 )
						{
							entity2->x += 0.75 * cos(shieldarm->yaw);
							entity2->y += 0.75 * sin(shieldarm->yaw);
						}
					}
				}
				break;
			// cloak
			case LIMB_HUMANOID_CLOAK:
				if ( multiplayer != CLIENT )
				{
					if ( myStats->cloak == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()?
					{
						entity->flags[INVISIBLE] = true;
					}
					else
					{
						entity->flags[INVISIBLE] = false;
						entity->sprite = itemModel(myStats->cloak);
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->skill[11] != entity->flags[INVISIBLE] )
						{
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}
				else
				{
					if ( entity->sprite <= 0 )
					{
						entity->flags[INVISIBLE] = true;
					}
				}
				entity->x -= cos(my->yaw);
				entity->y -= sin(my->yaw);
				entity->yaw += PI / 2;
				break;
			// helm
			case LIMB_HUMANOID_HELMET:
				entity->focalx = limbs[HUMAN][9][0]; // 0
				entity->focaly = limbs[HUMAN][9][1]; // 0
				entity->focalz = limbs[HUMAN][9][2]; // -1.75
				entity->pitch = my->pitch;
				entity->roll = 0;
				if ( multiplayer != CLIENT )
				{
					entity->sprite = itemModel(myStats->helmet);
					if ( myStats->helmet == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()?
					{
						entity->flags[INVISIBLE] = true;
					}
					else
					{
						entity->flags[INVISIBLE] = false;
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->skill[11] != entity->flags[INVISIBLE] )
						{
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}
				else
				{
					if ( entity->sprite <= 0 )
					{
						entity->flags[INVISIBLE] = true;
					}
				}
				my->setHelmetLimbOffset(entity);
				break;
			// mask
			case LIMB_HUMANOID_MASK:
				entity->focalx = limbs[HUMAN][10][0]; // 0
				entity->focaly = limbs[HUMAN][10][1]; // 0
				entity->focalz = limbs[HUMAN][10][2]; // .5
				entity->pitch = my->pitch;
				entity->roll = PI / 2;
				if ( multiplayer != CLIENT )
				{
					if ( myStats->mask == nullptr || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) //TODO: isInvisible()?
					{
						entity->flags[INVISIBLE] = true;
					}
					else
					{
						entity->flags[INVISIBLE] = false;
					}
					if ( myStats->mask != nullptr )
					{
						if ( myStats->mask->type == TOOL_GLASSES )
						{
							entity->sprite = 165; // GlassesWorn.vox
						}
						else
						{
							entity->sprite = itemModel(myStats->mask);
						}
					}
					if ( multiplayer == SERVER )
					{
						// update sprites for clients
						if ( entity->skill[10] != entity->sprite )
						{
							entity->skill[10] = entity->sprite;
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->skill[11] != entity->flags[INVISIBLE] )
						{
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my, bodypart);
						}
						if ( entity->getUID() % (TICKS_PER_SECOND * 10) == ticks % (TICKS_PER_SECOND * 10) )
						{
							serverUpdateEntityBodypart(my, bodypart);
						}
					}
				}
				else
				{
					if ( entity->sprite <= 0 )
					{
						entity->flags[INVISIBLE] = true;
					}
				}

				if ( entity->sprite != 165 )
				{
					entity->focalx = limbs[HUMAN][10][0] + .35; // .35
					entity->focaly = limbs[HUMAN][10][1] - 2; // -2
					entity->focalz = limbs[HUMAN][10][2]; // .5
				}
				else
				{
					entity->focalx = limbs[HUMAN][10][0] + .25; // .25
					entity->focaly = limbs[HUMAN][10][1] - 2.25; // -2.25
					entity->focalz = limbs[HUMAN][10][2]; // .5
				}
				break;
		}
	}
	// rotate shield a bit
	node_t* shieldNode = list_Node(&my->children, LIMB_HUMANOID_SHIELD);
	if ( shieldNode )
	{
		Entity* shieldEntity = (Entity*)shieldNode->element;
		if ( shieldEntity->sprite != items[TOOL_TORCH].index && shieldEntity->sprite != items[TOOL_LANTERN].index && shieldEntity->sprite != items[TOOL_CRYSTALSHARD].index )
		{
			shieldEntity->yaw -= PI / 6;
		}
	}
	if ( MONSTER_ATTACK > 0 && MONSTER_ATTACK <= MONSTER_POSE_MAGIC_CAST3 )
	{
		MONSTER_ATTACKTIME++;
	}
	else if ( MONSTER_ATTACK == 0 )
	{
		MONSTER_ATTACKTIME = 0;
	}
	else
	{
		// do nothing, don't reset attacktime or increment it.
	}
}
Пример #2
0
void skeletonMoveBodyparts(Entity *my, stat_t *myStats, double dist) {
	node_t *node;
	Entity *entity = NULL, *entity2 = NULL;
	Entity *rightbody = NULL;
	Entity *weaponarm=NULL;
	int bodypart;
	bool wearingring=FALSE;
	
	// set invisibility
	if( multiplayer != CLIENT ) {
		if( myStats->ring != NULL )
			if( myStats->ring->type == RING_INVISIBILITY )
				wearingring = TRUE;
		if( myStats->cloak != NULL )
			if( myStats->cloak->type == CLOAK_INVISIBILITY )
				wearingring = TRUE;
		if( myStats->EFFECTS[EFF_INVISIBLE] == TRUE || wearingring==TRUE ) {
			my->flags[INVISIBLE] = TRUE;
			my->flags[BLOCKSIGHT] = FALSE;
			bodypart=0;
			for(node = my->children.first; node!=NULL; node=node->next) {
				if( bodypart<2 ) {
					bodypart++;
					continue;
				}
				if( bodypart>=7 ) {
					break;
				}
				entity = (Entity *)node->element;
				if( !entity->flags[INVISIBLE] ) {
					entity->flags[INVISIBLE] = TRUE;
					serverUpdateEntityBodypart(my,bodypart);
				}
				bodypart++;
			}
		} else {
			my->flags[INVISIBLE] = FALSE;
			my->flags[BLOCKSIGHT] = TRUE;
			bodypart=0;
			for(node = my->children.first; node!=NULL; node=node->next) {
				if( bodypart<2 ) {
					bodypart++;
					continue;
				}
				if( bodypart>=7 ) {
					break;
				}
				entity = (Entity *)node->element;
				if( entity->flags[INVISIBLE] ) {
					entity->flags[INVISIBLE] = FALSE;
					serverUpdateEntityBodypart(my,bodypart);
				}
				bodypart++;
			}
		}

		// sleeping
		if( myStats->EFFECTS[EFF_ASLEEP] ) {
			my->z = 2;
			my->pitch = PI/4;
		} else {
			my->z = -.5;
			my->pitch = 0;
		}
	}

	//Move bodyparts
	for(bodypart=0, node = my->children.first; node!=NULL; node=node->next, bodypart++) {
		if( bodypart<2 ) {
			continue;
		}
		entity = (Entity *)node->element;
		entity->x = my->x;
		entity->y = my->y;
		entity->z = my->z;
		entity->yaw = my->yaw;
		if( bodypart==3||bodypart==6 ) {
			if( bodypart==3 )
				rightbody = (Entity *)node->next->element;
			node_t *shieldNode = list_Node(&my->children,7);
			if( shieldNode ) {
				Entity *shield = (Entity *)shieldNode->element;
				if( dist>0.1 && (bodypart!=6||shield->flags[INVISIBLE]) ) {
					if( !rightbody->skill[0] ) {
						entity->pitch -= dist*SKELETONWALKSPEED;
						if( entity->pitch < -PI/4.0 ) {
							entity->pitch = -PI/4.0;
							if(bodypart==3) {
								entity->skill[0]=1;
								if( dist>.1 )
									playSoundEntityLocal(my,95,32);
							}
						}
					} else {
						entity->pitch += dist*SKELETONWALKSPEED;
						if( entity->pitch > PI/4.0 ) {
							entity->pitch = PI/4.0;
							if(bodypart==3) {
								entity->skill[0]=0;
								if( dist>.1 )
									playSoundEntityLocal(my,95,32);
							}
						}
					}
				} else {
					if( entity->pitch < 0 ) {
						entity->pitch += 1/fmax(dist*.1,10.0);
						if( entity->pitch > 0 )
							entity->pitch=0;
					} else if( entity->pitch > 0 ) {
						entity->pitch -= 1/fmax(dist*.1,10.0);
						if( entity->pitch < 0 )
							entity->pitch=0;
					}
				}
			}
		} else if( bodypart==4||bodypart==5||bodypart==9 ) {
			if( bodypart==5 ) {
				weaponarm = entity;
				if( MONSTER_ATTACK == 1 ) {
					// vertical chop
					if( MONSTER_ATTACKTIME == 0 ) {
						MONSTER_ARMBENDED = 0;
						MONSTER_WEAPONYAW = 0;
						entity->pitch = -3*PI/4;
						entity->roll = 0;
					} else {
						if( entity->pitch >= -PI/2 )
							MONSTER_ARMBENDED = 1;
						if( entity->pitch >= PI/4 ) {
							entity->skill[0] = rightbody->skill[0];
							MONSTER_WEAPONYAW = 0;
							entity->pitch = rightbody->pitch;
							entity->roll = 0;
							MONSTER_ARMBENDED = 0;
							MONSTER_ATTACK = 0;
						} else {
							entity->pitch += .25;
						}
					}
				} else if( MONSTER_ATTACK == 2 ) {
					// horizontal chop
					if( MONSTER_ATTACKTIME == 0 ) {
						MONSTER_ARMBENDED = 1;
						MONSTER_WEAPONYAW = -3*PI/4;
						entity->pitch = 0;
						entity->roll = -PI/2;
					} else {
						if( MONSTER_WEAPONYAW >= PI/8 ) {
							entity->skill[0] = rightbody->skill[0];
							MONSTER_WEAPONYAW = 0;
							entity->pitch = rightbody->pitch;
							entity->roll = 0;
							MONSTER_ARMBENDED = 0;
							MONSTER_ATTACK = 0;
						} else {
							MONSTER_WEAPONYAW += .25;
						}
					}
				} else if( MONSTER_ATTACK == 3 ) {
					// stab
					if( MONSTER_ATTACKTIME == 0 ) {
						MONSTER_ARMBENDED = 0;
						MONSTER_WEAPONYAW = 0;
						entity->pitch = 2*PI/3;
						entity->roll = 0;
					} else {
						if( MONSTER_ATTACKTIME >= 5 ) {
							MONSTER_ARMBENDED = 1;
							entity->pitch = -PI/6;
						}
						if( MONSTER_ATTACKTIME >= 10 ) {
							entity->skill[0] = rightbody->skill[0];
							MONSTER_WEAPONYAW = 0;
							entity->pitch = rightbody->pitch;
							entity->roll = 0;
							MONSTER_ARMBENDED = 0;
							MONSTER_ATTACK = 0;
						}
					}
				}
			} else if( bodypart==9 ) {
				entity->pitch=entity->fskill[0];
			}
			
			if( bodypart!=5 || (MONSTER_ATTACK==0 && MONSTER_ATTACKTIME==0) ) {
				if( dist>0.1 ) {
					if( entity->skill[0] ) {
						entity->pitch -= dist*SKELETONWALKSPEED;
						if( entity->pitch < -PI/4.0 ) {
							entity->skill[0]=0;
							entity->pitch = -PI/4.0;
						}
					} else {
						entity->pitch += dist*SKELETONWALKSPEED;
						if( entity->pitch > PI/4.0 ) {
							entity->skill[0]=1;
							entity->pitch = PI/4.0;
						}
					}
				} else {
					if( entity->pitch < 0 ) {
						entity->pitch += 1/fmax(dist*.1,10.0);
						if( entity->pitch > 0 )
							entity->pitch=0;
					} else if( entity->pitch > 0 ) {
						entity->pitch -= 1/fmax(dist*.1,10.0);
						if( entity->pitch < 0 )
							entity->pitch=0;
					}
				}
			}
			if( bodypart==9 ) {
				entity->fskill[0]=entity->pitch;
				entity->roll=my->roll-fabs(entity->pitch)/2;
				entity->pitch=0;
			}
		}
		switch( bodypart ) {
			// torso
			case 2:
				if( multiplayer!=CLIENT ) {
					if( myStats->breastplate == NULL ) {
						entity->sprite = 230;
					} else {
						entity->sprite = itemModel(myStats->breastplate);
					}
					if( multiplayer==SERVER ) {
						// update sprites for clients
						if( entity->skill[10]!=entity->sprite ) {
							entity->skill[10]=entity->sprite;
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) {
							serverUpdateEntityBodypart(my,bodypart);
						}
					}
				}
				entity->x-=.25*cos(my->yaw);
				entity->y-=.25*sin(my->yaw);
				entity->z+=2;
				break;
			// right leg
			case 3:
				entity->sprite = 236;
				entity->x+=1*cos(my->yaw+PI/2)+.25*cos(my->yaw);
				entity->y+=1*sin(my->yaw+PI/2)+.25*sin(my->yaw);
				entity->z+=4;
				if( my->z >= 1.9 && my->z <= 2.1 ) {
					entity->yaw += PI/8;
					entity->pitch = -PI/2;
				}
				break;
			// left leg
			case 4:
				entity->sprite = 235;
				entity->x-=1*cos(my->yaw+PI/2)-.25*cos(my->yaw);
				entity->y-=1*sin(my->yaw+PI/2)-.25*sin(my->yaw);
				entity->z+=4;
				if( my->z >= 1.9 && my->z <= 2.1 ) {
					entity->yaw -= PI/8;
					entity->pitch = -PI/2;
				}
				break;
			// right arm
			case 5: {
				entity->sprite = 233;
				node_t *weaponNode = list_Node(&my->children,7);
				if( weaponNode ) {
					Entity *weapon = (Entity *)weaponNode->element;
					if( !MONSTER_ARMBENDED )
						entity->sprite += (weapon->flags[INVISIBLE]!=TRUE);
					if( weapon->flags[INVISIBLE] || MONSTER_ARMBENDED ) {
						entity->focalx = limbs[SKELETON][4][0]; // 0
						entity->focaly = limbs[SKELETON][4][1]; // 0
						entity->focalz = limbs[SKELETON][4][2]; // 2
					} else {
						entity->focalx = limbs[SKELETON][4][0] + 1; // 1
						entity->focaly = limbs[SKELETON][4][1]; // 0
						entity->focalz = limbs[SKELETON][4][2] - 1; // 1
					}
				}
				entity->x+=1.75*cos(my->yaw+PI/2)-.20*cos(my->yaw);
				entity->y+=1.75*sin(my->yaw+PI/2)-.20*sin(my->yaw);
				entity->z+=.5;
				entity->yaw += MONSTER_WEAPONYAW;
				if( my->z >= 1.9 && my->z <= 2.1 ) {
					entity->pitch = 0;
				}
				break;
			// left arm
			}
			case 6: {
				entity->sprite = 231;
				node_t *shieldNode = list_Node(&my->children,8);
				if( shieldNode ) {
					Entity *shield = (Entity *)shieldNode->element;
					entity->sprite += (shield->flags[INVISIBLE]!=TRUE);
					if( shield->flags[INVISIBLE] ) {
						entity->focalx = limbs[SKELETON][5][0]; // 0
						entity->focaly = limbs[SKELETON][5][1]; // 0
						entity->focalz = limbs[SKELETON][5][2]; // 2
					} else {
						entity->focalx = limbs[SKELETON][5][0] + 1; // 1
						entity->focaly = limbs[SKELETON][5][1]; // 0
						entity->focalz = limbs[SKELETON][5][2] - 1; // 1
					}
				}
				entity->x-=1.75*cos(my->yaw+PI/2)+.20*cos(my->yaw);
				entity->y-=1.75*sin(my->yaw+PI/2)+.20*sin(my->yaw);
				entity->z+=.5;
				if( my->z >= 1.9 && my->z <= 2.1 ) {
					entity->pitch = 0;
				}
				break;
			}
			// weapon
			case 7:
				if( multiplayer!=CLIENT ) {
					if( myStats->weapon == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) {
						entity->flags[INVISIBLE]=TRUE;
					} else {
						entity->sprite = itemModel(myStats->weapon);
						if( itemCategory(myStats->weapon) == SPELLBOOK )
							entity->flags[INVISIBLE]=TRUE;
						else
							entity->flags[INVISIBLE]=FALSE;
					}
					if( multiplayer==SERVER ) {
						// update sprites for clients
						if( entity->skill[10]!=entity->sprite ) {
							entity->skill[10]=entity->sprite;
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->skill[11] != entity->flags[INVISIBLE] ) {
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) {
							serverUpdateEntityBodypart(my,bodypart);
						}
					}
				}
				if( weaponarm != NULL ) {
					if( entity->flags[INVISIBLE] != TRUE ) {
						if( entity->sprite == items[SHORTBOW].index ) {
							entity->x=weaponarm->x-.5*cos(weaponarm->yaw);
							entity->y=weaponarm->y-.5*sin(weaponarm->yaw);
							entity->z=weaponarm->z+1;
							entity->pitch=weaponarm->pitch+.25;
						} else if( entity->sprite == items[ARTIFACT_BOW].index ) {
							entity->x=weaponarm->x-1.5*cos(weaponarm->yaw);
							entity->y=weaponarm->y-1.5*sin(weaponarm->yaw);
							entity->z=weaponarm->z+2;
							entity->pitch=weaponarm->pitch+.25;
						} else if( entity->sprite == items[CROSSBOW].index ) {
							entity->x=weaponarm->x;
							entity->y=weaponarm->y;
							entity->z=weaponarm->z+1;
							entity->pitch=weaponarm->pitch;
						} else {
							entity->x=weaponarm->x+.5*cos(weaponarm->yaw)*(MONSTER_ATTACK==0);
							entity->y=weaponarm->y+.5*sin(weaponarm->yaw)*(MONSTER_ATTACK==0);
							entity->z=weaponarm->z-.5*(MONSTER_ATTACK==0);
							entity->pitch=weaponarm->pitch+.25*(MONSTER_ATTACK==0);
						}
					}
					entity->yaw=weaponarm->yaw;
					entity->roll=weaponarm->roll;
					if( !MONSTER_ARMBENDED ) {
						entity->focalx = limbs[SKELETON][6][0]; // 2.5
						if( entity->sprite == items[CROSSBOW].index )
							entity->focalx += 2;
						entity->focaly = limbs[SKELETON][6][1]; // 0
						entity->focalz = limbs[SKELETON][6][2]; // -.5
					} else {
						entity->focalx = limbs[SKELETON][6][0] + 1; // 3.5
						entity->focaly = limbs[SKELETON][6][1]; // 0
						entity->focalz = limbs[SKELETON][6][2] - 2; // -2.5
						entity->yaw -= sin(weaponarm->roll)*PI/2;
						entity->pitch += cos(weaponarm->roll)*PI/2;
					}
				}
				break;
			// shield
			case 8:
				if( multiplayer!=CLIENT ) {
					if( myStats->shield == NULL ) {
						entity->flags[INVISIBLE]=TRUE;
						entity->sprite = 0;
					} else {
						entity->flags[INVISIBLE]=FALSE;
						entity->sprite = itemModel(myStats->shield);
					}
					if( myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) {
						entity->flags[INVISIBLE]=TRUE;
					}
					if( multiplayer==SERVER ) {
						// update sprites for clients
						if( entity->skill[10]!=entity->sprite ) {
							entity->skill[10]=entity->sprite;
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->skill[11] != entity->flags[INVISIBLE] ) {
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) {
							serverUpdateEntityBodypart(my,bodypart);
						}
					}
				}
				entity->x-=2.5*cos(my->yaw+PI/2)+.20*cos(my->yaw);
				entity->y-=2.5*sin(my->yaw+PI/2)+.20*sin(my->yaw);
				entity->z+=2.5;
				if( entity->sprite == items[TOOL_TORCH].index ) {
					entity2 = spawnFlame(entity);
					entity2->x += 2*cos(my->yaw);
					entity2->y += 2*sin(my->yaw);
					entity2->z -= 2;
				} else if( entity->sprite == items[TOOL_LANTERN].index ) {
					entity->z += 2;
					entity2 = spawnFlame(entity);
					entity2->x += 2*cos(my->yaw);
					entity2->y += 2*sin(my->yaw);
					entity2->z += 1;
				}
				break;
			// cloak
			case 9:
				if( multiplayer!=CLIENT ) {
					if( myStats->cloak == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) {
						entity->flags[INVISIBLE]=TRUE;
					} else {
						entity->flags[INVISIBLE]=FALSE;
						entity->sprite = itemModel(myStats->cloak);
					}
					if( multiplayer==SERVER ) {
						// update sprites for clients
						if( entity->skill[10]!=entity->sprite ) {
							entity->skill[10]=entity->sprite;
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->skill[11] != entity->flags[INVISIBLE] ) {
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) {
							serverUpdateEntityBodypart(my,bodypart);
						}
					}
				}
				entity->x-=cos(my->yaw);
				entity->y-=sin(my->yaw);
				entity->yaw+=PI/2;
				break;
			// helm
			case 10:
				entity->focalx = limbs[SKELETON][9][0]; // 0
				entity->focaly = limbs[SKELETON][9][1]; // 0
				entity->focalz = limbs[SKELETON][9][2]; // -2
				entity->pitch = my->pitch;
				entity->roll = 0;
				if( multiplayer!=CLIENT ) {
					entity->sprite = itemModel(myStats->helmet);
					if( myStats->helmet == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) {
						entity->flags[INVISIBLE]=TRUE;
					} else {
						entity->flags[INVISIBLE]=FALSE;
					}
					if( multiplayer==SERVER ) {
						// update sprites for clients
						if( entity->skill[10]!=entity->sprite ) {
							entity->skill[10]=entity->sprite;
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->skill[11] != entity->flags[INVISIBLE] ) {
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) {
							serverUpdateEntityBodypart(my,bodypart);
						}
					}
				}
				if( entity->sprite != items[STEEL_HELM].index ) {
					if( entity->sprite == items[HAT_PHRYGIAN].index ) {
						entity->focalx = limbs[SKELETON][9][0] - .5; // -.5
						entity->focaly = limbs[SKELETON][9][1] - 3.25; // -3.25
						entity->focalz = limbs[SKELETON][9][2] + 2.5; // .5
						entity->roll=PI/2;
					} else if( entity->sprite >= items[HAT_HOOD].index && entity->sprite < items[HAT_HOOD].index+items[HAT_HOOD].variations ) {
						entity->focalx = limbs[SKELETON][9][0] - .5; // -.5
						entity->focaly = limbs[SKELETON][9][1] - 2.5; // -2.5
						entity->focalz = limbs[SKELETON][9][2] + 2.5; // 2.5
						entity->roll=PI/2;
					} else if( entity->sprite == items[HAT_WIZARD].index ) {
						entity->focalx = limbs[SKELETON][9][0]; // 0
						entity->focaly = limbs[SKELETON][9][1] - 4.75; // -4.75
						entity->focalz = limbs[SKELETON][9][2] + .5; // .5
						entity->roll=PI/2;
					} else if( entity->sprite == items[HAT_JESTER].index ) {
						entity->focalx = limbs[SKELETON][9][0]; // 0
						entity->focaly = limbs[SKELETON][9][1] - 4.75; // -4.75
						entity->focalz = limbs[SKELETON][9][2] + .5; // .5
						entity->roll=PI/2;
					}
				} else {
					my->flags[INVISIBLE]=TRUE;
				}
				break;
			// mask
			case 11:
				entity->focalx = limbs[SKELETON][10][0]; // 0
				entity->focaly = limbs[SKELETON][10][1]; // 0
				entity->focalz = limbs[SKELETON][10][2]; // .5
				entity->pitch = my->pitch;
				entity->roll=PI/2;
				if( multiplayer!=CLIENT ) {
					if( myStats->mask == NULL || myStats->EFFECTS[EFF_INVISIBLE] || wearingring ) {
						entity->flags[INVISIBLE]=TRUE;
					} else {
						entity->flags[INVISIBLE]=FALSE;
					}
					if( myStats->mask != NULL ) {
						if( myStats->mask->type == TOOL_GLASSES ) {
							entity->sprite = 165; // GlassesWorn.vox
						} else {
							entity->sprite = itemModel(myStats->mask);
						}
					}
					if( multiplayer==SERVER ) {
						// update sprites for clients
						if( entity->skill[10]!=entity->sprite ) {
							entity->skill[10]=entity->sprite;
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->skill[11] != entity->flags[INVISIBLE] ) {
							entity->skill[11] = entity->flags[INVISIBLE];
							serverUpdateEntityBodypart(my,bodypart);
						}
						if( entity->uid%(TICKS_PER_SECOND*10) == ticks%(TICKS_PER_SECOND*10) ) {
							serverUpdateEntityBodypart(my,bodypart);
						}
					}
				}
				if( entity->sprite != 165 ) {
					entity->focalx = limbs[SKELETON][10][0] + .35; // .35
					entity->focaly = limbs[SKELETON][10][1] - 2; // -2
					entity->focalz = limbs[SKELETON][10][2]; // .5
				} else {
					entity->focalx = limbs[SKELETON][10][0] + .25; // .25
					entity->focaly = limbs[SKELETON][10][1] - 2.25; // -2.25
					entity->focalz = limbs[SKELETON][10][2]; // .5
				}
				break;
		}
	}
	if( MONSTER_ATTACK != 0 )
		MONSTER_ATTACKTIME++;
	else
		MONSTER_ATTACKTIME=0;
}
Пример #3
0
void actCampfire(Entity *my) {
	Entity *entity;
	int i;
	
	// init
	if( !CAMPFIRE_INIT ) {
		CAMPFIRE_INIT = 1;
		CAMPFIRE_HEALTH = MAXPLAYERS;
	}
		
	// crackling sounds
	if( CAMPFIRE_HEALTH>0 ) {
		CAMPFIRE_SOUNDTIME--;
		if( CAMPFIRE_SOUNDTIME <= 0 ) {
			CAMPFIRE_SOUNDTIME = 480;
			playSoundEntityLocal( my, 133, 128 );
		}
	
		// spew flame particles
		for( i=0; i<3; i++ ) {
			entity = spawnFlame(my);
			entity->x += ((rand()%30)-10)/10.f;
			entity->y += ((rand()%30)-10)/10.f;
			entity->z -= 1;
		}
		entity = spawnFlame(my);
		entity->z -= 2;
	
		// light environment
		if( !CAMPFIRE_LIGHTING ) {
			my->light = lightSphereShadow(my->x/16, my->y/16, 6, 160);
			CAMPFIRE_LIGHTING=1;
		}
		CAMPFIRE_FLICKER--;
		if(CAMPFIRE_FLICKER<=0) {
			CAMPFIRE_LIGHTING=(CAMPFIRE_LIGHTING==1)+1;
		
			if(CAMPFIRE_LIGHTING==1) {
				if( my->light != NULL )
					list_RemoveNode(my->light->node);
				my->light = lightSphereShadow(my->x/16, my->y/16, 6, 160);
			}
			else {
				if( my->light != NULL )
					list_RemoveNode(my->light->node);
				my->light = lightSphereShadow(my->x/16, my->y/16, 6, 152);
			}
			CAMPFIRE_FLICKER=2+rand()%7;
		}
	} else {
		if( my->light )
			if( my->light->node )
				list_RemoveNode(my->light->node);
		my->light = NULL;
		my->flags[BRIGHT] = FALSE;
	}

	if( multiplayer != CLIENT ) {
		// using campfire
		for(i=0;i<MAXPLAYERS;i++) {
			if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
				if(inrange[i]) {
					if( CAMPFIRE_HEALTH>0 ) {
						messagePlayer(i,language[457]);
						CAMPFIRE_HEALTH--;
						if( CAMPFIRE_HEALTH<=0 ) {
							serverUpdateEntitySkill(my,3); // extinguish for all clients
							messagePlayer(i,language[458]);
							if( my->light )
								if( my->light->node )
									list_RemoveNode(my->light->node);
							my->light = NULL;
						}
						Item *item = newItem(TOOL_TORCH,WORN,0,1,0,TRUE,NULL);
						itemPickup(i,item);
						free(item);
					} else {
						messagePlayer(i,language[458]);
					}
				}
			}
		}
	}
}