Beispiel #1
0
void actSkeletonLimb(Entity *my) {
	int i;
	
	Entity *parent = NULL;
	if( (parent=uidToEntity(my->skill[2]))==NULL ) {
		list_RemoveNode(my->mynode);
		return;
	}
	
	if( my->light != NULL ) {
		list_RemoveNode(my->light->node);
		my->light = NULL;
	}
	
	if( multiplayer!=CLIENT ) {
		for( i=0; i<MAXPLAYERS; i++ ) {
			if( inrange[i] ) {
				if( i==0 && selectedEntity==my ) {
					parent->skill[13] = i+1;
				}
				else if( client_selected[i]==my ) {
					parent->skill[13] = i+1;
				}
			}
		}
	}

	int torch = 0;
	if( my->flags[INVISIBLE] == FALSE ) {
		if( my->sprite == 93 ) { // torch
			torch = 6;
		} else if( my->sprite == 94 ) { // lantern
			torch = 9;
		}
	}
	if( torch != 0 ) {
		my->light = lightSphereShadow(my->x/16,my->y/16,torch,50+15*torch);
	}
}
Beispiel #2
0
void actWinningPortal(Entity *my) {
	int playercount=0;
	double dist;
	int i, c;

	if( multiplayer!=CLIENT ) {
		if( my->flags[INVISIBLE] ) {
			node_t *node;
			for( node=map.entities->first; node!=NULL; node=node->next ) {
				Entity *entity = (Entity *)node->element;
				if( entity->behavior==&actMonster ) {
					Stat *stats = entity->getStats();
					if( stats ) {
						if( stats->type == LICH || stats->type == DEVIL ) {
							return;
						}
					}
				}
			}
			my->flags[INVISIBLE] = FALSE;
		}
	} else {
		if( my->flags[INVISIBLE] )
			return;
	}
	
	if( !PORTAL_INIT ) {
		PORTAL_INIT=1;
		my->light = lightSphereShadow(my->x/16,my->y/16,3,255);
	}

	PORTAL_AMBIENCE--;
	if( PORTAL_AMBIENCE<=0 ) {
		PORTAL_AMBIENCE = TICKS_PER_SECOND*2;
		playSoundEntityLocal( my, 154, 128 );
	}

	my->yaw += 0.01; // rotate slowly on my axis
	my->sprite = 278+(my->ticks/20)%4; // animate

	if( multiplayer==CLIENT )
		return;

	// step through portal
	for(i=0;i<MAXPLAYERS;i++) {
		if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
			if(inrange[i]) {
				for( c=0; c<MAXPLAYERS; c++ ) {
					if( client_disconnected[c] || players[c] == NULL )
						continue;
					else
						playercount++;
					dist = sqrt( pow(my->x-players[c]->x,2) + pow(my->y-players[c]->y,2) );
					if( dist > TOUCHRANGE ) {
						messagePlayer(i,language[509]);
						return;
					}
				}
				victory = PORTAL_VICTORYTYPE;
				if( multiplayer==SERVER ) {
					for( c=0; c<MAXPLAYERS; c++ ) {
						if( client_disconnected[c]==TRUE )
							continue;
						strcpy((char *)net_packet->data,"WING");
						net_packet->data[4] = victory;
						net_packet->address.host = net_clients[c-1].host;
						net_packet->address.port = net_clients[c-1].port;
						net_packet->len = 8;
						sendPacketSafe(net_sock, -1, net_packet, c-1);
					}
				}
				subwindow=0;
				introstage=5; // prepares win game sequence
				fadeout=TRUE;
				if( !intro )
					pauseGame(2,FALSE);
				return;
			}
		}
	}
}
Beispiel #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]);
					}
				}
			}
		}
	}
}
Beispiel #4
0
void actPortal(Entity *my) {
	int playercount=0;
	double dist;
	int i, c;
	
	if( !PORTAL_INIT ) {
		PORTAL_INIT=1;
		my->light = lightSphereShadow(my->x/16,my->y/16,3,255);
	}

	PORTAL_AMBIENCE--;
	if( PORTAL_AMBIENCE<=0 ) {
		PORTAL_AMBIENCE = TICKS_PER_SECOND*2;
		playSoundEntityLocal( my, 154, 128 );
	}

	my->yaw += 0.01; // rotate slowly on my axis
	my->sprite = 254+(my->ticks/20)%4; // animate

	if( multiplayer==CLIENT )
		return;

	// step through portal
	for(i=0;i<MAXPLAYERS;i++) {
		if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
			if(inrange[i]) {
				for( c=0; c<MAXPLAYERS; c++ ) {
					if( client_disconnected[c] || players[c] == NULL )
						continue;
					else
						playercount++;
					dist = sqrt( pow(my->x-players[c]->x,2) + pow(my->y-players[c]->y,2) );
					if( dist > TOUCHRANGE ) {
						messagePlayer(i,language[505]);
						return;
					}
				}
				if( playercount==1 )
					messagePlayer(i,language[510]);
				else
					messagePlayer(i,language[511]);
				loadnextlevel=TRUE;
				if( secretlevel ) {
					switch( currentlevel ) {
						case 9: {
							;
							bool visiblegrave=FALSE;
							node_t *node;
							for( node=map.entities->first; node!=NULL; node=node->next ) {
								Entity *entity = (Entity *)node->element;
								if( entity->sprite==224 && !entity->flags[INVISIBLE] ) {
									visiblegrave=TRUE;
									break;
								}
							}
							if( visiblegrave )
								for( c=0; c<MAXPLAYERS; c++ )
									steamAchievementClient(c,"BARONY_ACH_ROBBING_THE_CRADLE");
							break;
						}
						case 14:
							for( c=0; c<MAXPLAYERS; c++ )
								steamAchievementClient(c,"BARONY_ACH_THESEUS_LEGACY");
							break;
					}
				}
				if( !PORTAL_NOTSECRET )
					secretlevel = (secretlevel==FALSE); // toggle level lists
				return;
			}
		}
	}
}
Beispiel #5
0
void actItem(Entity* my)
{
	Item* item;
	int i;

	if ( multiplayer == CLIENT )
	{
		my->flags[NOUPDATE] = true;
		if ( ITEM_LIFE == 0 )
		{
			Entity* tempEntity = uidToEntity(clientplayer);
			if ( tempEntity )
			{
				if ( entityInsideEntity(my, tempEntity) )
				{
					my->parent = tempEntity->getUID();
				}
				else
				{
					node_t* node;
					for ( node = map.creatures->first; node != nullptr; node = node->next )
					{
						Entity* entity = (Entity*)node->element;
						if ( entity->behavior == &actPlayer || entity->behavior == &actMonster )
						{
							if ( entityInsideEntity(my, entity) )
							{
								my->parent = entity->getUID();
								break;
							}
						}
					}
				}
			}
			else
			{
				node_t* node;
				for ( node = map.creatures->first; node != nullptr; node = node->next )
				{
					Entity* entity = (Entity*)node->element;
					if ( entity->behavior == &actPlayer || entity->behavior == &actMonster )
					{
						if ( entityInsideEntity(my, entity) )
						{
							my->parent = entity->getUID();
							break;
						}
					}
				}
			}
		}

		// request entity update (check if I've been deleted)
		if ( ticks % (TICKS_PER_SECOND * 5) == my->getUID() % (TICKS_PER_SECOND * 5) )
		{
			strcpy((char*)net_packet->data, "ENTE");
			net_packet->data[4] = clientnum;
			SDLNet_Write32(my->getUID(), &net_packet->data[5]);
			net_packet->address.host = net_server.host;
			net_packet->address.port = net_server.port;
			net_packet->len = 9;
			sendPacketSafe(net_sock, -1, net_packet, 0);
		}
	}
	else
	{
		// select appropriate model
		my->skill[2] = -5;
		if ( my->itemSokobanReward != 1 )
		{
			my->flags[INVISIBLE] = false;
		}
		item = newItemFromEntity(my);
		my->sprite = itemModel(item);
		free(item);
	}
	//if( ITEM_LIFE==0 )
	//	playSoundEntityLocal( my, 149, 64 );
	ITEM_LIFE++;
	/*ITEM_AMBIENCE++;
	if( ITEM_AMBIENCE>=TICKS_PER_SECOND*30 ) {
		ITEM_AMBIENCE=0;
		playSoundEntityLocal( my, 149, 64 );
	}*/

	// pick up item
	if (multiplayer != CLIENT)
	{
		if ( my->isInteractWithMonster() )
		{
			Entity* monsterInteracting = uidToEntity(my->interactedByMonster);
			if ( monsterInteracting )
			{
				if ( my->skill[10] >= 0 && my->skill[10] < NUMITEMS )
				{
					if ( items[my->skill[10]].category == Category::FOOD && monsterInteracting->getMonsterTypeFromSprite() != SLIME )
					{
						monsterInteracting->monsterConsumeFoodEntity(my, monsterInteracting->getStats());
					}
					else
					{
						monsterInteracting->monsterAddNearbyItemToInventory(monsterInteracting->getStats(), 24, 9, my);
					}
				}
				my->clearMonsterInteract();
				return;
			}
			my->clearMonsterInteract();
		}
		for ( i = 0; i < MAXPLAYERS; i++)
		{
			if ((i == 0 && selectedEntity == my) || (client_selected[i] == my))
			{
				if (inrange[i])
				{
					if (players[i] != nullptr && players[i]->entity != nullptr)
					{
						playSoundEntity( players[i]->entity, 35 + rand() % 3, 64 );
					}
					Item* item2 = newItemFromEntity(my);
					if ( players[i] && players[i]->entity )
					{
						if ( my->itemStolen == 1 && item2 && (static_cast<Uint32>(item2->ownerUid) == players[i]->entity->getUID()) )
						{
							steamAchievementClient(i, "BARONY_ACH_REPOSSESSION");
						}
					}
					//messagePlayer(i, "old owner: %d", item2->ownerUid);
					if (item2)
					{
						item = itemPickup(i, item2);
						if (item)
						{
							if (i == 0)
							{
								free(item2);
							}
							int oldcount = item->count;
							item->count = 1;
							messagePlayer(i, language[504], item->description());
							item->count = oldcount;
							if (i != 0)
							{
								free(item);
							}
							my->removeLightField();
							list_RemoveNode(my->mynode);
							return;
						}
					}
				}
			}
		}
	}

	if ( my->itemNotMoving )
	{
		switch ( my->sprite )
		{
			case 610:
			case 611:
			case 612:
			case 613:
				my->spawnAmbientParticles(80, my->sprite - 4, 10 + rand() % 40, 1.0, false);
				if ( !my->light )
				{
					my->light = lightSphereShadow(my->x / 16, my->y / 16, 3, 192);
				}
				break;
			default:
				break;
		}
		if ( multiplayer == CLIENT )
		{
			// let the client process some more gravity and make sure it isn't stopping early at an awkward angle.
			if ( my->itemNotMovingClient == 1 )
			{
				return;
			}
		}
		else
		{
			return;
		}
	}

	// gravity
	bool onground = false;
	if ( my->z < 7.5 - models[my->sprite]->sizey * .25 )
	{
		// fall
		// chakram and shuriken lie flat, needs to use sprites for client
		if ( my->sprite == 567 || my->sprite == 569 )
		{
			// todo: adjust falling rates for thrown items if need be
			ITEM_VELZ += 0.04;
			my->z += ITEM_VELZ;
			my->roll += 0.08;
		}
		else
		{
			ITEM_VELZ += 0.04;
			my->z += ITEM_VELZ;
			my->roll += 0.04;
		}
	}
	else
	{
		if ( my->x >= 0 && my->y >= 0 && my->x < map.width << 4 && my->y < map.height << 4 )
		{
			if ( map.tiles[(int)(my->y / 16)*MAPLAYERS + (int)(my->x / 16)*MAPLAYERS * map.height] 
				|| (my->sprite >= 610 && my->sprite <= 613) )
			{
				// land
				ITEM_VELZ *= -.7;
				if ( ITEM_VELZ > -.35 )
				{
					// chakram and shuriken lie flat, needs to use sprites for client
					if ( my->sprite == 567 || my->sprite == 569 )
					{
						my->roll = PI;
						my->pitch = 0;
						if ( my->sprite == 569 )
						{
							my->z = 8.5 - models[my->sprite]->sizey * .25;
						}
						else
						{
							my->z = 8.75 - models[my->sprite]->sizey * .25;
						}
					}
					else
					{
						my->roll = PI / 2.0;
						my->z = 7.5 - models[my->sprite]->sizey * .25;
					}
					ITEM_VELZ = 0;
					onground = true;
				}
				else
				{
					onground = true;
					my->z = 7.5 - models[my->sprite]->sizey * .25 - .0001;
				}
			}
			else
			{
				// fall
				ITEM_VELZ += 0.04;
				my->z += ITEM_VELZ;
				my->roll += 0.04;
			}
		}
		else
		{
			// fall
			ITEM_VELZ += 0.04;
			my->z += ITEM_VELZ;
			my->roll += 0.04;
		}
	}

	// falling out of the map
	if ( my->z > 128 )
	{
		if ( ITEM_TYPE == ARTIFACT_MACE && my->parent != 0 )
		{
			steamAchievementEntity(uidToEntity(my->parent), "BARONY_ACH_STFU");
		}
		list_RemoveNode(my->mynode);
		return;
	}

	// don't perform unneeded computations on items that have basically no velocity
	double groundheight;
	if ( my->sprite == 569 )
	{
		groundheight = 8.5 - models[my->sprite]->sizey * .25;
	}
	else if ( my->sprite == 567 )
	{
		groundheight = 8.75 - models[my->sprite]->sizey * .25;
	}
	else
	{
		groundheight = 7.5 - models[my->sprite]->sizey * .25;
	}

	if ( onground && my->z > groundheight - .0001 && my->z < groundheight + .0001 && fabs(ITEM_VELX) < 0.02 && fabs(ITEM_VELY) < 0.02 )
	{
		my->itemNotMoving = 1;
		my->flags[UPDATENEEDED] = false;
		if ( multiplayer != CLIENT )
		{
			serverUpdateEntitySkill(my, 18); //update itemNotMoving flag
		}
		else
		{
			my->itemNotMovingClient = 1;
		}
		return;
	}

	// horizontal motion
	if ( ITEM_NOCOLLISION )
	{
		double newx = my->x + ITEM_VELX;
		double newy = my->y + ITEM_VELY;
		if ( !checkObstacle( newx, newy, my, NULL ) )
		{
			my->x = newx;
			my->y = newy;
			my->yaw += sqrt( ITEM_VELX * ITEM_VELX + ITEM_VELY * ITEM_VELY ) * .05;
		}
	}
	else
	{
		double result = clipMove(&my->x, &my->y, ITEM_VELX, ITEM_VELY, my);
		my->yaw += result * .05;
		if ( result != sqrt( ITEM_VELX * ITEM_VELX + ITEM_VELY * ITEM_VELY ) )
		{
			if ( !hit.side )
			{
				ITEM_VELX *= -.5;
				ITEM_VELY *= -.5;
			}
			else if ( hit.side == HORIZONTAL )
			{
				ITEM_VELX *= -.5;
			}
			else
			{
				ITEM_VELY *= -.5;
			}
		}
	}
	ITEM_VELX = ITEM_VELX * .925;
	ITEM_VELY = ITEM_VELY * .925;
}