mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-20 09:34:19 +00:00
moved alot of stuff to their own cpp/hpp files
This commit is contained in:
parent
817f431377
commit
a420eb543f
|
@ -1,8 +1,11 @@
|
|||
#include <new>
|
||||
#include <engine/e_server_interface.h>
|
||||
#include <engine/e_config.h>
|
||||
#include "gs_common.hpp"
|
||||
#include <game/server/gs_common.hpp>
|
||||
|
||||
#include "character.hpp"
|
||||
#include "laser.hpp"
|
||||
#include "projectile.hpp"
|
||||
|
||||
struct INPUT_COUNT
|
||||
{
|
122
src/game/server/entities/character.hpp
Normal file
122
src/game/server/entities/character.hpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef GAME_SERVER_ENTITY_CHARACTER_H
|
||||
#define GAME_SERVER_ENTITY_CHARACTER_H
|
||||
|
||||
#include <game/server/entity.hpp>
|
||||
#include <game/generated/gs_data.hpp>
|
||||
#include <game/generated/g_protocol.hpp>
|
||||
|
||||
#include <game/g_game.hpp>
|
||||
|
||||
class CHARACTER : public ENTITY
|
||||
{
|
||||
public:
|
||||
// player controlling this character
|
||||
class PLAYER *player;
|
||||
|
||||
bool alive;
|
||||
|
||||
// weapon info
|
||||
ENTITY *hitobjects[10];
|
||||
int numobjectshit;
|
||||
struct WEAPONSTAT
|
||||
{
|
||||
int ammoregenstart;
|
||||
int ammo;
|
||||
int ammocost;
|
||||
bool got;
|
||||
} weapons[NUM_WEAPONS];
|
||||
|
||||
int active_weapon;
|
||||
int last_weapon;
|
||||
int queued_weapon;
|
||||
|
||||
int reload_timer;
|
||||
int attack_tick;
|
||||
|
||||
int damage_taken;
|
||||
|
||||
int emote_type;
|
||||
int emote_stop;
|
||||
|
||||
// TODO: clean this up
|
||||
char skin_name[64];
|
||||
int use_custom_color;
|
||||
int color_body;
|
||||
int color_feet;
|
||||
|
||||
int last_action; // last tick that the player took any action ie some input
|
||||
|
||||
// these are non-heldback inputs
|
||||
NETOBJ_PLAYER_INPUT latest_previnput;
|
||||
NETOBJ_PLAYER_INPUT latest_input;
|
||||
|
||||
// input
|
||||
NETOBJ_PLAYER_INPUT previnput;
|
||||
NETOBJ_PLAYER_INPUT input;
|
||||
int num_inputs;
|
||||
int jumped;
|
||||
|
||||
int damage_taken_tick;
|
||||
|
||||
int health;
|
||||
int armor;
|
||||
|
||||
// ninja
|
||||
struct
|
||||
{
|
||||
vec2 activationdir;
|
||||
int activationtick;
|
||||
int currentcooldown;
|
||||
int currentmovetime;
|
||||
} ninja;
|
||||
|
||||
//
|
||||
//int score;
|
||||
int team;
|
||||
int player_state; // if the client is chatting, accessing a menu or so
|
||||
|
||||
// the player core for the physics
|
||||
CHARACTER_CORE core;
|
||||
|
||||
//
|
||||
CHARACTER();
|
||||
|
||||
virtual void reset();
|
||||
virtual void destroy();
|
||||
|
||||
bool is_grounded();
|
||||
|
||||
void set_weapon(int w);
|
||||
|
||||
void handle_weaponswitch();
|
||||
void do_weaponswitch();
|
||||
|
||||
int handle_weapons();
|
||||
int handle_ninja();
|
||||
|
||||
void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void fire_weapon();
|
||||
|
||||
void die(int killer, int weapon);
|
||||
|
||||
bool take_damage(vec2 force, int dmg, int from, int weapon);
|
||||
|
||||
|
||||
bool spawn(PLAYER *player, vec2 pos, int team);
|
||||
//bool init_tryspawn(int team);
|
||||
bool remove();
|
||||
|
||||
static const int phys_size = 28;
|
||||
|
||||
virtual void tick();
|
||||
virtual void tick_defered();
|
||||
virtual void snap(int snaping_client);
|
||||
|
||||
bool increase_health(int amount);
|
||||
bool increase_armor(int amount);
|
||||
};
|
||||
|
||||
#endif
|
112
src/game/server/entities/laser.cpp
Normal file
112
src/game/server/entities/laser.cpp
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/e_server_interface.h>
|
||||
#include <game/generated/g_protocol.hpp>
|
||||
#include <game/server/gs_common.hpp>
|
||||
#include "laser.hpp"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// laser
|
||||
//////////////////////////////////////////////////
|
||||
LASER::LASER(vec2 pos, vec2 direction, float start_energy, CHARACTER *owner)
|
||||
: 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;
|
||||
CHARACTER *hit = game.world.intersect_character(pos, to, 0.0f, at, owner);
|
||||
if(!hit)
|
||||
return false;
|
||||
|
||||
this->from = from;
|
||||
pos = at;
|
||||
energy = -1;
|
||||
hit->take_damage(vec2(0,0), tuning.laser_damage, owner->player->client_id, WEAPON_RIFLE);
|
||||
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;
|
||||
|
||||
if(col_intersect_line(pos, to, &to))
|
||||
{
|
||||
if(!hit_character(pos, to))
|
||||
{
|
||||
// intersected
|
||||
from = pos;
|
||||
pos = to - dir*2;
|
||||
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)
|
||||
{
|
||||
if(distance(game.players[snapping_client].view_pos, pos) > 1000.0f)
|
||||
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;
|
||||
}
|
31
src/game/server/entities/laser.hpp
Normal file
31
src/game/server/entities/laser.hpp
Normal file
|
@ -0,0 +1,31 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef GAME_SERVER_ENTITY_LASER_H
|
||||
#define GAME_SERVER_ENTITY_LASER_H
|
||||
|
||||
#include <game/server/entity.hpp>
|
||||
|
||||
class CHARACTER;
|
||||
|
||||
class LASER : public ENTITY
|
||||
{
|
||||
vec2 from;
|
||||
vec2 dir;
|
||||
float energy;
|
||||
int bounces;
|
||||
int eval_tick;
|
||||
CHARACTER *owner;
|
||||
|
||||
bool hit_character(vec2 from, vec2 to);
|
||||
void do_bounce();
|
||||
|
||||
public:
|
||||
|
||||
LASER(vec2 pos, vec2 direction, float start_energy, CHARACTER *owner);
|
||||
|
||||
virtual void reset();
|
||||
virtual void tick();
|
||||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,8 +1,10 @@
|
|||
#include <engine/e_server_interface.h>
|
||||
#include "gs_common.hpp"
|
||||
#include <game/generated/g_protocol.hpp>
|
||||
#include <game/server/gs_common.hpp>
|
||||
#include "pickup.hpp"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// powerup
|
||||
// pickup
|
||||
//////////////////////////////////////////////////
|
||||
PICKUP::PICKUP(int _type, int _subtype)
|
||||
: ENTITY(NETOBJTYPE_PICKUP)
|
24
src/game/server/entities/pickup.hpp
Normal file
24
src/game/server/entities/pickup.hpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef GAME_SERVER_ENTITY_PICKUP_H
|
||||
#define GAME_SERVER_ENTITY_PICKUP_H
|
||||
|
||||
#include <game/server/entity.hpp>
|
||||
|
||||
// TODO: move to seperate file
|
||||
class PICKUP : public ENTITY
|
||||
{
|
||||
public:
|
||||
static const int phys_size = 14;
|
||||
|
||||
int type;
|
||||
int subtype; // weapon type for instance?
|
||||
int spawntick;
|
||||
PICKUP(int _type, int _subtype = 0);
|
||||
|
||||
virtual void reset();
|
||||
virtual void tick();
|
||||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
#endif
|
108
src/game/server/entities/projectile.cpp
Normal file
108
src/game/server/entities/projectile.cpp
Normal file
|
@ -0,0 +1,108 @@
|
|||
#include <engine/e_server_interface.h>
|
||||
#include <game/generated/g_protocol.hpp>
|
||||
#include <game/server/gs_common.hpp>
|
||||
#include "projectile.hpp"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// projectile
|
||||
//////////////////////////////////////////////////
|
||||
PROJECTILE::PROJECTILE(int type, int owner, vec2 pos, vec2 dir, int span, ENTITY* powner,
|
||||
int damage, int flags, float force, int sound_impact, int weapon)
|
||||
: ENTITY(NETOBJTYPE_PROJECTILE)
|
||||
{
|
||||
this->type = type;
|
||||
this->pos = pos;
|
||||
this->direction = dir;
|
||||
this->lifespan = span;
|
||||
this->owner = owner;
|
||||
this->powner = powner;
|
||||
this->flags = flags;
|
||||
this->force = force;
|
||||
this->damage = damage;
|
||||
this->sound_impact = sound_impact;
|
||||
this->weapon = weapon;
|
||||
this->bounce = 0;
|
||||
this->start_tick = server_tick();
|
||||
game.world.insert_entity(this);
|
||||
}
|
||||
|
||||
void PROJECTILE::reset()
|
||||
{
|
||||
game.world.destroy_entity(this);
|
||||
}
|
||||
|
||||
vec2 PROJECTILE::get_pos(float time)
|
||||
{
|
||||
float curvature = 0;
|
||||
float speed = 0;
|
||||
if(type == WEAPON_GRENADE)
|
||||
{
|
||||
curvature = tuning.grenade_curvature;
|
||||
speed = tuning.grenade_speed;
|
||||
}
|
||||
else if(type == WEAPON_SHOTGUN)
|
||||
{
|
||||
curvature = tuning.shotgun_curvature;
|
||||
speed = tuning.shotgun_speed;
|
||||
}
|
||||
else if(type == WEAPON_GUN)
|
||||
{
|
||||
curvature = tuning.gun_curvature;
|
||||
speed = tuning.gun_speed;
|
||||
}
|
||||
|
||||
return calc_pos(pos, direction, curvature, speed, time);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
lifespan--;
|
||||
|
||||
int collide = col_intersect_line(prevpos, curpos, &curpos);
|
||||
//int collide = col_check_point((int)curpos.x, (int)curpos.y);
|
||||
|
||||
CHARACTER *targetchr = game.world.intersect_character(prevpos, curpos, 6.0f, curpos, powner);
|
||||
if(targetchr || collide || lifespan < 0)
|
||||
{
|
||||
if(lifespan >= 0 || weapon == WEAPON_GRENADE)
|
||||
game.create_sound(curpos, sound_impact);
|
||||
|
||||
if(flags & PROJECTILE_FLAGS_EXPLODE)
|
||||
game.create_explosion(curpos, owner, weapon, false);
|
||||
else if(targetchr)
|
||||
{
|
||||
targetchr->take_damage(direction * max(0.001f, force), damage, owner, weapon);
|
||||
}
|
||||
|
||||
game.world.destroy_entity(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PROJECTILE::fill_info(NETOBJ_PROJECTILE *proj)
|
||||
{
|
||||
proj->x = (int)pos.x;
|
||||
proj->y = (int)pos.y;
|
||||
proj->vx = (int)(direction.x*100.0f);
|
||||
proj->vy = (int)(direction.y*100.0f);
|
||||
proj->start_tick = start_tick;
|
||||
proj->type = type;
|
||||
}
|
||||
|
||||
void PROJECTILE::snap(int snapping_client)
|
||||
{
|
||||
float ct = (server_tick()-start_tick)/(float)server_tickspeed();
|
||||
|
||||
if(distance(game.players[snapping_client].view_pos, get_pos(ct)) > 1000.0f)
|
||||
return;
|
||||
|
||||
NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
|
||||
fill_info(proj);
|
||||
}
|
38
src/game/server/entities/projectile.hpp
Normal file
38
src/game/server/entities/projectile.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
#ifndef GAME_SERVER_ENTITY_PROJECTILE_H
|
||||
#define GAME_SERVER_ENTITY_PROJECTILE_H
|
||||
|
||||
class PROJECTILE : public ENTITY
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PROJECTILE_FLAGS_EXPLODE = 1 << 0,
|
||||
};
|
||||
|
||||
vec2 direction;
|
||||
ENTITY *powner; // this is nasty, could be removed when client quits
|
||||
int lifespan;
|
||||
int owner;
|
||||
int type;
|
||||
int flags;
|
||||
int damage;
|
||||
int sound_impact;
|
||||
int weapon;
|
||||
int bounce;
|
||||
float force;
|
||||
int start_tick;
|
||||
|
||||
PROJECTILE(int type, int owner, vec2 pos, vec2 vel, int span, ENTITY* powner,
|
||||
int damage, int flags, float force, int sound_impact, int weapon);
|
||||
|
||||
vec2 get_pos(float time);
|
||||
void fill_info(NETOBJ_PROJECTILE *proj);
|
||||
|
||||
virtual void reset();
|
||||
virtual void tick();
|
||||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
#endif
|
83
src/game/server/entity.hpp
Normal file
83
src/game/server/entity.hpp
Normal file
|
@ -0,0 +1,83 @@
|
|||
#ifndef GAME_SERVER_ENTITY_H
|
||||
#define GAME_SERVER_ENTITY_H
|
||||
|
||||
#include <base/vmath.hpp>
|
||||
|
||||
/*
|
||||
Class: Entity
|
||||
Basic entity class.
|
||||
*/
|
||||
class ENTITY
|
||||
{
|
||||
private:
|
||||
friend class GAMEWORLD; // thy these?
|
||||
ENTITY *prev_entity;
|
||||
ENTITY *next_entity;
|
||||
|
||||
ENTITY *prev_type_entity;
|
||||
ENTITY *next_type_entity;
|
||||
protected:
|
||||
bool marked_for_destroy;
|
||||
int id;
|
||||
int objtype;
|
||||
public:
|
||||
|
||||
ENTITY(int objtype);
|
||||
virtual ~ENTITY();
|
||||
|
||||
ENTITY *typenext() { return next_type_entity; }
|
||||
ENTITY *typeprev() { return prev_type_entity; }
|
||||
|
||||
/*
|
||||
Function: destroy
|
||||
Destorys the entity.
|
||||
*/
|
||||
virtual void destroy() { delete this; }
|
||||
|
||||
/*
|
||||
Function: reset
|
||||
Called when the game resets the map. Puts the entity
|
||||
back to it's starting state or perhaps destroys it.
|
||||
*/
|
||||
virtual void reset() {}
|
||||
|
||||
/*
|
||||
Function: tick
|
||||
Called progress the entity to the next tick. Updates
|
||||
and moves the entity to it's new state and position.
|
||||
*/
|
||||
virtual void tick() {}
|
||||
|
||||
/*
|
||||
Function: tick_defered
|
||||
Called after all entities tick() function has been called.
|
||||
*/
|
||||
virtual void tick_defered() {}
|
||||
|
||||
/*
|
||||
Function: snap
|
||||
Called when a new snapshot is being generated for a specific
|
||||
client.
|
||||
|
||||
Arguments:
|
||||
snapping_client - ID of the client which snapshot is
|
||||
being generated. Could be -1 to create a complete
|
||||
snapshot of everything in the game for demo
|
||||
recording.
|
||||
*/
|
||||
virtual void snap(int snapping_client) {}
|
||||
|
||||
/*
|
||||
Variable: proximity_radius
|
||||
Contains the physical size of the entity.
|
||||
*/
|
||||
float proximity_radius;
|
||||
|
||||
/*
|
||||
Variable: pos
|
||||
Contains the current posititon of the entity.
|
||||
*/
|
||||
vec2 pos;
|
||||
};
|
||||
|
||||
#endif
|
25
src/game/server/eventhandler.hpp
Normal file
25
src/game/server/eventhandler.hpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
#ifndef GAME_SERVER_EVENTHANDLER_H
|
||||
#define GAME_SERVER_EVENTHANDLER_H
|
||||
|
||||
//
|
||||
class EVENTHANDLER
|
||||
{
|
||||
static const int MAX_EVENTS = 128;
|
||||
static const int MAX_DATASIZE = 128*64;
|
||||
|
||||
int types[MAX_EVENTS]; // TODO: remove some of these arrays
|
||||
int offsets[MAX_EVENTS];
|
||||
int sizes[MAX_EVENTS];
|
||||
int client_masks[MAX_EVENTS];
|
||||
char data[MAX_DATASIZE];
|
||||
|
||||
int current_offset;
|
||||
int num_events;
|
||||
public:
|
||||
EVENTHANDLER();
|
||||
void *create(int type, int size, int mask = -1);
|
||||
void clear();
|
||||
void snap(int snapping_client);
|
||||
};
|
||||
|
||||
#endif
|
38
src/game/server/gamecontext.hpp
Normal file
38
src/game/server/gamecontext.hpp
Normal file
|
@ -0,0 +1,38 @@
|
|||
|
||||
#include "eventhandler.hpp"
|
||||
#include "gamecontroller.hpp"
|
||||
#include "gameworld.hpp"
|
||||
|
||||
class GAMECONTEXT
|
||||
{
|
||||
public:
|
||||
GAMECONTEXT();
|
||||
void clear();
|
||||
|
||||
EVENTHANDLER events;
|
||||
PLAYER players[MAX_CLIENTS];
|
||||
|
||||
GAMECONTROLLER *controller;
|
||||
GAMEWORLD world;
|
||||
|
||||
void tick();
|
||||
void snap(int client_id);
|
||||
|
||||
// helper functions
|
||||
void create_damageind(vec2 p, float angle_mod, int amount);
|
||||
void create_explosion(vec2 p, int owner, int weapon, bool bnodamage);
|
||||
void create_smoke(vec2 p);
|
||||
void create_playerspawn(vec2 p);
|
||||
void create_death(vec2 p, int who);
|
||||
void create_sound(vec2 pos, int sound, int mask=-1);
|
||||
void create_sound_global(int sound, int target=-1);
|
||||
|
||||
// network
|
||||
void send_chat(int cid, int team, const char *text);
|
||||
void send_emoticon(int cid, int emoticon);
|
||||
void send_weapon_pickup(int cid, int weapon);
|
||||
void send_broadcast(const char *text, int cid);
|
||||
void send_info(int who, int to_who);
|
||||
};
|
||||
|
||||
extern GAMECONTEXT game;
|
|
@ -5,6 +5,8 @@
|
|||
#include <game/g_mapitems.hpp>
|
||||
#include "gs_common.hpp"
|
||||
|
||||
#include "entities/pickup.hpp"
|
||||
|
||||
GAMECONTROLLER::GAMECONTROLLER()
|
||||
{
|
||||
// select gametype
|
97
src/game/server/gamecontroller.hpp
Normal file
97
src/game/server/gamecontroller.hpp
Normal file
|
@ -0,0 +1,97 @@
|
|||
#ifndef GAME_SERVER_GAMECONTROLLER_H
|
||||
#define GAME_SERVER_GAMECONTROLLER_H
|
||||
|
||||
#include <base/vmath.hpp>
|
||||
|
||||
/*
|
||||
Class: Game Controller
|
||||
Controls the main game logic. Keeping track of team and player score,
|
||||
winning conditions and specific game logic.
|
||||
*/
|
||||
class GAMECONTROLLER
|
||||
{
|
||||
protected:
|
||||
void cyclemap();
|
||||
void resetgame();
|
||||
|
||||
int round_start_tick;
|
||||
int game_over_tick;
|
||||
int sudden_death;
|
||||
|
||||
int teamscore[2];
|
||||
|
||||
int warmup;
|
||||
int round_count;
|
||||
|
||||
bool is_teamplay;
|
||||
|
||||
public:
|
||||
int gametype;
|
||||
GAMECONTROLLER();
|
||||
|
||||
void do_team_score_wincheck();
|
||||
void do_player_score_wincheck();
|
||||
|
||||
void do_warmup(int seconds);
|
||||
|
||||
void startround();
|
||||
void endround();
|
||||
|
||||
bool is_friendly_fire(int cid1, int cid2);
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
virtual void tick();
|
||||
|
||||
virtual void snap(int snapping_client);
|
||||
|
||||
/*
|
||||
Function: on_entity
|
||||
Called when the map is loaded to process an entity
|
||||
in the map.
|
||||
|
||||
Arguments:
|
||||
index - Entity index.
|
||||
pos - Where the entity is located in the world.
|
||||
|
||||
Returns:
|
||||
bool?
|
||||
*/
|
||||
virtual bool on_entity(int index, vec2 pos);
|
||||
|
||||
/*
|
||||
Function: on_character_spawn
|
||||
Called when a character spawns into the game world.
|
||||
|
||||
Arguments:
|
||||
chr - The character that was spawned.
|
||||
*/
|
||||
virtual void on_character_spawn(class CHARACTER *chr) {}
|
||||
|
||||
/*
|
||||
Function: on_character_death
|
||||
Called when a character in the world dies.
|
||||
|
||||
Arguments:
|
||||
victim - The character that died.
|
||||
killer - The player that killed it.
|
||||
weapon - What weapon that killed it. Can be -1 for undefined
|
||||
weapon when switching team or player suicides.
|
||||
*/
|
||||
virtual int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
|
||||
|
||||
virtual void on_player_info_change(class PLAYER *p);
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
virtual const char *get_team_name(int team);
|
||||
virtual int get_auto_team(int notthisid);
|
||||
virtual bool can_join_team(int team, int notthisid);
|
||||
int clampteam(int team);
|
||||
|
||||
virtual void post_reset();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,8 +1,10 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/e_server_interface.h>
|
||||
#include <game/g_mapitems.hpp>
|
||||
#include "gs_common.hpp"
|
||||
#include "gs_game_ctf.hpp"
|
||||
#include <game/server/entities/character.hpp>
|
||||
#include <game/server/player.hpp>
|
||||
#include <game/server/gamecontext.hpp>
|
||||
#include "ctf.hpp"
|
||||
|
||||
GAMECONTROLLER_CTF::GAMECONTROLLER_CTF()
|
||||
{
|
|
@ -1,6 +1,8 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
|
||||
// game object
|
||||
#include <game/server/gamecontroller.hpp>
|
||||
#include <game/server/entity.hpp>
|
||||
|
||||
class GAMECONTROLLER_CTF : public GAMECONTROLLER
|
||||
{
|
||||
public:
|
|
@ -1,7 +1,5 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/e_config.h>
|
||||
#include "gs_common.hpp"
|
||||
#include "gs_game_dm.hpp"
|
||||
#include "dm.hpp"
|
||||
|
||||
void GAMECONTROLLER_DM::tick()
|
||||
{
|
|
@ -1,5 +1,7 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
// game object
|
||||
|
||||
#include <game/server/gamecontroller.hpp>
|
||||
|
||||
class GAMECONTROLLER_DM : public GAMECONTROLLER
|
||||
{
|
||||
public:
|
|
@ -1,7 +1,8 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
#include <engine/e_config.h>
|
||||
#include "gs_common.hpp"
|
||||
#include "gs_game_tdm.hpp"
|
||||
#include <engine/e_server_interface.h>
|
||||
#include <game/server/entities/character.hpp>
|
||||
#include <game/server/player.hpp>
|
||||
#include "tdm.hpp"
|
||||
|
||||
GAMECONTROLLER_TDM::GAMECONTROLLER_TDM()
|
||||
{
|
|
@ -1,5 +1,7 @@
|
|||
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
||||
// game object
|
||||
|
||||
#include <game/server/gamecontroller.hpp>
|
||||
|
||||
class GAMECONTROLLER_TDM : public GAMECONTROLLER
|
||||
{
|
||||
public:
|
126
src/game/server/gameworld.hpp
Normal file
126
src/game/server/gameworld.hpp
Normal file
|
@ -0,0 +1,126 @@
|
|||
|
||||
class CHARACTER;
|
||||
|
||||
/*
|
||||
Class: Game World
|
||||
Tracks all entities in the game. Propagates tick and
|
||||
snap calls to all entities.
|
||||
*/
|
||||
class GAMEWORLD
|
||||
{
|
||||
void reset();
|
||||
void remove_entities();
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_ENT_TYPES=10, // TODO: are more exact value perhaps? :)
|
||||
};
|
||||
|
||||
// TODO: two lists seams kinda not good, shouldn't be needed
|
||||
ENTITY *first_entity;
|
||||
ENTITY *first_entity_types[NUM_ENT_TYPES];
|
||||
|
||||
public:
|
||||
bool reset_requested;
|
||||
bool paused;
|
||||
WORLD_CORE core;
|
||||
|
||||
GAMEWORLD();
|
||||
~GAMEWORLD();
|
||||
|
||||
ENTITY *find_first() { return first_entity; }
|
||||
ENTITY *find_first(int type);
|
||||
|
||||
/*
|
||||
Function: find_entities
|
||||
Finds entities close to a position and returns them in a list.
|
||||
|
||||
Arguments:
|
||||
pos - Position.
|
||||
radius - How close the entities have to be.
|
||||
ents - Pointer to a list that should be filled with the pointers
|
||||
to the entities.
|
||||
max - Number of entities that fits into the ents array.
|
||||
type - Type of the entities to find. -1 for all types.
|
||||
|
||||
Returns:
|
||||
Number of entities found and added to the ents array.
|
||||
*/
|
||||
int find_entities(vec2 pos, float radius, ENTITY **ents, int max, int type = -1);
|
||||
|
||||
/*
|
||||
Function: interserct_character
|
||||
Finds the closest character that intersects the line.
|
||||
|
||||
Arguments:
|
||||
pos0 - Start position
|
||||
pos2 - End position
|
||||
radius - How for from the line the character is allowed to be.
|
||||
new_pos - Intersection position
|
||||
notthis - Entity to ignore intersecting with
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the closest hit or NULL of there is no intersection.
|
||||
*/
|
||||
class CHARACTER *intersect_character(vec2 pos0, vec2 pos1, float radius, vec2 &new_pos, class ENTITY *notthis = 0);
|
||||
|
||||
/*
|
||||
Function: closest_character
|
||||
Finds the closest character to a specific point.
|
||||
|
||||
Arguments:
|
||||
pos - The center position.
|
||||
radius - How far off the character is allowed to be
|
||||
notthis - Entity to ignore
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the closest character or NULL if no character is close enough.
|
||||
*/
|
||||
class CHARACTER *closest_character(vec2 pos, float radius, ENTITY *notthis);
|
||||
|
||||
/*
|
||||
Function: insert_entity
|
||||
Adds an entity to the world.
|
||||
|
||||
Arguments:
|
||||
entity - Entity to add
|
||||
*/
|
||||
void insert_entity(ENTITY *entity);
|
||||
|
||||
/*
|
||||
Function: remove_entity
|
||||
Removes an entity from the world.
|
||||
|
||||
Arguments:
|
||||
entity - Entity to remove
|
||||
*/
|
||||
void remove_entity(ENTITY *entity);
|
||||
|
||||
/*
|
||||
Function: destroy_entity
|
||||
Destroys an entity in the world.
|
||||
|
||||
Arguments:
|
||||
entity - Entity to destroy
|
||||
*/
|
||||
void destroy_entity(ENTITY *entity);
|
||||
|
||||
/*
|
||||
Function: snap
|
||||
Calls snap on all the entities in the world to create
|
||||
the snapshot.
|
||||
|
||||
Arguments:
|
||||
snapping_client - ID of the client which snapshot
|
||||
is being created.
|
||||
*/
|
||||
void snap(int snapping_client);
|
||||
|
||||
/*
|
||||
Function: tick
|
||||
Calls tick on all the entities in the world to progress
|
||||
the world to the next tick.
|
||||
|
||||
*/
|
||||
void tick();
|
||||
};
|
|
@ -32,590 +32,15 @@ inline bool cmask_is_set(int mask, int cid) { return (mask&cmask_one(cid)) != 0;
|
|||
*/
|
||||
|
||||
|
||||
#include "eventhandler.hpp"
|
||||
|
||||
//
|
||||
class EVENT_HANDLER
|
||||
{
|
||||
static const int MAX_EVENTS = 128;
|
||||
static const int MAX_DATASIZE = 128*64;
|
||||
#include "entity.hpp"
|
||||
|
||||
int types[MAX_EVENTS]; // TODO: remove some of these arrays
|
||||
int offsets[MAX_EVENTS];
|
||||
int sizes[MAX_EVENTS];
|
||||
int client_masks[MAX_EVENTS];
|
||||
char data[MAX_DATASIZE];
|
||||
|
||||
int current_offset;
|
||||
int num_events;
|
||||
public:
|
||||
EVENT_HANDLER();
|
||||
void *create(int type, int size, int mask = -1);
|
||||
void clear();
|
||||
void snap(int snapping_client);
|
||||
};
|
||||
|
||||
/*
|
||||
Class: Entity
|
||||
Basic entity class.
|
||||
*/
|
||||
class ENTITY
|
||||
{
|
||||
private:
|
||||
friend class GAMEWORLD; // thy these?
|
||||
ENTITY *prev_entity;
|
||||
ENTITY *next_entity;
|
||||
|
||||
ENTITY *prev_type_entity;
|
||||
ENTITY *next_type_entity;
|
||||
protected:
|
||||
bool marked_for_destroy;
|
||||
int id;
|
||||
int objtype;
|
||||
public:
|
||||
|
||||
ENTITY(int objtype);
|
||||
virtual ~ENTITY();
|
||||
|
||||
ENTITY *typenext() { return next_type_entity; }
|
||||
ENTITY *typeprev() { return prev_type_entity; }
|
||||
|
||||
/*
|
||||
Function: destroy
|
||||
Destorys the entity.
|
||||
*/
|
||||
virtual void destroy() { delete this; }
|
||||
|
||||
/*
|
||||
Function: reset
|
||||
Called when the game resets the map. Puts the entity
|
||||
back to it's starting state or perhaps destroys it.
|
||||
*/
|
||||
virtual void reset() {}
|
||||
|
||||
/*
|
||||
Function: tick
|
||||
Called progress the entity to the next tick. Updates
|
||||
and moves the entity to it's new state and position.
|
||||
*/
|
||||
virtual void tick() {}
|
||||
|
||||
/*
|
||||
Function: tick_defered
|
||||
Called after all entities tick() function has been called.
|
||||
*/
|
||||
virtual void tick_defered() {}
|
||||
|
||||
/*
|
||||
Function: snap
|
||||
Called when a new snapshot is being generated for a specific
|
||||
client.
|
||||
|
||||
Arguments:
|
||||
snapping_client - ID of the client which snapshot is
|
||||
being generated. Could be -1 to create a complete
|
||||
snapshot of everything in the game for demo
|
||||
recording.
|
||||
*/
|
||||
virtual void snap(int snapping_client) {}
|
||||
|
||||
/*
|
||||
Variable: proximity_radius
|
||||
Contains the physical size of the entity.
|
||||
*/
|
||||
float proximity_radius;
|
||||
|
||||
/*
|
||||
Variable: pos
|
||||
Contains the current posititon of the entity.
|
||||
*/
|
||||
vec2 pos;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Class: Game World
|
||||
Tracks all entities in the game. Propagates tick and
|
||||
snap calls to all entities.
|
||||
*/
|
||||
class GAMEWORLD
|
||||
{
|
||||
void reset();
|
||||
void remove_entities();
|
||||
|
||||
enum
|
||||
{
|
||||
NUM_ENT_TYPES=10, // TODO: are more exact value perhaps? :)
|
||||
};
|
||||
|
||||
// TODO: two lists seams kinda not good, shouldn't be needed
|
||||
ENTITY *first_entity;
|
||||
ENTITY *first_entity_types[NUM_ENT_TYPES];
|
||||
|
||||
public:
|
||||
bool reset_requested;
|
||||
bool paused;
|
||||
WORLD_CORE core;
|
||||
|
||||
GAMEWORLD();
|
||||
~GAMEWORLD();
|
||||
|
||||
ENTITY *find_first() { return first_entity; }
|
||||
ENTITY *find_first(int type);
|
||||
|
||||
/*
|
||||
Function: find_entities
|
||||
Finds entities close to a position and returns them in a list.
|
||||
|
||||
Arguments:
|
||||
pos - Position.
|
||||
radius - How close the entities have to be.
|
||||
ents - Pointer to a list that should be filled with the pointers
|
||||
to the entities.
|
||||
max - Number of entities that fits into the ents array.
|
||||
type - Type of the entities to find. -1 for all types.
|
||||
|
||||
Returns:
|
||||
Number of entities found and added to the ents array.
|
||||
*/
|
||||
int find_entities(vec2 pos, float radius, ENTITY **ents, int max, int type = -1);
|
||||
|
||||
/*
|
||||
Function: interserct_character
|
||||
Finds the closest character that intersects the line.
|
||||
|
||||
Arguments:
|
||||
pos0 - Start position
|
||||
pos2 - End position
|
||||
radius - How for from the line the character is allowed to be.
|
||||
new_pos - Intersection position
|
||||
notthis - Entity to ignore intersecting with
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the closest hit or NULL of there is no intersection.
|
||||
*/
|
||||
class CHARACTER *intersect_character(vec2 pos0, vec2 pos1, float radius, vec2 &new_pos, class ENTITY *notthis = 0);
|
||||
|
||||
/*
|
||||
Function: closest_character
|
||||
Finds the closest character to a specific point.
|
||||
|
||||
Arguments:
|
||||
pos - The center position.
|
||||
radius - How far off the character is allowed to be
|
||||
notthis - Entity to ignore
|
||||
|
||||
Returns:
|
||||
Returns a pointer to the closest character or NULL if no character is close enough.
|
||||
*/
|
||||
class CHARACTER *closest_character(vec2 pos, float radius, ENTITY *notthis);
|
||||
|
||||
/*
|
||||
Function: insert_entity
|
||||
Adds an entity to the world.
|
||||
|
||||
Arguments:
|
||||
entity - Entity to add
|
||||
*/
|
||||
void insert_entity(ENTITY *entity);
|
||||
|
||||
/*
|
||||
Function: remove_entity
|
||||
Removes an entity from the world.
|
||||
|
||||
Arguments:
|
||||
entity - Entity to remove
|
||||
*/
|
||||
void remove_entity(ENTITY *entity);
|
||||
|
||||
/*
|
||||
Function: destroy_entity
|
||||
Destroys an entity in the world.
|
||||
|
||||
Arguments:
|
||||
entity - Entity to destroy
|
||||
*/
|
||||
void destroy_entity(ENTITY *entity);
|
||||
|
||||
/*
|
||||
Function: snap
|
||||
Calls snap on all the entities in the world to create
|
||||
the snapshot.
|
||||
|
||||
Arguments:
|
||||
snapping_client - ID of the client which snapshot
|
||||
is being created.
|
||||
*/
|
||||
void snap(int snapping_client);
|
||||
|
||||
/*
|
||||
Function: tick
|
||||
Calls tick on all the entities in the world to progress
|
||||
the world to the next tick.
|
||||
|
||||
*/
|
||||
void tick();
|
||||
};
|
||||
|
||||
/*
|
||||
Class: Game Controller
|
||||
Controls the main game logic. Keeping track of team and player score,
|
||||
winning conditions and specific game logic.
|
||||
*/
|
||||
class GAMECONTROLLER
|
||||
{
|
||||
protected:
|
||||
void cyclemap();
|
||||
void resetgame();
|
||||
|
||||
int round_start_tick;
|
||||
int game_over_tick;
|
||||
int sudden_death;
|
||||
|
||||
int teamscore[2];
|
||||
|
||||
int warmup;
|
||||
int round_count;
|
||||
|
||||
bool is_teamplay;
|
||||
|
||||
public:
|
||||
int gametype;
|
||||
GAMECONTROLLER();
|
||||
|
||||
void do_team_score_wincheck();
|
||||
void do_player_score_wincheck();
|
||||
|
||||
void do_warmup(int seconds);
|
||||
|
||||
void startround();
|
||||
void endround();
|
||||
|
||||
bool is_friendly_fire(int cid1, int cid2);
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
virtual void tick();
|
||||
|
||||
virtual void snap(int snapping_client);
|
||||
|
||||
/*
|
||||
Function: on_entity
|
||||
Called when the map is loaded to process an entity
|
||||
in the map.
|
||||
|
||||
Arguments:
|
||||
index - Entity index.
|
||||
pos - Where the entity is located in the world.
|
||||
|
||||
Returns:
|
||||
bool?
|
||||
*/
|
||||
virtual bool on_entity(int index, vec2 pos);
|
||||
|
||||
/*
|
||||
Function: on_character_spawn
|
||||
Called when a character spawns into the game world.
|
||||
|
||||
Arguments:
|
||||
chr - The character that was spawned.
|
||||
*/
|
||||
virtual void on_character_spawn(class CHARACTER *chr) {}
|
||||
|
||||
/*
|
||||
Function: on_character_death
|
||||
Called when a character in the world dies.
|
||||
|
||||
Arguments:
|
||||
victim - The character that died.
|
||||
killer - The player that killed it.
|
||||
weapon - What weapon that killed it. Can be -1 for undefined
|
||||
weapon when switching team or player suicides.
|
||||
*/
|
||||
virtual int on_character_death(class CHARACTER *victim, class PLAYER *killer, int weapon);
|
||||
|
||||
virtual void on_player_info_change(class PLAYER *p);
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
virtual const char *get_team_name(int team);
|
||||
virtual int get_auto_team(int notthisid);
|
||||
virtual bool can_join_team(int team, int notthisid);
|
||||
int clampteam(int team);
|
||||
|
||||
virtual void post_reset();
|
||||
};
|
||||
|
||||
// TODO: move to seperate file
|
||||
class PICKUP : public ENTITY
|
||||
{
|
||||
public:
|
||||
static const int phys_size = 14;
|
||||
|
||||
int type;
|
||||
int subtype; // weapon type for instance?
|
||||
int spawntick;
|
||||
PICKUP(int _type, int _subtype = 0);
|
||||
|
||||
virtual void reset();
|
||||
virtual void tick();
|
||||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
// projectile entity
|
||||
class PROJECTILE : public ENTITY
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
PROJECTILE_FLAGS_EXPLODE = 1 << 0,
|
||||
};
|
||||
|
||||
vec2 direction;
|
||||
ENTITY *powner; // this is nasty, could be removed when client quits
|
||||
int lifespan;
|
||||
int owner;
|
||||
int type;
|
||||
int flags;
|
||||
int damage;
|
||||
int sound_impact;
|
||||
int weapon;
|
||||
int bounce;
|
||||
float force;
|
||||
int start_tick;
|
||||
|
||||
PROJECTILE(int type, int owner, vec2 pos, vec2 vel, int span, ENTITY* powner,
|
||||
int damage, int flags, float force, int sound_impact, int weapon);
|
||||
|
||||
vec2 get_pos(float time);
|
||||
void fill_info(NETOBJ_PROJECTILE *proj);
|
||||
|
||||
virtual void reset();
|
||||
virtual void tick();
|
||||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
class LASER : public ENTITY
|
||||
{
|
||||
vec2 from;
|
||||
vec2 dir;
|
||||
float energy;
|
||||
int bounces;
|
||||
int eval_tick;
|
||||
CHARACTER *owner;
|
||||
|
||||
bool hit_character(vec2 from, vec2 to);
|
||||
void do_bounce();
|
||||
|
||||
public:
|
||||
|
||||
LASER(vec2 pos, vec2 direction, float start_energy, CHARACTER *owner);
|
||||
|
||||
virtual void reset();
|
||||
virtual void tick();
|
||||
virtual void snap(int snapping_client);
|
||||
};
|
||||
|
||||
|
||||
class CHARACTER : public ENTITY
|
||||
{
|
||||
public:
|
||||
// player controlling this character
|
||||
class PLAYER *player;
|
||||
|
||||
bool alive;
|
||||
|
||||
// weapon info
|
||||
ENTITY *hitobjects[10];
|
||||
int numobjectshit;
|
||||
struct WEAPONSTAT
|
||||
{
|
||||
int ammoregenstart;
|
||||
int ammo;
|
||||
int ammocost;
|
||||
bool got;
|
||||
} weapons[NUM_WEAPONS];
|
||||
|
||||
int active_weapon;
|
||||
int last_weapon;
|
||||
int queued_weapon;
|
||||
|
||||
int reload_timer;
|
||||
int attack_tick;
|
||||
|
||||
int damage_taken;
|
||||
|
||||
int emote_type;
|
||||
int emote_stop;
|
||||
|
||||
// TODO: clean this up
|
||||
char skin_name[64];
|
||||
int use_custom_color;
|
||||
int color_body;
|
||||
int color_feet;
|
||||
|
||||
int last_action; // last tick that the player took any action ie some input
|
||||
|
||||
// these are non-heldback inputs
|
||||
NETOBJ_PLAYER_INPUT latest_previnput;
|
||||
NETOBJ_PLAYER_INPUT latest_input;
|
||||
|
||||
// input
|
||||
NETOBJ_PLAYER_INPUT previnput;
|
||||
NETOBJ_PLAYER_INPUT input;
|
||||
int num_inputs;
|
||||
int jumped;
|
||||
|
||||
int damage_taken_tick;
|
||||
|
||||
int health;
|
||||
int armor;
|
||||
|
||||
// ninja
|
||||
struct
|
||||
{
|
||||
vec2 activationdir;
|
||||
int activationtick;
|
||||
int currentcooldown;
|
||||
int currentmovetime;
|
||||
} ninja;
|
||||
|
||||
//
|
||||
//int score;
|
||||
int team;
|
||||
int player_state; // if the client is chatting, accessing a menu or so
|
||||
|
||||
// the player core for the physics
|
||||
CHARACTER_CORE core;
|
||||
|
||||
//
|
||||
CHARACTER();
|
||||
|
||||
virtual void reset();
|
||||
virtual void destroy();
|
||||
|
||||
bool is_grounded();
|
||||
|
||||
void set_weapon(int w);
|
||||
|
||||
void handle_weaponswitch();
|
||||
void do_weaponswitch();
|
||||
|
||||
int handle_weapons();
|
||||
int handle_ninja();
|
||||
|
||||
void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void fire_weapon();
|
||||
|
||||
void die(int killer, int weapon);
|
||||
|
||||
bool take_damage(vec2 force, int dmg, int from, int weapon);
|
||||
|
||||
|
||||
bool spawn(PLAYER *player, vec2 pos, int team);
|
||||
//bool init_tryspawn(int team);
|
||||
bool remove();
|
||||
|
||||
static const int phys_size = 28;
|
||||
|
||||
virtual void tick();
|
||||
virtual void tick_defered();
|
||||
virtual void snap(int snaping_client);
|
||||
|
||||
bool increase_health(int amount);
|
||||
bool increase_armor(int amount);
|
||||
};
|
||||
|
||||
// player object
|
||||
class PLAYER
|
||||
{
|
||||
public:
|
||||
PLAYER();
|
||||
|
||||
// TODO: clean this up
|
||||
char skin_name[64];
|
||||
int use_custom_color;
|
||||
int color_body;
|
||||
int color_feet;
|
||||
|
||||
//
|
||||
bool spawning;
|
||||
int client_id;
|
||||
int team;
|
||||
int score;
|
||||
|
||||
//
|
||||
int64 last_chat;
|
||||
|
||||
// network latency calculations
|
||||
struct
|
||||
{
|
||||
int accum;
|
||||
int accum_min;
|
||||
int accum_max;
|
||||
int avg;
|
||||
int min;
|
||||
int max;
|
||||
} latency;
|
||||
|
||||
CHARACTER character;
|
||||
|
||||
// this is used for snapping so we know how we can clip the view for the player
|
||||
vec2 view_pos;
|
||||
|
||||
void init(int client_id);
|
||||
|
||||
CHARACTER *get_character();
|
||||
|
||||
void kill_character();
|
||||
|
||||
void try_respawn();
|
||||
void respawn();
|
||||
void set_team(int team);
|
||||
|
||||
void tick();
|
||||
void snap(int snaping_client);
|
||||
|
||||
void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void on_disconnect();
|
||||
};
|
||||
|
||||
class GAMECONTEXT
|
||||
{
|
||||
public:
|
||||
GAMECONTEXT();
|
||||
void clear();
|
||||
|
||||
EVENT_HANDLER events;
|
||||
PLAYER players[MAX_CLIENTS];
|
||||
|
||||
GAMECONTROLLER *controller;
|
||||
GAMEWORLD world;
|
||||
|
||||
void tick();
|
||||
void snap(int client_id);
|
||||
|
||||
// helper functions
|
||||
void create_damageind(vec2 p, float angle_mod, int amount);
|
||||
void create_explosion(vec2 p, int owner, int weapon, bool bnodamage);
|
||||
void create_smoke(vec2 p);
|
||||
void create_playerspawn(vec2 p);
|
||||
void create_death(vec2 p, int who);
|
||||
void create_sound(vec2 pos, int sound, int mask=-1);
|
||||
void create_sound_global(int sound, int target=-1);
|
||||
|
||||
// network
|
||||
void send_chat(int cid, int team, const char *text);
|
||||
void send_emoticon(int cid, int emoticon);
|
||||
void send_weapon_pickup(int cid, int weapon);
|
||||
void send_broadcast(const char *text, int cid);
|
||||
void send_info(int who, int to_who);
|
||||
};
|
||||
|
||||
extern GAMECONTEXT game;
|
||||
#include "gamecontroller.hpp"
|
||||
#include "entities/character.hpp"
|
||||
#include "player.hpp"
|
||||
#include "gamecontext.hpp"
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -11,9 +11,10 @@
|
|||
#include <game/g_collision.hpp>
|
||||
#include <game/g_layers.hpp>
|
||||
#include "gs_common.hpp"
|
||||
#include "gs_game_ctf.hpp"
|
||||
#include "gs_game_tdm.hpp"
|
||||
#include "gs_game_dm.hpp"
|
||||
|
||||
#include "gamemodes/dm.hpp"
|
||||
#include "gamemodes/tdm.hpp"
|
||||
#include "gamemodes/ctf.hpp"
|
||||
|
||||
TUNING_PARAMS tuning;
|
||||
GAMECONTEXT game;
|
||||
|
@ -106,12 +107,12 @@ void send_tuning_params(int cid)
|
|||
//////////////////////////////////////////////////
|
||||
// Event handler
|
||||
//////////////////////////////////////////////////
|
||||
EVENT_HANDLER::EVENT_HANDLER()
|
||||
EVENTHANDLER::EVENTHANDLER()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void *EVENT_HANDLER::create(int type, int size, int mask)
|
||||
void *EVENTHANDLER::create(int type, int size, int mask)
|
||||
{
|
||||
if(num_events == MAX_EVENTS)
|
||||
return 0;
|
||||
|
@ -128,13 +129,13 @@ void *EVENT_HANDLER::create(int type, int size, int mask)
|
|||
return p;
|
||||
}
|
||||
|
||||
void EVENT_HANDLER::clear()
|
||||
void EVENTHANDLER::clear()
|
||||
{
|
||||
num_events = 0;
|
||||
current_offset = 0;
|
||||
}
|
||||
|
||||
void EVENT_HANDLER::snap(int snapping_client)
|
||||
void EVENTHANDLER::snap(int snapping_client)
|
||||
{
|
||||
for(int i = 0; i < num_events; i++)
|
||||
{
|
||||
|
@ -327,217 +328,6 @@ void GAMEWORLD::tick()
|
|||
remove_entities();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// projectile
|
||||
//////////////////////////////////////////////////
|
||||
PROJECTILE::PROJECTILE(int type, int owner, vec2 pos, vec2 dir, int span, ENTITY* powner,
|
||||
int damage, int flags, float force, int sound_impact, int weapon)
|
||||
: ENTITY(NETOBJTYPE_PROJECTILE)
|
||||
{
|
||||
this->type = type;
|
||||
this->pos = pos;
|
||||
this->direction = dir;
|
||||
this->lifespan = span;
|
||||
this->owner = owner;
|
||||
this->powner = powner;
|
||||
this->flags = flags;
|
||||
this->force = force;
|
||||
this->damage = damage;
|
||||
this->sound_impact = sound_impact;
|
||||
this->weapon = weapon;
|
||||
this->bounce = 0;
|
||||
this->start_tick = server_tick();
|
||||
game.world.insert_entity(this);
|
||||
}
|
||||
|
||||
void PROJECTILE::reset()
|
||||
{
|
||||
game.world.destroy_entity(this);
|
||||
}
|
||||
|
||||
vec2 PROJECTILE::get_pos(float time)
|
||||
{
|
||||
float curvature = 0;
|
||||
float speed = 0;
|
||||
if(type == WEAPON_GRENADE)
|
||||
{
|
||||
curvature = tuning.grenade_curvature;
|
||||
speed = tuning.grenade_speed;
|
||||
}
|
||||
else if(type == WEAPON_SHOTGUN)
|
||||
{
|
||||
curvature = tuning.shotgun_curvature;
|
||||
speed = tuning.shotgun_speed;
|
||||
}
|
||||
else if(type == WEAPON_GUN)
|
||||
{
|
||||
curvature = tuning.gun_curvature;
|
||||
speed = tuning.gun_speed;
|
||||
}
|
||||
|
||||
return calc_pos(pos, direction, curvature, speed, time);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
|
||||
lifespan--;
|
||||
|
||||
int collide = col_intersect_line(prevpos, curpos, &curpos);
|
||||
//int collide = col_check_point((int)curpos.x, (int)curpos.y);
|
||||
|
||||
CHARACTER *targetchr = game.world.intersect_character(prevpos, curpos, 6.0f, curpos, powner);
|
||||
if(targetchr || collide || lifespan < 0)
|
||||
{
|
||||
if(lifespan >= 0 || weapon == WEAPON_GRENADE)
|
||||
game.create_sound(curpos, sound_impact);
|
||||
|
||||
if(flags & PROJECTILE_FLAGS_EXPLODE)
|
||||
game.create_explosion(curpos, owner, weapon, false);
|
||||
else if(targetchr)
|
||||
{
|
||||
targetchr->take_damage(direction * max(0.001f, force), damage, owner, weapon);
|
||||
}
|
||||
|
||||
game.world.destroy_entity(this);
|
||||
}
|
||||
}
|
||||
|
||||
void PROJECTILE::fill_info(NETOBJ_PROJECTILE *proj)
|
||||
{
|
||||
proj->x = (int)pos.x;
|
||||
proj->y = (int)pos.y;
|
||||
proj->vx = (int)(direction.x*100.0f);
|
||||
proj->vy = (int)(direction.y*100.0f);
|
||||
proj->start_tick = start_tick;
|
||||
proj->type = type;
|
||||
}
|
||||
|
||||
void PROJECTILE::snap(int snapping_client)
|
||||
{
|
||||
float ct = (server_tick()-start_tick)/(float)server_tickspeed();
|
||||
|
||||
if(distance(game.players[snapping_client].view_pos, get_pos(ct)) > 1000.0f)
|
||||
return;
|
||||
|
||||
NETOBJ_PROJECTILE *proj = (NETOBJ_PROJECTILE *)snap_new_item(NETOBJTYPE_PROJECTILE, id, sizeof(NETOBJ_PROJECTILE));
|
||||
fill_info(proj);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// laser
|
||||
//////////////////////////////////////////////////
|
||||
LASER::LASER(vec2 pos, vec2 direction, float start_energy, CHARACTER *owner)
|
||||
: 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;
|
||||
CHARACTER *hit = game.world.intersect_character(pos, to, 0.0f, at, owner);
|
||||
if(!hit)
|
||||
return false;
|
||||
|
||||
this->from = from;
|
||||
pos = at;
|
||||
energy = -1;
|
||||
hit->take_damage(vec2(0,0), tuning.laser_damage, owner->player->client_id, WEAPON_RIFLE);
|
||||
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;
|
||||
|
||||
if(col_intersect_line(pos, to, &to))
|
||||
{
|
||||
if(!hit_character(pos, to))
|
||||
{
|
||||
// intersected
|
||||
from = pos;
|
||||
pos = to - dir*2;
|
||||
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)
|
||||
{
|
||||
if(distance(game.players[snapping_client].view_pos, pos) > 1000.0f)
|
||||
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;
|
||||
}
|
||||
|
||||
GAMECONTEXT::GAMECONTEXT()
|
||||
{
|
||||
clear();
|
||||
|
|
55
src/game/server/player.hpp
Normal file
55
src/game/server/player.hpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
// player object
|
||||
class PLAYER
|
||||
{
|
||||
public:
|
||||
PLAYER();
|
||||
|
||||
// TODO: clean this up
|
||||
char skin_name[64];
|
||||
int use_custom_color;
|
||||
int color_body;
|
||||
int color_feet;
|
||||
|
||||
//
|
||||
bool spawning;
|
||||
int client_id;
|
||||
int team;
|
||||
int score;
|
||||
|
||||
//
|
||||
int64 last_chat;
|
||||
|
||||
// network latency calculations
|
||||
struct
|
||||
{
|
||||
int accum;
|
||||
int accum_min;
|
||||
int accum_max;
|
||||
int avg;
|
||||
int min;
|
||||
int max;
|
||||
} latency;
|
||||
|
||||
CHARACTER character;
|
||||
|
||||
// this is used for snapping so we know how we can clip the view for the player
|
||||
vec2 view_pos;
|
||||
|
||||
void init(int client_id);
|
||||
|
||||
CHARACTER *get_character();
|
||||
|
||||
void kill_character();
|
||||
|
||||
void try_respawn();
|
||||
void respawn();
|
||||
void set_team(int team);
|
||||
|
||||
void tick();
|
||||
void snap(int snaping_client);
|
||||
|
||||
void on_direct_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void on_predicted_input(NETOBJ_PLAYER_INPUT *new_input);
|
||||
void on_disconnect();
|
||||
};
|
Loading…
Reference in a new issue