forked from github/server
Merge pull request #254 from badgerman/develop
static analysis bugfixes
This commit is contained in:
commit
f86314c55a
|
@ -2,10 +2,12 @@ language: c
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
- clang
|
- clang
|
||||||
script: s/travis-build
|
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get update -qq
|
- sudo apt-get update -qq
|
||||||
- sudo apt-get install -qq zlib1g-dev libtolua-dev liblua5.1-dev libncurses5-dev libsqlite3-dev libxml2-dev valgrind
|
install:
|
||||||
|
- sudo apt-get install -qq zlib1g-dev libtolua-dev liblua5.1-dev libncurses5-dev libsqlite3-dev libxml2-dev valgrind clang
|
||||||
|
script:
|
||||||
|
- s/travis-build
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
- osx
|
||||||
|
|
|
@ -4,9 +4,8 @@ set -e
|
||||||
ROOT=`pwd`
|
ROOT=`pwd`
|
||||||
SUPP=../share/ubuntu-12_04.supp
|
SUPP=../share/ubuntu-12_04.supp
|
||||||
MACHINE=`uname -m`
|
MACHINE=`uname -m`
|
||||||
|
[ -z "$CC" ] && [ ! -z `which clang` ] && CC="clang"
|
||||||
[ -z "$CC" ] && [ ! -z `which gcc` ] && CC="gcc"
|
[ -z "$CC" ] && [ ! -z `which gcc` ] && CC="gcc"
|
||||||
[ -z "$CC" ] && [ ! -z `which tcc` ] && CC="tcc"
|
|
||||||
[ -z "$CC" ] && [ ! -z `which cc` ] && CC="cc"
|
|
||||||
BUILD="$ROOT/build-$MACHINE-$CC-Debug"
|
BUILD="$ROOT/build-$MACHINE-$CC-Debug"
|
||||||
|
|
||||||
inifile() {
|
inifile() {
|
||||||
|
@ -20,7 +19,7 @@ fi
|
||||||
build() {
|
build() {
|
||||||
cd $BUILD
|
cd $BUILD
|
||||||
cmake -DCMAKE_MODULE_PATH=$ROOT/cmake/Modules -DCMAKE_BUILD_TYPE=Debug ..
|
cmake -DCMAKE_MODULE_PATH=$ROOT/cmake/Modules -DCMAKE_BUILD_TYPE=Debug ..
|
||||||
make
|
scan-build make
|
||||||
}
|
}
|
||||||
|
|
||||||
test_valgrind_report () {
|
test_valgrind_report () {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
+-------------------+ Enno Rehling <enno@eressea.de>
|
+-------------------+ Enno Rehling <enno@eressea.de>
|
||||||
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
|
| Eressea PBEM host | Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
|
| (c) 1998 - 2008 | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||||
|
@ -184,9 +184,9 @@ cr_output_curses(FILE * F, const faction * viewer, const void *obj, objtype_t ty
|
||||||
region *r;
|
region *r;
|
||||||
|
|
||||||
/* Die Sichtbarkeit eines Zaubers und die Zaubermeldung sind bei
|
/* Die Sichtbarkeit eines Zaubers und die Zaubermeldung sind bei
|
||||||
* Gebäuden und Schiffen je nach, ob man Besitzer ist, verschieden.
|
* Gebäuden und Schiffen je nach, ob man Besitzer ist, verschieden.
|
||||||
* Bei Einheiten sieht man Wirkungen auf eigene Einheiten immer.
|
* Bei Einheiten sieht man Wirkungen auf eigene Einheiten immer.
|
||||||
* Spezialfälle (besonderes Talent, verursachender Magier usw. werde
|
* Spezialfälle (besonderes Talent, verursachender Magier usw. werde
|
||||||
* bei jedem curse gesondert behandelt. */
|
* bei jedem curse gesondert behandelt. */
|
||||||
if (typ == TYP_SHIP) {
|
if (typ == TYP_SHIP) {
|
||||||
ship *sh = (ship *)obj;
|
ship *sh = (ship *)obj;
|
||||||
|
@ -747,8 +747,11 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
|
||||||
static const curse_type *itemcloak_ct = 0;
|
static const curse_type *itemcloak_ct = 0;
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
item result[MAX_INVENTORY];
|
item result[MAX_INVENTORY];
|
||||||
|
const faction *sf;
|
||||||
|
const char *prefix;
|
||||||
|
|
||||||
if (fval(u_race(u), RCF_INVISIBLE))
|
assert(u && u->number);
|
||||||
|
if (u != NULL || fval(u_race(u), RCF_INVISIBLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!init) {
|
if (!init) {
|
||||||
|
@ -756,21 +759,19 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
|
||||||
itemcloak_ct = ct_find("itemcloak");
|
itemcloak_ct = ct_find("itemcloak");
|
||||||
}
|
}
|
||||||
if (itemcloak_ct != NULL) {
|
if (itemcloak_ct != NULL) {
|
||||||
itemcloak = curse_active(get_curse(u->attribs, itemcloak_ct));
|
curse * cu = get_curse(u->attribs, itemcloak_ct);
|
||||||
|
itemcloak = cu && curse_active(cu);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(u && u->number);
|
|
||||||
|
|
||||||
fprintf(F, "EINHEIT %d\n", u->no);
|
fprintf(F, "EINHEIT %d\n", u->no);
|
||||||
fprintf(F, "\"%s\";Name\n", unit_getname(u));
|
fprintf(F, "\"%s\";Name\n", unit_getname(u));
|
||||||
str = u_description(u, f->locale);
|
str = u_description(u, f->locale);
|
||||||
if (str) {
|
if (str) {
|
||||||
fprintf(F, "\"%s\";Beschr\n", str);
|
fprintf(F, "\"%s\";Beschr\n", str);
|
||||||
}
|
}
|
||||||
{
|
|
||||||
/* print faction information */
|
/* print faction information */
|
||||||
const faction *sf = visible_faction(f, u);
|
sf = visible_faction(f, u);
|
||||||
const char *prefix = raceprefix(u);
|
prefix = raceprefix(u);
|
||||||
if (u->faction == f || omniscient(f)) {
|
if (u->faction == f || omniscient(f)) {
|
||||||
const attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction);
|
const attrib *a_otherfaction = a_find(u->attribs, &at_otherfaction);
|
||||||
const faction *otherfaction =
|
const faction *otherfaction =
|
||||||
|
@ -828,7 +829,6 @@ static void cr_output_unit(FILE * F, const region * r, const faction * f,
|
||||||
fprintf(F, "\"%s\";typprefix\n", translate(prefix, LOC(f->locale,
|
fprintf(F, "\"%s\";typprefix\n", translate(prefix, LOC(f->locale,
|
||||||
prefix)));
|
prefix)));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (u->faction != f && a_fshidden
|
if (u->faction != f && a_fshidden
|
||||||
&& a_fshidden->data.ca[0] == 1 && effskill(u, SK_STEALTH) >= 6) {
|
&& a_fshidden->data.ca[0] == 1 && effskill(u, SK_STEALTH) >= 6) {
|
||||||
fprintf(F, "-1;Anzahl\n");
|
fprintf(F, "-1;Anzahl\n");
|
||||||
|
@ -1037,18 +1037,6 @@ static void show_alliances_cr(FILE * F, const faction * f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* prints all visible spells in a region */
|
|
||||||
static void show_active_spells(const region * r)
|
|
||||||
{
|
|
||||||
char fogwall[MAXDIRECTIONS];
|
|
||||||
#ifdef TODO /* alte Regionszauberanzeigen umstellen */
|
|
||||||
unit *u;
|
|
||||||
int env = 0;
|
|
||||||
#endif
|
|
||||||
memset(fogwall, 0, sizeof(char) * MAXDIRECTIONS);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
|
||||||
|
|
||||||
/* this is a copy of laws.c->find_address output changed. */
|
/* this is a copy of laws.c->find_address output changed. */
|
||||||
|
@ -1312,6 +1300,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
|
||||||
if (r->display && r->display[0])
|
if (r->display && r->display[0])
|
||||||
fprintf(F, "\"%s\";Beschr\n", r->display);
|
fprintf(F, "\"%s\";Beschr\n", r->display);
|
||||||
if (fval(r->terrain, LAND_REGION)) {
|
if (fval(r->terrain, LAND_REGION)) {
|
||||||
|
assert(r->land);
|
||||||
fprintf(F, "%d;Bauern\n", rpeasants(r));
|
fprintf(F, "%d;Bauern\n", rpeasants(r));
|
||||||
if (fval(r, RF_ORCIFIED)) {
|
if (fval(r, RF_ORCIFIED)) {
|
||||||
fprintf(F, "1;Verorkt\n");
|
fprintf(F, "1;Verorkt\n");
|
||||||
|
@ -1342,7 +1331,7 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
|
||||||
fputs("1;mourning\n", F);
|
fputs("1;mourning\n", F);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r->land->ownership) {
|
if (r->land && r->land->ownership) {
|
||||||
fprintf(F, "%d;morale\n", r->land->morale);
|
fprintf(F, "%d;morale\n", r->land->morale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1412,7 +1401,6 @@ static void cr_output_region(FILE * F, report_context * ctx, seen_region * sr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* describe both passed and inhabited regions */
|
/* describe both passed and inhabited regions */
|
||||||
show_active_spells(r);
|
|
||||||
if (fval(r, RF_TRAVELUNIT)) {
|
if (fval(r, RF_TRAVELUNIT)) {
|
||||||
bool seeunits = false, seeships = false;
|
bool seeunits = false, seeships = false;
|
||||||
const attrib *ru;
|
const attrib *ru;
|
||||||
|
|
25
src/give.c
25
src/give.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
| | Enno Rehling <enno@eressea.de>
|
| | Enno Rehling <enno@eressea.de>
|
||||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||||
|
@ -299,7 +299,7 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord)
|
||||||
error = 96;
|
error = 96;
|
||||||
}
|
}
|
||||||
else if (u->faction != u2->faction) {
|
else if (u->faction != u2->faction) {
|
||||||
if (maxt>=0 && u2->faction->newbies + n > maxt) {
|
if (maxt >= 0 && u2->faction->newbies + n > maxt) {
|
||||||
error = 129;
|
error = 129;
|
||||||
}
|
}
|
||||||
else if (u_race(u) != u2->faction->race) {
|
else if (u_race(u) != u2->faction->race) {
|
||||||
|
@ -332,7 +332,7 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord)
|
||||||
if (has_skill(u2, SK_ALCHEMY) && !has_skill(u, SK_ALCHEMY))
|
if (has_skill(u2, SK_ALCHEMY) && !has_skill(u, SK_ALCHEMY))
|
||||||
k += n;
|
k += n;
|
||||||
|
|
||||||
/* Wenn Parteigrenzen überschritten werden */
|
/* Wenn Parteigrenzen überschritten werden */
|
||||||
if (u2->faction != u->faction)
|
if (u2->faction != u->faction)
|
||||||
k += n;
|
k += n;
|
||||||
|
|
||||||
|
@ -354,14 +354,14 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord)
|
||||||
freset(u2, UFL_HERO);
|
freset(u2, UFL_HERO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Einheiten von Schiffen können nicht NACH in von
|
/* Einheiten von Schiffen können nicht NACH in von
|
||||||
* Nicht-alliierten bewachten Regionen ausführen */
|
* Nicht-alliierten bewachten Regionen ausführen */
|
||||||
sh = leftship(u);
|
sh = leftship(u);
|
||||||
if (sh) {
|
if (sh) {
|
||||||
set_leftship(u2, sh);
|
set_leftship(u2, sh);
|
||||||
}
|
}
|
||||||
transfermen(u, u2, n);
|
transfermen(u, u2, n);
|
||||||
if (maxt>=0 && u->faction != u2->faction) {
|
if (maxt >= 0 && u->faction != u2->faction) {
|
||||||
u2->faction->newbies += n;
|
u2->faction->newbies += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,15 +400,15 @@ message * disband_men(int n, unit * u, struct order *ord) {
|
||||||
|
|
||||||
void give_unit(unit * u, unit * u2, order * ord)
|
void give_unit(unit * u, unit * u2, order * ord)
|
||||||
{
|
{
|
||||||
region *r = u->region;
|
|
||||||
int maxt = max_transfers();
|
int maxt = max_transfers();
|
||||||
|
|
||||||
|
assert(u);
|
||||||
if (!rule_transfermen() && u->faction != u2->faction) {
|
if (!rule_transfermen() && u->faction != u2->faction) {
|
||||||
cmistake(u, ord, 74, MSG_COMMERCE);
|
cmistake(u, ord, 74, MSG_COMMERCE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u && unit_has_cursed_item(u)) {
|
if (unit_has_cursed_item(u)) {
|
||||||
cmistake(u, ord, 78, MSG_COMMERCE);
|
cmistake(u, ord, 78, MSG_COMMERCE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -423,6 +423,7 @@ void give_unit(unit * u, unit * u2, order * ord)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u2 == NULL) {
|
if (u2 == NULL) {
|
||||||
|
region *r = u->region;
|
||||||
message *msg;
|
message *msg;
|
||||||
if (fval(r->terrain, SEA_REGION)) {
|
if (fval(r->terrain, SEA_REGION)) {
|
||||||
msg = disband_men(u->number, u, ord);
|
msg = disband_men(u->number, u, ord);
|
||||||
|
@ -518,7 +519,7 @@ void give_unit(unit * u, unit * u2, order * ord)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool can_give_to(unit *u, unit *u2) {
|
bool can_give_to(unit *u, unit *u2) {
|
||||||
/* Damit Tarner nicht durch die Fehlermeldung enttarnt werden können */
|
/* Damit Tarner nicht durch die Fehlermeldung enttarnt werden können */
|
||||||
if (!u2) {
|
if (!u2) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -613,7 +614,7 @@ void give_cmd(unit * u, order * ord)
|
||||||
item *itm = *itmp;
|
item *itm = *itmp;
|
||||||
const item_type *itype = itm->type;
|
const item_type *itype = itm->type;
|
||||||
if (fval(itype, ITF_HERB) && itm->number > 0) {
|
if (fval(itype, ITF_HERB) && itm->number > 0) {
|
||||||
/* give_item ändert im fall,das man alles übergibt, die
|
/* give_item ändert im fall,das man alles übergibt, die
|
||||||
* item-liste der unit, darum continue vor pointerumsetzten */
|
* item-liste der unit, darum continue vor pointerumsetzten */
|
||||||
if (give_item(itm->number, itm->type, u, u2, ord) == 0) {
|
if (give_item(itm->number, itm->type, u, u2, ord) == 0) {
|
||||||
given = true;
|
given = true;
|
||||||
|
@ -669,8 +670,8 @@ void give_cmd(unit * u, order * ord)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* für alle items einmal prüfen, ob wir mehr als von diesem Typ
|
/* für alle items einmal prüfen, ob wir mehr als von diesem Typ
|
||||||
* reserviert ist besitzen und diesen Teil dann übergeben */
|
* reserviert ist besitzen und diesen Teil dann übergeben */
|
||||||
if (u->items) {
|
if (u->items) {
|
||||||
item **itmp = &u->items;
|
item **itmp = &u->items;
|
||||||
while (*itmp) {
|
while (*itmp) {
|
||||||
|
|
|
@ -249,6 +249,8 @@ static void paint_map(window * wnd, const state * st)
|
||||||
int cols = getmaxx(win);
|
int cols = getmaxx(win);
|
||||||
int vx, vy;
|
int vx, vy;
|
||||||
|
|
||||||
|
assert(st);
|
||||||
|
if (!st) return;
|
||||||
lines = lines / THEIGHT;
|
lines = lines / THEIGHT;
|
||||||
cols = cols / TWIDTH;
|
cols = cols / TWIDTH;
|
||||||
for (vy = 0; vy != lines; ++vy) {
|
for (vy = 0; vy != lines; ++vy) {
|
||||||
|
@ -260,12 +262,10 @@ static void paint_map(window * wnd, const state * st)
|
||||||
int xp = vx * TWIDTH + (vy & 1) * TWIDTH / 2;
|
int xp = vx * TWIDTH + (vy & 1) * TWIDTH / 2;
|
||||||
int nx, ny;
|
int nx, ny;
|
||||||
if (mr) {
|
if (mr) {
|
||||||
if (st) {
|
|
||||||
cnormalize(&mr->coord, &nx, &ny);
|
cnormalize(&mr->coord, &nx, &ny);
|
||||||
if (tagged_region(st->selected, nx, ny)) {
|
if (tagged_region(st->selected, nx, ny)) {
|
||||||
attr |= A_REVERSE;
|
attr |= A_REVERSE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (mr->r && (mr->r->flags & RF_MAPPER_HIGHLIGHT))
|
if (mr->r && (mr->r->flags & RF_MAPPER_HIGHLIGHT))
|
||||||
hl = 1;
|
hl = 1;
|
||||||
mvwaddch(win, yp, xp, mr_tile(mr, hl) | attr);
|
mvwaddch(win, yp, xp, mr_tile(mr, hl) | attr);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "reports.h"
|
#include "reports.h"
|
||||||
#include "jsreport.h"
|
#include "jsreport.h"
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
#include <kernel/terrain.h>
|
#include <kernel/terrain.h>
|
||||||
|
@ -74,7 +74,7 @@ static int report_json(const char *filename, report_context * ctx, const char *c
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ferror(F);
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,6 +307,9 @@ const curse_type *ct_find(const char *c)
|
||||||
{
|
{
|
||||||
unsigned int hash = tolower(c[0]);
|
unsigned int hash = tolower(c[0]);
|
||||||
quicklist *ctl = cursetypes[hash];
|
quicklist *ctl = cursetypes[hash];
|
||||||
|
|
||||||
|
if (ctl) {
|
||||||
|
size_t c_len = strlen(c);
|
||||||
int qi;
|
int qi;
|
||||||
|
|
||||||
for (qi = 0; ctl; ql_advance(&ctl, &qi, 1)) {
|
for (qi = 0; ctl; ql_advance(&ctl, &qi, 1)) {
|
||||||
|
@ -316,12 +319,13 @@ const curse_type *ct_find(const char *c)
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
size_t k = _min(strlen(c), strlen(type->cname));
|
size_t k = _min(c_len, strlen(type->cname));
|
||||||
if (!_memicmp(c, type->cname, k)) {
|
if (!_memicmp(c, type->cname, k)) {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
@ -332,10 +332,15 @@ potion_type *new_potiontype(item_type * itype, int level)
|
||||||
}
|
}
|
||||||
|
|
||||||
void it_set_appearance(item_type *itype, const char *appearance) {
|
void it_set_appearance(item_type *itype, const char *appearance) {
|
||||||
assert(itype && itype->rtype);
|
assert(itype);
|
||||||
|
assert(itype->rtype);
|
||||||
|
if (appearance) {
|
||||||
itype->_appearance[0] = _strdup(appearance);
|
itype->_appearance[0] = _strdup(appearance);
|
||||||
itype->_appearance[1] = appearance ?
|
itype->_appearance[1] = strcat(strcpy((char *)malloc(strlen((char *)appearance) + 3), (char *)appearance), "_p");
|
||||||
strcat(strcpy((char *)malloc(strlen((char *)appearance) + 3), (char *)appearance), "_p") : 0;
|
} else {
|
||||||
|
itype->_appearance[0] = 0;
|
||||||
|
itype->_appearance[1] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const resource_type *item2resource(const item_type * itype)
|
const resource_type *item2resource(const item_type * itype)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
@ -305,7 +305,7 @@ void free_messagelist(message_list * msgs)
|
||||||
|
|
||||||
message *add_message(message_list ** pm, message * m)
|
message *add_message(message_list ** pm, message * m)
|
||||||
{
|
{
|
||||||
assert(m->type);
|
assert(m && m->type);
|
||||||
if (!lomem && m != NULL) {
|
if (!lomem && m != NULL) {
|
||||||
struct mlist *mnew = malloc(sizeof(struct mlist));
|
struct mlist *mnew = malloc(sizeof(struct mlist));
|
||||||
if (*pm == NULL) {
|
if (*pm == NULL) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
@ -200,7 +200,7 @@ static unit *unitorders(FILE * F, int enc, struct faction *f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Nun wird der Befehl erzeut und eingehängt */
|
/* Nun wird der Befehl erzeut und eingehängt */
|
||||||
*ordp = parse_order(s, u->faction->locale);
|
*ordp = parse_order(s, u->faction->locale);
|
||||||
if (*ordp) {
|
if (*ordp) {
|
||||||
ordp = &(*ordp)->next;
|
ordp = &(*ordp)->next;
|
||||||
|
@ -233,8 +233,8 @@ static faction *factionorders(void)
|
||||||
f->no, pass));
|
f->no, pass));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Die Partei hat sich zumindest gemeldet, so daß sie noch
|
/* Die Partei hat sich zumindest gemeldet, so daß sie noch
|
||||||
* nicht als untätig gilt */
|
* nicht als untätig gilt */
|
||||||
|
|
||||||
/* TODO: +1 ist ein Workaround, weil cturn erst in process_orders
|
/* TODO: +1 ist ein Workaround, weil cturn erst in process_orders
|
||||||
* incrementiert wird. */
|
* incrementiert wird. */
|
||||||
|
@ -308,9 +308,9 @@ int readorders(const char *filename)
|
||||||
/* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue
|
/* Falls in unitorders() abgebrochen wird, steht dort entweder eine neue
|
||||||
* Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut
|
* Partei, eine neue Einheit oder das File-Ende. Das switch() wird erneut
|
||||||
* durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf
|
* durchlaufen, und die entsprechende Funktion aufgerufen. Man darf buf
|
||||||
* auf alle Fälle nicht überschreiben! Bei allen anderen Einträgen hier
|
* auf alle Fälle nicht überschreiben! Bei allen anderen Einträgen hier
|
||||||
* muß buf erneut gefüllt werden, da die betreffende Information in nur
|
* muß buf erneut gefüllt werden, da die betreffende Information in nur
|
||||||
* einer Zeile steht, und nun die nächste gelesen werden muß. */
|
* einer Zeile steht, und nun die nächste gelesen werden muß. */
|
||||||
|
|
||||||
case P_NEXT:
|
case P_NEXT:
|
||||||
f = NULL;
|
f = NULL;
|
||||||
|
@ -331,7 +331,7 @@ int readorders(const char *filename)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
/* #define INNER_WORLD */
|
/* #define INNER_WORLD */
|
||||||
/* fürs debuggen nur den inneren Teil der Welt laden */
|
/* fürs debuggen nur den inneren Teil der Welt laden */
|
||||||
/* -9;-27;-1;-19;Sumpfloch */
|
/* -9;-27;-1;-19;Sumpfloch */
|
||||||
int inner_world(region * r)
|
int inner_world(region * r)
|
||||||
{
|
{
|
||||||
|
@ -978,6 +978,9 @@ static region *readregion(struct gamedata *data, int x, int y)
|
||||||
|
|
||||||
void writeregion(struct gamedata *data, const region * r)
|
void writeregion(struct gamedata *data, const region * r)
|
||||||
{
|
{
|
||||||
|
assert(r);
|
||||||
|
assert(data);
|
||||||
|
|
||||||
WRITE_INT(data->store, r->uid);
|
WRITE_INT(data->store, r->uid);
|
||||||
WRITE_STR(data->store, region_getinfo(r));
|
WRITE_STR(data->store, region_getinfo(r));
|
||||||
WRITE_TOK(data->store, r->terrain->_name);
|
WRITE_TOK(data->store, r->terrain->_name);
|
||||||
|
@ -988,6 +991,8 @@ void writeregion(struct gamedata *data, const region * r)
|
||||||
const item_type *rht;
|
const item_type *rht;
|
||||||
struct demand *demand;
|
struct demand *demand;
|
||||||
rawmaterial *res = r->resources;
|
rawmaterial *res = r->resources;
|
||||||
|
|
||||||
|
assert(r->land);
|
||||||
WRITE_STR(data->store, (const char *)r->land->name);
|
WRITE_STR(data->store, (const char *)r->land->name);
|
||||||
assert(rtrees(r, 0) >= 0);
|
assert(rtrees(r, 0) >= 0);
|
||||||
assert(rtrees(r, 1) >= 0);
|
assert(rtrees(r, 1) >= 0);
|
||||||
|
@ -1018,12 +1023,10 @@ void writeregion(struct gamedata *data, const region * r)
|
||||||
WRITE_INT(data->store, rherbs(r));
|
WRITE_INT(data->store, rherbs(r));
|
||||||
WRITE_INT(data->store, rpeasants(r));
|
WRITE_INT(data->store, rpeasants(r));
|
||||||
WRITE_INT(data->store, rmoney(r));
|
WRITE_INT(data->store, rmoney(r));
|
||||||
if (r->land) {
|
|
||||||
for (demand = r->land->demands; demand; demand = demand->next) {
|
for (demand = r->land->demands; demand; demand = demand->next) {
|
||||||
WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0));
|
WRITE_TOK(data->store, resourcename(demand->type->itype->rtype, 0));
|
||||||
WRITE_INT(data->store, demand->value);
|
WRITE_INT(data->store, demand->value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
WRITE_TOK(data->store, "end");
|
WRITE_TOK(data->store, "end");
|
||||||
write_items(data->store, r->land->items);
|
write_items(data->store, r->land->items);
|
||||||
WRITE_SECTION(data->store);
|
WRITE_SECTION(data->store);
|
||||||
|
|
|
@ -435,13 +435,25 @@ void write_ship_reference(const struct ship *sh, struct storage *store)
|
||||||
void ship_setname(ship * self, const char *name)
|
void ship_setname(ship * self, const char *name)
|
||||||
{
|
{
|
||||||
free(self->name);
|
free(self->name);
|
||||||
if (name)
|
self->name = name ? _strdup(name) : 0;
|
||||||
self->name = _strdup(name);
|
|
||||||
else
|
|
||||||
self->name = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *ship_getname(const ship * self)
|
const char *ship_getname(const ship * self)
|
||||||
{
|
{
|
||||||
return self->name;
|
return self->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unit *get_captain(const ship * sh)
|
||||||
|
{
|
||||||
|
const region *r = sh->region;
|
||||||
|
unit *u;
|
||||||
|
|
||||||
|
for (u = r->units; u; u = u->next) {
|
||||||
|
if (u->ship == sh && u->number
|
||||||
|
&& eff_skill(u, SK_SAILING, r) >= sh->type->cptskill)
|
||||||
|
return u;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -121,9 +121,10 @@ extern "C" {
|
||||||
extern void free_ship(struct ship *s);
|
extern void free_ship(struct ship *s);
|
||||||
extern void free_ships(void);
|
extern void free_ships(void);
|
||||||
|
|
||||||
extern const char *ship_getname(const struct ship *self);
|
const char *ship_getname(const struct ship *self);
|
||||||
extern void ship_setname(struct ship *self, const char *name);
|
void ship_setname(struct ship *self, const char *name);
|
||||||
int shipspeed(const struct ship *sh, const struct unit *u);
|
int shipspeed(const struct ship *sh, const struct unit *u);
|
||||||
|
struct unit *get_captain(const struct ship *sh);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
148
src/laws.c
148
src/laws.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2014,
|
Copyright (c) 1998-2014,
|
||||||
Enno Rehling <enno@eressea.de>
|
Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
|
@ -165,7 +165,7 @@ static void live(region * r)
|
||||||
while (*up) {
|
while (*up) {
|
||||||
unit *u = *up;
|
unit *u = *up;
|
||||||
/* IUW: age_unit() kann u loeschen, u->next ist dann
|
/* IUW: age_unit() kann u loeschen, u->next ist dann
|
||||||
* undefiniert, also muessen wir hier schon das nächste
|
* undefiniert, also muessen wir hier schon das nächste
|
||||||
* Element bestimmen */
|
* Element bestimmen */
|
||||||
|
|
||||||
int effect = get_effect(u, oldpotiontype[P_FOOL]);
|
int effect = get_effect(u, oldpotiontype[P_FOOL]);
|
||||||
|
@ -183,7 +183,7 @@ static void live(region * r)
|
||||||
reduce_skill(u, sb, weeks);
|
reduce_skill(u, sb, weeks);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("dumbeffect",
|
ADDMSG(&u->faction->msgs, msg_message("dumbeffect",
|
||||||
"unit weeks skill", u, weeks, (skill_t)sb->id));
|
"unit weeks skill", u, weeks, (skill_t)sb->id));
|
||||||
} /* sonst Glück gehabt: wer nix weiß, kann nix vergessen... */
|
} /* sonst Glück gehabt: wer nix weiß, kann nix vergessen... */
|
||||||
change_effect(u, oldpotiontype[P_FOOL], -effect);
|
change_effect(u, oldpotiontype[P_FOOL], -effect);
|
||||||
}
|
}
|
||||||
age_unit(r, u);
|
age_unit(r, u);
|
||||||
|
@ -325,16 +325,16 @@ static void peasants(region * r)
|
||||||
peasants += births + luck;
|
peasants += births + luck;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Alle werden satt, oder halt soviele für die es auch Geld gibt */
|
/* Alle werden satt, oder halt soviele für die es auch Geld gibt */
|
||||||
|
|
||||||
satiated = _min(peasants, money / maintenance_cost(NULL));
|
satiated = _min(peasants, money / maintenance_cost(NULL));
|
||||||
rsetmoney(r, money - satiated * maintenance_cost(NULL));
|
rsetmoney(r, money - satiated * maintenance_cost(NULL));
|
||||||
|
|
||||||
/* Von denjenigen, die nicht satt geworden sind, verhungert der
|
/* Von denjenigen, die nicht satt geworden sind, verhungert der
|
||||||
* Großteil. dead kann nie größer als rpeasants(r) - satiated werden,
|
* Großteil. dead kann nie größer als rpeasants(r) - satiated werden,
|
||||||
* so dass rpeasants(r) >= 0 bleiben muß. */
|
* so dass rpeasants(r) >= 0 bleiben muß. */
|
||||||
|
|
||||||
/* Es verhungert maximal die unterernährten Bevölkerung. */
|
/* Es verhungert maximal die unterernährten Bevölkerung. */
|
||||||
|
|
||||||
n = _min(peasants - satiated, rpeasants(r));
|
n = _min(peasants - satiated, rpeasants(r));
|
||||||
dead += (int)(0.5 + n * PEASANT_STARVATION_CHANCE);
|
dead += (int)(0.5 + n * PEASANT_STARVATION_CHANCE);
|
||||||
|
@ -399,10 +399,10 @@ static void migrate(region * r)
|
||||||
rsethorses(r, rhorses(r) + m->horses);
|
rsethorses(r, rhorses(r) + m->horses);
|
||||||
/* Was macht das denn hier?
|
/* Was macht das denn hier?
|
||||||
* Baumwanderung wird in trees() gemacht.
|
* Baumwanderung wird in trees() gemacht.
|
||||||
* wer fragt das? Die Baumwanderung war abhängig von der
|
* wer fragt das? Die Baumwanderung war abhängig von der
|
||||||
* Auswertungsreihenfolge der regionen,
|
* Auswertungsreihenfolge der regionen,
|
||||||
* das hatte ich geändert. jemand hat es wieder gelöscht, toll.
|
* das hatte ich geändert. jemand hat es wieder gelöscht, toll.
|
||||||
* ich habe es wieder aktiviert, muß getestet werden.
|
* ich habe es wieder aktiviert, muß getestet werden.
|
||||||
*/
|
*/
|
||||||
*hp = m->next;
|
*hp = m->next;
|
||||||
m->next = free_migrants;
|
m->next = free_migrants;
|
||||||
|
@ -442,8 +442,8 @@ static void horses(region * r)
|
||||||
|
|
||||||
/* Pferde wandern in Nachbarregionen.
|
/* Pferde wandern in Nachbarregionen.
|
||||||
* Falls die Nachbarregion noch berechnet
|
* Falls die Nachbarregion noch berechnet
|
||||||
* werden muß, wird eine migration-Struktur gebildet,
|
* werden muß, wird eine migration-Struktur gebildet,
|
||||||
* die dann erst in die Berechnung der Nachbarstruktur einfließt.
|
* die dann erst in die Berechnung der Nachbarstruktur einfließt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (n = 0; n != MAXDIRECTIONS; n++) {
|
for (n = 0; n != MAXDIRECTIONS; n++) {
|
||||||
|
@ -457,7 +457,7 @@ static void horses(region * r)
|
||||||
else {
|
else {
|
||||||
migration *nb;
|
migration *nb;
|
||||||
/* haben wir die Migration schonmal benutzt?
|
/* haben wir die Migration schonmal benutzt?
|
||||||
* wenn nicht, müssen wir sie suchen.
|
* wenn nicht, müssen wir sie suchen.
|
||||||
* Wandernde Pferde vermehren sich nicht.
|
* Wandernde Pferde vermehren sich nicht.
|
||||||
*/
|
*/
|
||||||
nb = get_migrants(r2);
|
nb = get_migrants(r2);
|
||||||
|
@ -553,11 +553,11 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
|
|
||||||
a = a_find(r->attribs, &at_germs);
|
a = a_find(r->attribs, &at_germs);
|
||||||
if (a && last_weeks_season == SEASON_SPRING) {
|
if (a && last_weeks_season == SEASON_SPRING) {
|
||||||
/* ungekeimte Samen bleiben erhalten, Sprößlinge wachsen */
|
/* ungekeimte Samen bleiben erhalten, Sprößlinge wachsen */
|
||||||
sprout = _min(a->data.sa[1], rtrees(r, 1));
|
sprout = _min(a->data.sa[1], rtrees(r, 1));
|
||||||
/* aus dem gesamt Sprößlingepool abziehen */
|
/* aus dem gesamt Sprößlingepool abziehen */
|
||||||
rsettrees(r, 1, rtrees(r, 1) - sprout);
|
rsettrees(r, 1, rtrees(r, 1) - sprout);
|
||||||
/* zu den Bäumen hinzufügen */
|
/* zu den Bäumen hinzufügen */
|
||||||
rsettrees(r, 2, rtrees(r, 2) + sprout);
|
rsettrees(r, 2, rtrees(r, 2) + sprout);
|
||||||
|
|
||||||
a_removeall(&r->attribs, &at_germs);
|
a_removeall(&r->attribs, &at_germs);
|
||||||
|
@ -573,7 +573,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Grundchance 1.0% */
|
/* Grundchance 1.0% */
|
||||||
/* Jeder Elf in der Region erhöht die Chance marginal */
|
/* Jeder Elf in der Region erhöht die Chance marginal */
|
||||||
elves = _min(elves, production(r) / 8);
|
elves = _min(elves, production(r) / 8);
|
||||||
if (elves) {
|
if (elves) {
|
||||||
seedchance += 1.0 - pow(0.99999, elves * RESOURCE_QUANTITY);
|
seedchance += 1.0 - pow(0.99999, elves * RESOURCE_QUANTITY);
|
||||||
|
@ -594,19 +594,19 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bäume breiten sich in Nachbarregionen aus. */
|
/* Bäume breiten sich in Nachbarregionen aus. */
|
||||||
|
|
||||||
/* Gesamtzahl der Samen:
|
/* Gesamtzahl der Samen:
|
||||||
* bis zu 6% (FORESTGROWTH*3) der Bäume samen in die Nachbarregionen */
|
* bis zu 6% (FORESTGROWTH*3) der Bäume samen in die Nachbarregionen */
|
||||||
seeds = (rtrees(r, 2) * FORESTGROWTH * 3) / 1000000;
|
seeds = (rtrees(r, 2) * FORESTGROWTH * 3) / 1000000;
|
||||||
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||||
region *r2 = rconnect(r, d);
|
region *r2 = rconnect(r, d);
|
||||||
if (r2 && fval(r2->terrain, LAND_REGION) && r2->terrain->size) {
|
if (r2 && fval(r2->terrain, LAND_REGION) && r2->terrain->size) {
|
||||||
/* Eine Landregion, wir versuchen Samen zu verteilen:
|
/* Eine Landregion, wir versuchen Samen zu verteilen:
|
||||||
* Die Chance, das Samen ein Stück Boden finden, in dem sie
|
* Die Chance, das Samen ein Stück Boden finden, in dem sie
|
||||||
* keimen können, hängt von der Bewuchsdichte und der
|
* keimen können, hängt von der Bewuchsdichte und der
|
||||||
* verfügbaren Fläche ab. In Gletschern gibt es weniger
|
* verfügbaren Fläche ab. In Gletschern gibt es weniger
|
||||||
* Möglichkeiten als in Ebenen. */
|
* Möglichkeiten als in Ebenen. */
|
||||||
sprout = 0;
|
sprout = 0;
|
||||||
seedchance = (1000 * maxworkingpeasants(r2)) / r2->terrain->size;
|
seedchance = (1000 * maxworkingpeasants(r2)) / r2->terrain->size;
|
||||||
for (i = 0; i < seeds / MAXDIRECTIONS; i++) {
|
for (i = 0; i < seeds / MAXDIRECTIONS; i++) {
|
||||||
|
@ -623,8 +623,8 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0))
|
if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* in at_germs merken uns die Zahl der Samen und Sprößlinge, die
|
/* in at_germs merken uns die Zahl der Samen und Sprößlinge, die
|
||||||
* dieses Jahr älter werden dürfen, damit nicht ein Same im selben
|
* dieses Jahr älter werden dürfen, damit nicht ein Same im selben
|
||||||
* Zyklus zum Baum werden kann */
|
* Zyklus zum Baum werden kann */
|
||||||
a = a_find(r->attribs, &at_germs);
|
a = a_find(r->attribs, &at_germs);
|
||||||
if (!a) {
|
if (!a) {
|
||||||
|
@ -632,13 +632,13 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
a->data.sa[0] = (short)rtrees(r, 0);
|
a->data.sa[0] = (short)rtrees(r, 0);
|
||||||
a->data.sa[1] = (short)rtrees(r, 1);
|
a->data.sa[1] = (short)rtrees(r, 1);
|
||||||
}
|
}
|
||||||
/* wir haben 6 Wochen zum wachsen, jeder Same/Sproß hat 18% Chance
|
/* wir haben 6 Wochen zum wachsen, jeder Same/Sproß hat 18% Chance
|
||||||
* zu wachsen, damit sollten nach 5-6 Wochen alle gewachsen sein */
|
* zu wachsen, damit sollten nach 5-6 Wochen alle gewachsen sein */
|
||||||
growth = 1800;
|
growth = 1800;
|
||||||
|
|
||||||
/* Samenwachstum */
|
/* Samenwachstum */
|
||||||
|
|
||||||
/* Raubbau abfangen, es dürfen nie mehr Samen wachsen, als aktuell
|
/* Raubbau abfangen, es dürfen nie mehr Samen wachsen, als aktuell
|
||||||
* in der Region sind */
|
* in der Region sind */
|
||||||
seeds = _min(a->data.sa[0], rtrees(r, 0));
|
seeds = _min(a->data.sa[0], rtrees(r, 0));
|
||||||
sprout = 0;
|
sprout = 0;
|
||||||
|
@ -651,15 +651,15 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
a->data.sa[0] = (short)(seeds - sprout);
|
a->data.sa[0] = (short)(seeds - sprout);
|
||||||
/* aus dem gesamt Samenpool abziehen */
|
/* aus dem gesamt Samenpool abziehen */
|
||||||
rsettrees(r, 0, rtrees(r, 0) - sprout);
|
rsettrees(r, 0, rtrees(r, 0) - sprout);
|
||||||
/* zu den Sprößlinge hinzufügen */
|
/* zu den Sprößlinge hinzufügen */
|
||||||
rsettrees(r, 1, rtrees(r, 1) + sprout);
|
rsettrees(r, 1, rtrees(r, 1) + sprout);
|
||||||
|
|
||||||
/* Baumwachstum */
|
/* Baumwachstum */
|
||||||
|
|
||||||
/* hier gehen wir davon aus, das Jungbäume nicht ohne weiteres aus
|
/* hier gehen wir davon aus, das Jungbäume nicht ohne weiteres aus
|
||||||
* der Region entfernt werden können, da Jungbäume in der gleichen
|
* der Region entfernt werden können, da Jungbäume in der gleichen
|
||||||
* Runde nachwachsen, wir also nicht mehr zwischen diesjährigen und
|
* Runde nachwachsen, wir also nicht mehr zwischen diesjährigen und
|
||||||
* 'alten' Jungbäumen unterscheiden könnten */
|
* 'alten' Jungbäumen unterscheiden könnten */
|
||||||
sprout = _min(a->data.sa[1], rtrees(r, 1));
|
sprout = _min(a->data.sa[1], rtrees(r, 1));
|
||||||
grownup_trees = 0;
|
grownup_trees = 0;
|
||||||
|
|
||||||
|
@ -667,11 +667,11 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
if (rng_int() % 10000 < growth)
|
if (rng_int() % 10000 < growth)
|
||||||
grownup_trees++;
|
grownup_trees++;
|
||||||
}
|
}
|
||||||
/* aus dem Sprößlingepool dieses Jahres abziehen */
|
/* aus dem Sprößlingepool dieses Jahres abziehen */
|
||||||
a->data.sa[1] = (short)(sprout - grownup_trees);
|
a->data.sa[1] = (short)(sprout - grownup_trees);
|
||||||
/* aus dem gesamt Sprößlingepool abziehen */
|
/* aus dem gesamt Sprößlingepool abziehen */
|
||||||
rsettrees(r, 1, rtrees(r, 1) - grownup_trees);
|
rsettrees(r, 1, rtrees(r, 1) - grownup_trees);
|
||||||
/* zu den Bäumen hinzufügen */
|
/* zu den Bäumen hinzufügen */
|
||||||
rsettrees(r, 2, rtrees(r, 2) + grownup_trees);
|
rsettrees(r, 2, rtrees(r, 2) + grownup_trees);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -679,10 +679,10 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
||||||
static void
|
static void
|
||||||
growing_herbs(region * r, const int current_season, const int last_weeks_season)
|
growing_herbs(region * r, const int current_season, const int last_weeks_season)
|
||||||
{
|
{
|
||||||
/* Jetzt die Kräutervermehrung. Vermehrt wird logistisch:
|
/* Jetzt die Kräutervermehrung. Vermehrt wird logistisch:
|
||||||
*
|
*
|
||||||
* Jedes Kraut hat eine Wahrscheinlichkeit von (100-(vorhandene
|
* Jedes Kraut hat eine Wahrscheinlichkeit von (100-(vorhandene
|
||||||
* Kräuter))% sich zu vermehren. */
|
* Kräuter))% sich zu vermehren. */
|
||||||
if (current_season != SEASON_WINTER) {
|
if (current_season != SEASON_WINTER) {
|
||||||
int i;
|
int i;
|
||||||
for (i = rherbs(r); i > 0; i--) {
|
for (i = rherbs(r); i > 0; i--) {
|
||||||
|
@ -1098,7 +1098,7 @@ int enter_building(unit * u, order * ord, int id, bool report)
|
||||||
region *r = u->region;
|
region *r = u->region;
|
||||||
building *b;
|
building *b;
|
||||||
|
|
||||||
/* Schwimmer können keine Gebäude betreten, außer diese sind
|
/* Schwimmer können keine Gebäude betreten, außer diese sind
|
||||||
* auf dem Ozean */
|
* auf dem Ozean */
|
||||||
if (!fval(u_race(u), RCF_WALK) && !fval(u_race(u), RCF_FLY)) {
|
if (!fval(u_race(u), RCF_WALK) && !fval(u_race(u), RCF_FLY)) {
|
||||||
if (!fval(r->terrain, SEA_REGION)) {
|
if (!fval(r->terrain, SEA_REGION)) {
|
||||||
|
@ -1214,8 +1214,8 @@ void do_enter(struct region *r, bool is_final_attempt)
|
||||||
}
|
}
|
||||||
if (ulast != NULL) {
|
if (ulast != NULL) {
|
||||||
/* Wenn wir hier angekommen sind, war der Befehl
|
/* Wenn wir hier angekommen sind, war der Befehl
|
||||||
* erfolgreich und wir löschen ihn, damit er im
|
* erfolgreich und wir löschen ihn, damit er im
|
||||||
* zweiten Versuch nicht nochmal ausgeführt wird. */
|
* zweiten Versuch nicht nochmal ausgeführt wird. */
|
||||||
*ordp = ord->next;
|
*ordp = ord->next;
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
|
@ -1527,10 +1527,11 @@ int prefix_cmd(unit * u, struct order *ord)
|
||||||
ap = &u->faction->attribs;
|
ap = &u->faction->attribs;
|
||||||
if (fval(u, UFL_GROUP)) {
|
if (fval(u, UFL_GROUP)) {
|
||||||
attrib *a = a_find(u->attribs, &at_group);
|
attrib *a = a_find(u->attribs, &at_group);
|
||||||
|
if (a) {
|
||||||
group *g = (group *)a->data.v;
|
group *g = (group *)a->data.v;
|
||||||
if (a)
|
|
||||||
ap = &g->attribs;
|
ap = &g->attribs;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
set_prefix(ap, race_prefixes[var.i]);
|
set_prefix(ap, race_prefixes[var.i]);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1765,10 +1766,11 @@ int name_cmd(struct unit *u, struct order *ord)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const struct locale *lang = locales;
|
const struct locale *lang = locales;
|
||||||
|
size_t f_len = strlen(f->name);
|
||||||
for (; lang; lang = nextlocale(lang)) {
|
for (; lang; lang = nextlocale(lang)) {
|
||||||
const char *fdname = LOC(lang, "factiondefault");
|
const char *fdname = LOC(lang, "factiondefault");
|
||||||
size_t fdlen = strlen(fdname);
|
size_t fdlen = strlen(fdname);
|
||||||
if (strlen(f->name) >= fdlen && strncmp(f->name, fdname, fdlen) == 0) {
|
if (f_len >= fdlen && strncmp(f->name, fdname, fdlen) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1802,18 +1804,17 @@ int name_cmd(struct unit *u, struct order *ord)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const struct locale *lang = locales;
|
const struct locale *lang = locales;
|
||||||
|
size_t sh_len = strlen(sh->name);
|
||||||
for (; lang; lang = nextlocale(lang)) {
|
for (; lang; lang = nextlocale(lang)) {
|
||||||
const char *sdname = LOC(lang, sh->type->_name);
|
const char *sdname = LOC(lang, sh->type->_name);
|
||||||
size_t sdlen = strlen(sdname);
|
size_t sdlen = strlen(sdname);
|
||||||
if (strlen(sh->name) >= sdlen
|
if (sh_len >= sdlen && strncmp(sh->name, sdname, sdlen) == 0) {
|
||||||
&& strncmp(sh->name, sdname, sdlen) == 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
sdname = LOC(lang, parameters[P_SHIP]);
|
sdname = LOC(lang, parameters[P_SHIP]);
|
||||||
sdlen = strlen(sdname);
|
sdlen = strlen(sdname);
|
||||||
if (strlen(sh->name) >= sdlen
|
if (sh_len >= sdlen && strncmp(sh->name, sdname, sdlen) == 0) {
|
||||||
&& strncmp(sh->name, sdname, sdlen) == 0) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1989,13 +1990,13 @@ int mail_cmd(unit * u, struct order *ord)
|
||||||
s = gettoken(token, sizeof(token));
|
s = gettoken(token, sizeof(token));
|
||||||
|
|
||||||
/* Falls kein Parameter, ist das eine Einheitsnummer;
|
/* Falls kein Parameter, ist das eine Einheitsnummer;
|
||||||
* das Füllwort "AN" muß wegfallen, da gültige Nummer! */
|
* das Füllwort "AN" muß wegfallen, da gültige Nummer! */
|
||||||
|
|
||||||
do {
|
do {
|
||||||
cont = 0;
|
cont = 0;
|
||||||
switch (findparam_ex(s, u->faction->locale)) {
|
switch (findparam_ex(s, u->faction->locale)) {
|
||||||
case P_REGION:
|
case P_REGION:
|
||||||
/* können alle Einheiten in der Region sehen */
|
/* können alle Einheiten in der Region sehen */
|
||||||
s = getstrtoken();
|
s = getstrtoken();
|
||||||
if (!s || !s[0]) {
|
if (!s || !s[0]) {
|
||||||
cmistake(u, ord, 30, MSG_MESSAGE);
|
cmistake(u, ord, 30, MSG_MESSAGE);
|
||||||
|
@ -2348,7 +2349,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
|
||||||
if (wrptr(&bufp, &size, bytes) != 0)
|
if (wrptr(&bufp, &size, bytes) != 0)
|
||||||
WARN_STATIC_BUFFER();
|
WARN_STATIC_BUFFER();
|
||||||
|
|
||||||
/* b_armor : Rüstung */
|
/* b_armor : Rüstung */
|
||||||
if (rc->armor > 0) {
|
if (rc->armor > 0) {
|
||||||
bytes =
|
bytes =
|
||||||
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_armor"), rc->armor);
|
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_armor"), rc->armor);
|
||||||
|
@ -2659,7 +2660,7 @@ int combatspell_cmd(unit * u, struct order *ord)
|
||||||
init_order(ord);
|
init_order(ord);
|
||||||
s = gettoken(token, sizeof(token));
|
s = gettoken(token, sizeof(token));
|
||||||
|
|
||||||
/* KAMPFZAUBER [NICHT] löscht alle gesetzten Kampfzauber */
|
/* KAMPFZAUBER [NICHT] löscht alle gesetzten Kampfzauber */
|
||||||
if (!s || *s == 0 || findparam(s, u->faction->locale) == P_NOT) {
|
if (!s || *s == 0 || findparam(s, u->faction->locale) == P_NOT) {
|
||||||
unset_combatspell(u, 0);
|
unset_combatspell(u, 0);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2667,7 +2668,7 @@ int combatspell_cmd(unit * u, struct order *ord)
|
||||||
|
|
||||||
/* Optional: STUFE n */
|
/* Optional: STUFE n */
|
||||||
if (findparam(s, u->faction->locale) == P_LEVEL) {
|
if (findparam(s, u->faction->locale) == P_LEVEL) {
|
||||||
/* Merken, setzen kommt erst später */
|
/* Merken, setzen kommt erst später */
|
||||||
level = getint();
|
level = getint();
|
||||||
level = _max(0, level);
|
level = _max(0, level);
|
||||||
s = gettoken(token, sizeof(token));
|
s = gettoken(token, sizeof(token));
|
||||||
|
@ -2682,7 +2683,7 @@ int combatspell_cmd(unit * u, struct order *ord)
|
||||||
s = gettoken(token, sizeof(token));
|
s = gettoken(token, sizeof(token));
|
||||||
|
|
||||||
if (findparam(s, u->faction->locale) == P_NOT) {
|
if (findparam(s, u->faction->locale) == P_NOT) {
|
||||||
/* KAMPFZAUBER "<Spruchname>" NICHT löscht diesen speziellen
|
/* KAMPFZAUBER "<Spruchname>" NICHT löscht diesen speziellen
|
||||||
* Kampfzauber */
|
* Kampfzauber */
|
||||||
unset_combatspell(u, sp);
|
unset_combatspell(u, sp);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2697,7 +2698,7 @@ int combatspell_cmd(unit * u, struct order *ord)
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Beachten: einige Monster sollen auch unbewaffent die Region bewachen
|
/* Beachten: einige Monster sollen auch unbewaffent die Region bewachen
|
||||||
* können */
|
* können */
|
||||||
|
|
||||||
enum { E_GUARD_OK, E_GUARD_UNARMED, E_GUARD_NEWBIE, E_GUARD_FLEEING };
|
enum { E_GUARD_OK, E_GUARD_UNARMED, E_GUARD_NEWBIE, E_GUARD_FLEEING };
|
||||||
|
|
||||||
|
@ -2740,12 +2741,15 @@ void update_guards(void)
|
||||||
int guard_on_cmd(unit * u, struct order *ord)
|
int guard_on_cmd(unit * u, struct order *ord)
|
||||||
{
|
{
|
||||||
assert(getkeyword(ord) == K_GUARD);
|
assert(getkeyword(ord) == K_GUARD);
|
||||||
|
assert(u);
|
||||||
|
assert(u->faction);
|
||||||
|
|
||||||
init_order(ord);
|
init_order(ord);
|
||||||
|
|
||||||
/* GUARD NOT is handled in goard_off_cmd earlier in the turn */
|
/* GUARD NOT is handled in goard_off_cmd earlier in the turn */
|
||||||
if (getparam(u->faction->locale) == P_NOT)
|
if (getparam(u->faction->locale) == P_NOT) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (fval(u->region->terrain, SEA_REGION)) {
|
if (fval(u->region->terrain, SEA_REGION)) {
|
||||||
cmistake(u, ord, 2, MSG_EVENT);
|
cmistake(u, ord, 2, MSG_EVENT);
|
||||||
|
@ -2759,7 +2763,7 @@ int guard_on_cmd(unit * u, struct order *ord)
|
||||||
cmistake(u, ord, 95, MSG_EVENT);
|
cmistake(u, ord, 95, MSG_EVENT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Monster der Monsterpartei dürfen immer bewachen */
|
/* Monster der Monsterpartei dürfen immer bewachen */
|
||||||
if (is_monsters(u->faction)) {
|
if (is_monsters(u->faction)) {
|
||||||
guard(u, GUARD_ALL);
|
guard(u, GUARD_ALL);
|
||||||
}
|
}
|
||||||
|
@ -2793,7 +2797,7 @@ void sinkships(struct region * r)
|
||||||
if (!sh->type->construction || sh->size >= sh->type->construction->maxsize) {
|
if (!sh->type->construction || sh->size >= sh->type->construction->maxsize) {
|
||||||
if (fval(r->terrain, SEA_REGION) && (!enoughsailors(sh, r)
|
if (fval(r->terrain, SEA_REGION) && (!enoughsailors(sh, r)
|
||||||
|| get_captain(sh) == NULL)) {
|
|| get_captain(sh) == NULL)) {
|
||||||
/* Schiff nicht seetüchtig */
|
/* Schiff nicht seetüchtig */
|
||||||
float dmg = get_param_flt(global.parameters,
|
float dmg = get_param_flt(global.parameters,
|
||||||
"rules.ship.damage.nocrewocean",
|
"rules.ship.damage.nocrewocean",
|
||||||
0.30F);
|
0.30F);
|
||||||
|
@ -3250,7 +3254,7 @@ static void ageing(void)
|
||||||
sp = &(*sp)->next;
|
sp = &(*sp)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gebäude */
|
/* Gebäude */
|
||||||
for (bp = &r->buildings; *bp;) {
|
for (bp = &r->buildings; *bp;) {
|
||||||
building *b = *bp;
|
building *b = *bp;
|
||||||
age_building(b);
|
age_building(b);
|
||||||
|
@ -3456,7 +3460,7 @@ void update_long_order(unit * u)
|
||||||
freset(u, UFL_MOVED);
|
freset(u, UFL_MOVED);
|
||||||
freset(u, UFL_LONGACTION);
|
freset(u, UFL_LONGACTION);
|
||||||
if (hunger) {
|
if (hunger) {
|
||||||
/* Hungernde Einheiten führen NUR den default-Befehl aus */
|
/* Hungernde Einheiten führen NUR den default-Befehl aus */
|
||||||
set_order(&u->thisorder, default_order(u->faction->locale));
|
set_order(&u->thisorder, default_order(u->faction->locale));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3477,7 +3481,7 @@ void update_long_order(unit * u)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (is_exclusive(ord)) {
|
if (is_exclusive(ord)) {
|
||||||
/* Über dieser Zeile nur Befehle, die auch eine idle Faction machen darf */
|
/* Über dieser Zeile nur Befehle, die auch eine idle Faction machen darf */
|
||||||
if (idle(u->faction)) {
|
if (idle(u->faction)) {
|
||||||
set_order(&u->thisorder, default_order(u->faction->locale));
|
set_order(&u->thisorder, default_order(u->faction->locale));
|
||||||
}
|
}
|
||||||
|
@ -3489,13 +3493,13 @@ void update_long_order(unit * u)
|
||||||
else {
|
else {
|
||||||
keyword_t keyword = getkeyword(ord);
|
keyword_t keyword = getkeyword(ord);
|
||||||
switch (keyword) {
|
switch (keyword) {
|
||||||
/* Wenn gehandelt wird, darf kein langer Befehl ausgeführt
|
/* Wenn gehandelt wird, darf kein langer Befehl ausgeführt
|
||||||
* werden. Da Handel erst nach anderen langen Befehlen kommt,
|
* werden. Da Handel erst nach anderen langen Befehlen kommt,
|
||||||
* muß das vorher abgefangen werden. Wir merken uns also
|
* muß das vorher abgefangen werden. Wir merken uns also
|
||||||
* hier, ob die Einheit handelt. */
|
* hier, ob die Einheit handelt. */
|
||||||
case K_BUY:
|
case K_BUY:
|
||||||
case K_SELL:
|
case K_SELL:
|
||||||
/* Wenn die Einheit handelt, muß der Default-Befehl gelöscht
|
/* Wenn die Einheit handelt, muß der Default-Befehl gelöscht
|
||||||
* werden.
|
* werden.
|
||||||
* Wird je diese Ausschliesslichkeit aufgehoben, muss man aufpassen
|
* Wird je diese Ausschliesslichkeit aufgehoben, muss man aufpassen
|
||||||
* mit der Reihenfolge von Kaufen, Verkaufen etc., damit es Spielern
|
* mit der Reihenfolge von Kaufen, Verkaufen etc., damit es Spielern
|
||||||
|
@ -3505,7 +3509,7 @@ void update_long_order(unit * u)
|
||||||
|
|
||||||
case K_CAST:
|
case K_CAST:
|
||||||
/* dient dazu, das neben Zaubern kein weiterer Befehl
|
/* dient dazu, das neben Zaubern kein weiterer Befehl
|
||||||
* ausgeführt werden kann, Zaubern ist ein kurzer Befehl */
|
* ausgeführt werden kann, Zaubern ist ein kurzer Befehl */
|
||||||
set_order(&u->thisorder, copy_order(ord));
|
set_order(&u->thisorder, copy_order(ord));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -3518,7 +3522,7 @@ void update_long_order(unit * u)
|
||||||
if (hunger) {
|
if (hunger) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/* Wenn die Einheit handelt, muß der Default-Befehl gelöscht
|
/* Wenn die Einheit handelt, muß der Default-Befehl gelöscht
|
||||||
* werden. */
|
* werden. */
|
||||||
|
|
||||||
if (trade) {
|
if (trade) {
|
||||||
|
@ -3594,7 +3598,7 @@ void monthly_healing(void)
|
||||||
double healingcurse = 0;
|
double healingcurse = 0;
|
||||||
|
|
||||||
if (heal_ct != NULL) {
|
if (heal_ct != NULL) {
|
||||||
/* bonus zurücksetzen */
|
/* bonus zurücksetzen */
|
||||||
curse *c = get_curse(r->attribs, heal_ct);
|
curse *c = get_curse(r->attribs, heal_ct);
|
||||||
if (c != NULL) {
|
if (c != NULL) {
|
||||||
healingcurse = curse_geteffect(c);
|
healingcurse = curse_geteffect(c);
|
||||||
|
@ -3604,8 +3608,8 @@ void monthly_healing(void)
|
||||||
int umhp = unit_max_hp(u) * u->number;
|
int umhp = unit_max_hp(u) * u->number;
|
||||||
double p = 1.0;
|
double p = 1.0;
|
||||||
|
|
||||||
/* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht
|
/* hp über Maximum bauen sich ab. Wird zb durch Elixier der Macht
|
||||||
* oder verändertes Ausdauertalent verursacht */
|
* oder verändertes Ausdauertalent verursacht */
|
||||||
if (u->hp > umhp) {
|
if (u->hp > umhp) {
|
||||||
u->hp -= (int)ceil((u->hp - umhp) / 2.0);
|
u->hp -= (int)ceil((u->hp - umhp) / 2.0);
|
||||||
if (u->hp < umhp)
|
if (u->hp < umhp)
|
||||||
|
@ -3632,7 +3636,7 @@ void monthly_healing(void)
|
||||||
if (btype == bt_find("inn")) {
|
if (btype == bt_find("inn")) {
|
||||||
p *= 1.5;
|
p *= 1.5;
|
||||||
}
|
}
|
||||||
/* pro punkt 5% höher */
|
/* pro punkt 5% höher */
|
||||||
p *= (1.0 + healingcurse * 0.05);
|
p *= (1.0 + healingcurse * 0.05);
|
||||||
|
|
||||||
maxheal = p * maxheal;
|
maxheal = p * maxheal;
|
||||||
|
@ -3644,7 +3648,7 @@ void monthly_healing(void)
|
||||||
/* Aufaddieren der geheilten HP. */
|
/* Aufaddieren der geheilten HP. */
|
||||||
u->hp = _min(u->hp + addhp, umhp);
|
u->hp = _min(u->hp + addhp, umhp);
|
||||||
|
|
||||||
/* soll man an negativer regeneration sterben können? */
|
/* soll man an negativer regeneration sterben können? */
|
||||||
assert(u->hp > 0);
|
assert(u->hp > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3691,7 +3695,7 @@ void defaultorders(void)
|
||||||
ord->next = NULL;
|
ord->next = NULL;
|
||||||
free_order(ord);
|
free_order(ord);
|
||||||
if (!neworders) {
|
if (!neworders) {
|
||||||
/* lange Befehle aus orders und old_orders löschen zu gunsten des neuen */
|
/* lange Befehle aus orders und old_orders löschen zu gunsten des neuen */
|
||||||
remove_exclusive(&u->orders);
|
remove_exclusive(&u->orders);
|
||||||
remove_exclusive(&u->old_orders);
|
remove_exclusive(&u->old_orders);
|
||||||
neworders = true;
|
neworders = true;
|
||||||
|
@ -4564,8 +4568,8 @@ void processorders(void)
|
||||||
wormholes_update();
|
wormholes_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* immer ausführen, wenn neue Sprüche dazugekommen sind, oder sich
|
/* immer ausführen, wenn neue Sprüche dazugekommen sind, oder sich
|
||||||
* Beschreibungen geändert haben */
|
* Beschreibungen geändert haben */
|
||||||
update_spells();
|
update_spells();
|
||||||
warn_password();
|
warn_password();
|
||||||
}
|
}
|
||||||
|
|
224
src/magic.c
224
src/magic.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2014,
|
Copyright (c) 1998-2014,
|
||||||
Enno Rehling <enno@eressea.de>
|
Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
|
@ -193,7 +193,7 @@ attrib_type at_icastle = {
|
||||||
extern int dice(int count, int value);
|
extern int dice(int count, int value);
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* aus dem alten System übriggebliegene Funktionen, die bei der
|
/* aus dem alten System übriggebliegene Funktionen, die bei der
|
||||||
* Umwandlung von alt nach neu gebraucht werden */
|
* Umwandlung von alt nach neu gebraucht werden */
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
|
@ -352,9 +352,9 @@ sc_mage *get_mage(const unit * u)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Ausgabe der Spruchbeschreibungen
|
/* Ausgabe der Spruchbeschreibungen
|
||||||
* Anzeige des Spruchs nur, wenn die Stufe des besten Magiers vorher
|
* Anzeige des Spruchs nur, wenn die Stufe des besten Magiers vorher
|
||||||
* kleiner war (u->faction->seenspells). Ansonsten muss nur geprüft
|
* kleiner war (u->faction->seenspells). Ansonsten muss nur geprüft
|
||||||
* werden, ob dieser Magier den Spruch schon kennt, und andernfalls der
|
* werden, ob dieser Magier den Spruch schon kennt, und andernfalls der
|
||||||
* Spruch zu seiner List-of-known-spells hinzugefügt werden.
|
* Spruch zu seiner List-of-known-spells hinzugefügt werden.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int read_seenspell(attrib * a, void *owner, struct storage *store)
|
static int read_seenspell(attrib * a, void *owner, struct storage *store)
|
||||||
|
@ -507,7 +507,7 @@ sc_mage *create_mage(unit * u, magic_t mtyp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Funktionen für die Bearbeitung der List-of-known-spells */
|
/* Funktionen für die Bearbeitung der List-of-known-spells */
|
||||||
|
|
||||||
int u_hasspell(const unit *u, const struct spell *sp)
|
int u_hasspell(const unit *u, const struct spell *sp)
|
||||||
{
|
{
|
||||||
|
@ -535,7 +535,7 @@ int get_combatspelllevel(const unit * u, int nr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Kampfzauber ermitteln, setzen oder löschen */
|
/* Kampfzauber ermitteln, setzen oder löschen */
|
||||||
|
|
||||||
const spell *get_combatspell(const unit * u, int nr)
|
const spell *get_combatspell(const unit * u, int nr)
|
||||||
{
|
{
|
||||||
|
@ -560,7 +560,7 @@ void set_combatspell(unit * u, spell * sp, struct order *ord, int level)
|
||||||
|
|
||||||
assert(mage || !"trying to set a combat spell for non-mage");
|
assert(mage || !"trying to set a combat spell for non-mage");
|
||||||
|
|
||||||
/* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */
|
/* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */
|
||||||
if (!knowsspell(u->region, u, sp)) {
|
if (!knowsspell(u->region, u, sp)) {
|
||||||
/* Fehler 'Spell not found' */
|
/* Fehler 'Spell not found' */
|
||||||
cmistake(u, ord, 173, MSG_MAGIC);
|
cmistake(u, ord, 173, MSG_MAGIC);
|
||||||
|
@ -626,7 +626,7 @@ void unset_combatspell(unit * u, spell * sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Gibt die aktuelle Anzahl der Magiepunkte der Einheit zurück */
|
/* Gibt die aktuelle Anzahl der Magiepunkte der Einheit zurück */
|
||||||
int get_spellpoints(const unit * u)
|
int get_spellpoints(const unit * u)
|
||||||
{
|
{
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
|
@ -652,7 +652,7 @@ void set_spellpoints(unit * u, int sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* verändert die Anzahl der Magiepunkte der Einheit um +mp
|
* verändert die Anzahl der Magiepunkte der Einheit um +mp
|
||||||
*/
|
*/
|
||||||
int change_spellpoints(unit * u, int mp)
|
int change_spellpoints(unit * u, int mp)
|
||||||
{
|
{
|
||||||
|
@ -671,7 +671,7 @@ int change_spellpoints(unit * u, int mp)
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bietet die Möglichkeit, die maximale Anzahl der Magiepunkte mit
|
/* bietet die Möglichkeit, die maximale Anzahl der Magiepunkte mit
|
||||||
* Regionszaubern oder Attributen zu beinflussen
|
* Regionszaubern oder Attributen zu beinflussen
|
||||||
*/
|
*/
|
||||||
static int get_spchange(const unit * u)
|
static int get_spchange(const unit * u)
|
||||||
|
@ -687,13 +687,13 @@ static int get_spchange(const unit * u)
|
||||||
|
|
||||||
/* ein Magier kann normalerweise maximal Stufe^2.1/1.2+1 Magiepunkte
|
/* ein Magier kann normalerweise maximal Stufe^2.1/1.2+1 Magiepunkte
|
||||||
* haben.
|
* haben.
|
||||||
* Manche Rassen haben einen zusätzlichen Multiplikator
|
* Manche Rassen haben einen zusätzlichen Multiplikator
|
||||||
* Durch Talentverlust (zB Insekten im Berg) können negative Werte
|
* Durch Talentverlust (zB Insekten im Berg) können negative Werte
|
||||||
* entstehen
|
* entstehen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Artefakt der Stärke
|
/* Artefakt der Stärke
|
||||||
* Ermöglicht dem Magier mehr Magiepunkte zu 'speichern'
|
* Ermöglicht dem Magier mehr Magiepunkte zu 'speichern'
|
||||||
*/
|
*/
|
||||||
/** TODO: at_skillmod daraus machen */
|
/** TODO: at_skillmod daraus machen */
|
||||||
static int use_item_aura(const region * r, const unit * u)
|
static int use_item_aura(const region * r, const unit * u)
|
||||||
|
@ -741,8 +741,8 @@ int change_maxspellpoints(unit * u, int csp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Counter für die bereits gezauberte Anzahl Sprüche pro Runde.
|
/* Counter für die bereits gezauberte Anzahl Sprüche pro Runde.
|
||||||
* Um nur die Zahl der bereits gezauberten Sprüche zu ermitteln mit
|
* Um nur die Zahl der bereits gezauberten Sprüche zu ermitteln mit
|
||||||
* step = 0 aufrufen.
|
* step = 0 aufrufen.
|
||||||
*/
|
*/
|
||||||
int countspells(unit * u, int step)
|
int countspells(unit * u, int step)
|
||||||
|
@ -766,9 +766,9 @@ int countspells(unit * u, int step)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Die für den Spruch benötigte Aura pro Stufe.
|
/* Die für den Spruch benötigte Aura pro Stufe.
|
||||||
* Die Grundkosten pro Stufe werden hier um 2^count erhöht. Der
|
* Die Grundkosten pro Stufe werden hier um 2^count erhöht. Der
|
||||||
* Parameter count ist dabei die Anzahl der bereits gezauberten Sprüche
|
* Parameter count ist dabei die Anzahl der bereits gezauberten Sprüche
|
||||||
*/
|
*/
|
||||||
int spellcost(unit * u, const spell * sp)
|
int spellcost(unit * u, const spell * sp)
|
||||||
{
|
{
|
||||||
|
@ -786,12 +786,12 @@ int spellcost(unit * u, const spell * sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* SPC_LINEAR ist am höchstwertigen, dann müssen Komponenten für die
|
/* SPC_LINEAR ist am höchstwertigen, dann müssen Komponenten für die
|
||||||
* Stufe des Magiers vorhanden sein.
|
* Stufe des Magiers vorhanden sein.
|
||||||
* SPC_LINEAR hat die gewünschte Stufe als multiplikator,
|
* SPC_LINEAR hat die gewünschte Stufe als multiplikator,
|
||||||
* nur SPC_FIX muss nur einmal vorhanden sein, ist also am
|
* nur SPC_FIX muss nur einmal vorhanden sein, ist also am
|
||||||
* niedrigstwertigen und sollte von den beiden anderen Typen
|
* niedrigstwertigen und sollte von den beiden anderen Typen
|
||||||
* überschrieben werden */
|
* überschrieben werden */
|
||||||
static int spl_costtyp(const spell * sp)
|
static int spl_costtyp(const spell * sp)
|
||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
|
@ -805,7 +805,7 @@ static int spl_costtyp(const spell * sp)
|
||||||
return SPC_LINEAR;
|
return SPC_LINEAR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wenn keine Fixkosten, Typ übernehmen */
|
/* wenn keine Fixkosten, Typ übernehmen */
|
||||||
if (sp->components[k].cost != SPC_FIX) {
|
if (sp->components[k].cost != SPC_FIX) {
|
||||||
costtyp = sp->components[k].cost;
|
costtyp = sp->components[k].cost;
|
||||||
}
|
}
|
||||||
|
@ -814,10 +814,10 @@ static int spl_costtyp(const spell * sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* durch Komponenten und cast_level begrenzter maximal möglicher
|
/* durch Komponenten und cast_level begrenzter maximal möglicher
|
||||||
* Level
|
* Level
|
||||||
* Da die Funktion nicht alle Komponenten durchprobiert sondern beim
|
* Da die Funktion nicht alle Komponenten durchprobiert sondern beim
|
||||||
* ersten Fehler abbricht, muss die Fehlermeldung später mit cancast()
|
* ersten Fehler abbricht, muss die Fehlermeldung später mit cancast()
|
||||||
* generiert werden.
|
* generiert werden.
|
||||||
* */
|
* */
|
||||||
int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range)
|
int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range)
|
||||||
|
@ -831,8 +831,8 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (sp->components[k].amount > 0) {
|
if (sp->components[k].amount > 0) {
|
||||||
/* Die Kosten für Aura sind auch von der Zahl der bereits
|
/* Die Kosten für Aura sind auch von der Zahl der bereits
|
||||||
* gezauberten Sprüche abhängig */
|
* gezauberten Sprüche abhängig */
|
||||||
if (sp->components[k].type == r_aura) {
|
if (sp->components[k].type == r_aura) {
|
||||||
needplevel = spellcost(u, sp) * range;
|
needplevel = spellcost(u, sp) * range;
|
||||||
}
|
}
|
||||||
|
@ -844,18 +844,18 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range)
|
||||||
needplevel * cast_level) / needplevel;
|
needplevel * cast_level) / needplevel;
|
||||||
|
|
||||||
/* sind die Kosten fix, so muss die Komponente nur einmal vorhanden
|
/* sind die Kosten fix, so muss die Komponente nur einmal vorhanden
|
||||||
* sein und der cast_level ändert sich nicht */
|
* sein und der cast_level ändert sich nicht */
|
||||||
if (sp->components[k].cost == SPC_FIX) {
|
if (sp->components[k].cost == SPC_FIX) {
|
||||||
if (maxlevel < 1)
|
if (maxlevel < 1)
|
||||||
cast_level = 0;
|
cast_level = 0;
|
||||||
/* ansonsten wird das Minimum aus maximal möglicher Stufe und der
|
/* ansonsten wird das Minimum aus maximal möglicher Stufe und der
|
||||||
* gewünschten gebildet */
|
* gewünschten gebildet */
|
||||||
}
|
}
|
||||||
else if (sp->components[k].cost == SPC_LEVEL) {
|
else if (sp->components[k].cost == SPC_LEVEL) {
|
||||||
costtyp = SPC_LEVEL;
|
costtyp = SPC_LEVEL;
|
||||||
cast_level = _min(cast_level, maxlevel);
|
cast_level = _min(cast_level, maxlevel);
|
||||||
/* bei Typ Linear müssen die Kosten in Höhe der Stufe vorhanden
|
/* bei Typ Linear müssen die Kosten in Höhe der Stufe vorhanden
|
||||||
* sein, ansonsten schlägt der Spruch fehl */
|
* sein, ansonsten schlägt der Spruch fehl */
|
||||||
}
|
}
|
||||||
else if (sp->components[k].cost == SPC_LINEAR) {
|
else if (sp->components[k].cost == SPC_LINEAR) {
|
||||||
costtyp = SPC_LINEAR;
|
costtyp = SPC_LINEAR;
|
||||||
|
@ -882,7 +882,7 @@ int eff_spelllevel(unit * u, const spell * sp, int cast_level, int range)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Die Spruchgrundkosten werden mit der Entfernung (Farcasting)
|
/* Die Spruchgrundkosten werden mit der Entfernung (Farcasting)
|
||||||
* multipliziert, wobei die Aurakosten ein Sonderfall sind, da sie sich
|
* multipliziert, wobei die Aurakosten ein Sonderfall sind, da sie sich
|
||||||
* auch durch die Menge der bereits gezauberten Sprüche erhöht.
|
* auch durch die Menge der bereits gezauberten Sprüche erhöht.
|
||||||
* Je nach Kostenart werden dann die Komponenten noch mit cast_level
|
* Je nach Kostenart werden dann die Komponenten noch mit cast_level
|
||||||
* multipliziert.
|
* multipliziert.
|
||||||
*/
|
*/
|
||||||
|
@ -913,12 +913,12 @@ void pay_spell(unit * u, const spell * sp, int cast_level, int range)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Ein Magier kennt den Spruch und kann sich die Beschreibung anzeigen
|
/* Ein Magier kennt den Spruch und kann sich die Beschreibung anzeigen
|
||||||
* lassen, wenn diese in seiner Spruchliste steht. Zaubern muss er ihn
|
* lassen, wenn diese in seiner Spruchliste steht. Zaubern muss er ihn
|
||||||
* aber dann immer noch nicht können, vieleicht ist seine Stufe derzeit
|
* aber dann immer noch nicht können, vieleicht ist seine Stufe derzeit
|
||||||
* nicht ausreichend oder die Komponenten fehlen.
|
* nicht ausreichend oder die Komponenten fehlen.
|
||||||
*/
|
*/
|
||||||
bool knowsspell(const region * r, const unit * u, const spell * sp)
|
bool knowsspell(const region * r, const unit * u, const spell * sp)
|
||||||
{
|
{
|
||||||
/* Ist überhaupt ein gültiger Spruch angegeben? */
|
/* Ist überhaupt ein gültiger Spruch angegeben? */
|
||||||
if (!sp || sp->id == 0) {
|
if (!sp || sp->id == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -929,7 +929,7 @@ bool knowsspell(const region * r, const unit * u, const spell * sp)
|
||||||
/* Um einen Spruch zu beherrschen, muss der Magier die Stufe des
|
/* Um einen Spruch zu beherrschen, muss der Magier die Stufe des
|
||||||
* Spruchs besitzen, nicht nur wissen, das es ihn gibt (also den Spruch
|
* Spruchs besitzen, nicht nur wissen, das es ihn gibt (also den Spruch
|
||||||
* in seiner Spruchliste haben).
|
* in seiner Spruchliste haben).
|
||||||
* Kosten für einen Spruch können Magiepunkte, Silber, Kraeuter
|
* Kosten für einen Spruch können Magiepunkte, Silber, Kraeuter
|
||||||
* und sonstige Gegenstaende sein.
|
* und sonstige Gegenstaende sein.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -948,7 +948,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord)
|
||||||
}
|
}
|
||||||
/* reicht die Stufe aus? */
|
/* reicht die Stufe aus? */
|
||||||
if (eff_skill(u, SK_MAGIC, u->region) < level) {
|
if (eff_skill(u, SK_MAGIC, u->region) < level) {
|
||||||
/* die Einheit ist nicht erfahren genug für diesen Zauber */
|
/* die Einheit ist nicht erfahren genug für diesen Zauber */
|
||||||
cmistake(u, ord, 169, MSG_MAGIC);
|
cmistake(u, ord, 169, MSG_MAGIC);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -958,8 +958,8 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord)
|
||||||
const resource_type *rtype = sp->components[k].type;
|
const resource_type *rtype = sp->components[k].type;
|
||||||
int itemhave;
|
int itemhave;
|
||||||
|
|
||||||
/* Die Kosten für Aura sind auch von der Zahl der bereits
|
/* Die Kosten für Aura sind auch von der Zahl der bereits
|
||||||
* gezauberten Sprüche abhängig */
|
* gezauberten Sprüche abhängig */
|
||||||
if (rtype == r_aura) {
|
if (rtype == r_aura) {
|
||||||
itemanz = spellcost(u, sp) * range;
|
itemanz = spellcost(u, sp) * range;
|
||||||
}
|
}
|
||||||
|
@ -967,7 +967,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord)
|
||||||
itemanz = sp->components[k].amount * range;
|
itemanz = sp->components[k].amount * range;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sind die Kosten stufenabhängig, so muss itemanz noch mit dem
|
/* sind die Kosten stufenabhängig, so muss itemanz noch mit dem
|
||||||
* level multipliziert werden */
|
* level multipliziert werden */
|
||||||
switch (sp->components[k].cost) {
|
switch (sp->components[k].cost) {
|
||||||
case SPC_LEVEL:
|
case SPC_LEVEL:
|
||||||
|
@ -1004,7 +1004,7 @@ cancast(unit * u, const spell * sp, int level, int range, struct order * ord)
|
||||||
* Spruchitems und Antimagiefeldern zusammen. Es koennen noch die
|
* Spruchitems und Antimagiefeldern zusammen. Es koennen noch die
|
||||||
* Stufe des Spruchs und Magiekosten mit einfliessen.
|
* Stufe des Spruchs und Magiekosten mit einfliessen.
|
||||||
*
|
*
|
||||||
* Die effektive Spruchstärke und ihre Auswirkungen werden in der
|
* Die effektive Spruchstärke und ihre Auswirkungen werden in der
|
||||||
* Spruchfunktionsroutine ermittelt.
|
* Spruchfunktionsroutine ermittelt.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1080,7 +1080,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* farcasting() == 1 -> gleiche Region, da man mit Null nicht vernünfigt
|
/* farcasting() == 1 -> gleiche Region, da man mit Null nicht vernünfigt
|
||||||
* rechnen kann */
|
* rechnen kann */
|
||||||
static int farcasting(unit * magician, region * r)
|
static int farcasting(unit * magician, region * r)
|
||||||
{
|
{
|
||||||
|
@ -1166,7 +1166,7 @@ double magic_resistance(unit * target)
|
||||||
/* Bonus durch Artefakte */
|
/* Bonus durch Artefakte */
|
||||||
/* TODO (noch gibs keine) */
|
/* TODO (noch gibs keine) */
|
||||||
|
|
||||||
/* Bonus durch Gebäude */
|
/* Bonus durch Gebäude */
|
||||||
{
|
{
|
||||||
struct building *b = inside_building(target);
|
struct building *b = inside_building(target);
|
||||||
const struct building_type *btype = b ? b->type : NULL;
|
const struct building_type *btype = b ? b->type : NULL;
|
||||||
|
@ -1179,14 +1179,14 @@ double magic_resistance(unit * target)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Prüft, ob das Objekt dem Zauber widerstehen kann.
|
/* Prüft, ob das Objekt dem Zauber widerstehen kann.
|
||||||
* Objekte können Regionen, Units, Gebäude oder Schiffe sein.
|
* Objekte können Regionen, Units, Gebäude oder Schiffe sein.
|
||||||
* TYP_UNIT:
|
* TYP_UNIT:
|
||||||
* Das höchste Talent des Ziels ist sein 'Magieresistenz-Talent', Magier
|
* Das höchste Talent des Ziels ist sein 'Magieresistenz-Talent', Magier
|
||||||
* bekommen einen Bonus. Grundchance ist 50%, für jede Stufe
|
* bekommen einen Bonus. Grundchance ist 50%, für jede Stufe
|
||||||
* Unterschied gibt es 5%, minimalchance ist 5% für jeden (5-95%)
|
* Unterschied gibt es 5%, minimalchance ist 5% für jeden (5-95%)
|
||||||
* Scheitert der Spruch an der Magieresistenz, so gibt die Funktion
|
* Scheitert der Spruch an der Magieresistenz, so gibt die Funktion
|
||||||
* true zurück
|
* true zurück
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1248,8 +1248,8 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus)
|
||||||
probability = _min(0.98, probability);
|
probability = _min(0.98, probability);
|
||||||
|
|
||||||
/* gibt true, wenn die Zufallszahl kleiner als die chance ist und
|
/* gibt true, wenn die Zufallszahl kleiner als die chance ist und
|
||||||
* false, wenn sie gleich oder größer ist, dh je größer die
|
* false, wenn sie gleich oder größer ist, dh je größer die
|
||||||
* Magieresistenz (chance) desto eher gibt die Funktion true zurück */
|
* Magieresistenz (chance) desto eher gibt die Funktion true zurück */
|
||||||
return chance(probability);
|
return chance(probability);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1276,7 +1276,7 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade)
|
||||||
{
|
{
|
||||||
/* X ergibt Zahl zwischen 1 und 0, je kleiner, desto besser der Magier.
|
/* X ergibt Zahl zwischen 1 und 0, je kleiner, desto besser der Magier.
|
||||||
* 0,5*40-20=0, dh wenn der Magier doppelt so gut ist, wie der Spruch
|
* 0,5*40-20=0, dh wenn der Magier doppelt so gut ist, wie der Spruch
|
||||||
* benötigt, gelingt er immer, ist er gleich gut, gelingt der Spruch mit
|
* benötigt, gelingt er immer, ist er gleich gut, gelingt der Spruch mit
|
||||||
* 20% Warscheinlichkeit nicht
|
* 20% Warscheinlichkeit nicht
|
||||||
* */
|
* */
|
||||||
|
|
||||||
|
@ -1306,8 +1306,8 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade)
|
||||||
fumble_chance += CHAOSPATZERCHANCE;
|
fumble_chance += CHAOSPATZERCHANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wenn die Chance kleiner als 0 ist, können wir gleich false
|
/* wenn die Chance kleiner als 0 ist, können wir gleich false
|
||||||
* zurückgeben */
|
* zurückgeben */
|
||||||
if (fumble_chance <= 0) {
|
if (fumble_chance <= 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1317,7 +1317,7 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Dummy-Zauberpatzer, Platzhalter für speziel auf die Sprüche
|
/* Dummy-Zauberpatzer, Platzhalter für speziel auf die Sprüche
|
||||||
* zugeschnittene Patzer */
|
* zugeschnittene Patzer */
|
||||||
static void fumble_default(castorder * co)
|
static void fumble_default(castorder * co)
|
||||||
{
|
{
|
||||||
|
@ -1328,7 +1328,7 @@ static void fumble_default(castorder * co)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Die normalen Spruchkosten müssen immer bezahlt werden, hier noch
|
/* Die normalen Spruchkosten müssen immer bezahlt werden, hier noch
|
||||||
* alle weiteren Folgen eines Patzers
|
* alle weiteren Folgen eines Patzers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1390,7 +1390,7 @@ static void do_fumble(castorder * co)
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
case 4:
|
case 4:
|
||||||
/* Spruch schlägt fehl, alle Magiepunkte weg */
|
/* Spruch schlägt fehl, alle Magiepunkte weg */
|
||||||
set_spellpoints(u, 0);
|
set_spellpoints(u, 0);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("patzer3", "unit region spell",
|
ADDMSG(&u->faction->msgs, msg_message("patzer3", "unit region spell",
|
||||||
u, r, sp));
|
u, r, sp));
|
||||||
|
@ -1409,7 +1409,7 @@ static void do_fumble(castorder * co)
|
||||||
case 8:
|
case 8:
|
||||||
case 9:
|
case 9:
|
||||||
default:
|
default:
|
||||||
/* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */
|
/* Spruch gelingt, alle nachfolgenden Sprüche werden 2^4 so teuer */
|
||||||
co->level = sp->cast(co);
|
co->level = sp->cast(co);
|
||||||
ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell",
|
ADDMSG(&u->faction->msgs, msg_message("patzer5", "unit region spell",
|
||||||
u, r, sp));
|
u, r, sp));
|
||||||
|
@ -1422,7 +1422,7 @@ static void do_fumble(castorder * co)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
/* Ein Magier regeneriert pro Woche W(Stufe^1.5/2+1), mindestens 1
|
/* Ein Magier regeneriert pro Woche W(Stufe^1.5/2+1), mindestens 1
|
||||||
* Zwerge nur die Hälfte
|
* Zwerge nur die Hälfte
|
||||||
*/
|
*/
|
||||||
static double regeneration(unit * u)
|
static double regeneration(unit * u)
|
||||||
{
|
{
|
||||||
|
@ -1439,7 +1439,7 @@ static double regeneration(unit * u)
|
||||||
/* Einfluss von Artefakten */
|
/* Einfluss von Artefakten */
|
||||||
/* TODO (noch gibs keine) */
|
/* TODO (noch gibs keine) */
|
||||||
|
|
||||||
/* Würfeln */
|
/* Würfeln */
|
||||||
aura = (rng_double() * d + rng_double() * d) / 2 + 1;
|
aura = (rng_double() * d + rng_double() * d) / 2 + 1;
|
||||||
|
|
||||||
aura *= MagicRegeneration();
|
aura *= MagicRegeneration();
|
||||||
|
@ -1469,8 +1469,8 @@ void regenerate_aura(void)
|
||||||
const struct building_type *btype = b ? b->type : NULL;
|
const struct building_type *btype = b ? b->type : NULL;
|
||||||
reg_aura = regeneration(u);
|
reg_aura = regeneration(u);
|
||||||
|
|
||||||
/* Magierturm erhöht die Regeneration um 75% */
|
/* Magierturm erhöht die Regeneration um 75% */
|
||||||
/* Steinkreis erhöht die Regeneration um 50% */
|
/* Steinkreis erhöht die Regeneration um 50% */
|
||||||
if (btype)
|
if (btype)
|
||||||
reg_aura *= btype->auraregen;
|
reg_aura *= btype->auraregen;
|
||||||
|
|
||||||
|
@ -1609,14 +1609,14 @@ order * ord)
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Zuerst wird versucht alle noch nicht gefundenen Objekte zu finden
|
/* Zuerst wird versucht alle noch nicht gefundenen Objekte zu finden
|
||||||
* oder zu prüfen, ob das gefundene Objekt wirklich hätte gefunden
|
* oder zu prüfen, ob das gefundene Objekt wirklich hätte gefunden
|
||||||
* werden dürfen (nicht alle Zauber wirken global). Dabei zählen wir die
|
* werden dürfen (nicht alle Zauber wirken global). Dabei zählen wir die
|
||||||
* Misserfolge (failed).
|
* Misserfolge (failed).
|
||||||
* Dann folgen die Tests der gefundenen Objekte auf Magieresistenz und
|
* Dann folgen die Tests der gefundenen Objekte auf Magieresistenz und
|
||||||
* Sichtbarkeit. Dabei zählen wir die magieresistenten (resists)
|
* Sichtbarkeit. Dabei zählen wir die magieresistenten (resists)
|
||||||
* Objekte. Alle anderen werten wir als Erfolge (success) */
|
* Objekte. Alle anderen werten wir als Erfolge (success) */
|
||||||
|
|
||||||
/* gibt bei Misserfolg 0 zurück, bei Magieresistenz zumindeste eines
|
/* gibt bei Misserfolg 0 zurück, bei Magieresistenz zumindeste eines
|
||||||
* Objektes 1 und bei Erfolg auf ganzer Linie 2 */
|
* Objektes 1 und bei Erfolg auf ganzer Linie 2 */
|
||||||
static void
|
static void
|
||||||
verify_targets(castorder * co, int *invalid, int *resist, int *success)
|
verify_targets(castorder * co, int *invalid, int *resist, int *success)
|
||||||
|
@ -1634,8 +1634,8 @@ verify_targets(castorder * co, int *invalid, int *resist, int *success)
|
||||||
if (sa && sa->length) {
|
if (sa && sa->length) {
|
||||||
/* zuerst versuchen wir vorher nicht gefundene Objekte zu finden.
|
/* zuerst versuchen wir vorher nicht gefundene Objekte zu finden.
|
||||||
* Wurde ein Objekt durch globalsuche gefunden, obwohl der Zauber
|
* Wurde ein Objekt durch globalsuche gefunden, obwohl der Zauber
|
||||||
* gar nicht global hätte suchen dürften, setzen wir das Objekt
|
* gar nicht global hätte suchen dürften, setzen wir das Objekt
|
||||||
* zurück. */
|
* zurück. */
|
||||||
for (i = 0; i < sa->length; i++) {
|
for (i = 0; i < sa->length; i++) {
|
||||||
spllprm *spobj = sa->param[i];
|
spllprm *spobj = sa->param[i];
|
||||||
|
|
||||||
|
@ -1719,7 +1719,7 @@ verify_targets(castorder * co, int *invalid, int *resist, int *success)
|
||||||
|
|
||||||
case SPP_REGION:
|
case SPP_REGION:
|
||||||
/* haben wir ein Regionsobjekt, dann wird auch dieses und
|
/* haben wir ein Regionsobjekt, dann wird auch dieses und
|
||||||
nicht target_r überprüft. */
|
nicht target_r überprüft. */
|
||||||
tr = spobj->data.r;
|
tr = spobj->data.r;
|
||||||
|
|
||||||
if ((sp->sptyp & TESTRESISTANCE)
|
if ((sp->sptyp & TESTRESISTANCE)
|
||||||
|
@ -1745,7 +1745,7 @@ verify_targets(castorder * co, int *invalid, int *resist, int *success)
|
||||||
else {
|
else {
|
||||||
/* der Zauber hat keine expliziten Parameter/Ziele, es kann sich
|
/* der Zauber hat keine expliziten Parameter/Ziele, es kann sich
|
||||||
* aber um einen Regionszauber handeln. Wenn notwendig hier die
|
* aber um einen Regionszauber handeln. Wenn notwendig hier die
|
||||||
* Magieresistenz der Region prüfen. */
|
* Magieresistenz der Region prüfen. */
|
||||||
if ((sp->sptyp & REGIONSPELL)) {
|
if ((sp->sptyp & REGIONSPELL)) {
|
||||||
/* Zielobjekt Region anlegen */
|
/* Zielobjekt Region anlegen */
|
||||||
spllprm *spobj = (spllprm *)malloc(sizeof(spllprm));
|
spllprm *spobj = (spllprm *)malloc(sizeof(spllprm));
|
||||||
|
@ -1782,16 +1782,17 @@ verify_targets(castorder * co, int *invalid, int *resist, int *success)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Hilfsstrukturen für ZAUBERE */
|
/* Hilfsstrukturen für ZAUBERE */
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
|
|
||||||
static void free_spellparameter(spellparameter * pa)
|
static void free_spellparameter(spellparameter * pa)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Elemente free'en */
|
assert(pa->param);
|
||||||
for (i = 0; i < pa->length; i++) {
|
|
||||||
|
|
||||||
|
for (i = 0; i < pa->length; i++) {
|
||||||
|
assert(pa->param[i]);
|
||||||
switch (pa->param[i]->typ) {
|
switch (pa->param[i]->typ) {
|
||||||
case SPP_STRING:
|
case SPP_STRING:
|
||||||
free(pa->param[i]->data.s);
|
free(pa->param[i]->data.s);
|
||||||
|
@ -1801,10 +1802,7 @@ static void free_spellparameter(spellparameter * pa)
|
||||||
}
|
}
|
||||||
free(pa->param[i]);
|
free(pa->param[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pa->param)
|
|
||||||
free(pa->param);
|
free(pa->param);
|
||||||
/* struct free'en */
|
|
||||||
free(pa);
|
free(pa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1966,7 +1964,7 @@ static spellparameter *add_spellparameter(region * target_r, unit * u,
|
||||||
break;
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
/* das vorhergehende Element kommt ein oder mehrmals vor, wir
|
/* das vorhergehende Element kommt ein oder mehrmals vor, wir
|
||||||
* springen zum key zurück */
|
* springen zum key zurück */
|
||||||
j = 0;
|
j = 0;
|
||||||
--c;
|
--c;
|
||||||
break;
|
break;
|
||||||
|
@ -2090,7 +2088,7 @@ void free_castorder(struct castorder *co)
|
||||||
if (co->order) free_order(co->order);
|
if (co->order) free_order(co->order);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hänge c-order co an die letze c-order von cll an */
|
/* Hänge c-order co an die letze c-order von cll an */
|
||||||
void add_castorder(spellrank * cll, castorder * co)
|
void add_castorder(spellrank * cll, castorder * co)
|
||||||
{
|
{
|
||||||
if (cll->begin == NULL) {
|
if (cll->begin == NULL) {
|
||||||
|
@ -2521,7 +2519,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
init_order(ord);
|
init_order(ord);
|
||||||
s = gettoken(token, sizeof(token));
|
s = gettoken(token, sizeof(token));
|
||||||
param = findparam(s, u->faction->locale);
|
param = findparam(s, u->faction->locale);
|
||||||
/* für Syntax ' STUFE x REGION y z ' */
|
/* für Syntax ' STUFE x REGION y z ' */
|
||||||
if (param == P_LEVEL) {
|
if (param == P_LEVEL) {
|
||||||
int p = getint();
|
int p = getint();
|
||||||
level = _min(p, level);
|
level = _min(p, level);
|
||||||
|
@ -2550,8 +2548,8 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
s = gettoken(token, sizeof(token));
|
s = gettoken(token, sizeof(token));
|
||||||
param = findparam(s, u->faction->locale);
|
param = findparam(s, u->faction->locale);
|
||||||
}
|
}
|
||||||
/* für Syntax ' REGION x y STUFE z '
|
/* für Syntax ' REGION x y STUFE z '
|
||||||
* hier nach REGION nochmal auf STUFE prüfen */
|
* hier nach REGION nochmal auf STUFE prüfen */
|
||||||
if (param == P_LEVEL) {
|
if (param == P_LEVEL) {
|
||||||
int p = getint();
|
int p = getint();
|
||||||
level = _min(p, level);
|
level = _min(p, level);
|
||||||
|
@ -2570,8 +2568,8 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
|
|
||||||
sp = unit_getspell(u, s, u->faction->locale);
|
sp = unit_getspell(u, s, u->faction->locale);
|
||||||
|
|
||||||
/* Vertraute können auch Zauber sprechen, die sie selbst nicht
|
/* Vertraute können auch Zauber sprechen, die sie selbst nicht
|
||||||
* können. unit_getspell findet aber nur jene Sprüche, die
|
* können. unit_getspell findet aber nur jene Sprüche, die
|
||||||
* die Einheit beherrscht. */
|
* die Einheit beherrscht. */
|
||||||
if (!sp && is_familiar(u)) {
|
if (!sp && is_familiar(u)) {
|
||||||
caster = get_familiar_mage(u);
|
caster = get_familiar_mage(u);
|
||||||
|
@ -2594,7 +2592,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
/* um testen auf spruchnamen zu unterbinden sollte vor allen
|
/* um testen auf spruchnamen zu unterbinden sollte vor allen
|
||||||
* fehlermeldungen die anzeigen das der magier diesen Spruch
|
* fehlermeldungen die anzeigen das der magier diesen Spruch
|
||||||
* nur in diese Situation nicht anwenden kann, noch eine
|
* nur in diese Situation nicht anwenden kann, noch eine
|
||||||
* einfache Sicherheitsprüfung kommen */
|
* einfache Sicherheitsprüfung kommen */
|
||||||
if (!knowsspell(r, u, sp)) {
|
if (!knowsspell(r, u, sp)) {
|
||||||
/* vorsicht! u kann der familiar sein */
|
/* vorsicht! u kann der familiar sein */
|
||||||
if (!familiar) {
|
if (!familiar) {
|
||||||
|
@ -2607,9 +2605,9 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
cmistake(u, ord, 174, MSG_MAGIC);
|
cmistake(u, ord, 174, MSG_MAGIC);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Auf dem Ozean Zaubern als quasi-langer Befehl können
|
/* Auf dem Ozean Zaubern als quasi-langer Befehl können
|
||||||
* normalerweise nur Meermenschen, ausgenommen explizit als
|
* normalerweise nur Meermenschen, ausgenommen explizit als
|
||||||
* OCEANCASTABLE deklarierte Sprüche */
|
* OCEANCASTABLE deklarierte Sprüche */
|
||||||
if (fval(r->terrain, SEA_REGION)) {
|
if (fval(r->terrain, SEA_REGION)) {
|
||||||
if (u_race(u) != get_race(RC_AQUARIAN)
|
if (u_race(u) != get_race(RC_AQUARIAN)
|
||||||
&& !fval(u_race(u), RCF_SWIM)
|
&& !fval(u_race(u), RCF_SWIM)
|
||||||
|
@ -2632,7 +2630,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Farcasting bei nicht farcastbaren Sprüchen abfangen */
|
/* Farcasting bei nicht farcastbaren Sprüchen abfangen */
|
||||||
range = farcasting(u, target_r);
|
range = farcasting(u, target_r);
|
||||||
if (range > 1) {
|
if (range > 1) {
|
||||||
if (!(sp->sptyp & FARCASTING)) {
|
if (!(sp->sptyp & FARCASTING)) {
|
||||||
|
@ -2647,7 +2645,7 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Stufenangabe bei nicht Stufenvariierbaren Sprüchen abfangen */
|
/* Stufenangabe bei nicht Stufenvariierbaren Sprüchen abfangen */
|
||||||
if (!(sp->sptyp & SPELLLEVEL)) {
|
if (!(sp->sptyp & SPELLLEVEL)) {
|
||||||
int ilevel = eff_skill(u, SK_MAGIC, u->region);
|
int ilevel = eff_skill(u, SK_MAGIC, u->region);
|
||||||
if (ilevel != level) {
|
if (ilevel != level) {
|
||||||
|
@ -2680,9 +2678,9 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
"mage", caster));
|
"mage", caster));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* mage auf magier setzen, level anpassen, range für Erhöhung
|
/* mage auf magier setzen, level anpassen, range für Erhöhung
|
||||||
* der Spruchkosten nutzen, langen Befehl des Magiers
|
* der Spruchkosten nutzen, langen Befehl des Magiers
|
||||||
* löschen, zaubern kann er noch */
|
* löschen, zaubern kann er noch */
|
||||||
range *= 2;
|
range *= 2;
|
||||||
set_order(&caster->thisorder, NULL);
|
set_order(&caster->thisorder, NULL);
|
||||||
level = _min(level, eff_skill(caster, SK_MAGIC, caster->region) / 2);
|
level = _min(level, eff_skill(caster, SK_MAGIC, caster->region) / 2);
|
||||||
|
@ -2721,19 +2719,19 @@ static castorder *cast_cmd(unit * u, order * ord)
|
||||||
/* ------------------------------------------------------------- */
|
/* ------------------------------------------------------------- */
|
||||||
/* Damit man keine Rituale in fremden Gebiet machen kann, diese vor
|
/* Damit man keine Rituale in fremden Gebiet machen kann, diese vor
|
||||||
* Bewegung zaubern. Magier sind also in einem fremden Gebiet eine Runde
|
* Bewegung zaubern. Magier sind also in einem fremden Gebiet eine Runde
|
||||||
* lang verletzlich, da sie es betreten, und angegriffen werden können,
|
* lang verletzlich, da sie es betreten, und angegriffen werden können,
|
||||||
* bevor sie ein Ritual machen können.
|
* bevor sie ein Ritual machen können.
|
||||||
*
|
*
|
||||||
* Syntax: ZAUBER [REGION X Y] [STUFE <stufe>] "Spruchname" [Einheit-1
|
* Syntax: ZAUBER [REGION X Y] [STUFE <stufe>] "Spruchname" [Einheit-1
|
||||||
* Einheit-2 ..]
|
* Einheit-2 ..]
|
||||||
*
|
*
|
||||||
* Nach Priorität geordnet die Zauber global auswerten.
|
* Nach Priorität geordnet die Zauber global auswerten.
|
||||||
*
|
*
|
||||||
* Die Kosten für Farcasting multiplizieren sich mit der Entfernung,
|
* Die Kosten für Farcasting multiplizieren sich mit der Entfernung,
|
||||||
* cast_level gibt die virtuelle Stufe an, die den durch das Farcasten
|
* cast_level gibt die virtuelle Stufe an, die den durch das Farcasten
|
||||||
* entstandenen Spruchkosten entspricht. Sind die Spruchkosten nicht
|
* entstandenen Spruchkosten entspricht. Sind die Spruchkosten nicht
|
||||||
* levelabhängig, so sind die Kosten nur von der Entfernung bestimmt,
|
* levelabhängig, so sind die Kosten nur von der Entfernung bestimmt,
|
||||||
* die Stärke/Level durch den realen Skill des Magiers
|
* die Stärke/Level durch den realen Skill des Magiers
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void magic(void)
|
void magic(void)
|
||||||
|
@ -2776,11 +2774,11 @@ void magic(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Da sich die Aura und Komponenten in der Zwischenzeit verändert
|
/* Da sich die Aura und Komponenten in der Zwischenzeit verändert
|
||||||
* haben können und sich durch vorherige Sprüche das Zaubern
|
* haben können und sich durch vorherige Sprüche das Zaubern
|
||||||
* erschwert haben kann, muss beim zaubern erneut geprüft werden, ob der
|
* erschwert haben kann, muss beim zaubern erneut geprüft werden, ob der
|
||||||
* Spruch überhaupt gezaubert werden kann.
|
* Spruch überhaupt gezaubert werden kann.
|
||||||
* (level) die effektive Stärke des Spruchs (= Stufe, auf der der
|
* (level) die effektive Stärke des Spruchs (= Stufe, auf der der
|
||||||
* Spruch gezaubert wird) */
|
* Spruch gezaubert wird) */
|
||||||
|
|
||||||
for (rank = 0; rank < MAX_SPELLRANK; rank++) {
|
for (rank = 0; rank < MAX_SPELLRANK; rank++) {
|
||||||
|
@ -2802,30 +2800,30 @@ void magic(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cast_level > co->level) {
|
if (cast_level > co->level) {
|
||||||
/* Sprüche mit Fixkosten werden immer auf Stufe des Spruchs
|
/* Sprüche mit Fixkosten werden immer auf Stufe des Spruchs
|
||||||
* gezaubert, co->level ist aber defaultmäßig Stufe des Magiers */
|
* gezaubert, co->level ist aber defaultmäßig Stufe des Magiers */
|
||||||
if (spl_costtyp(sp) != SPC_FIX) {
|
if (spl_costtyp(sp) != SPC_FIX) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("missing_components",
|
ADDMSG(&u->faction->msgs, msg_message("missing_components",
|
||||||
"unit spell level", u, sp, cast_level));
|
"unit spell level", u, sp, cast_level));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prüfen, ob die realen Kosten für die gewünschten Stufe bezahlt
|
/* Prüfen, ob die realen Kosten für die gewünschten Stufe bezahlt
|
||||||
* werden können */
|
* werden können */
|
||||||
if (!cancast(u, sp, co->level, co->distance, ord)) {
|
if (!cancast(u, sp, co->level, co->distance, ord)) {
|
||||||
/* die Fehlermeldung wird in cancast generiert */
|
/* die Fehlermeldung wird in cancast generiert */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
co->force = spellpower(target_r, u, sp, co->level, ord);
|
co->force = spellpower(target_r, u, sp, co->level, ord);
|
||||||
/* die Stärke kann durch Antimagie auf 0 sinken */
|
/* die Stärke kann durch Antimagie auf 0 sinken */
|
||||||
if (co->force <= 0) {
|
if (co->force <= 0) {
|
||||||
co->force = 0;
|
co->force = 0;
|
||||||
ADDMSG(&u->faction->msgs, msg_message("missing_force",
|
ADDMSG(&u->faction->msgs, msg_message("missing_force",
|
||||||
"unit spell level", u, sp, co->level));
|
"unit spell level", u, sp, co->level));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ziele auf Existenz prüfen und Magieresistenz feststellen. Wurde
|
/* Ziele auf Existenz prüfen und Magieresistenz feststellen. Wurde
|
||||||
* kein Ziel gefunden, so ist verify_targets=0. Scheitert der
|
* kein Ziel gefunden, so ist verify_targets=0. Scheitert der
|
||||||
* Spruch an der Magieresistenz, so ist verify_targets = 1, bei
|
* Spruch an der Magieresistenz, so ist verify_targets = 1, bei
|
||||||
* Erfolg auf ganzer Linie ist verify_targets= 2
|
* Erfolg auf ganzer Linie ist verify_targets= 2
|
||||||
|
@ -2833,8 +2831,8 @@ void magic(void)
|
||||||
verify_targets(co, &invalid, &resist, &success);
|
verify_targets(co, &invalid, &resist, &success);
|
||||||
if (success + resist == 0) {
|
if (success + resist == 0) {
|
||||||
/* kein Ziel gefunden, Fehlermeldungen sind in verify_targets */
|
/* kein Ziel gefunden, Fehlermeldungen sind in verify_targets */
|
||||||
/* keine kosten für den zauber */
|
/* keine kosten für den zauber */
|
||||||
continue; /* äußere Schleife, nächster Zauberer */
|
continue; /* äußere Schleife, nächster Zauberer */
|
||||||
}
|
}
|
||||||
else if (co->force > 0 && resist > 0) {
|
else if (co->force > 0 && resist > 0) {
|
||||||
/* einige oder alle Ziele waren magieresistent */
|
/* einige oder alle Ziele waren magieresistent */
|
||||||
|
@ -2847,8 +2845,8 @@ void magic(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Auch für Patzer gibt es Erfahrung, müssen die Spruchkosten
|
/* Auch für Patzer gibt es Erfahrung, müssen die Spruchkosten
|
||||||
* bezahlt werden und die nachfolgenden Sprüche werden teurer */
|
* bezahlt werden und die nachfolgenden Sprüche werden teurer */
|
||||||
if (co->force > 0) {
|
if (co->force > 0) {
|
||||||
if (fumble(target_r, u, sp, co->level)) {
|
if (fumble(target_r, u, sp, co->level)) {
|
||||||
/* zuerst bezahlen, dann evt in do_fumble alle Aura verlieren */
|
/* zuerst bezahlen, dann evt in do_fumble alle Aura verlieren */
|
||||||
|
@ -2857,12 +2855,12 @@ void magic(void)
|
||||||
else {
|
else {
|
||||||
co->level = sp->cast(co);
|
co->level = sp->cast(co);
|
||||||
if (co->level <= 0) {
|
if (co->level <= 0) {
|
||||||
/* Kosten nur für real benötige Stufe berechnen */
|
/* Kosten nur für real benötige Stufe berechnen */
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* erst bezahlen, dann Kostenzähler erhöhen */
|
/* erst bezahlen, dann Kostenzähler erhöhen */
|
||||||
if (co->level > 0) {
|
if (co->level > 0) {
|
||||||
pay_spell(u, sp, co->level, co->distance);
|
pay_spell(u, sp, co->level, co->distance);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,7 @@ extern "C" {
|
||||||
void make_zombie(struct unit * u);
|
void make_zombie(struct unit * u);
|
||||||
|
|
||||||
#define MONSTER_ID 666
|
#define MONSTER_ID 666
|
||||||
#define is_monsters(f) (f && fval(f, FFL_NPC) && f==get_monsters())
|
#define is_monsters(f) (fval(f, FFL_NPC) && f==get_monsters())
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
98
src/move.c
98
src/move.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2014,
|
Copyright (c) 1998-2014,
|
||||||
Enno Rehling <enno@eressea.de>
|
Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
|
@ -90,7 +90,7 @@ static attrib_type at_traveldir = {
|
||||||
"traveldir",
|
"traveldir",
|
||||||
DEFAULT_INIT,
|
DEFAULT_INIT,
|
||||||
DEFAULT_FINALIZE,
|
DEFAULT_FINALIZE,
|
||||||
DEFAULT_AGE, /* Weil normales Aging an ungünstiger Stelle */
|
DEFAULT_AGE, /* Weil normales Aging an ungünstiger Stelle */
|
||||||
a_writechars,
|
a_writechars,
|
||||||
a_readchars
|
a_readchars
|
||||||
};
|
};
|
||||||
|
@ -245,15 +245,15 @@ static int ridingcapacity(unit * u)
|
||||||
|
|
||||||
get_transporters(u->items, &animals, &acap, &vehicles, &vcap);
|
get_transporters(u->items, &animals, &acap, &vehicles, &vcap);
|
||||||
|
|
||||||
/* Man trägt sein eigenes Gewicht plus seine Kapazität! Die Menschen
|
/* Man trägt sein eigenes Gewicht plus seine Kapazität! Die Menschen
|
||||||
** tragen nichts (siehe walkingcapacity). Ein Wagen zählt nur, wenn er
|
** tragen nichts (siehe walkingcapacity). Ein Wagen zählt nur, wenn er
|
||||||
** von zwei Pferden gezogen wird */
|
** von zwei Pferden gezogen wird */
|
||||||
|
|
||||||
animals = _min(animals, effskill(u, SK_RIDING) * u->number * 2);
|
animals = _min(animals, effskill(u, SK_RIDING) * u->number * 2);
|
||||||
if (fval(u_race(u), RCF_HORSE))
|
if (fval(u_race(u), RCF_HORSE))
|
||||||
animals += u->number;
|
animals += u->number;
|
||||||
|
|
||||||
/* maximal diese Pferde können zum Ziehen benutzt werden */
|
/* maximal diese Pferde können zum Ziehen benutzt werden */
|
||||||
vehicles = _min(animals / HORSESNEEDED, vehicles);
|
vehicles = _min(animals / HORSESNEEDED, vehicles);
|
||||||
|
|
||||||
return vehicles * vcap + animals * acap;
|
return vehicles * vcap + animals * acap;
|
||||||
|
@ -282,7 +282,7 @@ int walkingcapacity(const struct unit *u)
|
||||||
people = u->number;
|
people = u->number;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* maximal diese Pferde können zum Ziehen benutzt werden */
|
/* maximal diese Pferde können zum Ziehen benutzt werden */
|
||||||
wagen_mit_pferden = _min(vehicles, pferde_fuer_wagen / HORSESNEEDED);
|
wagen_mit_pferden = _min(vehicles, pferde_fuer_wagen / HORSESNEEDED);
|
||||||
|
|
||||||
n = wagen_mit_pferden * vcap;
|
n = wagen_mit_pferden * vcap;
|
||||||
|
@ -295,7 +295,7 @@ int walkingcapacity(const struct unit *u)
|
||||||
/* Genug Trolle, um die Restwagen zu ziehen? */
|
/* Genug Trolle, um die Restwagen zu ziehen? */
|
||||||
wagen_mit_trollen = _min(u->number / 4, wagen_ohne_pferde);
|
wagen_mit_trollen = _min(u->number / 4, wagen_ohne_pferde);
|
||||||
|
|
||||||
/* Wagenkapazität hinzuzählen */
|
/* Wagenkapazität hinzuzählen */
|
||||||
n += wagen_mit_trollen * vcap;
|
n += wagen_mit_trollen * vcap;
|
||||||
wagen_ohne_pferde -= wagen_mit_trollen;
|
wagen_ohne_pferde -= wagen_mit_trollen;
|
||||||
}
|
}
|
||||||
|
@ -357,16 +357,16 @@ static int canwalk(unit * u)
|
||||||
if (walkingcapacity(u) - eff_weight(u) >= 0)
|
if (walkingcapacity(u) - eff_weight(u) >= 0)
|
||||||
return E_CANWALK_OK;
|
return E_CANWALK_OK;
|
||||||
|
|
||||||
/* Stimmt das Gewicht, impliziert dies hier, daß alle Wagen ohne
|
/* Stimmt das Gewicht, impliziert dies hier, daß alle Wagen ohne
|
||||||
* Zugpferde/-trolle als Fracht aufgeladen wurden: zu viele Pferde hat
|
* Zugpferde/-trolle als Fracht aufgeladen wurden: zu viele Pferde hat
|
||||||
* die Einheit nicht zum Ziehen benutzt, also nicht mehr Wagen gezogen
|
* die Einheit nicht zum Ziehen benutzt, also nicht mehr Wagen gezogen
|
||||||
* als erlaubt. */
|
* als erlaubt. */
|
||||||
|
|
||||||
if (vehicles > maxwagen)
|
if (vehicles > maxwagen)
|
||||||
return E_CANWALK_TOOMANYCARTS;
|
return E_CANWALK_TOOMANYCARTS;
|
||||||
/* Es muß nicht zwingend an den Wagen liegen, aber egal... (man
|
/* Es muß nicht zwingend an den Wagen liegen, aber egal... (man
|
||||||
* könnte z.B. auch 8 Eisen abladen, damit ein weiterer Wagen als
|
* könnte z.B. auch 8 Eisen abladen, damit ein weiterer Wagen als
|
||||||
* Fracht draufpaßt) */
|
* Fracht draufpaßt) */
|
||||||
|
|
||||||
return E_CANWALK_TOOHEAVY;
|
return E_CANWALK_TOOHEAVY;
|
||||||
}
|
}
|
||||||
|
@ -663,7 +663,7 @@ int check_ship_allowed(struct ship *sh, const region * r)
|
||||||
bt_harbour = bt_find("harbour");
|
bt_harbour = bt_find("harbour");
|
||||||
|
|
||||||
if (sh->region && r_insectstalled(r)) {
|
if (sh->region && r_insectstalled(r)) {
|
||||||
/* insekten dürfen nicht hier rein. haben wir welche? */
|
/* insekten dürfen nicht hier rein. haben wir welche? */
|
||||||
unit *u;
|
unit *u;
|
||||||
|
|
||||||
for (u = sh->region->units; u != NULL; u = u->next) {
|
for (u = sh->region->units; u != NULL; u = u->next) {
|
||||||
|
@ -757,13 +757,13 @@ static void drifting_ships(region * r)
|
||||||
sh->flags |= SF_FISHING;
|
sh->flags |= SF_FISHING;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Schiff schon abgetrieben oder durch Zauber geschützt? */
|
/* Schiff schon abgetrieben oder durch Zauber geschützt? */
|
||||||
if (!drift || fval(sh, SF_DRIFTED) || is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) {
|
if (!drift || fval(sh, SF_DRIFTED) || is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) {
|
||||||
shp = &sh->next;
|
shp = &sh->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Kapitän bestimmen */
|
/* Kapitän bestimmen */
|
||||||
for (captain = r->units; captain; captain = captain->next) {
|
for (captain = r->units; captain; captain = captain->next) {
|
||||||
if (captain->ship != sh)
|
if (captain->ship != sh)
|
||||||
continue;
|
continue;
|
||||||
|
@ -773,8 +773,8 @@ static void drifting_ships(region * r)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Kapitän da? Beschädigt? Genügend Matrosen?
|
/* Kapitän da? Beschädigt? Genügend Matrosen?
|
||||||
* Genügend leicht? Dann ist alles OK. */
|
* Genügend leicht? Dann ist alles OK. */
|
||||||
|
|
||||||
assert(sh->type->construction->improvement == NULL); /* sonst ist construction::size nicht ship_type::maxsize */
|
assert(sh->type->construction->improvement == NULL); /* sonst ist construction::size nicht ship_type::maxsize */
|
||||||
if (captain && sh->size == sh->type->construction->maxsize
|
if (captain && sh->size == sh->type->construction->maxsize
|
||||||
|
@ -784,7 +784,7 @@ static void drifting_ships(region * r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Auswahl einer Richtung: Zuerst auf Land, dann
|
/* Auswahl einer Richtung: Zuerst auf Land, dann
|
||||||
* zufällig. Falls unmögliches Resultat: vergiß es. */
|
* zufällig. Falls unmögliches Resultat: vergiß es. */
|
||||||
d_offset = rng_int() % MAXDIRECTIONS;
|
d_offset = rng_int() % MAXDIRECTIONS;
|
||||||
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||||
region *rn;
|
region *rn;
|
||||||
|
@ -1335,7 +1335,9 @@ static bool roadto(const region * r, direction_t dir)
|
||||||
region *r2;
|
region *r2;
|
||||||
static const curse_type *roads_ct = NULL;
|
static const curse_type *roads_ct = NULL;
|
||||||
|
|
||||||
if (dir >= MAXDIRECTIONS || dir < 0)
|
assert(r);
|
||||||
|
assert(dir<MAXDIRECTIONS);
|
||||||
|
if (!r || dir >= MAXDIRECTIONS || dir < 0)
|
||||||
return false;
|
return false;
|
||||||
r2 = rconnect(r, dir);
|
r2 = rconnect(r, dir);
|
||||||
if (r == NULL || r2 == NULL)
|
if (r == NULL || r2 == NULL)
|
||||||
|
@ -1476,12 +1478,12 @@ static void make_route(unit * u, order * ord, region_list ** routep)
|
||||||
|
|
||||||
/** calculate the speed of a unit
|
/** calculate the speed of a unit
|
||||||
*
|
*
|
||||||
* zu Fuß reist man 1 Region, zu Pferd 2 Regionen. Mit Straßen reist
|
* zu Fuß reist man 1 Region, zu Pferd 2 Regionen. Mit Straßen reist
|
||||||
* man zu Fuß 2, mit Pferden 3 weit.
|
* man zu Fuß 2, mit Pferden 3 weit.
|
||||||
*
|
*
|
||||||
* Berechnet wird das mit BPs. Zu Fuß hat man 4 BPs, zu Pferd 6.
|
* Berechnet wird das mit BPs. Zu Fuß hat man 4 BPs, zu Pferd 6.
|
||||||
* Normalerweise verliert man 3 BP pro Region, bei Straßen nur 2 BP.
|
* Normalerweise verliert man 3 BP pro Region, bei Straßen nur 2 BP.
|
||||||
* Außerdem: Wenn Einheit transportiert, nur halbe BP
|
* Außerdem: Wenn Einheit transportiert, nur halbe BP
|
||||||
*/
|
*/
|
||||||
static int movement_speed(unit * u)
|
static int movement_speed(unit * u)
|
||||||
{
|
{
|
||||||
|
@ -1621,7 +1623,7 @@ static const region_list *travel_route(unit * u,
|
||||||
landing = true;
|
landing = true;
|
||||||
}
|
}
|
||||||
else if ((u_race(u)->flags & RCF_WALK) == 0) {
|
else if ((u_race(u)->flags & RCF_WALK) == 0) {
|
||||||
/* Spezialeinheiten, die nicht laufen können. */
|
/* Spezialeinheiten, die nicht laufen können. */
|
||||||
ADDMSG(&u->faction->msgs, msg_message("detectocean",
|
ADDMSG(&u->faction->msgs, msg_message("detectocean",
|
||||||
"unit region", u, next));
|
"unit region", u, next));
|
||||||
break;
|
break;
|
||||||
|
@ -1634,7 +1636,7 @@ static const region_list *travel_route(unit * u,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Ozeanfelder können nur von Einheiten mit Schwimmen und ohne
|
/* Ozeanfelder können nur von Einheiten mit Schwimmen und ohne
|
||||||
* Pferde betreten werden. */
|
* Pferde betreten werden. */
|
||||||
if (!(canswim(u) || canfly(u))) {
|
if (!(canswim(u) || canfly(u))) {
|
||||||
ADDMSG(&u->faction->msgs, msg_message("detectocean",
|
ADDMSG(&u->faction->msgs, msg_message("detectocean",
|
||||||
|
@ -1729,7 +1731,7 @@ static const region_list *travel_route(unit * u,
|
||||||
walkmode = 2;
|
walkmode = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Berichte über Durchreiseregionen */
|
/* Berichte über Durchreiseregionen */
|
||||||
|
|
||||||
if (mode != TRAVEL_TRANSPORTED) {
|
if (mode != TRAVEL_TRANSPORTED) {
|
||||||
arg_regions *ar = var_copy_regions(route_begin, steps - 1);
|
arg_regions *ar = var_copy_regions(route_begin, steps - 1);
|
||||||
|
@ -1808,7 +1810,7 @@ buildingtype_exists(const region * r, const building_type * bt, bool working)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prüft, ob Ablegen von einer Küste in eine der erlaubten Richtungen erfolgt. */
|
/* Prüft, ob Ablegen von einer Küste in eine der erlaubten Richtungen erfolgt. */
|
||||||
|
|
||||||
static bool check_takeoff(ship * sh, region * from, region * to)
|
static bool check_takeoff(ship * sh, region * from, region * to)
|
||||||
{
|
{
|
||||||
|
@ -1858,18 +1860,18 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Wir suchen so lange nach neuen Richtungen, wie es geht. Diese werden
|
/* Wir suchen so lange nach neuen Richtungen, wie es geht. Diese werden
|
||||||
* dann nacheinander ausgeführt. */
|
* dann nacheinander ausgeführt. */
|
||||||
|
|
||||||
k = shipspeed(sh, u);
|
k = shipspeed(sh, u);
|
||||||
|
|
||||||
last_point = starting_point;
|
last_point = starting_point;
|
||||||
current_point = starting_point;
|
current_point = starting_point;
|
||||||
|
|
||||||
/* die nächste Region, in die man segelt, wird durch movewhere () aus der
|
/* die nächste Region, in die man segelt, wird durch movewhere () aus der
|
||||||
* letzten Region bestimmt.
|
* letzten Region bestimmt.
|
||||||
*
|
*
|
||||||
* Anfangen tun wir bei starting_point. next_point ist beim ersten
|
* Anfangen tun wir bei starting_point. next_point ist beim ersten
|
||||||
* Durchlauf schon gesetzt (Parameter!). current_point ist die letzte gültige,
|
* Durchlauf schon gesetzt (Parameter!). current_point ist die letzte gültige,
|
||||||
* befahrene Region. */
|
* befahrene Region. */
|
||||||
|
|
||||||
while (next_point && current_point != next_point && step < k) {
|
while (next_point && current_point != next_point && step < k) {
|
||||||
|
@ -1916,7 +1918,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
|
||||||
bool storm = true;
|
bool storm = true;
|
||||||
int d_offset = rng_int() % MAXDIRECTIONS;
|
int d_offset = rng_int() % MAXDIRECTIONS;
|
||||||
direction_t d;
|
direction_t d;
|
||||||
/* Sturm nur, wenn nächste Region Hochsee ist. */
|
/* Sturm nur, wenn nächste Region Hochsee ist. */
|
||||||
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
for (d = 0; d != MAXDIRECTIONS; ++d) {
|
||||||
direction_t dnext = (direction_t)((d + d_offset) % MAXDIRECTIONS);
|
direction_t dnext = (direction_t)((d + d_offset) % MAXDIRECTIONS);
|
||||||
region *rn = rconnect(current_point, dnext);
|
region *rn = rconnect(current_point, dnext);
|
||||||
|
@ -2052,16 +2054,16 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
|
||||||
sh = NULL;
|
sh = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nun enthält current_point die Region, in der das Schiff seine Runde
|
/* Nun enthält current_point die Region, in der das Schiff seine Runde
|
||||||
* beendet hat. Wir generieren hier ein Ereignis für den Spieler, das
|
* beendet hat. Wir generieren hier ein Ereignis für den Spieler, das
|
||||||
* ihm sagt, bis wohin er gesegelt ist, falls er überhaupt vom Fleck
|
* ihm sagt, bis wohin er gesegelt ist, falls er überhaupt vom Fleck
|
||||||
* gekommen ist. Das ist nicht der Fall, wenn er von der Küste ins
|
* gekommen ist. Das ist nicht der Fall, wenn er von der Küste ins
|
||||||
* Inland zu segeln versuchte */
|
* Inland zu segeln versuchte */
|
||||||
|
|
||||||
if (sh != NULL && fval(sh, SF_MOVED)) {
|
if (sh != NULL && fval(sh, SF_MOVED)) {
|
||||||
unit *harbourmaster;
|
unit *harbourmaster;
|
||||||
/* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten
|
/* nachdem alle Richtungen abgearbeitet wurden, und alle Einheiten
|
||||||
* transferiert wurden, kann der aktuelle Befehl gelöscht werden. */
|
* transferiert wurden, kann der aktuelle Befehl gelöscht werden. */
|
||||||
cycle_route(ord, u, step);
|
cycle_route(ord, u, step);
|
||||||
set_order(&u->thisorder, NULL);
|
set_order(&u->thisorder, NULL);
|
||||||
if (!move_on_land) {
|
if (!move_on_land) {
|
||||||
|
@ -2086,7 +2088,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
|
||||||
|
|
||||||
sh = move_ship(sh, starting_point, current_point, *routep);
|
sh = move_ship(sh, starting_point, current_point, *routep);
|
||||||
|
|
||||||
/* Hafengebühren ? */
|
/* Hafengebühren ? */
|
||||||
|
|
||||||
harbourmaster = owner_buildingtyp(current_point, bt_find("harbour"));
|
harbourmaster = owner_buildingtyp(current_point, bt_find("harbour"));
|
||||||
if (sh && harbourmaster != NULL) {
|
if (sh && harbourmaster != NULL) {
|
||||||
|
@ -2128,20 +2130,6 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unit *get_captain(const ship * sh)
|
|
||||||
{
|
|
||||||
const region *r = sh->region;
|
|
||||||
unit *u;
|
|
||||||
|
|
||||||
for (u = r->units; u; u = u->next) {
|
|
||||||
if (u->ship == sh && u->number
|
|
||||||
&& eff_skill(u, SK_SAILING, r) >= sh->type->cptskill)
|
|
||||||
return u;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Segeln, Wandern, Reiten
|
/* Segeln, Wandern, Reiten
|
||||||
* when this routine returns a non-zero value, movement for the region needs
|
* when this routine returns a non-zero value, movement for the region needs
|
||||||
* to be done again because of followers that got new MOVE orders.
|
* to be done again because of followers that got new MOVE orders.
|
||||||
|
@ -2434,7 +2422,7 @@ static void piracy_cmd(unit * u, struct order *ord)
|
||||||
/* Wenn nicht, sehen wir, ob wir ein Ziel finden. */
|
/* Wenn nicht, sehen wir, ob wir ein Ziel finden. */
|
||||||
|
|
||||||
if (target_dir == NODIRECTION) {
|
if (target_dir == NODIRECTION) {
|
||||||
/* Einheit ist also Kapitän. Jetzt gucken, in wievielen
|
/* Einheit ist also Kapitän. Jetzt gucken, in wievielen
|
||||||
* Nachbarregionen potentielle Opfer sind. */
|
* Nachbarregionen potentielle Opfer sind. */
|
||||||
|
|
||||||
for (dir = 0; dir < MAXDIRECTIONS; dir++) {
|
for (dir = 0; dir < MAXDIRECTIONS; dir++) {
|
||||||
|
@ -2493,7 +2481,7 @@ static void piracy_cmd(unit * u, struct order *ord)
|
||||||
set_order(&u->thisorder, create_order(K_MOVE, u->faction->locale, "%s",
|
set_order(&u->thisorder, create_order(K_MOVE, u->faction->locale, "%s",
|
||||||
LOC(u->faction->locale, directions[target_dir])));
|
LOC(u->faction->locale, directions[target_dir])));
|
||||||
|
|
||||||
/* Bewegung ausführen */
|
/* Bewegung ausführen */
|
||||||
init_order(u->thisorder);
|
init_order(u->thisorder);
|
||||||
move(u, true);
|
move(u, true);
|
||||||
}
|
}
|
||||||
|
@ -2604,7 +2592,7 @@ static int hunt(unit * u, order * ord)
|
||||||
/* NACH ignorieren und Parsing initialisieren. */
|
/* NACH ignorieren und Parsing initialisieren. */
|
||||||
init_tokens_str(command);
|
init_tokens_str(command);
|
||||||
getstrtoken();
|
getstrtoken();
|
||||||
/* NACH ausführen */
|
/* NACH ausführen */
|
||||||
move(u, false);
|
move(u, false);
|
||||||
return 1; /* true -> Einheitenliste von vorne durchgehen */
|
return 1; /* true -> Einheitenliste von vorne durchgehen */
|
||||||
}
|
}
|
||||||
|
@ -2803,7 +2791,7 @@ void movement(void)
|
||||||
if (repeat)
|
if (repeat)
|
||||||
continue;
|
continue;
|
||||||
if (ships == 0) {
|
if (ships == 0) {
|
||||||
/* Abtreiben von beschädigten, unterbemannten, überladenen Schiffen */
|
/* Abtreiben von beschädigten, unterbemannten, überladenen Schiffen */
|
||||||
drifting_ships(r);
|
drifting_ships(r);
|
||||||
}
|
}
|
||||||
r = r->next;
|
r = r->next;
|
||||||
|
|
|
@ -64,7 +64,6 @@ extern "C" {
|
||||||
int enoughsailors(const struct ship *sh, const struct region *r);
|
int enoughsailors(const struct ship *sh, const struct region *r);
|
||||||
bool canswim(struct unit *u);
|
bool canswim(struct unit *u);
|
||||||
bool canfly(struct unit *u);
|
bool canfly(struct unit *u);
|
||||||
struct unit *get_captain(const struct ship *sh);
|
|
||||||
void travelthru(const struct unit *u, struct region *r);
|
void travelthru(const struct unit *u, struct region *r);
|
||||||
struct ship *move_ship(struct ship *sh, struct region *from,
|
struct ship *move_ship(struct ship *sh, struct region *from,
|
||||||
struct region *to, struct region_list *route);
|
struct region *to, struct region_list *route);
|
||||||
|
|
18
src/report.c
18
src/report.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
@ -552,9 +552,9 @@ static void nr_curses(stream *out, int indent, const faction *viewer, objtype_t
|
||||||
region *r;
|
region *r;
|
||||||
|
|
||||||
/* Die Sichtbarkeit eines Zaubers und die Zaubermeldung sind bei
|
/* Die Sichtbarkeit eines Zaubers und die Zaubermeldung sind bei
|
||||||
* Gebäuden und Schiffen je nach, ob man Besitzer ist, verschieden.
|
* Gebäuden und Schiffen je nach, ob man Besitzer ist, verschieden.
|
||||||
* Bei Einheiten sieht man Wirkungen auf eigene Einheiten immer.
|
* Bei Einheiten sieht man Wirkungen auf eigene Einheiten immer.
|
||||||
* Spezialfälle (besonderes Talent, verursachender Magier usw. werde
|
* Spezialfälle (besonderes Talent, verursachender Magier usw. werde
|
||||||
* bei jedem curse gesondert behandelt. */
|
* bei jedem curse gesondert behandelt. */
|
||||||
if (typ == TYP_SHIP) {
|
if (typ == TYP_SHIP) {
|
||||||
ship *sh = (ship *)obj;
|
ship *sh = (ship *)obj;
|
||||||
|
@ -840,7 +840,7 @@ bool see_border(const connection * b, const faction * f, const region * r)
|
||||||
|
|
||||||
static void describe(stream *out, const seen_region * sr, faction * f)
|
static void describe(stream *out, const seen_region * sr, faction * f)
|
||||||
{
|
{
|
||||||
const region *r = sr->r;
|
const region *r;
|
||||||
int n;
|
int n;
|
||||||
bool dh;
|
bool dh;
|
||||||
direction_t d;
|
direction_t d;
|
||||||
|
@ -862,6 +862,11 @@ static void describe(stream *out, const seen_region * sr, faction * f)
|
||||||
size_t size = sizeof(buf);
|
size_t size = sizeof(buf);
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
|
assert(out);
|
||||||
|
assert(f);
|
||||||
|
assert(sr);
|
||||||
|
|
||||||
|
r = sr->r;
|
||||||
for (d = 0; d != MAXDIRECTIONS; d++) {
|
for (d = 0; d != MAXDIRECTIONS; d++) {
|
||||||
/* Nachbarregionen, die gesehen werden, ermitteln */
|
/* Nachbarregionen, die gesehen werden, ermitteln */
|
||||||
region *r2 = rconnect(r, d);
|
region *r2 = rconnect(r, d);
|
||||||
|
@ -953,7 +958,7 @@ static void describe(stream *out, const seen_region * sr, faction * f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* iron & stone */
|
/* iron & stone */
|
||||||
if (sr->mode == see_unit && f != (faction *)NULL) {
|
if (sr->mode == see_unit) {
|
||||||
resource_report result[MAX_RAWMATERIALS];
|
resource_report result[MAX_RAWMATERIALS];
|
||||||
int n, numresults = report_resources(sr, result, MAX_RAWMATERIALS, f);
|
int n, numresults = report_resources(sr, result, MAX_RAWMATERIALS, f);
|
||||||
|
|
||||||
|
@ -1188,7 +1193,7 @@ static void describe(stream *out, const seen_region * sr, faction * f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Wirkungen permanenter Sprüche */
|
/* Wirkungen permanenter Sprüche */
|
||||||
nr_curses(out, 0, f, TYP_REGION, r);
|
nr_curses(out, 0, f, TYP_REGION, r);
|
||||||
n = 0;
|
n = 0;
|
||||||
|
|
||||||
|
@ -1410,7 +1415,6 @@ static void durchreisende(stream *out, const region * r, const faction * f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* TODO: finish localization */
|
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
if (maxtravel == 1) {
|
if (maxtravel == 1) {
|
||||||
bytes = _snprintf(bufp, size, " %s", LOC(f->locale, "has_moved_one"));
|
bytes = _snprintf(bufp, size, " %s", LOC(f->locale, "has_moved_one"));
|
||||||
|
|
42
src/spy.c
42
src/spy.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
@ -53,6 +53,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
/* in spy steht der Unterschied zwischen Wahrnehmung des Opfers und
|
/* in spy steht der Unterschied zwischen Wahrnehmung des Opfers und
|
||||||
* Spionage des Spions */
|
* Spionage des Spions */
|
||||||
|
@ -375,7 +376,7 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff)
|
||||||
}
|
}
|
||||||
else if (skilldiff < 0) {
|
else if (skilldiff < 0) {
|
||||||
/* tell the unit that the attempt was detected: */
|
/* tell the unit that the attempt was detected: */
|
||||||
ADDMSG(&u2->faction->msgs, msg_message(destruction_detected_msg,
|
ADDMSG(&u->faction->msgs, msg_message(destruction_detected_msg,
|
||||||
"ship unit", sh, u));
|
"ship unit", sh, u));
|
||||||
/* tell the enemy whodunit: */
|
/* tell the enemy whodunit: */
|
||||||
if (u2) {
|
if (u2) {
|
||||||
|
@ -394,7 +395,7 @@ static int try_destruction(unit * u, unit * u2, const ship * sh, int skilldiff)
|
||||||
return 1; /* success */
|
return 1; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
static void sink_ship(region * r, ship * sh, unit * saboteur)
|
||||||
{
|
{
|
||||||
unit **ui, *u;
|
unit **ui, *u;
|
||||||
region *safety = r;
|
region *safety = r;
|
||||||
|
@ -404,6 +405,9 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
||||||
message *sink_msg = NULL;
|
message *sink_msg = NULL;
|
||||||
faction *f;
|
faction *f;
|
||||||
|
|
||||||
|
assert(r);
|
||||||
|
assert(sh);
|
||||||
|
assert(saboteur);
|
||||||
for (f = NULL, u = r->units; u; u = u->next) {
|
for (f = NULL, u = r->units; u; u = u->next) {
|
||||||
/* slight optimization to avoid dereferencing u->faction each time */
|
/* slight optimization to avoid dereferencing u->faction each time */
|
||||||
if (f != u->faction) {
|
if (f != u->faction) {
|
||||||
|
@ -426,7 +430,7 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (ui = &r->units; *ui; ui = &(*ui)->next) {
|
for (ui = &r->units; *ui;) {
|
||||||
unit *u = *ui;
|
unit *u = *ui;
|
||||||
|
|
||||||
/* inform this faction about the sinking ship: */
|
/* inform this faction about the sinking ship: */
|
||||||
|
@ -471,13 +475,14 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
||||||
add_message(&u->faction->msgs, msg);
|
add_message(&u->faction->msgs, msg);
|
||||||
msg_release(msg);
|
msg_release(msg);
|
||||||
if (dead == u->number) {
|
if (dead == u->number) {
|
||||||
/* the poor creature, she dies */
|
if (remove_unit(ui, u) == 0) {
|
||||||
if (remove_unit(ui, u) != 0) {
|
/* ui is already pointing at u->next */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
ui = &u->next;
|
ui = &u->next;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sink_msg)
|
if (sink_msg)
|
||||||
msg_release(sink_msg);
|
msg_release(sink_msg);
|
||||||
/* finally, get rid of the ship */
|
/* finally, get rid of the ship */
|
||||||
|
@ -487,19 +492,21 @@ static void sink_ship(region * r, ship * sh, const char *name, unit * saboteur)
|
||||||
int sabotage_cmd(unit * u, struct order *ord)
|
int sabotage_cmd(unit * u, struct order *ord)
|
||||||
{
|
{
|
||||||
const char *s;
|
const char *s;
|
||||||
int i;
|
param_t p;
|
||||||
ship *sh;
|
ship *sh;
|
||||||
unit *u2;
|
unit *u2;
|
||||||
char buffer[DISPLAYSIZE];
|
region *r;
|
||||||
region *r = u->region;
|
int skdiff = INT_MAX;
|
||||||
int skdiff;
|
|
||||||
|
assert(u);
|
||||||
|
assert(ord);
|
||||||
|
|
||||||
init_order(ord);
|
init_order(ord);
|
||||||
s = getstrtoken();
|
s = getstrtoken();
|
||||||
|
|
||||||
i = findparam(s, u->faction->locale);
|
p = findparam(s, u->faction->locale);
|
||||||
|
|
||||||
switch (i) {
|
switch (p) {
|
||||||
case P_SHIP:
|
case P_SHIP:
|
||||||
sh = u->ship;
|
sh = u->ship;
|
||||||
if (!sh) {
|
if (!sh) {
|
||||||
|
@ -507,10 +514,13 @@ int sabotage_cmd(unit * u, struct order *ord)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
u2 = ship_owner(sh);
|
u2 = ship_owner(sh);
|
||||||
|
r = u->region;
|
||||||
|
if (u2->faction != u->faction) {
|
||||||
skdiff =
|
skdiff =
|
||||||
eff_skill(u, SK_SPY, r) - crew_skill(r, u2->faction, sh, SK_PERCEPTION);
|
eff_skill(u, SK_SPY, r) - crew_skill(r, u2->faction, sh, SK_PERCEPTION);
|
||||||
|
}
|
||||||
if (try_destruction(u, u2, sh, skdiff)) {
|
if (try_destruction(u, u2, sh, skdiff)) {
|
||||||
sink_ship(r, sh, buffer, u);
|
sink_ship(r, sh, u);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -5,9 +5,12 @@
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
#include <kernel/unit.h>
|
#include <kernel/unit.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
|
#include <kernel/ship.h>
|
||||||
|
#include <kernel/order.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
#include <kernel/messages.h>
|
#include <kernel/messages.h>
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
|
#include <util/language.h>
|
||||||
#include <util/message.h>
|
#include <util/message.h>
|
||||||
#include <util/crmessage.h>
|
#include <util/crmessage.h>
|
||||||
#include <tests.h>
|
#include <tests.h>
|
||||||
|
@ -16,6 +19,7 @@
|
||||||
|
|
||||||
#include "spy.h"
|
#include "spy.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include <CuTest.h>
|
#include <CuTest.h>
|
||||||
|
@ -98,12 +102,96 @@ static void test_all_spy_message(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setup_sabotage(void) {
|
||||||
|
struct locale *lang;
|
||||||
|
|
||||||
|
test_cleanup();
|
||||||
|
lang = get_or_create_locale("de");
|
||||||
|
locale_setstring(lang, parameters[P_SHIP], "SCHIFF");
|
||||||
|
test_create_world();
|
||||||
|
init_locales();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_sabotage_self(CuTest *tc) {
|
||||||
|
unit *u;
|
||||||
|
region *r;
|
||||||
|
order *ord;
|
||||||
|
|
||||||
|
setup_sabotage();
|
||||||
|
r = test_create_region(0, 0, NULL);
|
||||||
|
assert(r);
|
||||||
|
u = test_create_unit(test_create_faction(NULL), r);
|
||||||
|
assert(u && u->faction && u->region == r);
|
||||||
|
u->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||||
|
assert(u->ship);
|
||||||
|
ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
|
||||||
|
assert(ord);
|
||||||
|
CuAssertIntEquals(tc, 0, sabotage_cmd(u, ord));
|
||||||
|
CuAssertPtrEquals(tc, 0, r->ships);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_sabotage_other_fail(CuTest *tc) {
|
||||||
|
unit *u, *u2;
|
||||||
|
region *r;
|
||||||
|
order *ord;
|
||||||
|
message *msg;
|
||||||
|
|
||||||
|
setup_sabotage();
|
||||||
|
r = test_create_region(0, 0, NULL);
|
||||||
|
assert(r);
|
||||||
|
u = test_create_unit(test_create_faction(NULL), r);
|
||||||
|
u2 = test_create_unit(test_create_faction(NULL), r);
|
||||||
|
assert(u && u2);
|
||||||
|
u2->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||||
|
assert(u2->ship);
|
||||||
|
u->ship = u2->ship;
|
||||||
|
ship_update_owner(u->ship);
|
||||||
|
assert(ship_owner(u->ship) == u);
|
||||||
|
ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
|
||||||
|
assert(ord);
|
||||||
|
CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord));
|
||||||
|
msg = test_get_last_message(u2->faction->msgs);
|
||||||
|
CuAssertStrEquals(tc, "destroy_ship_1", test_get_messagetype(msg));
|
||||||
|
msg = test_get_last_message(u->faction->msgs);
|
||||||
|
CuAssertStrEquals(tc, "destroy_ship_3", test_get_messagetype(msg));
|
||||||
|
CuAssertPtrNotNull(tc, r->ships);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void test_sabotage_other_success(CuTest *tc) {
|
||||||
|
unit *u, *u2;
|
||||||
|
region *r;
|
||||||
|
order *ord;
|
||||||
|
|
||||||
|
setup_sabotage();
|
||||||
|
r = test_create_region(0, 0, NULL);
|
||||||
|
assert(r);
|
||||||
|
u = test_create_unit(test_create_faction(NULL), r);
|
||||||
|
u2 = test_create_unit(test_create_faction(NULL), r);
|
||||||
|
assert(u && u2);
|
||||||
|
u2->ship = test_create_ship(r, test_create_shiptype("boat"));
|
||||||
|
assert(u2->ship);
|
||||||
|
u->ship = u2->ship;
|
||||||
|
ship_update_owner(u->ship);
|
||||||
|
assert(ship_owner(u->ship) == u);
|
||||||
|
ord = create_order(K_SABOTAGE, u->faction->locale, "SCHIFF");
|
||||||
|
assert(ord);
|
||||||
|
set_level(u2, SK_SPY, 1);
|
||||||
|
CuAssertIntEquals(tc, 0, sabotage_cmd(u2, ord));
|
||||||
|
CuAssertPtrEquals(tc, 0, r->ships);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_spy_suite(void)
|
CuSuite *get_spy_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_simple_spy_message);
|
SUITE_ADD_TEST(suite, test_simple_spy_message);
|
||||||
SUITE_ADD_TEST(suite, test_all_spy_message);
|
SUITE_ADD_TEST(suite, test_all_spy_message);
|
||||||
|
SUITE_ADD_TEST(suite, test_sabotage_self);
|
||||||
|
SUITE_ADD_TEST(suite, test_sabotage_other_fail);
|
||||||
|
SUITE_ADD_TEST(suite, test_sabotage_other_success);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
14
src/study.c
14
src/study.c
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
@ -542,6 +542,9 @@ int learn_cmd(unit * u, order * ord)
|
||||||
int maxalchemy = 0;
|
int maxalchemy = 0;
|
||||||
int speed_rule = (study_rule_t)get_param_int(global.parameters, "study.speedup", 0);
|
int speed_rule = (study_rule_t)get_param_int(global.parameters, "study.speedup", 0);
|
||||||
static int learn_newskills = -1;
|
static int learn_newskills = -1;
|
||||||
|
struct building *b = inside_building(u);
|
||||||
|
const struct building_type *btype = b ? b->type : NULL;
|
||||||
|
|
||||||
if (learn_newskills < 0) {
|
if (learn_newskills < 0) {
|
||||||
const char *str = get_param(global.parameters, "study.newskills");
|
const char *str = get_param(global.parameters, "study.newskills");
|
||||||
if (str && strcmp(str, "false") == 0)
|
if (str && strcmp(str, "false") == 0)
|
||||||
|
@ -603,14 +606,12 @@ int learn_cmd(unit * u, order * ord)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* Akademie: */
|
/* Akademie: */
|
||||||
{
|
b = inside_building(u);
|
||||||
struct building *b = inside_building(u);
|
btype = b ? b->type : NULL;
|
||||||
const struct building_type *btype = b ? b->type : NULL;
|
|
||||||
|
|
||||||
if (btype && btype == bt_find("academy")) {
|
if (btype && btype == bt_find("academy")) {
|
||||||
studycost = _max(50, studycost * 2);
|
studycost = _max(50, studycost * 2);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (sk == SK_MAGIC) {
|
if (sk == SK_MAGIC) {
|
||||||
if (u->number > 1) {
|
if (u->number > 1) {
|
||||||
|
@ -710,6 +711,7 @@ int learn_cmd(unit * u, order * ord)
|
||||||
if (teach == NULL) {
|
if (teach == NULL) {
|
||||||
a = a_add(&u->attribs, a_new(&at_learning));
|
a = a_add(&u->attribs, a_new(&at_learning));
|
||||||
teach = (teaching_info *)a->data.v;
|
teach = (teaching_info *)a->data.v;
|
||||||
|
assert(teach);
|
||||||
teach->teachers[0] = 0;
|
teach->teachers[0] = 0;
|
||||||
}
|
}
|
||||||
if (money > 0) {
|
if (money > 0) {
|
||||||
|
@ -769,7 +771,6 @@ int learn_cmd(unit * u, order * ord)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (a != NULL) {
|
if (a != NULL) {
|
||||||
if (teach != NULL) {
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
while (teach->teachers[index] && index != MAXTEACHERS) {
|
while (teach->teachers[index] && index != MAXTEACHERS) {
|
||||||
unit *teacher = teach->teachers[index++];
|
unit *teacher = teach->teachers[index++];
|
||||||
|
@ -784,7 +785,6 @@ int learn_cmd(unit * u, order * ord)
|
||||||
"teacher student skill", teacher, u, sk));
|
"teacher student skill", teacher, u, sk));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
a_remove(&u->attribs, a);
|
a_remove(&u->attribs, a);
|
||||||
a = NULL;
|
a = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
* +-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
* | | Enno Rehling <enno@eressea.de>
|
* | | Enno Rehling <enno@eressea.de>
|
||||||
* | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
* | Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include "upkeep.h"
|
#include "upkeep.h"
|
||||||
|
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
|
@ -82,6 +82,7 @@ void test_upkeep_from_pool(CuTest * tc)
|
||||||
assert(i_silver);
|
assert(i_silver);
|
||||||
r = findregion(0, 0);
|
r = findregion(0, 0);
|
||||||
u1 = test_create_unit(test_create_faction(test_create_race("human")), r);
|
u1 = test_create_unit(test_create_faction(test_create_race("human")), r);
|
||||||
|
assert(u1);
|
||||||
u2 = test_create_unit(u1->faction, r);
|
u2 = test_create_unit(u1->faction, r);
|
||||||
assert(r && u1 && u2);
|
assert(r && u1 && u2);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
Copyright (c) 1998-2015, Enno Rehling <enno@eressea.de>
|
||||||
Katja Zedel <katze@felidae.kn-bremen.de
|
Katja Zedel <katze@felidae.kn-bremen.de
|
||||||
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
|
@ -69,7 +69,7 @@ static attrib_type *at_find(unsigned int hk)
|
||||||
{
|
{
|
||||||
const char *translate[3][2] = {
|
const char *translate[3][2] = {
|
||||||
{ "zielregion", "targetregion" }, /* remapping: from 'zielregion, heute targetregion */
|
{ "zielregion", "targetregion" }, /* remapping: from 'zielregion, heute targetregion */
|
||||||
{ "verzaubert", "curse" }, /* remapping: früher verzaubert, jetzt curse */
|
{ "verzaubert", "curse" }, /* remapping: früher verzaubert, jetzt curse */
|
||||||
{ NULL, NULL }
|
{ NULL, NULL }
|
||||||
};
|
};
|
||||||
attrib_type *find = at_hash[hk % MAXATHASH];
|
attrib_type *find = at_hash[hk % MAXATHASH];
|
||||||
|
@ -110,11 +110,11 @@ const attrib *a_findc(const attrib * a, const attrib_type * at)
|
||||||
|
|
||||||
static attrib *a_insert(attrib * head, attrib * a)
|
static attrib *a_insert(attrib * head, attrib * a)
|
||||||
{
|
{
|
||||||
attrib **pa = &head->next;
|
attrib **pa;
|
||||||
|
|
||||||
assert(!(a->type->flags & ATF_UNIQUE));
|
assert(!(a->type->flags & ATF_UNIQUE));
|
||||||
assert(head && head->type == a->type);
|
assert(head && head->type == a->type);
|
||||||
|
|
||||||
|
pa = &head->next;
|
||||||
while (*pa && (*pa)->type == a->type) {
|
while (*pa && (*pa)->type == a->type) {
|
||||||
pa = &(*pa)->next;
|
pa = &(*pa)->next;
|
||||||
}
|
}
|
||||||
|
@ -250,7 +250,7 @@ int a_age(attrib ** p)
|
||||||
{
|
{
|
||||||
attrib **ap = p;
|
attrib **ap = p;
|
||||||
/* Attribute altern, und die Entfernung (age()==0) eines Attributs
|
/* Attribute altern, und die Entfernung (age()==0) eines Attributs
|
||||||
* hat Einfluß auf den Besitzer */
|
* hat Einfluß auf den Besitzer */
|
||||||
while (*ap) {
|
while (*ap) {
|
||||||
attrib *a = *ap;
|
attrib *a = *ap;
|
||||||
if (a->type->age) {
|
if (a->type->age) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
+-------------------+ Christian Schlittchen <corwin@amber.kn-bremen.de>
|
||||||
| | Enno Rehling <enno@eressea.de>
|
| | Enno Rehling <enno@eressea.de>
|
||||||
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
| Eressea PBEM host | Katja Zedel <katze@felidae.kn-bremen.de>
|
||||||
|
@ -54,13 +54,13 @@ cp_convert(const char *format, char *buffer, size_t length, int codepage)
|
||||||
char *pos = buffer;
|
char *pos = buffer;
|
||||||
|
|
||||||
while (pos + 1 < buffer + length && *input) {
|
while (pos + 1 < buffer + length && *input) {
|
||||||
size_t length = 0;
|
size_t size = 0;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
if (codepage == 437) {
|
if (codepage == 437) {
|
||||||
result = unicode_utf8_to_cp437(pos, input, &length);
|
result = unicode_utf8_to_cp437(pos, input, &size);
|
||||||
}
|
}
|
||||||
else if (codepage == 1252) {
|
else if (codepage == 1252) {
|
||||||
result = unicode_utf8_to_cp1252(pos, input, &length);
|
result = unicode_utf8_to_cp1252(pos, input, &size);
|
||||||
}
|
}
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
*pos = 0; /* just in case caller ignores our return value */
|
*pos = 0; /* just in case caller ignores our return value */
|
||||||
|
|
Loading…
Reference in New Issue