Exemple #1
0
void actWallBuilder(Entity *my) {
	int c;

	if( !my->skill[28] )
		return;

	// received on signal
	if( my->skill[28] == 2) {
		playSoundEntity( my, 182, 64 );
		Uint16 x = std::min<Uint16>(std::max(0.0,my->x/16),map.width-1);
		Uint16 y = std::min<Uint16>(std::max(0.0,my->y/16),map.height-1);
		map.tiles[OBSTACLELAYER+y*MAPLAYERS+x*MAPLAYERS*map.height] = map.tiles[y*MAPLAYERS+x*MAPLAYERS*map.height];
		if( multiplayer==SERVER ) {
			for( c=0; c<MAXPLAYERS; c++ ) {
				if( client_disconnected[c]==TRUE )
					continue;
				strcpy((char *)net_packet->data,"WALC");
				SDLNet_Write16(x,&net_packet->data[4]);
				SDLNet_Write16(y,&net_packet->data[6]);
				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);
			}
		}
		list_RemoveNode(my->mynode);
	}
}
Exemple #2
0
void spell_changeHealth(Entity* entity, int amount)
{
	if (!entity)
	{
		return;
	}

	entity->modHP(amount);

	int player = -1;
	int i = 0;
	for (i = 0; i < MAXPLAYERS; ++i)
	{
		if (entity == players[i]->entity)
		{
			player = i;
		}
	}

	if (player > -1 && player < MAXPLAYERS)
	{
		if (amount > 0)
		{
			Uint32 color = SDL_MapRGB(mainsurface->format, 0, 255, 0);
			messagePlayerColor(player, color, language[443]);
		}
		else
		{
			Uint32 color = SDL_MapRGB(mainsurface->format, 255, 255, 0);
			if (amount == 0)
			{
				messagePlayerColor(player, color, language[444]);
			}
			else
			{
				messagePlayerColor(player, color, language[445]);
			}
		}

		if (multiplayer == SERVER)
		{
			strcpy((char*)net_packet->data, "UPHP");
			SDLNet_Write32((Uint32)stats[player]->HP, &net_packet->data[4]);
			SDLNet_Write32(0, &net_packet->data[8]);
			net_packet->address.host = net_clients[player - 1].host;
			net_packet->address.port = net_clients[player - 1].port;
			net_packet->len = 12;
			sendPacketSafe(net_sock, net_packet->channel, net_packet, player - 1);
		}
	}
}
Exemple #3
0
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;
			}
		}
	}
}
Exemple #4
0
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;
	}
Exemple #5
0
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;
			}
		}
	}
}
Exemple #6
0
int boulderCheckAgainstEntity(Entity *my, Entity *entity) {
	if (!my || !entity)
		return 0;

	if( entity->behavior == &actPlayer || entity->behavior == &actMonster ) {
		if( entityInsideEntity( my, entity ) ) {
			Stat *stats = entity->getStats();
			if( stats ) {
				if( entity->behavior==&actPlayer ) {
					Uint32 color = SDL_MapRGB(mainsurface->format,255,0,0);
					messagePlayerColor(entity->skill[2],color,language[455]);
					if( entity->skill[2] == clientnum ) {
						camera_shakex += .1;
						camera_shakey += 10;
					} else {
						strcpy((char *)net_packet->data,"SHAK");
						net_packet->data[4]=10; // turns into .1
						net_packet->data[5]=10;
						net_packet->address.host = net_clients[entity->skill[2]-1].host;
						net_packet->address.port = net_clients[entity->skill[2]-1].port;
						net_packet->len = 6;
						sendPacketSafe(net_sock, -1, net_packet, entity->skill[2]-1);
					}
				}
				playSoundEntity(my,181,128);
				playSoundEntity(entity,28,64);
				spawnGib(entity);
				entity->modHP(-80);
				entity->setObituary(language[1505]);
				if( entity->behavior==&actPlayer )
					if( stats->HP<=0 )
						steamAchievementClient(entity->skill[2],"BARONY_ACH_THROW_ME_THE_WHIP");
				if( stats->HP > 0 ) {
					// spawn several rock items
					int i = 8+rand()%4;
					
					int c;
					for( c=0; c<i; c++ ) {
						Entity *entity = newEntity(-1,1,map.entities);
						entity->flags[INVISIBLE]=TRUE;
						entity->flags[UPDATENEEDED]=TRUE;
						entity->x = my->x - 4 + rand()%8;
						entity->y = my->y - 4 + rand()%8;
						entity->z = -6+rand()%12;
						entity->sizex = 4;
						entity->sizey = 4;
						entity->yaw = rand()%360 * PI/180;
						entity->vel_x = (rand()%20-10)/10.0;
						entity->vel_y = (rand()%20-10)/10.0;
						entity->vel_z = -.25 - (rand()%5)/10.0;
						entity->flags[PASSABLE] = TRUE;
						entity->behavior = &actItem;
						entity->flags[USERFLAG1] = TRUE; // no collision: helps performance
						entity->skill[10] = GEM_ROCK;    // type
						entity->skill[11] = WORN;        // status
						entity->skill[12] = 0;           // beatitude
						entity->skill[13] = 1;           // count
						entity->skill[14] = 0;           // appearance
						entity->skill[15] = FALSE;       // identified
					}

					double ox = my->x;
					double oy = my->y;
					
					// destroy the boulder
					playSoundEntity(my,67,128);
					list_RemoveNode(my->mynode);

					// on sokoban, destroying boulders spawns scorpions
					if( !strcmp(map.name,"Sokoban") ) {
						Entity *monster = summonMonster(SCORPION,ox,oy);
						if( monster ) {
							int c;
							for( c=0; c<MAXPLAYERS; c++ ) {
								Uint32 color = SDL_MapRGB(mainsurface->format,255,128,0);
								messagePlayerColor(c,color,language[406]);
							}
						}
					}

					return 1;
				}
			}
		}
	} else if( entity->behavior == &actGate || entity->behavior == &actBoulder || entity->behavior==&actChest || entity->behavior==&actHeadstone || entity->behavior==&actFountain || entity->behavior==&actSink ) {
		if( !entity->flags[PASSABLE] ) {
			if( entityInsideEntity( my, entity ) ) {
				// stop the boulder
				BOULDER_STOPPED=1;
				BOULDER_ROLLING=0;
				playSoundEntity(my,181,128);
				if( my->flags[PASSABLE] ) {
					my->flags[PASSABLE] = FALSE;
					if( multiplayer==SERVER )
						serverUpdateEntityFlag(my,PASSABLE);
				}
			}
		}
	} else if( entity->behavior == &actDoor ) {
		if( entityInsideEntity( my, entity ) ) {
			playSoundEntity(entity,28,64);
			entity->skill[4] = 0;
			if( !entity->skill[0] )
				entity->skill[6] = (my->x > entity->x);
			else
				entity->skill[6] = (my->y < entity->y);
			playSoundEntity(my,181,128);
		}
	}
	return 0;
}
Exemple #7
0
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.
}
Exemple #8
0
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;
}
Exemple #9
0
void actWinningPortal(Entity *my) {
	int playercount=0;
	double dist;
	int i, c;

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

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

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

	if( multiplayer==CLIENT )
		return;

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

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

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

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

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

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

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

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

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

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