コード例 #1
0
void identifyGUIIdentify(Item *item) {
	if (!item)
		return;
	if (item->identified) {
		messagePlayer(clientnum, language[319],item->getName());
		return;
	}

	if (!identifygui_appraising) {
		item->identified = TRUE;
		messagePlayer(clientnum, language[320], item->description());
		if (appraisal_timer > 0 && appraisal_item && appraisal_item == item->uid) {
			appraisal_timer = 0;
			appraisal_item = 0;
		}
	} else {
		//Appraising.
		messagePlayer(clientnum, language[321], item->description());

		//Tick the timer in act player.
		//Once the timer hits zero, roll to see if the item is identified.
		//If it is identified, identify it and print out a message for the player.

		identifygui_appraising = FALSE;
		if( item->type!=GEM_GLASS )
			appraisal_timer = (items[item->type].value * 60) / (stats[clientnum].PROFICIENCIES[PRO_APPRAISAL] + 1); // time in ticks until item is appraised
		else
			appraisal_timer = (1000 * 60) / (stats[clientnum].PROFICIENCIES[PRO_APPRAISAL] + 1); // time in ticks until item is appraised+-
		appraisal_timer = std::min(std::max(1,appraisal_timer),36000);
		appraisal_timermax = appraisal_timer;
		appraisal_item = item->uid;
		//printlog( "DEBUGGING: Appraisal timer = %i.\n", appraisal_timer);
	}
	identifygui_active = FALSE;
}
コード例 #2
0
ファイル: actladder.cpp プロジェクト: firehot/Barony
void actLadder(Entity *my) {
	int playercount=0;
	double dist;
	int i, c;
	
	LADDER_AMBIENCE--;
	if( LADDER_AMBIENCE<=0 ) {
		LADDER_AMBIENCE = TICKS_PER_SECOND*30;
		playSoundEntityLocal( my, 149, 64 );
	}

	// use ladder (climb)
	if( multiplayer!=CLIENT ) {
		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[506]);
					else
						messagePlayer(i,language[507]);
					loadnextlevel=TRUE;
					if( secretlevel ) {
						switch( currentlevel ) {
							case 3:
								for( c=0; c<MAXPLAYERS; c++ )
									steamAchievementClient(c,"BARONY_ACH_THUNDERGNOME");
								break;
						}
					}
					if( LADDER_SECRET )
						secretlevel = (secretlevel==FALSE); // toggle level lists
					return;
				}
			}
		}
	}
}
コード例 #3
0
ファイル: spell.cpp プロジェクト: ganthore/Barony
void equipSpell(spell_t* spell, int playernum)
{
	if ( playernum == clientnum )
	{
		selected_spell = spell;
		messagePlayer(playernum, language[442], spell->name);
	}
}
コード例 #4
0
ファイル: actladder.cpp プロジェクト: firehot/Barony
void actLadderUp(Entity *my) {
	int i;
	
	LADDER_AMBIENCE--;
	if( LADDER_AMBIENCE<=0 ) {
		LADDER_AMBIENCE = TICKS_PER_SECOND*30;
		playSoundEntityLocal( my, 149, 64 );
	}

	// use ladder
	if( multiplayer!=CLIENT ) {
		for(i=0;i<MAXPLAYERS;i++) {
			if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
				if(inrange[i]) {
					messagePlayer(i,language[508]);
					return;
				}
			}
		}
	}
}
コード例 #5
0
ファイル: actitem.cpp プロジェクト: TurningWheel/Barony
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;
}
コード例 #6
0
ファイル: actfountain.cpp プロジェクト: mroutledge/Barony
void actFountain(Entity *my) {
	Entity *entity;

	//messagePlayer(0, "actFountain()");
	//TODO: Temporary mechanism testing code.
	/*
	if( multiplayer != CLIENT ) {
		if (my->skill[28]) {
			//All it does is change its sprite to sink if it's powered.
			if (my->skill[28] == 1) {
				my->sprite = 163;
			} else {
				my->sprite = 164;
			}
		}
	}*/
	//****************END TEST CODE***************

	//TODO: Sounds.
	
	// spray water
	if( my->skill[0] > 0 || ( !my->skill[2] && multiplayer == CLIENT ) ) {
		#define FOUNTAIN_AMBIENCE my->skill[7]
		FOUNTAIN_AMBIENCE--;
		if( FOUNTAIN_AMBIENCE<=0 ) {
			FOUNTAIN_AMBIENCE = TICKS_PER_SECOND*6;
			playSoundEntityLocal(my, 135, 32 );
		}
		entity = spawnGib(my);
		entity->flags[INVISIBLE] = FALSE;
		entity->y -= 2;
		entity->z -= 8;
		entity->flags[SPRITE] = FALSE;
		entity->flags[NOUPDATE] = TRUE;
		entity->flags[UPDATENEEDED] = FALSE;
		entity->skill[4] = 7;
		entity->sprite = 4;
		entity->yaw = (rand()%360)*PI/180.0;
		entity->pitch = (rand()%360)*PI/180.0;
		entity->roll = (rand()%360)*PI/180.0;
		entity->vel_x = 0;
		entity->vel_y = 0;
		entity->vel_z = .25;
		entity->fskill[3] = 0.03;
	}
	
	 // the rest of the function is server-side.
	if( multiplayer==CLIENT )
		return;
		
	// makes the fountain stop spraying water on clients
	if( my->skill[0] <= 0 )
		my->skill[2] = 1;
	else
		my->skill[2] = 0;

	//Using the fountain (TODO: Monsters using it?).
	int i;
	for (i = 0; i < MAXPLAYERS; ++i) {
		if ( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
			if (inrange[i]) { //Act on it only if the player (or monster, if/when this is changed to support monster interaction?) is in range.
				//First check that it's not depleted.
				if (my->skill[0] == 0) {
					//Depleted
					messagePlayer(i, language[467]);
				} else {
					if (players[i]->entity->flags[BURNING])
					{
						messagePlayer(i, language[468]);
						players[i]->entity->flags[BURNING] = FALSE;
						if (i > 0)
							serverUpdateEntityFlag(players[i]->entity, BURNING);
					}
					switch (my->skill[1]) {
						case 0: {
							playSoundEntity(players[i]->entity, 52, 64);
							
							//Spawn succubus.
							Uint32 color = SDL_MapRGB(mainsurface->format,255,128,0);
							messagePlayerColor(i, color, language[469]);
							summonMonster(SUCCUBUS, my->x, my->y);
							break;
						}
						case 1:
							messagePlayer(i, language[470]);
							messagePlayer(i, language[471]);
							playSoundEntity(players[i]->entity, 52, 64);
							stats[i]->HUNGER += 50;
							break;
						case 2: {
							//Potion effect. Potion effect is stored in my->skill[3], randomly chosen when the fountain is created.
							messagePlayer(i, language[470]);
							Item *item = newItem(static_cast<ItemType>(POTION_WATER+my->skill[3]), static_cast<Status>(4), 0,1,0,FALSE,NULL);
							useItem(item,i);
							// Long live the mystical fountain of TODO.
							break;
						}
						case 3: {
							// bless equipment
							playSoundEntity(players[i]->entity, 52, 64);
							Uint32 textcolor = SDL_MapRGB(mainsurface->format,0,255,255);
							messagePlayerColor(i, textcolor, language[471]);
							messagePlayer(i, language[473]);
							if( stats[i]->helmet )
								stats[i]->helmet->beatitude++;
							if( stats[i]->breastplate )
								stats[i]->breastplate->beatitude++;
							if( stats[i]->gloves )
								stats[i]->gloves->beatitude++;
							if( stats[i]->shoes )
								stats[i]->shoes->beatitude++;
							if( stats[i]->shield )
								stats[i]->shield->beatitude++;
							if( stats[i]->weapon )
								stats[i]->weapon->beatitude++;
							if( stats[i]->cloak )
								stats[i]->cloak->beatitude++;
							if( stats[i]->amulet )
								stats[i]->amulet->beatitude++;
							if( stats[i]->ring )
								stats[i]->ring->beatitude++;
							if( stats[i]->mask )
								stats[i]->mask->beatitude++;
							if( multiplayer==SERVER && i>0 ) {
								strcpy((char *)net_packet->data,"BLES");
								net_packet->address.host = net_clients[i-1].host;
								net_packet->address.port = net_clients[i-1].port;
								net_packet->len = 4;
								sendPacketSafe(net_sock, -1, net_packet, i-1);
							}
							break;
						}
						default:
							break;
					}
					messagePlayer(i, language[474]);
					my->skill[0] = 0; //Dry up fountain.
					//TODO: messagePlayersInSight() instead.
				}
				//Then perform the effect randomly determined when the fountain was created.
				return;
			}
		}
	}
}
コード例 #7
0
ファイル: actfountain.cpp プロジェクト: ganthore/Barony
void actFountain(Entity* my)
{
	Entity* entity;

	//messagePlayer(0, "actFountain()");
	//TODO: Temporary mechanism testing code.
	/*
	if( multiplayer != CLIENT ) {
		if (my->skill[28]) {
			//All it does is change its sprite to sink if it's powered.
			if (my->skill[28] == 1) {
				my->sprite = 163;
			} else {
				my->sprite = 164;
			}
		}
	}*/
	//****************END TEST CODE***************

	//TODO: Sounds.

	// spray water
	if ( my->skill[0] > 0 )
	{
#define FOUNTAIN_AMBIENCE my->skill[7]
		FOUNTAIN_AMBIENCE--;
		if ( FOUNTAIN_AMBIENCE <= 0 )
		{
			FOUNTAIN_AMBIENCE = TICKS_PER_SECOND * 6;
			playSoundEntityLocal(my, 135, 32 );
		}
		entity = spawnGib(my);
		entity->flags[INVISIBLE] = false;
		entity->y -= 2;
		entity->z -= 8;
		entity->flags[SPRITE] = false;
		entity->flags[NOUPDATE] = true;
		entity->flags[UPDATENEEDED] = false;
		entity->skill[4] = 7;
		entity->sprite = 4;
		entity->yaw = (rand() % 360) * PI / 180.0;
		entity->pitch = (rand() % 360) * PI / 180.0;
		entity->roll = (rand() % 360) * PI / 180.0;
		entity->vel_x = 0;
		entity->vel_y = 0;
		entity->vel_z = .25;
		entity->fskill[3] = 0.03;
	}

	// the rest of the function is server-side.
	if ( multiplayer == CLIENT )
	{
		return;
	}

	//Using the fountain (TODO: Monsters using it?).
	int i;
	for (i = 0; i < MAXPLAYERS; ++i)
	{
		if ( (i == 0 && selectedEntity == my) || (client_selected[i] == my) )
		{
			if (inrange[i])   //Act on it only if the player (or monster, if/when this is changed to support monster interaction?) is in range.
			{
				//First check that it's not depleted.
				if (my->skill[0] == 0)
				{
					//Depleted
					messagePlayer(i, language[467]);
				}
				else
				{
					if (players[i]->entity->flags[BURNING])
					{
						messagePlayer(i, language[468]);
						players[i]->entity->flags[BURNING] = false;
						serverUpdateEntityFlag(players[i]->entity, BURNING);
						steamAchievementClient(i, "BARONY_ACH_HOT_SHOWER");
					}
					switch (my->skill[1])
					{
						case 0:
						{
							playSoundEntity(players[i]->entity, 52, 64);
							//Spawn succubus.
							Uint32 color = SDL_MapRGB(mainsurface->format, 255, 128, 0);
							Entity* spawnedMonster = nullptr;

							if ( !strncmp(map.name, "Underworld", 10) )
							{
								Monster creature = SUCCUBUS;
								if ( rand() % 2 )
								{
									creature = INCUBUS;
								}
								for ( int c = 0; spawnedMonster == nullptr && c < 5; ++c )
								{
									switch ( c )
									{
										case 0:
											spawnedMonster = summonMonster(creature, my->x, my->y);
											break;
										case 1:
											spawnedMonster = summonMonster(creature, my->x + 16, my->y);
											break;
										case 2:
											spawnedMonster = summonMonster(creature, my->x - 16, my->y);
											break;
										case 3:
											spawnedMonster = summonMonster(creature, my->x, my->y + 16);
											break;
										case 4:
											spawnedMonster = summonMonster(creature, my->x, my->y - 16);
											break;
									}
								}
								if ( spawnedMonster )
								{
									if ( creature == INCUBUS )
									{
										messagePlayerColor(i, color, language[2519]);
										Stat* tmpStats = spawnedMonster->getStats();
										if ( tmpStats )
										{
											strcpy(tmpStats->name, "lesser incubus");
										}
									}
									else
									{
										messagePlayerColor(i, color, language[469]);
									}
								}
							}
							else if ( currentlevel < 10 )
							{
								messagePlayerColor(i, color, language[469]);
								spawnedMonster = summonMonster(SUCCUBUS, my->x, my->y);
							}
							else if ( currentlevel < 20 )
							{
								if ( rand() % 2 )
								{
									spawnedMonster = summonMonster(INCUBUS, my->x, my->y);
									Stat* tmpStats = spawnedMonster->getStats();
									if ( tmpStats )
									{
										strcpy(tmpStats->name, "lesser incubus");
									}
									messagePlayerColor(i, color, language[2519]);
								}
								else
								{
									messagePlayerColor(i, color, language[469]);
									spawnedMonster = summonMonster(SUCCUBUS, my->x, my->y);
								}
							}
							else
							{
								messagePlayerColor(i, color, language[2519]);
								spawnedMonster = summonMonster(INCUBUS, my->x, my->y);
							}
							break;
						}
						case 1:
							messagePlayer(i, language[470]);
							messagePlayer(i, language[471]);
							playSoundEntity(players[i]->entity, 52, 64);
							stats[i]->HUNGER += 100;
							players[i]->entity->modHP(5);
							break;
						case 2:
						{
							//Potion effect. Potion effect is stored in my->skill[3], randomly chosen when the fountain is created.
							messagePlayer(i, language[470]);
							Item* item = newItem(static_cast<ItemType>(POTION_WATER + my->skill[3]), static_cast<Status>(4), 0, 1, 0, false, NULL);
							useItem(item, i);
							// Long live the mystical fountain of TODO.
							break;
						}
						case 3:
						{
							// bless all equipment
							playSoundEntity(players[i]->entity, 52, 64);
							Uint32 textcolor = SDL_MapRGB(mainsurface->format, 0, 255, 255);
							messagePlayerColor(i, textcolor, language[471]);
							messagePlayer(i, language[473]);
							if ( stats[i]->helmet )
							{
								stats[i]->helmet->beatitude++;
							}
							if ( stats[i]->breastplate )
							{
								stats[i]->breastplate->beatitude++;
							}
							if ( stats[i]->gloves )
							{
								stats[i]->gloves->beatitude++;
							}
							if ( stats[i]->shoes )
							{
								stats[i]->shoes->beatitude++;
							}
							if ( stats[i]->shield )
							{
								stats[i]->shield->beatitude++;
							}
							if ( stats[i]->weapon )
							{
								stats[i]->weapon->beatitude++;
							}
							if ( stats[i]->cloak )
							{
								stats[i]->cloak->beatitude++;
							}
							if ( stats[i]->amulet )
							{
								stats[i]->amulet->beatitude++;
							}
							if ( stats[i]->ring )
							{
								stats[i]->ring->beatitude++;
							}
							if ( stats[i]->mask )
							{
								stats[i]->mask->beatitude++;
							}
							if ( multiplayer == SERVER && i > 0 )
							{
								strcpy((char*)net_packet->data, "BLES");
								net_packet->address.host = net_clients[i - 1].host;
								net_packet->address.port = net_clients[i - 1].port;
								net_packet->len = 4;
								sendPacketSafe(net_sock, -1, net_packet, i - 1);
							}
							break;
						}
						case 4:
						{
							// bless one piece of equipment
							playSoundEntity(players[i]->entity, 52, 64);
							Uint32 textcolor = SDL_MapRGB(mainsurface->format, 0, 255, 255);
							messagePlayerColor(i, textcolor, language[471]);
							//Choose only one piece of equipment to bless.

							//First, Figure out what equipment is available.
							std::vector<std::pair<Item*, Uint32>> items;
							if ( stats[i]->helmet )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->helmet, 0));
							}
							if ( stats[i]->breastplate )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->breastplate, 1));
							}
							if ( stats[i]->gloves )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->gloves, 2));
							}
							if ( stats[i]->shoes )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->shoes, 3));
							}
							if ( stats[i]->shield )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->shield, 4));
							}
							if ( stats[i]->weapon )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->weapon, 5));
							}
							if ( stats[i]->cloak )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->cloak, 6));
							}
							if ( stats[i]->amulet )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->amulet, 7));
							}
							if ( stats[i]->ring )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->ring, 8));
							}
							if ( stats[i]->mask )
							{
								items.push_back(std::pair<Item*,int>(stats[i]->mask, 9));
							}

							if ( items.size() )
							{
								messagePlayer(i, language[2592]); //"The fountain blesses a piece of equipment"
								//Randomly choose a piece of equipment.
								std::pair<Item*, Uint32> chosen = items[rand()%items.size()];
								chosen.first->beatitude++;

								if ( multiplayer == SERVER && i > 0 )
								{
									strcpy((char*)net_packet->data, "BLE1");
									SDLNet_Write32(chosen.second, &net_packet->data[4]);
									net_packet->address.host = net_clients[i - 1].host;
									net_packet->address.port = net_clients[i - 1].port;
									net_packet->len = 8;
									sendPacketSafe(net_sock, -1, net_packet, i - 1);
								}
							}
							//Does nothing if no valid items.
							break;
						}
						default:
							break;
					}
					messagePlayer(i, language[474]);
					my->skill[0] = 0; //Dry up fountain.
					serverUpdateEntitySkill(my, my->skill[0]);
					//TODO: messagePlayersInSight() instead.
				}
				//Then perform the effect randomly determined when the fountain was created.
				return;
			}
		}
	}
}
コード例 #8
0
ファイル: castSpell.cpp プロジェクト: boskee/Barony
void castSpellInit(Uint32 caster_uid, spell_t *spell){
	Entity *caster = uidToEntity(caster_uid);
	node_t *node = NULL;
	if (!caster || !spell)
	{
		//Need a spell and caster to cast a spell.
		return;
	}

	if (!spell->elements.first) {
		return;
	}

	if (hudweapon) {
		if (hudweapon->skill[0] != 0) { //HUDWEAPON_CHOP.
			return; //Can't cast spells while attacking.
		}
	}

	if (cast_animation.active) {
		//Already casting spell.
		return;
	}

	int player = -1;
	int i = 0;
	for (i = 0; i < numplayers; ++i) {
		if (caster == players[i]) {
			player = i; //Set the player.
		}
	}

	if (player > -1) {
		if( stats[player].defending ) {
			messagePlayer(player,language[407]);
			return;
		}
		if (spell_isChanneled(spell)) {
			if (channeledSpells[clientnum], spell) {
				for (node = channeledSpells[player].first; node; node = node->next) {
					spell_t *spell_search = (spell_t*)node->element;
					if (spell_search->ID == spell->ID) {
						//list_RemoveNode(node);
						//node = NULL;
						spell_search->sustain = FALSE;
						//if (spell->magic_effects)
						//	list_RemoveNode(spell->magic_effects);
						messagePlayer(player, language[408], spell->name);
						if (multiplayer == CLIENT) {
							list_RemoveNode(node);
							strcpy( (char *)net_packet->data, "UNCH");
							net_packet->data[4] = clientnum;
							SDLNet_Write32(spell->ID, &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);
						}
						return;
					}
				}
			}
		}
	}

	int magiccost = 0;
	//Entity *entity = NULL;
	//node_t *node = spell->elements->first;

	stat_t *stat = caster->getStats();
	if( !stat )
		return;
	
	if (stat->EFFECTS[EFF_PARALYZED]) {
		return;		
	}

	magiccost = getCostOfSpell(spell);
	if (magiccost > stat->MP) {
		if (player >= 0)
			messagePlayer(player, language[375]); //TODO: Allow overexpending at the cost of extreme danger? (maybe an immensely powerful tree of magic actually likes this -- using your life-force to power spells instead of mana)
		return;
	}
	if (magiccost < 0) {
		if (player >= 0)
			messagePlayer(player, "Error: Invalid spell. Mana cost is negative?");
		return;
	}

	//Hand the torch off to the spell animator. And stuff. Stuff. I mean spell animation handler thingymabobber.
	fireOffSpellAnimation(&cast_animation, caster->uid, spell);

	//castSpell(caster, spell); //For now, do this while the spell animations are worked on.
}
コード例 #9
0
ファイル: shops.cpp プロジェクト: ganthore/Barony
void buyItemFromShop(Item* item)
{
	if ( !item )
	{
		return;
	}

	if ( stats[clientnum]->GOLD >= item->buyValue(clientnum) )
	{
		if ( items[item->type].value * 1.5 >= item->buyValue(clientnum) )
		{
			shopspeech = language[200 + rand() % 3];
		}
		else
		{
			shopspeech = language[197 + rand() % 3];
		}
		shoptimer = ticks - 1;
		Item* itemToPickup = newItem(item->type, item->status, item->beatitude, 1, item->appearance, item->identified, nullptr);
		itemPickup(clientnum, itemToPickup);

		stats[clientnum]->GOLD -= item->buyValue(clientnum);
		playSound(89, 64);
		int ocount = item->count;
		item->count = 1;
		messagePlayer(clientnum, language[1123], item->description(), item->buyValue(clientnum));
		item->count = ocount;
		if ( multiplayer != CLIENT )
		{
			Entity* entity = uidToEntity(shopkeeper);
			if (entity)
			{
				Stat* shopstats = entity->getStats();
				shopstats->GOLD += item->buyValue(clientnum);
			}
			if ( rand() % 2 )
			{
				if ( item->buyValue(clientnum) <= 1 )
				{
					// buying cheap items does not increase trading past basic
					if ( stats[clientnum]->PROFICIENCIES[PRO_TRADING] < SKILL_LEVEL_SKILLED )
					{
						players[clientnum]->entity->increaseSkill(PRO_TRADING);
					}
				}
				else
				{
					players[clientnum]->entity->increaseSkill(PRO_TRADING);
				}
			}
			else if ( item->buyValue(clientnum) >= 150 )
			{
				if ( item->buyValue(clientnum) >= 300 || rand() % 2 )
				{
					players[clientnum]->entity->increaseSkill(PRO_TRADING);
				}
			}
		}
		else
		{
			strcpy((char*)net_packet->data, "SHPB");
			SDLNet_Write32(shopkeeper, &net_packet->data[4]);

			// send item that was bought to server
			SDLNet_Write32(item->type, &net_packet->data[8]);
			SDLNet_Write32(item->status, &net_packet->data[12]);
			SDLNet_Write32(item->beatitude, &net_packet->data[16]);
			SDLNet_Write32((Uint32)item->appearance, &net_packet->data[20]);
			if ( item->identified )
			{
				net_packet->data[24] = 1;
			}
			else
			{
				net_packet->data[24] = 0;
			}
			net_packet->data[25] = clientnum;
			net_packet->address.host = net_server.host;
			net_packet->address.port = net_server.port;
			net_packet->len = 26;
			sendPacketSafe(net_sock, -1, net_packet, 0);
		}
		consumeItem(item);
	}
	else
	{
		shopspeech = language[203 + rand() % 3];
		shoptimer = ticks - 1;
		playSound(90, 64);
	}
}
コード例 #10
0
    void Server::processInput(int connection, const std::string& input)
    {
        std::cout << "Connection " << connection << ": " << input << std::endl;

        try
        {
            Player temp = getPlayer(connection);
            
            if (input == "/quit")
            {
                unregisterPlayer(temp);

                std::cout << "Removed player on connection " << connection << std::endl;
            }
            else if (input == "/show")
            {
                if (temp.inGame() < 0)
                {
                    messagePlayer(temp, "Invalid command, not in a game!");
                }
                else
                {
                    messagePlayer(temp, (myGameList[temp.inGame()].getBoard()));
                }
            }
            else if (input == "/list")
            {
                messagePlayer(temp, getPlayerList());
            }
            else if (input == "/forfeit")
            {
                messagePlayer(temp, "Forfeit game message.");
            }
            else if (input.find("/play") == 0)
            {
                messagePlayer(temp, "Play game message.");
                std::stringstream ss(input);
                std::istream_iterator<std::string> it(ss);
                
                std::vector<std::string> tokens(it, std::istream_iterator<std::string>());

                Player potential_p2;

                try
                {
                    potential_p2 = getPlayer(tokens[1]);
                }
                catch(std::runtime_error&)
                {
                    messagePlayer(temp, "No such player exists.");
                }

                if (potential_p2 == temp)
                {
                    messagePlayer(temp, "No single player!");
                }
                else if (potential_p2.inGame() != -1)
                {
                    messagePlayer(temp, "That party is already in a game.");
                }
                else
                {
                    messagePlayer(temp, "Creating game.");
                    messagePlayer(potential_p2, temp.getName() + " started a game with you!");
                }
            }
            else if (input == "/help")
            {
                messagePlayer(temp, "Valid commands: /help /list /show /quit /play /forfeit");
            }
            else
            {
#if 1
                std::cout << "Broadcasting to lobby." << std::endl;
                for (auto it = myPlayerList.begin(); it != myPlayerList.end(); ++it)
                {
                    if (it->second.inGame() < 0 && !(it->second == temp))
                        messagePlayer(it->second, temp.getName() + ": " + input);
                }
#else
                std::cout << "Echoing message." << std::endl;
                messagePlayer(temp, temp.getName() + ": " + input);
#endif
            }
        }
        catch(std::runtime_error&) // Probably because the player didn't exist!
        {
            // New player, this message should be the name.
            //myPlayerList.emplace(input, connection, input);
            myPlayerList[input] = Player(connection, input);
            std::cout << "Player created with name " << input << '.' << std::endl;
            messagePlayer(myPlayerList[input], "Username registered.");
        }
    }
