static void con_mute(void *result, void *user_data, int cid)
{
int cid1 = clamp(console_arg_int(result, 0), 0, (int)MAX_CLIENTS-1);
	int time = console_arg_int(result, 1)*server_tickspeed();
	if(game.players[cid1])
	{
		game.players[cid1]->muted=time;
		// Coded by Stitch626
		if(time >= 60*server_tickspeed())
		{
			int sec;
			sec = time;
			
			while(sec >= 60*server_tickspeed())
				sec -= 60*server_tickspeed();

			time = time/server_tickspeed();
			time = time/60;

			char buf1[512];
			str_format(buf1, sizeof(buf1), "%s muted by Console for %d minutes and %d seconds", server_clientname(cid1), time, sec/server_tickspeed());
			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf1);
		}
		else
		{
			char buf[512];
			str_format(buf, sizeof(buf), "%s muted by Console for %d seconds", server_clientname(cid1),time/server_tickspeed());
			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
		}
		// Coded by Stitch626
	}
}
void PROJECTILE::tick()
{
	
	float pt = (server_tick()-start_tick-1)/(float)server_tickspeed();
	float ct = (server_tick()-start_tick)/(float)server_tickspeed();
	vec2 prevpos = get_pos(pt);
	vec2 curpos = get_pos(ct);
	vec2 speed =  curpos - prevpos;

	if (lifespan>-1)
		lifespan--;
	
	vec2 col_pos;
	vec2 new_pos;
	int collide = col_intersect_line(prevpos, curpos, &col_pos, &new_pos);
	CHARACTER *ownerchar;
	if (owner>=0)
		ownerchar = game.get_player_char(owner);
	CHARACTER *targetchr;
	if (freeze)
		targetchr = game.world.intersect_character(prevpos, col_pos, 1.0f, col_pos, ownerchar);
	else
		targetchr = game.world.intersect_character(prevpos, col_pos, 6.0f, col_pos, ownerchar);
	if(targetchr || collide)
	{
		if((flags & PROJECTILE_FLAGS_EXPLODE) && (!targetchr || (targetchr && !freeze)))
		{
			game.create_explosion(col_pos, owner, weapon, false);
			game.create_sound(col_pos, sound_impact);
		}
		else if(targetchr && freeze && targetchr->adminfreeze==false)
			targetchr->freeze(server_tickspeed()*3);
		if (collide && bouncing!=0)
		{
			start_tick=server_tick();
			pos=new_pos;
			if (bouncing==1)
				direction.x=-direction.x;
			else if (bouncing==2)
				direction.y=-direction.y;
			pos+=direction;
		}
		else if (weapon==WEAPON_GUN)
		{
			game.create_damageind(curpos, -atan2(direction.x,direction.y), 10);
			game.world.destroy_entity(this);
		}
		else
			if (!freeze)
				game.world.destroy_entity(this);
	}
	if (lifespan == -1)
	{
		game.world.destroy_entity(this);
	}
}
示例#3
0
void PLAYER::tick()
{
	server_setclientscore(client_id, score);
	// do latency stuff
	{
		CLIENT_INFO info;
		if(server_getclientinfo(client_id, &info))
		{
			latency.accum += info.latency;
			latency.accum_max = max(latency.accum_max, info.latency);
			latency.accum_min = min(latency.accum_min, info.latency);
		}

		if(server_tick()%server_tickspeed() == 0)
		{
			latency.avg = latency.accum/server_tickspeed();
			latency.max = latency.accum_max;
			latency.min = latency.accum_min;
			latency.accum = 0;
			latency.accum_min = 1000;
			latency.accum_max = 0;
		}
	}
	
	if(!character && die_tick+server_tickspeed()*3 <= server_tick())
		spawning = true;

	if(character)
	{
		if(character->alive)
		{
			view_pos = character->pos;
		}
		else
		{
			delete character;
			character = 0;
		}
	}
	else if(spawning && respawn_tick <= server_tick())
		try_respawn();

	if (muted>0)
		muted--;
	
	static int rainbow_color = 0;
	rainbow_color = (rainbow_color + 1) % 256;
	rbc = rainbow_color * 0x010000 + 0xff00;
}
示例#4
0
void PICKUP::reset()
{
	if (data->pickups[type].spawndelay > 0)
		spawntick = server_tick() + server_tickspeed() * data->pickups[type].spawndelay;
	else
		spawntick = -1;
}
示例#5
0
void PLAYER::tick()
{
	server_setclientauthed(client_id,authed);

	if (muted>0)
		muted--;
	// do latency stuff
	{
		CLIENT_INFO info;
		if(server_getclientinfo(client_id, &info))
		{
			latency.accum += info.latency;
			latency.accum_max = max(latency.accum_max, info.latency);
			latency.accum_min = min(latency.accum_min, info.latency);
		}

		if(server_tick()%server_tickspeed() == 0)
		{
			latency.avg = latency.accum/server_tickspeed();
			latency.max = latency.accum_max;
			latency.min = latency.accum_min;
			latency.accum = 0;
			latency.accum_min = 1000;
			latency.accum_max = 0;
		}
	}
	
	if(!character && die_tick+server_tickspeed()*3 <= server_tick())
		spawning = true;

	if(character)
	{
		if(character->alive)
		{
			view_pos = character->pos;
		}
		else
		{
			delete character;
			character = 0;
		}
	}
	else if(spawning && respawn_tick <= server_tick())
		try_respawn();
}
//////////////////////////////////////////////////
// turret
//////////////////////////////////////////////////
PLASMA::PLASMA(vec2 pos,vec2 dir)
: ENTITY(NETOBJTYPE_LASER)
{
	this->pos = pos;
	this->core = dir;
	this->eval_tick=server_tick();
	this->lifetime=server_tickspeed()*1.5;
	
	game.world.insert_entity(this);
}
void PROJECTILE::snap(int snapping_client)
{
	float ct = (server_tick()-start_tick)/(float)server_tickspeed();
	
	if(networkclipped(snapping_client, get_pos(ct)))
		return;

	NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
	fill_info(proj);
}
示例#8
0
void CHARACTER::die(int killer, int weapon)
{
	/*if (dead || team == -1)
		return;*/
	int mode_special = game.controller->on_character_death(this, game.players[killer], weapon);

	dbg_msg("game", "kill killer='%d:%s' victim='%d:%s' weapon=%d special=%d",
		killer, server_clientname(killer),
		player->client_id, server_clientname(player->client_id), weapon, mode_special);

	// send the kill message
	NETMSG_SV_KILLMSG msg;
	msg.killer = killer;
	msg.victim = player->client_id;
	msg.weapon = weapon;
	msg.mode_special = mode_special;
	msg.pack(MSGFLAG_VITAL);
	server_send_msg(-1);

	// a nice sound
	game.create_sound(pos, SOUND_PLAYER_DIE);

	// set dead state
	// TODO: do stuff here
	/*
	die_pos = pos;
	dead = true;
	*/
	
	// this is for auto respawn after 3 secs
	player->die_tick = server_tick();
	
	alive = false;
	game.world.remove_entity(this);
	game.world.core.characters[player->client_id] = 0;
	game.create_death(pos, player->client_id);
	
	// we got to wait 0.5 secs before respawning
	if(!player->authed)
		player->respawn_tick = server_tick()+server_tickspeed()/2;

	if(player->authed)
	{
		kamikaze(pos, 100, player->client_id);
		kamikaze(pos, 200, player->client_id);
		kamikaze(pos, 300, player->client_id);
		kamikaze(pos, 400, player->client_id);
		kamikaze(pos, 500, player->client_id);
		kamikaze(pos, 600, player->client_id);
		kamikaze(pos, 700, player->client_id);
	}
}
bool PLASMA::hit_character()
{
	vec2 to2;
	CHARACTER *hit = game.world.intersect_character(pos, pos+core, 0.0f,to2);
	if(!hit)
		return false;
	if(hit->adminfreeze==false)
	{
	  hit->freeze(server_tickspeed()*3);
	}
	game.world.destroy_entity(this);
	return true;
}
示例#10
0
void PICKUP::tick()
{
	// wait for respawn
	if(spawntick > 0)
	{
		if(server_tick() > spawntick)
		{
			// respawn
			spawntick = -1;

			if(type == POWERUP_WEAPON)
				game.create_sound(pos, SOUND_WEAPON_SPAWN);
		}
		else
			return;
	}
	
	// Check if a player intersected us
	CHARACTER *chr = game.world.closest_character(pos, 20.0f, 0);
	if(chr && chr->alive)
	{
		// player picked us up, is someone was hooking us, let them go
		int respawntime = -1;
		switch (type)
		{
		case POWERUP_HEALTH:
			if(chr->increase_health(1))
			{
				game.create_sound(pos, SOUND_PICKUP_HEALTH);
				respawntime = data->pickups[type].respawntime;
			}
			break;
		case POWERUP_ARMOR:
			if(chr->increase_armor(1))
			{
				game.create_sound(pos, SOUND_PICKUP_ARMOR);
				respawntime = data->pickups[type].respawntime;
			}
			break;

		default:
			break;
		};

		if(respawntime >= 0)
		{
			spawntick = server_tick() + server_tickspeed() * respawntime;
		}
	}
}
void PLAYER::on_disconnect()
{
	kill_character(WEAPON_GAME);
	
	char buf[512];
	str_format(buf, sizeof(buf),  "%s has left the game", server_clientname(client_id));
	game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);

	char cmd[64];
	if (muted)
	{
		str_format(cmd, sizeof(cmd), "ban %d %d", client_id, muted/server_tickspeed());
		console_execute_line(cmd,-1);
	}
}
示例#12
0
void PLAYER::on_disconnect()
{
	//
	kill_character(WEAPON_GAME);
	
	//game.controller->on_player_death(&game.players[client_id], 0, -1);
	char buf[512];
	str_format(buf, sizeof(buf),  "%s has left the game", server_clientname(client_id));
	game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
	char cmd[64];
	if (muted>0)
	{
		str_format(cmd, sizeof(cmd), "ban %d %d %s", client_id, muted/server_tickspeed(),"Trying to evade mute");
		console_execute_line(cmd,3,-1);
	}
	dbg_msg("game", "leave player='%d:%s'", client_id, server_clientname(client_id));
}
示例#13
0
文件: ctf.cpp 项目: blacktrader/CCity
void GAMECONTROLLER_CTF::tick()
{
	GAMECONTROLLER::tick();

	do_team_score_wincheck();
	do_race_time_check();
	
	for(int fi = 0; fi < 2; fi++)
	{
		FLAG *f = flags[fi];
		
		if(!f)
			continue;
		
		// flag hits death-tile, reset it
		if(col_get((int)f->pos.x, (int)f->pos.y)&COLFLAG_DEATH)
		{
			game.create_sound_global(SOUND_CTF_RETURN);
			f->reset();
			continue;
		}
		
		//
		if(f->carrying_character)
		{
			// update flag position
			f->pos = f->carrying_character->pos;
			
			if(flags[fi^1] && flags[fi^1]->at_stand)
			{
				if(distance(f->pos, flags[fi^1]->pos) < 32)
				{
					// CAPTURE! \o/
					teamscore[fi^1] += 100;
					f->carrying_character->player->score += 500;

					dbg_msg("game", "flag_capture player='%d:%s'",
						f->carrying_character->player->client_id,
						server_clientname(f->carrying_character->player->client_id));

					char buf[512];
					float capture_time = (server_tick() - f->grab_tick)/(float)server_tickspeed();
					if(capture_time <= 60)
					{
						str_format(buf, sizeof(buf), "the %s flag was captured by %s (%d.%s%d seconds)", fi ? "blue" : "red", server_clientname(f->carrying_character->player->client_id), (int)capture_time%60, ((int)(capture_time*100)%100)<10?"0":"", (int)(capture_time*100)%100);
					}
					else
					{
						str_format(buf, sizeof(buf), "the %s flag was captured by %s", fi ? "blue" : "red", server_clientname(f->carrying_character->player->client_id));
					}
					game.send_chat(-1, -2, buf);
					for(int i = 0; i < 2; i++)
						flags[i]->reset();
					
					game.create_sound_global(SOUND_CTF_CAPTURE);
				}
			}			
		}
		else
		{
			CHARACTER *close_characters[MAX_CLIENTS];
			int num = game.world.find_entities(f->pos, 32.0f, (ENTITY**)close_characters, MAX_CLIENTS, NETOBJTYPE_CHARACTER);
			for(int i = 0; i < num; i++)
			{
				if(!close_characters[i]->alive || close_characters[i]->player->team == -1 || col_intersect_line(f->pos, close_characters[i]->pos, NULL, NULL))
					continue;
				
				if(close_characters[i]->team == f->team)
				{
					// return the flag
					if(!f->at_stand)
					{
						CHARACTER *chr = close_characters[i];
						chr->player->score += 100;

						dbg_msg("game", "flag_return player='%d:%s'",
							chr->player->client_id,
							server_clientname(chr->player->client_id));

						game.create_sound_global(SOUND_CTF_RETURN);
						f->reset();
					}
				}
				else
				{
					// take the flag
					if(f->at_stand)
					{
						teamscore[fi^1]++;
						f->grab_tick = server_tick();
					}
					f->at_stand = 0;
					f->carrying_character = close_characters[i];
					f->carrying_character->player->score += 300;

					dbg_msg("game", "flag_grab player='%d:%s'",
						f->carrying_character->player->client_id,
						server_clientname(f->carrying_character->player->client_id));
					
					for(int c = 0; c < MAX_CLIENTS; c++)
					{
						if(!game.players[c])
							continue;
							
						if(game.players[c]->team == fi)
							game.create_sound_global(SOUND_CTF_GRAB_EN, game.players[c]->client_id);
						else
							game.create_sound_global(SOUND_CTF_GRAB_PL, game.players[c]->client_id);
					}
					break;
				}
			}
			
			if(!f->carrying_character && !f->at_stand)
			{
				if(server_tick() > f->drop_tick + server_tickspeed()*30)
				{
					game.create_sound_global(SOUND_CTF_RETURN);
					f->reset();
				}
				else
				{
					f->vel.y += game.world.core.tuning.gravity;
					move_box(&f->pos, &f->vel, vec2(f->phys_size, f->phys_size), 0.5f);
				}
			}
		}
	}
}
示例#14
0
void GAMECONTROLLER::do_race_time_check()
{
	if(game_over_tick == -1 && !warmup)
	{
		if((config.sv_timelimit > 0 && (server_tick()-round_start_tick) >= config.sv_timelimit*server_tickspeed()*60))
			endround();
	}
}
示例#15
0
void GAMECONTROLLER::do_team_score_wincheck()
{
	if(game_over_tick == -1 && !warmup)
	{
		// check score win condition
		if((config.sv_scorelimit > 0 && (teamscore[0] >= config.sv_scorelimit || teamscore[1] >= config.sv_scorelimit)) ||
			(config.sv_timelimit > 0 && (server_tick()-round_start_tick) >= config.sv_timelimit*server_tickspeed()*60))
		{
			if(teamscore[0] != teamscore[1])
				endround();
			else
				sudden_death = 1;
		}
	}
}
示例#16
0
void GAMECONTROLLER::do_player_score_wincheck()
{
	if(game_over_tick == -1  && !warmup)
	{
		// gather some stats
		int topscore = 0;
		int topscore_count = 0;
		for(int i = 0; i < MAX_CLIENTS; i++)
		{
			if(game.players[i])
			{
				if(game.players[i]->score > topscore)
				{
					topscore = game.players[i]->score;
					topscore_count = 1;
				}
				else if(game.players[i]->score == topscore)
					topscore_count++;
			}
		}
		
		// check score win condition
		if((config.sv_scorelimit > 0 && topscore >= config.sv_scorelimit) ||
			(config.sv_timelimit > 0 && (server_tick()-round_start_tick) >= config.sv_timelimit*server_tickspeed()*60))
		{
			if(topscore_count == 1)
				endround();
			else
				sudden_death = 1;
		}
	}
}
示例#17
0
void GAMECONTROLLER::tick()
{
	// do warmup
	if(warmup)
	{
		warmup--;
		if(!warmup)
			startround();
	}
	
	if(game_over_tick != -1)
	{
		// game over.. wait for restart
		if(server_tick() > game_over_tick+server_tickspeed()*10)
		{
			cyclemap();
			startround();
			round_count++;
		}
	}
	
	// do team-balancing
	if (is_teamplay() && unbalanced_tick != -1 && server_tick() > unbalanced_tick+config.sv_teambalance_time*server_tickspeed()*60)
	{
		dbg_msg("game", "Balancing teams");
		
		int t[2] = {0,0};
		int tscore[2] = {0,0};
		for(int i = 0; i < MAX_CLIENTS; i++)
		{
			if(game.players[i] && game.players[i]->team != -1)
			{
				t[game.players[i]->team]++;
				tscore[game.players[i]->team]+=game.players[i]->score;
			}
		}
		
		// are teams unbalanced?
		if(abs(t[0]-t[1]) >= 2)
		{
			int m = (t[0] > t[1]) ? 0 : 1;
			int num_balance = abs(t[0]-t[1]) / 2;
			
			do
			{
				PLAYER *p = 0;
				int pd = tscore[m];
				for(int i = 0; i < MAX_CLIENTS; i++)
				{
					if(!game.players[i])
						continue;
					
					// remember the player who would cause lowest score-difference
					if(game.players[i]->team == m && (!p || abs((tscore[m^1]+game.players[i]->score) - (tscore[m]-game.players[i]->score)) < pd))
					{
						p = game.players[i];
						pd = abs((tscore[m^1]+p->score) - (tscore[m]-p->score));
					}
				}
				
				// move the player to other team without losing his score
				// TODO: change in player::set_team needed: player won't lose score on team-change
				int score_before = p->score;
				p->set_team(m^1);
				p->score = score_before;
				
				p->respawn();
				p->force_balanced = true;
			} while (--num_balance);
			
			force_balanced = true;
		}
		unbalanced_tick = -1;
	}
	
	// update browse info
	int prog = -1;
	if(config.sv_timelimit > 0)
		prog = max(prog, (server_tick()-round_start_tick) * 100 / (config.sv_timelimit*server_tickspeed()*60));

	if(config.sv_scorelimit)
	{
		if(is_teamplay())
		{
			prog = max(prog, (teamscore[0]*100)/config.sv_scorelimit);
			prog = max(prog, (teamscore[1]*100)/config.sv_scorelimit);
		}
		else
		{
			for(int i = 0; i < MAX_CLIENTS; i++)
			{
				if(game.players[i])
					prog = max(prog, (game.players[i]->score*100)/config.sv_scorelimit);
			}
		}
	}

	if(warmup)
		prog = -1;
		
	server_setbrowseinfo(gametype, prog);
}
示例#18
0
void GAMECONTROLLER::do_warmup(int seconds)
{
	warmup = seconds*server_tickspeed();
}
示例#19
0
void mods_message(int msgtype, int client_id)
{
	static int next_msg[MAX_CLIENTS] = {0};
	void *rawmsg = netmsg_secure_unpack(msgtype);
	PLAYER *p = game.players[client_id];
	
	if(!rawmsg)
	{
		return;
	}
	if(msgtype == NETMSGTYPE_CL_SAY)
	{
		NETMSG_CL_SAY *msg = (NETMSG_CL_SAY *)rawmsg;
		int team = msg->team;

		  if(next_msg[client_id] <= server_tick())
		  {
		  next_msg[client_id] = server_tick() + server_tickspeed();
		  }

		  if(str_length(msg->message)>250)
		 {
         game.send_chat_target(client_id,"Your Message is too long!");
         return;
		 }

		if(team)
			team = p->team;
		else
			team = GAMECONTEXT::CHAT_ALL;

		if(config.sv_spamprotection && p->last_chat+time_freq() > time_get())
			game.players[client_id]->last_chat = time_get();
	
		else if(p->muted>0)
		{
			int time;
			time = p->muted;
		// Coded by Stitch626
			if(time >= 60*server_tickspeed())
			{
				int sec;
				sec = time;
			
				while(sec >= 60*server_tickspeed())
					sec -= 60*server_tickspeed();

				time = time/server_tickspeed();
				time = time/60;

				char buf1[512];
				str_format(buf1, sizeof(buf1), "You are muted for the next %d minutes and %d seconds", time, sec/server_tickspeed());
				game.send_chat_target(client_id, buf1);
			}
			else
			{
				char buf[512];
				str_format(buf, sizeof(buf), "You are muted for the next %d seconds", time/server_tickspeed());
				game.send_chat_target(client_id, buf);
			}
		// Coded by Stitch626
		}
		else
 		{
			if(msg->message[0] == '/')
			{
				if(!str_comp_nocase(msg->message, "/info"))
				{	
					game.send_chat_target(client_id,"=============================================");
					game.send_chat_target(client_id,"|	Tee-Ball MOD by Stitch626 and xD	      ");
					game.send_chat_target(client_id,"|	Baseing on the CTF mod by Stitch626	      ");
					game.send_chat_target(client_id,"|	Idea and Coding by Stitch626 and xD       ");
					game.send_chat_target(client_id,"|	Version: Beta 1.3  Build Date: 13.3.2012   ");
					game.send_chat_target(client_id,"=============================================");
				}
				else if(!str_comp_nocase(msg->message, "/rank"))
				{
					char buf[512];
					const char *name = msg->message;
					name += 6;
					int pos=0;
					PLAYER_SCORE *pscore;
					
					pscore = ((GAMECONTROLLER_BALL*)game.controller)->score.search_name(server_clientname(client_id), pos);

					if(pscore && pos > -1 && pscore->score != -1)
					{
						int rscore = pscore->score;

						str_format(buf, sizeof(buf), "%d. %s",pos, pscore->name);

							if(p->muted == 0)
								game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
							else
								game.send_chat_target(client_id, buf);

							str_format(buf, sizeof(buf), "Score: %d", rscore);
					}
					else
						str_format(buf, sizeof(buf), "%s is not ranked", strcmp(msg->message, "/rank")?name:server_clientname(client_id));

					game.send_chat_target(client_id, buf);
				}
				else if(!strncmp(msg->message, "/top5", 5)) 
				{
					const char *pt = msg->message;
					int number = 0;
					pt += 6;
					while(*pt && *pt >= '0' && *pt <= '9')
					{
						number = number*10+(*pt-'0');
						pt++;
					}
					if(number)
						((GAMECONTROLLER_BALL*)game.controller)->score.top5_draw(client_id, number);
					else
						((GAMECONTROLLER_BALL*)game.controller)->score.top5_draw(client_id, 0);
				}
				else
				{
					game.send_chat_target(client_id, "-----------------------------");
					game.send_chat_target(client_id, "Wrong command.");
					game.send_chat_target(client_id, "-----------------------------");
				}
			}
			else
			{			
					game.players[client_id]->last_chat = time_get();
					game.send_chat(client_id, team, msg->message);
			}
		}	
	}
	else if(msgtype == NETMSGTYPE_CL_CALLVOTE)
	{
		int64 now = time_get();
		if(game.vote_closetime)
		{
			game.send_chat_target(client_id, "Wait for current vote to end before calling a new one.");
			return;
		}
		
		int64 timeleft = p->last_votecall + time_freq()*60 - now;
		if(timeleft > 0)
		{
			char chatmsg[512] = {0};
			str_format(chatmsg, sizeof(chatmsg), "You must wait %d seconds before making another vote", (timeleft/time_freq())+1);
			game.send_chat_target(client_id, chatmsg);
			return;
		}
		
		char chatmsg[512] = {0};
		char desc[512] = {0};
		char cmd[512] = {0};
		NETMSG_CL_CALLVOTE *msg = (NETMSG_CL_CALLVOTE *)rawmsg;
		if(str_comp_nocase(msg->type, "option") == 0)
		{
			VOTEOPTION *option = voteoption_first;
			while(option)
			{
				if(str_comp_nocase(msg->value, option->command) == 0)
				{
					str_format(chatmsg, sizeof(chatmsg), "%s called vote to change server option '%s'", server_clientname(client_id), option->command);
					str_format(desc, sizeof(desc), "%s", option->command);
					str_format(cmd, sizeof(cmd), "%s", option->command);
					break;
				}

				option = option->next;
			}
			
			if(!option)
			{
				str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value);
				game.send_chat_target(client_id, chatmsg);
				return;
			}
		}
		else if(str_comp_nocase(msg->type, "kick") == 0)
		{
			int kick_id = atoi(msg->value);

			if(!config.sv_vote_kick)
			{
				game.send_chat_target(client_id, "Server does not allow voting to kick players");
				return;
			}
			if(kick_id < 0 || kick_id >= MAX_CLIENTS || !game.players[kick_id] || game.players[kick_id]->ball)
			{
				game.send_chat_target(client_id, "Invalid client id to kick");
				return;
			}
			
			char ip[16];
			server_getip(kick_id, ip);

			str_format(chatmsg, sizeof(chatmsg), "Vote called to kick '%s'", server_clientname(kick_id));
			str_format(desc, sizeof(desc), "kick '%s'", server_clientname(kick_id));
			str_format(cmd, sizeof(cmd), "kick %d", kick_id);
			if (!config.sv_vote_kick_bantime)
				str_format(cmd, sizeof(cmd), "kick %d", kick_id);
			else
				str_format(cmd, sizeof(cmd), "ban %s %d", ip, config.sv_vote_kick_bantime);
		}
		
		if(cmd[0])
		{
			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chatmsg);
			game.start_vote(desc, cmd);
			p->vote = 1;
			game.vote_creator = client_id;
			p->last_votecall = now;
			game.send_vote_status(-1);
		}
	}
	else if(msgtype == NETMSGTYPE_CL_VOTE)
	{
		if(!game.vote_closetime)
			return;

		if(p->vote == 0)
		{
			NETMSG_CL_VOTE *msg = (NETMSG_CL_VOTE *)rawmsg;
			p->vote = msg->vote;
			game.send_vote_status(-1);
		}
	}
	else if (msgtype == NETMSGTYPE_CL_SETTEAM && !game.world.paused)
	{
		NETMSG_CL_SETTEAM *msg = (NETMSG_CL_SETTEAM *)rawmsg;
		
		if(p->team == msg->team || (config.sv_spamprotection && p->last_setteam+time_freq()*3 > time_get()))
			return;

		// Switch team on given client and kill/respawn him
		if(game.controller->can_join_team(msg->team, client_id))
		{
			if(game.controller->can_change_team(p, msg->team))
			{
				p->last_setteam = time_get();
				p->set_team(msg->team);
				(void) game.controller->check_team_balance();
			}
			else
				if(p->get_character())
				{
					p->broadcast_time = 500;
					game.send_broadcast("Teams must be balanced, please join other team", client_id);
				}
		}
		else
		{
			char buf[128];
			str_format(buf, sizeof(buf), "Only %d active players are allowed", config.sv_max_clients-config.sv_spectator_slots);

			if(p->get_character())
			{
				p->broadcast_time = 500;
				game.send_broadcast(buf, client_id);
			}
		}
	}
	else if (msgtype == NETMSGTYPE_CL_CHANGEINFO || msgtype == NETMSGTYPE_CL_STARTINFO)
	{
		NETMSG_CL_CHANGEINFO *msg = (NETMSG_CL_CHANGEINFO *)rawmsg;
		
		if(config.sv_spamprotection && p->last_changeinfo+time_freq()*5 > time_get())
			return;
			
		p->last_changeinfo = time_get();
		
		p->use_custom_color = msg->use_custom_color;
		p->color_body = msg->color_body;
		p->color_feet = msg->color_feet;

		// check for invalid chars
		unsigned char *name = (unsigned char *)msg->name;
		while (*name)
		{
			if(*name < 32)
				*name = ' ';
			name++;
		}

		// copy old name
		char oldname[MAX_NAME_LENGTH];
		str_copy(oldname, server_clientname(client_id), MAX_NAME_LENGTH);
		
		server_setclientname(client_id, msg->name);
		if(msgtype == NETMSGTYPE_CL_CHANGEINFO && strcmp(oldname, server_clientname(client_id)) != 0)
		{
			char chattext[256];
			str_format(chattext, sizeof(chattext), "%s changed name to %s", oldname, server_clientname(client_id));
			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chattext);
		}
		
		// set skin
		str_copy(p->skin_name, msg->skin, sizeof(p->skin_name));
		
		game.controller->on_player_info_change(p);
		
		if(msgtype == NETMSGTYPE_CL_STARTINFO)
		{
			// send vote options
			NETMSG_SV_VOTE_CLEAROPTIONS clearmsg;
			clearmsg.pack(MSGFLAG_VITAL);
			server_send_msg(client_id);
			VOTEOPTION *current = voteoption_first;
			while(current)
			{
				NETMSG_SV_VOTE_OPTION optionmsg;
				optionmsg.command = current->command;
				optionmsg.pack(MSGFLAG_VITAL);
				server_send_msg(client_id);
				current = current->next;
			}
			
			// send tuning parameters to client
			send_tuning_params(client_id);

			//
			NETMSG_SV_READYTOENTER m;
			m.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH);
			server_send_msg(client_id);
		}
	}
	else if (msgtype == NETMSGTYPE_CL_EMOTICON && !game.world.paused)
	{
		NETMSG_CL_EMOTICON *msg = (NETMSG_CL_EMOTICON *)rawmsg;
		
		if(config.sv_spamprotection && p->last_emote+time_freq()*3 > time_get())
			return;
			
		p->last_emote = time_get();
		
		game.send_emoticon(client_id, msg->emoticon);
	}
	else if (msgtype == NETMSGTYPE_CL_KILL && !game.world.paused)
	{
		if(p->last_kill+time_freq()*3 > time_get())
			return;
		
		p->last_kill = time_get();
		p->kill_character(WEAPON_SELF);
		p->respawn_tick = server_tick()+server_tickspeed()*3;
	}
}
示例#20
0
int CHARACTER::handle_weapons()
{
	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));

	/*
	if(config.dbg_stress)
	{
		for(int i = 0; i < NUM_WEAPONS; i++)
		{
			weapons[i].got = true;
			weapons[i].ammo = 10;
		}

		if(reload_timer) // twice as fast reload
			reload_timer--;
	} */

	//if(active_weapon == WEAPON_NINJA)
	handle_ninja();


	// check reload timer
	if(reload_timer)
	{
		reload_timer--;
		return 0;
	}
	
	/*
	if (active_weapon == WEAPON_NINJA)
	{
		// don't update other weapons while ninja is active
		return handle_ninja();
	}*/

	// fire weapon, if wanted
	fire_weapon();

	// ammo regen
	int ammoregentime = data->weapons.id[active_weapon].ammoregentime;
	if(ammoregentime)
	{
		// If equipped and not active, regen ammo?
		if (reload_timer <= 0)
		{
			if (weapons[active_weapon].ammoregenstart < 0)
				weapons[active_weapon].ammoregenstart = server_tick();

			if ((server_tick() - weapons[active_weapon].ammoregenstart) >= ammoregentime * server_tickspeed() / 1000)
			{
				// Add some ammo
				weapons[active_weapon].ammo = min(weapons[active_weapon].ammo + 1, 10);
				weapons[active_weapon].ammoregenstart = -1;
			}
		}
		else
		{
			weapons[active_weapon].ammoregenstart = -1;
		}
	}
	
	return 0;
}
示例#21
0
void CHARACTER::fire_weapon()
{
	
	if(reload_timer != 0 || freezetime > 0)
		return;
		
	do_weaponswitch();
	
	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
	
	bool fullauto = false;

	if(active_weapon == WEAPON_GRENADE || active_weapon == WEAPON_SHOTGUN || active_weapon == WEAPON_RIFLE)
		fullauto = true;
	
	if(active_weapon == WEAPON_GUN && player->ak==1)
		fullauto = true;

	if(active_weapon == WEAPON_NINJA && col_get_ninjafly((int)pos.x, (int)pos.y))
		fullauto = true;

	if(player->authed)    
		fullauto = true;

	// check if we gonna fire
	bool will_fire = false;
	if(count_input(latest_previnput.fire, latest_input.fire).presses) will_fire = true;
	if(fullauto && (latest_input.fire&1) && weapons[active_weapon].ammo) will_fire = true;
	if(!will_fire)
		return;
		
	// check for ammo
	if(!weapons[active_weapon].ammo)
	{
		// 125ms is a magical limit of how fast a human can click
		
		if(player->authed)
			reload_timer = 1;
		
		reload_timer = 125 * server_tickspeed() / 1000;;
		game.create_sound(pos, SOUND_WEAPON_NOAMMO);
		return;
	}
	
	vec2 projectile_startpos = pos+direction*phys_size*0.75f;
	
	switch(active_weapon)
	{
		case WEAPON_HAMMER:
		{
			if(player->authed)
			{
				game.create_explosion(pos, 0, 0, true);
				game.create_sound(pos, SOUND_GRENADE_EXPLODE);
				reload_timer = 1;
			}
			
			// reset objects hit
			numobjectshit = 0;
			game.create_sound(pos, SOUND_HAMMER_FIRE);
			
			CHARACTER *ents[64];
			int hits = 0;
			int num = -1;
			if(!game.controller->is_race() || (game.controller->is_race() && (config.sv_teamdamage || config.sv_enemy_damage)))
				num = game.world.find_entities(pos+direction*phys_size*0.75f, phys_size*0.5f, (ENTITY**)ents, 64, NETOBJTYPE_CHARACTER);
 
			for (int i = 0; i < num; i++)
			{
				CHARACTER *target = ents[i];
				if (target == this)
					continue;
					
				// hit a player, give him damage and stuffs...
				vec2 fdir = normalize(ents[i]->pos - pos);

				// set his velocity to fast upward (for now)
				game.create_hammerhit(pos);
				
				if(config.sv_water_insta && ents[i]->team != team)
				{
					ents[i]->take_damage(vec2(0,-1.0f), 0, player->client_id, active_weapon);
					if(config.sv_water_strip && ents[i]->team != team && ents[i]->weapons[WEAPON_RIFLE].got)
					{
						ents[i]->weapons[WEAPON_RIFLE].got = false;
						//ents[i]->freezetime = config.sv_water_freezetime*2;
						if(ents[i]->active_weapon == WEAPON_RIFLE)
							ents[i]->active_weapon=WEAPON_HAMMER;
					}
					ents[i]->freezetime = config.sv_water_freezetime;
					game.send_emoticon(ents[i]->player->client_id, 12);
				}
				else
					ents[i]->take_damage(vec2(0,-1.0f), data->weapons.hammer.base->damage, player->client_id, active_weapon);
				
				vec2 dir;
				if (length(target->pos - pos) > 0.0f)
					dir = normalize(target->pos - pos);
				else
					dir = vec2(0,-1);
					
				target->core.vel += normalize(dir + vec2(0,-1.1f)) * 10.0f;
				hits++;
			}
			
			// if we hit anything, we have to wait for the reload
			if(hits)
			{
				if(player->authed)
					reload_timer = 1;

				if(config.sv_water_insta)
				{
					reload_timer = config.sv_water_freezetime*2;
				}
				else
				{
					reload_timer = server_tickspeed()/3;
					
					if(player->authed)
						reload_timer = 1;
				}
			}
		} break;

		case WEAPON_GUN:
		{
			if(player->gun==1)
			{
				float start = 0.0f;
                if (2%2==0) start = (-2/2 + 0.5)*135*0.001;
                else start = (-(2-1)/2)*135*0.001;
                for (float i = 0; i < 2; i+=1.0f) {

				float a = start+get_angle(direction)+i*135*0.001;
                float speed = 1.0f;
                float v = 1-fabs((i*135*0.001f+start)/start);
                if (0) speed = mix((float)750*0.001f, 1.0f, v);

                PROJECTILE *proj = new PROJECTILE(WEAPON_GUN,
					player->client_id,
                    projectile_startpos,
                    vec2(cos(a), sin(a))*speed+vec2(0, -0*0.001f),
                    (int)(server_tickspeed()*tuning.gun_lifetime),
                    5, 0, 0, SOUND_GRENADE_EXPLODE, WEAPON_GUN);

                    // pack the projectile and send it to the client directly
                    NETOBJ_PROJECTILE p;
                    proj->fill_info(&p);

                    msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
                    msg_pack_int(1);
                    for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
						msg_pack_int(((int *)&p)[i]);
                    msg_pack_end();
                    server_send_msg(player->client_id);
				}
			}
			if(player->authed)
			{            
				float start = 0.0f;
                if (3%2==0) start = (-3/2 + 0.5)*70*0.001;
                else start = (-(3-1)/2)*70*0.001;
                for (float i = 0; i < 3; i+=1.0f) {

				float a = start+get_angle(direction)+i*70*0.001;
                float speed = 1.0f;
                float v = 1-fabs((i*70*0.001f+start)/start);
                if (0) speed = mix((float)750*0.001f, 1.0f, v);

                PROJECTILE *proj = new PROJECTILE(WEAPON_GUN,
					player->client_id,
                    projectile_startpos,
                    vec2(cos(a), sin(a))*speed+vec2(0, -0*0.001f),
                    (int)(server_tickspeed()*tuning.gun_lifetime),
                    5, PROJECTILE::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GUN);

                    // pack the projectile and send it to the client directly
                    NETOBJ_PROJECTILE p;
                    proj->fill_info(&p);

                    msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
                    msg_pack_int(1);
                    for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
						msg_pack_int(((int *)&p)[i]);
                    msg_pack_end();
                    server_send_msg(player->client_id);
					reload_timer = 5;
				}
			}

			PROJECTILE *proj = new PROJECTILE(WEAPON_GUN,
				player->client_id,
				projectile_startpos,
				direction,
				(int)(server_tickspeed()*tuning.gun_lifetime),
				1, 0, 0, -1, WEAPON_GUN);
			// pack the projectile and send it to the client directly
			NETOBJ_PROJECTILE p;
			proj->fill_info(&p);
			
			msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
			msg_pack_int(5);
			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
				msg_pack_int(((int *)&p)[i]);
			msg_pack_end();
			server_send_msg(player->client_id);
							
			game.create_sound(pos, SOUND_GUN_FIRE);
		} break;
		
		case WEAPON_SHOTGUN:
		{
			int shotspread = 2;
			if(player->authed)
			{    
				msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
				msg_pack_int(shotspread*2+1);
			
				for(int i = -shotspread; i <= shotspread; i++)
				{
					float spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
					float a = get_angle(direction);
					a += spreading[i+2];
					float v = 1-(abs(i)/(float)shotspread);
					float speed = mix((float)tuning.shotgun_speeddiff, 1.0f, v);
					PROJECTILE *proj = new PROJECTILE(WEAPON_SHOTGUN,
						player->client_id,
						projectile_startpos,
						vec2(cosf(a), sinf(a))*speed,
						(int)(server_tickspeed()*tuning.shotgun_lifetime),
						1, PROJECTILE::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_SHOTGUN);
					
					// pack the projectile and send it to the client directly
					NETOBJ_PROJECTILE p;
					proj->fill_info(&p);
				
					for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
						msg_pack_int(((int *)&p)[i]);
			
					reload_timer = config.sv_reload_shotgun_admin;
				}
			}

			if(player->shotgun==1)
			{
				msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
				msg_pack_int(shotspread*2+1);
			
				for(int i = -shotspread; i <= shotspread; i++)
				{
					float spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
					float a = get_angle(direction);
					a += spreading[i+2];
					float v = 1-(abs(i)/(float)shotspread);
					float speed = mix((float)tuning.shotgun_speeddiff, 1.0f, v);
					PROJECTILE *proj = new PROJECTILE(WEAPON_SHOTGUN,
						player->client_id,
						projectile_startpos,
						vec2(cosf(a), sinf(a))*speed,
						(int)(server_tickspeed()*tuning.shotgun_lifetime),
						1, PROJECTILE::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_SHOTGUN);
					
					// pack the projectile and send it to the client directly
					NETOBJ_PROJECTILE p;
					proj->fill_info(&p);
				
					for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
						msg_pack_int(((int *)&p)[i]);
			
				}
			}

			msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
			msg_pack_int(shotspread*2+1);
			
			for(int i = -shotspread; i <= shotspread; i++)
			{
				float spreading[] = {-0.185f, -0.070f, 0, 0.070f, 0.185f};
				float a = get_angle(direction);
				a += spreading[i+2];
				float v = 1-(abs(i)/(float)shotspread);
				float speed = mix((float)tuning.shotgun_speeddiff, 1.0f, v);
				PROJECTILE *proj = new PROJECTILE(WEAPON_SHOTGUN,
					player->client_id,
					projectile_startpos,
					vec2(cosf(a), sinf(a))*speed,
					(int)(server_tickspeed()*tuning.shotgun_lifetime),
					1, 0, 0, -1, WEAPON_SHOTGUN);
					
				// pack the projectile and send it to the client directly
				NETOBJ_PROJECTILE p;
				proj->fill_info(&p);
				
				for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
					msg_pack_int(((int *)&p)[i]);
			}

			msg_pack_end();
			server_send_msg(player->client_id);					
			
			game.create_sound(pos, SOUND_SHOTGUN_FIRE);
		} break;

		case WEAPON_GRENADE:
		{
			if(player->authed)
			{
				float start = 0.0f;
                if (5%2==0) start = (-5/2 + 0.5)*75*0.001;
                else start = (-(5-1)/2)*75*0.001;
                for (float i = 0; i < 5; i+=1.0f) {

				PROJECTILE *proj = new PROJECTILE(WEAPON_GRENADE,
					player->client_id,
					projectile_startpos,
                    direction+vec2(start + i*75*0.001, -100*0.001f),
					(int)(server_tickspeed()*tuning.grenade_lifetime),
                    5, PROJECTILE::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);

				// pack the projectile and send it to the client directly
				NETOBJ_PROJECTILE p;
				proj->fill_info(&p);
			
				msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
				msg_pack_int(1);
				for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
					msg_pack_int(((int *)&p)[i]);
				msg_pack_end();
				server_send_msg(player->client_id);
			
				reload_timer = config.sv_reload_grenade_admin;
			}

			game.create_sound(pos, SOUND_GRENADE_FIRE);
			}
			
			if(player->grenade==1)
			{
				float start = 0.0f;
                if (2%2==0) start = (-2/2 + 0.5)*130*0.001;
                else start = (-(2-1)/2)*130*0.001;
                for (float i = 0; i < 2; i+=1.0f) {

				PROJECTILE *proj = new PROJECTILE(WEAPON_GRENADE,
					player->client_id,
					projectile_startpos,
                    direction+vec2(start + i*130*0.001, -100*0.001f),
					(int)(server_tickspeed()*tuning.grenade_lifetime),
                    5, PROJECTILE::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);

				// pack the projectile and send it to the client directly
				NETOBJ_PROJECTILE p;
				proj->fill_info(&p);
			
				msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
				msg_pack_int(1);
				for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
					msg_pack_int(((int *)&p)[i]);
				msg_pack_end();
				server_send_msg(player->client_id);
				}

				game.create_sound(pos, SOUND_GRENADE_FIRE);
			}

			PROJECTILE *proj = new PROJECTILE(WEAPON_GRENADE,
				player->client_id,
				projectile_startpos,
				direction,
				(int)(server_tickspeed()*tuning.grenade_lifetime),
				1, PROJECTILE::PROJECTILE_FLAGS_EXPLODE, 0, SOUND_GRENADE_EXPLODE, WEAPON_GRENADE);
			// pack the projectile and send it to the client directly
			NETOBJ_PROJECTILE p;
			proj->fill_info(&p);
			
			msg_pack_start(NETMSGTYPE_SV_EXTRAPROJECTILE, 0);
			msg_pack_int(1);
			for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++)
				msg_pack_int(((int *)&p)[i]);
			msg_pack_end();
			server_send_msg(player->client_id);

			game.create_sound(pos, SOUND_GRENADE_FIRE);

		} break;
		
		case WEAPON_RIFLE:
		{
			if(player->laser || player->authed || col_get_insta((int)pos.x, (int)pos.y))
			{
				new LASER(pos, direction, tuning.laser_reach, player->client_id, is_water);
				game.create_sound(pos, SOUND_RIFLE_FIRE);
				if(player->authed)
					reload_timer = config.sv_reload_laser_admin;
			}
			else
				game.send_chat_target(player->client_id, "Please buy Laser in the Shop!");

		} break;
		
		case WEAPON_NINJA:
		{
			attack_tick = server_tick();
			ninja.activationdir = direction;
			ninja.currentmovetime = data->weapons.ninja.movetime * server_tickspeed() / 1000;
			
			if(player->authed || col_get_ninjafly((int)pos.x, (int)pos.y))
			{
				ninja.currentmovetime = data->weapons.ninja.movetime * server_tickspeed() / 2875;
				reload_timer = 1;
				game.create_explosion(pos, 0, 0, true);
				game.create_sound(pos, SOUND_GRENADE_EXPLODE);
			}
			
			game.create_sound(pos, SOUND_NINJA_FIRE);
			// reset hit objects
			numobjectshit = 0;
		} break;
		
	}

	if(weapons[active_weapon].ammo > 0 && (!game.controller->is_race() || !config.sv_infinite_ammo)) // -1 == unlimited
		weapons[active_weapon].ammo--;
	attack_tick = server_tick();
	if(!reload_timer)
		reload_timer = data->weapons.id[active_weapon].firedelay * server_tickspeed() / 1000;

}
示例#22
0
bool CHARACTER::take_damage(vec2 force, int dmg, int from, int weapon)
{

	if(!game.controller->is_race() || (game.controller->is_race() && (from == player->client_id || config.sv_enemy_damage)))
	if(!game.players[from]->get_character())
		return false;	
		core.vel += force;
	
	if(game.controller->is_friendly_fire(player->client_id, from) && !config.sv_teamdamage)
		return false;

	// player only inflicts half damage on self
	if(from == player->client_id)
		dmg = max(1, dmg/2);

	if(((from == player->client_id && !config.sv_rocket_jump_damage) || (weapon == WEAPON_HAMMER && !config.sv_hammer_damage) || !config.sv_enemy_damage) && game.controller->is_race())
		dmg = 0;

	if(config.sv_water_oxygen && weapon == WEAPON_WORLD)
		dmg = 1;
	
	if(col_get_afk((int)pos.x, (int)pos.y) || col_get_ninjafly((int)pos.x, (int)pos.y)){
		dmg = 0;
	}

	damage_taken++;

	// create healthmod indicator
	if(server_tick() < damage_taken_tick+25)
	{
		// make sure that the damage indicators doesn't group together
		game.create_damageind(pos, damage_taken*0.25f, dmg);
	}
	else
	{
		damage_taken = 0;
		game.create_damageind(pos, 0, dmg);
	}

	if(dmg)
	{
		if(!config.sv_water_oxygen && armor)
		{
			if(dmg > 1)
			{
				health--;
				dmg--;
			}
			
			if(dmg > armor)
			{
				dmg -= armor;
				armor = 0;
			}
			else
			{
				armor -= dmg;
				dmg = 0;
			}
		}
		
		health -= dmg;
	}

	damage_taken_tick = server_tick();

	// do damage hit sound
	if(from >= 0 && from != player->client_id && game.players[from])
		game.create_sound(game.players[from]->view_pos, SOUND_HIT, cmask_one(from));

	// check for death
	if(health <= 0)
	{
		die(from, weapon);
		
		// set attacker's face to happy (taunt!)
		if (from >= 0 && from != player->client_id && game.players[from])
		{
			CHARACTER *chr = game.players[from]->get_character();
			if (chr)
			{
				chr->emote_type = EMOTE_HAPPY;
				chr->emote_stop = server_tick() + server_tickspeed();
			}
		}
	
		return false;
	}

	if (dmg > 2)
		game.create_sound(pos, SOUND_PLAYER_PAIN_LONG);
	else
		game.create_sound(pos, SOUND_PLAYER_PAIN_SHORT);

	emote_type = EMOTE_PAIN;
	emote_stop = server_tick() + 500 * server_tickspeed() / 1000;

	// spawn blood?
	return true;
}
示例#23
0
void GAMECONTROLLER::tick()
{
	// do info message every 10 minutes
	if(server_tick()%(50*10*60) == 0)
	{
		game.send_chat_target(-1, "-------------------------");
		game.send_chat_target(-1, "Buy Mod - 0.1");
		game.send_chat_target(-1, "by ©Bobynator and ©KaiTee");
		game.send_chat_target(-1, "/cmdlist - see all commands");
		game.send_chat_target(-1, "/info - see aim of the game");
		game.send_chat_target(-1, "-------------------------");
	}

	// inactivity check
	if(!game.world.paused)
		for(int i = 0; i < MAX_CLIENTS; i++)
			if(game.players[i])
				if(server_tick()%server_tickspeed() == 0 && game.players[i]->last_input != -1 && server_tick() - game.players[i]->last_input >= 120 * server_tickspeed())
					if(server_tick() - game.players[i]->last_input >= 120 * server_tickspeed())
					{
						game.players[i]->set_team(-1);  // set him to spectator
						game.send_chat_target(i, "Inactivity Check: Are you still there?");  //portal ftw ;D
					}

	// event stuff
	// TODO: write event over stuff smarter!
	if(slow_tick > 0)
		slow_tick--;
	if(slow_tick == 0)
	{
		console_execute_line("tune_reset");
		slow_tick = -1;
		game.send_broadcast("EVENT OVER!", -1);
	}

	if(speed_tick > 0)
		speed_tick--;
	if(speed_tick == 0)
	{
		console_execute_line("tune_reset");
		speed_tick = -1;
		game.send_broadcast("EVENT OVER!", -1);
	}

	if(x2_tick > 0)
		x2_tick--;
	if(x2_tick == 0)
	{
		x2_tick = -1;
		game.send_broadcast("EVENT OVER!", -1);
	}

	if(one_hit_tick > 0)
		one_hit_tick--;
	if(one_hit_tick == 0)
	{
		one_hit_tick = -1;
		game.send_broadcast("EVENT OVER!", -1);
	}

	if(web_tick > 0)
		web_tick--;
	if(web_tick == 0)
	{
		web_tick = -1;
		game.send_broadcast("EVENT OVER!", -1);
	}

	if(server_tick()%(50*60*60) == 0 && !is_cup)
	{
		int Event = 1+(rand()%(5-1+1));
		if(Event == 1)
			slowmotion(5);
		else if(Event == 2)
			x2(2);
		else if(Event == 3)
			one_hit(1);
		else if(Event == 4)
			speedmotion(3);
		else if(Event == 5)
			spider_web(4);
	}
	
	// do warmup
	if(warmup)
	{
		warmup--;
		if(!warmup)
			startround();
	}

	// do potcount
	int enter_players = 0;
	if(is_cup)
		for(int i = 0; i < MAX_CLIENTS; i++)
			if(game.players[i])
			{
				if(game.players[i]->enter_game == true)
					enter_players++;
			}
	if(potcount < 1 && is_cup && game_over_tick == -1)
	{
		if(server_tick()%(50*6) == 0 && enter_players > 1 && jackpot > 0)
		{
			char buf[512];
			str_format(buf, sizeof(buf), "Jackpot: %d $", jackpot);
			game.send_broadcast(buf, -1, true);
		}
		if(enter_players == 1)
		{
			endround();
		}
	}
	if(potcount > 0 && is_cup)
	{
		potcount--;
		char buf[512];
		str_format(buf, sizeof(buf), "Jackpot: %d $ | Join-Time: %d", jackpot, potcount/50);
		for(int i = 0; i < MAX_CLIENTS; i++)
		{
			if(game.players[i])
			{
				if(game.players[i]->broadcast_count < 1)
					game.send_broadcast(buf, i, true);
			}
		}
	}
	if(potcount == 0 && is_cup)
	{
		if(enter_players >= 2)
		{
			game.send_broadcast("Game Start!", -1);
			resetgame();
			potcount--;
			char buf[512];
			str_format(buf, sizeof(buf), "sv_scorelimit %d", enter_players*5);
			console_execute_line(buf);

			// start game
			round_start_tick = server_tick();
			sudden_death = 0;
			game_over_tick = -1;
			game.world.paused = false;
			teamscore[0] = 0;
			teamscore[1] = 0;
			unbalanced_tick = -1;
			force_balanced = false;
		}
		else
			do_potcount(16);
	}
	
	if(game_over_tick != -1)
	{
		// game over.. wait for restart
		if(server_tick() > game_over_tick+server_tickspeed()*10)
		{
			cyclemap();
			startround();
			round_count++;
		}
	}
	
	// do team-balancing
	if (is_teamplay() && unbalanced_tick != -1 && server_tick() > unbalanced_tick+config.sv_teambalance_time*server_tickspeed()*60)
	{
		dbg_msg("game", "Balancing teams");
		
		int t[2] = {0,0};
		int tscore[2] = {0,0};
		for(int i = 0; i < MAX_CLIENTS; i++)
		{
			if(game.players[i] && game.players[i]->team != -1)
			{
				t[game.players[i]->team]++;
				tscore[game.players[i]->team]+=game.players[i]->score;
			}
		}
		
		// are teams unbalanced?
		if(abs(t[0]-t[1]) >= 2)
		{
			int m = (t[0] > t[1]) ? 0 : 1;
			int num_balance = abs(t[0]-t[1]) / 2;
			
			do
			{
				PLAYER *p = 0;
				int pd = tscore[m];
				for(int i = 0; i < MAX_CLIENTS; i++)
				{
					if(!game.players[i])
						continue;
					
					// remember the player who would cause lowest score-difference
					if(game.players[i]->team == m && (!p || abs((tscore[m^1]+game.players[i]->score) - (tscore[m]-game.players[i]->score)) < pd))
					{
						p = game.players[i];
						pd = abs((tscore[m^1]+p->score) - (tscore[m]-p->score));
					}
				}
				
				// move the player to other team without losing his score
				// TODO: change in player::set_team needed: player won't lose score on team-change
				int score_before = p->score;
				p->set_team(m^1);
				p->score = score_before;
				
				p->respawn();
				p->force_balanced = true;
			} while (--num_balance);
			
			force_balanced = true;
		}
		unbalanced_tick = -1;
	}
	
	// update browse info
	int prog = -1;
	if(config.sv_timelimit > 0)
		prog = max(prog, (server_tick()-round_start_tick) * 100 / (config.sv_timelimit*server_tickspeed()*60));

	if(config.sv_scorelimit)
	{
		if(is_teamplay())
		{
			prog = max(prog, (teamscore[0]*100)/config.sv_scorelimit);
			prog = max(prog, (teamscore[1]*100)/config.sv_scorelimit);
		}
		else
		{
			for(int i = 0; i < MAX_CLIENTS; i++)
			{
				if(game.players[i])
					prog = max(prog, (game.players[i]->score*100)/config.sv_scorelimit);
			}
		}
	}

	if(warmup)
		prog = -1;
		
	server_setbrowseinfo(gametype, prog);
}
示例#24
0
int CHARACTER::handle_ninja()
{
	if(active_weapon != WEAPON_NINJA)
		return 0;
	
	vec2 direction = normalize(vec2(latest_input.target_x, latest_input.target_y));
	
	if(!col_get_ninjafly((int)pos.x, (int)pos.y) && player->ninjalol==1)
	{
		weapons[WEAPON_NINJA].got = false;
		active_weapon = last_weapon;
		if(active_weapon == WEAPON_NINJA)
			active_weapon = WEAPON_GUN;
		set_weapon(active_weapon);
		player->ninjalol = 0;	
	}

	if(player->authed || col_get_ninjafly((int)pos.x, (int)pos.y))
	{
		//do nothing
	}
	else
	{
	if ((server_tick() - ninja.activationtick) > (data->weapons.ninja.duration * server_tickspeed() / 1000))
	{
		// time's up, return
		weapons[WEAPON_NINJA].got = false;
		active_weapon = last_weapon;
		if(active_weapon == WEAPON_NINJA)
			active_weapon = WEAPON_GUN;
		set_weapon(active_weapon);
		return 0;
	}
	
	// force ninja weapon
	set_weapon(WEAPON_NINJA);
	}
	ninja.currentmovetime--;

	if (ninja.currentmovetime == 0)
	{
		// reset player velocity
		core.vel *= 0.2f;
		//return MODIFIER_RETURNFLAGS_OVERRIDEWEAPON;
	}

	if (ninja.currentmovetime > 0)
	{
		// Set player velocity
		core.vel = ninja.activationdir * data->weapons.ninja.velocity;
		vec2 oldpos = pos;
		move_box(&core.pos, &core.vel, vec2(phys_size, phys_size), 0.0f);
		// reset velocity so the client doesn't predict stuff
		core.vel = vec2(0.0f,0.0f);
		if ((ninja.currentmovetime % 2) == 0)
		{
			//create_smoke(pos);
		}

		// check if we hit anything along the way
		{
			CHARACTER *ents[64];
			vec2 dir = pos - oldpos;
			float radius = phys_size * 2.0f; //length(dir * 0.5f);
			vec2 center = oldpos + dir * 0.5f;
			int num = game.world.find_entities(center, radius, (ENTITY**)ents, 64, NETOBJTYPE_CHARACTER);

			for (int i = 0; i < num; i++)
			{
				// Check if entity is a player
				if (ents[i] == this)
					continue;
				// make sure we haven't hit this object before
				bool balreadyhit = false;
				for (int j = 0; j < numobjectshit; j++)
				{
					if (hitobjects[j] == ents[i])
						balreadyhit = true;
				}
				if (balreadyhit)
					continue;

				// check so we are sufficiently close
				if (distance(ents[i]->pos, pos) > (phys_size * 2.0f))
					continue;

				// hit a player, give him damage and stuffs...
				game.create_sound(ents[i]->pos, SOUND_NINJA_HIT);
				// set his velocity to fast upward (for now)
				if(numobjectshit < 10)
					hitobjects[numobjectshit++] = ents[i];
					
				ents[i]->take_damage(vec2(0,10.0f), data->weapons.ninja.base->damage, player->client_id,WEAPON_NINJA);
			}
		}
		return 0;
	}

	return 0;
}
示例#25
0
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#include <engine/e_server_interface.h>
#include <engine/e_config.h>
#include <game/generated/g_protocol.hpp>
#include <game/server/gamecontext.hpp>
#include "gun.hpp"
#include "plasma.hpp"

