2 #include "CLIContext.hpp"
3 #include "commands.hpp"
5 #include "../io/TokenStreamReader.hpp"
6 #include "../world/Entity.hpp"
7 #include "../world/Player.hpp"
8 #include "../world/World.hpp"
12 #include <glm/gtx/io.hpp>
19 CLI::CLI(World &world)
22 AddCommand("as", new ImpersonateCommand);
23 AddCommand("tp", new TeleportCommand);
27 for (auto &entry : commands) {
32 void CLI::AddCommand(const string &name, Command *cmd) {
36 void CLI::Execute(CLIContext &ctx, const string &line) {
38 TokenStreamReader args(s);
39 if (!args.HasMore()) {
40 // ignore empty command line
43 if (args.Peek().type != Token::IDENTIFIER) {
44 ctx.Error("I don't understand");
48 args.ReadIdentifier(name);
49 auto entry = commands.find(name);
50 if (entry == commands.end()) {
51 ctx.Error(name + ": command not found");
55 entry->second->Execute(*this, ctx, args);
56 } catch (exception &e) {
57 ctx.Error(name + ": " + e.what());
59 ctx.Error(name + ": unknown execution error");
63 CLI::Command::~Command() {
68 CLIContext::CLIContext(Player *p, Entity *e)
72 , effective_entity(e) {
74 original_entity = effective_entity = &p->GetEntity();
78 std::string CLIContext::Name() const {
79 if (HasPlayer()) return GetPlayer().Name();
80 if (HasEntity()) return GetEntity().Name();
85 void ImpersonateCommand::Execute(CLI &cli, CLIContext &ctx, TokenStreamReader &args) {
86 if (!args.HasMore()) {
87 // no argument => reset
89 ctx.Broadcast(ctx.Name() + " returned to their own self");
92 // TODO: broadcast who (real player name) impersonates who
93 string old_name = ctx.Name();
94 string name(args.GetString());
96 Player *p = cli.GetWorld().FindPlayer(name);
99 ctx.SetEntity(p->GetEntity());
100 ctx.Broadcast(old_name + " now impersonating " + p->Name());
104 // not a player, try an entity
105 Entity *e = cli.GetWorld().FindEntity(name);
108 ctx.Broadcast(old_name + " now impersonating " + e->Name());
112 ctx.Error("no player or entity with name " + name);
116 void TeleportCommand::Execute(CLI &, CLIContext &ctx, TokenStreamReader &args) {
117 if (!ctx.HasEntity()) {
118 ctx.Error("teleport needs entity to operate on");
122 glm::vec3 pos(args.GetFloat(), args.GetFloat(), args.GetFloat());
123 EntityState state = ctx.GetEntity().GetState();
124 state.pos = ExactLocation(pos).Sanitize();
125 ctx.GetEntity().SetState(state);
128 msg << ctx.GetEntity().Name() << " teleported to " << pos;
129 ctx.Broadcast(msg.str());