2001-04-26 19:41:06 +02:00
|
|
|
|
/* vi: set ts=2:
|
|
|
|
|
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
|
|
|
|
| | Enno Rehling <enno@eressea-pbem.de>
|
|
|
|
|
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
2003-07-29 11:48:03 +02:00
|
|
|
|
| (c) 1998 - 2003 | Henning Peters <faroul@beyond.kn-bremen.de>
|
2001-04-26 19:41:06 +02:00
|
|
|
|
| | Ingo Wilken <Ingo.Wilken@informatik.uni-oldenburg.de>
|
|
|
|
|
+-------------------+ Stefan Reich <reich@halbling.de>
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
This program may not be used, modified or distributed
|
2001-04-26 19:41:06 +02:00
|
|
|
|
without prior permission by the authors of Eressea.
|
2001-05-11 22:19:22 +02:00
|
|
|
|
*/
|
|
|
|
|
|
2001-01-28 11:10:22 +01:00
|
|
|
|
#include <config.h>
|
|
|
|
|
#include <eressea.h>
|
|
|
|
|
#include "gmcmd.h"
|
2001-04-26 19:41:06 +02:00
|
|
|
|
#include "command.h"
|
2001-01-28 11:10:22 +01:00
|
|
|
|
|
2001-05-11 22:19:22 +02:00
|
|
|
|
/* misc includes */
|
2001-01-28 11:10:22 +01:00
|
|
|
|
#include <items/demonseye.h>
|
|
|
|
|
#include <attributes/key.h>
|
2001-05-11 22:19:22 +02:00
|
|
|
|
#include <triggers/gate.h>
|
2001-12-10 01:13:39 +01:00
|
|
|
|
#include <triggers/unguard.h>
|
2001-01-28 11:10:22 +01:00
|
|
|
|
|
|
|
|
|
/* kernel includes */
|
2001-05-11 22:19:22 +02:00
|
|
|
|
#include <building.h>
|
2002-03-02 16:26:45 +01:00
|
|
|
|
#include <reports.h>
|
2001-01-28 11:10:22 +01:00
|
|
|
|
#include <faction.h>
|
|
|
|
|
#include <item.h>
|
2001-09-05 21:40:40 +02:00
|
|
|
|
#include <message.h>
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#include <order.h>
|
2001-04-01 08:58:45 +02:00
|
|
|
|
#include <plane.h>
|
|
|
|
|
#include <region.h>
|
|
|
|
|
#include <terrain.h>
|
|
|
|
|
#include <unit.h>
|
2001-01-28 11:10:22 +01:00
|
|
|
|
|
|
|
|
|
/* util includes */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#include <util/attrib.h>
|
|
|
|
|
#include <util/base36.h>
|
|
|
|
|
#include <util/event.h>
|
|
|
|
|
#include <util/umlaut.h>
|
2001-01-28 11:10:22 +01:00
|
|
|
|
|
|
|
|
|
/* libc includes */
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2004-06-21 18:45:27 +02:00
|
|
|
|
#include <limits.h>
|
2001-01-28 11:10:22 +01:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
** at_permissions
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
write_permissions(const attrib * a, FILE * F)
|
|
|
|
|
{
|
|
|
|
|
a_write(F, (attrib*)a->data.v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2002-05-09 13:01:15 +02:00
|
|
|
|
read_permissions(attrib * at, FILE * F)
|
2001-01-28 11:10:22 +01:00
|
|
|
|
{
|
2002-05-09 13:01:15 +02:00
|
|
|
|
attrib ** p_a = (attrib**)&at->data.v;
|
2001-01-28 11:10:22 +01:00
|
|
|
|
a_read(F, p_a);
|
2002-05-09 13:01:15 +02:00
|
|
|
|
/* eliminate duplicates: */
|
|
|
|
|
while (*p_a) {
|
|
|
|
|
attrib * a = (*p_a)->next;
|
|
|
|
|
while (a) {
|
|
|
|
|
attrib * nexta = a->next;
|
|
|
|
|
if (a->type == (*p_a)->type && a->data.v==(*p_a)->data.v) {
|
|
|
|
|
static int print = 0;
|
|
|
|
|
a_remove((attrib**)&at->data.v, a);
|
|
|
|
|
if (!print) {
|
|
|
|
|
log_error(("duplicated entries in permission structure\n"));
|
|
|
|
|
print = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
a = nexta;
|
|
|
|
|
}
|
|
|
|
|
p_a = &(*p_a)->next;
|
|
|
|
|
}
|
2002-04-07 02:44:01 +02:00
|
|
|
|
return AT_READ_OK;
|
2001-01-28 11:10:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
struct attrib_type at_permissions = {
|
2001-01-28 11:10:22 +01:00
|
|
|
|
"GM:permissions",
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
write_permissions, read_permissions,
|
|
|
|
|
ATF_UNIQUE
|
|
|
|
|
};
|
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
attrib *
|
|
|
|
|
make_atpermissions(void)
|
|
|
|
|
{
|
|
|
|
|
return a_new(&at_permissions);
|
|
|
|
|
}
|
|
|
|
|
|
2001-01-28 11:10:22 +01:00
|
|
|
|
/**
|
|
|
|
|
** GM: CREATE <number> <itemtype>
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
write_gmcreate(const attrib * a, FILE * F)
|
|
|
|
|
{
|
2004-05-31 14:19:26 +02:00
|
|
|
|
const item_type * itype = (const item_type *)a->data.v;
|
|
|
|
|
assert(itype);
|
|
|
|
|
fprintf(F, "%s ", resourcename(itype->rtype, 0));
|
2001-01-28 11:10:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
read_gmcreate(attrib * a, FILE * F)
|
|
|
|
|
{
|
2004-05-31 14:19:26 +02:00
|
|
|
|
char zText[32];
|
|
|
|
|
const item_type ** p_itype = (const item_type **)&a->data.v;
|
|
|
|
|
fscanf(F, "%s", zText);
|
|
|
|
|
*p_itype = it_find(zText);
|
|
|
|
|
if (a->data.v==NULL) {
|
|
|
|
|
log_error(("unknown itemtype %s in gmcreate attribute\n", zText));
|
2003-12-14 11:10:30 +01:00
|
|
|
|
return AT_READ_FAIL;
|
2004-05-31 14:19:26 +02:00
|
|
|
|
}
|
|
|
|
|
return AT_READ_OK;
|
2001-01-28 11:10:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* at_gmcreate specifies that the owner can create items of a particular type */
|
2001-09-05 21:40:40 +02:00
|
|
|
|
attrib_type at_gmcreate = {
|
2001-01-28 11:10:22 +01:00
|
|
|
|
"GM:create",
|
|
|
|
|
NULL, NULL, NULL,
|
|
|
|
|
write_gmcreate, read_gmcreate
|
|
|
|
|
};
|
|
|
|
|
|
2001-02-10 20:24:05 +01:00
|
|
|
|
attrib *
|
2001-01-28 11:10:22 +01:00
|
|
|
|
make_atgmcreate(const struct item_type * itype)
|
|
|
|
|
{
|
|
|
|
|
attrib * a = a_new(&at_gmcreate);
|
|
|
|
|
a->data.v = (void*)itype;
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_create(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-01-28 11:10:22 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
int i;
|
2001-01-28 11:10:22 +01:00
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
2001-01-31 00:16:17 +01:00
|
|
|
|
if (permissions) permissions = (attrib*)permissions->data.v;
|
|
|
|
|
if (!permissions) return;
|
2001-01-28 11:10:22 +01:00
|
|
|
|
i = atoi(igetstrtoken(str));
|
|
|
|
|
|
|
|
|
|
if (i>0) {
|
2003-06-22 10:38:55 +02:00
|
|
|
|
const char * iname = getstrtoken();
|
2001-01-28 11:10:22 +01:00
|
|
|
|
const item_type * itype = finditemtype(iname, u->faction->locale);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (itype==NULL) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unbekannter Gegenstand.\n", 0);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
} else {
|
|
|
|
|
attrib * a = a_find(permissions, &at_gmcreate);
|
|
|
|
|
|
|
|
|
|
while (a && a->data.v!=(void*)itype) a=a->nexttype;
|
|
|
|
|
if (a) i_change(&u->items, itype, i);
|
2004-06-21 18:45:27 +02:00
|
|
|
|
else mistake(u, ord, "Diesen Gegenstand darf deine Partei nicht machen.\n", 0);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
2001-01-28 11:10:22 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-05 21:40:40 +02:00
|
|
|
|
static boolean
|
|
|
|
|
has_permission(const attrib * permissions, unsigned int key)
|
|
|
|
|
{
|
|
|
|
|
return (find_key((attrib*)permissions->data.v, key) ||
|
|
|
|
|
find_key((attrib*)permissions->data.v, atoi36("master")));
|
|
|
|
|
}
|
|
|
|
|
|
2001-05-11 22:19:22 +02:00
|
|
|
|
/**
|
|
|
|
|
** GM: GATE <id> <x> <y>
|
|
|
|
|
** requires: permission-key "gmgate"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_gate(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-05-11 22:19:22 +02:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
const struct plane * p = rplane(u->region);
|
|
|
|
|
int id = atoi36(igetstrtoken(str));
|
2001-05-11 22:19:22 +02:00
|
|
|
|
int x = rel_to_abs(p, u->faction, atoi(getstrtoken()), 0);
|
|
|
|
|
int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
|
|
|
|
|
region * r = findregion(x, y);
|
|
|
|
|
building * b = findbuilding(id);
|
|
|
|
|
if (b==NULL || r==NULL || p!=rplane(b->region) || p!=rplane(r)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Dieses Geb<65>ude kann die Einheit nicht umwandeln.\n", 0);
|
2001-05-11 22:19:22 +02:00
|
|
|
|
return;
|
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (permissions && has_permission(permissions, atoi36("gmgate"))) {
|
2001-12-10 01:13:39 +01:00
|
|
|
|
remove_triggers(&b->attribs, "timer", &tt_gate);
|
|
|
|
|
remove_triggers(&b->attribs, "create", &tt_unguard);
|
|
|
|
|
if (r!=b->region) {
|
|
|
|
|
add_trigger(&b->attribs, "timer", trigger_gate(b, r));
|
|
|
|
|
add_trigger(&b->attribs, "create", trigger_unguard(b));
|
|
|
|
|
fset(b, BLD_UNGUARDED);
|
|
|
|
|
}
|
2001-05-11 22:19:22 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2001-01-28 11:10:22 +01:00
|
|
|
|
/**
|
2002-02-23 12:30:41 +01:00
|
|
|
|
** GM: TERRAFORM <x> <y> <terrain>
|
2001-04-01 08:58:45 +02:00
|
|
|
|
** requires: permission-key "gmterf"
|
2001-01-28 11:10:22 +01:00
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_terraform(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-01-28 11:10:22 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
2001-04-01 08:58:45 +02:00
|
|
|
|
const struct plane * p = rplane(u->region);
|
|
|
|
|
int x = rel_to_abs(p, u->faction, atoi(igetstrtoken(str)), 0);
|
|
|
|
|
int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
|
|
|
|
|
const char * c = getstrtoken();
|
|
|
|
|
region * r = findregion(x, y);
|
2001-01-28 11:10:22 +01:00
|
|
|
|
terrain_t t;
|
2001-04-01 08:58:45 +02:00
|
|
|
|
if (r==NULL || p!=rplane(r)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Diese Region kann die Einheit nicht umwandeln.\n", 0);
|
2001-04-22 20:14:07 +02:00
|
|
|
|
return;
|
2001-04-01 08:58:45 +02:00
|
|
|
|
} else {
|
2001-01-28 11:10:22 +01:00
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmterf"))) return;
|
2001-01-28 11:10:22 +01:00
|
|
|
|
}
|
|
|
|
|
for (t=0;t!=MAXTERRAINS;++t) {
|
|
|
|
|
if (!strcasecmp(locale_string(u->faction->locale, terrain[t].name), c)) break;
|
|
|
|
|
}
|
2001-04-01 08:58:45 +02:00
|
|
|
|
if (t!=MAXTERRAINS) terraform(r, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
** GM: TELEPORT <unit> <x> <y>
|
|
|
|
|
** requires: permission-key "gmtele"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_teleport(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-04-01 08:58:45 +02:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
2001-04-01 08:58:45 +02:00
|
|
|
|
const struct plane * p = rplane(u->region);
|
|
|
|
|
unit * to = findunit(atoi36(igetstrtoken(str)));
|
|
|
|
|
int x = rel_to_abs(p, u->faction, atoi(getstrtoken()), 0);
|
|
|
|
|
int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
|
|
|
|
|
region * r = findregion(x, y);
|
|
|
|
|
|
|
|
|
|
if (r==NULL || p!=rplane(r)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "In diese Region kann die Einheit nicht teleportieren.\n", 0);
|
2001-04-26 19:41:06 +02:00
|
|
|
|
} else if (to==NULL) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Die Einheit wurde nicht gefunden.\n", 0);
|
2001-04-26 19:41:06 +02:00
|
|
|
|
} else if (rplane(to->region)!=rplane(r) && !ucontact(to, u)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Die Einheit hat uns nicht kontaktiert.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmtele"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
}
|
|
|
|
|
else move_unit(to, r, NULL);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-09-05 21:40:40 +02:00
|
|
|
|
/**
|
2002-02-23 12:30:41 +01:00
|
|
|
|
** GM: TELL PLANE <string>
|
|
|
|
|
** requires: permission-key "gmmsgr"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_messageplane(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2002-02-23 12:30:41 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
2002-02-23 12:30:41 +01:00
|
|
|
|
const struct plane * p = rplane(u->region);
|
2002-03-02 16:26:45 +01:00
|
|
|
|
const char * zmsg = igetstrtoken(str);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
if (p==NULL) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "In diese Ebene kann keine Nachricht gesandt werden.\n", 0);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmmsgr"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
}
|
|
|
|
|
else {
|
2002-03-02 16:26:45 +01:00
|
|
|
|
message * msg = msg_message("msg_event", "string", strdup(zmsg));
|
2002-02-23 12:30:41 +01:00
|
|
|
|
faction * f;
|
|
|
|
|
region * r;
|
|
|
|
|
for (f=factions;f;f=f->next) {
|
|
|
|
|
freset(f, FL_DH);
|
|
|
|
|
}
|
|
|
|
|
for (r=regions;r;r=r->next) {
|
|
|
|
|
unit * u;
|
|
|
|
|
if (rplane(r)!=p) continue;
|
|
|
|
|
for (u=r->units;u;u=u->next) if (!fval(u->faction, FL_DH)) {
|
|
|
|
|
f = u->faction;
|
|
|
|
|
fset(f, FL_DH);
|
2002-03-02 16:26:45 +01:00
|
|
|
|
add_message(&f->msgs, msg);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2002-03-02 16:26:45 +01:00
|
|
|
|
msg_release(msg);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_messagefaction(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2002-02-23 12:30:41 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
int n = atoi36(igetstrtoken(str));
|
|
|
|
|
faction * f = findfaction(n);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
const char * msg = getstrtoken();
|
|
|
|
|
plane * p = rplane(u->region);
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmmsgr"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (f!=NULL) {
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) if (rplane(r)==p) {
|
|
|
|
|
unit * u;
|
|
|
|
|
for (u=r->units;u;u=u->next) if (u->faction==f) {
|
|
|
|
|
add_message(&f->msgs, msg_message("msg_event", "string", msg));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "An diese Partei kann keine Nachricht gesandt werden.\n", 0);
|
2002-02-23 12:30:41 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
** GM: TELL REGION <x> <y> <string>
|
2001-09-05 21:40:40 +02:00
|
|
|
|
** requires: permission-key "gmmsgr"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_messageregion(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-09-05 21:40:40 +02:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
const struct plane * p = rplane(u->region);
|
|
|
|
|
int x = rel_to_abs(p, u->faction, atoi(igetstrtoken(str)), 0);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
int y = rel_to_abs(p, u->faction, atoi(getstrtoken()), 1);
|
|
|
|
|
const char * msg = getstrtoken();
|
|
|
|
|
region * r = findregion(x, y);
|
|
|
|
|
|
|
|
|
|
if (r==NULL || p!=rplane(r)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "In diese Region kann keine Nachricht gesandt werden.\n", 0);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmmsgr"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
add_message(&r->msgs, msg_message("msg_event", "string", msg));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-02-24 10:20:38 +01:00
|
|
|
|
/**
|
|
|
|
|
** GM: KILL UNIT <id> <string>
|
|
|
|
|
** requires: permission-key "gmkill"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_killunit(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2002-02-24 10:20:38 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
const struct plane * p = rplane(u->region);
|
|
|
|
|
unit * target = findunit(atoi36(igetstrtoken(str)));
|
2002-02-24 10:20:38 +01:00
|
|
|
|
const char * msg = getstrtoken();
|
|
|
|
|
region * r = target->region;
|
|
|
|
|
|
|
|
|
|
if (r==NULL || p!=rplane(r)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "In dieser Region kann niemand get<65>tet werden.\n", 0);
|
2002-02-24 10:20:38 +01:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmkill"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2002-02-24 10:20:38 +01:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char * zmsg = (char*)gc_add(strdup(msg));
|
|
|
|
|
scale_number(target, 0);
|
|
|
|
|
ADDMSG(&target->faction->msgs, msg_message("killedbygm",
|
|
|
|
|
"region unit string", r, target, zmsg));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
** GM: KILL FACTION <id> <string>
|
|
|
|
|
** requires: permission-key "gmmsgr"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_killfaction(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2002-02-24 10:20:38 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
int n = atoi36(igetstrtoken(str));
|
|
|
|
|
faction * f = findfaction(n);
|
2002-02-24 10:20:38 +01:00
|
|
|
|
const char * msg = getstrtoken();
|
|
|
|
|
plane * p = rplane(u->region);
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmkill"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2002-02-24 10:20:38 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (f!=NULL) {
|
|
|
|
|
region * r;
|
|
|
|
|
for (r=regions;r;r=r->next) if (rplane(r)==p) {
|
|
|
|
|
unit * target;
|
|
|
|
|
for (target=r->units;target;target=target->next) {
|
|
|
|
|
if (target->faction==f) {
|
|
|
|
|
char * zmsg = (char*)gc_add(strdup(msg));
|
|
|
|
|
scale_number(target, 0);
|
|
|
|
|
ADDMSG(&target->faction->msgs, msg_message("killedbygm",
|
|
|
|
|
"region unit string", r, target, zmsg));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Aus dieser Partei kann niemand gel<65>scht werden.\n", 0);
|
2002-02-24 10:20:38 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
/**
|
|
|
|
|
** GM: TELL <unit> <string>
|
|
|
|
|
** requires: permission-key "gmmsgr"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_messageunit(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-12-10 01:13:39 +01:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
const struct plane * p = rplane(u->region);
|
|
|
|
|
unit * target = findunit(atoi36(igetstrtoken(str)));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
const char * msg = getstrtoken();
|
2002-03-12 20:36:59 +01:00
|
|
|
|
region * r;
|
|
|
|
|
|
|
|
|
|
if (target == NULL) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
cmistake(u, ord, 63, MSG_EVENT);
|
2002-03-12 20:36:59 +01:00
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r = target->region;
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
if (r==NULL || p!=rplane(r)) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "In diese Region kann keine Nachricht gesandt werden.\n", 0);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmmsgu"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2001-12-10 01:13:39 +01:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char * m = (char*)gc_add(strdup(msg));
|
|
|
|
|
add_message(&target->faction->msgs,
|
|
|
|
|
msg_message("unitmessage", "region unit string", r, u, m));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
/**
|
|
|
|
|
** GM: GIVE <unit> <int> <itemtype>
|
|
|
|
|
** requires: permission-key "gmgive"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_give(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-04-01 08:58:45 +02:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
unit * to = findunit(atoi36(igetstrtoken(str)));
|
|
|
|
|
int num = atoi(getstrtoken());
|
2001-04-01 08:58:45 +02:00
|
|
|
|
const item_type * itype = finditemtype(getstrtoken(), u->faction->locale);
|
|
|
|
|
|
|
|
|
|
if (to==NULL || rplane(to->region) != rplane(u->region)) {
|
|
|
|
|
/* unknown or in another plane */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Die Einheit wurde nicht gefunden.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
} else if (itype==NULL || i_get(u->items, itype)==0) {
|
|
|
|
|
/* unknown or not enough */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "So einen Gegenstand hat die Einheit nicht.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmgive"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
int i = i_get(u->items, itype);
|
|
|
|
|
if (i<num) num=i;
|
|
|
|
|
if (num) {
|
|
|
|
|
i_change(&u->items, itype, -num);
|
|
|
|
|
i_change(&to->items, itype, num);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
/**
|
|
|
|
|
** GM: TAKE <unit> <int> <itemtype>
|
|
|
|
|
** requires: permission-key "gmtake"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_take(const tnode * tnext, const char * str, void * data, struct order * ord)
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
unit * to = findunit(atoi36(igetstrtoken(str)));
|
|
|
|
|
int num = atoi(getstrtoken());
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
const item_type * itype = finditemtype(getstrtoken(), u->faction->locale);
|
|
|
|
|
|
|
|
|
|
if (to==NULL || rplane(to->region) != rplane(u->region)) {
|
|
|
|
|
/* unknown or in another plane */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Die Einheit wurde nicht gefunden.\n", 0);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
} else if (itype==NULL || i_get(to->items, itype)==0) {
|
|
|
|
|
/* unknown or not enough */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "So einen Gegenstand hat die Einheit nicht.\n", 0);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmtake"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
- Neue Messages fertig
Messages werden jetzt in einem anderen Meta-Format (message* of
message_type*) gespeichert, das man in beliebige Formate (CR oder NR)
rendern kann. crmessage.c und nrmessage.c sind die render-engines dafür.
Die Messagetypen werden in res/{de,en}/messages.xml gesammelt, ultimativ
kann das aber durchaus eine einzelne Datei sein. Die ist derzeit nicht
wirklich xml (Umlaute drin, keine Definitionsdatei), aber gut lesbar.
- make_message
Diese Funktion ersetzt new_message, und ist etwas einfacher in der Syntax:
make_message("dumb_mistake", "unit region command", u, r, cmd) erzeugt
eine neue Nachricht, die dann einfach mit add_message wie bisher an die
Nachrichtenliste gehängt werden kann.
TODO: Messages könnte man durchaus reference-counten, und in mehrere Listen
einfügen, solang sie a) mehrfachverwendet (Kampf!) und b) vom Betrachter
unabhängig sind. Das spart einigen Speicher.
- CR Version erhöht.
Weil die MESSAGETYPES Blocks anders sind als früher
- OFFENSIVE_DELAY
Verbietet Einheiten, deren Partei eine Reigon niht bewachen, den
Angriff in der Region, wenn sie sich in der Runde zuvor bewegt haben.
Status der letzten Runde wird in neuem Attribut at_moved gespeichert.
- SHORT_ATTACKS
ein define, das angibt ob Kämpfen grundsätzlich keine lange Aktion ist.
- XML Parser
xml.[hc] enthält einen XML-Parser, dem man ein plugin mit callbacks
übergibt, die nach dem Parsen eines tokens aufgerufen werden.
2001-04-12 19:21:57 +02:00
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
int i = i_get(to->items, itype);
|
|
|
|
|
if (i<num) num=i;
|
|
|
|
|
if (num) {
|
|
|
|
|
i_change(&to->items, itype, -num);
|
|
|
|
|
i_change(&u->items, itype, num);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
/**
|
|
|
|
|
** GM: SKILL <unit> <skill> <tage>
|
|
|
|
|
** requires: permission-key "gmskil"
|
|
|
|
|
**/
|
|
|
|
|
static void
|
2004-06-21 18:45:27 +02:00
|
|
|
|
gm_skill(const tnode * tnext, const char * str, void * data, struct order * ord)
|
2001-04-01 08:58:45 +02:00
|
|
|
|
{
|
2004-06-21 18:45:27 +02:00
|
|
|
|
unit * u = (unit*)data;
|
|
|
|
|
unit * to = findunit(atoi36(igetstrtoken(str)));
|
|
|
|
|
skill_t skill = findskill(getstrtoken(), u->faction->locale);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
int num = atoi(getstrtoken());
|
2001-04-22 20:14:07 +02:00
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
if (to==NULL || rplane(to->region) != rplane(u->region)) {
|
|
|
|
|
/* unknown or in another plane */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Die Einheit wurde nicht gefunden.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
} else if (skill==NOSKILL || skill==SK_MAGIC || skill==SK_ALCHEMY) {
|
|
|
|
|
/* unknown or not enough */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Dieses Talent ist unbekannt, oder kann nicht erh<72>ht werden.\n", 0);
|
2002-09-02 22:36:12 +02:00
|
|
|
|
} else if (num<0 || num>30) {
|
2001-04-01 08:58:45 +02:00
|
|
|
|
/* sanity check failed */
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Der gew<65>hlte Wert ist nicht zugelassen.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
} else {
|
|
|
|
|
/* checking permissions */
|
|
|
|
|
attrib * permissions = a_find(u->faction->attribs, &at_permissions);
|
2001-09-05 21:40:40 +02:00
|
|
|
|
if (!permissions || !has_permission(permissions, atoi36("gmskil"))) {
|
2004-06-21 18:45:27 +02:00
|
|
|
|
mistake(u, ord, "Unzureichende Rechte f<>r diesen Befehl.\n", 0);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
}
|
|
|
|
|
else {
|
2002-02-10 14:23:30 +01:00
|
|
|
|
set_level(to, skill, num);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2001-01-28 11:10:22 +01:00
|
|
|
|
}
|
|
|
|
|
|
2001-04-26 19:41:06 +02:00
|
|
|
|
static tnode g_keys;
|
2002-02-23 12:30:41 +01:00
|
|
|
|
static tnode g_root;
|
|
|
|
|
static tnode g_tell;
|
2002-02-24 10:20:38 +01:00
|
|
|
|
static tnode g_kill;
|
2001-04-26 19:41:06 +02:00
|
|
|
|
|
2001-01-28 11:10:22 +01:00
|
|
|
|
void
|
|
|
|
|
init_gmcmd(void)
|
|
|
|
|
{
|
|
|
|
|
at_register(&at_gmcreate);
|
|
|
|
|
at_register(&at_permissions);
|
2002-09-02 22:36:12 +02:00
|
|
|
|
add_command(&g_root, &g_keys, "gm", NULL);
|
|
|
|
|
add_command(&g_keys, NULL, "terraform", &gm_terraform);
|
|
|
|
|
add_command(&g_keys, NULL, "create", &gm_create);
|
|
|
|
|
add_command(&g_keys, NULL, "gate", &gm_gate);
|
|
|
|
|
add_command(&g_keys, NULL, "give", &gm_give);
|
|
|
|
|
add_command(&g_keys, NULL, "take", &gm_take);
|
|
|
|
|
add_command(&g_keys, NULL, "teleport", &gm_teleport);
|
|
|
|
|
add_command(&g_keys, NULL, "skill", &gm_skill);
|
|
|
|
|
add_command(&g_keys, &g_tell, "tell", NULL);
|
|
|
|
|
add_command(&g_tell, NULL, "region", &gm_messageregion);
|
|
|
|
|
add_command(&g_tell, NULL, "unit", &gm_messageunit);
|
|
|
|
|
add_command(&g_tell, NULL, "plane", &gm_messageplane);
|
|
|
|
|
add_command(&g_tell, NULL, "faction", &gm_messagefaction);
|
|
|
|
|
add_command(&g_keys, &g_kill, "kill", NULL);
|
|
|
|
|
add_command(&g_kill, NULL, "unit", &gm_killunit);
|
|
|
|
|
add_command(&g_kill, NULL, "faction", &gm_killfaction);
|
2001-01-28 11:10:22 +01:00
|
|
|
|
}
|
2001-01-30 21:02:06 +01:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* execute gm-commands for all units in the game
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
gmcommands(void)
|
|
|
|
|
{
|
|
|
|
|
region ** rp = ®ions;
|
2004-06-21 18:45:27 +02:00
|
|
|
|
while (*rp) {
|
|
|
|
|
region * r = *rp;
|
|
|
|
|
unit **up = &r->units;
|
|
|
|
|
while (*up) {
|
|
|
|
|
unit * u = *up;
|
|
|
|
|
struct order * ord;
|
|
|
|
|
for (ord = u->orders; ord; ord = ord->next) {
|
|
|
|
|
if (get_keyword(ord) == K_GM) {
|
|
|
|
|
do_command(&g_root, u, ord);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (u==*up) up = &u->next;
|
|
|
|
|
}
|
|
|
|
|
if (*rp==r) rp = &r->next;
|
|
|
|
|
}
|
2001-01-30 21:02:06 +01:00
|
|
|
|
}
|
2001-04-01 08:58:45 +02:00
|
|
|
|
|
|
|
|
|
#define EXTENSION 10000
|
|
|
|
|
|
|
|
|
|
faction *
|
|
|
|
|
gm_addquest(const char * email, const char * name, int radius, unsigned int flags)
|
|
|
|
|
{
|
|
|
|
|
plane * p;
|
|
|
|
|
attrib * a;
|
|
|
|
|
unit * u;
|
2002-03-02 16:26:45 +01:00
|
|
|
|
watcher * w = calloc(sizeof(watcher), 1);
|
2001-04-01 08:58:45 +02:00
|
|
|
|
region * center;
|
|
|
|
|
boolean invalid = false;
|
|
|
|
|
int minx, miny, maxx, maxy, cx, cy;
|
|
|
|
|
int x, y, i;
|
|
|
|
|
faction * f = calloc(1, sizeof(faction));
|
|
|
|
|
|
|
|
|
|
/* GM faction */
|
|
|
|
|
a_add(&f->attribs, make_key(atoi36("quest")));
|
|
|
|
|
f->banner = strdup("Questenpartei");
|
|
|
|
|
f->passw = strdup(itoa36(rand()));
|
2002-03-03 13:53:05 +01:00
|
|
|
|
f->override = strdup(itoa36(rand()));
|
|
|
|
|
f->override = strdup(itoa36(rand()));
|
2001-04-01 08:58:45 +02:00
|
|
|
|
f->email = strdup(email);
|
|
|
|
|
f->name = strdup("Questenpartei");
|
2001-12-10 01:13:39 +01:00
|
|
|
|
f->race = new_race[RC_TEMPLATE];
|
2001-04-01 08:58:45 +02:00
|
|
|
|
f->age = 0;
|
|
|
|
|
f->lastorders = turn;
|
|
|
|
|
f->alive = true;
|
|
|
|
|
f->locale = find_locale("de");
|
|
|
|
|
f->options = want(O_COMPRESS) | want(O_REPORT) | want(O_COMPUTER) | want(O_ADRESSEN);
|
|
|
|
|
{
|
|
|
|
|
faction * xist;
|
|
|
|
|
int i = atoi36("gm00")-1;
|
|
|
|
|
do {
|
|
|
|
|
xist = findfaction(++i);
|
|
|
|
|
} while (xist);
|
2001-04-22 20:14:07 +02:00
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
f->no = i;
|
|
|
|
|
addlist(&factions, f);
|
|
|
|
|
}
|
2001-04-22 20:14:07 +02:00
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
/* GM playfield */
|
|
|
|
|
do {
|
|
|
|
|
minx = (rand() % (2*EXTENSION)) - EXTENSION;
|
|
|
|
|
miny = (rand() % (2*EXTENSION)) - EXTENSION;
|
|
|
|
|
for (x=0;!invalid && x<=radius*2;++x) {
|
|
|
|
|
for (y=0;!invalid && y<=radius*2;++y) {
|
|
|
|
|
region * r = findregion(minx+x, miny+y);
|
|
|
|
|
if (r) invalid = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (invalid);
|
|
|
|
|
maxx = minx+2*radius; cx = minx+radius;
|
|
|
|
|
maxy = miny+2*radius; cy = miny+radius;
|
|
|
|
|
p = create_new_plane(rand(), name, minx, maxx, miny, maxy, flags);
|
|
|
|
|
center = new_region(cx, cy);
|
|
|
|
|
for (x=0;x<=2*radius;++x) {
|
|
|
|
|
int y;
|
|
|
|
|
for (y=0;y<=2*radius;++y) {
|
|
|
|
|
region * r = findregion(minx+x, miny+y);
|
|
|
|
|
if (!r) r = new_region(minx+x, miny+y);
|
|
|
|
|
freset(r, RF_ENCOUNTER);
|
|
|
|
|
r->planep = p;
|
|
|
|
|
if (distance(r, center)==radius) {
|
|
|
|
|
terraform(r, T_FIREWALL);
|
|
|
|
|
} else if (r==center) {
|
|
|
|
|
terraform(r, T_PLAIN);
|
|
|
|
|
} else {
|
|
|
|
|
terraform(r, T_OCEAN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-03-02 16:26:45 +01:00
|
|
|
|
/* watcher: */
|
|
|
|
|
w->faction = f;
|
|
|
|
|
w->mode = see_unit;
|
|
|
|
|
w->next = p->watchers;
|
|
|
|
|
p->watchers = w;
|
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
/* generic permissions */
|
|
|
|
|
a = a_add(&f->attribs, a_new(&at_permissions));
|
|
|
|
|
|
2002-03-02 20:26:39 +01:00
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmterf"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmtele"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmgive"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmskil"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmtake"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmmsgr"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmmsgu"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmgate"));
|
2001-04-22 20:14:07 +02:00
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
a_add((attrib**)&a->data.v, make_atgmcreate(resource2item(r_silver)));
|
|
|
|
|
|
|
|
|
|
for (i=0;i<=I_INCENSE;++i) {
|
|
|
|
|
a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i]));
|
|
|
|
|
}
|
2001-09-05 21:40:40 +02:00
|
|
|
|
for (i=I_GREATSWORD;i!=I_KEKS;++i) {
|
|
|
|
|
a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i]));
|
|
|
|
|
}
|
2001-04-22 20:14:07 +02:00
|
|
|
|
|
2001-04-01 08:58:45 +02:00
|
|
|
|
/* one initial unit */
|
2001-12-10 01:13:39 +01:00
|
|
|
|
u = createunit(center, f, 1, new_race[RC_TEMPLATE]);
|
|
|
|
|
u->irace = new_race[RC_GNOME];
|
2001-04-01 08:58:45 +02:00
|
|
|
|
u->number = 1;
|
|
|
|
|
set_string(&u->name, "Questenmeister");
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
2001-12-10 01:13:39 +01:00
|
|
|
|
faction *
|
|
|
|
|
gm_addfaction(const char * email, plane * p, region * r)
|
|
|
|
|
{
|
|
|
|
|
attrib * a;
|
|
|
|
|
unit * u;
|
|
|
|
|
int i;
|
|
|
|
|
faction * f = calloc(1, sizeof(faction));
|
|
|
|
|
|
|
|
|
|
assert(p!=NULL);
|
|
|
|
|
|
|
|
|
|
/* GM faction */
|
2002-03-02 20:26:39 +01:00
|
|
|
|
add_key(&f->attribs, atoi36("quest"));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
f->banner = strdup("Questenpartei");
|
|
|
|
|
f->passw = strdup(itoa36(rand()));
|
|
|
|
|
f->email = strdup(email);
|
|
|
|
|
f->name = strdup("Questenpartei");
|
|
|
|
|
f->race = new_race[RC_TEMPLATE];
|
|
|
|
|
f->age = 0;
|
|
|
|
|
f->lastorders = turn;
|
|
|
|
|
f->alive = true;
|
|
|
|
|
f->locale = find_locale("de");
|
|
|
|
|
f->options = want(O_COMPRESS) | want(O_REPORT) | want(O_COMPUTER) | want(O_ADRESSEN);
|
|
|
|
|
{
|
|
|
|
|
faction * xist;
|
|
|
|
|
int i = atoi36("gm00")-1;
|
|
|
|
|
do {
|
|
|
|
|
xist = findfaction(++i);
|
|
|
|
|
} while (xist);
|
|
|
|
|
|
|
|
|
|
f->no = i;
|
|
|
|
|
addlist(&factions, f);
|
|
|
|
|
}
|
|
|
|
|
/* generic permissions */
|
|
|
|
|
a = a_add(&f->attribs, a_new(&at_permissions));
|
|
|
|
|
|
2002-03-02 20:26:39 +01:00
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmterf"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmtele"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmgive"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmskil"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmtake"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmmsgr"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmmsgu"));
|
|
|
|
|
add_key((attrib**)&a->data.v, atoi36("gmgate"));
|
2001-12-10 01:13:39 +01:00
|
|
|
|
|
|
|
|
|
a_add((attrib**)&a->data.v, make_atgmcreate(resource2item(r_silver)));
|
|
|
|
|
|
|
|
|
|
for (i=0;i<=I_INCENSE;++i) {
|
|
|
|
|
a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i]));
|
|
|
|
|
}
|
|
|
|
|
for (i=I_GREATSWORD;i!=I_KEKS;++i) {
|
|
|
|
|
a_add((attrib**)&a->data.v, make_atgmcreate(olditemtype[i]));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* one initial unit */
|
|
|
|
|
u = createunit(r, f, 1, new_race[RC_TEMPLATE]);
|
|
|
|
|
u->irace = new_race[RC_GNOME];
|
|
|
|
|
u->number = 1;
|
|
|
|
|
set_string(&u->name, "Questenmeister");
|
|
|
|
|
|
|
|
|
|
return f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
plane *
|
|
|
|
|
gm_addplane(int radius, unsigned int flags, const char * name)
|
|
|
|
|
{
|
|
|
|
|
region * center;
|
|
|
|
|
plane * p;
|
|
|
|
|
boolean invalid = false;
|
|
|
|
|
int minx, miny, maxx, maxy, cx, cy;
|
|
|
|
|
int x, y;
|
|
|
|
|
|
|
|
|
|
/* GM playfield */
|
|
|
|
|
do {
|
|
|
|
|
minx = (rand() % (2*EXTENSION)) - EXTENSION;
|
|
|
|
|
miny = (rand() % (2*EXTENSION)) - EXTENSION;
|
|
|
|
|
for (x=0;!invalid && x<=radius*2;++x) {
|
|
|
|
|
for (y=0;!invalid && y<=radius*2;++y) {
|
|
|
|
|
region * r = findregion(minx+x, miny+y);
|
|
|
|
|
if (r) invalid = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} while (invalid);
|
|
|
|
|
maxx = minx+2*radius; cx = minx+radius;
|
|
|
|
|
maxy = miny+2*radius; cy = miny+radius;
|
|
|
|
|
p = create_new_plane(rand(), name, minx, maxx, miny, maxy, flags);
|
|
|
|
|
center = new_region(cx, cy);
|
|
|
|
|
for (x=0;x<=2*radius;++x) {
|
|
|
|
|
int y;
|
|
|
|
|
for (y=0;y<=2*radius;++y) {
|
|
|
|
|
region * r = findregion(minx+x, miny+y);
|
|
|
|
|
if (!r) r = new_region(minx+x, miny+y);
|
|
|
|
|
freset(r, RF_ENCOUNTER);
|
|
|
|
|
r->planep = p;
|
|
|
|
|
if (distance(r, center)==radius) {
|
|
|
|
|
terraform(r, T_FIREWALL);
|
|
|
|
|
} else if (r==center) {
|
|
|
|
|
terraform(r, T_PLAIN);
|
|
|
|
|
} else {
|
|
|
|
|
terraform(r, T_OCEAN);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return p;
|
|
|
|
|
}
|