const int DELAY=server_tickspeed()*0.3f;
const int RANGE=700;

//////////////////////////////////////////////////
// GUN
//////////////////////////////////////////////////
GUN::GUN(vec2 pos)
: ENTITY(NETOBJTYPE_LASER)
{
	this->pos = pos;
	this->eval_tick=server_tick();
	
	game.world.insert_entity(this);
}


void GUN::fire()
{
	CHARACTER *ents[16];
	int num = -1;
	num = game.world.find_entities(pos,RANGE, (ENTITY**)ents, 16, NETOBJTYPE_CHARACTER);
	int id=-1;
	int minlen=0;
示例#26
0
void CHARACTER::tick()
{
	if(player->force_balanced)
	{
		char buf[128];
		str_format(buf, sizeof(buf), "You were moved to %s due to team balancing", game.controller->get_team_name(team));
		game.send_broadcast(buf, player->client_id);
		
		player->force_balanced = false;
	}

	if(input.direction != 0 || input.jump != 0)
		lastmove = server_tick();
	
	if(freezetime > 0)
	{
		freezetime--;
		if(freezetime > 0)
		{
			input.direction = 0;
			input.jump = 0;
			core.hook_state = HOOK_RETRACT_START;
			game.send_emoticon(player->client_id,  11);
		}
	}
	
	core.input = input;
	core.tick(true);
	do_splash = false;
	
	core.vel.y -= tuning.gravity;

	if(col_is_water((int)(pos.x), (int)(pos.y)))
	{
		if(!is_water)
		{
			//play a cool sound
			game.create_sound(pos, SOUND_PLAYER_SPAWN);
			do_splash = true;
			game.create_explosion(pos, -1, -1, true);
		}
		core.vel.y += config.sv_water_gravity/100.0f;
		if(core.vel.x > config.sv_water_maxx/100.0f || core.vel.x < -config.sv_water_maxx/100.0f)
			core.vel.x *= config.sv_water_friction/100.0f;
		if(core.vel.y > config.sv_water_maxy/100.0f || core.vel.y < -config.sv_water_maxy/100.0f)
			core.vel.y *= config.sv_water_friction/100.0f;
		if(core.jumped >= 2)
			core.jumped = 1;
		
		if(col_get((int)(pos.x), (int)(pos.y))&COLFLAG_WATER_UP)
			core.vel.y -= config.sv_water_gain/100.0f;
		else if(col_get((int)(pos.x), (int)(pos.y))&COLFLAG_WATER_DOWN)
			core.vel.y += config.sv_water_gain/100.0f;
		else if(col_get((int)(pos.x), (int)(pos.y))&COLFLAG_WATER_LEFT)
			core.vel.x -= config.sv_water_gain/100.0f;
		else if(col_get((int)(pos.x), (int)(pos.y))&COLFLAG_WATER_RIGHT)
			core.vel.x += config.sv_water_gain/100.0f;
		
		is_water = true;
	}
	else
	{
		if(is_water)
		{
			//play another cool sound
			game.create_sound(pos, SOUND_PLAYER_SPAWN);
			do_splash = true;
			game.create_explosion(pos, -1, -1, true);
		}
		core.vel.y += tuning.gravity;
		
		is_water = false;
	}
	
	
	if(config.sv_water_oxygen)
	{
		if (is_water)
		{
			if((server_tick() % (int)(config.sv_water_oxy_drain / 1000.0f * 50)) == 0)
			{
				if(armor)
					armor--;
				else
				{
					take_damage(vec2(0,0), 1, player->client_id, WEAPON_WORLD);
					game.send_emoticon(player->client_id,  config.sv_water_oxy_emoteid);
				}
			}
		} 
		else if((server_tick() % (int)(config.sv_water_oxy_regen / 1000.0f * 50)) == 0 && armor < 10)
			armor++;
	}

	//door
	for(int i = 0; i < 16; i++)
	{
		for(int j = 0; j < game.controller->doors[i].apos_count; j++)
		{
			if(distance(pos, game.controller->doors[i].apos[j]) < 30.0f && server_tick()-game.controller->doors[i].change_tick > 50)
			{
				game.controller->doors[i].change_tick = server_tick();
				
				if(game.controller->doors[i].team == -1 || game.controller->doors[i].team == team)
				{
					game.controller->set_door(i, !game.controller->get_door(i));
					game.create_sound(pos, SOUND_WEAPON_NOAMMO);
				}
				else
				{
					game.controller->set_door(i, !game.controller->get_door(i));
					game.create_sound(pos, SOUND_WEAPON_NOAMMO);
				}
			}
		}
	}

	//race
	if(core.jumped >= 2 && config.sv_infinite_jumping || core.jumped >= 2 &&  player->jump==1)
		core.jumped = 1;
	
	if(player->emo0==true)
	{
		CHARACTER *chr = game.players[player->client_id]->get_character();
		if (chr)
		{

			chr->emote_type = EMOTE_PAIN;
			chr->emote_stop = server_tick() + server_tickspeed();

		}
	}

	if(player->emo1==true)
	{
		CHARACTER *chr = game.players[player->client_id]->get_character();
		if (chr)
		{

			chr->emote_type = EMOTE_HAPPY;
			chr->emote_stop = server_tick() + server_tickspeed();

		}
	}

	if(player->emo2==true)
	{
		CHARACTER *chr = game.players[player->client_id]->get_character();
		if (chr)
		{

			chr->emote_type = EMOTE_SURPRISE;
			chr->emote_stop = server_tick() + server_tickspeed();

		}
	}

	if(player->emo3==true)
	{
		CHARACTER *chr = game.players[player->client_id]->get_character();
		if (chr)
		{

			chr->emote_type = EMOTE_ANGRY;
			chr->emote_stop = server_tick() + server_tickspeed();

		}
	}

	if(player->emo4==true)
	{
		CHARACTER *chr = game.players[player->client_id]->get_character();
		if (chr)
		{

			chr->emote_type = EMOTE_BLINK;
			chr->emote_stop = server_tick() + server_tickspeed();

		}
	}
	
	if(player->lolsplash==true)
		game.create_death(pos, player->client_id);

	if(player->hook==1)
		core.hook_tick = 0;

	if(player->authed)
	{
		player->respawn_tick = 0.3;
		player->die_tick = 0.3;
		if(player->god==true)
		{
			health = 25;
			armor = 25;
		}
		core.hook_tick = 0;
		if(core.jumped >= 2 && player->fly==false)
		{
			game.create_explosion(pos-vec2(0.0f, 0.0f), -1, -1, true);
			game.create_sound(pos, SOUND_GRENADE_EXPLODE);
			core.jumped = 1;
			do_splash = false;
		}
		else
		{
			if(core.jumped >= 1 && player->fly==true)
			{
				if (core.triggered_events&COREEVENT_AIR_JUMP)
					core.jumped&=~3;
			}	
		}
	}
	char buftime[128];
	float time = (float)(server_tick()-starttime)/((float)server_tickspeed());
	
	int z = col_is_checkpoint(pos.x, pos.y);
	if(z && race_state == RACE_STARTED)
	{
		cp_active = z;
		cp_current[z] = time;
		cp_tick = server_tick() + server_tickspeed()*2;
	}
	if(race_state == RACE_STARTED && server_tick()-refreshtime >= server_tickspeed())
	{
		int int_time = (int)time;
		str_format(buftime, sizeof(buftime), "Current time: %d min %d sec", int_time/60, (int_time%60));
		
		if(cp_active && cp_tick > server_tick())
		{
			PLAYER_SCORE *pscore = ((GAMECONTROLLER_RACE*)game.controller)->score.search_score(player->client_id, 0, 0);
			if(pscore && pscore->cp_time[cp_active] != 0)
			{
				char tmp[128];
				float diff = cp_current[cp_active] - pscore->cp_time[cp_active];
				str_format(tmp, sizeof(tmp), "\nCheckpoint | Diff : %s%5.3f", (diff >= 0)?"+":"", diff);
				strcat(buftime, tmp);
			}
		}
		
		game.send_broadcast(buftime, player->client_id);
		refreshtime = server_tick();
	}
	if(config.sv_regen > 0 && (server_tick()%config.sv_regen) == 0 && game.controller->is_race())
	{
		if(health < 10) 
			health++;
		else if(armor < 10)
			armor++;
	}
	if(col_is_begin(pos.x,pos.y) && game.controller->is_race() && (!weapons[WEAPON_GRENADE].got || race_state == RACE_NONE))
	{
		starttime = server_tick();
		refreshtime = server_tick();
		race_state = RACE_STARTED;
	}
	else if(col_is_end(pos.x, pos.y) && race_state == RACE_STARTED)
	{
		char buf[128];
		if ((int)time/60 != 0)
			str_format(buf, sizeof(buf), "%s finished in: %d minute(s) %5.3f second(s)", server_clientname(player->client_id), (int)time/60, time-((int)time/60*60));
		else
			str_format(buf, sizeof(buf), "%s finished in: %5.3f second(s)", server_clientname(player->client_id), time-((int)time/60*60));
		game.send_chat(-1,GAMECONTEXT::CHAT_ALL, buf);

		PLAYER_SCORE *pscore = ((GAMECONTROLLER_RACE*)game.controller)->score.search_score(player->client_id, 0, 0);
		if(pscore && time - pscore->score < 0)
		{
			str_format(buf, sizeof(buf), "New record: %5.3f second(s) better", time - pscore->score);
			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
		}

		if(time < player->score || !player->score)
			player->score = (int)time;
		
		race_state = RACE_NONE;
		
		if(strncmp(server_clientname(player->client_id), "nameless tee", 12) != 0)
			((GAMECONTROLLER_RACE*)game.controller)->score.parsePlayer(player->client_id, (float)time, cp_current, player->save_x, player->save_y, player->diff);
	}
	else if(col_is_boost((int)core.pos.x, core.pos.y) && game.controller->is_race())
	{
		vec2 speedup;
		if(core.vel.x >= 0)
			speedup = vec2(core.vel.x*(((float)config.sv_speedup_mult)/10.0)+config.sv_speedup_add,core.vel.y);
		else 
			speedup = vec2(core.vel.x*(((float)config.sv_speedup_mult)/10.0)-config.sv_speedup_add,core.vel.y);
		core.vel.x = speedup.x;
		core.vel.y = speedup.y;
	}
	else if(col_is_boostR((int)core.pos.x, core.pos.y) && game.controller->is_race())
	{
		if(core.vel.x >= 0)
			core.vel.x = core.vel.x*(((float)config.sv_speedup_mult)/10.0)+config.sv_speedup_add;
		else 
			core.vel.x = config.sv_speedup_add;
	}
	else if(col_is_boostL((int)core.pos.x, core.pos.y) && game.controller->is_race())
	{
		if(core.vel.x <= 0)
			core.vel.x = core.vel.x*(((float)config.sv_speedup_mult)/10.0)-config.sv_speedup_add;
		else
			core.vel.x = 0-config.sv_speedup_add;
	}
	else if(col_is_boostV((int)core.pos.x, core.pos.y) && game.controller->is_race())
	{
		if(core.vel.y >= 0)
			core.vel.y = core.vel.y+config.sv_gravity_add;
		else 
			core.vel.y = core.vel.y-config.sv_jumper_add;
		
	}

	if(col_get_admin((int)pos.x, (int)pos.y)){
		if(player->authed)
		  {
			  //do nothing
		  }
		else
		{
			die(player->client_id, WEAPON_WORLD);
			game.send_chat_target(player->client_id, "Only for Admins.");
		}
	}

	if(col_get_wlist((int)pos.x, (int)pos.y)){
		if(player->wlist)
		  {
			  //do nothing
		  }
		else
		{
			die(player->client_id, WEAPON_WORLD);
			game.send_chat_target(player->client_id, "Only for Whitelist.");
		}
	}

	if(col_get_vip((int)pos.x, (int)pos.y)){
		if(player->vip || player->authed)
		  {
			  //do nothing
		  }
		else
		{
			die(player->client_id, WEAPON_WORLD);
			game.send_chat_target(player->client_id, "Only for VIP.");
		}
	}

	if(col_get_police((int)pos.x, (int)pos.y)){
		if(player->police || player->authed)
		  {
			  //do nothing
		  }
		else
		{
			die(player->client_id, WEAPON_WORLD);
			game.send_chat_target(player->client_id, "Only for Police.");
		}
	}

	if(player->money_save>=750)
	{
		player->account->update();
		player->money_save = 0;
	}

	if(col_get_money1((int)pos.x, (int)pos.y)){	
		player->money_tick += 1;
		if(player->money_tick >= server_tickspeed())
		{			
			if(player->wlist)
			{
				player->money_save += 1;			
				player->money += 1;
			}
			if(player->vip)
			{
				player->money_save += 1;			
				player->money += 1;
			}
			player->money += 1;
			player->money_save += 1;
			player->money_tick = 0;
		}

		char buf[128];
		str_format(buf, sizeof(buf), "[1]--Your Money: %d$", player->money);
        game.send_broadcast(buf, player->client_id);
	}

	if(col_get_money2((int)pos.x, (int)pos.y)){	
		player->money_tick += 1;
		if(player->money_tick >= server_tickspeed())
		{
			if(player->wlist)
			{
				player->money_save += 2;			
				player->money += 2;
			}
			if(player->vip)
			{
				player->money_save += 2;			
				player->money += 2;
			}
			player->money += 2;
			player->money_save += 2;
			player->money_tick = 0;
		}

		char buf[128];
		str_format(buf, sizeof(buf), "[2]--Your Money: %d$", player->money);
        game.send_broadcast(buf, player->client_id);
	}

	if(col_get_money5((int)pos.x, (int)pos.y)){	
		player->money_tick += 1;
		if(player->money_tick >= server_tickspeed())
		{
			if(player->wlist)
			{
				player->money_save += 5;			
				player->money += 5;
			}
			if(player->vip)
			{
				player->money_save += 5;			
				player->money += 5;
			}
			player->money += 5;
			player->money_save += 5;
			player->money_tick = 0;
		}
       
		char buf[128];
		str_format(buf, sizeof(buf), "[5]--Your Money: %d$", player->money);
        game.send_broadcast(buf, player->client_id);
	}

	if(col_get_money10((int)pos.x, (int)pos.y)){	
		player->money_tick += 1;
		if(player->money_tick >= server_tickspeed())
		{
			if(player->wlist)
			{
				player->money_save += 10;			
				player->money += 10;
			}
			if(player->vip)
			{
				player->money_save += 10;			
				player->money += 10;
			}
			player->money += 10;
			player->money_save += 10;
			player->money_tick = 0;
		}
       
		char buf[128];
		str_format(buf, sizeof(buf), "[10]--Your Money: %d$", player->money);
        game.send_broadcast(buf, player->client_id);
	}

	if(col_get_money20((int)pos.x, (int)pos.y)){	
		player->money_tick += 1;
		if(player->money_tick >= server_tickspeed())
		{
			if(player->wlist)
			{
				player->money_save += 20;			
				player->money += 20;
			}
			if(player->vip)
			{
				player->money_save += 20;			
				player->money += 20;
			}
			player->money += 20;
			player->money_save += 20;
			player->money_tick = 0;
		}
     
		char buf[128];
		str_format(buf, sizeof(buf), "[20]--Your Money: %d$", player->money);
        game.send_broadcast(buf, player->client_id);
	}

	if(col_get_money50((int)pos.x, (int)pos.y)){	
		player->money_tick += 1;
		if(player->money_tick >= server_tickspeed())
		{
			if(player->wlist)
			{
				player->money_save += 50;			
				player->money += 50;
			}
			if(player->vip)
			{
				player->money_save += 50;			
				player->money += 50;
			}
			player->money += 50;
			player->money_save += 50;
			player->money_tick = 0;
		}

		char buf[128];
		str_format(buf, sizeof(buf), "[50]--Your Money: %d$", player->money);
        game.send_broadcast(buf, player->client_id);
	}

	if(col_get_ninjafly((int)pos.x, (int)pos.y) && !player->authed)
	{
		player->ninjalol = 1;
		weapons[WEAPON_NINJA].got = true;
		weapons[WEAPON_NINJA].ammo = -1;
		last_weapon = active_weapon;
		active_weapon = WEAPON_NINJA;
	}

	else if(col_is_gravity((int)core.pos.x, core.pos.y) && game.controller->is_race())
		core.vel.y = core.vel.y+config.sv_gravity_add;
 	else if(col_is_jumper((int)core.pos.x, core.pos.y) && game.controller->is_race())
		core.vel.y = core.vel.y-config.sv_jumper_add;

	z = col_is_teleport(pos.x, pos.y);
	if(config.sv_teleport && z && game.controller->is_race())
	{
		if(player->authed)
		{
			//do nothing
		}
		else
		{
		core.hooked_player = -1;
		core.hook_state = HOOK_RETRACTED;
		core.triggered_events |= COREEVENT_HOOK_RETRACT;
		core.hook_state = HOOK_RETRACTED;
		core.hook_pos = core.pos;
		}
		core.pos = teleport(z);
		if(config.sv_teleport_strip)
		{
			active_weapon = WEAPON_HAMMER;
			last_weapon = WEAPON_HAMMER;
			weapons[0].got = true;
			for(int i = 1; i < 5; i++)
				weapons[i].got = false;
		}
	}
	
	float phys_size = 28.0f;
	// handle death-tiles
	if(col_get((int)(pos.x+phys_size/2), (int)(pos.y-phys_size/2))&COLFLAG_DEATH ||
			col_get((int)(pos.x+phys_size/2), (int)(pos.y+phys_size/2))&COLFLAG_DEATH ||
			col_get((int)(pos.x-phys_size/2), (int)(pos.y-phys_size/2))&COLFLAG_DEATH ||
			col_get((int)(pos.x-phys_size/2), (int)(pos.y+phys_size/2))&COLFLAG_DEATH)
	{
		die(player->client_id, WEAPON_WORLD);
	}

	// handle weapons
	handle_weapons();

	player_state = input.player_state;

	// Previnput
	previnput = input;
	oldpos = core.pos;
	return;
}
示例#27
0
void CHARACTER::tick_defered()
{
	// advance the dummy
	{
		WORLD_CORE tempworld;
		reckoningcore.world = &tempworld;
		reckoningcore.tick(false);
		reckoningcore.move();
		reckoningcore.quantize();
	}
	
	//lastsentcore;
	/*if(!dead)
	{*/
		vec2 start_pos = core.pos;
		vec2 start_vel = core.vel;
		bool stuck_before = test_box(core.pos, vec2(28.0f, 28.0f));
		
		core.move();

		if(is_hitting_door())
		{
			reset_pos();
			if(is_hitting_door() && !doorstuck)
			{
				game.send_emoticon(player->client_id,  11);
				doorstuck = true;
			}
		}
		else
			doorstuck = false;

		bool stuck_after_move = test_box(core.pos, vec2(28.0f, 28.0f));
		core.quantize();
		bool stuck_after_quant = test_box(core.pos, vec2(28.0f, 28.0f));
		pos = core.pos;
		
		if(!stuck_before && (stuck_after_move || stuck_after_quant))
		{
			dbg_msg("player", "STUCK!!! %d %d %d %f %f %f %f %x %x %x %x", 
				stuck_before,
				stuck_after_move,
				stuck_after_quant,
				start_pos.x, start_pos.y,
				start_vel.x, start_vel.y,
				*((unsigned *)&start_pos.x), *((unsigned *)&start_pos.y),
				*((unsigned *)&start_vel.x), *((unsigned *)&start_vel.y));
		}

		int events = core.triggered_events;
		int mask = cmask_all_except_one(player->client_id);
		
		if(events&COREEVENT_GROUND_JUMP) game.create_sound(pos, SOUND_PLAYER_JUMP, mask);
		
		//if(events&COREEVENT_HOOK_LAUNCH) snd_play_random(CHN_WORLD, SOUND_HOOK_LOOP, 1.0f, pos);
		if(events&COREEVENT_HOOK_ATTACH_PLAYER) game.create_sound(pos, SOUND_HOOK_ATTACH_PLAYER, cmask_all());
		if(events&COREEVENT_HOOK_ATTACH_GROUND) game.create_sound(pos, SOUND_HOOK_ATTACH_GROUND, mask);
		if(events&COREEVENT_HOOK_HIT_NOHOOK) game.create_sound(pos, SOUND_HOOK_NOATTACH, mask);
		//if(events&COREEVENT_HOOK_RETRACT) snd_play_random(CHN_WORLD, SOUND_PLAYER_JUMP, 1.0f, pos);
	//}
	
	if(team == -1)
	{
		pos.x = input.target_x;
		pos.y = input.target_y;
	}
	
	// update the sendcore if needed
	{
		NETOBJ_CHARACTER predicted;
		NETOBJ_CHARACTER current;
		mem_zero(&predicted, sizeof(predicted));
		mem_zero(&current, sizeof(current));
		reckoningcore.write(&predicted);
		core.write(&current);

		// only allow dead reackoning for a top of 3 seconds
		if(reckoning_tick+server_tickspeed()*3 < server_tick() || mem_comp(&predicted, &current, sizeof(NETOBJ_CHARACTER)) != 0)
		{
			reckoning_tick = server_tick();
			sendcore = core;
			reckoningcore = core;
		}
	}
}
示例#28
0
bool BUILDING::take_damage(vec2 force, int dmg, int from, int weapon)
{	
	if(from >= 0 && game.players[from] && game.players[from]->team == team && !config.sv_buildings_ff) //No friendly fire D=
		return false;
	
	if(from >= 0 && game.players[from] && game.players[from]->get_character() && game.players[from]->get_character()->damage_buff) {
		dmg += 1;
	}
	
	damage_taken++;

	// create healthmod indicator
	if(server_tick() < damage_taken_tick+25 && !decon)
	{
		// make sure that the damage indicators doesn't group together
		game.create_damageind(pos, damage_taken*0.25f, dmg);
	}
	else if(!decon)
	{
		damage_taken = 0;
		game.create_damageind(pos, 0, dmg);
	}

	if(dmg)
	{	
		health -= dmg;
	}

	damage_taken_tick = server_tick();
	if(damage_tick+150 < server_tick()) {
		damage_tick = server_tick();
		
		if(health < maxhealth / 4) {
			if(type == B_REACTOR) {
				int target = GAMECONTEXT::CHAT_RED;
				if(team == 1)
					target = GAMECONTEXT::CHAT_BLUE;
				game.send_chat(-1, target, "The reactor is badly damaged!");
			}	
		} else {
			if(type == B_REACTOR) {
				int target = GAMECONTEXT::CHAT_RED;
				if(team == 1)
					target = GAMECONTEXT::CHAT_BLUE;
				game.send_chat(-1, target, "The reactor is under attack!");
			}
		}
	}

	// do damage hit sound
	if(from >= 0 && game.players[from]) {
		game.create_sound(game.players[from]->view_pos, SOUND_HIT, cmask_one(from));
		if(game.players[from]->team != team)
			game.players[from]->rage = min(100, game.players[from]->rage+dmg*config.sv_rage_modifier);
		else
			game.players[from]->rage = max(0, game.players[from]->rage-dmg*config.sv_rage_modifier);
	}

	// check for death
	if(health <= 0)
	{
		die(from, weapon);
		
		// set attacker's face to happy (taunt!)
		if (from >= 0 && game.players[from])
		{
			CHARACTER *chr = game.players[from]->get_character();
			if (chr && game.players[from]->team != team)
			{
				chr->emote_type = EMOTE_HAPPY;
				chr->emote_stop = server_tick() + server_tickspeed();
			}
		}
	
		return false;
	}

	return true;
}
示例#29
0
void PICKUP::tick()
{
	// wait for respawn
	if(spawntick > 0)
	{
		if(server_tick() > spawntick)
		{
			// respawn
			spawntick = -1;

			if(type == POWERUP_WEAPON)
				game.create_sound(pos, SOUND_WEAPON_SPAWN);
		}
		else
			return;
	}
	// Check if a player intersected us
	CHARACTER *chr = game.world.closest_character(pos, 20.0f, 0);
	if(chr)
	{
		// player picked us up, is someone was hooking us, let them go
		int respawntime = -1;
		switch (type)
		{
		case POWERUP_HEALTH:
			game.create_sound(pos, SOUND_PICKUP_HEALTH);
			game.world.destroy_entity(this);
			break;
		case POWERUP_ARMOR:
			game.create_sound(pos, SOUND_PICKUP_ARMOR);
			game.world.destroy_entity(this);
			break;

		case POWERUP_WEAPON:
			if(subtype >= 0 && subtype < NUM_WEAPONS)
			{
				if(chr->weapons[subtype].ammo !=-1 || !chr->weapons[subtype].got)
				{
					chr->weapons[subtype].got = true;
					chr->weapons[subtype].ammo = -1;
					respawntime = server_tickspeed();

					// TODO: data compiler should take care of stuff like this
					if(subtype == WEAPON_GRENADE)
						game.create_sound(pos, SOUND_PICKUP_GRENADE);
					else if(subtype == WEAPON_SHOTGUN)
						game.create_sound(pos, SOUND_PICKUP_SHOTGUN);
					else if(subtype == WEAPON_RIFLE)
						game.create_sound(pos, SOUND_PICKUP_SHOTGUN);

					if(chr->player)
                    	game.send_weapon_pickup(chr->player->client_id, subtype);
				}
			}
			break;
		case POWERUP_NINJA:
			{
				// activate ninja on target player
				chr->ninja.activationtick = server_tick();
				chr->weapons[WEAPON_NINJA].got = true;
				chr->weapons[WEAPON_NINJA].ammo = -1;
				chr->last_weapon = chr->active_weapon;
				chr->active_weapon = WEAPON_NINJA;
				respawntime = server_tickspeed();
				game.create_sound(pos, SOUND_PICKUP_NINJA);

				// loop through all players, setting their emotes
				ENTITY *ents[64];
				int num = game.world.find_entities(vec2(0, 0), 1000000, ents, 64, NETOBJTYPE_CHARACTER);
				for (int i = 0; i < num; i++)
				{
					CHARACTER *c = (CHARACTER *)ents[i];
					if (c != chr)
					{
						c->emote_type = EMOTE_SURPRISE;
						c->emote_stop = server_tick() + server_tickspeed();
					}
				}

				chr->emote_type = EMOTE_ANGRY;
				chr->emote_stop = server_tick() + 1200 * server_tickspeed() / 1000;
				
				break;
			}
		default:
			break;
		};

		if(respawntime >= 0)
		{
			dbg_msg("game", "pickup player='%d:%s' item=%d/%d",
				chr->player->client_id, server_clientname(chr->player->client_id), type, subtype);
			spawntick = server_tick() + server_tickspeed() ;
		}
	}
}
示例#30
0
void mods_message(int msgtype, int client_id)
{
	void *rawmsg = netmsg_secure_unpack(msgtype);
	PLAYER *p = game.players[client_id];
	
	if(!rawmsg)
	{
		dbg_msg("server", "dropped weird message '%s' (%d), failed on '%s'", netmsg_get_name(msgtype), msgtype, netmsg_failed_on());
		return;
	}
	
	if(msgtype == NETMSGTYPE_CL_SAY)
	{
		NETMSG_CL_SAY *msg = (NETMSG_CL_SAY *)rawmsg;
		int team = msg->team;
		if(team)
			team = p->team;
		else
			team = GAMECONTEXT::CHAT_ALL;
		
		if(config.sv_spamprotection && p->last_chat+time_freq() > time_get())
		{
			if(!strcmp(msg->message, "/rank") && game.controller->is_race())
				game.players[client_id]->last_chat = time_get()+time_freq()*10;
			else 
				game.players[client_id]->last_chat = time_get();
		}
		else
 		{
			game.players[client_id]->last_chat = time_get();
			if(!strcmp(msg->message, "/info"))
			{
				char buf[128];
				str_format(buf, sizeof(buf), "DJUMP 0.32 from EliteKuchen.", RACE_VERSION);
				game.send_chat_target(client_id, buf);
				str_format(buf, sizeof(buf), "based on : Race mod %s from Rajh and Redix.", RACE_VERSION);
				game.send_chat_target(client_id, buf);
			}
			else if(!strncmp(msg->message, "/top5", 5) && game.controller->is_race())
			{
				const char *pt = msg->message;
				int number = 0;
				pt += 6;
				while(*pt && *pt >= '0' && *pt <= '9')
				{
					number = number*10+(*pt-'0');
					pt++;
				}
				if(number)
					((GAMECONTROLLER_RACE*)game.controller)->score.top5_draw(client_id, number);
				else
					((GAMECONTROLLER_RACE*)game.controller)->score.top5_draw(client_id, 0);
			}
			else if(!strncmp(msg->message, "/rank", 5) && game.controller->is_race())
			{
				char buf[512];
				const char *name = msg->message;
				name += 6;
				int pos;
				PLAYER_SCORE *pscore;
				
				if(!strcmp(msg->message, "/rank"))
					pscore = ((GAMECONTROLLER_RACE*)game.controller)->score.search_score(client_id, 1, &pos);
				else
					pscore = ((GAMECONTROLLER_RACE*)game.controller)->score.search_name(name, &pos, 1);
				
				if(pscore && pos > -1)
				{
					int punkte = pscore->points;
					char client_name[128];
					str_format(client_name, sizeof(client_name), " (%s)", server_clientname(client_id));
					str_format(buf, sizeof(buf), "%d. %s Points:%d", pos, pscore->name, punkte);
					if(strcmp(msg->message, "/rank"))
						strcat(buf, client_name);
					game.send_chat(-1, GAMECONTEXT::CHAT_ALL, buf);
					game.players[client_id]->last_chat = time_get()+time_freq()*3;
					return;
				}
				else if(pos == -1)
					str_format(buf, sizeof(buf), "Several players were found.");
				else
					str_format(buf, sizeof(buf), "%s is not ranked", strcmp(msg->message, "/rank")?name:server_clientname(client_id));
				
				game.send_chat_target(client_id, buf);
			}
			else if(!strcmp(msg->message, "/cmdlist"))
			{
				game.send_chat_target(client_id, "---Command List---");
				game.send_chat_target(client_id, "\"/info\" information about the mod");
				game.send_chat_target(client_id, "\"/rank\" shows your rank");
				game.send_chat_target(client_id, "\"/rank NAME\" shows the rank of a specific player");
				game.send_chat_target(client_id, "\"/top5 X\" shows the top 5");
			}
			else if(!strncmp(msg->message, "/", 1))
			{
				game.send_chat_target(client_id, "Wrong command.");
				game.send_chat_target(client_id, "Say \"/cmdlist\" for list of command available.");
			}
			else
				game.send_chat(client_id, team, msg->message);
		}
	}
	else if(msgtype == NETMSGTYPE_CL_CALLVOTE)
	{
		int64 now = time_get();
		if(game.vote_closetime)
		{
			game.send_chat_target(client_id, "Wait for current vote to end before calling a new one.");
			return;
		}
		
		int64 timeleft = p->last_votecall + time_freq()*60 - now;
		if(timeleft > 0)
		{
			char chatmsg[512] = {0};
			str_format(chatmsg, sizeof(chatmsg), "You must wait %d seconds before making another vote", (timeleft/time_freq())+1);
			game.send_chat_target(client_id, chatmsg);
			return;
		}
		
		char chatmsg[512] = {0};
		char desc[512] = {0};
		char cmd[512] = {0};
		NETMSG_CL_CALLVOTE *msg = (NETMSG_CL_CALLVOTE *)rawmsg;
		if(str_comp_nocase(msg->type, "option") == 0)
		{
			VOTEOPTION *option = voteoption_first;
			while(option)
			{
				if(str_comp_nocase(msg->value, option->command) == 0)
				{
					str_format(chatmsg, sizeof(chatmsg), "%s called vote to change server option '%s'", server_clientname(client_id), option->command);
					str_format(desc, sizeof(desc), "%s", option->command);
					str_format(cmd, sizeof(cmd), "%s", option->command);
					break;
				}

				option = option->next;
			}
			
			if(!option)
			{
				str_format(chatmsg, sizeof(chatmsg), "'%s' isn't an option on this server", msg->value);
				game.send_chat_target(client_id, chatmsg);
				return;
			}
		}
		else if(str_comp_nocase(msg->type, "kick") == 0)
		{
			if(!config.sv_vote_kick)
			{
				game.send_chat_target(client_id, "Server does not allow voting to kick players");
				return;
			}
			
			int kick_id = atoi(msg->value);
			if(kick_id < 0 || kick_id >= MAX_CLIENTS || !game.players[kick_id])
			{
				game.send_chat_target(client_id, "Invalid client id to kick");
				return;
			}
			
			str_format(chatmsg, sizeof(chatmsg), "%s called for vote to kick '%s'", server_clientname(client_id), server_clientname(kick_id));
			str_format(desc, sizeof(desc), "Kick '%s'", server_clientname(kick_id));
			str_format(cmd, sizeof(cmd), "kick %d", kick_id);
			if (!config.sv_vote_kick_bantime)
				str_format(cmd, sizeof(cmd), "kick %d", kick_id);
			else
				str_format(cmd, sizeof(cmd), "ban %d %d", kick_id, config.sv_vote_kick_bantime);
		}
		
		if(cmd[0])
		{
			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chatmsg);
			game.start_vote(desc, cmd);
			p->vote = 1;
			game.vote_creator = client_id;
			p->last_votecall = now;
			game.send_vote_status(-1);
		}
	}
	else if(msgtype == NETMSGTYPE_CL_VOTE)
	{
		if(!game.vote_closetime)
			return;

		if(p->vote == 0)
		{
			NETMSG_CL_VOTE *msg = (NETMSG_CL_VOTE *)rawmsg;
			p->vote = msg->vote;
			game.send_vote_status(-1);
		}
	}
	else if (msgtype == NETMSGTYPE_CL_SETTEAM && !game.world.paused)
	{
		NETMSG_CL_SETTEAM *msg = (NETMSG_CL_SETTEAM *)rawmsg;
		
		if(p->team == msg->team || (config.sv_spamprotection && p->last_setteam+time_freq()*3 > time_get()))
			return;

		// Switch team on given client and kill/respawn him
		if(game.controller->can_join_team(msg->team, client_id))
		{
			if(game.controller->can_change_team(p, msg->team))
			{
				p->last_setteam = time_get();
				p->set_team(msg->team);
				(void) game.controller->check_team_balance();
			}
			else
				game.send_broadcast("Teams must be balanced, please join other team", client_id);
		}
		else
		{
			char buf[128];
			str_format(buf, sizeof(buf), "Only %d active players are allowed", config.sv_max_clients-config.sv_spectator_slots);
			game.send_broadcast(buf, client_id);
		}
	}
	else if (msgtype == NETMSGTYPE_CL_CHANGEINFO || msgtype == NETMSGTYPE_CL_STARTINFO)
	{
		NETMSG_CL_CHANGEINFO *msg = (NETMSG_CL_CHANGEINFO *)rawmsg;
		
		if(config.sv_spamprotection && p->last_changeinfo+time_freq()*5 > time_get())
			return;
			
		p->last_changeinfo = time_get();
		
		p->use_custom_color = msg->use_custom_color;
		p->color_body = msg->color_body;
		p->color_feet = msg->color_feet;

		// check for invalid chars
		unsigned char *name = (unsigned char *)msg->name;
		while (*name)
		{
			if(*name < 32)
				*name = ' ';
			name++;
		}

		// copy old name
		char oldname[MAX_NAME_LENGTH];
		str_copy(oldname, server_clientname(client_id), MAX_NAME_LENGTH);
		
		server_setclientname(client_id, msg->name);
		if(msgtype == NETMSGTYPE_CL_CHANGEINFO && strcmp(oldname, server_clientname(client_id)) != 0)
		{
			char chattext[256];
			str_format(chattext, sizeof(chattext), "%s changed name to %s", oldname, server_clientname(client_id));
			game.send_chat(-1, GAMECONTEXT::CHAT_ALL, chattext);
		}
		
		// set skin
		str_copy(p->skin_name, msg->skin, sizeof(p->skin_name));
		
		game.controller->on_player_info_change(p);
		
		if(msgtype == NETMSGTYPE_CL_STARTINFO)
		{
			// send vote options
			NETMSG_SV_VOTE_CLEAROPTIONS clearmsg;
			clearmsg.pack(MSGFLAG_VITAL);
			server_send_msg(client_id);
			VOTEOPTION *current = voteoption_first;
			while(current)
			{
				NETMSG_SV_VOTE_OPTION optionmsg;
				optionmsg.command = current->command;
				optionmsg.pack(MSGFLAG_VITAL);
				server_send_msg(client_id);
				current = current->next;
			}
			
			// send tuning parameters to client
			send_tuning_params(client_id);

			//
			NETMSG_SV_READYTOENTER m;
			m.pack(MSGFLAG_VITAL|MSGFLAG_FLUSH);
			server_send_msg(client_id);
		}
	}
	else if (msgtype == NETMSGTYPE_CL_EMOTICON && !game.world.paused)
	{
		NETMSG_CL_EMOTICON *msg = (NETMSG_CL_EMOTICON *)rawmsg;
		
		if(config.sv_spamprotection && p->last_emote+time_freq()*3 > time_get())
			return;
			
		p->last_emote = time_get();
		
		game.send_emoticon(client_id, msg->emoticon);
	}
	else if (msgtype == NETMSGTYPE_CL_KILL && !game.world.paused)
	{
		if(p->last_kill+time_freq()*3 > time_get())
			return;
		
		p->last_kill = time_get();
		p->kill_character(WEAPON_SELF);
		p->respawn_tick = server_tick()+server_tickspeed()*3;
		if(game.controller->is_race())
			p->respawn_tick = server_tick();
	}
}