示例#1
0
// TODO: rewrite this smarter!
int col_intersect_line(vec2 pos0, vec2 pos1, vec2 *out_collision, vec2 *out_before_collision)
{
	float d = distance(pos0, pos1);
	vec2 last = pos0;
	
	for(float f = 0; f < d; f++)
	{
		float a = f/d;
		vec2 pos = mix(pos0, pos1, a);
		if(col_is_solid(round(pos.x), round(pos.y)))
		{
			if(out_collision)
				*out_collision = pos;
			if(out_before_collision)
				*out_before_collision = last;
			return col_get(round(pos.x), round(pos.y));
		}
		last = pos;
	}
	if(out_collision)
		*out_collision = pos1;
	if(out_before_collision)
		*out_before_collision = pos1;
	return 0;
}
示例#2
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);
				}
			}
		}
	}
}
示例#3
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;
}
示例#4
0
int col_is_solid(int x, int y)
{
	return col_get(x,y)&COLFLAG_SOLID;
}
示例#5
0
void CRATE::tick()
{
	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();
		return;
	}
	
	grounded = is_grounded();
	
	bool was_grounded = grounded;
	
	if(!grounded) {
		//die();
		int k = 3;
		while(!grounded && k-- > 0) {
			pos.y += 1;
			grounded = is_grounded();
		}
	}
	
	if(grounded && !was_grounded)
		game.create_sound(pos, SOUND_CRATE_IMPACT);
	
	was_grounded = grounded;
	
	if(!alive)
		return;

	CHARACTER *c = get_nearest(28);
	GAMECONTROLLER_NODES* gc = (GAMECONTROLLER_NODES*)game.controller;
	
	if(c) {
		dbg_msg("nodes", "activated a crate of type %d", type);
		char buf[128];
		str_format(buf, sizeof(buf), "%s", BUF_NAMES[type]);
		game.send_broadcast(buf, c->player->client_id);
		
		switch(type) {
			//c->crate = type;
			//c->crate_tick = server_tick();
			
			case CRATE_HEALTH: {
				c->health = 10;
				game.create_sound(pos, SOUND_PICKUP_HEALTH);
			} break;
			
			case CRATE_ARMOR: {
				c->armor = 10;
				game.create_sound(pos, SOUND_PICKUP_ARMOR);
			} break;
			
			case CRATE_CONSTRUCTION: {
				
				
				c->crate = CRATE_CONSTRUCTION;
				c->crate_tick = server_tick();
				c->core.frozen = false;
				/*if(gc->buildings_buffpoints[1-c->team] > 0) {
					gc->buildings_points[1-c->team] -= gc->buildings_buffpoints[1-c->team];
					gc->buildings_buffpoints[1-c->team] = 0;
				}
				
				if(gc->buildings_buffpoints[c->team] == 0) {
					gc->buildings_points[c->team] += config.sv_buffpoints;
					gc->buildings_buffpoints[c->team] = config.sv_buffpoints;
				}*/
			} break;
			
			case CRATE_BASEBALL: {
				c->crate = CRATE_BASEBALL;
				c->crate_tick = server_tick();
				c->core.frozen = false;
				c->active_weapon = WEAPON_HAMMER;
			} break;
			
			case CRATE_FREEZE: {
				c->crate = 0; //undo crate thingy, only enemies will get this "buff"
				c->core.frozen = false;
				
				CHARACTER *close_characters[MAX_CLIENTS];
				int num = game.world.find_entities(c->pos, config.sv_freeze_radius, (ENTITY**)close_characters, MAX_CLIENTS, NETOBJTYPE_CHARACTER);
				
				for(int i = 0; i < num; i++) {
					if(close_characters[i]->player->team != c->player->team) {
						close_characters[i]->core.frozen = true;
						close_characters[i]->crate = CRATE_FREEZE;
						close_characters[i]->crate_tick = server_tick();
						close_characters[i]->crate_misc = (int)(frandom() *2);
						game.create_sound(close_characters[i]->pos, SOUND_CRATE_ICE);
					}
				}
				game.create_sound(pos, SOUND_CRATE_ICE);
				game.create_effect(pos, 3);
			} break;
			
			case CRATE_EMP: {
				gc->emp = true;
				gc->emp_tick = server_tick();
				game.create_effect(pos, 2);
				game.create_sound_global(SOUND_CRATE_EMP, -1);
			} break;
			
			case CRATE_DUCK: {
				c->core.frozen = true;
				//c->ill = true;
				c->crate = CRATE_FREEZE;
				c->crate_tick = server_tick();
				c->crate_misc = (int)(frandom() *2);
				c->core.hook_state = -1;
				c->core.hooked_player = -1;
				game.create_sound(pos, SOUND_CRATE_ICE);
			} break;
			
			case CRATE_BOOM: {
				game.create_explosion(pos, -4, WEAPON_WORLD, false);
				game.create_explosion(pos, -4, WEAPON_WORLD, false);
				game.create_explosion(pos, -4, WEAPON_WORLD, false);
				game.create_sound(pos, SOUND_GRENADE_EXPLODE);
			}
			
			/*case CRATE_EXPLOSION: {
				game.create_explosion(pos, -1, WEAPON_WORLD, false);
				game.create_explosion(pos, -1, WEAPON_WORLD, false);
				game.create_explosion(pos, -1, WEAPON_WORLD, false);
			} break;
			case CRATE_ILLNESS: {
				c->ill = true;
				c->infecter = -1;
			} break;
			case CRATE_NOGRAV: {
				c->core.nograv = true;
			} break;
			case CRATE_FREEZE: {
				c->core.frozen = true;
			} break;
			case CRATE_STRIP: {
				c->weapons[WEAPON_GUN].got = 0;
				c->weapons[WEAPON_GRENADE].got = 0;
				c->weapons[WEAPON_RIFLE].got = 0;
			}
			
			case CRATE_HEALTH: {
				c->health = 10;
			} break;
			case CRATE_ARMOR: {
				c->armor = 10;
			}
			case CRATE_AMMO: {
				c->weapons[WEAPON_GUN].ammo = 10;
				c->weapons[WEAPON_GRENADE].ammo = 10;
				c->weapons[WEAPON_RIFLE].ammo = 10;
			}
			case CRATE_WEAPONS: {
				c->weapons[WEAPON_GUN].got = 1;
				c->weapons[WEAPON_GRENADE].got = 1;
				c->weapons[WEAPON_RIFLE].got = 1;
			}*/
			
		}
		
		die();
		return;
	}

	if(server_tick() > creation_tick + 20*50) {
		game.create_explosion(pos, -1, WEAPON_WORLD, true);
		game.create_sound(pos, SOUND_GRENADE_EXPLODE);
		die();
	}
	
	return;
}