Beispiel #1
0
static void ackClient(IPaddress clientAddr) {
  IPXHeader regHeader;
  UDPpacket regPacket;
  Bits result;

  SDLNet_Write16(0xffff, regHeader.checkSum);
  SDLNet_Write16(sizeof(regHeader), regHeader.length);
	
  SDLNet_Write32(0, regHeader.dest.network);
  PackIP(clientAddr, &regHeader.dest.addr.byIP);
  SDLNet_Write16(0x2, regHeader.dest.socket);

  SDLNet_Write32(1, regHeader.src.network);
  PackIP(ipxServerIp, &regHeader.src.addr.byIP);
  SDLNet_Write16(0x2, regHeader.src.socket);
  regHeader.transControl = 0;

  regPacket.data = (Uint8 *)&regHeader;
  regPacket.len = sizeof(regHeader);
  regPacket.maxlen = sizeof(regHeader);
  regPacket.address = clientAddr;
  // Send registration string to client.  If client doesn't get this, client will not be registered
  result = SDLNet_UDP_Send(ipxServerSocket,-1,&regPacket);

}
Beispiel #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);
		}
	}
}
void NetworkCommandBuffer::SendString ( const std::string message )
{
	char buffer[4];
	SDLNet_Write32(message.size(), buffer);
	SDLNet_TCP_Send ( socket, buffer, 4 );
	SDLNet_TCP_Send ( socket, const_cast<char*> ( message.data() ), message.size() );
}
Beispiel #4
0
Datei: net.c Projekt: esohns/jnb
void
bufToPacket(const char* buf, struct NetPacket* pkt)
{
	SDLNet_Write32(*((Uint32*)(buf +  0)), &pkt->cmd);
	SDLNet_Write32(*((Uint32*)(buf +  4)), &pkt->arg);
	SDLNet_Write32(*((Uint32*)(buf +  8)), &pkt->arg2);
	SDLNet_Write32(*((Uint32*)(buf + 12)), &pkt->arg3);
	SDLNet_Write32(*((Uint32*)(buf + 16)), &pkt->arg4);
/*
	pkt->cmd               =        ntohl(*((unsigned long *) (buf +  0)));
	pkt->arg               = (long) ntohl(*((unsigned long *) (buf +  4)));
	pkt->arg2              = (long) ntohl(*((unsigned long *) (buf +  8)));
	pkt->arg3              = (long) ntohl(*((unsigned long *) (buf + 12)));
	pkt->arg4              = (long) ntohl(*((unsigned long *) (buf + 16)));
*/
}
Beispiel #5
0
bool PacketManager::Write32(Uint32 val){
  Uint32 size = dataPos + sizeof(Uint32);
  if(bufferSize < size)if(!Allocate(size))return false;
  SDLNet_Write32(val, buffer + dataPos);
  dataPos += sizeof(Uint32);
  if(dataLength < dataPos)dataLength = dataPos;
  return true;
}
Beispiel #6
0
bool PacketManager::WriteF(float val){
  Uint32 size = dataPos + sizeof(float);
  if(bufferSize < size)if(!Allocate(size))return false;
  Uint32 *v = (Uint32*)(&val);
  SDLNet_Write32(*v, buffer + dataPos);
  dataPos += sizeof(float);
  if(dataLength < dataPos)dataLength = dataPos;
  return true;
}
Beispiel #7
0
UDPpacket NetInputNewPacket(NetInputChannel *n, size_t len)
{
	UDPpacket packet;
	SDLNet_Write32(n->otherHost, &packet.address.host);
	SDLNet_Write16(n->otherPort, &packet.address.port);
	packet.maxlen = packet.len = len;
	CMALLOC(packet.data, len);
	return packet;
}
Beispiel #8
0
void NetInputClientSend(NetInputClient *n, int cmd)
{
	if (n->channel.sock == NULL || n->channel.state != CHANNEL_STATE_CONNECTED)
	{
		return;
	}

	UDPpacket packet = NetInputNewPacket(&n->channel, sizeof(NetMsgCmd));
	NetMsgCmd *packetCmd = (NetMsgCmd *)packet.data;
	SDLNet_Write32(n->ticks, &packetCmd->ticks);
	SDLNet_Write32(cmd, &packetCmd->cmd);
	if (!NetInputTrySendPacket(&n->channel, packet))
	{
		goto bail;
	}

bail:
	CFREE(packet.data);
}
char * TCP_NetBase::buildTCPMessageBuffer(ulong playerId, const char msg[], size_t & msgLen)
{
	ulong totalMsgLen = msgLen + TCP_HEADER_SIZE;

	//build buffer
	char * const buffer = reinterpret_cast<char *>(malloc(totalMsgLen));
	if (buffer == NULL) {
		NETMSG("malloc failure");
		msgLen = 0;
		return buffer;
	}

	SDLNet_Write32(playerId, buffer);
	SDLNet_Write32(msgLen, buffer + 4);
	memcpy(buffer + 8, msg, msgLen);
	msgLen = totalMsgLen;

	return buffer;
}
void BomberNetClient::sendDisconnection() {
	char data[7];
	memset(data, 0, sizeof data);
	SDLNet_Write32(requestNumber, data);
	data[4] = 0x01;
	data[5] = GameConfig::Instance().getNbPlayerOfClient();
	data[6] = '\0';
	if (SDLNet_CheckSockets(BomberNetClient::socketset, 0) >= 0) {
		SDLNet_TCP_Send(BomberNetClient::tcpsock, &data, 7);
		requestNumber++;
	}
}
Beispiel #11
0
void Action::Write(char *buffer) const
{
  uint32_t len = GetSize();
  SDLNet_Write32(len, buffer);
  buffer += 4;
  buffer[0] = m_header.type;
  buffer++;

  if (m_header.len) {
    memcpy(buffer, m_var, m_header.len);
  }
}
Beispiel #12
0
unsigned long host_to_net32(unsigned int value)
{
  union
  {
    unsigned long l;
    char b[4];
  } data;

  SDLNet_Write32(value, data.b);

  return data.l;
}
Beispiel #13
0
void Action::Push(Double m_val)
{
#if FIXINT_BITS == 32
  uint32_t tmp = *((uint32_t*)&m_val.intValue);
  if (MemWriteLeft() < 4)
    Increase();
  SDLNet_Write32(m_val, m_write); m_write += 4;
#else
  uint32_t tmp[2];

  if (MemWriteLeft() < 8)
    Increase();
  memcpy(tmp, &m_val.intValue, 8);
#  if (SDL_BYTEORDER == SDL_LIL_ENDIAN)
  SDLNet_Write32(tmp[0], m_write); m_write+= 4;
  SDLNet_Write32(tmp[1], m_write); m_write+= 4;
#  else
  SDLNet_Write32(tmp[1], m_write); m_write+= 4;
  SDLNet_Write32(tmp[0], m_write); m_write+= 4;
#  endif
#endif
  m_header.len += sizeof(fp::fint_t);
}
void BomberNetClient::sendKeystate() {
	char data[38];
	memset(data, 0, sizeof data);
	SDLNet_Write32(requestNumber, data);
	data[4] = 0x02;
	data[5] = GameConfig::Instance().getNbPlayerOfClient();
	int pos = 6;
	for (int i = 0; i < GameConfig::Instance().getNbPlayerOfClient(); i++) {
		SDLNet_Write16(keystate[i], data + pos);
		pos += 2;
	}
	data[pos] = '\0';
	if (SDLNet_CheckSockets(BomberNetClient::socketset, 0) >= 0) {
		SDLNet_TCP_Send(BomberNetClient::tcpsock, &data, pos);
		requestNumber++;
	}
}
Beispiel #15
0
/*!
 * Send the digest packet of the previous frame to a single client
 */
