From 83d6c17799c4d448a67ab5cdad02954282fa5c94 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Sat, 1 Nov 2008 13:33:18 +0000 Subject: server-side model loading, initial @dock function --- src/core/commandbuffer.cc | 36 ++++++++++++++++++++++++-------- src/core/entity.cc | 52 +++++++++++++++++++++++++++++++++++++---------- src/core/entity.h | 41 +++++++++++++++++++++---------------- src/core/func.cc | 33 ++++++++++++++++++++++++++---- src/core/func.h | 16 ++++++++++++--- src/core/gameserver.cc | 20 ++++++++++++------ src/core/parser.cc | 3 ++- 7 files changed, 151 insertions(+), 50 deletions(-) (limited to 'src/core') diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc index 8c3c8a1..d3cb4f2 100644 --- a/src/core/commandbuffer.cc +++ b/src/core/commandbuffer.cc @@ -231,19 +231,39 @@ void CommandBuffer::exec(std::string const &cmdline) // is it a function Func *f = Func::find(command); if (f) { - std::string args; - char c; - if (cmdstream >> args) { - while (cmdstream.get(c)) - args += c; - } - // console can not execute game functions, and neither should rcon if ((f->flags() & Func::Game) && (Cvar::sv_dedicated->value() == 0)) { + if (application()->connected()) { - f->exec(game()->localplayer(), args); + + if ((f->flags() & Func::Target)) { + // target function + unsigned int id = 0; + if ((cmdstream >> id)) { + con_debug << "target function " << command << " " << id << std::endl; + Entity *entity = Entity::find(id); + if (entity) + f->exec(game()->localplayer(), entity); + } + } else { + // game function + std::string args; + char c; + if (cmdstream >> args) { + while (cmdstream.get(c)) + args += c; + } + f->exec(game()->localplayer(), args); + } } } else { + // regular function + std::string args; + char c; + if (cmdstream >> args) { + while (cmdstream.get(c)) + args += c; + } f->exec(args); } return; diff --git a/src/core/entity.cc b/src/core/entity.cc index 2c63b18..f9062e0 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -102,7 +102,6 @@ Entity::Entity(unsigned int flags) : entity_dirty = false; entity_model = 0; - entity_modelname.clear(); entity_label.clear(); entity_name.clear(); @@ -213,22 +212,53 @@ void Entity::hide() entity_visible = false; } +void Entity::set_flag(Flags flag) +{ + entity_flags |= flag; +} + +void Entity::unset_flag(Flags flag) +{ + entity_flags &= ~flag; +} + +void Entity::set_model(model::Model *model) +{ + entity_model = model; + if (entity_model) { + entity_radius = entity_model->radius(); + entity_modelname = entity_model->name(); + } +} + +void Entity::set_modelname(const std::string &modelname) +{ + if (!modelname.size()) { + set_model(0); + } else { + set_model(model::Model::load(modelname)); + } + + if (!entity_model) + entity_modelname.clear(); +} + void Entity::serialize_server_create(std::ostream & os) const { - os << entity_moduletypeid << " " - << entity_flags << " " - << (entity_visible ? 1 : 0) << " " - << (entity_zone ? entity_zone->id() : 0) << " " + os << moduletype() << " " + << flags() << " " + << (visible() ? 1 : 0) << " " + << (zone() ? zone()->id() : 0) << " " << std::setprecision(8) << entity_location << " " - << entity_color << " " - << entity_color_second << " " - << entity_shape << " " - << entity_radius << " " + << color() << " " + << color_second() << " " + << shape() << " " + << radius() << " " << std::setprecision(8) << entity_axis.forward() << " " << std::setprecision(8) << entity_axis.left() << " " << "\"" << entity_label << "\" " << "\"" << entity_name << "\" " - << "\"" << entity_modelname << "\" "; + << "\"" << (entity_model ? entity_model->name() : "") << "\" "; } void Entity::receive_server_create(std::istream &is) @@ -288,8 +318,8 @@ void Entity::receive_server_create(std::istream &is) while ( (is.get(c)) && (c != '"')); while ( (is.get(c)) && (c != '"')) n += c; - entity_modelname = n; + set_modelname(n); entity_dirty = false; } diff --git a/src/core/entity.h b/src/core/entity.h index 2c4814e..149419b 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -35,10 +35,7 @@ class Entity { public: /// Entity flags - /** - * entities with the Static flag set will not get client-side interpolation - */ - enum Flags {Static=1, Solid=2, Bright=4}; + enum Flags {Static=1, Solid=2, Bright=4, Dock=8}; /// Entity type constants enum Type {Default=0, Dynamic=1, Controlable=2, Globe=3}; @@ -78,15 +75,15 @@ public: /// entity name (can not contain double qoutes ") inline std::string const & name() { return entity_name; } - /// entity model name - inline std::string const & modelname() { return entity_modelname; } - /// entity client render state inline ClientState * state() { return entity_clientstate; } /// pointer to the model, is used client-side inline model::Model * model() { return entity_model; } + /// modelname + inline const std::string & modelname() const { return entity_modelname; } + /// pointer to the zone the entity belongs to inline Zone *zone() const { return entity_zone; } @@ -176,12 +173,24 @@ public: /// set visibility void set_visible(bool visible = true); + /// set the model name and load the model + void set_modelname(const std:: string &model); + + /// set the model + void set_model(model::Model *model); + /// show the entity, make it visible virtual void show(); /// hide the entity, make it invisible virtual void hide(); + /// set a flag + void set_flag(Flags flag); + + /// unset a flag + void unset_flag(Flags flag); + /// clear all update flags virtual void clear_updates(); @@ -210,13 +219,10 @@ public: math::Axis entity_axis; float entity_radius; - std::string entity_modelname; - model::Model *entity_model; Shape entity_shape; math::Color entity_color; math::Color entity_color_second; unsigned int entity_moduletypeid; - unsigned int entity_flags; bool entity_dirty; bool entity_created; @@ -236,19 +242,20 @@ protected: bool entity_visible; bool entity_serverside; +private: + unsigned int entity_id; + unsigned int entity_flags; + std::string entity_name; std::string entity_label; -private: - // add an entity to the registry - static void add(Entity *ent); - - // the id is set by add() - unsigned int entity_id; + model::Model *entity_model; + std::string entity_modelname; - // the entity registry static Registry entity_registry; static size_t entity_nextid; + + static void add(Entity *ent); }; diff --git a/src/core/func.cc b/src/core/func.cc index 81175f8..42c46c8 100644 --- a/src/core/func.cc +++ b/src/core/func.cc @@ -18,12 +18,12 @@ namespace core Func::Registry Func::func_registry; -Func * Func::add(const char *name, FuncPtr functionptr, unsigned int flags) +Func * Func::add(const char *name, FuncPtr functionptr, bool shared) { Func *func = 0; Registry::iterator it = func_registry.find(name); if (it == func_registry.end()) { - func = new Func(name, (void *)functionptr, flags & ~Func::Game); + func = new Func(name, (void *)functionptr, shared ? Shared : 0); func_registry[std::string(name)] = func; //con_debug << "Function '" << name << "' registered." << std::endl; } else { @@ -33,12 +33,27 @@ Func * Func::add(const char *name, FuncPtr functionptr, unsigned int flags) return func; } -Func *Func::add(const char *name, GameFuncPtr gamefunctionptr, unsigned int flags) +Func *Func::add(const char *name, GameFuncPtr gamefunctionptr) { Func *func = 0; Registry::iterator it = func_registry.find(name); if (it == func_registry.end()) { - func = new Func(name, (void *)gamefunctionptr, flags | Func::Game); + func = new Func(name, (void *)gamefunctionptr, Game); + func_registry[func->name()] = func; + //con_debug << "Function '" << name << "' registered." << std::endl; + } else { + con_warn << "Function '" << name << "' already registered!" << std::endl; + func = (*it).second; + } + return func; +} + +Func *Func::add(const char *name, TargetFuncPtr targetfunctionptr) +{ + Func *func = 0; + Registry::iterator it = func_registry.find(name); + if (it == func_registry.end()) { + func = new Func(name, (void *)targetfunctionptr, Game | Target); func_registry[func->name()] = func; //con_debug << "Function '" << name << "' registered." << std::endl; } else { @@ -145,5 +160,15 @@ void Func::exec(Player *player, std::string const &args) gamefunction(player, args); } +void Func::exec(Player *player, Entity *entity) +{ + if (!(flags() & (Game | Target))) + return; + + TargetFuncPtr targetfunction = (TargetFuncPtr) func_ptr; + targetfunction(player, entity); + +} + } // namespace core diff --git a/src/core/func.h b/src/core/func.h index 7c5635f..eacd47e 100644 --- a/src/core/func.h +++ b/src/core/func.h @@ -8,6 +8,7 @@ #define __INCLUDED_CORE_FUNC_H__ #include "core/player.h" +#include "core/entity.h" #include #include @@ -22,12 +23,15 @@ typedef void(* FuncPtr)(std::string const &args); /// fuction pointer for game functions typedef void(* GameFuncPtr)(Player *player, std::string const &args); +/// fuction pointer for target functions +typedef void(* TargetFuncPtr)(Player *player, Entity *entity); + /// a function pointer encapsulation class class Func { public: /// function flags - enum Flags {Game=1, Shared=2}; + enum Flags {Game=1, Shared=2, Target=4}; /// create a new function Func(char const * name, void *ptr, unsigned int flags = 0); @@ -56,16 +60,22 @@ public: /// execute the function if the Game flag is set void exec(Player *player, std::string const &args); + /// execute the function if the Target flag is set + void exec(Player *player, Entity *entity); + /* ---- Static functions for the Func registry -------------------- */ /// type definition typedef std::map Registry; /// add a function to the registry - static Func *add(const char *name, FuncPtr functionptr, unsigned int flags=0); + static Func *add(const char *name, FuncPtr functionptr, bool shared=false); /// add a game function to the registry and set the Game flag - static Func *add(const char *name, GameFuncPtr functionptr, unsigned int flags=0); + static Func *add(const char *name, GameFuncPtr functionptr); + + /// add a target function to the registry and set Game and Target flag + static Func *add(const char *name, TargetFuncPtr targetfunctionptr); /// remove a function from the registry static void remove(const char *name); diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc index 4da0be6..3268e38 100644 --- a/src/core/gameserver.cc +++ b/src/core/gameserver.cc @@ -178,11 +178,11 @@ GameServer::GameServer() : GameInterface() func = Func::add("revoke_rcon", func_grant_rcon); func->set_info("[player] revoke rcon rights"); */ - /* -- player functions --*/ - func = Func::add("time", func_time, Func::Shared); + /* -- shared functions --*/ + func = Func::add("time", func_time, true); func->set_info("get the server uptime and current server localtime"); - func = Func::add("who", func_who, Func::Shared); + func = Func::add("who", func_who, true); func->set_info("get a list of connected players"); if (!Cvar::sv_dedicated->value()) { @@ -489,8 +489,16 @@ void GameServer::exec(Player *player, std::string const & cmdline) args.assign(cmdline.substr(command.size()+1)); if ((function ->flags() & Func::Game) == Func::Game) { - function->exec(player, args); - return; + if ((function ->flags() & Func::Target) == Func::Target) { + unsigned int id = 0; + if ((cmdstream >> id)) { + Entity *entity = Entity::find(id); + if (entity) + function->exec(player, entity); + } + } else { + function->exec(player, args); + } } else if ((function->flags() & Func::Shared) == Func::Shared) { @@ -505,8 +513,8 @@ void GameServer::exec(Player *player, std::string const & cmdline) // disable rcon buffering console()->set_rcon(false); - return; } + return; } std::string message("Unknown command '"); diff --git a/src/core/parser.cc b/src/core/parser.cc index 99dc1d5..39eb073 100644 --- a/src/core/parser.cc +++ b/src/core/parser.cc @@ -43,7 +43,8 @@ bool Parser::got_entity_key(filesystem::IniFile &inifile, core::Entity *entity) } else if (inifile.got_key_string("name", strval)) { entity->set_name(strval); return true; - } else if (inifile.got_key_string("model", entity->entity_modelname)) { + } else if (inifile.got_key_string("model", strval)) { + entity->set_modelname(strval); return true; } else if (inifile.got_key_angle("direction", direction)) { entity->axis().change_direction(direction); -- cgit v1.2.3