コード例 #11
0
ファイル: actgate.cpp プロジェクト: Gilgatex/Barony
void actGate(Entity *my) {
	int i;

	if( multiplayer!=CLIENT ) {
		if (!my->skill[28])
			return; //Gate needs the mechanism powered state variable to be set.

		if (my->skill[28] == 2) {
			//Raise gate if it's closed.
			if (!GATE_STATUS) {
				GATE_STATUS = 1;
				playSoundEntity(my, 81, 64);
				serverUpdateEntitySkill(my,3);
			}
		} else {
			//Close gate if it's open.
			if (GATE_STATUS) {
				GATE_STATUS = 0;
				playSoundEntity(my, 82, 64);
				serverUpdateEntitySkill(my,3);
			}
		}
	} else {
		my->flags[NOUPDATE] = TRUE;
	}
	if (!GATE_INIT ) {
		GATE_INIT = 1;
		GATE_STARTHEIGHT = my->z;
		my->scalex = 1.01;
		my->scaley = 1.01;
		my->scalez = 1.01;
	}
	
	// rightclick message
	if( multiplayer!=CLIENT ) {
		for(i=0;i<MAXPLAYERS;i++) {
			if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
				if(inrange[i]) {
					messagePlayer(i,language[475]);
				}
			}
		}
	}

	if( !GATE_STATUS ) {
		//Closing gate.
		if( my->z < GATE_STARTHEIGHT ) {
			GATE_VELZ += .25;
			my->z = std::min(GATE_STARTHEIGHT, my->z + GATE_VELZ);
		} else {
			GATE_VELZ = 0;
		}
	} else {
		//Opening gate.
		if( my->z > GATE_STARTHEIGHT-12 ) {
			my->z = std::max(GATE_STARTHEIGHT-12, my->z - 0.25);
			
			// rattle the gate
			GATE_RATTLE = (GATE_RATTLE==0);
			if( GATE_RATTLE ) {
				my->x += .05;
				my->y += .05;
			} else {
				my->x -= .05;
				my->y -= .05;
			}
		} else {
			// reset the gate's position
			if( GATE_RATTLE ) {
				GATE_RATTLE = 0;
				my->x -= .05;
				my->y -= .05;
			}
		}
	}
	
	//Setting collision
	node_t *node;
	bool somebodyinside = FALSE;
	if( my->z > GATE_STARTHEIGHT-6 && my->flags[PASSABLE] ) {
		for( node=map.entities->first; node!=NULL; node=node->next ) {
			Entity *entity = (Entity *)node->element;
			if( entity==my || entity->flags[PASSABLE] || entity->sprite == 1 )
				continue;
			if( entityInsideEntity(my,entity) ) {
				somebodyinside = TRUE;
				break;
			}
		}
		if( !somebodyinside )
			my->flags[PASSABLE] = FALSE;
	} else if( my->z < GATE_STARTHEIGHT-9 && !my->flags[PASSABLE] ) {
		my->flags[PASSABLE] = TRUE;
	}
}
コード例 #12
0
ファイル: actcampfire.cpp プロジェクト: Gilgatex/Barony
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]);
					}
				}
			}
		}
	}
}
コード例 #13
0
ファイル: spell.cpp プロジェクト: mroutledge/Barony
void addSpell(int spell, int player) {
	node_t *node = NULL;

	// this is a local function
	if( player != clientnum )
		return;

	spell_t *new_spell = NULL;

	switch( spell ) {
		case SPELL_FORCEBOLT:
			new_spell = copySpell(&spell_forcebolt);
			break;
		case SPELL_MAGICMISSILE:
			new_spell = copySpell(&spell_magicmissile);
			break;
		case SPELL_COLD:
			new_spell = copySpell(&spell_cold);
			break;
		case SPELL_FIREBALL:
			new_spell = copySpell(&spell_fireball);
			break;
		case SPELL_LIGHTNING:
			new_spell = copySpell(&spell_lightning);
			break;
		case SPELL_REMOVECURSE:
			new_spell = copySpell(&spell_removecurse);
			break;
		case SPELL_LIGHT:
			new_spell = copySpell(&spell_light);
			break;
		case SPELL_IDENTIFY:
			new_spell = copySpell(&spell_identify);
			break;
		case SPELL_MAGICMAPPING:
			new_spell = copySpell(&spell_magicmapping);
			break;
		case SPELL_SLEEP:
			new_spell = copySpell(&spell_sleep);
			break;
		case SPELL_CONFUSE:
			new_spell = copySpell(&spell_confuse);
			break;
		case SPELL_SLOW:
			new_spell = copySpell(&spell_slow);
			break;
		case SPELL_OPENING:
			new_spell = copySpell(&spell_opening);
			break;
		case SPELL_LOCKING:
			new_spell = copySpell(&spell_locking);
			break;
		case SPELL_LEVITATION:
			new_spell = copySpell(&spell_levitation);
			break;
		case SPELL_INVISIBILITY:
			new_spell = copySpell(&spell_invisibility);
			break;
		case SPELL_TELEPORTATION:
			new_spell = copySpell(&spell_teleportation);
			break;
		case SPELL_HEALING:
			new_spell = copySpell(&spell_healing);
			break;
		case SPELL_EXTRAHEALING:
			new_spell = copySpell(&spell_extrahealing);
			break;
		case SPELL_CUREAILMENT:
			new_spell = copySpell(&spell_cureailment);
			break;
		case SPELL_DIG:
			new_spell = copySpell(&spell_dig);
			break;
		default:
			return;
	}
	if( spellInList(&spellList, new_spell) ) {
		messagePlayer(player, language[439],new_spell->name);
		spellDeconstructor((void *)new_spell);
		return;
	}
	if( stats[player]->PROFICIENCIES[PRO_MAGIC]+statGetINT(stats[player]) < new_spell->difficulty ) {
		messagePlayer(player, language[440]);
		spellDeconstructor((void *)new_spell);
		return;
	}
	messagePlayer(player,language[441],new_spell->name);
	node = list_AddNodeLast(&spellList);
	node->element = new_spell;
	node->size = sizeof(spell_t);
	node->deconstructor = &spellDeconstructor;

	players[player]->entity->increaseSkill(PRO_MAGIC);

	Item *item = newItem(SPELL_ITEM, SERVICABLE, 0, 1, spell, TRUE, NULL);
	itemPickup(player, item);
	free(item);
}
コード例 #14
0
ファイル: actgold.cpp プロジェクト: mroutledge/Barony
void actGoldBag(Entity *my) {
	int i;

	if( my->flags[INVISIBLE] ) {
		if( multiplayer!=CLIENT ) {
			node_t *node;
			for( node=map.entities->first; node!=NULL; node=node->next ) {
				Entity *entity = (Entity *)node->element;
				if( entity->sprite == 245 ) // boulder.vox
					return;
			}
			my->flags[INVISIBLE] = FALSE;
			serverUpdateEntityFlag(my,INVISIBLE);
			if( !strcmp(map.name,"Sokoban") ) {
				for( i=0; i<MAXPLAYERS; i++ )
					steamAchievementClient(i,"BARONY_ACH_PUZZLE_MASTER");
			}
		} else {
			return;
		}
	}

	GOLDBAG_AMBIENCE--;
	if( GOLDBAG_AMBIENCE<=0 ) {
		GOLDBAG_AMBIENCE = TICKS_PER_SECOND*30;
		playSoundEntityLocal( my, 149, 16 );
	}
	
	// pick up gold
	if( multiplayer!=CLIENT ) {
		for(i=0;i<MAXPLAYERS;i++) {
			if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
				if(inrange[i]) {
					if (players[i] && players[i]->entity)
						playSoundEntity(players[i]->entity, 242+rand()%4, 64 );
					stats[i]->GOLD += GOLDBAG_AMOUNT;
					if( i!=0 ) {
						if( multiplayer==SERVER ) {
							// send the client info on the gold it picked up
							strcpy((char *)net_packet->data,"GOLD");
							SDLNet_Write32(stats[i]->GOLD,&net_packet->data[4]);
							net_packet->address.host = net_clients[i-1].host;
							net_packet->address.port = net_clients[i-1].port;
							net_packet->len = 8;
							sendPacketSafe(net_sock, -1, net_packet, i-1);
						}
					}

					// message for item pickup
					if( GOLDBAG_AMOUNT==1 )
						messagePlayer(i,language[483]);
					else
						messagePlayer(i,language[484],GOLDBAG_AMOUNT);

					// remove gold entity
					list_RemoveNode(my->mynode);
					return;
				}
			}
		}
	} else {
		my->flags[NOUPDATE] = TRUE;
	}
}
コード例 #15
0
ファイル: shops.cpp プロジェクト: ganthore/Barony
void sellItemToShop(Item* item)
{
	if ( !item )
	{
		return;
	}
	if ( item->beatitude < 0 && itemIsEquipped(item, clientnum) )
	{
		messagePlayer(clientnum, language[1124], item->getName());
		playSound(90, 64);
		return;
	}

	bool deal = true;
	if ( stats[clientnum]->PROFICIENCIES[PRO_TRADING] >= CAPSTONE_UNLOCK_LEVEL[PRO_TRADING] )
	{
		//Skill capstone: Can sell anything to any shop.
	}
	else
	{
		switch ( shopkeepertype )
		{
			case 0: // arms & armor
				if ( itemCategory(item) != WEAPON && itemCategory(item) != ARMOR && itemCategory(item) != THROWN )
				{
					deal = false;
				}
				break;
			case 1: // hats
				if ( itemCategory(item) != ARMOR )
				{
					deal = false;
				}
				break;
			case 2: // jewelry
				if ( itemCategory(item) != RING && itemCategory(item) != AMULET && itemCategory(item) != GEM )
				{
					deal = false;
				}
				break;
			case 3: // bookstore
				if ( itemCategory(item) != SPELLBOOK && itemCategory(item) != SCROLL && itemCategory(item) != BOOK )
				{
					deal = false;
				}
				break;
			case 4: // potion shop
				if ( itemCategory(item) != POTION )
				{
					deal = false;
				}
				break;
			case 5: // magicstaffs
				if ( itemCategory(item) != MAGICSTAFF )
				{
					deal = false;
				}
				break;
			case 6: // food
				if ( itemCategory(item) != FOOD )
				{
					deal = false;
				}
				break;
			case 7: // tools
			case 8: // lights
				if ( itemCategory(item) != TOOL && itemCategory(item) != THROWN )
				{
					deal = false;
				}
				break;
			default:
				break;
		}
	}
	if ( !deal )
	{
		shopspeech = language[212 + rand() % 3];
		shoptimer = ticks - 1;
		playSound(90, 64);
		return;
	}

	if ( items[item->type].value * .75 <= item->sellValue(clientnum) )
	{
		shopspeech = language[209 + rand() % 3];
	}
	else
	{
		shopspeech = language[206 + rand() % 3];
	}
	shoptimer = ticks - 1;
	newItem(item->type, item->status, item->beatitude, 1, item->appearance, item->identified, shopInv);
	stats[clientnum]->GOLD += item->sellValue(clientnum);
	playSound(89, 64);
	int ocount = item->count;
	item->count = 1;
	messagePlayer(clientnum, language[1125], item->description(), item->sellValue(clientnum));
	item->count = ocount;
	if ( multiplayer != CLIENT )
	{
		if ( rand() % 2 )
		{
			if ( item->sellValue(clientnum) <= 1 )
			{
				// selling cheap items does not increase trading past basic
				if ( stats[clientnum]->PROFICIENCIES[PRO_TRADING] < SKILL_LEVEL_SKILLED )
				{
					players[clientnum]->entity->increaseSkill(PRO_TRADING);
				}
			}
			else
			{
				players[clientnum]->entity->increaseSkill(PRO_TRADING);
			}
		}
	}
	else
	{
		strcpy((char*)net_packet->data, "SHPS");
		SDLNet_Write32(shopkeeper, &net_packet->data[4]);

		// send item that was sold to server
		SDLNet_Write32(item->type, &net_packet->data[8]);
		SDLNet_Write32(item->status, &net_packet->data[12]);
		SDLNet_Write32(item->beatitude, &net_packet->data[16]);
		SDLNet_Write32((Uint32)item->appearance, &net_packet->data[20]);
		if ( item->identified )
		{
			net_packet->data[24] = 1;
		}
		else
		{
			net_packet->data[24] = 0;
		}
		net_packet->data[25] = clientnum;
		net_packet->address.host = net_server.host;
		net_packet->address.port = net_server.port;
		net_packet->len = 26;
		sendPacketSafe(net_sock, -1, net_packet, 0);
	}
	consumeItem(item);
	sellitem = NULL;
}
コード例 #16
0
ファイル: castSpell.cpp プロジェクト: boskee/Barony
Entity* castSpell(Uint32 caster_uid, spell_t *spell, bool using_magicstaff, bool trap) {
	Entity *caster = uidToEntity(caster_uid);

	if (!caster || !spell)
	{
		//Need a spell and caster to cast a spell.
		return NULL;
	}

	Entity *result = NULL; //If the spell spawns an entity (like a magic light ball or a magic missile), it gets stored here and returned.
	#define spellcasting std::min(std::max(0,stat->PROFICIENCIES[PRO_SPELLCASTING]+statGetINT(stat)),100) //Shortcut!

	if (clientnum != 0 && multiplayer == CLIENT) {
		strcpy( (char *)net_packet->data, "SPEL" );
		net_packet->data[4] = clientnum;
		SDLNet_Write32(spell->ID, &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);
		return NULL;
	}

	if (!spell->elements.first) {
		return NULL;
	}
	
	//node_t *node = spell->types->first;

	#define PROPULSION_MISSILE 1
	int i = 0;
	int chance = 0;
	int propulsion = 0;
	int traveltime = 0;
	int magiccost = 0;
	int extramagic = 0; //Extra magic drawn in from the caster being a newbie.
	int extramagic_to_use = 0; //Instead of doing element->mana (which causes bugs), this is an extra factor in the mana equations. Pumps extra mana into elements from extramagic.
	Entity *entity = NULL;
	spell_t *channeled_spell=NULL; //Pointer to the spell if it's a channeled spell. For the purpose of giving it its node in the channeled spell list.
	node_t *node = spell->elements.first;

	stat_t *stat = caster->getStats();

	int player = -1;
	for (i = 0; i < numplayers; ++i) {
		if (caster == players[i]) {
			player = i; //Set the player.
		}
	}

	bool newbie = FALSE;
	if( !using_magicstaff && !trap) {
		if (stat->PROFICIENCIES[PRO_SPELLCASTING] < SPELLCASTING_BEGINNER) {
			newbie = TRUE; //The caster has lower spellcasting skill. Cue happy fun times.
		}

		/*magiccost = getCostOfSpell(spell);
		if (magiccost < 0) {
			if (player >= 0)
				messagePlayer(player, "Error: Invalid spell. Mana cost is negative?");
			return NULL;
		}*/
		if (multiplayer == SINGLE) {
			magiccost = cast_animation.mana_left;
			caster->drainMP(magiccost);
		} else {
			magiccost = getCostOfSpell(spell);
			caster->drainMP(magiccost);
		}
	}

	if (newbie) {
		//So This wizard is a newbie.

		//First, drain some extra mana maybe.
		int chance = rand()%10;
		if (chance >= spellcasting/10) { //At skill 20, there's an 80% chance you'll use extra mana. At 70, there's a 30% chance.
			extramagic = rand()%(300/(spellcasting+1)); //Use up extra mana. More mana used the lower your spellcasting skill.
			extramagic = std::min(extramagic, stat->MP / 10); //To make sure it doesn't draw, say, 5000 mana. Cause dammit, if you roll a 1 here...you're doomed.
			caster->drainMP(extramagic);
		}

		//Now, there's a chance they'll fumble the spell.
		chance = rand()%10;
		if (chance >= spellcasting/10) {
			if (rand()%3 == 1) {
				//Fizzle the spell.
				//TODO: Cool effects.
				playSoundEntity(caster,163,128);
				if (player >= 0)
					messagePlayer(player, language[409]);
				return NULL;
			}
		}
	}

	//Check if the bugger is levitating.
	bool levitating = FALSE;
	if (!trap) {
		if (stat->EFFECTS[EFF_LEVITATING] == TRUE )
			levitating=TRUE;
		if (stat->ring != NULL )
			if (stat->ring->type == RING_LEVITATION )
				levitating = TRUE;
		if (stat->shoes != NULL)
			if (stat->shoes->type == STEEL_BOOTS_LEVITATION )
				levitating = TRUE;
	}

	//Water walking boots
	bool waterwalkingboots = FALSE;
	if (!trap) {
		if (stat->shoes != NULL)
			if (stat->shoes->type == IRON_BOOTS_WATERWALKING )
				waterwalkingboots = TRUE;
	}

	node_t *node2; //For traversing the map looking for...liquids?
	//Check if swimming.
	if (!waterwalkingboots && !levitating && !trap && player>=0) {
		bool swimming=FALSE;
		if( players[player] ) {
			int x = std::min<int>(std::max(0.0,floor(caster->x/16)),map.width-1);
			int y = std::min<int>(std::max(0.0,floor(caster->y/16)),map.height-1);
			if( animatedtiles[map.tiles[y*MAPLAYERS+x*MAPLAYERS*map.height]] )
				swimming=TRUE;
		}
		if( swimming ) {
			//Can't cast spells while swimming if not levitating or water walking.
			if (player >= 0)
				messagePlayer(player, language[410]);
			return NULL;
		}
	}

	//Right. First, grab the root element, which is what determines the delivery system.
	//spellElement_t *element = (spellElement_t *)spell->elements->first->element;
	spellElement_t *element = (spellElement_t *)node->element;
	if (element) {
		extramagic_to_use = 0;
		/*if (magiccost > stat->MP) {
			if (player >= 0)
				messagePlayer(player, "Insufficient mana!"); //TODO: Allow overexpending at the cost of extreme danger? (maybe an immensely powerful tree of magic actually likes this -- using your life-force to power spells instead of mana)
			return NULL;
		}*/

		if (extramagic > 0) {
			//Extra magic. Pump it in here?
			chance = rand()%5;
			if (chance == 1) {
				//Use some of that extra magic in this element.
				int amount = rand()%extramagic;
				extramagic -= amount;
				extramagic_to_use += amount;
			}
		}

		if (!strcmp(element->name, spellElement_missile.name)) {
			//Set the propulsion to missile.
			propulsion = PROPULSION_MISSILE;
			traveltime = element->duration;
			if (newbie) {
				//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
				chance = rand()%10;
				if (chance >= spellcasting/10)
					traveltime -= rand()%(1000/(spellcasting+1));
				if (traveltime < 30)
					traveltime = 30; //Range checking.
			}
			traveltime += (((element->mana + extramagic_to_use) - element->base_mana) / element->overload_multiplier) * element->duration;
		} else if (!strcmp(element->name, spellElement_light.name)) {
			entity = newEntity(175, 1, map.entities); // black magic ball
			entity->parent = caster->uid;
			entity->x = caster->x;
			entity->y = caster->y;
			entity->z = -5.5 + ((-6.5f + -4.5f) / 2) * sin(0);
			entity->skill[7] = -5.5; //Base z.
			entity->sizex = 1;
			entity->sizey = 1;
			entity->yaw = caster->yaw;
			entity->flags[UPDATENEEDED]=TRUE;
			entity->flags[PASSABLE]=TRUE;
			entity->flags[BRIGHT]=TRUE;
			entity->behavior=&actMagiclightBall;
			entity->skill[4] = entity->x; //Store what x it started shooting out from the player at.
			entity->skill[5] = entity->y; //Store what y it started shooting out from the player at.
			entity->skill[12] = (element->duration * (((element->mana + extramagic_to_use) / element->base_mana) * element->overload_multiplier)); //How long this thing lives.
			node_t *spellnode = list_AddNodeLast(&entity->children);
			spellnode->element = copySpell(spell); //We need to save the spell since this is a channeled spell.
			channeled_spell = (spell_t*)(spellnode->element);
			spellnode->size = sizeof(spell_t);
			((spell_t *)spellnode->element)->caster = caster->uid;
			if( using_magicstaff )
				((spell_t *)spellnode->element)->magicstaff = TRUE;
			spellnode->deconstructor = &spellDeconstructor;
			if (newbie) {
				//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
				chance = rand()%10;
				if (chance >= spellcasting/10) {
					// lifespan of the lightball
					entity->skill[12] -= rand()%(2000/(spellcasting+1));
					if (entity->skill[12] < 180)
						entity->skill[12] = 180; //Range checking.
				}
			}
			if (using_magicstaff || trap) {
				entity->skill[12] = MAGICSTAFF_LIGHT_DURATION; //TODO: Grab the duration from the magicstaff or trap?
				((spell_t *)spellnode->element)->sustain = FALSE;
			} else {
				entity->skill[12] /= getCostOfSpell((spell_t *)spellnode->element);
			}
			((spell_t *)spellnode->element)->channel_duration = entity->skill[12]; //Tell the spell how long it's supposed to last so that it knows what to reset its timer to.
			result = entity;

			playSoundEntity(entity, 165, 128 );
		} else if (!strcmp(element->name, spellElement_invisible.name)) {
			int duration = element->duration;
			duration += (((element->mana + extramagic_to_use) - element->base_mana) / element->overload_multiplier) * element->duration;
			node_t *spellnode = list_AddNodeLast(&caster->getStats()->magic_effects);
			spellnode->element = copySpell(spell); //We need to save the spell since this is a channeled spell.
			channeled_spell = (spell_t*)(spellnode->element);
			channeled_spell->magic_effects_node = spellnode;
			spellnode->size = sizeof(spell_t);
			((spell_t *)spellnode->element)->caster = caster->uid;
			spellnode->deconstructor = &spellDeconstructor;
			if (newbie) {
				//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
				chance = rand()%10;
				if (chance >= spellcasting/10)
					duration -= rand()%(1000/(spellcasting+1));
				if (duration < 180)
					duration = 180; //Range checking.
			}
			duration /= getCostOfSpell((spell_t *)spellnode->element);
			channeled_spell->channel_duration = duration; //Tell the spell how long it's supposed to last so that it knows what to reset its timer to.
			stat->EFFECTS[EFF_INVISIBLE] = TRUE;
			stat->EFFECTS_TIMERS[EFF_INVISIBLE] = duration;
			for (i = 0; i < numplayers; ++i) {
				if (caster == players[i]) {
					serverUpdateEffects(i);
				}
			}

			playSoundEntity(caster, 166, 128 );
			spawnMagicEffectParticles(caster->x,caster->y,caster->z,174);
		} else if (!strcmp(element->name, spellElement_levitation.name)) {
			int duration = element->duration;
			duration += (((element->mana + extramagic_to_use) - element->base_mana) / element->overload_multiplier) * element->duration;
			node_t *spellnode = list_AddNodeLast(&caster->getStats()->magic_effects);
			spellnode->element = copySpell(spell); //We need to save the spell since this is a channeled spell.
			channeled_spell = (spell_t*)(spellnode->element);
			channeled_spell->magic_effects_node = spellnode;
			spellnode->size = sizeof(spell_t);
			((spell_t *)spellnode->element)->caster = caster->uid;
			spellnode->deconstructor = &spellDeconstructor;
			if (newbie) {
				//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
				chance = rand()%10;
				if (chance >= spellcasting/10)
					duration -= rand()%(1000/(spellcasting+1));
				if (duration < 180)
					duration = 180; //Range checking.
			}
			duration /= getCostOfSpell((spell_t *)spellnode->element);
			channeled_spell->channel_duration = duration; //Tell the spell how long it's supposed to last so that it knows what to reset its timer to.
			stat->EFFECTS[EFF_LEVITATING] = TRUE;
			stat->EFFECTS_TIMERS[EFF_LEVITATING] = duration;
			for (i = 0; i < numplayers; ++i) {
				if (caster == players[i]) {
					serverUpdateEffects(i);
				}
			}

			playSoundEntity(caster, 178, 128 );
			spawnMagicEffectParticles(caster->x,caster->y,caster->z,170);
		} else if (!strcmp(element->name, spellElement_teleportation.name)) {
			caster->teleportRandom();
		} else if (!strcmp(element->name, spellElement_identify.name)) {
			for (i = 0; i < numplayers; ++i) {
				if (caster == players[i]) {
					spawnMagicEffectParticles(caster->x,caster->y,caster->z,171);
					if (i != 0) {
						//Tell the client to identify an item.
						strcpy((char *)net_packet->data,"IDEN");
						net_packet->address.host = net_clients[i - 1].host;
						net_packet->address.port = net_clients[i - 1].port;
						net_packet->len = 4;
						sendPacketSafe(net_sock, -1, net_packet, i-1);
					} else {
						//Identify an item.
						shootmode = FALSE;
						gui_mode = GUI_MODE_INVENTORY; //Reset the GUI to the inventory.
						identifygui_active = TRUE;
						identifygui_appraising = FALSE;
						//identifygui_mode = TRUE;
					}
				}
			}

			playSoundEntity(caster, 167, 128 );
		} else if (!strcmp(element->name, spellElement_removecurse.name)) {
			for (i = 0; i < numplayers; ++i) {
				if (caster == players[i]) {
					spawnMagicEffectParticles(caster->x,caster->y,caster->z,169);
					if (i != 0) {
						//Tell the client to uncurse an item.
						strcpy((char *)net_packet->data,"RCUR");
						net_packet->address.host = net_clients[i - 1].host;
						net_packet->address.port = net_clients[i - 1].port;
						net_packet->len = 4;
						sendPacketSafe(net_sock, -1, net_packet, i-1);
					} else {
						//Uncurse an item
						shootmode = FALSE;
						gui_mode = GUI_MODE_INVENTORY; //Reset the GUI to the inventory.
						removecursegui_active = TRUE;
					}
				}
			}

			playSoundEntity(caster, 167, 128 );
		} else if (!strcmp(element->name, spellElement_magicmapping.name)) {
			for (i = 0; i < numplayers; ++i) {
				if (caster == players[i]) {
					spawnMagicEffectParticles(caster->x,caster->y,caster->z,171);
					spell_magicMap(i);
				}
			}

			playSoundEntity(caster, 167, 128 );
		} else if (!strcmp(element->name, spellElement_heal.name)) { //TODO: Make it work for NPCs.
			for (i = 0; i < numplayers; ++i) {
				if (caster == players[i]) {
					int amount = element->damage * (((element->mana + extramagic_to_use) / element->base_mana) * element->overload_multiplier); //Amount to heal.
					if (newbie) {
						//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
						chance = rand()%10;
						if (chance >= spellcasting/10)
							amount -= rand()%(1000/(spellcasting+1));
						if (amount < 8)
							amount = 8; //Range checking.
					}
					spell_changeHealth(players[i], amount);
					playSoundEntity(caster, 168, 128);

					for(node = map.entities->first; node->next; node = node->next) {
						entity = (Entity *)(node->element);
						if ( !entity ||  entity==caster )
							continue;
						if( entity->behavior!=&actPlayer && entity->behavior!=&actMonster )
							continue;

						if (entityDist(entity, caster) <= HEAL_RADIUS && entity->checkFriend(caster)) {
							spell_changeHealth(entity, amount);
							playSoundEntity(entity, 168, 128);
							spawnMagicEffectParticles(entity->x,entity->y,entity->z,169);
						}
					}
					break;
				}
			}

			playSoundEntity(caster, 168, 128);
			spawnMagicEffectParticles(caster->x,caster->y,caster->z,169);
		} else if (!strcmp(element->name, spellElement_cure_ailment.name)) { //TODO: Generalize it for NPCs too?
			for (i = 0; i < numplayers; ++i) {
				if (caster == players[i]) {
					Uint32 color = SDL_MapRGB(mainsurface->format,0,255,0);
					messagePlayerColor(i,color,language[411]);
					int c = 0;
					for (c = 0; c < NUMEFFECTS; ++c) { //This does a whole lot more than just cure ailments.
						stats[i].EFFECTS[c]=FALSE;
						stats[i].EFFECTS_TIMERS[c]=0;
					}
					serverUpdateEffects(player);
					playSoundEntity(entity, 168, 128);

					for(node = map.entities->first; node->next; node = node->next) {
						entity = (Entity *)(node->element);
						if( !entity || entity==caster )
							continue;
						if( entity->behavior!=&actPlayer && entity->behavior!=&actMonster )
							continue;
						stat_t *target_stat = entity->getStats();
						if( target_stat ) {
							if (entityDist(entity, caster) <= HEAL_RADIUS && entity->checkFriend(caster)) {
								for (c = 0; c < NUMEFFECTS; ++c) { //This does a whole lot more than just cure ailments.
									target_stat->EFFECTS[c]=FALSE;
									target_stat->EFFECTS_TIMERS[c]=0;
								}
								if( entity->behavior==&actPlayer )
									serverUpdateEffects(entity->skill[2]);
								if( entity->flags[BURNING] ) {
									entity->flags[BURNING] = FALSE;
									serverUpdateEntityFlag(entity,BURNING);
								}
								playSoundEntity(entity, 168, 128);
								spawnMagicEffectParticles(entity->x,entity->y,entity->z,169);
							}
						}
					}
					break;
				}
			}

			playSoundEntity(caster, 168, 128 );
			spawnMagicEffectParticles(caster->x,caster->y,caster->z,169);
		}

		if (propulsion == PROPULSION_MISSILE) {
			entity = newEntity(168, 1, map.entities); // red magic ball
			entity->parent = caster->uid;
			entity->x = caster->x;
			entity->y = caster->y;
			entity->z = -1;
			entity->sizex = 1;
			entity->sizey = 1;
			entity->yaw = caster->yaw;
			entity->flags[UPDATENEEDED]=TRUE;
			entity->flags[PASSABLE]=TRUE;
			entity->flags[BRIGHT]=TRUE;
			entity->behavior = &actMagicMissile;
			
			double missile_speed = 4 * ((double)element->mana / element->overload_multiplier); //TODO: Factor in base mana cost?
			entity->vel_x = cos(entity->yaw) * (missile_speed);
			entity->vel_y = sin(entity->yaw) * (missile_speed);

			entity->skill[4] = 0;
			entity->skill[5] = traveltime;
			node = list_AddNodeFirst(&entity->children);
			node->element = copySpell(spell);
			((spell_t *)node->element)->caster = caster->uid;
			node->deconstructor = &spellDeconstructor;
			node->size = sizeof(spell_t);

			if( !strcmp(spell->name, spell_fireball.name) )
				playSoundEntity(entity, 164, 128 );
			else if( !strcmp(spell->name, spell_lightning.name) )
				playSoundEntity(entity, 171, 128 );
			else if( !strcmp(spell->name, spell_cold.name) )
				playSoundEntity(entity, 172, 128 );
			else
				playSoundEntity(entity, 169, 128 );
			result = entity;
		}

		extramagic_to_use = 0;
		if (extramagic > 0) {
			//Extra magic. Pump it in here?
			chance = rand()%5;
			if (chance == 1) {
				//Use some of that extra magic in this element.
				int amount = rand()%extramagic;
				extramagic -= amount;
				extramagic_to_use += amount; //TODO: Make the elements here use this? Looks like they won't, currently. Oh well.
			}
		}
		//TODO: Add the status/conditional elements/modifiers (probably best as elements) too. Like onCollision or something.
		//element = (spellElement_t *)element->elements->first->element;
		node = element->elements.first;
		if( node ) {
			element = (spellElement_t *)node->element;
			if (!strcmp(element->name, spellElement_force.name)) {
				//Give the spell force properties.
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 173;
				}
				if (newbie) {
					//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
					chance = rand()%10;
					if (chance >= spellcasting/10)
						element->damage -= rand()%(100/(spellcasting+1));
					if (element->damage < 10)
						element->damage = 10; //Range checking.
				}
			} else if (!strcmp(element->name, spellElement_fire.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 168;
					//entity->skill[4] = entity->x; //Store what x it started shooting out from the player at.
					//entity->skill[5] = entity->y; //Store what y it started shooting out from the player at.
					//entity->skill[12] = (100 * stat->PROFICIENCIES[PRO_SPELLCASTING]) + (100 * stat->PROFICIENCIES[PRO_MAGIC]) + (100 * (rand()%10)) + (10 * (rand()%10)) + (rand()%10); //How long this thing lives.

					//playSoundEntity( entity, 59, 128 );
				}
				if (newbie) {
					//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
					chance = rand()%10;
					if (chance >= spellcasting/10)
						element->damage -= rand()%(100/(spellcasting+1));
					if (element->damage < 10)
						element->damage = 10; //Range checking.
				}
			} else if (!strcmp(element->name, spellElement_lightning.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 170;
				}
				if (newbie) {
					//This guy's a newbie. There's a chance they've screwed up and negatively impacted the efficiency of the spell.
					chance = rand()%10;
					if (chance >= spellcasting/10)
						element->damage -= rand()%(100/(spellcasting+1));
					if (element->damage < 10)
						element->damage = 10; //Range checking.
				}
			} else if (!strcmp(element->name, spellElement_confuse.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 173;
				}
			} else if (!strcmp(element->name, spellElement_cold.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 172;
				}
			} else if (!strcmp(element->name, spellElement_dig.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 171;
				}
			} else if (!strcmp(element->name, spellElement_locking.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 171;
				}
			} else if (!strcmp(element->name, spellElement_opening.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 171;
				}
			} else if (!strcmp(element->name, spellElement_slow.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 171;
				}
			} else if (!strcmp(element->name, spellElement_sleep.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 172;
				}
			} else if (!strcmp(spell->name, spell_magicmissile.name)) {
				if (propulsion == PROPULSION_MISSILE) {
					entity->sprite = 173;
				}
			}
		}
	}

	//Random chance to level up spellcasting skill.
	if(rand()%4==0) {
		caster->increaseSkill(PRO_SPELLCASTING);
	}
	if(rand()%5==0) {
		caster->increaseSkill(PRO_MAGIC); // otherwise you will basically never be able to learn all the spells in the game...
	}

	if (spell_isChanneled(spell) && !using_magicstaff) { //TODO: What about magic traps and channeled spells?
		if (!channeled_spell) {
				printlog( "What. Spell is channeled but no channeled_spell pointer? What sorcery is this?\n");
		} else {
			int target_client = 0;
			for (i = 0; i < numplayers; ++i) {
				if (players[i] == caster) {
					target_client = i;
				}
			}
			//printlog( "Client is: %d\n", target_client);
			if (multiplayer == SERVER && target_client != 0) {
				strcpy( (char *)net_packet->data, "CHAN" );
				net_packet->data[4] = clientnum;
				SDLNet_Write32(spell->ID, &net_packet->data[5]);
				net_packet->address.host = net_clients[target_client - 1].host;
				net_packet->address.port = net_clients[target_client - 1].port;
				net_packet->len = 9;
				sendPacketSafe(net_sock, -1, net_packet, target_client-1);
			}
			//Add this spell to the list of channeled spells.
			node = list_AddNodeLast(&channeledSpells[target_client]);
			node->element = channeled_spell;
			node->size = sizeof(spell_t);
			node->deconstructor = &emptyDeconstructor;
			channeled_spell->sustain_node = node;
		}
	}

	return result;
}
コード例 #17
0
ファイル: shops.cpp プロジェクト: ganthore/Barony
void startTradingServer(Entity* entity, int player)
{
	if (!entity)
	{
		return;
	}
	if ( multiplayer == CLIENT )
	{
		return;
	}
	if (!players[player] || !players[player]->entity)
	{
		return;
	}

	Stat* stats = entity->getStats();
	if ( stats == NULL )
	{
		return;
	}

	if ( player == 0 )
	{
		shootmode = false;
		gui_mode = GUI_MODE_SHOP;
		shopInv = &stats->inventory;
		shopkeeper = entity->getUID();
		shoptimer = ticks - 1;
		shopspeech = language[194 + rand() % 3];
		shopinventorycategory = 7;
		sellitem = NULL;
		Entity* entity = uidToEntity(shopkeeper);
		shopkeepertype = entity->monsterStoreType;
		shopkeepername = stats->name;
		shopitemscroll = 0;
		identifygui_active = false;
		closeRemoveCurseGUI();

		//Initialize shop gamepad code here.
		if ( shopinvitems[0] != nullptr )
		{
			selectedShopSlot = 0;
			warpMouseToSelectedShopSlot();
		}
		else
		{
			selectedShopSlot = -1;
		}
	}
	else if ( multiplayer == SERVER )
	{
		// open shop on client
		Stat* entitystats = entity->getStats();
		strcpy((char*)net_packet->data, "SHOP");
		SDLNet_Write32((Uint32)entity->getUID(), &net_packet->data[4]);
		net_packet->data[8] = entity->monsterStoreType;
		strcpy((char*)(&net_packet->data[9]), entitystats->name);
		net_packet->data[9 + strlen(entitystats->name)] = 0;
		net_packet->address.host = net_clients[player - 1].host;
		net_packet->address.port = net_clients[player - 1].port;
		net_packet->len = 9 + strlen(entitystats->name) + 1;
		sendPacketSafe(net_sock, -1, net_packet, player - 1);

		// fill client's shop inventory with items
		node_t* node;
		for ( node = entitystats->inventory.first; node != NULL; node = node->next )
		{
			Item* item = (Item*)node->element;
			strcpy((char*)net_packet->data, "SHPI");
			SDLNet_Write32(item->type, &net_packet->data[4]);
			net_packet->data[8] = (char)item->status;
			net_packet->data[9] = (char)item->beatitude;
			net_packet->data[10] = (unsigned char)item->count;
			SDLNet_Write32((Uint32)item->appearance, &net_packet->data[11]);
			if ( item->identified )
			{
				net_packet->data[15] = 1;
			}
			else
			{
				net_packet->data[15] = 0;
			}
			net_packet->address.host = net_clients[player - 1].host;
			net_packet->address.port = net_clients[player - 1].port;
			net_packet->len = 16;
			sendPacketSafe(net_sock, -1, net_packet, player - 1);
		}
	}
	entity->skill[0] = 4; // talk state
	entity->skill[1] = players[player]->entity->getUID();
	messagePlayer(player, language[1122], stats->name);
}
コード例 #18
0
void updateIdentifyGUI() {
	//if (openedChest[clientnum])
	//	return; //Cannot have the identify and chest GUIs open at the same time.

	SDL_Rect pos;
	node_t *node;
	int y, c;

	//Identify GUI.
	if (identifygui_active) {
		//Center the identify GUI.
		pos.x = IDENTIFY_GUI_X;
		pos.y = IDENTIFY_GUI_Y;
		drawImage(identifyGUI_img, NULL, &pos);
		
		//Buttons
		if( mousestatus[SDL_BUTTON_LEFT] ) {
			//Identify GUI scroll up button.
			if (omousey >= IDENTIFY_GUI_Y + 16 && omousey < IDENTIFY_GUI_Y + 52) {
				if (omousex >= IDENTIFY_GUI_X + (identifyGUI_img->w - 28) && omousex < IDENTIFY_GUI_X + (identifyGUI_img->w - 12)) {
					buttonclick = 7;
					identifyscroll--;
					mousestatus[SDL_BUTTON_LEFT] = 0;
				}
			}
			//Identify GUI scroll down button.
			else if (omousey >= IDENTIFY_GUI_Y + 52 && omousey < IDENTIFY_GUI_Y + 88) {
				if (omousex >= IDENTIFY_GUI_X + (identifyGUI_img->w - 28) && omousex < IDENTIFY_GUI_X + (identifyGUI_img->w - 12)) {
					buttonclick = 8;
					identifyscroll++;
					mousestatus[SDL_BUTTON_LEFT] = 0;
				}
			}
			else if (omousey >= IDENTIFY_GUI_Y && omousey < IDENTIFY_GUI_Y + 15) {
				//Identify GUI close button.
				if (omousex >= IDENTIFY_GUI_X + 393 && omousex < IDENTIFY_GUI_X + 407) {
					buttonclick = 9;
					mousestatus[SDL_BUTTON_LEFT] = 0;
				}
				if (omousex >= IDENTIFY_GUI_X && omousex < IDENTIFY_GUI_X + 377 && omousey >= IDENTIFY_GUI_Y && omousey < IDENTIFY_GUI_Y + 15) {
					gui_clickdrag = TRUE;
					dragging_identifyGUI = TRUE;
					dragoffset_x = omousex - IDENTIFY_GUI_X;
					dragoffset_y = omousey - IDENTIFY_GUI_Y;
					mousestatus[SDL_BUTTON_LEFT] = 0;
				}
			}
		}
		
		// mousewheel
		if( omousex>=IDENTIFY_GUI_X+12 && omousex<IDENTIFY_GUI_X+(identifyGUI_img->w-28) ) {
			if( omousey>=IDENTIFY_GUI_Y+16 && omousey<IDENTIFY_GUI_Y+(identifyGUI_img->h-8) ) {
				if( mousestatus[SDL_BUTTON_WHEELDOWN] ) {
					mousestatus[SDL_BUTTON_WHEELDOWN] = 0;
					identifyscroll++;
				} else if( mousestatus[SDL_BUTTON_WHEELUP] ) {
					mousestatus[SDL_BUTTON_WHEELUP] = 0;
					identifyscroll--;
				}
			}
		}
		
		if (dragging_identifyGUI) {
			if (gui_clickdrag) {
				identifygui_offset_x = (omousex - dragoffset_x) - (IDENTIFY_GUI_X - identifygui_offset_x);
				identifygui_offset_y = (omousey - dragoffset_y) - (IDENTIFY_GUI_Y - identifygui_offset_y);
				if (IDENTIFY_GUI_X <= camera.winx)
					identifygui_offset_x = camera.winx - (IDENTIFY_GUI_X - identifygui_offset_x);
				if (IDENTIFY_GUI_X > camera.winx + camera.winw - identifyGUI_img->w)
					identifygui_offset_x = (camera.winx + camera.winw - identifyGUI_img->w) - (IDENTIFY_GUI_X - identifygui_offset_x);
				if (IDENTIFY_GUI_Y <= camera.winy)
					identifygui_offset_y = camera.winy - (IDENTIFY_GUI_Y - identifygui_offset_y);
				if (IDENTIFY_GUI_Y > camera.winy + camera.winh - identifyGUI_img->h)
					identifygui_offset_y = (camera.winy + camera.winh - identifyGUI_img->h) - (IDENTIFY_GUI_Y - identifygui_offset_y);
			} else {
				dragging_identifyGUI = FALSE;
			}
		}

		list_t *identify_inventory = &stats[clientnum].inventory;

		if (!identify_inventory) {
			messagePlayer(0, "Warning: stats[%d].inventory is not a valid list. This should not happen.", clientnum);
		} else {
			//Print the window label signifying this as the identify GUI.
			//char *window_name = (char*)malloc(sizeof(char));
			//strcpy(window_name, "Identify Item");
			char *window_name;
			if (identifygui_appraising)
				window_name = language[317];
			else
				window_name = language[318];
			ttfPrintText(ttf8, (IDENTIFY_GUI_X + 2 + ((identifyGUI_img->w / 2) - ((TTF8_WIDTH * longestline(window_name)) / 2))), IDENTIFY_GUI_Y + 4, window_name);

			//Identify GUI up button.
			if (buttonclick == 7) {
				pos.x = IDENTIFY_GUI_X + (identifyGUI_img->w - 28); pos.y = IDENTIFY_GUI_Y + 16;
				pos.w = 0; pos.h = 0;
				drawImage(invup_bmp, NULL, &pos);
			}
			//Identify GUI down button.
			if (buttonclick == 8) {
				pos.x = IDENTIFY_GUI_X + (identifyGUI_img->w - 28); pos.y = IDENTIFY_GUI_Y + 52;
				pos.w = 0; pos.h = 0;
				drawImage(invdown_bmp, NULL, &pos);
			}
			//Identify GUI close button.
			if (buttonclick == 9) {
				pos.x = IDENTIFY_GUI_X + 393; pos.y = IDENTIFY_GUI_Y;
				pos.w = 0; pos.h = 0;
				drawImage(invclose_bmp, NULL, &pos);
				identifygui_active = FALSE;
				identifygui_appraising = FALSE;
			}

			Item *item = NULL;
			if (omousex >= IDENTIFY_GUI_X && omousex < IDENTIFY_GUI_X + (identifyGUI_img->w - 28)) {
				pos.x = IDENTIFY_GUI_X + 12;
				pos.w = 0; pos.h = 0;
				if (omousey >= IDENTIFY_GUI_Y + 16 && omousey < IDENTIFY_GUI_Y + 34) { //First inventory slot.
					pos.y = IDENTIFY_GUI_Y + 16;
					drawImage(inventoryoptionChest_bmp, NULL, &pos);
					if (mousestatus[SDL_BUTTON_LEFT]) {
						mousestatus[SDL_BUTTON_LEFT] = 0;
						identifyGUIIdentify(identify_items[0]);
					}
				}
				else if (omousey >= IDENTIFY_GUI_Y + 34 && omousey < IDENTIFY_GUI_Y + 52) {
					pos.y = IDENTIFY_GUI_Y + 34;
					drawImage(inventoryoptionChest_bmp, NULL, &pos);
					if (mousestatus[SDL_BUTTON_LEFT]) {
						mousestatus[SDL_BUTTON_LEFT]=0;
						identifyGUIIdentify(identify_items[1]);
					}
				}
				else if (omousey >= IDENTIFY_GUI_Y + 52 && omousey < IDENTIFY_GUI_Y + 70 ) {
					pos.y = IDENTIFY_GUI_Y + 52;
					drawImage(inventoryoptionChest_bmp, NULL, &pos);
					if( mousestatus[SDL_BUTTON_LEFT] ) {
						mousestatus[SDL_BUTTON_LEFT]=0;
						identifyGUIIdentify(identify_items[2]);
					}
				}
				else if (omousey >= IDENTIFY_GUI_Y + 70 && omousey < IDENTIFY_GUI_Y + 88) {
					pos.y = IDENTIFY_GUI_Y + 70;
					drawImage(inventoryoptionChest_bmp, NULL, &pos);
					if( mousestatus[SDL_BUTTON_LEFT] ) {
						mousestatus[SDL_BUTTON_LEFT]=0;
						identifyGUIIdentify(identify_items[3]);
					}
				}
			}

			//Okay, now prepare to render all the items.
			y = IDENTIFY_GUI_Y + 22; c = 0;
			if (identify_inventory) {
				for (node = identify_inventory->first; node != NULL; node = node->next) {
					item = (Item *) node->element;
					if (item && !item->identified)
						c++;
				}
				identifyscroll = std::max(0, std::min(identifyscroll, c - 4));
				for (c = 0; c < 4; ++c) {
					identify_items[c] = NULL;
				}
				c = 0;

				//Actually render the items.
				for (node = identify_inventory->first; node != NULL; node = node->next) {
					if (node->element) {
						item = (Item *) node->element;
						if (item && !item->identified) { //Skip over all identified items.
							c++;
							if (c <= identifyscroll)
								continue;
							identify_items[c - identifyscroll - 1] = item;
							char tempstr[64] = { 0 };
							strncpy(tempstr,item->description(),46);
							if( strlen(tempstr)==46 )
								strcat(tempstr," ...");
							ttfPrintText(ttf8,IDENTIFY_GUI_X+36,y,tempstr);
							pos.x = IDENTIFY_GUI_X + 16;
							pos.y = IDENTIFY_GUI_Y + 17 + 18 * (c - identifyscroll - 1);
							pos.w = 16; pos.h = 16;
							drawImageScaled(itemSprite(item), NULL, &pos);
							y += 18;
							if (c > 3 + identifyscroll)
								break;
						}
					}
				}
			}
		}
	}
} //updateIdentifyGUI()
コード例 #19
0
ファイル: mechanisms.cpp プロジェクト: TurningWheel/Barony
void actSwitch(Entity* my)
{
	//TODO: If powered on, and it detects a depowered neighbor, it should pulse that neighbor to turn on.
	//Thus, this function needs to be called periodically.
	//This is so that if a switch goes off and there's another switch on the network, the entire network shuts off regardless of the other switch's status.
	//So then when that second switch's actSwitch() comes up, and if it's on, it'll repower the entire network -- which will stay powered until ALL connected switches go off.
	my->flags[PASSABLE] = true; // these should ALWAYS be passable. No exceptions

	if ( multiplayer != CLIENT )
	{
		int i = 0;
		for (i = 0; i < MAXPLAYERS; ++i)
		{
			if ( (i == 0 && selectedEntity == my) || (client_selected[i] == my) )
			{
				if (inrange[i])   //Act on it only if the player (or monster, if/when this is changed to support monster interaction?) is in range.
				{
					messagePlayer(i, language[1110]);
					playSoundEntity(my, 56, 64);
					my->toggleSwitch();
				}
			}
		}
		if ( my->isInteractWithMonster() )
		{
			my->toggleSwitch();
			my->clearMonsterInteract();
		}

		if (my->skill[0])
		{
			//Power on any neighbors that don't have power.
			my->switchUpdateNeighbors();
			//TODO: Alternatively, instead of using CPU cycles on this, have the recursive network shutdown alert any switches connected to it that are powered on that it's shutting down, so that they can repower the network come next frame.
		}
	}
	else
	{
		my->flags[NOUPDATE] = true;
	}

	// Rotate the switch when it is on/off.
	if ( my->skill[0] )
	{
		if ( my->roll > -PI / 4 )
		{
			my->roll -= std::max<real_t>((my->roll + PI / 4) / 2, .05);
		}
		else
		{
			my->roll = -PI / 4;
		}
	}
	else
	{
		if ( my->roll < PI / 4 )
		{
			my->roll += std::max<real_t>(-(my->roll - PI / 4) / 2, .05);
		}
		else
		{
			my->roll = PI / 4;
		}
	}
}
コード例 #20
0
ファイル: actboulder.cpp プロジェクト: Gilgatex/Barony
void actBoulder(Entity *my) {
	int i;
	
	my->skill[2]=-7; // invokes actEmpty() on clients
	my->flags[UPDATENEEDED] = TRUE;

	bool noground=FALSE;
	int x = std::min<int>(std::max(0,(int)(my->x/16)),map.width);
	int y = std::min<int>(std::max(0,(int)(my->y/16)),map.height);
	Uint32 index = y*MAPLAYERS+x*MAPLAYERS*map.height;
	if( !map.tiles[index] || animatedtiles[map.tiles[index]] )
		noground = TRUE;

	// gravity
	bool nobounce=TRUE;
	if( !BOULDER_NOGROUND )
		if( noground )
			BOULDER_NOGROUND = TRUE;
	if( my->z < 0 || BOULDER_NOGROUND ) {
		my->vel_z = std::min(my->vel_z+.1,3.0);
		nobounce = TRUE;
		if( my->z >= 128 ) {
			list_RemoveNode(my->mynode);
			return;
		}
		if( !BOULDER_NOGROUND ) {
			if( my->z >= -8 && fabs(my->vel_z) > 2 ) {
				node_t *node;
				for( node=map.entities->first; node!=NULL; node=node->next ) {
					Entity *entity = (Entity *)node->element;
					if( entity == my )
						continue;
					if( boulderCheckAgainstEntity(my,entity) )
						return;
				}
			}
		}
	} else {
		if( fabs(my->vel_z) > 1 ) {
			playSoundEntity(my,182,128);
			my->vel_z = -(my->vel_z/2);
			nobounce = TRUE;
		} else {
			if( my->vel_z )
				playSoundEntity(my,182,128);
			my->vel_z = 0;
			nobounce = FALSE;
		}
		my->z = 0;
	}
	my->z += my->vel_z;
	if( nobounce ) {
		if( !my->flags[PASSABLE] ) {
			my->flags[PASSABLE] = TRUE;
			if( multiplayer==SERVER )
				serverUpdateEntityFlag(my,PASSABLE);
		}
		if( !BOULDER_STOPPED ) {
			my->x += my->vel_x;
			my->y += my->vel_y;
			double dist = sqrt(pow(my->vel_x,2)+pow(my->vel_y,2));
			my->pitch += dist*.06;
			my->roll = PI/2;
		}
	} else if( !BOULDER_STOPPED ) {
		if( my->flags[PASSABLE] ) {
			my->flags[PASSABLE] = FALSE;
			if( multiplayer==SERVER )
				serverUpdateEntityFlag(my,PASSABLE);
		}
		
		// horizontal velocity
		my->vel_x += cos(my->yaw)*.1;
		my->vel_y += sin(my->yaw)*.1;
		if( my->vel_x > 1.5 )
			my->vel_x = 1.5;
		if( my->vel_x < -1.5 )
			my->vel_x = -1.5;
		if( my->vel_y > 1.5 )
			my->vel_y = 1.5;
		if( my->vel_y < -1.5 )
			my->vel_y = -1.5;
		int x = std::min<int>(std::max(0.0,(my->x+cos(my->yaw)*8)/16),map.width-1);
		int y = std::min<int>(std::max(0.0,(my->y+sin(my->yaw)*8)/16),map.height-1);
		if( map.tiles[OBSTACLELAYER+y*MAPLAYERS+x*MAPLAYERS*map.height] ) {
			playSoundEntity(my,181,128);
			BOULDER_STOPPED = 1;
		} else {
			my->x += my->vel_x;
			my->y += my->vel_y;
			double dist = sqrt(pow(my->vel_x,2)+pow(my->vel_y,2));
			my->pitch += dist*.06;
			my->roll = PI/2;
		
			// crush objects
			if( dist && !BOULDER_NOGROUND ) {
				node_t *node;
				for( node=map.entities->first; node!=NULL; node=node->next ) {
					Entity *entity = (Entity *)node->element;
					if( entity == my )
						continue;
					if( boulderCheckAgainstEntity(my,entity) )
						return;
				}
			}
		}
	}
	
	// pushing boulders
	if( BOULDER_STOPPED ) {
		if( !BOULDER_ROLLING ) {
			for(i=0;i<MAXPLAYERS;i++) {
				if( (i==0 && selectedEntity==my) || (client_selected[i]==my) ) {
					if(inrange[i]) {
						if( statGetSTR(stats[i])<5 ) {
							messagePlayer(i,language[456]);
						} else {
							if( players[i] ) {
								playSoundEntity(my, 151, 128);
								BOULDER_ROLLING=1;
								my->x = floor(my->x/16)*16+8;
								my->y = floor(my->y/16)*16+8;
								BOULDER_DESTX=(int)(my->x/16)*16+8;
								BOULDER_DESTY=(int)(my->y/16)*16+8;
								if( (int)(players[i]->x/16) < (int)(my->x/16) ) {
									BOULDER_ROLLDIR=0; // east
								} else if( (int)(players[i]->y/16) < (int)(my->y/16) ) {
									BOULDER_ROLLDIR=1; // south
								} else if( (int)(players[i]->x/16) > (int)(my->x/16) ) {
									BOULDER_ROLLDIR=2; // west
								} else if( (int)(players[i]->y/16) > (int)(my->y/16) ) {
									BOULDER_ROLLDIR=3; // north
								}
								switch( BOULDER_ROLLDIR ) {
									case 0:
										BOULDER_DESTX += 16;
										break;
									case 1:
										BOULDER_DESTY += 16;
										break;
									case 2:
										BOULDER_DESTX -= 16;
										break;
									case 3:
										BOULDER_DESTY -= 16;
										break;
								}
							}
						}
					}
				}
			}
		} else {
			switch( BOULDER_ROLLDIR ) {
				case 0:
					my->vel_x=1;
					my->vel_y=0;
					break;
				case 1:
					my->vel_x=0;
					my->vel_y=1;
					break;
				case 2:
					my->vel_x=-1;
					my->vel_y=0;
					break;
				case 3:
					my->vel_x=0;
					my->vel_y=-1;
					break;
			}
			int x = (my->x+my->vel_x*8)/16;
			int y = (my->y+my->vel_y*8)/16;
			x = std::min<unsigned int>(std::max(0,x),map.width-1);
			y = std::min<unsigned int>(std::max(0,y),map.height-1);
			if( map.tiles[OBSTACLELAYER+y*MAPLAYERS+x*MAPLAYERS*map.height] ) {
				BOULDER_ROLLING = 0;
			} else {
				my->x += my->vel_x;
				my->y += my->vel_y;
				double dist = sqrt(pow(my->vel_x,2)+pow(my->vel_y,2));
				my->pitch += dist*.06;

				if( BOULDER_ROLLDIR==0 ) {
					if( my->x>=BOULDER_DESTX ) {
						my->x=BOULDER_DESTX;
						BOULDER_ROLLING=0;
					}
				} else if( BOULDER_ROLLDIR==1 ) {
					if( my->y>=BOULDER_DESTY ) {
						my->y=BOULDER_DESTY;
						BOULDER_ROLLING=0;
					}
				} else if( BOULDER_ROLLDIR==2 ) {
					if( my->x<=BOULDER_DESTX ) {
						my->x=BOULDER_DESTX;
						BOULDER_ROLLING=0;
					}
				} else if( BOULDER_ROLLDIR==3 ) {
					if( my->y<=BOULDER_DESTY ) {
						my->y=BOULDER_DESTY;
						BOULDER_ROLLING=0;
					}
				}
				double dir = my->yaw - BOULDER_ROLLDIR*PI/2;
				while( dir >= PI )
					dir -= PI*2;
				while( dir < -PI )
					dir += PI*2;
				my->yaw -= dir/16;
				while( my->yaw < 0 )
					my->yaw += 2*PI;
				while( my->yaw >= 2*PI )
					my->yaw -= 2*PI;
		
				// crush objects
				if( dist && !BOULDER_NOGROUND ) {
					node_t *node;
					for( node=map.entities->first; node!=NULL; node=node->next ) {
						Entity *entity = (Entity *)node->element;
						if( entity == my )
							continue;
						if( boulderCheckAgainstEntity(my,entity) )
							return;
					}
				}
			}
		}
	}

	// wrap around angles
	while( my->pitch >= PI*2 )
		my->pitch -= PI*2;
	while( my->pitch < 0 )
		my->pitch += PI*2;
	while( my->roll >= PI*2 )
		my->roll -= PI*2;
	while( my->roll < 0 )
		my->roll += PI*2;
	
	// rolling sound
	if( !BOULDER_STOPPED && (fabs(my->vel_x)>0 || fabs(my->vel_y)>0) ) {
		BOULDER_AMBIENCE++;
		if( BOULDER_AMBIENCE>=TICKS_PER_SECOND/3 ) {
			BOULDER_AMBIENCE=0;
			playSoundEntity(my, 151, 128);
		}
	}
}
コード例 #21
0
ファイル: mechanisms.cpp プロジェクト: TurningWheel/Barony
void actSwitchWithTimer(Entity* my)
{
	my->flags[PASSABLE] = true; // these should ALWAYS be passable. No exceptions

	if ( multiplayer != CLIENT )
	{
		int i = 0;
		for ( i = 0; i < MAXPLAYERS; ++i )
		{
			if ( (i == 0 && selectedEntity == my) || (client_selected[i] == my) )
			{
				// server/client has clicked on the entity.
				if ( inrange[i] )   //Act on it only if the player (or monster, if/when this is changed to support monster interaction?) is in range.
				{
					switch ( my->leverStatus )
					{
						case 0:
							messagePlayer(i, language[2360]);
							break;
						case 1:
							messagePlayer(i, language[2361]);
							break;
						case 2:
							messagePlayer(i, language[2362]);
							break;
						default:
							messagePlayer(i, language[2363]);
							break;
					}

					if ( my->leverStatus < 3 )
					{
						++my->leverStatus;
						playSoundEntity(my, 248, 64);
						serverUpdateEntitySkill(my, 1);
						if ( my->leverStatus == 3 )
						{
							playSoundEntity(my, 56, 64);
							my->toggleSwitch();
						}
					}
				}
			}
		}

		if ( my->leverStatus == 4 )
		{
			//Power on any neighbors that don't have power.
			my->switchUpdateNeighbors();
			//TODO: Alternatively, instead of using CPU cycles on this, have the recursive network shutdown alert any switches connected to it that are powered on that it's shutting down, so that they can repower the network come next frame.
		}
	}
	else
	{
		my->flags[NOUPDATE] = true;
	}

	// Rotate the switch when it is on/off.
	if ( my->leverStatus == 0 )
	{
		if ( my->roll > -PI / 4 )
		{
			my->roll -= std::max<real_t>((my->roll + PI / 4) / 2, .05);
		}
		else
		{
			my->roll = -PI / 4;
		}
	}
	else if (my->leverStatus == 1 ) // 1/3 of the way up
	{
		if ( my->roll < -PI / 12 )
		{
			my->roll += std::max<real_t>(-(my->roll + PI / 12) / 8, .02);
		}
		else
		{
			my->roll = -PI / 12;
		}
	}
	else if ( my->leverStatus == 2 ) // 2/3 of the way up
	{
		if ( my->roll < PI / 12 )
		{
			my->roll += std::max<real_t>(-(my->roll - PI / 12) / 8, .02);
		}
		else
		{
			my->roll = PI / 12;
		}
	}
	else if ( my->leverStatus == 3 ) // all the way up
	{
		if ( my->roll < PI / 4 )
		{
			my->roll += std::max<real_t>(-(my->roll - PI / 4) / 4, .02);
		}
		else
		{
			my->roll = PI / 4;
			if ( multiplayer != CLIENT )
			{
				my->leverStatus = 4;
				serverUpdateEntitySkill(my, 1);
			}
		}
	}
	else if ( my->leverStatus == 4 ) // ticking down
	{
		if ( my->roll > -PI / 12 )
		{
			my->roll -= (PI / 3) / static_cast<real_t>(my->leverTimerTicks); // move slowly towards 2/3rds of the resting point
			if ( my->ticks % 10 == 0 )
			{
				playSoundEntityLocal(my, 247, 32);
			}
		}
		else
		{
			my->roll = -PI / 12;
			if ( multiplayer != CLIENT )
			{
				playSoundEntity(my, 56, 64);
				my->leverStatus = 0;
				serverUpdateEntitySkill(my, 1);
				my->toggleSwitch();
			}
		}
	}
}
コード例 #22
0
ファイル: consolecommand.cpp プロジェクト: boskee/Barony
void consoleCommand(char *command_str) {
	node_t *node;
	Entity *entity;
	char name[64];
	int c;
	
	if( !command_str )
		return;

	if( !strncmp(command_str,"/ping",5) ) {
		if( multiplayer != CLIENT ) {
			messagePlayer(clientnum,language[1117],0);
		} else {
			strcpy((char *)net_packet->data,"PING");
			net_packet->data[4] = clientnum;
			net_packet->address.host = net_server.host;
			net_packet->address.port = net_server.port;
			net_packet->len = 5;
			sendPacketSafe(net_sock, -1, net_packet, 0);
			pingtime = SDL_GetTicks();
		}
	}
	else if (!strncmp(command_str, "/fov", 4)) {
		fov = atoi(&command_str[5]);
		fov = std::min(std::max<Uint32>(40,fov),100u);
	}
	else if (!strncmp(command_str, "/svflags ", 9)) {
		if( multiplayer==CLIENT ) {
			messagePlayer(clientnum,language[275]);
		} else {
			svFlags = atoi(&command_str[9]);
			messagePlayer(clientnum,language[276]);

			if( multiplayer==SERVER ) {
				// update client flags
				strcpy((char *)net_packet->data,"SVFL");
				SDLNet_Write32(svFlags,&net_packet->data[4]);
				net_packet->len = 8;

				int c;
				for( c=1; c<MAXPLAYERS; c++ ) {
					if( client_disconnected[c] )
						continue;
					net_packet->address.host = net_clients[c-1].host;
					net_packet->address.port = net_clients[c-1].port;
					sendPacketSafe(net_sock, -1, net_packet, c-1);
					messagePlayer(c,language[276]);
				}
			}
		}
	}
	else if( !strncmp(command_str,"/spawnitem ",11) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		strcpy(name,command_str+11);
		for( c=0; c<NUMITEMS; c++ ) {
			if( strstr(items[c].name_identified, name) ) {
				dropItem(newItem(static_cast<ItemType>(c),EXCELLENT,0,1,rand(),TRUE,&stats[clientnum].inventory),0);
				break;
			}
		}
		if( c==NUMITEMS ) {
			messagePlayer(clientnum,language[278],name);
		}
	}
	else if( !strncmp(command_str,"/spawncursed ",13) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		strcpy(name,command_str+13);
		for( c=0; c<NUMITEMS; c++ ) {
			if( strstr(items[c].name_identified, name) ) {
				dropItem(newItem(static_cast<ItemType>(c),WORN,-2,1,rand(),FALSE,&stats[clientnum].inventory),0);
				break;
			}
		}
		if( c==NUMITEMS ) {
			messagePlayer(clientnum,language[278],name);
		}
	}
	else if( !strncmp(command_str,"/kick ",6) ) {
		strcpy(name,command_str+6);
		if( multiplayer==SERVER ) {
			for( c=1; c<MAXPLAYERS; c++ ) {
				if( !client_disconnected[c] && !strncmp(name,stats[c].name,128) ) {
					client_disconnected[c] = TRUE;
					strcpy((char *)net_packet->data,"KICK");
					net_packet->address.host = net_clients[c-1].host;
					net_packet->address.port = net_clients[c-1].port;
					net_packet->len = 4;
					sendPacketSafe(net_sock, -1, net_packet, c-1);
					int i;
					for( i=0; i<MAXPLAYERS; i++ ) {
						messagePlayer(i,language[279],c,stats[c].name);
					}
					break;
				}
			}
			if( c==MAXPLAYERS ) {
				messagePlayer(clientnum,language[280]);
			}
		} else if( multiplayer==CLIENT ) {
			messagePlayer(clientnum,language[281]);
		} else {
			messagePlayer(clientnum,language[282]);
		}
	}
	else if( !strncmp(command_str,"/spawnbook ",11) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		strcpy(name,command_str+11);
		dropItem(newItem(READABLE_BOOK,EXCELLENT,0,1,getBook(name),TRUE,&stats[clientnum].inventory),0);
	}
	else if( !strncmp(command_str,"/savemap ",9) ) {
		if( command_str[9]!=0 ) {
			saveMap(command_str+9);
			messagePlayer(clientnum,language[283],command_str+9);
		}
	}
	else if( !strncmp(command_str,"/nextlevel",10) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		if( multiplayer==CLIENT ) {
			messagePlayer(clientnum,language[284]);
		} else {
			messagePlayer(clientnum,language[285]);
			loadnextlevel=TRUE;
		}
	}
	else if( !strncmp(command_str,"/pos",4) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		messagePlayer(clientnum,language[286],(int)camera.x,(int)camera.y,(int)camera.z,camera.ang,camera.vang);
	}
	else if( !strncmp(command_str,"/pathmap",4) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		if( players[clientnum] ) {
			int x = std::min<int>(std::max(0.0,floor(players[clientnum]->x/16)),map.width-1);
			int y = std::min<int>(std::max(0.0,floor(players[clientnum]->y/16)),map.height-1);
			messagePlayer(clientnum,"pathMapGrounded value: %d",pathMapGrounded[y+x*map.height]);
			messagePlayer(clientnum,"pathMapFlying value: %d",pathMapFlying[y+x*map.height]);
		}
	}
	else if( !strncmp(command_str,"/exit",5) ) {
		mainloop=0;
	}
	else if( !strncmp(command_str,"/showfps",8) ) {
		showfps=(showfps==FALSE);
	}
	else if( !strncmp(command_str,"/noclip",7) ) {
		if( multiplayer!=SINGLE ) {
			messagePlayer(clientnum,language[287]);
		} else {
			noclip=(noclip==FALSE);
			if( noclip )
				messagePlayer(clientnum,language[288]);
			else
				messagePlayer(clientnum,language[289]);
		}
	}
	else if( !strncmp(command_str,"/god",4) ) {
		if( multiplayer!=SINGLE ) {
			messagePlayer(clientnum,language[290]);
		} else {
			godmode=(godmode==FALSE);
			if( godmode )
				messagePlayer(clientnum,language[291]);
			else
				messagePlayer(clientnum,language[292]);
		}
	}
	else if( !strncmp(command_str,"/buddha",7) ) {
		if( multiplayer!=SINGLE ) {
			messagePlayer(clientnum,language[293]);
		} else {
			buddhamode=(buddhamode==FALSE);
			if( buddhamode )
				messagePlayer(clientnum,language[294]);
			else
				messagePlayer(clientnum,language[295]);
		}
	}
	else if( !strncmp(command_str,"/friendly",9) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		if( multiplayer==CLIENT ) {
			messagePlayer(clientnum,language[284]);
			return;
		}
		everybodyfriendly=(everybodyfriendly==FALSE);
		if( everybodyfriendly )
			messagePlayer(clientnum,language[296]);
		else
			messagePlayer(clientnum,language[297]);
	}
	else if( !strncmp(command_str,"/dowse",6) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		for( node=map.entities->first; node!=NULL; node=node->next ) {
			entity = (Entity *)node->element;
			if( entity->behavior == &actLadder )
				messagePlayer(clientnum,language[298],(int)(entity->x/16),(int)(entity->y/16));
		}
	}
	else if( !strncmp(command_str,"/thirdperson",12) ) {
		if( !(svFlags&SV_FLAG_CHEATS) ) {
			messagePlayer(clientnum,language[277]);
			return;
		}
		if( players[clientnum] != NULL ) {
			players[clientnum]->skill[3]=(players[clientnum]->skill[3]==0);
			if( players[clientnum]->skill[3]==1 )
				messagePlayer(clientnum,"thirdperson ON");
			else
				messagePlayer(clientnum,"thirdperson OFF");
		}
	}
	else if( !strncmp(command_str,"/res ",5) ) {
		xres = atoi(&command_str[5]);
		for( c=0; c<strlen(command_str); c++ ) {
			if( command_str[c] == 'x' ) {
				yres = atoi(&command_str[c+1]);
				break;
			}
		}
	}
	else if( !strncmp(command_str,"/rscale",7) ) {
		rscale = atoi(&command_str[8]);
	}
	else if( !strncmp(command_str,"/smoothlighting",15) ) {
		smoothlighting = (smoothlighting==0);
	}
	else if( !strncmp(command_str,"/fullscreen",11) ) {
		fullscreen = (fullscreen==0);
	}
	else if( !strncmp(command_str,"/shaking",8) ) {
		shaking = (shaking==0);
	}
	else if( !strncmp(command_str,"/bobbing",8) ) {
		bobbing = (bobbing==0);
	}
	else if( !strncmp(command_str,"/sfxvolume",10) ) {
		sfxvolume = atoi(&command_str[11]);
	}
	else if( !strncmp(command_str,"/musvolume",10) ) {
		musvolume = atoi(&command_str[11]);
	}
	else if( !strncmp(command_str,"/bind",5) ) {
		if( strstr(command_str,"IN_FORWARD") ) {
			impulses[IN_FORWARD] = atoi(&command_str[6]);
			printlog("Bound IN_FORWARD: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_LEFT") ) {
			impulses[IN_LEFT] = atoi(&command_str[6]);
			printlog("Bound IN_LEFT: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_BACK") ) {
			impulses[IN_BACK] = atoi(&command_str[6]);
			printlog("Bound IN_BACK: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_RIGHT") ) {
			impulses[IN_RIGHT] = atoi(&command_str[6]);
			printlog("Bound IN_RIGHT: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_TURNL") ) {
			impulses[IN_TURNL] = atoi(&command_str[6]);
			printlog("Bound IN_TURNL: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_TURNR") ) {
			impulses[IN_TURNR] = atoi(&command_str[6]);
			printlog("Bound IN_TURNR: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_UP") ) {
			impulses[IN_UP] = atoi(&command_str[6]);
			printlog("Bound IN_UP: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_DOWN") ) {
			impulses[IN_DOWN] = atoi(&command_str[6]);
			printlog("Bound IN_DOWN: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_CHAT") ) {
			impulses[IN_CHAT] = atoi(&command_str[6]);
			printlog("Bound IN_CHAT: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_COMMAND") ) {
			impulses[IN_COMMAND] = atoi(&command_str[6]);
			printlog("Bound IN_COMMAND: %d\n",atoi(&command_str[6]));
		} else if( strstr(command_str,"IN_STATUS") ) {
			impulses[IN_STATUS] = atoi(&command_str[6]);
			printlog("Bound IN_STATUS: %d\n",atoi(&command_str[6]));
		} else if (strstr(command_str, "IN_SPELL_LIST")) {
			impulses[IN_SPELL_LIST] = atoi(&command_str[6]);
			printlog( "Bound IN_SPELL_LIST: %d\n", atoi(&command_str[6]));
		} else if (strstr(command_str, "IN_CAST_SPELL")) {
			impulses[IN_CAST_SPELL] = atoi(&command_str[6]);
			printlog( "Bound IN_CAST_SPELL: %d\n", atoi(&command_str[6]));
		} else if (strstr(command_str, "IN_DEFEND")) {
			impulses[IN_DEFEND] = atoi(&command_str[6]);
			printlog( "Bound IN_DEFEND: %d\n", atoi(&command_str[6]));
		} else if (strstr(command_str, "IN_ATTACK")) {
			impulses[IN_ATTACK] = atoi(&command_str[6]);
			printlog( "Bound IN_ATTACK: %d\n", atoi(&command_str[6]));
		} else if (strstr(command_str, "IN_USE")) {
			impulses[IN_USE] = atoi(&command_str[6]);
			printlog( "Bound IN_USE: %d\n", atoi(&command_str[6]));
		} else {
			messagePlayer(clientnum,"Invalid binding.");
		}
	}
	else if( !strncmp(command_str,"/mousespeed",11) ) {
		mousespeed = atoi(&command_str[12]);
	}
	else if( !strncmp(command_str,"/reversemouse",13) ) {
		reversemouse = (reversemouse==0);
	}
	else if( !strncmp(command_str,"/smoothmouse",12) ) {
		smoothmouse = (smoothmouse==FALSE);
	}
	else if( !strncmp(command_str,"/mana", 4) ) {
		if( multiplayer == SINGLE ) {
			stats[clientnum].MP = stats[clientnum].MAXMP;
		} else {
			messagePlayer(clientnum,language[299]);
		}
	}
	else if( !strncmp(command_str,"/heal", 4) ) {
		if( multiplayer == SINGLE ) {
			stats[clientnum].HP = stats[clientnum].MAXHP;
		} else {
			messagePlayer(clientnum,language[299]);
		}
	}
	else if (!strncmp(command_str, "/ip ", 4)) {
		if( command_str[4]!=0 ) {
			strcpy(last_ip, command_str + 4);
			last_ip[strlen(last_ip)-1]=0;
		}
	}
	else if (!strncmp(command_str, "/port ", 6)) {
		if (command_str[6] != 0) {
			strcpy(last_port, command_str + 6);
			last_port[strlen(last_port)-1]=0;
		}
	}
	else if (!strncmp(command_str, "/noblood", 8)) {
		spawn_blood = (spawn_blood==FALSE);
	}
	else if(!strncmp(command_str, "/colorblind", 11)) {
		colorblind = (colorblind==FALSE);
	}
	else if (!strncmp(command_str, "/gamma", 6)) {
		std::stringstream ss;
		ss << command_str + 7;
		ss >> vidgamma;
	}
コード例 #23
0
ファイル: actladder.cpp プロジェクト: firehot/Barony
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;
			}
		}
	}
}
コード例 #24
0
ファイル: spell.cpp プロジェクト: ganthore/Barony
bool addSpell(int spell, int player, bool ignoreSkill)
{
	node_t* node = nullptr;

	// this is a local function
	if ( player != clientnum )
	{
		return false;
	}

	spell_t* new_spell = nullptr;

	switch ( spell )
	{
		case SPELL_FORCEBOLT:
			new_spell = copySpell(&spell_forcebolt);
			break;
		case SPELL_MAGICMISSILE:
			new_spell = copySpell(&spell_magicmissile);
			break;
		case SPELL_COLD:
			new_spell = copySpell(&spell_cold);
			break;
		case SPELL_FIREBALL:
			new_spell = copySpell(&spell_fireball);
			break;
		case SPELL_LIGHTNING:
			new_spell = copySpell(&spell_lightning);
			break;
		case SPELL_REMOVECURSE:
			new_spell = copySpell(&spell_removecurse);
			break;
		case SPELL_LIGHT:
			new_spell = copySpell(&spell_light);
			break;
		case SPELL_IDENTIFY:
			new_spell = copySpell(&spell_identify);
			break;
		case SPELL_MAGICMAPPING:
			new_spell = copySpell(&spell_magicmapping);
			break;
		case SPELL_SLEEP:
			new_spell = copySpell(&spell_sleep);
			break;
		case SPELL_CONFUSE:
			new_spell = copySpell(&spell_confuse);
			break;
		case SPELL_SLOW:
			new_spell = copySpell(&spell_slow);
			break;
		case SPELL_OPENING:
			new_spell = copySpell(&spell_opening);
			break;
		case SPELL_LOCKING:
			new_spell = copySpell(&spell_locking);
			break;
		case SPELL_LEVITATION:
			new_spell = copySpell(&spell_levitation);
			break;
		case SPELL_INVISIBILITY:
			new_spell = copySpell(&spell_invisibility);
			break;
		case SPELL_TELEPORTATION:
			new_spell = copySpell(&spell_teleportation);
			break;
		case SPELL_HEALING:
			new_spell = copySpell(&spell_healing);
			break;
		case SPELL_EXTRAHEALING:
			new_spell = copySpell(&spell_extrahealing);
			break;
		case SPELL_CUREAILMENT:
			new_spell = copySpell(&spell_cureailment);
			break;
		case SPELL_DIG:
			new_spell = copySpell(&spell_dig);
			break;
		case SPELL_STONEBLOOD:
			new_spell = copySpell(&spell_stoneblood);
			break;
		case SPELL_BLEED:
			new_spell = copySpell(&spell_bleed);
			break;
		case SPELL_SUMMON:
			new_spell = copySpell(&spell_summon);
			break;
		case SPELL_DOMINATE:
			new_spell = copySpell(&spell_dominate);
			break;
		case SPELL_REFLECT_MAGIC:
			new_spell = copySpell(&spell_reflectMagic);
			break;
		case SPELL_ACID_SPRAY:
			new_spell = copySpell(&spell_acidSpray);
			break;
		case SPELL_STEAL_WEAPON:
			new_spell = copySpell(&spell_stealWeapon);
			break;
		case SPELL_DRAIN_SOUL:
			new_spell = copySpell(&spell_drainSoul);
			break;
		case SPELL_VAMPIRIC_AURA:
			new_spell = copySpell(&spell_vampiricAura);
			break;
		case SPELL_CHARM_MONSTER:
			new_spell = copySpell(&spell_charmMonster);
			break;
		default:
			return false;
	}
	if ( spellInList(&spellList, new_spell) )
	{
		messagePlayer(player, language[439], new_spell->name);
		spellDeconstructor((void*)new_spell);
		return false;
	}
	if ( !ignoreSkill && stats[player]->PROFICIENCIES[PRO_MAGIC] + statGetINT(stats[player]) < new_spell->difficulty )
	{
		messagePlayer(player, language[440]);
		spellDeconstructor((void*)new_spell);
		return false;
	}
	messagePlayer(player, language[441], new_spell->name);
	node = list_AddNodeLast(&spellList);
	node->element = new_spell;
	node->size = sizeof(spell_t);
	node->deconstructor = &spellDeconstructor;

	players[player]->entity->increaseSkill(PRO_MAGIC);

	Item* item = newItem(SPELL_ITEM, SERVICABLE, 0, 1, spell, true, nullptr);
	itemPickup(player, item);
	free(item);

	return true;
}
コード例 #25
0
ファイル: actladder.cpp プロジェクト: firehot/Barony
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;
			}
		}
	}
}
コード例 #26
0
ファイル: actheadstone.cpp プロジェクト: TurningWheel/Barony
void actHeadstone(Entity* my)
{
	if ( my->flags[INVISIBLE] )
	{
		if ( multiplayer != CLIENT )
		{
			node_t* node;
			int goldbags = 0;
			bool artifact = false;
			for ( node = map.entities->first; node != nullptr; node = node->next )
			{
				Entity* entity = (Entity*)node->element;
				if ( entity->sprite == 130 )   // gold bag
				{
					++goldbags;
				}
				if ( entity->sprite == 508 )
				{
					artifact = true;
				}
			}
			if ( goldbags >= 9 && artifact )
			{
				return;
			}
			my->flags[INVISIBLE] = false;
			my->flags[PASSABLE] = false;
			serverUpdateEntityFlag(my, INVISIBLE);
			serverUpdateEntityFlag(my, PASSABLE);
		}
		else
		{
			return;
		}
	}

	HEADSTONE_AMBIENCE--;
	if ( HEADSTONE_AMBIENCE <= 0 )
	{
		HEADSTONE_AMBIENCE = TICKS_PER_SECOND * 30;
		playSoundEntityLocal( my, 149, 32 );
	}

	if ( multiplayer == CLIENT )
	{
		return;
	}

	if ( !HEADSTONE_INIT )
	{
		HEADSTONE_INIT = 1;
		HEADSTONE_MESSAGE = rand();
		HEADSTONE_GHOUL = (rand() % 4 == 0);
	}

	bool shouldspawn = false;

	// rightclick message
	int i;
	if ( multiplayer != CLIENT )
	{
		for (i = 0; i < MAXPLAYERS; i++)
		{
			if ( (i == 0 && selectedEntity == my) || (client_selected[i] == my) )
			{
				if (inrange[i])
				{
					messagePlayer(i, language[485 + HEADSTONE_MESSAGE % 17]);
					if ( HEADSTONE_GHOUL && !HEADSTONE_FIRED )
					{
						shouldspawn = true;
						Uint32 color = SDL_MapRGB(mainsurface->format, 255, 128, 0);
						messagePlayerColor(i, color, language[502]);
					}
				}
			}
		}
	}

	// received on signal
	if ( my->skill[28] == 2 || shouldspawn )
	{
		if ( !HEADSTONE_FIRED )
		{
			HEADSTONE_FIRED = 1;

			// make a ghoul
			Entity* monster = summonMonster(GHOUL, my->x, my->y);
			if ( monster )
			{
				monster->z = 13;
				if ( currentlevel >= 15 || !strncmp(map.name, "The Haunted Castle", 18) )
				{
					Stat* tmpStats = monster->getStats();
					if ( tmpStats )
					{
						strcpy(tmpStats->name, "enslaved ghoul");
					}
				}
			}
		}
	}
}
コード例 #27
0
ファイル: clickdescription.cpp プロジェクト: boskee/Barony
void clickDescription(int player, Entity *entity) {
	stat_t *stat;
	Item *item;
	Uint32 uidnum;
	
	if( entity==NULL ) {
		if( !(*inputPressed(impulses[IN_ATTACK])) || shootmode )
			return;
		if( omousex<camera.winx || omousex>=camera.winx+camera.winw || omousey<camera.winy || omousey>=camera.winy+camera.winh )
			return;
		if (openedChest[clientnum])
			if (omousex > CHEST_INVENTORY_X && omousex < CHEST_INVENTORY_X + inventoryChest_bmp->w && omousey > CHEST_INVENTORY_Y && omousey < CHEST_INVENTORY_Y + inventoryChest_bmp->h)
				return; //Click falls inside the chest inventory GUI.
		if (identifygui_active)
			if (omousex > IDENTIFY_GUI_X && omousex < IDENTIFY_GUI_X + identifyGUI_img->w && omousey > IDENTIFY_GUI_Y && omousey < IDENTIFY_GUI_Y + identifyGUI_img->h)
				return; //Click falls inside the identify item gui.
		if (book_open)
			if (mouseInBounds(BOOK_GUI_X, BOOK_GUI_X + bookgui_img->w, BOOK_GUI_Y, BOOK_GUI_Y + bookgui_img->h))
				return; //Click falls inside the book GUI.
		if (gui_mode == GUI_MODE_INVENTORY || gui_mode == GUI_MODE_SHOP) {
			if( gui_mode == GUI_MODE_INVENTORY )
				if (mouseInBounds(RIGHTSIDEBAR_X, RIGHTSIDEBAR_X + rightsidebar_titlebar_img->w, RIGHTSIDEBAR_Y, RIGHTSIDEBAR_Y + rightsidebar_height))
					return; //Click falls inside the right sidebar.
			//int x = std::max(character_bmp->w, xres/2-inventory_bmp->w/2);
			//if (mouseInBounds(x,x+inventory_bmp->w,0,inventory_bmp->h))
				//return NULL;
			if( mouseInBounds(INVENTORY_STARTX,INVENTORY_STARTX+INVENTORY_SIZEX*INVENTORY_SLOTSIZE,INVENTORY_STARTY,INVENTORY_STARTY+INVENTORY_SIZEY*INVENTORY_SLOTSIZE) ) {
				// clicked in inventory
				return;
			}
			if( gui_mode == GUI_MODE_SHOP ) {
				int x1 = xres/2-SHOPWINDOW_SIZEX/2, x2 = xres/2+SHOPWINDOW_SIZEX/2;
				int y1 = yres/2-SHOPWINDOW_SIZEY/2, y2 = yres/2+SHOPWINDOW_SIZEY/2;
				if (mouseInBounds(x1,x2,y1,y2))
					return;
			}
		} else if (gui_mode == GUI_MODE_MAGIC) {
			if (magic_GUI_state == 0) {
				//Right, now calculate the spell list's height (the same way it calculates it for itself).
				int height = spell_list_titlebar_bmp->h;
				int numspells = 0;
				node_t *node;
				for (node = spellList.first; node != NULL; node = node->next) {
					numspells++;
				}
				int maxSpellsOnscreen = camera.winh / spell_list_gui_slot_bmp->h;
				numspells = std::min(numspells, maxSpellsOnscreen);
				height += numspells * spell_list_gui_slot_bmp->h;
				int spelllist_y = camera.winy + ((camera.winh / 2) - (height / 2)) + magicspell_list_offset_x;

				if (mouseInBounds(MAGICSPELL_LIST_X, MAGICSPELL_LIST_X + spell_list_titlebar_bmp->w, spelllist_y, spelllist_y + height))
					return;
			}
		}
		if (mouseInBounds(0,224,0,420)) // character sheet
			return;
		int x = xres/2-(status_bmp->w/2);
		if (mouseInBounds(x,x+status_bmp->w,yres-status_bmp->h-hotbar_img->h,yres))
			return;
		*inputPressed(impulses[IN_ATTACK])=0;
		
		if( softwaremode ) {
			entity = clickmap[omousey+omousex*yres];
		} else {
			GLubyte pixel[4];
			glReadPixels(omousex,yres-omousey,1,1,GL_RGBA,GL_UNSIGNED_BYTE,(void *)pixel);
			uidnum = pixel[0] + (((Uint32)pixel[1])<<8) + (((Uint32)pixel[2])<<16) + (((Uint32)pixel[3])<<24);
			entity = uidToEntity(uidnum);
		}
	}
	
	if( entity != NULL ) {
		if( multiplayer != CLIENT ) {
			if( (stat=entity->getStats())==NULL ) {
				Entity *parent = uidToEntity(entity->parent);
				if( entity->behavior==&actPlayerLimb || entity->skill[2]==entity->parent ) {
					if( parent ) {
						if( parent->behavior==&actPlayer || parent->behavior==&actMonster ) {
							stat_t *stats = parent->getStats();
							if( stats ) {
								if( strcmp(stats->name,"") ) {
									messagePlayer(player,language[253],language[90+stats->type],stats->name);
								} else {
									messagePlayer(player,language[254],language[90+stats->type]);
								}
							}
						}
					}
				}
				else if( entity->behavior==&actTorch ) {
					messagePlayer(player,language[255]);
				}
				else if( entity->behavior==&actDoor ) {
					messagePlayer(player,language[256]);
				}
				else if( entity->behavior==&actItem ) {
					item = newItem(static_cast<ItemType>(entity->skill[10]),static_cast<Status>(entity->skill[11]),entity->skill[12],entity->skill[13],entity->skill[14],FALSE,NULL);
					if (item) {
						messagePlayer(player,language[257],item->description());
						free(item);
					}
				}
				else if( entity->behavior==&actGoldBag ) {
					if( entity->skill[0]==1 )
						messagePlayer(player,language[258]);
					else
						messagePlayer(player,language[259],entity->skill[0]);
				}
				else if( entity->behavior==&actCampfire) {
					messagePlayer(player,language[260]);
				}
				else if( entity->behavior==&actFountain) {
					messagePlayer(player,language[262]);
				}
				else if( entity->behavior==&actSink) {
					messagePlayer(player,language[263]);
				}
				else if( entity->behavior==&actLadder) {
					messagePlayer(player,language[264]);
				}
				else if( entity->behavior==&actLadderUp) {
					messagePlayer(player,language[265]);
				}
				else if( entity->behavior==&actChest || entity->behavior==&actChestLid ) {
					messagePlayer(player,language[266]);
				}
				else if( entity->behavior==&actGate) {
					messagePlayer(player,language[267]);
				}
				else if( entity->behavior==&actSpearTrap) {
					messagePlayer(player,language[268]);
				}
				else if( entity->behavior==&actSwitch) {
					messagePlayer(player,language[269]);
				}
				else if( entity->behavior==&actBoulder ) {
					messagePlayer(player,language[270]);
				}
				else if( entity->behavior==&actHeadstone ) {
					messagePlayer(player,language[271]);
				}
				else if( entity->behavior==&actPortal || entity->behavior==&actWinningPortal ) {
					messagePlayer(player,language[272]);
				}
				else if( entity->behavior==&actFurniture ) {
					if( entity->skill[0] )
						messagePlayer(player,language[273]);
					else
						messagePlayer(player,language[274]);
				}
			} else {
				if( !strcmp(stat->name,"") ) {
					messagePlayer(player,language[254],language[90+stat->type]);
				} else {
					messagePlayer(player,language[253],language[90+stat->type],stat->name);
				}
			}
		} else {
			// send spot command to server
			strcpy((char *)net_packet->data,"SPOT");
			net_packet->data[4]=player;
			SDLNet_Write32((Uint32)entity->uid,&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);
		}
	}
}