void
send_previous_digest_packet (global_status_type * global_status,
			     global_option_type * global_option,
			     IPaddress address)
{

  int player_index;

  /* Set the identifier */
  global_status->digest_packet->data[PACKET_IDENTIFIER] = PACKET_DIGEST_ID;

  /* Set the previous frame */
  SDLNet_Write32 (global_status->frame_number - 1,
		  global_status->digest_packet->
		  data + PACKET_STATUS_FRAME_NUMBER);

  /* Set the digest input values */
  for (player_index = 0; player_index < global_option->number_player;
       player_index++)
    {
      global_status->digest_packet->data[PACKET_STATUS_INPUT_DEVICE_NUMBER +
					 player_index] =
	previous_input_value[player_index];
    }

  /* Compute the checksum */
  global_status->digest_packet->
    data[PACKET_STATUS_CHECKSUM] =
    compute_checksum (global_status->digest_packet->data, PACKET_IDENTIFIER,
		      PACKET_STATUS_CHECKSUM);


  global_status->digest_packet->len = PACKET_STATUS_LENGTH;

  /* Now, global_status->digest_packet is the previous digest packet we can send to this given client */

  send_individual_digest_packet (global_status->input_mapping[player_index].
				 address, global_status);
}
Beispiel #16
0
int main(int argc, char **argv)
{
	Uint16 port;
	char *host,*fname,*fbasename;
	Sint32 flen,pos,p2;
	int len,blocks,i,err=0;
	Uint32 ack;
	IPaddress ip;
	UDPsocket sock;
	UDPpacket *in, *out;
	FILE *f;
	
	/* check our commandline */
	if(argc<4)
	{
		printf("%s host port file\n",argv[0]);
		exit(0);
	}
	
	/* initialize SDL */
	if(SDL_Init(0)==-1)
	{
		printf("SDL_Init: %s\n",SDL_GetError());
		exit(1);
	}

	/* initialize SDL_net */
	if(SDLNet_Init()==-1)
	{
		printf("SDLNet_Init: %s\n",SDLNet_GetError());
		exit(2);
	}

	/* get the host from the commandline */
	host=argv[1];
	/* get the port from the commandline */
	port=(Uint16) strtol(argv[2],NULL,0);
	if(!port)
	{
		printf("a server port cannot be 0.\n");
		exit(3);
	}
	/* get filename to get from server from commandline */
	fname=argv[3];

	if(SDLNet_ResolveHost(&ip,host,port)==-1)
	{
		printf("SDLNet_ResolveHost: %s\n",SDLNet_GetError());
		exit(4);
	}
	
	/* open udp client socket */
	if(!(sock=SDLNet_UDP_Open(0)))
	{
		printf("SDLNet_UDP_Open: %s\n",SDLNet_GetError());
		exit(5);
	}

	/* allocate max packet */
	if(!(out=SDLNet_AllocPacket(65535)))
	{
		printf("SDLNet_AllocPacket: %s\n",SDLNet_GetError());
		exit(6);
	}
	if(!(in=SDLNet_AllocPacket(65535)))
	{
		printf("SDLNet_AllocPacket: %s\n",SDLNet_GetError());
		exit(6);
	}
	
	/* bind server address to channel 0 */
	if(SDLNet_UDP_Bind(sock, 0, &ip)==-1)
	{
		printf("SDLNet_UDP_Bind: %s\n",SDLNet_GetError());
		exit(7);
	}

	/* open output file */
	fbasename=strrchr(fname,'/');
	if(!fbasename)
		fbasename=fname;
	else
		fbasename++;
	printf("writting file: %s\n",fbasename);
	if(!(f=fopen(fbasename,"wb")))
	{
		perror("fopen");
		exit(8);
	}

	/* request file / expect filesize */
	printf("requesting file=%s\n",fname);
	out->data[0]=1<<4;
	strcpy((char*)out->data+1,fname);
	out->len=strlen(fname)+2;
	if(udpsend(sock,0,out,in,200,1,TIMEOUT)<1)
		exit(9);
	
	flen=SDLNet_Read32(in->data+1);
	len=SDLNet_Read32(in->data+5);
	blocks=(flen+len-1)/len;
	printf("flen=%d blocksize=%d blocks=%d\n",flen,len,blocks);

	/* send ready / expect file */
	printf("starting transfer\n");
	out->data[0]=2<<4;
	out->len=1;
	if(udpsend(sock,0,out,in,10,2,TIMEOUT)<1)
		exit(10);
	
	if(flen<0)
	{
		printf("file not available...\n");
		exit(11);
	}

	pos=0; /* count per 32 blocks */
	while(pos*32<blocks && !err)
	{
		/*printf("pos=%d\n",pos); */
		ack=0;
		if((pos+1)*32>=blocks)
		{
			for(i=blocks%32;i<32;i++)
				ack|=1<<i;
		}
		printf("\r                                                                  "
				"\r%3d%% %08x: ",(pos*3200)/blocks,pos*32*len);
		while(ack!=0xffffffff && !err)
		{
			i=in->data[1];
			p2=SDLNet_Read32(in->data+2);
			/*printf("received %d,%d\n",i,p2); */
			if(!(ack&1<<i) && p2>=pos*32*len)
			{
				fseek(f,p2,SEEK_SET);
				fwrite(in->data+6,in->len-6,1,f);
				ack|=1<<i;

				printf(".");
				fflush(stdout);
			}
			if(ack!=0xffffffff)
				err=udprecv(sock,in,10,2,500);
			if(err<0)
				continue; /* error... */
			if(!err)
			{
				/*printf("sending ack 0x%0X\n",ack); */
				out->data[0]=3<<4;
				SDLNet_Write32(pos*32*len,out->data+1);
				SDLNet_Write32(ack,out->data+5);
				out->len=9;
				SDLNet_UDP_Send(sock,0,out);
			}
			err=0;
		}
		pos++;
	}
	
	printf("\ndone.\n");

	fclose(f);
	
	/* close the socket */
	SDLNet_UDP_Close(sock);
	
	/* free packets */
	SDLNet_FreePacket(out);
	SDLNet_FreePacket(in);
	
	/* shutdown SDL_net */
	SDLNet_Quit();

	/* shutdown SDL */
	SDL_Quit();

	return(0);
}
Beispiel #17
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;
}
Beispiel #18
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;
	}
