2008-08-14 18:25:44 +00:00
|
|
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
|
|
|
#include <engine/e_server_interface.h>
|
|
|
|
#include <game/generated/g_protocol.hpp>
|
2008-08-14 18:42:47 +00:00
|
|
|
#include <game/server/gamecontext.hpp>
|
2008-08-14 18:25:44 +00:00
|
|
|
#include "laser.hpp"
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////
|
|
|
|
// laser
|
|
|
|
//////////////////////////////////////////////////
|
2008-10-20 23:00:46 +00:00
|
|
|
LASER::LASER(vec2 pos, vec2 direction, float start_energy, int owner)
|
2008-08-14 18:25:44 +00:00
|
|
|
: ENTITY(NETOBJTYPE_LASER)
|
|
|
|
{
|
|
|
|
this->pos = pos;
|
|
|
|
this->owner = owner;
|
|
|
|
energy = start_energy;
|
|
|
|
dir = direction;
|
|
|
|
bounces = 0;
|
|
|
|
do_bounce();
|
|
|
|
|
|
|
|
game.world.insert_entity(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool LASER::hit_character(vec2 from, vec2 to)
|
|
|
|
{
|
|
|
|
vec2 at;
|
2008-10-20 23:00:46 +00:00
|
|
|
CHARACTER *owner_char = game.get_player_char(owner);
|
|
|
|
CHARACTER *hit = game.world.intersect_character(pos, to, 0.0f, at, owner_char);
|
2008-08-14 18:25:44 +00:00
|
|
|
if(!hit)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
this->from = from;
|
|
|
|
pos = at;
|
|
|
|
energy = -1;
|
2008-10-20 23:00:46 +00:00
|
|
|
hit->take_damage(vec2(0,0), tuning.laser_damage, owner, WEAPON_RIFLE);
|
2008-08-14 18:25:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LASER::do_bounce()
|
|
|
|
{
|
|
|
|
eval_tick = server_tick();
|
|
|
|
|
|
|
|
if(energy < 0)
|
|
|
|
{
|
|
|
|
//dbg_msg("laser", "%d removed", server_tick());
|
|
|
|
game.world.destroy_entity(this);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
vec2 to = pos + dir*energy;
|
2009-01-11 10:26:17 +00:00
|
|
|
vec2 org_to = to;
|
2008-08-14 18:25:44 +00:00
|
|
|
|
2009-01-11 10:26:17 +00:00
|
|
|
if(col_intersect_line(pos, to, 0x0, &to))
|
2008-08-14 18:25:44 +00:00
|
|
|
{
|
|
|
|
if(!hit_character(pos, to))
|
|
|
|
{
|
|
|
|
// intersected
|
|
|
|
from = pos;
|
2009-01-11 10:26:17 +00:00
|
|
|
pos = to;
|
|
|
|
|
2008-08-14 18:25:44 +00:00
|
|
|
vec2 temp_pos = pos;
|
|
|
|
vec2 temp_dir = dir*4.0f;
|
|
|
|
|
|
|
|
move_point(&temp_pos, &temp_dir, 1.0f, 0);
|
|
|
|
pos = temp_pos;
|
|
|
|
dir = normalize(temp_dir);
|
|
|
|
|
|
|
|
energy -= distance(from, pos) + tuning.laser_bounce_cost;
|
|
|
|
bounces++;
|
|
|
|
|
|
|
|
if(bounces > tuning.laser_bounce_num)
|
|
|
|
energy = -1;
|
|
|
|
|
|
|
|
game.create_sound(pos, SOUND_RIFLE_BOUNCE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!hit_character(pos, to))
|
|
|
|
{
|
|
|
|
from = pos;
|
|
|
|
pos = to;
|
|
|
|
energy = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//dbg_msg("laser", "%d done %f %f %f %f", server_tick(), from.x, from.y, pos.x, pos.y);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LASER::reset()
|
|
|
|
{
|
|
|
|
game.world.destroy_entity(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
void LASER::tick()
|
|
|
|
{
|
|
|
|
if(server_tick() > eval_tick+(server_tickspeed()*tuning.laser_bounce_delay)/1000.0f)
|
|
|
|
{
|
|
|
|
do_bounce();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void LASER::snap(int snapping_client)
|
|
|
|
{
|
2008-10-06 18:05:01 +00:00
|
|
|
if(networkclipped(snapping_client))
|
2008-08-14 18:25:44 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
NETOBJ_LASER *obj = (NETOBJ_LASER *)snap_new_item(NETOBJTYPE_LASER, id, sizeof(NETOBJ_LASER));
|
|
|
|
obj->x = (int)pos.x;
|
|
|
|
obj->y = (int)pos.y;
|
|
|
|
obj->from_x = (int)from.x;
|
|
|
|
obj->from_y = (int)from.y;
|
|
|
|
obj->start_tick = eval_tick;
|
|
|
|
}
|