Crossfire Server, Trunk  R21466
c_new.c
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
19 #include "global.h"
20 
21 #include <stdlib.h>
22 #include <string.h>
23 #include <ctype.h>
24 
25 #include "commands.h"
26 #include "sproto.h"
27 
28 #ifndef tolower
29 
30 #define tolower(C) (((C) >= 'A' && (C) <= 'Z') ? (C)-'A'+'a' : (C))
31 #endif
32 
46 static int compare_A(const void *a, const void *b) {
47  return strcmp(((const command_array_struct *)a)->name,
48  ((const command_array_struct *)b)->name);
49 }
50 
63 static command_array_struct *find_command_element(const char *cmd, command_array_struct *commarray, int commsize) {
64  command_array_struct *asp, dummy;
65 
66  dummy.name = cmd;
67  asp = (command_array_struct *)bsearch((void *)&dummy,
68  (void *)commarray, commsize,
69  sizeof(command_array_struct),
70  compare_A);
71  return asp;
72 }
73 
84 void execute_newserver_command(object *pl, char *command) {
85  command_array_struct *csp, sent;
86  char *cp, *low;
87 
88  pl->contr->has_hit = 0;
89 
90  /*
91  * remove trailing spaces from commant
92  */
93  cp = command+strlen(command)-1;
94  while ((cp >= command) && (*cp == ' ')) {
95  *cp = '\0';
96  cp--;
97  }
98  cp = strchr(command, ' ');
99  if (cp) {
100  *(cp++) = '\0';
101  while (*cp == ' ')
102  cp++;
103  } else {
104  cp = strchr(command, '\0');
105  }
106 
107  for (low = command; *low; low++)
108  *low = tolower(*low);
109 
110  csp = find_plugin_command(command, &sent);
111  if (!csp)
112  csp = find_command_element(command, Commands, CommandsSize);
113  if (!csp)
116  if (!csp && QUERY_FLAG(pl, FLAG_WIZ))
118 
119  if (csp == NULL) {
122  "'%s' is not a valid command.",
123  command);
124  return;
125  }
126 
127  pl->speed_left -= csp->time;
128 
129  /* A character time can never exceed his speed (which in many cases,
130  * if wearing armor, is less than one.) Thus, in most cases, if
131  * the command takes 1.0, the player's speed will be less than zero.
132  * it is only really an issue if time goes below -1
133  * Due to various reasons that are too long to go into here, we will
134  * actually still execute player even if his time is less than 0,
135  * but greater than -1. This is to improve the performance of the
136  * new client/server. In theory, it shouldn't make much difference.
137  */
138 
139  if (csp->time && pl->speed_left < -2.0) {
140  LOG(llevDebug, "execute_newclient_command: Player issued command that takes more time than he has left.\n");
141  }
142  csp->func(pl, cp);
143 }
144 
153 void command_run(object *op, const char *params) {
154  int dir;
155 
156  dir = atoi(params);
157  if (dir < 0 || dir >= 9) {
159  "Can't run into a non adjacent square.");
160  return;
161  }
162  op->contr->run_on = 1;
163  move_player(op, dir);
164 }
165 
176 void command_run_stop(object *op, const char *params) {
177  op->contr->run_on = 0;
178 }
179 
188 void command_fire(object *op, const char *params) {
189  int dir;
190 
191  dir = atoi(params);
192  if (dir < 0 || dir >= 9) {
194  "Can't fire to a non adjacent square.");
195  return;
196  }
197  op->contr->fire_on = 1;
198  move_player(op, dir);
199 }
200 
209 void command_fire_stop(object *op, const char *params) {
210  op->contr->fire_on = 0;
211 }
212 
221 void command_face(object *op, const char *params) {
222  int dir;
223 
224  if ( !isdigit(*params) ) {
225  if ( strcmp(params,"stay") == 0 || strcmp(params,"down") == 0 ) dir=0;
226  else if ( strcmp(params,"north") == 0 || strcmp(params,"n") == 0 ) dir=1;
227  else if ( strcmp(params,"northeast") == 0 || strcmp(params,"ne") == 0 ) dir=2;
228  else if ( strcmp(params,"east") == 0 || strcmp(params,"e") == 0 ) dir=3;
229  else if ( strcmp(params,"southeast") == 0 || strcmp(params,"se") == 0 ) dir=4;
230  else if ( strcmp(params,"south") == 0 || strcmp(params,"s") == 0 ) dir=5;
231  else if ( strcmp(params,"southwest") == 0 || strcmp(params,"sw") == 0 ) dir=6;
232  else if ( strcmp(params,"west") == 0 || strcmp(params,"w") == 0 ) dir=7;
233  else if ( strcmp(params,"northwest") == 0 || strcmp(params,"nw") == 0 ) dir=8;
234  else {
236  "Unknown direction to face: %s",params);
237  return;
238  }
239  }
240  else dir = atoi(params);
241  if (dir < 0 || dir >= 9) {
243  "Can't face to a non adjacent square.");
244  return;
245  }
246  face_player(op, dir);
247 }
void draw_ext_info_format(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *format,...)
Definition: main.c:316
Definition: player.h:92
command_array_struct * find_plugin_command(const char *cmd, command_array_struct *command)
Definition: plugins.c:4736
command_array_struct Commands[]
Definition: commands.c:36
int move_player(object *op, int dir)
Definition: player.c:3014
const int WizCommandsSize
Definition: commands.c:268
uint32_t run_on
Definition: player.h:128
void draw_ext_info(int flags, int pri, const object *pl, uint8_t type, uint8_t subtype, const char *message)
Definition: main.c:311
const int CommunicationCommandSize
Definition: commands.c:201
#define MSG_TYPE_COMMAND
Definition: newclient.h:379
float speed_left
Definition: object.h:329
#define MSG_TYPE_COMMAND_ERROR
Definition: newclient.h:509
static int compare_A(const void *a, const void *b)
Definition: c_new.c:46
void command_face(object *op, const char *params)
Definition: c_new.c:221
void command_run(object *op, const char *params)
Definition: c_new.c:153
void command_run_stop(object *op, const char *params)
Definition: c_new.c:176
uint32_t has_hit
Definition: player.h:129
struct pl * contr
Definition: object.h:276
const char * name
Definition: commands.h:38
#define QUERY_FLAG(xyz, p)
Definition: define.h:225
#define FLAG_WIZ
Definition: define.h:231
void execute_newserver_command(object *pl, char *command)
Definition: c_new.c:84
command_array_struct WizCommands[]
Definition: commands.c:204
#define tolower(C)
Definition: c_new.c:30
void command_fire(object *op, const char *params)
Definition: c_new.c:188
command_function func
Definition: commands.h:39
uint32_t fire_on
Definition: player.h:127
const int CommandsSize
Definition: commands.c:128
command_array_struct CommunicationCommands[]
Definition: commands.c:131
#define NDI_UNIQUE
Definition: newclient.h:245
void LOG(LogLevel logLevel, const char *format,...)
Definition: logger.c:51
static command_array_struct * find_command_element(const char *cmd, command_array_struct *commarray, int commsize)
Definition: c_new.c:63
void command_fire_stop(object *op, const char *params)
Definition: c_new.c:209
int face_player(object *op, int dir)
Definition: player.c:3093