Beispiel #19
0
void MovePacket::SetTime( Uint32 time )
{
	SDLNet_Write32( time, &data_[2] );
}
Beispiel #20
0
void Write32(FILE *out, uint32_t val)
{
  uint32_t render;
  SDLNet_Write32(val, &render);
  fwrite(&render, 1, 4, out);
}
Beispiel #21
0
//-------------  Add datas to the action  ----------------
void Action::Push(int32_t m_val)
{
  if (MemWriteLeft() < 4)
    Increase();
  SDLNet_Write32(m_val, m_write); m_write += 4; m_header.len += 4;
}
Beispiel #22
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.
}
Beispiel #23
0
/*!
 * Send a packet to a client to fit the need in term of frame number(s)
 * \param global_status global status for the application
 * \param client_index index of the global player to which send a packet
 */
void
send_individual_internet_digest_packet (global_status_type * global_status,
					int client_index)
{
  unsigned int frame_number;
  unsigned int frame_number_start;
  int number_digest;
  int digest_index;
  int number_destination;

  /* Set the identifier */
  global_status->digest_packet->data[PACKET_IDENTIFIER] =
    PACKET_INTERNET_DIGEST_ID;

  /* Set the number of the first frame digest */
  SDLNet_Write32 (global_status->next_frame_to_send[client_index],
		  global_status->digest_packet->data +
		  PACKET_INTERNET_DIGEST_FRAME_NUMBER);

  /* Compute the number of digest to send */
  number_digest =
    min (PACKET_INTERNET_DIGEST_DIGEST_NUMBER, global_status->frame_number);

  if (number_digest < PACKET_INTERNET_DIGEST_DIGEST_NUMBER)
    {
      /* We're at the beginning of the game */
      frame_number_start = 1;
    }
  else
    {
      if (global_status->next_frame_to_send[client_index] + number_digest >
	  global_status->frame_number)
	{
	  /* 
	   * If we feed the client with frames between what is expected and what we can provide at max, we won't fill all
	   * the space we have. Let's then feed the maximum of space up to what we can provide (thus giving frames which are
	   * thought to be older than what the client is waiting for [but it could be false and effectively waiting them])
	   */
	  frame_number_start =
	    global_status->frame_number -
	    PACKET_INTERNET_DIGEST_DIGEST_NUMBER + 1;
	}
      else
	{
	  /*
	   * We can fill the whole space with data from what was requested and we won't reach the last frame for which
	   * we can provide the status
	   */
	  frame_number_start =
	    global_status->next_frame_to_send[client_index];
	}
    }

#if defined(DEBUG)
  fprintf (stderr,
	   "number of digests to send = %d (%d-%d)\nnext_frame_to_send = %d, frame_number = %d\n",
	   number_digest,
	   frame_number_start,
	   frame_number_start + number_digest - 1,
	   global_status->next_frame_to_send[client_index],
	   global_status->frame_number);
#endif

  /* Set the number of digest to send */
  global_status->digest_packet->data[PACKET_INTERNET_DIGEST_NUMBER_DIGEST] =
    number_digest;

  global_status->digest_packet->len =
    PACKET_INTERNET_DIGEST_BASE_LENGTH +
    number_digest * PACKET_INTERNET_DIGEST_INCREMENT_LENGTH;

  /* Set destination address */
  global_status->digest_packet->address =
    global_status->input_mapping[client_index].address;

  for (digest_index = 0, frame_number = frame_number_start;
       digest_index < number_digest; digest_index++, frame_number++)
    {
      memcpy (global_status->digest_packet->data +
	      PACKET_INTERNET_DIGEST_DIGEST_INDEX +
	      digest_index * DIGEST_SIZE,
	      history_digest + (frame_number % AUTO_OUTDATE) * DIGEST_SIZE,
	      DIGEST_SIZE);
    }

  /* The checksum is located after the last digest data */
  global_status->digest_packet->data[PACKET_INTERNET_DIGEST_DIGEST_INDEX +
				     number_digest * DIGEST_SIZE] =
    compute_checksum (global_status->digest_packet->data, PACKET_IDENTIFIER,
		      PACKET_INTERNET_DIGEST_DIGEST_INDEX +
		      number_digest * DIGEST_SIZE);

  number_destination = SDLNet_UDP_Send (global_status->server_socket,
					-1, global_status->digest_packet);

  if (number_destination != 1)
    {
      fprintf (stderr, "Couldn't send the digest packet to client\n");
    }

  /* Next time, we'll send the next frame we haven't send yet */
  global_status->next_frame_to_send[client_index] = frame_number;

}
Beispiel #24
0
void MovePacket::SetPosition(Vec2 position)
{
	SDLNet_Write32( floatToUint32( position.x ), &data_[6] );
	SDLNet_Write32( floatToUint32( position.y ), &data_[10] );
}
Beispiel #25
0
int FCEUD_NetworkConnect(void)
{
 IPaddress rip;

 SDLNet_Init();
 int netplay =1;
 if(netplay==1)	/* Be a server. */
 {
  TCPsocket tmp;
  Uint16 p=LocalPortUDP;

  SDLNet_ResolveHost(&rip,NULL,LocalPortTCP);

  UDPSocket=SDLNet_UDP_Open(p);

  tmp=SDLNet_TCP_Open(&rip);
  Socket=SDLNet_TCP_Accept(tmp);

  memcpy(&rip,SDLNet_TCP_GetPeerAddress(Socket),sizeof(IPaddress));
  {
   Uint32 buf[12];
   uint32 player=1;

   magic=SDL_GetTicks();

   SDLNet_Write32(buf,uport);
   SDLNet_Write32(buf+4,1);
   SDLNet_Write32(buf+8,magic);

   SDLNet_TCP_Send(Socket, buf, 12);

   /* Get the UDP port the client is waiting for data on. */
   SDLNet_TCP_Recv(Socket, buf, 2);
   RemotePortUDP=de32(buf);
  }
 }
 else		/* Be a client	*/
 {
  SDLNet_ResolveHost(&rip,ServerHost,RemotePortTCP);
  Socket=SDLNet_TCP_Open(&rip);

  {
   Uint16 p=LocalPortUDP;
   uint8 buf[12];
  
   UDPSocket=SDLNet_UDP_Open(p);

   /* Now, tell the server what local UDP port it should send to. */
   en32(buf,p);
   SDLNet_TCP_Send(Socket, buf, 4);
 
   /* Get the UDP port from the server we should send data to. */
   SDLNet_TCP_Recv(Socket, buf, 12);
   RemotePortUDP=de32(buf);
   magic=de32(buf+8);
  }
  set=SDLNet_AllocSocketSet(1);
  SDLNet_TCP_AddSocket(set,Socket);
  SDLNet_UDP_AddSocket(set,UDPSocket);
 }	// End client connect code.

 rip.port=RemotePortUDP;
 SDLNet_UDP_Bind(UDPSocket, 0, &rip);
}
Beispiel #26
0
void MovePacket::SetVelocity(Vec2 velocity)
{
	SDLNet_Write32( floatToUint32( velocity.x ), &data_[14] );
	SDLNet_Write32( floatToUint32( velocity.y ), &data_[18] );
}
Beispiel #27
0
static EEL_xno n2_tcp_send(EEL_vm *vm)
{
	EEL_value *args = vm->heap + vm->argv;
	EB_socket *ebs;
	int i, count = 0;
	if(EEL_TYPE(args) != md.net2_socket_cid)
		return EEL_XWRONGTYPE;
	ebs = o2EB_socket(args->objref.v);
	if(!ebs->rs)
		return EEL_XDEVICECLOSED;
	if(ebs->rs->status)
		return ebs->rs->status;
	for(i = 1; i < vm->argc; ++i)
	{
		void *buf;
		int bsize;
		EEL_value *v = args + i;
		switch((EEL_classes)EEL_TYPE(v))
		{
		  case EEL_CREAL:
		  {
			int n;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
			char lb[sizeof(EEL_real)];
			*((EEL_real *)&lb) = v->real.v;
#else
			union
			{
				EEL_real r;
				char c[sizeof(EEL_real)];
			} cvt;
			char lb[sizeof(EEL_real)];
			cvt.r = v->real.v;
			for(n = 0; n < sizeof(EEL_real); ++n)
				lb[n] = cvt.c[sizeof(EEL_real) - 1 - n];
#endif
			buf = &lb;
			bsize = sizeof(EEL_real);
			break;
		  }
		  case EEL_CINTEGER:
		  {
			EEL_uint32 cvt;
			SDLNet_Write32(eel_v2l(v), &cvt);
			buf = &cvt;
			bsize = 4;
			break;
		  }
		  case EEL_CSTRING:
		  case EEL_CDSTRING:
		  {
		  	buf = (void *)eel_v2s(v);
			bsize = eel_length(v->objref.v);
			break;
		  }
		  default:
			return EEL_XARGUMENTS;
		}
		if(ebs->rs->sender)
		{
			/* Buffered, non-blocking */
			if(sfifo_space(&ebs->rs->fifo) < bsize)
				return EEL_XBUFOVERFLOW;
			sfifo_write(&ebs->rs->fifo, buf, bsize);
		}
		else
		{
			/* Direct, blocking */
			int n = NET2_TCPSend(ebs->rs->n2socket, buf, bsize);
			if(n < 0)
				return EEL_XDEVICEWRITE;
		}
		count += bsize;
	}
	eel_l2v(vm->heap + vm->resv, count);
	return 0;
}
Beispiel #28
0
void MovePacket::SetAngle(float degrees)
{
	SDLNet_Write32( floatToUint32( degrees ), &data_[22] );
}
Beispiel #29
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;
			}
		}
	}
}
Beispiel #30
0
/*!
 * Send a digest packet to clients if they reeeeeeeeeally deserve it
 */
