233 lines
6.1 KiB
C
233 lines
6.1 KiB
C
/*
|
|
* static char *rcsid_c_new_c =
|
|
* "$Id: c_new.c 11578 2009-02-23 22:02:27Z lalo $";
|
|
*/
|
|
|
|
/*
|
|
CrossFire, A Multiplayer game for X-windows
|
|
|
|
Copyright (C) 2002-2006 Mark Wedel & Crossfire Development Team
|
|
Copyright (C) 1992 Frank Tore Johansen
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
The author can be reached via e-mail to crossfire-devel@real-time.com
|
|
*/
|
|
|
|
/**
|
|
* @file
|
|
* This file deals with administrative commands from the client.
|
|
*/
|
|
|
|
#include <global.h>
|
|
#include <commands.h>
|
|
#ifndef __CEXTRACT__
|
|
#include <sproto.h>
|
|
#endif
|
|
|
|
#ifndef tolower
|
|
/** Simple macro to convert a letter to lowercase. */
|
|
#define tolower(C) (((C) >= 'A' && (C) <= 'Z') ? (C)-'A'+'a' : (C))
|
|
#endif
|
|
|
|
/**
|
|
* Compare function for commands.
|
|
*
|
|
* @param a
|
|
* @param b
|
|
* commands to compare.
|
|
* @retval -1
|
|
* a is less then b.
|
|
* @retval 0
|
|
* a and b are equals.
|
|
* @retval 1
|
|
* a is greater than b.
|
|
*/
|
|
static int compare_A(const void *a, const void *b) {
|
|
return strcmp(((const command_array_struct *)a)->name,
|
|
((const command_array_struct *)b)->name);
|
|
}
|
|
|
|
/**
|
|
* Finds the specified command in the command array. Utility function.
|
|
*
|
|
* @param cmd
|
|
* command to find. Will be put to lowercase.
|
|
* @param commarray
|
|
* commands to search into.
|
|
* @param commsize
|
|
* length of commarray.
|
|
* @return
|
|
* matching command, NULL for no match.
|
|
*/
|
|
static command_array_struct *find_command_element(const char *cmd, command_array_struct *commarray, int commsize) {
|
|
command_array_struct *asp, dummy;
|
|
|
|
dummy.name = cmd;
|
|
asp = (command_array_struct *)bsearch((void *)&dummy,
|
|
(void *)commarray, commsize,
|
|
sizeof(command_array_struct),
|
|
compare_A);
|
|
return asp;
|
|
}
|
|
|
|
/**
|
|
* Player issued a command, let's handle it.
|
|
*
|
|
* This function is called from the new client/server code.
|
|
*
|
|
* @param pl
|
|
* player who is issuing the command
|
|
* @param command
|
|
* the actual command with its arguments.
|
|
* @return
|
|
* 0 if invalid command, else actual command's return value (which may be zero).
|
|
*/
|
|
int execute_newserver_command(object *pl, char *command) {
|
|
command_array_struct *csp;
|
|
char *cp, *low;
|
|
|
|
pl->contr->has_hit = 0;
|
|
|
|
/*
|
|
* remove trailing spaces from commant
|
|
*/
|
|
cp = command+strlen(command)-1;
|
|
while ((cp >= command) && (*cp == ' ')) {
|
|
*cp = '\0';
|
|
cp--;
|
|
}
|
|
cp = strchr(command, ' ');
|
|
if (cp) {
|
|
*(cp++) = '\0';
|
|
while (*cp == ' ')
|
|
cp++;
|
|
}
|
|
|
|
for (low = command; *low; low++)
|
|
*low = tolower(*low);
|
|
|
|
csp = find_plugin_command(command, pl);
|
|
if (!csp)
|
|
csp = find_command_element(command, Commands, CommandsSize);
|
|
if (!csp)
|
|
csp = find_command_element(command, CommunicationCommands,
|
|
CommunicationCommandSize);
|
|
if (!csp && QUERY_FLAG(pl, FLAG_WIZ))
|
|
csp = find_command_element(command, WizCommands, WizCommandsSize);
|
|
|
|
if (csp == NULL) {
|
|
draw_ext_info_format(NDI_UNIQUE, 0, pl,
|
|
MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
|
|
"'%s' is not a valid command.",
|
|
"'%s' is not a valid command.",
|
|
command);
|
|
return 0;
|
|
}
|
|
|
|
pl->speed_left -= csp->time;
|
|
|
|
/* A character time can never exceed his speed (which in many cases,
|
|
* if wearing armor, is less than one.) Thus, in most cases, if
|
|
* the command takes 1.0, the player's speed will be less than zero.
|
|
* it is only really an issue if time goes below -1
|
|
* Due to various reasons that are too long to go into here, we will
|
|
* actually still execute player even if his time is less than 0,
|
|
* but greater than -1. This is to improve the performance of the
|
|
* new client/server. In theory, it shouldn't make much difference.
|
|
*/
|
|
|
|
if (csp->time && pl->speed_left < -2.0) {
|
|
LOG(llevDebug, "execute_newclient_command: Player issued command that takes more time than he has left.\n");
|
|
}
|
|
return csp->func(pl, cp);
|
|
}
|
|
|
|
/**
|
|
* Player wants to start running.
|
|
*
|
|
* @param op
|
|
* player.
|
|
* @param params
|
|
* additional parameters.
|
|
* @return
|
|
* 0.
|
|
*/
|
|
int command_run(object *op, char *params) {
|
|
int dir;
|
|
|
|
dir = params ? atoi(params) : 0;
|
|
if (dir < 0 || dir >= 9) {
|
|
draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
|
|
"Can't run into a non adjacent square.", NULL);
|
|
return 0;
|
|
}
|
|
op->contr->run_on = 1;
|
|
return move_player(op, dir);
|
|
}
|
|
|
|
/**
|
|
* Player wants to stop running.
|
|
*
|
|
* @param op
|
|
* player.
|
|
* @param params
|
|
* ignored.
|
|
* @return
|
|
* 1.
|
|
*/
|
|
int command_run_stop(object *op, char *params) {
|
|
op->contr->run_on = 0;
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Player wants to start furing.
|
|
*
|
|
* @param op
|
|
* player.
|
|
* @param params
|
|
* additional parameters.
|
|
* @return
|
|
* 0.
|
|
*/
|
|
int command_fire(object *op, char *params) {
|
|
int dir;
|
|
|
|
dir = params ? atoi(params) : 0;
|
|
if (dir < 0 || dir >= 9) {
|
|
draw_ext_info(NDI_UNIQUE, 0, op, MSG_TYPE_COMMAND, MSG_TYPE_COMMAND_ERROR,
|
|
"Can't fire to a non adjacent square.", NULL);
|
|
return 0;
|
|
}
|
|
op->contr->fire_on = 1;
|
|
return move_player(op, dir);
|
|
}
|
|
|
|
/**
|
|
* Player wants to stop firing.
|
|
*
|
|
* @param op
|
|
* player.
|
|
* @param params
|
|
* ignored.
|
|
* @return
|
|
* 0.
|
|
*/
|
|
int command_fire_stop(object *op, char *params) {
|
|
op->contr->fire_on = 0;
|
|
return 1;
|
|
}
|