void
send_digest_lan_packets (global_status_type * global_status,
			 global_option_type * global_option)
{

  int player_index;

  for (player_index = 0; player_index < global_option->number_player;
       player_index++)
    {
      if (global_status->player_status[player_index] != READY)
	{
#if defined(DEBUG)
	  fprintf (stderr,
		   "Player number %d not being READY prevent the sending of the digest packet\n",
		   player_index);
#endif
	  return;
	}
    }

  /* If we're here, all concerned clients are READY (== we got their status) */

  /* Set the identifier */
  global_status->digest_packet->data[PACKET_IDENTIFIER] = PACKET_DIGEST_ID;

  /* Set the current frame */
  SDLNet_Write32 (global_status->frame_number,
		  global_status->digest_packet->
		  data + PACKET_STATUS_FRAME_NUMBER);

  /* Set the digest input values */
  for (player_index = 0; player_index < global_option->number_player;
       player_index++)
    {
      global_status->digest_packet->data[PACKET_STATUS_INPUT_DEVICE_NUMBER +
					 player_index] =
	global_status->input_value[player_index];
    }

  /* Compute the checksum */
  global_status->digest_packet->
    data[PACKET_STATUS_CHECKSUM] =
    compute_checksum (global_status->digest_packet->data, PACKET_IDENTIFIER,
		      PACKET_STATUS_CHECKSUM);


  global_status->digest_packet->len = PACKET_STATUS_LENGTH;

  /* Now, global_status->digest_packet is THE digest packet we can send to all clients */

  for (player_index = 0; player_index < global_option->number_player;
       player_index++)
    {

      /* TODO : find a much more elegant and efficient way to find unique client addresses */

      int duplicate_index;
      int already_sent;

      already_sent = 0;

      for (duplicate_index = 0; duplicate_index < player_index;
	   duplicate_index++)
	{
	  if (equals_address
	      (global_status->input_mapping[player_index].address,
	       global_status->input_mapping[duplicate_index].address))
	    {
	      already_sent = 1;
	      break;
	    }
	}

      if (!already_sent)
	{
	  send_individual_digest_packet (global_status->
					 input_mapping[player_index].address,
					 global_status);
	}

    }

  /* We're done with this frame, skip to the next one */
  global_status->frame_number++;

  /* Get ready for receiving status for next (now current) frame */
  init_frame_status (global_status, global_option);

}