forked from github/server
Merge pull request #723 from ennorehling/develop
syncing master and develop for 3.14
This commit is contained in:
commit
77f6e7adb4
21
s/install
21
s/install
|
@ -1,18 +1,25 @@
|
|||
#!/bin/sh
|
||||
ROOT=$(pwd)
|
||||
while [ ! -d $ROOT/.git ]; do
|
||||
ROOT=$(dirname $ROOT)
|
||||
if [ "/" = "$ROOT" ]; then
|
||||
echo "could not find root, are you in the git repository?"
|
||||
exit
|
||||
fi
|
||||
|
||||
FORCE=0
|
||||
while getopts f o; do
|
||||
case "${o}" in
|
||||
f) usage ; FORCE=yes ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ "$FORCE" != "yes" ] ; then
|
||||
BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//')
|
||||
if [ "$BRANCH" != "master" ] ; then
|
||||
echo "you should only install stable versions from the master branch"
|
||||
exit
|
||||
fi
|
||||
fi
|
||||
[ -z "$CC" ] && [ ! -z `which clang` ] && CC="clang"
|
||||
[ -z "$CC" ] && [ ! -z `which gcc` ] && CC="gcc"
|
||||
[ -z "$CC" ] && [ ! -z `which tcc` ] && CC="tcc"
|
||||
[ -z "$CC" ] && [ ! -z `which cc` ] && CC="cc"
|
||||
BIN_DIR="Debug"
|
||||
|
||||
ROOT=$(git rev-parse --show-toplevel)
|
||||
cd $ROOT/$BIN_DIR
|
||||
make install
|
||||
|
|
|
@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <util/attrib.h>
|
||||
#include <util/gamedata.h>
|
||||
#include <util/log.h>
|
||||
#include <storage.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -30,38 +31,107 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
static void a_writekeys(const attrib *a, const void *o, storage *store) {
|
||||
int i, *keys = (int *)a->data.v;
|
||||
assert(keys[0] < 4096 && keys[0]>0);
|
||||
WRITE_INT(store, keys[0]);
|
||||
for (i = 0; i < keys[0]; ++i) {
|
||||
int n = 0;
|
||||
if (keys) {
|
||||
assert(keys[0] < 4096 && keys[0]>0);
|
||||
n = keys[0];
|
||||
}
|
||||
WRITE_INT(store, n);
|
||||
for (i = 0; i < n; ++i) {
|
||||
WRITE_INT(store, keys[i * 2 + 1]);
|
||||
WRITE_INT(store, keys[i * 2 + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
static int a_readkeys(attrib * a, void *owner, gamedata *data) {
|
||||
int i, *p = 0;
|
||||
READ_INT(data->store, &i);
|
||||
assert(i < 4096 && i>=0);
|
||||
if (i == 0) {
|
||||
return AT_READ_FAIL;
|
||||
}
|
||||
a->data.v = p = malloc(sizeof(int)*(i*2 + 1));
|
||||
*p++ = i;
|
||||
while (i--) {
|
||||
READ_INT(data->store, p++);
|
||||
if (data->version >= KEYVAL_VERSION) {
|
||||
READ_INT(data->store, p++);
|
||||
static int keys_lower_bound(int *base, int k, int l, int r) {
|
||||
int km = k;
|
||||
int *p = base + 1;
|
||||
|
||||
while (l != r) {
|
||||
int m = (l + r) / 2;
|
||||
km = p[m * 2];
|
||||
if (km < k) {
|
||||
if (l == m) l = r;
|
||||
else l = m;
|
||||
}
|
||||
else {
|
||||
*p++ = 1;
|
||||
if (r == m) r = l;
|
||||
else r = m;
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
static int keys_size(int n) {
|
||||
/* TODO maybe use log2 from https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog */
|
||||
assert(n > 0 && n <= 4096);
|
||||
if (n <= 1) return 1;
|
||||
if (n <= 4) return 4;
|
||||
if (n <= 16) return 16;
|
||||
if (n <= 256) return 256;
|
||||
return 4096;
|
||||
}
|
||||
|
||||
static int a_readkeys(attrib * a, void *owner, gamedata *data) {
|
||||
int i, n, *keys;
|
||||
|
||||
READ_INT(data->store, &n);
|
||||
assert(n < 4096 && n >= 0);
|
||||
if (n == 0) {
|
||||
return AT_READ_FAIL;
|
||||
}
|
||||
keys = malloc(sizeof(int)*(keys_size(n) * 2 + 1));
|
||||
*keys = n;
|
||||
for (i = 0; i != n; ++i) {
|
||||
READ_INT(data->store, keys + i * 2 + 1);
|
||||
if (data->version >= KEYVAL_VERSION) {
|
||||
READ_INT(data->store, keys + i * 2 + 2);
|
||||
}
|
||||
else {
|
||||
keys[i * 2 + 2] = 1;
|
||||
}
|
||||
}
|
||||
if (data->version < SORTKEYS_VERSION) {
|
||||
int e = 1;
|
||||
for (i = 1; i != n; ++i) {
|
||||
int k = keys[i * 2 + 1];
|
||||
int v = keys[i * 2 + 2];
|
||||
int l = keys_lower_bound(keys, k, 0, e);
|
||||
if (l != e) {
|
||||
int km = keys[l * 2 + 1];
|
||||
if (km == k) {
|
||||
int vm = keys[l * 2 + 2];
|
||||
if (v != vm) {
|
||||
log_error("key %d has values %d and %d", k, v, vm);
|
||||
}
|
||||
--e;
|
||||
}
|
||||
else {
|
||||
if (e > l) {
|
||||
memmove(keys + 2 * l + 3, keys + 2 * l + 1, (e - l) * 2 * sizeof(int));
|
||||
}
|
||||
keys[2 * l + 1] = k;
|
||||
keys[2 * l + 2] = v;
|
||||
}
|
||||
}
|
||||
++e;
|
||||
}
|
||||
if (e != n) {
|
||||
int sz = keys_size(n);
|
||||
if (e > sz) {
|
||||
sz = keys_size(e);
|
||||
keys = realloc(keys, sizeof(int)*(2 * sz + 1));
|
||||
keys[0] = e;
|
||||
}
|
||||
}
|
||||
}
|
||||
a->data.v = keys;
|
||||
return AT_READ_OK;
|
||||
}
|
||||
|
||||
static int a_readkey(attrib *a, void *owner, struct gamedata *data) {
|
||||
int res = a_readint(a, owner, data);
|
||||
if (data->version>=KEYVAL_VERSION) {
|
||||
if (data->version >= KEYVAL_VERSION) {
|
||||
return AT_READ_FAIL;
|
||||
}
|
||||
return (res != AT_READ_FAIL) ? AT_READ_DEPR : res;
|
||||
|
@ -101,9 +171,55 @@ attrib_type at_key = {
|
|||
a_upgradekeys
|
||||
};
|
||||
|
||||
static int* keys_get(int *base, int i)
|
||||
{
|
||||
int n = base[0];
|
||||
assert(i >= 0 && i < n);
|
||||
return base + 1 + i * 2;
|
||||
}
|
||||
|
||||
static int *keys_update(int *base, int key, int val)
|
||||
{
|
||||
int *kv;
|
||||
int n = base[0];
|
||||
int l = keys_lower_bound(base, key, 0, n);
|
||||
if (l < n) {
|
||||
kv = keys_get(base, l);
|
||||
if (kv[0] == key) {
|
||||
kv[1] = val;
|
||||
}
|
||||
else {
|
||||
int sz = keys_size(n);
|
||||
assert(kv[0] > key);
|
||||
if (n + 1 > sz) {
|
||||
ptrdiff_t diff = kv - base;
|
||||
sz = keys_size(n + 1);
|
||||
base = realloc(base, (sz * 2 + 1) * sizeof(int));
|
||||
kv = base + diff;
|
||||
}
|
||||
base[0] = n + 1;
|
||||
memmove(kv + 2, kv, 2 * sizeof(int) * (n - l));
|
||||
kv[0] = key;
|
||||
kv[1] = val;
|
||||
}
|
||||
}
|
||||
else {
|
||||
int sz = keys_size(n);
|
||||
if (n + 1 > sz) {
|
||||
sz = keys_size(n + 1);
|
||||
base = realloc(base, (sz * 2 + 1) * sizeof(int));
|
||||
}
|
||||
base[0] = n + 1;
|
||||
kv = keys_get(base, l);
|
||||
kv[0] = key;
|
||||
kv[1] = val;
|
||||
}
|
||||
return base;
|
||||
}
|
||||
|
||||
void key_set(attrib ** alist, int key, int val)
|
||||
{
|
||||
int *keys, n = 0;
|
||||
int *keys;
|
||||
attrib *a;
|
||||
assert(key != 0);
|
||||
a = a_find(*alist, &at_keys);
|
||||
|
@ -111,16 +227,17 @@ void key_set(attrib ** alist, int key, int val)
|
|||
a = a_add(alist, a_new(&at_keys));
|
||||
}
|
||||
keys = (int *)a->data.v;
|
||||
if (keys) {
|
||||
n = keys[0];
|
||||
if (!keys) {
|
||||
int sz = keys_size(1);
|
||||
a->data.v = keys = malloc((2 * sz + 1) * sizeof(int));
|
||||
keys[0] = 1;
|
||||
keys[1] = key;
|
||||
keys[2] = val;
|
||||
}
|
||||
else {
|
||||
a->data.v = keys = keys_update(keys, key, val);
|
||||
assert(keys[0] < 4096 && keys[0] >= 0);
|
||||
}
|
||||
/* TODO: too many allocations, unsorted array */
|
||||
keys = realloc(keys, sizeof(int) *(2 * n + 3));
|
||||
keys[0] = n + 1;
|
||||
assert(keys[0] < 4096 && keys[0]>=0);
|
||||
keys[2 * n + 1] = key;
|
||||
keys[2 * n + 2] = val;
|
||||
a->data.v = keys;
|
||||
}
|
||||
|
||||
void key_unset(attrib ** alist, int key)
|
||||
|
@ -129,15 +246,14 @@ void key_unset(attrib ** alist, int key)
|
|||
assert(key != 0);
|
||||
a = a_find(*alist, &at_keys);
|
||||
if (a) {
|
||||
int i, *keys = (int *)a->data.v;
|
||||
int *keys = (int *)a->data.v;
|
||||
if (keys) {
|
||||
int n = keys[0];
|
||||
assert(keys[0] < 4096 && keys[0]>0);
|
||||
for (i = 0; i != n; ++i) {
|
||||
if (keys[2 * i + 1] == key) {
|
||||
memmove(keys + 2 * i + 1, keys + 2 * n - 1, 2 * sizeof(int));
|
||||
keys[0]--;
|
||||
break;
|
||||
int l = keys_lower_bound(keys, key, 0, n);
|
||||
if (l < n) {
|
||||
int *kv = keys_get(keys, l);
|
||||
if (kv[0] == key) {
|
||||
kv[1] = 0; /* do not delete, just set to 0 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,12 +265,14 @@ int key_get(attrib *alist, int key) {
|
|||
assert(key != 0);
|
||||
a = a_find(alist, &at_keys);
|
||||
if (a) {
|
||||
int i, *keys = (int *)a->data.v;
|
||||
int *keys = (int *)a->data.v;
|
||||
if (keys) {
|
||||
/* TODO: binary search this! */
|
||||
for (i = 0; i != keys[0]; ++i) {
|
||||
if (keys[i*2+1] == key) {
|
||||
return keys[i * 2 + 2];
|
||||
int n = keys[0];
|
||||
int l = keys_lower_bound(keys, key, 0, n);
|
||||
if (l < n) {
|
||||
int * kv = keys_get(keys, l);
|
||||
if (kv[0] == key) {
|
||||
return kv[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,8 +32,8 @@ static void test_upgrade_key(CuTest *tc) {
|
|||
attrib *alist = 0;
|
||||
key_set_orig(&alist, 40);
|
||||
key_set_orig(&alist, 41);
|
||||
key_set_orig(&alist, 42);
|
||||
key_set_orig(&alist, 43);
|
||||
key_set_orig(&alist, 42);
|
||||
key_set_orig(&alist, 44);
|
||||
CuAssertPtrNotNull(tc, alist->type->upgrade);
|
||||
alist->type->upgrade(&alist, alist);
|
||||
|
|
77
src/battle.c
77
src/battle.c
|
@ -28,6 +28,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "skill.h"
|
||||
#include "study.h"
|
||||
|
||||
#include <spells/buildingcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
#include <spells/unitcurse.h>
|
||||
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/alliance.h>
|
||||
#include <kernel/build.h>
|
||||
|
@ -55,7 +59,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <attributes/racename.h>
|
||||
#include <attributes/otherfaction.h>
|
||||
#include <attributes/moved.h>
|
||||
#include <spells/buildingcurse.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/assert.h>
|
||||
|
@ -139,15 +142,10 @@ static int rule_nat_armor;
|
|||
static int rule_cavalry_mode;
|
||||
static int rule_vampire;
|
||||
|
||||
static const curse_type *peace_ct, *slave_ct, *calm_ct;
|
||||
|
||||
/** initialize rules from configuration.
|
||||
*/
|
||||
static void init_rules(void)
|
||||
{
|
||||
peace_ct = ct_find("peacezone");
|
||||
slave_ct = ct_find("slavery");
|
||||
calm_ct = ct_find("calmmonster");
|
||||
rule_nat_armor = config_get_int("rules.combat.nat_armor", 0);
|
||||
rule_tactics_formula = config_get_int("rules.tactics.formula", 0);
|
||||
rule_goblin_bonus = config_get_int("rules.combat.goblinbonus", 10);
|
||||
|
@ -1904,14 +1902,11 @@ int skilldiff(troop at, troop dt, int dist)
|
|||
if (df->building) {
|
||||
building *b = df->building;
|
||||
if (b->attribs) {
|
||||
const curse_type *strongwall_ct = ct_find("strongwall");
|
||||
if (strongwall_ct) {
|
||||
curse *c = get_curse(b->attribs, strongwall_ct);
|
||||
if (curse_active(c)) {
|
||||
/* wirkt auf alle Geb<65>ude */
|
||||
skdiff -= curse_geteffect_int(c);
|
||||
is_protected = 2;
|
||||
}
|
||||
curse *c = get_curse(b->attribs, &ct_strongwall);
|
||||
if (curse_active(c)) {
|
||||
/* wirkt auf alle Geb<65>ude */
|
||||
skdiff -= curse_geteffect_int(c);
|
||||
is_protected = 2;
|
||||
}
|
||||
}
|
||||
if (b->type->flags & BTF_FORTIFICATION) {
|
||||
|
@ -3188,14 +3183,10 @@ fighter *make_fighter(battle * b, unit * u, side * s1, bool attack)
|
|||
/* Effekte von Spr<70>chen */
|
||||
|
||||
if (u->attribs) {
|
||||
const curse_type *speed_ct;
|
||||
speed_ct = ct_find("speed");
|
||||
if (speed_ct) {
|
||||
curse *c = get_curse(u->attribs, speed_ct);
|
||||
if (c) {
|
||||
speeded = get_cursedmen(u, c);
|
||||
speed = curse_geteffect_int(c);
|
||||
}
|
||||
curse *c = get_curse(u->attribs, &ct_speed);
|
||||
if (c) {
|
||||
speeded = get_cursedmen(u, c);
|
||||
speed = curse_geteffect_int(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3763,6 +3754,21 @@ static void flee(const troop dt)
|
|||
kill_troop(dt);
|
||||
}
|
||||
|
||||
static bool is_calmed(const unit *u, const faction *f) {
|
||||
attrib *a = a_find(u->attribs, &at_curse);
|
||||
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *)a->data.v;
|
||||
if (c->type == &ct_calmmonster && curse_geteffect_int(c) == f->subscription) {
|
||||
if (curse_active(c)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool start_battle(region * r, battle ** bp)
|
||||
{
|
||||
battle *b = NULL;
|
||||
|
@ -3809,12 +3815,12 @@ static bool start_battle(region * r, battle ** bp)
|
|||
if (fval(u, UFL_LONGACTION))
|
||||
continue;
|
||||
|
||||
if (peace_ct && curse_active(get_curse(r->attribs, peace_ct))) {
|
||||
if (curse_active(get_curse(r->attribs, &ct_peacezone))) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "peace_active", ""));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (slave_ct && curse_active(get_curse(u->attribs, slave_ct))) {
|
||||
if (curse_active(get_curse(u->attribs, &ct_slavery))) {
|
||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "slave_active", ""));
|
||||
continue;
|
||||
}
|
||||
|
@ -3862,26 +3868,11 @@ static bool start_battle(region * r, battle ** bp)
|
|||
NewbieImmunity()));
|
||||
continue;
|
||||
}
|
||||
/* Fehler: "Die Einheit ist mit uns alliert" */
|
||||
|
||||
if (calm_ct) {
|
||||
attrib *a = a_find(u->attribs, &at_curse);
|
||||
bool calm = false;
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *)a->data.v;
|
||||
if (c->type == calm_ct
|
||||
&& curse_geteffect_int(c) == u2->faction->subscription) {
|
||||
if (curse_active(c)) {
|
||||
calm = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
if (calm) {
|
||||
cmistake(u, ord, 47, MSG_BATTLE);
|
||||
continue;
|
||||
}
|
||||
/* Fehler: "Die Einheit ist mit uns alliert" */
|
||||
if (is_calmed(u, u2->faction)) {
|
||||
cmistake(u, ord, 47, MSG_BATTLE);
|
||||
continue;
|
||||
}
|
||||
/* Ende Fehlerbehandlung */
|
||||
if (b == NULL) {
|
||||
|
|
|
@ -471,11 +471,9 @@ static void test_battle_skilldiff_building(CuTest *tc)
|
|||
unit *ua, *ud;
|
||||
battle *b = NULL;
|
||||
building_type *btype;
|
||||
const curse_type *strongwall_ct;
|
||||
|
||||
test_setup();
|
||||
btype = setup_castle();
|
||||
strongwall_ct = ct_find("strongwall");
|
||||
|
||||
r = test_create_region(0, 0, 0);
|
||||
ud = test_create_unit(test_create_faction(0), r);
|
||||
|
@ -494,7 +492,7 @@ static void test_battle_skilldiff_building(CuTest *tc)
|
|||
create_curse(NULL, &ud->building->attribs, &ct_magicwalls, 1, 1, 1, 1);
|
||||
CuAssertIntEquals(tc, -2, skilldiff(ta, td, 0));
|
||||
|
||||
create_curse(NULL, &ud->building->attribs, strongwall_ct, 1, 1, 2, 1);
|
||||
create_curse(NULL, &ud->building->attribs, &ct_strongwall, 1, 1, 2, 1);
|
||||
CuAssertIntEquals(tc, -4, skilldiff(ta, td, 0));
|
||||
|
||||
free_battle(b);
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#include "spells/shipcurse.h"
|
||||
#include "monsters.h"
|
||||
|
||||
#include <spells/flyingship.h>
|
||||
|
||||
#include <kernel/equipment.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/race.h>
|
||||
|
@ -9,8 +11,6 @@
|
|||
#include <kernel/spellbook.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
#include <spells/flyingship.h>
|
||||
|
||||
#include <tolua.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
|
|
@ -20,6 +20,8 @@ without prior permission by the authors of Eressea.
|
|||
#define BUFFERSIZE 32768
|
||||
#define RESOURCECOMPAT
|
||||
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
/* modules include */
|
||||
#include <modules/score.h>
|
||||
|
||||
|
@ -1361,7 +1363,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
|
|||
if (skill_enabled(SK_ENTERTAINMENT)) {
|
||||
fprintf(F, "%d;Unterh\n", entertainmoney(r));
|
||||
}
|
||||
if (is_cursed(r->attribs, C_RIOT, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_riotzone)) {
|
||||
fputs("0;Rekruten\n", F);
|
||||
}
|
||||
else {
|
||||
|
@ -1419,7 +1421,7 @@ static void cr_output_region(FILE * F, report_context * ctx, region * r)
|
|||
cr_output_curses_compat(F, f, r, TYP_REGION);
|
||||
cr_borders(r, f, r->seen.mode, F);
|
||||
if (r->seen.mode >= seen_unit && is_astral(r)
|
||||
&& !is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
||||
&& !is_cursed(r->attribs, &ct_astralblock)) {
|
||||
/* Sonderbehandlung Teleport-Ebene */
|
||||
region_list *rl = astralregions(r, inhabitable);
|
||||
|
||||
|
|
|
@ -36,6 +36,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "reports.h"
|
||||
#include "calendar.h"
|
||||
|
||||
#include <attributes/reduceproduction.h>
|
||||
#include <attributes/racename.h>
|
||||
#include <spells/buildingcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
#include <spells/unitcurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/building.h>
|
||||
|
@ -67,10 +73,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/parser.h>
|
||||
#include <util/rng.h>
|
||||
|
||||
#include <attributes/reduceproduction.h>
|
||||
#include <attributes/racename.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
/* libs includes */
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
@ -117,14 +119,14 @@ int entertainmoney(const region * r)
|
|||
{
|
||||
double n;
|
||||
|
||||
if (is_cursed(r->attribs, C_DEPRESSION, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_depression)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = rmoney(r) / (double)ENTERTAINFRACTION;
|
||||
|
||||
if (is_cursed(r->attribs, C_GENEROUS, 0)) {
|
||||
n *= get_curseeffect(r->attribs, C_GENEROUS, 0);
|
||||
if (is_cursed(r->attribs, &ct_generous)) {
|
||||
n *= get_curseeffect(r->attribs, &ct_generous);
|
||||
}
|
||||
|
||||
return (int)n;
|
||||
|
@ -501,7 +503,7 @@ static void recruit(unit * u, struct order *ord, request ** recruitorders)
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (is_cursed(r->attribs, C_RIOT, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_riotzone)) {
|
||||
/* Die Region befindet sich in Aufruhr */
|
||||
cmistake(u, ord, 237, MSG_EVENT);
|
||||
return;
|
||||
|
@ -651,7 +653,7 @@ static int forget_cmd(unit * u, order * ord)
|
|||
skill_t sk;
|
||||
const char *s;
|
||||
|
||||
if (is_cursed(u->attribs, C_SLAVE, 0)) {
|
||||
if (is_cursed(u->attribs, &ct_slavery)) {
|
||||
/* charmed units shouldn't be losing their skills */
|
||||
return 0;
|
||||
}
|
||||
|
@ -729,13 +731,12 @@ static int maintain(building * b)
|
|||
|
||||
void maintain_buildings(region * r)
|
||||
{
|
||||
const curse_type *nocost_ct = ct_find("nocostbuilding");
|
||||
building **bp = &r->buildings;
|
||||
while (*bp) {
|
||||
building *b = *bp;
|
||||
int flags = BLD_MAINTAINED;
|
||||
|
||||
if (!curse_active(get_curse(b->attribs, nocost_ct))) {
|
||||
if (!curse_active(get_curse(b->attribs, &ct_nocostbuilding))) {
|
||||
flags = maintain(b);
|
||||
}
|
||||
fset(b, flags);
|
||||
|
@ -2589,7 +2590,7 @@ void entertain_cmd(unit * u, struct order *ord)
|
|||
cmistake(u, ord, 69, MSG_INCOME);
|
||||
return;
|
||||
}
|
||||
if (is_cursed(r->attribs, C_DEPRESSION, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_depression)) {
|
||||
cmistake(u, ord, 28, MSG_INCOME);
|
||||
return;
|
||||
}
|
||||
|
@ -3026,7 +3027,7 @@ void produce(struct region *r)
|
|||
continue;
|
||||
|
||||
if (u_race(u) == rc_insect && r_insectstalled(r) &&
|
||||
!is_cursed(u->attribs, C_KAELTESCHUTZ, 0))
|
||||
!is_cursed(u->attribs, &ct_insectfur))
|
||||
continue;
|
||||
|
||||
if (fval(u, UFL_LONGACTION) && u->thisorder == NULL) {
|
||||
|
|
14
src/give.c
14
src/give.c
|
@ -17,7 +17,12 @@
|
|||
#include "economy.h"
|
||||
#include "laws.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include <spells/unitcurse.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/racename.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/build.h>
|
||||
#include <kernel/curse.h>
|
||||
|
@ -33,9 +38,6 @@
|
|||
#include <kernel/terrain.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/racename.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/base36.h>
|
||||
|
@ -286,7 +288,7 @@ static bool can_give_men(const unit *u, const unit *dst, order *ord, message **m
|
|||
/* hungry people cannot be given away */
|
||||
if (msg) *msg = msg_error(u, ord, 73);
|
||||
}
|
||||
else if (fval(u, UFL_LOCKED) || is_cursed(u->attribs, C_SLAVE, 0)) {
|
||||
else if (fval(u, UFL_LOCKED) || is_cursed(u->attribs, &ct_slavery)) {
|
||||
if (msg) *msg = msg_error(u, ord, 74);
|
||||
}
|
||||
else {
|
||||
|
@ -329,7 +331,7 @@ message * give_men(int n, unit * u, unit * u2, struct order *ord)
|
|||
else if (unit_has_cursed_item(u2)) {
|
||||
error = 78;
|
||||
}
|
||||
else if (fval(u2, UFL_LOCKED) || is_cursed(u2->attribs, C_SLAVE, 0)) {
|
||||
else if (fval(u2, UFL_LOCKED) || is_cursed(u2->attribs, &ct_slavery)) {
|
||||
error = 75;
|
||||
}
|
||||
else if (!ucontact(u2, u)) {
|
||||
|
|
|
@ -903,6 +903,7 @@ static void seed_player(state *st, const newfaction *player) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void handlekey(state * st, int c)
|
||||
{
|
||||
window *wnd;
|
||||
|
|
17
src/items.c
17
src/items.c
|
@ -7,6 +7,12 @@
|
|||
#include "move.h"
|
||||
#include "magic.h"
|
||||
|
||||
#include <attributes/fleechance.h>
|
||||
|
||||
#include <spells/shipcurse.h>
|
||||
#include <spells/unitcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
#include <kernel/curse.h>
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/faction.h>
|
||||
|
@ -21,9 +27,6 @@
|
|||
#include <kernel/spell.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
#include <attributes/fleechance.h>
|
||||
#include <spells/shipcurse.h>
|
||||
|
||||
/* triggers includes */
|
||||
#include <triggers/changerace.h>
|
||||
#include <triggers/timeout.h>
|
||||
|
@ -167,7 +170,7 @@ struct order *ord)
|
|||
}
|
||||
|
||||
if (force > 0) {
|
||||
create_curse(u, &r->attribs, ct_find("antimagiczone"), force, duration,
|
||||
create_curse(u, &r->attribs, &ct_antimagiczone, force, duration,
|
||||
effect, 0);
|
||||
}
|
||||
}
|
||||
|
@ -185,7 +188,7 @@ int amount, struct order *ord)
|
|||
{
|
||||
int money;
|
||||
|
||||
if (get_curse(u->region->attribs, ct_find("depression"))) {
|
||||
if (get_curse(u->region->attribs, &ct_depression)) {
|
||||
cmistake(u, ord, 58, MSG_MAGIC);
|
||||
return -1;
|
||||
}
|
||||
|
@ -194,7 +197,7 @@ int amount, struct order *ord)
|
|||
change_money(u, money);
|
||||
rsetmoney(u->region, rmoney(u->region) - money);
|
||||
|
||||
create_curse(u, &u->region->attribs, ct_find("depression"),
|
||||
create_curse(u, &u->region->attribs, &ct_depression,
|
||||
20, BAGPIPEDURATION, 0.0, 0);
|
||||
|
||||
ADDMSG(&u->faction->msgs, msg_message("bagpipeoffear_faction",
|
||||
|
@ -354,7 +357,7 @@ use_tacticcrystal(unit * u, const struct item_type *itype, int amount,
|
|||
der vor den Antimagiezaubern passiert */
|
||||
|
||||
effect = (float)(rng_int() % 6 - 1);
|
||||
c = create_curse(u, &u->attribs, ct_find("skillmod"), power,
|
||||
c = create_curse(u, &u->attribs, &ct_skillmod, power,
|
||||
duration, effect, u->number);
|
||||
c->data.i = SK_TACTICS;
|
||||
UNUSED_ARG(ord);
|
||||
|
|
|
@ -21,6 +21,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/config.h>
|
||||
#include "building.h"
|
||||
|
||||
#include <attributes/reduceproduction.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include "curse.h"
|
||||
#include "item.h"
|
||||
|
@ -54,10 +57,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <string.h>
|
||||
#include <limits.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <spells/regioncurse.h>
|
||||
#include <attributes/reduceproduction.h>
|
||||
|
||||
typedef struct building_typelist {
|
||||
struct building_typelist *next;
|
||||
building_type *type;
|
||||
|
@ -681,12 +680,7 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn)
|
|||
building *b = largestbuilding(r, cmp_wage, false);
|
||||
int esize = 0;
|
||||
double wage;
|
||||
static int ct_cache;
|
||||
static const struct curse_type *drought_ct;
|
||||
|
||||
if (ct_changed(&ct_cache)) {
|
||||
drought_ct = ct_find("drought");
|
||||
}
|
||||
if (b != NULL) {
|
||||
/* TODO: this reveals imaginary castles */
|
||||
esize = buildingeffsize(b, false);
|
||||
|
@ -717,18 +711,18 @@ default_wage(const region * r, const faction * f, const race * rc, int in_turn)
|
|||
|
||||
if (r->attribs) {
|
||||
attrib *a;
|
||||
const struct curse_type *ctype;
|
||||
curse *c;
|
||||
|
||||
/* Godcurse: Income -10 */
|
||||
ctype = ct_find("godcursezone");
|
||||
if (ctype && curse_active(get_curse(r->attribs, ctype))) {
|
||||
c = get_curse(r->attribs, &ct_godcursezone);
|
||||
if (c && curse_active(c)) {
|
||||
wage = MAX(0, wage - 10);
|
||||
}
|
||||
|
||||
/* Bei einer D<>rre verdient man nur noch ein Viertel */
|
||||
if (drought_ct) {
|
||||
curse *c = get_curse(r->attribs, drought_ct);
|
||||
if (curse_active(c))
|
||||
wage /= curse_geteffect(c);
|
||||
c = get_curse(r->attribs, &ct_drought);
|
||||
if (c && curse_active(c)) {
|
||||
wage /= curse_geteffect(c);
|
||||
}
|
||||
|
||||
a = a_find(r->attribs, &at_reduceproduction);
|
||||
|
|
|
@ -141,10 +141,11 @@ static int read_ccompat(const char *cursename, struct storage *store)
|
|||
struct compat {
|
||||
const char *name;
|
||||
const char *tokens;
|
||||
} *seek, old_curses[] = { {
|
||||
"disorientationzone", "" }, {
|
||||
"shipdisorientation", "" }, {
|
||||
NULL, NULL } };
|
||||
} *seek, old_curses[] = {
|
||||
{ "disorientationzone", "" },
|
||||
{ "shipdisorientation", "" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
for (seek = old_curses; seek->name; ++seek) {
|
||||
if (strcmp(seek->tokens, cursename) == 0) {
|
||||
const char *p;
|
||||
|
@ -213,6 +214,12 @@ int curse_read(attrib * a, void *owner, gamedata *data)
|
|||
assert(result == 0);
|
||||
return AT_READ_FAIL;
|
||||
}
|
||||
if (data->version <= NOLANDITEM_VERSION) {
|
||||
if ((c->type->flags & CURSE_NOAGE) && !(c_flags(c) & CURSE_NOAGE)) {
|
||||
/* bugfix bug 2356 */
|
||||
c_setflag(c, CURSE_NOAGE);
|
||||
}
|
||||
}
|
||||
if (data->version < EXPLICIT_CURSE_ISNEW_VERSION) {
|
||||
c_clearflag(c, CURSE_ISNEW);
|
||||
}
|
||||
|
@ -226,7 +233,7 @@ int curse_read(attrib * a, void *owner, gamedata *data)
|
|||
if (c->type->typ == CURSETYP_REGION) {
|
||||
int rr =
|
||||
read_reference(&c->data.v, data, read_region_reference,
|
||||
RESOLVE_REGION(data->version));
|
||||
RESOLVE_REGION(data->version));
|
||||
if (ur == 0 && rr == 0 && !c->data.v) {
|
||||
return AT_READ_FAIL;
|
||||
}
|
||||
|
@ -278,27 +285,15 @@ attrib_type at_curse = {
|
|||
|
||||
#define MAXCTHASH 128
|
||||
static selist *cursetypes[MAXCTHASH];
|
||||
static int ct_changes = 1;
|
||||
|
||||
bool ct_changed(int *cache)
|
||||
{
|
||||
assert(cache);
|
||||
if (*cache != ct_changes) {
|
||||
*cache = ct_changes;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ct_register(const curse_type * ct)
|
||||
{
|
||||
unsigned int hash = tolower(ct->cname[0]) & 0xFF;
|
||||
selist **ctlp = cursetypes + hash;
|
||||
|
||||
assert(ct->age==NULL || (ct->flags&CURSE_NOAGE) == 0);
|
||||
assert(ct->age == NULL || (ct->flags&CURSE_NOAGE) == 0);
|
||||
assert((ct->flags&CURSE_ISNEW) == 0);
|
||||
selist_set_insert(ctlp, (void *)ct, NULL);
|
||||
++ct_changes;
|
||||
}
|
||||
|
||||
void ct_remove(const char *c)
|
||||
|
@ -314,7 +309,6 @@ void ct_remove(const char *c)
|
|||
|
||||
if (strcmp(c, type->cname) == 0) {
|
||||
selist_delete(&ctl, qi);
|
||||
++ct_changes;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -473,7 +467,7 @@ int curse_geteffect_int(const curse * c)
|
|||
/* ------------------------------------------------------------- */
|
||||
static void
|
||||
set_curseingmagician(struct unit *magician, struct attrib *ap_target,
|
||||
const curse_type * ct)
|
||||
const curse_type * ct)
|
||||
{
|
||||
curse *c = get_curse(ap_target, ct);
|
||||
if (c) {
|
||||
|
@ -725,51 +719,6 @@ bool is_cursed_with(const attrib * ap, const curse * c)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* cursedata */
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static const char *oldnames[MAXCURSE] = {
|
||||
/* OBS: when removing curses, remember to update read_ccompat() */
|
||||
"fogtrap",
|
||||
"antimagiczone",
|
||||
"farvision",
|
||||
"gbdream",
|
||||
"auraboost",
|
||||
"maelstrom",
|
||||
"blessedharvest",
|
||||
"drought",
|
||||
"badlearn",
|
||||
"stormwind",
|
||||
"flyingship",
|
||||
"nodrift",
|
||||
"depression",
|
||||
"magicwalls",
|
||||
"strongwall",
|
||||
"astralblock",
|
||||
"generous",
|
||||
"peacezone",
|
||||
"magicstreet",
|
||||
"magicrunes",
|
||||
"badmagicresistancezone",
|
||||
"goodmagicresistancezone",
|
||||
"slavery",
|
||||
"calmmonster",
|
||||
"oldrace",
|
||||
"fumble",
|
||||
"riotzone",
|
||||
"godcursezone",
|
||||
"speed",
|
||||
"orcish",
|
||||
"magicboost",
|
||||
"insectfur"
|
||||
};
|
||||
|
||||
const char *oldcursename(int id)
|
||||
{
|
||||
return oldnames[id];
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
message *cinfo_simple(const void *obj, objtype_t typ, const struct curse * c,
|
||||
int self)
|
||||
|
@ -834,5 +783,4 @@ void curses_done(void) {
|
|||
selist_free(cursetypes[i]);
|
||||
cursetypes[i] = 0;
|
||||
}
|
||||
++ct_changes;
|
||||
}
|
||||
|
|
|
@ -285,7 +285,6 @@ extern "C" {
|
|||
struct curse *get_curse(struct attrib *ap, const curse_type * ctype);
|
||||
|
||||
const curse_type *ct_find(const char *c);
|
||||
bool ct_changed(int *cache);
|
||||
void ct_register(const curse_type *);
|
||||
void ct_remove(const char *c);
|
||||
void ct_checknames(void);
|
||||
|
@ -304,14 +303,13 @@ extern "C" {
|
|||
bool curse_active(const struct curse *c);
|
||||
|
||||
/*** COMPATIBILITY MACROS. DO NOT USE FOR NEW CODE, REPLACE IN OLD CODE: */
|
||||
const char *oldcursename(int id);
|
||||
struct message *cinfo_simple(const void *obj, objtype_t typ,
|
||||
const struct curse *c, int self);
|
||||
int curse_cansee(const struct curse *c, const struct faction *viewer, objtype_t typ, const void *obj, int self);
|
||||
#define is_cursed(a, id, id2) \
|
||||
(a && curse_active(get_curse(a, ct_find(oldcursename(id)))))
|
||||
#define get_curseeffect(a, id, id2) \
|
||||
curse_geteffect(get_curse(a, ct_find(oldcursename(id))))
|
||||
#define is_cursed(a, ctype) \
|
||||
(a && curse_active(get_curse(a, ctype)))
|
||||
#define get_curseeffect(a, ctype) \
|
||||
curse_geteffect(get_curse(a, ctype))
|
||||
|
||||
/* eressea-defined attribute-type flags */
|
||||
#define ATF_CURSE ATF_USER_DEFINED
|
||||
|
|
|
@ -159,24 +159,6 @@ static void test_write_flag(CuTest *tc) {
|
|||
cleanup_curse(&fix);
|
||||
}
|
||||
|
||||
static void test_curse_cache(CuTest *tc)
|
||||
{
|
||||
int cache = 0;
|
||||
const curse_type ct_dummy = { "dummy", CURSETYP_NORM, 0, M_SUMEFFECT, NULL };
|
||||
test_setup();
|
||||
CuAssertIntEquals(tc, true, ct_changed(&cache));
|
||||
CuAssertIntEquals(tc, false, ct_changed(&cache));
|
||||
CuAssertPtrEquals(tc, NULL, (void *)ct_find(ct_dummy.cname));
|
||||
ct_register(&ct_dummy);
|
||||
CuAssertIntEquals(tc, true, ct_changed(&cache));
|
||||
CuAssertPtrEquals(tc, (void *)&ct_dummy, (void *)ct_find(ct_dummy.cname));
|
||||
ct_remove(ct_dummy.cname);
|
||||
CuAssertIntEquals(tc, true, ct_changed(&cache));
|
||||
CuAssertIntEquals(tc, false, ct_changed(&cache));
|
||||
CuAssertPtrEquals(tc, NULL, (void *)ct_find(ct_dummy.cname));
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
static void test_curse_ids(CuTest *tc) {
|
||||
const curse_type ct_dummy = { "dummy", CURSETYP_NORM, 0, M_SUMEFFECT, NULL };
|
||||
curse *c1, *c2;
|
||||
|
@ -218,7 +200,6 @@ CuSuite *get_curse_suite(void)
|
|||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_curse);
|
||||
SUITE_ADD_TEST(suite, test_curse_cache);
|
||||
SUITE_ADD_TEST(suite, test_magicstreet);
|
||||
SUITE_ADD_TEST(suite, test_magicstreet_warning);
|
||||
SUITE_ADD_TEST(suite, test_good_dreams);
|
||||
|
|
|
@ -33,6 +33,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "terrain.h"
|
||||
#include "unit.h"
|
||||
|
||||
#include <spells/unitcurse.h>
|
||||
#include <attributes/otherfaction.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/base36.h>
|
||||
|
@ -49,8 +52,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/rng.h>
|
||||
#include <util/variant.h>
|
||||
|
||||
#include <attributes/otherfaction.h>
|
||||
|
||||
#include <selist.h>
|
||||
#include <storage.h>
|
||||
|
||||
|
@ -729,7 +730,7 @@ int count_faction(const faction * f, int flags)
|
|||
}
|
||||
}
|
||||
else if (flags&COUNT_MIGRANTS) {
|
||||
if (!is_cursed(u->attribs, C_SLAVE, 0)) {
|
||||
if (!is_cursed(u->attribs, &ct_slavery)) {
|
||||
n += x;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,6 +37,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "terrainid.h"
|
||||
#include "unit.h"
|
||||
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/assert.h>
|
||||
#include <util/attrib.h>
|
||||
|
@ -157,7 +159,7 @@ void deathcounts(region * r, int fallen)
|
|||
if (fallen == 0)
|
||||
return;
|
||||
if (r->attribs) {
|
||||
const curse_type *ctype = ct_find("holyground");
|
||||
const curse_type *ctype = &ct_holyground;
|
||||
if (ctype && curse_active(get_curse(r->attribs, ctype)))
|
||||
return;
|
||||
a = a_find(r->attribs, &at_deathcount);
|
||||
|
@ -584,7 +586,7 @@ int rroad(const region * r, direction_t d)
|
|||
bool r_isforest(const region * r)
|
||||
{
|
||||
if (fval(r->terrain, FOREST_REGION)) {
|
||||
/* needs to be covered with at leas 48% trees */
|
||||
/* needs to be covered with at least 48% trees */
|
||||
int mincover = (int)(r->terrain->size * 0.48);
|
||||
int trees = rtrees(r, 2) + rtrees(r, 1);
|
||||
return (trees * TREESIZE >= mincover);
|
||||
|
@ -1242,8 +1244,9 @@ int production(const region * r)
|
|||
{
|
||||
/* muß rterrain(r) sein, nicht rterrain() wegen rekursion */
|
||||
int p = r->terrain->size;
|
||||
if (curse_active(get_curse(r->attribs, ct_find("drought"))))
|
||||
if (curse_active(get_curse(r->attribs, &ct_drought))) {
|
||||
p /= 2;
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/config.h>
|
||||
#include "ship.h"
|
||||
|
||||
#include <attributes/movement.h>
|
||||
#include <spells/shipcurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include "build.h"
|
||||
#include "curse.h"
|
||||
|
@ -41,9 +44,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/umlaut.h>
|
||||
#include <util/xml.h>
|
||||
|
||||
#include <attributes/movement.h>
|
||||
#include <spells/shipcurse.h>
|
||||
|
||||
#include <storage.h>
|
||||
#include <selist.h>
|
||||
#include <critbit.h>
|
||||
|
@ -332,10 +332,10 @@ int shipspeed(const ship * sh, const unit * u)
|
|||
return 0;
|
||||
|
||||
if (sh->attribs) {
|
||||
if (curse_active(get_curse(sh->attribs, ct_find("stormwind")))) {
|
||||
if (curse_active(get_curse(sh->attribs, &ct_stormwind))) {
|
||||
k *= 2;
|
||||
}
|
||||
if (curse_active(get_curse(sh->attribs, ct_find("nodrift")))) {
|
||||
if (curse_active(get_curse(sh->attribs, &ct_nodrift))) {
|
||||
k += 1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -432,8 +432,11 @@ static void test_shipspeed_stormwind(CuTest *tc) {
|
|||
register_shipcurse();
|
||||
assert(sh && cap && crew);
|
||||
|
||||
create_curse(0, &sh->attribs, ct_find("stormwind"), 1, 1, 1, 0);
|
||||
create_curse(0, &sh->attribs, &ct_stormwind, 1, 1, 1, 0);
|
||||
CuAssertPtrNotNull(tc, sh->attribs);
|
||||
CuAssertIntEquals_Msg(tc, "stormwind doubles ship range", sh->type->range * 2, shipspeed(sh, cap));
|
||||
a_age(&sh->attribs, sh);
|
||||
CuAssertPtrEquals(tc, NULL, sh->attribs);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
|
@ -447,7 +450,7 @@ static void test_shipspeed_nodrift(CuTest *tc) {
|
|||
register_shipcurse();
|
||||
assert(sh && cap && crew);
|
||||
|
||||
create_curse(0, &sh->attribs, ct_find("nodrift"), 1, 1, 1, 0);
|
||||
create_curse(0, &sh->attribs, &ct_nodrift, 1, 1, 1, 0);
|
||||
CuAssertIntEquals_Msg(tc, "nodrift adds +1 to range", sh->type->range + 1, shipspeed(sh, cap));
|
||||
test_cleanup();
|
||||
}
|
||||
|
|
|
@ -18,14 +18,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <platform.h>
|
||||
#include <kernel/config.h>
|
||||
#include <attributes/racename.h>
|
||||
#include "terrain.h"
|
||||
#include "terrainid.h"
|
||||
|
||||
#include <attributes/racename.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include "curse.h"
|
||||
#include "region.h"
|
||||
#include "resources.h"
|
||||
#include "terrainid.h"
|
||||
|
||||
#include <util/log.h>
|
||||
#include <util/attrib.h>
|
||||
|
@ -160,7 +162,7 @@ const char *terrain_name(const struct region *r)
|
|||
return r->terrain->name(r);
|
||||
}
|
||||
else if (fval(r->terrain, SEA_REGION)) {
|
||||
if (curse_active(get_curse(r->attribs, ct_find("maelstrom")))) {
|
||||
if (curse_active(get_curse(r->attribs, &ct_maelstrom))) {
|
||||
return "maelstrom";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,6 +43,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <attributes/racename.h>
|
||||
#include <attributes/stealth.h>
|
||||
|
||||
#include <spells/unitcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
#include "guard.h"
|
||||
|
||||
/* util includes */
|
||||
|
@ -923,8 +926,7 @@ bool can_survive(const unit * u, const region * r)
|
|||
return false;
|
||||
|
||||
if (r->attribs) {
|
||||
const curse_type *ctype = ct_find("holyground");
|
||||
if (fval(u_race(u), RCF_UNDEAD) && curse_active(get_curse(r->attribs, ctype)))
|
||||
if (fval(u_race(u), RCF_UNDEAD) && curse_active(get_curse(r->attribs, &ct_holyground)))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -1255,52 +1257,45 @@ static int att_modification(const unit * u, skill_t sk)
|
|||
|
||||
if (u->attribs) {
|
||||
curse *c;
|
||||
static int cache;
|
||||
static const curse_type *skillmod_ct, *worse_ct;
|
||||
if (ct_changed(&cache)) {
|
||||
skillmod_ct = ct_find("skillmod");
|
||||
worse_ct = ct_find("worse");
|
||||
}
|
||||
c = get_curse(u->attribs, worse_ct);
|
||||
if (c != NULL)
|
||||
attrib *a;
|
||||
|
||||
c = get_curse(u->attribs, &ct_worse);
|
||||
if (c != NULL) {
|
||||
result += curse_geteffect(c);
|
||||
if (skillmod_ct) {
|
||||
attrib *a = a_find(u->attribs, &at_curse);
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *)a->data.v;
|
||||
if (c->type == skillmod_ct && c->data.i == sk) {
|
||||
result += curse_geteffect(c);
|
||||
break;
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
|
||||
a = a_find(u->attribs, &at_curse);
|
||||
while (a && a->type == &at_curse) {
|
||||
c = (curse *)a->data.v;
|
||||
if (c->type == &ct_skillmod && c->data.i == sk) {
|
||||
result += curse_geteffect(c);
|
||||
break;
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
}
|
||||
/* TODO hier kann nicht mit get/iscursed gearbeitet werden, da nur der
|
||||
* jeweils erste vom Typ C_GBDREAM zurueckgegen wird, wir aber alle
|
||||
* durchsuchen und aufaddieren muessen */
|
||||
if (u->region && u->region->attribs) {
|
||||
const curse_type *gbdream_ct = ct_find("gbdream");
|
||||
if (gbdream_ct) {
|
||||
int bonus = 0, malus = 0;
|
||||
attrib *a = a_find(u->region->attribs, &at_curse);
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *)a->data.v;
|
||||
int bonus = 0, malus = 0;
|
||||
attrib *a = a_find(u->region->attribs, &at_curse);
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *)a->data.v;
|
||||
|
||||
if (c->magician && curse_active(c) && c->type == gbdream_ct) {
|
||||
int effect = curse_geteffect_int(c);
|
||||
bool allied = alliedunit(c->magician, u->faction, HELP_GUARD);
|
||||
if (allied) {
|
||||
if (effect > bonus) bonus = effect;
|
||||
}
|
||||
else {
|
||||
if (effect < malus) malus = effect;
|
||||
}
|
||||
if (c->magician && curse_active(c) && c->type == &ct_gbdream) {
|
||||
int effect = curse_geteffect_int(c);
|
||||
bool allied = alliedunit(c->magician, u->faction, HELP_GUARD);
|
||||
if (allied) {
|
||||
if (effect > bonus) bonus = effect;
|
||||
}
|
||||
else {
|
||||
if (effect < malus) malus = effect;
|
||||
}
|
||||
a = a->next;
|
||||
}
|
||||
result = result + bonus + malus;
|
||||
a = a->next;
|
||||
}
|
||||
result = result + bonus + malus;
|
||||
}
|
||||
|
||||
return (int)result;
|
||||
|
@ -1728,16 +1723,9 @@ int unit_max_hp(const unit * u)
|
|||
|
||||
/* der healing curse veraendert die maximalen hp */
|
||||
if (u->region && u->region->attribs) {
|
||||
static int cache;
|
||||
static const curse_type *heal_ct;
|
||||
if (ct_changed(&cache)) {
|
||||
heal_ct = ct_find("healingzone");
|
||||
}
|
||||
if (heal_ct) {
|
||||
curse *c = get_curse(u->region->attribs, heal_ct);
|
||||
if (c) {
|
||||
h = (int)(h * (1.0 + (curse_geteffect(c) / 100)));
|
||||
}
|
||||
curse *c = get_curse(u->region->attribs, &ct_healing);
|
||||
if (c) {
|
||||
h = (int)(h * (1.0 + (curse_geteffect(c) / 100)));
|
||||
}
|
||||
}
|
||||
return h;
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#ifndef ERESSEA_VERSION
|
||||
/* the version number, if it was not passed to make with -D */
|
||||
#define ERESSEA_VERSION "3.13.0"
|
||||
#define ERESSEA_VERSION "3.14.0"
|
||||
#endif
|
||||
|
||||
const char *eressea_version(void) {
|
||||
|
|
45
src/laws.c
45
src/laws.c
|
@ -42,6 +42,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "calendar.h"
|
||||
#include "guard.h"
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/racename.h>
|
||||
#include <attributes/raceprefix.h>
|
||||
#include <attributes/stealth.h>
|
||||
|
||||
#include <spells/buildingcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
#include <spells/unitcurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/alliance.h>
|
||||
#include <kernel/ally.h>
|
||||
|
@ -66,12 +75,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/terrainid.h> /* for volcanoes in emigration (needs a flag) */
|
||||
#include <kernel/unit.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/racename.h>
|
||||
#include <attributes/raceprefix.h>
|
||||
#include <attributes/stealth.h>
|
||||
#include <spells/buildingcurse.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/base36.h>
|
||||
|
@ -415,7 +418,7 @@ static void horses(region * r)
|
|||
maxhorses = MAX(0, maxhorses);
|
||||
horses = rhorses(r);
|
||||
if (horses > 0) {
|
||||
if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_godcursezone)) {
|
||||
rsethorses(r, (int)(horses * 0.9));
|
||||
}
|
||||
else if (maxhorses) {
|
||||
|
@ -568,7 +571,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
|||
a_removeall(&r->attribs, &at_germs);
|
||||
}
|
||||
|
||||
if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_godcursezone)) {
|
||||
rsettrees(r, 1, (int)(rtrees(r, 1) * 0.9));
|
||||
rsettrees(r, 2, (int)(rtrees(r, 2) * 0.9));
|
||||
return;
|
||||
|
@ -625,7 +628,7 @@ growing_trees(region * r, const int current_season, const int last_weeks_season)
|
|||
}
|
||||
else if (current_season == SEASON_SPRING) {
|
||||
|
||||
if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0))
|
||||
if (is_cursed(r->attribs, &ct_godcursezone))
|
||||
return;
|
||||
|
||||
/* in at_germs merken uns die Zahl der Samen und Sprößlinge, die
|
||||
|
@ -2846,13 +2849,12 @@ static void age_stonecircle(building *b) {
|
|||
if (get_astralplane()) {
|
||||
region *rt = r_standard_to_astral(r);
|
||||
if (mage && rt && !fval(rt->terrain, FORBIDDEN_REGION)) {
|
||||
const struct curse_type *ct_astralblock = ct_find("astralblock");
|
||||
curse *c = get_curse(rt->attribs, ct_astralblock);
|
||||
curse *c = get_curse(rt->attribs, &ct_astralblock);
|
||||
if (!c) {
|
||||
int sk = effskill(mage, SK_MAGIC, 0);
|
||||
float effect = 100;
|
||||
/* the mage reactivates the circle */
|
||||
c = create_curse(mage, &rt->attribs, ct_astralblock,
|
||||
c = create_curse(mage, &rt->attribs, &ct_astralblock,
|
||||
(float)MAX(1, sk), MAX(1, sk / 2), effect, 0);
|
||||
ADDMSG(&r->msgs,
|
||||
msg_message("astralshield_activate", "region unit", r, mage));
|
||||
|
@ -2909,11 +2911,13 @@ static void ageing(void)
|
|||
change_effect(u, oldpotiontype[P_BERSERK], -1 * MIN(u->number, i));
|
||||
}
|
||||
|
||||
if (is_cursed(u->attribs, C_OLDRACE, 0)) {
|
||||
curse *c = get_curse(u->attribs, ct_find("oldrace"));
|
||||
if (c->duration == 1 && !(c_flags(c) & CURSE_NOAGE)) {
|
||||
u_setrace(u, get_race(curse_geteffect_int(c)));
|
||||
u->irace = NULL;
|
||||
if (u->attribs) {
|
||||
curse * c = get_curse(u->attribs, &ct_oldrace);
|
||||
if (c && curse_active(c)) {
|
||||
if (c->duration == 1 && !(c_flags(c) & CURSE_NOAGE)) {
|
||||
u_setrace(u, get_race(curse_geteffect_int(c)));
|
||||
u->irace = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3221,15 +3225,14 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order
|
|||
void monthly_healing(void)
|
||||
{
|
||||
region *r;
|
||||
const curse_type *heal_ct = ct_find("healingzone");
|
||||
|
||||
for (r = regions; r; r = r->next) {
|
||||
unit *u;
|
||||
double healingcurse = 0;
|
||||
|
||||
if (r->attribs && heal_ct) {
|
||||
if (r->attribs) {
|
||||
/* bonus zurücksetzen */
|
||||
curse *c = get_curse(r->attribs, heal_ct);
|
||||
curse *c = get_curse(r->attribs, &ct_healing);
|
||||
if (c != NULL) {
|
||||
healingcurse = curse_geteffect(c);
|
||||
}
|
||||
|
@ -3775,7 +3778,7 @@ void process(void)
|
|||
}
|
||||
else if (u_race(u) == get_race(RC_INSECT)
|
||||
&& r_insectstalled(r)
|
||||
&& !is_cursed(u->attribs, C_KAELTESCHUTZ, 0)) {
|
||||
&& !is_cursed(u->attribs, &ct_insectfur)) {
|
||||
ord = NULL;
|
||||
}
|
||||
else if (LongHunger(u)) {
|
||||
|
|
57
src/magic.c
57
src/magic.c
|
@ -25,6 +25,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "study.h"
|
||||
#include "helpers.h"
|
||||
#include "laws.h"
|
||||
#include "spells.h"
|
||||
|
||||
#include <triggers/timeout.h>
|
||||
#include <triggers/shock.h>
|
||||
#include <triggers/killunit.h>
|
||||
#include <triggers/giveitem.h>
|
||||
#include <triggers/changerace.h>
|
||||
#include <triggers/clonedied.h>
|
||||
|
||||
#include <spells/regioncurse.h>
|
||||
#include <spells/buildingcurse.h>
|
||||
#include <spells/unitcurse.h>
|
||||
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/building.h>
|
||||
|
@ -46,13 +58,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/terrain.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
#include <triggers/timeout.h>
|
||||
#include <triggers/shock.h>
|
||||
#include <triggers/killunit.h>
|
||||
#include <triggers/giveitem.h>
|
||||
#include <triggers/changerace.h>
|
||||
#include <triggers/clonedied.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/gamedata.h>
|
||||
|
@ -695,7 +700,7 @@ int max_spellpoints(const region * r, const unit * u)
|
|||
if (rtype && i_get(u->items, rtype->itype) > 0) {
|
||||
msp += use_item_aura(r, u);
|
||||
}
|
||||
n = get_curseeffect(u->attribs, C_AURA, 0);
|
||||
n = get_curseeffect(u->attribs, &ct_auraboost);
|
||||
if (n > 0) {
|
||||
msp = (msp * n) / 100;
|
||||
}
|
||||
|
@ -1024,7 +1029,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order
|
|||
curse *c;
|
||||
|
||||
/* Antimagie in der Zielregion */
|
||||
c = get_curse(r->attribs, ct_find("antimagiczone"));
|
||||
c = get_curse(r->attribs, &ct_antimagiczone);
|
||||
if (curse_active(c)) {
|
||||
unit *mage = c->magician;
|
||||
force -= curse_geteffect(c);
|
||||
|
@ -1043,7 +1048,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order
|
|||
}
|
||||
|
||||
/* Patzerfluch-Effekt: */
|
||||
c = get_curse(r->attribs, ct_find("fumble"));
|
||||
c = get_curse(r->attribs, &ct_fumble);
|
||||
if (curse_active(c)) {
|
||||
unit *mage = c->magician;
|
||||
force -= curse_geteffect(c);
|
||||
|
@ -1100,21 +1105,22 @@ variant magic_resistance(unit * target)
|
|||
{
|
||||
attrib *a;
|
||||
curse *c;
|
||||
const curse_type * ct_goodresist = 0, *ct_badresist = 0;
|
||||
const resource_type *rtype;
|
||||
const race *rc = u_race(target);
|
||||
variant v, prob = rc_magres(rc);
|
||||
const plane *pl = rplane(target->region);
|
||||
bool good_resist = true;
|
||||
bool bad_resist = true;
|
||||
|
||||
if (rc == get_race(RC_HIRNTOETER) && !pl) {
|
||||
prob = frac_mul(prob, frac_make(1, 2));
|
||||
prob = frac_mul(prob, frac_make(1, 2));
|
||||
}
|
||||
assert(target->number > 0);
|
||||
/* Magier haben einen Resistenzbonus vom Magietalent * 5% */
|
||||
prob = frac_add(prob, frac_make(effskill(target, SK_MAGIC, 0), 20));
|
||||
|
||||
/* Auswirkungen von Zaubern auf der Einheit */
|
||||
c = get_curse(target->attribs, ct_find("magicresistance"));
|
||||
c = get_curse(target->attribs, &ct_magicresistance);
|
||||
if (c) {
|
||||
/* TODO: legacy. magicresistance-effect is an integer-percentage stored in a double */
|
||||
int effect = curse_geteffect_int(c) * get_cursedmen(target, c);
|
||||
|
@ -1132,27 +1138,23 @@ variant magic_resistance(unit * target)
|
|||
|
||||
/* Auswirkungen von Zaubern auf der Region */
|
||||
a = a_find(target->region->attribs, &at_curse);
|
||||
if (a) {
|
||||
ct_badresist = ct_find("badmagicresistancezone");
|
||||
ct_goodresist = ct_find("goodmagicresistancezone");
|
||||
}
|
||||
while (a && a->type == &at_curse) {
|
||||
curse *c = (curse *)a->data.v;
|
||||
unit *mage = c->magician;
|
||||
|
||||
if (mage != NULL) {
|
||||
if (ct_goodresist && c->type == ct_goodresist) {
|
||||
if (good_resist && c->type == &ct_goodmagicresistancezone) {
|
||||
if (alliedunit(mage, target->faction, HELP_GUARD)) {
|
||||
/* TODO: legacy. magicresistance-effect is an integer-percentage stored in a double */
|
||||
prob = frac_add(prob, frac_make(curse_geteffect_int(c), 100));
|
||||
ct_goodresist = 0; /* only one effect per region */
|
||||
good_resist = false; /* only one effect per region */
|
||||
}
|
||||
}
|
||||
else if (ct_badresist && c->type == ct_badresist) {
|
||||
else if (bad_resist && c->type == &ct_badmagicresistancezone) {
|
||||
if (!alliedunit(mage, target->faction, HELP_GUARD)) {
|
||||
/* TODO: legacy. magicresistance-effect is an integer-percentage stored in a double */
|
||||
prob = frac_sub(prob, frac_make(curse_geteffect_int(c), 100));
|
||||
ct_badresist = 0; /* only one effect per region */
|
||||
bad_resist = false; /* only one effect per region */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1247,8 +1249,7 @@ target_resists_magic(unit * magician, void *obj, int objtyp, int t_bonus)
|
|||
}
|
||||
|
||||
if (a) {
|
||||
const struct curse_type *ct_resist = ct_find(oldcursename(C_RESIST_MAGIC));
|
||||
curse * c = get_curse(a, ct_resist);
|
||||
curse * c = get_curse(a, &ct_magicrunes);
|
||||
int effect = curse_geteffect_int(c);
|
||||
prob = frac_add(prob, frac_make(effect, 100));
|
||||
}
|
||||
|
@ -1316,10 +1317,10 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade)
|
|||
if (mage->magietyp == M_DRAIG) {
|
||||
fumble_chance += CHAOSPATZERCHANCE;
|
||||
}
|
||||
if (is_cursed(u->attribs, C_MBOOST, 0)) {
|
||||
if (is_cursed(u->attribs, &ct_magicboost)) {
|
||||
fumble_chance += CHAOSPATZERCHANCE;
|
||||
}
|
||||
if (is_cursed(u->attribs, C_FUMBLE, 0)) {
|
||||
if (is_cursed(u->attribs, &ct_fumble)) {
|
||||
fumble_chance += CHAOSPATZERCHANCE;
|
||||
}
|
||||
|
||||
|
@ -1407,7 +1408,7 @@ static void do_fumble(castorder * co)
|
|||
/* temporary skill loss */
|
||||
duration = MAX(rng_int() % level / 2, 2);
|
||||
effect = level / -2.0;
|
||||
c = create_curse(u, &u->attribs, ct_find("skillmod"), level,
|
||||
c = create_curse(u, &u->attribs, &ct_skillmod, level,
|
||||
duration, effect, 1);
|
||||
c->data.i = SK_MAGIC;
|
||||
ADDMSG(&u->faction->msgs, msg_message("patzer2", "unit region", u, r));
|
||||
|
@ -1499,7 +1500,7 @@ void regenerate_aura(void)
|
|||
reg_aura *= btype->auraregen;
|
||||
|
||||
/* Bonus/Malus durch Zauber */
|
||||
mod = get_curseeffect(u->attribs, C_AURA, 0);
|
||||
mod = get_curseeffect(u->attribs, &ct_auraboost);
|
||||
if (mod > 0) {
|
||||
reg_aura = (reg_aura * mod) / 100.0;
|
||||
}
|
||||
|
@ -2790,7 +2791,7 @@ void magic(void)
|
|||
continue;
|
||||
|
||||
if (u_race(u) == rc_insect && r_insectstalled(r) &&
|
||||
!is_cursed(u->attribs, C_KAELTESCHUTZ, 0))
|
||||
!is_cursed(u->attribs, &ct_insectfur))
|
||||
continue;
|
||||
|
||||
if (fval(u, UFL_WERE | UFL_LONGACTION)) {
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#include <attributes/targetregion.h>
|
||||
#include <attributes/hate.h>
|
||||
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/build.h>
|
||||
#include <kernel/building.h>
|
||||
|
@ -904,13 +906,12 @@ void spawn_undead(void)
|
|||
{
|
||||
region *r;
|
||||
faction *monsters = get_monsters();
|
||||
const curse_type *ctype = ct_find("holyground");
|
||||
|
||||
for (r = regions; r; r = r->next) {
|
||||
int unburied = deathcount(r);
|
||||
|
||||
if (r->attribs && ctype) {
|
||||
if (curse_active(get_curse(r->attribs, ctype))) {
|
||||
if (r->attribs) {
|
||||
if (curse_active(get_curse(r->attribs, &ct_holyground))) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <platform.h>
|
||||
#include "morale.h"
|
||||
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
#include <kernel/config.h>
|
||||
#include <kernel/curse.h>
|
||||
#include <kernel/region.h>
|
||||
|
@ -53,7 +55,7 @@ void morale_update(region *r) {
|
|||
if (stability > MORALE_COOLDOWN && r->land->ownership->owner
|
||||
&& morale < MORALE_MAX) {
|
||||
double ch = popularity();
|
||||
if (is_cursed(r->attribs, C_GENEROUS, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_generous)) {
|
||||
ch *= 1.2; /* 20% improvement */
|
||||
}
|
||||
if (stability >= MORALE_AVERAGE * 2 || chance(ch)) {
|
||||
|
|
52
src/move.c
52
src/move.c
|
@ -31,6 +31,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "lighthouse.h"
|
||||
#include "piracy.h"
|
||||
|
||||
#include <spells/flyingship.h>
|
||||
#include <spells/unitcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
#include <spells/shipcurse.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/follow.h>
|
||||
#include <attributes/movement.h>
|
||||
#include <attributes/stealth.h>
|
||||
#include <attributes/targetregion.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/build.h>
|
||||
#include <kernel/building.h>
|
||||
|
@ -49,8 +61,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/terrainid.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
#include <spells/flyingship.h>
|
||||
|
||||
#include "teleport.h"
|
||||
#include "direction.h"
|
||||
#include "calendar.h"
|
||||
|
@ -71,12 +81,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <storage.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/follow.h>
|
||||
#include <attributes/movement.h>
|
||||
#include <attributes/stealth.h>
|
||||
#include <attributes/targetregion.h>
|
||||
|
||||
/* libc includes */
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
@ -670,7 +674,7 @@ static bool is_freezing(const unit * u)
|
|||
{
|
||||
if (u_race(u) != get_race(RC_INSECT))
|
||||
return false;
|
||||
if (is_cursed(u->attribs, C_KAELTESCHUTZ, 0))
|
||||
if (is_cursed(u->attribs, &ct_insectfur))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
@ -829,7 +833,7 @@ static void drifting_ships(region * r)
|
|||
}
|
||||
|
||||
/* 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, &ct_nodrift)) {
|
||||
shp = &sh->next;
|
||||
continue;
|
||||
}
|
||||
|
@ -1001,7 +1005,7 @@ bool move_blocked(const unit * u, const region * r, const region * r2)
|
|||
}
|
||||
|
||||
if (r->attribs) {
|
||||
const curse_type *fogtrap_ct = ct_find("fogtrap");
|
||||
const curse_type *fogtrap_ct = &ct_fogtrap;
|
||||
curse *c = get_curse(r->attribs, fogtrap_ct);
|
||||
return curse_active(c);
|
||||
}
|
||||
|
@ -1253,7 +1257,7 @@ static bool roadto(const region * r, direction_t dir)
|
|||
return false;
|
||||
}
|
||||
if (r->attribs || r2->attribs) {
|
||||
const curse_type *roads_ct = ct_find("magicstreet");
|
||||
const curse_type *roads_ct = &ct_magicstreet;
|
||||
if (roads_ct != NULL) {
|
||||
if (get_curse(r->attribs, roads_ct) != NULL)
|
||||
return true;
|
||||
|
@ -1415,13 +1419,10 @@ static int movement_speed(unit * u)
|
|||
}
|
||||
|
||||
if (u->attribs) {
|
||||
const curse_type *speed_ct = ct_find("speed");
|
||||
if (speed_ct) {
|
||||
curse *c = get_curse(u->attribs, speed_ct);
|
||||
if (c != NULL) {
|
||||
int men = get_cursedmen(u, c);
|
||||
dk *= 1.0 + (double)men / (double)u->number;
|
||||
}
|
||||
curse *c = get_curse(u->attribs, &ct_speed);
|
||||
if (c != NULL) {
|
||||
int men = get_cursedmen(u, c);
|
||||
dk *= 1.0 + (double)men / (double)u->number;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1580,7 +1581,7 @@ static const region_list *travel_route(unit * u,
|
|||
|
||||
/* illusionary units disappear in antimagic zones */
|
||||
if (fval(u_race(u), RCF_ILLUSIONARY)) {
|
||||
curse *c = get_curse(next->attribs, ct_find("antimagiczone"));
|
||||
curse *c = get_curse(next->attribs, &ct_antimagiczone);
|
||||
if (curse_active(c)) {
|
||||
curse_changevigour(&next->attribs, c, (float)-u->number);
|
||||
ADDMSG(&u->faction->msgs, msg_message("illusionantimagic", "unit", u));
|
||||
|
@ -1803,7 +1804,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
}
|
||||
if (rng_int() % 10000 < stormchance * sh->type->storm
|
||||
&& fval(current_point->terrain, SEA_REGION)) {
|
||||
if (!is_cursed(sh->attribs, C_SHIP_NODRIFT, 0)) {
|
||||
if (!is_cursed(sh->attribs, &ct_nodrift)) {
|
||||
region *rnext = NULL;
|
||||
bool storm = true;
|
||||
int d_offset = rng_int() % MAXDIRECTIONS;
|
||||
|
@ -1894,7 +1895,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
break;
|
||||
}
|
||||
|
||||
if (curse_active(get_curse(next_point->attribs, ct_find("maelstrom")))) {
|
||||
if (curse_active(get_curse(next_point->attribs, &ct_maelstrom))) {
|
||||
if (do_maelstrom(next_point, u) == NULL)
|
||||
break;
|
||||
}
|
||||
|
@ -1920,9 +1921,10 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
last_point = current_point;
|
||||
current_point = next_point;
|
||||
|
||||
if (!fval(current_point->terrain, SEA_REGION)
|
||||
&& !is_cursed(sh->attribs, C_SHIP_FLYING, 0))
|
||||
if (!fval(next_point->terrain, SEA_REGION)
|
||||
&& !is_cursed(sh->attribs, &ct_flyingship)) {
|
||||
break;
|
||||
}
|
||||
token = getstrtoken();
|
||||
error = movewhere(u, token, current_point, &next_point);
|
||||
if (error || next_point == NULL) {
|
||||
|
@ -1958,7 +1960,7 @@ static void sail(unit * u, order * ord, region_list ** routep, bool drifting)
|
|||
set_order(&u->thisorder, NULL);
|
||||
set_coast(sh, last_point, current_point);
|
||||
|
||||
if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) {
|
||||
if (is_cursed(sh->attribs, &ct_flyingship)) {
|
||||
ADDMSG(&f->msgs, msg_message("shipfly", "ship from to", sh,
|
||||
starting_point, current_point));
|
||||
}
|
||||
|
|
|
@ -27,6 +27,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "chaos.h"
|
||||
#include "study.h"
|
||||
|
||||
#include <spells/unitcurse.h>
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/racename.h>
|
||||
#include <attributes/reduceproduction.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/curse.h>
|
||||
|
@ -44,10 +51,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <kernel/terrainid.h>
|
||||
#include <kernel/unit.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/racename.h>
|
||||
#include <attributes/reduceproduction.h>
|
||||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/bsdstring.h>
|
||||
|
@ -649,7 +652,7 @@ static void godcurse(void)
|
|||
region *r;
|
||||
|
||||
for (r = regions; r; r = r->next) {
|
||||
if (is_cursed(r->attribs, C_CURSED_BY_THE_GODS, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_godcursezone)) {
|
||||
unit *u;
|
||||
for (u = r->units; u; u = u->next) {
|
||||
skill *sv = u->skills;
|
||||
|
@ -692,32 +695,28 @@ static void orc_growth(void)
|
|||
for (u = r->units; u; u = u->next) {
|
||||
if (u->attribs && !has_skill(u, SK_MAGIC) && !has_skill(u, SK_ALCHEMY)
|
||||
&& !fval(u, UFL_HERO)) {
|
||||
const curse_type *ct_orcish = ct_find("orcish");
|
||||
curse *c = get_curse(u->attribs, &ct_orcish);
|
||||
if (c) {
|
||||
int n;
|
||||
int increase = 0;
|
||||
int num = get_cursedmen(u, c);
|
||||
double prob = curse_geteffect(c);
|
||||
const item_type * it_chastity = it_find("ao_chastity");
|
||||
|
||||
if (ct_orcish) {
|
||||
curse *c = get_curse(u->attribs, ct_orcish);
|
||||
if (c) {
|
||||
int n;
|
||||
int increase = 0;
|
||||
int num = get_cursedmen(u, c);
|
||||
double prob = curse_geteffect(c);
|
||||
const item_type * it_chastity = it_find("ao_chastity");
|
||||
if (it_chastity) {
|
||||
num -= i_get(u->items, it_chastity);
|
||||
}
|
||||
for (n = num; n > 0; n--) {
|
||||
if (chance(prob)) {
|
||||
++increase;
|
||||
}
|
||||
}
|
||||
if (increase) {
|
||||
unit *u2 = create_unit(r, u->faction, increase, u_race(u), 0, NULL, u);
|
||||
transfermen(u2, u, u2->number);
|
||||
|
||||
if (it_chastity) {
|
||||
num -= i_get(u->items, it_chastity);
|
||||
}
|
||||
for (n = num; n > 0; n--) {
|
||||
if (chance(prob)) {
|
||||
++increase;
|
||||
}
|
||||
}
|
||||
if (increase) {
|
||||
unit *u2 = create_unit(r, u->faction, increase, u_race(u), 0, NULL, u);
|
||||
transfermen(u2, u, u2->number);
|
||||
|
||||
ADDMSG(&u->faction->msgs, msg_message("orcgrowth",
|
||||
"unit amount race", u, increase, u_race(u)));
|
||||
}
|
||||
ADDMSG(&u->faction->msgs, msg_message("orcgrowth",
|
||||
"unit amount race", u, increase, u_race(u)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,6 +29,9 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "monsters.h"
|
||||
#include "travelthru.h"
|
||||
|
||||
#include <spells/regioncurse.h>
|
||||
#include <spells/buildingcurse.h>
|
||||
|
||||
/* modules includes */
|
||||
#include <modules/score.h>
|
||||
|
||||
|
@ -1185,7 +1188,7 @@ void report_region(struct stream *out, const region * r, faction * f)
|
|||
paragraph(out, buf, 0, 0, 0);
|
||||
|
||||
if (r->seen.mode >= seen_unit && is_astral(r) &&
|
||||
!is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
||||
!is_cursed(r->attribs, &ct_astralblock)) {
|
||||
/* Sonderbehandlung Teleport-Ebene */
|
||||
region_list *rl = astralregions(r, inhabitable);
|
||||
region_list *rl2;
|
||||
|
@ -1390,7 +1393,6 @@ report_template(const char *filename, report_context * ctx, const char *bom)
|
|||
char buf[8192], *bufp;
|
||||
size_t size;
|
||||
int bytes;
|
||||
const curse_type *nocost_ct = ct_find("nocostbuilding");
|
||||
|
||||
if (F == NULL) {
|
||||
perror(filename);
|
||||
|
@ -1459,7 +1461,7 @@ report_template(const char *filename, report_context * ctx, const char *bom)
|
|||
WARN_STATIC_BUFFER();
|
||||
if (u->building && building_owner(u->building) == u) {
|
||||
building *b = u->building;
|
||||
if (!curse_active(get_curse(b->attribs, nocost_ct))) {
|
||||
if (!curse_active(get_curse(b->attribs, &ct_nocostbuilding))) {
|
||||
int cost = buildingmaintenance(b, rsilver);
|
||||
if (cost > 0) {
|
||||
bytes = (int)strlcpy(bufp, ",U", size);
|
||||
|
|
|
@ -26,6 +26,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "lighthouse.h"
|
||||
#include "donations.h"
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/attributes.h>
|
||||
#include <attributes/follow.h>
|
||||
#include <attributes/otherfaction.h>
|
||||
#include <attributes/racename.h>
|
||||
#include <attributes/stealth.h>
|
||||
|
||||
#include <spells/unitcurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/alliance.h>
|
||||
|
@ -69,13 +78,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
|
||||
/* attributes includes */
|
||||
#include <attributes/attributes.h>
|
||||
#include <attributes/follow.h>
|
||||
#include <attributes/otherfaction.h>
|
||||
#include <attributes/racename.h>
|
||||
#include <attributes/stealth.h>
|
||||
|
||||
#include "move.h"
|
||||
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
|
@ -306,12 +308,9 @@ report_items(const unit *u, item * result, int size, const unit * owner,
|
|||
assert(size);
|
||||
|
||||
if (u->attribs) {
|
||||
const curse_type *itemcloak_ct = ct_find("itemcloak");
|
||||
if (itemcloak_ct) {
|
||||
curse * cu = get_curse(u->attribs, itemcloak_ct);
|
||||
if (cu && curse_active(cu)) {
|
||||
return 0;
|
||||
}
|
||||
curse * cu = get_curse(u->attribs, &ct_itemcloak);
|
||||
if (cu && curse_active(cu)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
for (itm = items; itm; itm = itm->next) {
|
||||
|
|
170
src/spells.c
170
src/spells.c
|
@ -827,7 +827,7 @@ static int sp_goodwinds(castorder * co)
|
|||
|
||||
/* keine Probleme mit C_SHIP_SPEEDUP und C_SHIP_FLYING */
|
||||
/* NODRIFT bewirkt auch +1 Geschwindigkeit */
|
||||
create_curse(mage, &sh->attribs, ct_find("nodrift"), power, duration,
|
||||
create_curse(mage, &sh->attribs, &ct_nodrift, power, duration,
|
||||
zero_effect, 0);
|
||||
|
||||
/* melden, 1x pro Partei */
|
||||
|
@ -874,7 +874,7 @@ static int sp_magicstreet(castorder * co)
|
|||
}
|
||||
|
||||
/* wirkt schon in der Zauberrunde! */
|
||||
create_curse(mage, &r->attribs, ct_find("magicstreet"), co->force,
|
||||
create_curse(mage, &r->attribs, &ct_magicstreet, co->force,
|
||||
co->level + 1, zero_effect, 0);
|
||||
|
||||
/* melden, 1x pro Partei */
|
||||
|
@ -1024,7 +1024,7 @@ static int sp_maelstrom(castorder * co)
|
|||
/* Attribut auf Region.
|
||||
* Existiert schon ein curse, so wird dieser verstaerkt
|
||||
* (Max(Dauer), Max(Staerke))*/
|
||||
c = create_curse(mage, &r->attribs, ct_find("maelstrom"), co->force, duration, co->force, 0);
|
||||
c = create_curse(mage, &r->attribs, &ct_maelstrom, co->force, duration, co->force, 0);
|
||||
|
||||
/* melden, 1x pro Partei */
|
||||
if (c) {
|
||||
|
@ -1104,7 +1104,7 @@ static int sp_blessedharvest(castorder * co)
|
|||
* Existiert schon ein curse, so wird dieser verstaerkt
|
||||
* (Max(Dauer), Max(Staerke))*/
|
||||
|
||||
if (create_curse(mage, &r->attribs, ct_find("blessedharvest"), co->force,
|
||||
if (create_curse(mage, &r->attribs, &ct_blessedharvest, co->force,
|
||||
duration, 1.0, 0)) {
|
||||
const char * effect = co->sp->sname[0]=='b' ? "harvest_effect" : "raindance_effect";
|
||||
message *seen = msg_message(effect, "mage", mage);
|
||||
|
@ -1407,7 +1407,7 @@ static int sp_kaelteschutz(castorder * co)
|
|||
}
|
||||
|
||||
effect = 1;
|
||||
create_curse(mage, &u->attribs, ct_find("insectfur"), (float)cast_level,
|
||||
create_curse(mage, &u->attribs, &ct_insectfur, (float)cast_level,
|
||||
duration, effect, men);
|
||||
|
||||
force -= u->number;
|
||||
|
@ -1457,7 +1457,7 @@ static int sp_sparkle(castorder * co)
|
|||
|
||||
u = pa->param[0]->data.u;
|
||||
effect = (float)(rng_int() % 0xffffff);
|
||||
create_curse(mage, &u->attribs, ct_find("sparkle"), (float)cast_level,
|
||||
create_curse(mage, &u->attribs, &ct_sparkle, (float)cast_level,
|
||||
duration, effect, u->number);
|
||||
|
||||
ADDMSG(&mage->faction->msgs, msg_message("sparkle_effect", "mage target",
|
||||
|
@ -1661,7 +1661,7 @@ static int sp_great_drought(castorder * co)
|
|||
|
||||
/* Arbeitslohn = 1/4 */
|
||||
effect = 4.0; /* curses: higher is stronger */
|
||||
create_curse(mage, &r->attribs, ct_find("drought"), force, duration, effect,
|
||||
create_curse(mage, &r->attribs, &ct_drought, force, duration, effect,
|
||||
0);
|
||||
|
||||
/* terraforming */
|
||||
|
@ -1787,7 +1787,7 @@ static int sp_treewalkenter(castorder * co)
|
|||
}
|
||||
|
||||
rt = r_standard_to_astral(r);
|
||||
if (rt == NULL || is_cursed(rt->attribs, C_ASTRALBLOCK, 0)
|
||||
if (rt == NULL || is_cursed(rt->attribs, &ct_astralblock)
|
||||
|| fval(rt->terrain, FORBIDDEN_REGION)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_astralblock", ""));
|
||||
|
@ -1903,7 +1903,7 @@ static int sp_treewalkexit(castorder * co)
|
|||
"spellfail_astralonly", ""));
|
||||
return 0;
|
||||
}
|
||||
if (is_cursed(r->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_astralblock)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_astralblock", ""));
|
||||
return 0;
|
||||
|
@ -2038,7 +2038,7 @@ static int sp_holyground(castorder * co)
|
|||
report_spell(mage, r, msg);
|
||||
msg_release(msg);
|
||||
|
||||
ctype = ct_find("holyground");
|
||||
ctype = &ct_holyground;
|
||||
create_curse(mage, &r->attribs, ctype, power * power, 1, zero_effect, 0);
|
||||
|
||||
a_removeall(&r->attribs, &at_deathcount);
|
||||
|
@ -2085,7 +2085,7 @@ static int sp_homestone(castorder * co)
|
|||
/* Magieresistenz der Burg erhoeht sich um 50% */
|
||||
effect = 50.0F;
|
||||
c = create_curse(mage, &mage->building->attribs,
|
||||
ct_find("magicresistance"), force * force, 1, effect, 0);
|
||||
&ct_magicresistance, force * force, 1, effect, 0);
|
||||
c_setflag(c, CURSE_NOAGE);
|
||||
|
||||
/* melden, 1x pro Partei in der Burg */
|
||||
|
@ -2143,7 +2143,7 @@ static int sp_drought(castorder * co)
|
|||
* hoch (evtl dauert dann die Duerre laenger). Ansonsten volle
|
||||
* Auswirkungen.
|
||||
*/
|
||||
c = get_curse(r->attribs, ct_find("drought"));
|
||||
c = get_curse(r->attribs, &ct_drought);
|
||||
if (c) {
|
||||
c->vigour = MAX(c->vigour, power);
|
||||
c->duration = MAX(c->duration, (int)power);
|
||||
|
@ -2156,7 +2156,7 @@ static int sp_drought(castorder * co)
|
|||
rsettrees(r, 0, rtrees(r, 0) / 2);
|
||||
rsethorses(r, rhorses(r) / 2);
|
||||
|
||||
create_curse(mage, &r->attribs, ct_find("drought"), power, duration, effect,
|
||||
create_curse(mage, &r->attribs, &ct_drought, power, duration, effect,
|
||||
0);
|
||||
}
|
||||
return cast_level;
|
||||
|
@ -2266,19 +2266,19 @@ static int sp_stormwinds(castorder * co)
|
|||
sh = pa->param[n]->data.sh;
|
||||
|
||||
/* mit C_SHIP_NODRIFT haben wir kein Problem */
|
||||
if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) {
|
||||
if (is_cursed(sh->attribs, &ct_flyingship)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"error_spell_on_flying_ship", "ship", sh))
|
||||
continue;
|
||||
}
|
||||
if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) {
|
||||
if (is_cursed(sh->attribs, &ct_shipspeedup)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"error_spell_on_ship_already", "ship", sh))
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Duration = 1, nur diese Runde */
|
||||
create_curse(mage, &sh->attribs, ct_find("stormwind"), power, 1,
|
||||
create_curse(mage, &sh->attribs, &ct_stormwind, power, 1,
|
||||
zero_effect, 0);
|
||||
/* Da der Spruch nur diese Runde wirkt wird er nie im Report
|
||||
* erscheinen */
|
||||
|
@ -2340,7 +2340,7 @@ static int sp_earthquake(castorder * co)
|
|||
while (*blist) {
|
||||
building *burg = *blist;
|
||||
|
||||
if (burg->size != 0 && !is_cursed(burg->attribs, C_MAGICWALLS, 0)) {
|
||||
if (burg->size != 0 && !is_cursed(burg->attribs, &ct_magicwalls)) {
|
||||
/* Magieresistenz */
|
||||
if (!target_resists_magic(mage, burg, TYP_BUILDING, 0)) {
|
||||
kaputt = MIN(10 * cast_level, burg->size / 4);
|
||||
|
@ -2540,7 +2540,7 @@ static int sp_fumblecurse(castorder * co)
|
|||
duration = MAX(sx, rx) + 1;
|
||||
|
||||
effect = force / 2;
|
||||
c = create_curse(mage, &target->attribs, ct_find("fumble"),
|
||||
c = create_curse(mage, &target->attribs, &ct_fumble,
|
||||
force, duration, effect, 0);
|
||||
if (c == NULL) {
|
||||
report_failure(mage, co->order);
|
||||
|
@ -2563,7 +2563,7 @@ void patzer_fumblecurse(const castorder * co)
|
|||
curse *c;
|
||||
|
||||
effect = force / 2;
|
||||
c = create_curse(mage, &mage->attribs, ct_find("fumble"), force,
|
||||
c = create_curse(mage, &mage->attribs, &ct_fumble, force,
|
||||
duration, effect, 0);
|
||||
if (c != NULL) {
|
||||
ADDMSG(&mage->faction->msgs, msg_message("magic_fumble",
|
||||
|
@ -2800,7 +2800,7 @@ static int sp_unholypower(castorder * co)
|
|||
* korrekt abgefangen wird. Besser (aber nicht gerade einfach)
|
||||
* waere es, eine solche Konstruktion irgendwie zu kapseln. */
|
||||
if (fval(u, UFL_LOCKED) || fval(u, UFL_HUNGER)
|
||||
|| is_cursed(u->attribs, C_SLAVE, 0)) {
|
||||
|| is_cursed(u->attribs, &ct_slavery)) {
|
||||
cmistake(mage, co->order, 74, MSG_MAGIC);
|
||||
continue;
|
||||
}
|
||||
|
@ -3188,7 +3188,7 @@ static int sp_chaossuction(castorder * co)
|
|||
cmistake(mage, co->order, 216, MSG_MAGIC);
|
||||
return 0;
|
||||
}
|
||||
else if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) {
|
||||
else if (is_cursed(rt->attribs, &ct_astralblock)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_astralblock", ""));
|
||||
return 0;
|
||||
|
@ -3233,28 +3233,21 @@ static int sp_magicboost(castorder * co)
|
|||
double power = co->force;
|
||||
double effect;
|
||||
trigger *tsummon;
|
||||
const curse_type *ct_auraboost;
|
||||
const curse_type *ct_magicboost;
|
||||
|
||||
ct_auraboost = ct_find("auraboost");
|
||||
ct_magicboost = ct_find("magicboost");
|
||||
assert(ct_auraboost != NULL);
|
||||
assert(ct_magicboost != NULL);
|
||||
|
||||
/* fehler, wenn schon ein boost */
|
||||
if (is_cursed(mage->attribs, C_MBOOST, 0)) {
|
||||
if (is_cursed(mage->attribs, &ct_magicboost)) {
|
||||
report_failure(mage, co->order);
|
||||
return 0;
|
||||
}
|
||||
|
||||
effect = 6;
|
||||
create_curse(mage, &mage->attribs, ct_magicboost, power, 10, effect, 1);
|
||||
create_curse(mage, &mage->attribs, &ct_magicboost, power, 10, effect, 1);
|
||||
/* one aura boost with 200% aura now: */
|
||||
effect = 200;
|
||||
c = create_curse(mage, &mage->attribs, ct_auraboost, power, 4, effect, 1);
|
||||
c = create_curse(mage, &mage->attribs, &ct_auraboost, power, 4, effect, 1);
|
||||
|
||||
/* and one aura boost with 50% aura in 5 weeks: */
|
||||
tsummon = trigger_createcurse(mage, mage, ct_auraboost, power, 6, 50, 1);
|
||||
tsummon = trigger_createcurse(mage, mage, &ct_auraboost, power, 6, 50, 1);
|
||||
add_trigger(&mage->attribs, "timer", trigger_timeout(5, tsummon));
|
||||
|
||||
ADDMSG(&mage->faction->msgs, msg_message("magicboost_effect",
|
||||
|
@ -3649,7 +3642,7 @@ static int sp_charmingsong(castorder * co)
|
|||
add_trigger(&mage->faction->attribs, "destroy", trigger_killunit(target));
|
||||
}
|
||||
/* sperre ATTACKIERE, GIB PERSON und ueberspringe Migranten */
|
||||
create_curse(mage, &target->attribs, ct_find("slavery"), force, duration, zero_effect, 0);
|
||||
create_curse(mage, &target->attribs, &ct_slavery, force, duration, zero_effect, 0);
|
||||
|
||||
/* setze Partei um und loesche langen Befehl aus Sicherheitsgruenden */
|
||||
u_setfaction(target, mage->faction);
|
||||
|
@ -3687,7 +3680,7 @@ static int sp_song_resistmagic(castorder * co)
|
|||
double force = co->force;
|
||||
int duration = (int)force + 1;
|
||||
|
||||
create_curse(mage, &r->attribs, ct_find("goodmagicresistancezone"),
|
||||
create_curse(mage, &r->attribs, &ct_goodmagicresistancezone,
|
||||
force, duration, 15, 0);
|
||||
|
||||
/* Erfolg melden */
|
||||
|
@ -3716,7 +3709,7 @@ static int sp_song_susceptmagic(castorder * co)
|
|||
double force = co->force;
|
||||
int duration = (int)force + 1;
|
||||
|
||||
create_curse(mage, &r->attribs, ct_find("badmagicresistancezone"),
|
||||
create_curse(mage, &r->attribs, &ct_badmagicresistancezone,
|
||||
force, duration, 15, 0);
|
||||
|
||||
ADDMSG(&mage->faction->msgs, msg_message("regionmagic_effect",
|
||||
|
@ -3757,7 +3750,7 @@ static int sp_rallypeasantmob(castorder * co)
|
|||
}
|
||||
}
|
||||
|
||||
c = get_curse(r->attribs, ct_find(oldcursename(C_RIOT)));
|
||||
c = get_curse(r->attribs, &ct_riotzone);
|
||||
if (c != NULL) {
|
||||
remove_curse(&r->attribs, c);
|
||||
}
|
||||
|
@ -3824,7 +3817,7 @@ static int sp_raisepeasantmob(castorder * co)
|
|||
a->data.ca[1] = 15; /* 15% */
|
||||
a_add(&u->attribs, a);
|
||||
|
||||
create_curse(mage, &r->attribs, ct_find("riotzone"), (float)cast_level, duration,
|
||||
create_curse(mage, &r->attribs, &ct_riotzone, (float)cast_level, duration,
|
||||
(float)anteil, 0);
|
||||
|
||||
msg = msg_message("sp_raisepeasantmob_effect", "mage region", mage, r);
|
||||
|
@ -3923,7 +3916,7 @@ static int sp_song_of_peace(castorder * co)
|
|||
int duration = 2 + lovar(force / 2);
|
||||
message *msg[2] = { NULL, NULL };
|
||||
|
||||
create_curse(mage, &r->attribs, ct_find("peacezone"), force, duration,
|
||||
create_curse(mage, &r->attribs, &ct_peacezone, force, duration,
|
||||
zero_effect, 0);
|
||||
|
||||
for (u = r->units; u; u = u->next)
|
||||
|
@ -3973,14 +3966,14 @@ static int sp_generous(castorder * co)
|
|||
double effect;
|
||||
message *msg[2] = { NULL, NULL };
|
||||
|
||||
if (is_cursed(r->attribs, C_DEPRESSION, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_depression)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_generous", ""));
|
||||
return 0;
|
||||
}
|
||||
|
||||
effect = 2;
|
||||
create_curse(mage, &r->attribs, ct_find("generous"), force, duration, effect,
|
||||
create_curse(mage, &r->attribs, &ct_generous, force, duration, effect,
|
||||
0);
|
||||
|
||||
for (u = r->units; u; u = u->next)
|
||||
|
@ -4292,7 +4285,7 @@ static int sp_calm_monster(castorder * co)
|
|||
}
|
||||
|
||||
effect = mage->faction->subscription;
|
||||
c = create_curse(mage, &target->attribs, ct_find("calmmonster"), force,
|
||||
c = create_curse(mage, &target->attribs, &ct_calmmonster, force,
|
||||
(int)force, effect, 0);
|
||||
if (c == NULL) {
|
||||
report_failure(mage, co->order);
|
||||
|
@ -4440,7 +4433,7 @@ static int sp_depression(castorder * co)
|
|||
int duration = (int)force + 1;
|
||||
message *msg;
|
||||
|
||||
create_curse(mage, &r->attribs, ct_find("depression"), force, duration,
|
||||
create_curse(mage, &r->attribs, &ct_depression, force, duration,
|
||||
zero_effect, 0);
|
||||
|
||||
msg = msg_message("sp_depression_effect", "mage region", mage, r);
|
||||
|
@ -4666,7 +4659,29 @@ int sp_analysedream(castorder * co)
|
|||
return cast_level;
|
||||
}
|
||||
|
||||
static int sp_gbdreams(castorder * co, const char *curse_name, int effect);
|
||||
static int sp_gbdreams(castorder * co, int effect)
|
||||
{
|
||||
int duration;
|
||||
unit *mage = co->magician.u;
|
||||
int cast_level = co->level;
|
||||
double power = co->force;
|
||||
region *r = co_get_region(co);
|
||||
|
||||
/* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken,
|
||||
* also duration+2 */
|
||||
duration = (int)MAX(1, power / 2); /* Stufe 1 macht sonst mist */
|
||||
duration = 2 + rng_int() % duration;
|
||||
|
||||
/* Nichts machen als ein entsprechendes Attribut in die Region legen. */
|
||||
create_curse(mage, &r->attribs, &ct_gbdream, power, duration, effect, 0);
|
||||
|
||||
/* Erfolg melden */
|
||||
ADDMSG(&mage->faction->msgs, msg_message("regionmagic_effect",
|
||||
"unit region command", mage, mage->region, co->order));
|
||||
|
||||
return cast_level;
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
/* Name: Schlechte Traeume
|
||||
|
@ -4683,7 +4698,7 @@ static int sp_gbdreams(castorder * co, const char *curse_name, int effect);
|
|||
* */
|
||||
int sp_baddreams(castorder * co)
|
||||
{
|
||||
return sp_gbdreams(co, "gbdream", -1);
|
||||
return sp_gbdreams(co, -1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
@ -4700,30 +4715,7 @@ int sp_baddreams(castorder * co)
|
|||
*/
|
||||
int sp_gooddreams(castorder * co)
|
||||
{
|
||||
return sp_gbdreams(co, "gbdream", 1);
|
||||
}
|
||||
|
||||
static int sp_gbdreams(castorder * co, const char *curse_name, int effect)
|
||||
{
|
||||
int duration;
|
||||
unit *mage = co->magician.u;
|
||||
int cast_level = co->level;
|
||||
double power = co->force;
|
||||
region *r = co_get_region(co);
|
||||
|
||||
/* wirkt erst in der Folgerunde, soll mindestens eine Runde wirken,
|
||||
* also duration+2 */
|
||||
duration = (int)MAX(1, power / 2); /* Stufe 1 macht sonst mist */
|
||||
duration = 2 + rng_int() % duration;
|
||||
|
||||
/* Nichts machen als ein entsprechendes Attribut in die Region legen. */
|
||||
create_curse(mage, &r->attribs, ct_find(curse_name), power, duration, effect, 0);
|
||||
|
||||
/* Erfolg melden */
|
||||
ADDMSG(&mage->faction->msgs, msg_message("regionmagic_effect",
|
||||
"unit region command", mage, mage->region, co->order));
|
||||
|
||||
return cast_level;
|
||||
return sp_gbdreams(co, 1);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
@ -4854,7 +4846,7 @@ int sp_sweetdreams(castorder * co)
|
|||
|
||||
/* Nichts machen als ein entsprechendes Attribut an die Einheit legen. */
|
||||
effect = 0.05f;
|
||||
create_curse(mage, &u->attribs, ct_find("orcish"), power, duration, effect, men);
|
||||
create_curse(mage, &u->attribs, &ct_orcish, power, duration, effect, men);
|
||||
|
||||
msg = msg_message("sp_sweetdreams_effect", "mage unit region", mage, u, r);
|
||||
r_addmessage(r, mage->faction, msg);
|
||||
|
@ -4877,7 +4869,7 @@ int sp_disturbingdreams(castorder * co)
|
|||
double effect;
|
||||
|
||||
effect = 10;
|
||||
create_curse(mage, &r->attribs, ct_find("badlearn"), power, duration, effect, 0);
|
||||
create_curse(mage, &r->attribs, &ct_badlearn, power, duration, effect, 0);
|
||||
|
||||
ADDMSG(&mage->faction->msgs, msg_message("sp_disturbingdreams_effect",
|
||||
"mage region", mage, r));
|
||||
|
@ -4971,7 +4963,7 @@ int sp_itemcloak(castorder * co)
|
|||
/* Zieleinheit */
|
||||
target = pa->param[0]->data.u;
|
||||
|
||||
create_curse(mage, &target->attribs, ct_find("itemcloak"), power, duration,
|
||||
create_curse(mage, &target->attribs, &ct_itemcloak, power, duration,
|
||||
zero_effect, 0);
|
||||
ADDMSG(&mage->faction->msgs, msg_message("itemcloak", "mage target", mage,
|
||||
target));
|
||||
|
@ -5023,7 +5015,7 @@ int sp_resist_magic_bonus(castorder * co)
|
|||
m = MIN(u->number, victims);
|
||||
victims -= m;
|
||||
|
||||
create_curse(mage, &u->attribs, ct_find("magicresistance"),
|
||||
create_curse(mage, &u->attribs, &ct_magicresistance,
|
||||
power, duration, 20, m);
|
||||
|
||||
msg = msg_message("magicresistance_effect", "unit", u);
|
||||
|
@ -5074,8 +5066,8 @@ int sp_enterastral(castorder * co)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0)
|
||||
|| is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (is_cursed(rt->attribs, &ct_astralblock)
|
||||
|| is_cursed(ro->attribs, &ct_astralblock)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_astralblock", ""));
|
||||
return 0;
|
||||
|
@ -5201,8 +5193,8 @@ int sp_pullastral(castorder * co)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (is_cursed(rt->attribs, C_ASTRALBLOCK, 0)
|
||||
|| is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (is_cursed(rt->attribs, &ct_astralblock)
|
||||
|| is_cursed(ro->attribs, &ct_astralblock)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_astralblock", ""));
|
||||
return 0;
|
||||
|
@ -5345,8 +5337,8 @@ int sp_leaveastral(castorder * co)
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (ro == NULL || is_cursed(ro->attribs, C_ASTRALBLOCK, 0)
|
||||
|| is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (ro == NULL || is_cursed(ro->attribs, &ct_astralblock)
|
||||
|| is_cursed(rt->attribs, &ct_astralblock)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_astralblock", ""));
|
||||
return 0;
|
||||
|
@ -5485,7 +5477,7 @@ int sp_fetchastral(castorder * co)
|
|||
ro = u->region;
|
||||
}
|
||||
|
||||
if (is_cursed(ro->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (is_cursed(ro->attribs, &ct_astralblock)) {
|
||||
ADDMSG(&mage->faction->msgs, msg_feedback(mage, co->order,
|
||||
"spellfail_astralblock", ""));
|
||||
continue;
|
||||
|
@ -5598,7 +5590,7 @@ int sp_showastral(castorder * co)
|
|||
|
||||
for (rl2 = rl; rl2; rl2 = rl2->next) {
|
||||
region *r2 = rl2->data;
|
||||
if (!is_cursed(r2->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (!is_cursed(r2->attribs, &ct_astralblock)) {
|
||||
for (u = r2->units; u; u = u->next) {
|
||||
n++;
|
||||
}
|
||||
|
@ -5618,7 +5610,7 @@ int sp_showastral(castorder * co)
|
|||
"Nebel zu erkennen sind ", unitname(mage));
|
||||
|
||||
for (rl2 = rl; rl2; rl2 = rl2->next) {
|
||||
if (!is_cursed(rl2->data->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (!is_cursed(rl2->data->attribs, &ct_astralblock)) {
|
||||
for (u = rl2->data->units; u; u = u->next) {
|
||||
c++;
|
||||
scat(unitname(u));
|
||||
|
@ -5674,7 +5666,7 @@ int sp_viewreality(castorder * co)
|
|||
/* Irgendwann mal auf Curses u/o Attribut umstellen. */
|
||||
for (rl2 = rl; rl2; rl2 = rl2->next) {
|
||||
region *rt = rl2->data;
|
||||
if (!is_cursed(rt->attribs, C_ASTRALBLOCK, 0)) {
|
||||
if (!is_cursed(rt->attribs, &ct_astralblock)) {
|
||||
set_observer(rt, mage->faction, co->level / 2, 2);
|
||||
}
|
||||
}
|
||||
|
@ -5728,7 +5720,7 @@ int sp_disruptastral(castorder * co)
|
|||
int inhab_regions = 0;
|
||||
region_list *trl = NULL;
|
||||
|
||||
if (is_cursed(r2->attribs, C_ASTRALBLOCK, 0))
|
||||
if (is_cursed(r2->attribs, &ct_astralblock))
|
||||
continue;
|
||||
|
||||
if (r2->units != NULL) {
|
||||
|
@ -5777,7 +5769,7 @@ int sp_disruptastral(castorder * co)
|
|||
|
||||
/* Kontakt unterbinden */
|
||||
effect = 100;
|
||||
create_curse(mage, &rl2->data->attribs, ct_find("astralblock"),
|
||||
create_curse(mage, &rl2->data->attribs, &ct_astralblock,
|
||||
power, duration, effect, 0);
|
||||
}
|
||||
|
||||
|
@ -5813,7 +5805,7 @@ static int sp_eternizewall(castorder * co)
|
|||
return 0;
|
||||
|
||||
b = pa->param[0]->data.b;
|
||||
c = create_curse(mage, &b->attribs, ct_find("nocostbuilding"),
|
||||
c = create_curse(mage, &b->attribs, &ct_nocostbuilding,
|
||||
power * power, 1, zero_effect, 0);
|
||||
|
||||
if (c == NULL) { /* ist bereits verzaubert */
|
||||
|
@ -6091,7 +6083,7 @@ int sp_antimagiczone(castorder * co)
|
|||
/* Reduziert die Staerke jedes Spruchs um effect */
|
||||
effect = cast_level;
|
||||
|
||||
create_curse(mage, &r->attribs, ct_find("antimagiczone"), power, duration,
|
||||
create_curse(mage, &r->attribs, &ct_antimagiczone, power, duration,
|
||||
effect, 0);
|
||||
|
||||
/* Erfolg melden */
|
||||
|
@ -6151,7 +6143,7 @@ static int sp_magicrunes(castorder * co)
|
|||
b = pa->param[0]->data.b;
|
||||
|
||||
/* Magieresistenz der Burg erhoeht sich um 20% */
|
||||
create_curse(mage, &b->attribs, ct_find("magicrunes"), force,
|
||||
create_curse(mage, &b->attribs, &ct_magicrunes, force,
|
||||
duration, effect, 0);
|
||||
|
||||
/* Erfolg melden */
|
||||
|
@ -6165,7 +6157,7 @@ static int sp_magicrunes(castorder * co)
|
|||
ship *sh;
|
||||
sh = pa->param[0]->data.sh;
|
||||
/* Magieresistenz des Schiffs erhoeht sich um 20% */
|
||||
create_curse(mage, &sh->attribs, ct_find("magicrunes"), force,
|
||||
create_curse(mage, &sh->attribs, &ct_magicrunes, force,
|
||||
duration, effect, 0);
|
||||
|
||||
/* Erfolg melden */
|
||||
|
@ -6217,7 +6209,7 @@ int sp_speed2(castorder * co)
|
|||
|
||||
men = MIN(maxmen, u->number);
|
||||
effect = 2;
|
||||
create_curse(mage, &u->attribs, ct_find("speed"), force, dur, effect, men);
|
||||
create_curse(mage, &u->attribs, &ct_speed, force, dur, effect, men);
|
||||
maxmen -= men;
|
||||
used += men;
|
||||
}
|
||||
|
|
|
@ -22,13 +22,15 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct ship;
|
||||
struct curse;
|
||||
struct curse_type;
|
||||
struct region;
|
||||
struct unit;
|
||||
struct faction;
|
||||
struct region;
|
||||
struct message;
|
||||
|
||||
extern const struct curse_type ct_magicresistance;
|
||||
|
||||
void register_magicresistance(void);
|
||||
void register_spells(void);
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ static void test_good_dreams(CuTest *tc) {
|
|||
|
||||
level = sp_gooddreams(&co);
|
||||
CuAssertIntEquals(tc, 10, level);
|
||||
curse = get_curse(r->attribs, ct_find("gbdream"));
|
||||
curse = get_curse(r->attribs, &ct_gbdream);
|
||||
CuAssertTrue(tc, curse && curse->duration > 1);
|
||||
CuAssertTrue(tc, curse->effect == 1);
|
||||
|
||||
|
@ -101,7 +101,7 @@ static void test_bad_dreams(CuTest *tc) {
|
|||
|
||||
level = sp_baddreams(&co);
|
||||
CuAssertIntEquals(tc, 10, level);
|
||||
curse = get_curse(r->attribs, ct_find("gbdream"));
|
||||
curse = get_curse(r->attribs, &ct_gbdream);
|
||||
CuAssertTrue(tc, curse && curse->duration > 1);
|
||||
CuAssertTrue(tc, curse->effect == -1);
|
||||
|
||||
|
|
|
@ -70,7 +70,7 @@ static message *cinfo_magicrunes(const void *obj, objtype_t typ, const curse * c
|
|||
return msg;
|
||||
}
|
||||
|
||||
static struct curse_type ct_magicrunes = { "magicrunes",
|
||||
const struct curse_type ct_magicrunes = { "magicrunes",
|
||||
CURSETYP_NORM, 0, M_SUMEFFECT, cinfo_magicrunes
|
||||
};
|
||||
|
||||
|
@ -80,12 +80,12 @@ CURSETYP_NORM, CURSE_ONLYONE|CURSE_NOAGE, NO_MERGE, cinfo_building
|
|||
};
|
||||
|
||||
/* Feste Mauer - Präkampfzauber, wirkt nur 1 Runde */
|
||||
static struct curse_type ct_strongwall = { "strongwall",
|
||||
const struct curse_type ct_strongwall = { "strongwall",
|
||||
CURSETYP_NORM, 0, NO_MERGE, NULL
|
||||
};
|
||||
|
||||
/* Ewige Mauern-Zauber */
|
||||
static struct curse_type ct_nocostbuilding = { "nocostbuilding",
|
||||
const struct curse_type ct_nocostbuilding = { "nocostbuilding",
|
||||
CURSETYP_NORM, CURSE_NOAGE | CURSE_ONLYONE, NO_MERGE, cinfo_building
|
||||
};
|
||||
|
||||
|
|
|
@ -24,6 +24,9 @@ extern "C" {
|
|||
struct curse_type;
|
||||
|
||||
extern const struct curse_type ct_magicwalls;
|
||||
extern const struct curse_type ct_strongwall;
|
||||
extern const struct curse_type ct_magicrunes;
|
||||
extern const struct curse_type ct_nocostbuilding;
|
||||
|
||||
extern void register_buildingcurse(void);
|
||||
struct message *cinfo_building(const void *obj, objtype_t typ, const struct curse * c, int self);
|
||||
|
|
|
@ -12,7 +12,9 @@
|
|||
#include <platform.h>
|
||||
#include "combatspells.h"
|
||||
|
||||
/* kernel includes */
|
||||
#include <spells/buildingcurse.h>
|
||||
|
||||
/* kernel includes */
|
||||
#include <kernel/build.h>
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/curse.h>
|
||||
|
@ -880,7 +882,7 @@ int sp_strong_wall(struct castorder * co)
|
|||
burg = mage->building;
|
||||
|
||||
effect = power / 4;
|
||||
create_curse(mage, &burg->attribs, ct_find("strongwall"), power, 1, effect, 0);
|
||||
create_curse(mage, &burg->attribs, &ct_strongwall, power, 1, effect, 0);
|
||||
|
||||
msg =
|
||||
msg_message("sp_strongwalls_effect", "mage building", mage, mage->building);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include <platform.h>
|
||||
#include "flyingship.h"
|
||||
|
||||
#include <spells/shipcurse.h>
|
||||
|
||||
#include <kernel/build.h>
|
||||
#include <kernel/curse.h>
|
||||
#include <kernel/faction.h>
|
||||
|
@ -13,8 +15,6 @@
|
|||
|
||||
#include <magic.h>
|
||||
|
||||
#include <spells/shipcurse.h>
|
||||
|
||||
#include <storage.h>
|
||||
|
||||
/* libc includes */
|
||||
|
@ -66,11 +66,11 @@ int sp_flying_ship(castorder * co)
|
|||
|
||||
cno = levitate_ship(sh, mage, power, 1);
|
||||
if (cno == 0) {
|
||||
if (is_cursed(sh->attribs, C_SHIP_FLYING, 0)) {
|
||||
if (is_cursed(sh->attribs, &ct_flyingship)) {
|
||||
/* Auf dem Schiff befindet liegt bereits so ein Zauber. */
|
||||
cmistake(mage, co->order, 211, MSG_MAGIC);
|
||||
}
|
||||
else if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) {
|
||||
else if (is_cursed(sh->attribs, &ct_shipspeedup)) {
|
||||
/* Es ist zu gefaehrlich, ein sturmgepeitschtes Schiff fliegen zu lassen. */
|
||||
cmistake(mage, co->order, 210, MSG_MAGIC);
|
||||
}
|
||||
|
@ -127,7 +127,7 @@ static int flyingship_age(curse * c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct curse_type ct_flyingship = { "flyingship",
|
||||
const struct curse_type ct_flyingship = { "flyingship",
|
||||
CURSETYP_NORM, 0, NO_MERGE, cinfo_ship, NULL, flyingship_read,
|
||||
flyingship_write, NULL, flyingship_age
|
||||
};
|
||||
|
@ -153,7 +153,7 @@ static curse *shipcurse_flyingship(ship * sh, unit * mage, double power, int dur
|
|||
if (curse_active(get_curse(sh->attribs, &ct_flyingship))) {
|
||||
return NULL;
|
||||
}
|
||||
if (is_cursed(sh->attribs, C_SHIP_SPEEDUP, 0)) {
|
||||
if (is_cursed(sh->attribs, &ct_shipspeedup)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,9 @@ extern "C" {
|
|||
struct castorder;
|
||||
struct ship;
|
||||
struct unit;
|
||||
struct curse_type;
|
||||
|
||||
extern const struct curse_type ct_flyingship;
|
||||
|
||||
int sp_flying_ship(struct castorder * co);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ static struct message *cinfo_magicresistance(const void *obj, objtype_t typ, con
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct curse_type ct_magicresistance = {
|
||||
const struct curse_type ct_magicresistance = {
|
||||
"magicresistance", CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_magicresistance
|
||||
};
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ static void test_magicresistance_unit(CuTest *tc) {
|
|||
f2 = test_create_faction(NULL);
|
||||
u2 = test_create_unit(f2, r);
|
||||
|
||||
c = create_curse(u1, &u2->attribs, ct_find("magicresistance"), 10, 20, 30, u2->number);
|
||||
c = create_curse(u1, &u2->attribs, &ct_magicresistance, 10, 20, 30, u2->number);
|
||||
CuAssertPtrNotNull(tc, u2->attribs);
|
||||
CuAssertPtrEquals(tc, (void *)&at_curse, (void *)u2->attribs->type);
|
||||
msg = c->type->curseinfo(u2, TYP_UNIT, c, 1);
|
||||
|
@ -62,7 +62,7 @@ static void test_magicresistance_building(CuTest *tc) {
|
|||
|
||||
b1 = test_create_building(r, NULL);
|
||||
|
||||
c = create_curse(u1, &b1->attribs, ct_find("magicresistance"), 10, 20, 30, 0);
|
||||
c = create_curse(u1, &b1->attribs, &ct_magicresistance, 10, 20, 30, 0);
|
||||
CuAssertPtrNotNull(tc, b1->attribs);
|
||||
CuAssertPtrEquals(tc, (void *)&at_curse, (void *)b1->attribs->type);
|
||||
msg = c->type->curseinfo(b1, TYP_BUILDING, c, 1);
|
||||
|
|
|
@ -52,7 +52,7 @@ static message *cinfo_cursed_by_the_gods(const void *obj, objtype_t typ,
|
|||
return msg_message("curseinfo::godcurse", "id", c->no);
|
||||
}
|
||||
|
||||
static struct curse_type ct_godcursezone = {
|
||||
const struct curse_type ct_godcursezone = {
|
||||
"godcursezone",
|
||||
CURSETYP_NORM, CURSE_IMMUNE, (NO_MERGE),
|
||||
cinfo_cursed_by_the_gods,
|
||||
|
@ -78,7 +78,7 @@ static message *cinfo_dreamcurse(const void *obj, objtype_t typ, const curse * c
|
|||
}
|
||||
}
|
||||
|
||||
static struct curse_type ct_gbdream = {
|
||||
const struct curse_type ct_gbdream = {
|
||||
"gbdream",
|
||||
CURSETYP_NORM, 0, (NO_MERGE), cinfo_dreamcurse
|
||||
};
|
||||
|
@ -103,7 +103,7 @@ static message *cinfo_magicstreet(const void *obj, objtype_t typ, const curse *
|
|||
return msg_message("curseinfo::magicstreetwarn", "id", c->no);
|
||||
}
|
||||
|
||||
static struct curse_type ct_magicstreet = {
|
||||
const struct curse_type ct_magicstreet = {
|
||||
"magicstreet",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_magicstreet
|
||||
|
@ -154,7 +154,7 @@ const curse * c, int self)
|
|||
return self;
|
||||
}
|
||||
|
||||
static struct curse_type ct_antimagiczone = {
|
||||
const struct curse_type ct_antimagiczone = {
|
||||
"antimagiczone",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_antimagiczone, NULL, NULL, NULL, cansee_antimagiczone
|
||||
|
@ -185,19 +185,19 @@ static struct curse_type ct_farvision = {
|
|||
|
||||
/* --------------------------------------------------------------------- */
|
||||
|
||||
static struct curse_type ct_fogtrap = {
|
||||
const struct curse_type ct_fogtrap = {
|
||||
"fogtrap",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
static struct curse_type ct_maelstrom = {
|
||||
const struct curse_type ct_maelstrom = {
|
||||
"maelstrom",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
static struct curse_type ct_blessedharvest = {
|
||||
const struct curse_type ct_blessedharvest = {
|
||||
"blessedharvest",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_simple
|
||||
|
@ -219,41 +219,41 @@ int harvest_effect(const struct region *r) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct curse_type ct_drought = {
|
||||
const struct curse_type ct_drought = {
|
||||
"drought",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
static struct curse_type ct_badlearn = {
|
||||
const struct curse_type ct_badlearn = {
|
||||
"badlearn",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
/* Trübsal-Zauber */
|
||||
static struct curse_type ct_depression = {
|
||||
const struct curse_type ct_depression = {
|
||||
"depression",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
/* Astralblock, auf Astralregion */
|
||||
static struct curse_type ct_astralblock = {
|
||||
const struct curse_type ct_astralblock = {
|
||||
"astralblock",
|
||||
CURSETYP_NORM, 0, NO_MERGE,
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
/* Unterhaltungsanteil vermehren */
|
||||
static struct curse_type ct_generous = {
|
||||
const struct curse_type ct_generous = {
|
||||
"generous",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR | M_MAXEFFECT),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
/* verhindert Attackiere regional */
|
||||
static struct curse_type ct_peacezone = {
|
||||
const struct curse_type ct_peacezone = {
|
||||
"peacezone",
|
||||
CURSETYP_NORM, 0, NO_MERGE,
|
||||
cinfo_simple
|
||||
|
@ -261,7 +261,7 @@ static struct curse_type ct_peacezone = {
|
|||
|
||||
/* erniedigt Magieresistenz von nicht-aliierten Einheiten, wirkt nur 1x
|
||||
* pro Einheit */
|
||||
static struct curse_type ct_badmagicresistancezone = {
|
||||
const struct curse_type ct_badmagicresistancezone = {
|
||||
"badmagicresistancezone",
|
||||
CURSETYP_NORM, 0, NO_MERGE,
|
||||
cinfo_simple
|
||||
|
@ -269,25 +269,25 @@ static struct curse_type ct_badmagicresistancezone = {
|
|||
|
||||
/* erhöht Magieresistenz von aliierten Einheiten, wirkt nur 1x pro
|
||||
* Einheit */
|
||||
static struct curse_type ct_goodmagicresistancezone = {
|
||||
const struct curse_type ct_goodmagicresistancezone = {
|
||||
"goodmagicresistancezone",
|
||||
CURSETYP_NORM, 0, NO_MERGE,
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
static struct curse_type ct_riotzone = {
|
||||
const struct curse_type ct_riotzone = {
|
||||
"riotzone",
|
||||
CURSETYP_NORM, 0, (M_DURATION),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
static struct curse_type ct_holyground = {
|
||||
const struct curse_type ct_holyground = {
|
||||
"holyground",
|
||||
CURSETYP_NORM, CURSE_NOAGE, (M_VIGOUR_ADD),
|
||||
cinfo_simple
|
||||
};
|
||||
|
||||
static struct curse_type ct_healing = {
|
||||
const struct curse_type ct_healing = {
|
||||
"healingzone",
|
||||
CURSETYP_NORM, 0, (M_VIGOUR | M_DURATION),
|
||||
cinfo_simple
|
||||
|
|
|
@ -18,6 +18,26 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct region;
|
||||
struct curse_type;
|
||||
|
||||
extern const struct curse_type ct_peacezone;
|
||||
extern const struct curse_type ct_drought;
|
||||
extern const struct curse_type ct_blessedharvest;
|
||||
extern const struct curse_type ct_godcursezone;
|
||||
extern const struct curse_type ct_gbdream;
|
||||
extern const struct curse_type ct_healing;
|
||||
extern const struct curse_type ct_antimagiczone;
|
||||
extern const struct curse_type ct_depression;
|
||||
extern const struct curse_type ct_astralblock;
|
||||
extern const struct curse_type ct_badmagicresistancezone;
|
||||
extern const struct curse_type ct_goodmagicresistancezone;
|
||||
extern const struct curse_type ct_holyground;
|
||||
extern const struct curse_type ct_fogtrap;
|
||||
extern const struct curse_type ct_magicstreet;
|
||||
extern const struct curse_type ct_maelstrom;
|
||||
extern const struct curse_type ct_riotzone;
|
||||
extern const struct curse_type ct_generous;
|
||||
extern const struct curse_type ct_badlearn;
|
||||
|
||||
int harvest_effect(const struct region *r);
|
||||
void register_regioncurse(void);
|
||||
|
|
|
@ -72,11 +72,11 @@ static message *cinfo_shipnodrift(const void *obj, objtype_t typ, const curse *
|
|||
return msg_message("curseinfo::shipnodrift_0", "ship id", sh, c->no);
|
||||
}
|
||||
|
||||
static struct curse_type ct_stormwind = { "stormwind",
|
||||
CURSETYP_NORM, CURSE_NOAGE, NO_MERGE, cinfo_ship
|
||||
const struct curse_type ct_stormwind = { "stormwind",
|
||||
CURSETYP_NORM, 0, NO_MERGE, cinfo_ship
|
||||
};
|
||||
|
||||
static struct curse_type ct_nodrift = { "nodrift",
|
||||
const struct curse_type ct_nodrift = { "nodrift",
|
||||
CURSETYP_NORM, 0, (M_DURATION | M_VIGOUR), cinfo_shipnodrift
|
||||
};
|
||||
|
||||
|
|
|
@ -21,8 +21,11 @@ extern "C" {
|
|||
|
||||
struct message;
|
||||
struct curse;
|
||||
struct curse_type;
|
||||
|
||||
extern const struct curse_type ct_shipspeedup;
|
||||
extern const struct curse_type ct_stormwind;
|
||||
extern const struct curse_type ct_nodrift;
|
||||
|
||||
struct message *cinfo_ship(const void *obj, objtype_t typ,
|
||||
const struct curse *c, int self);
|
||||
|
|
|
@ -60,14 +60,14 @@ static message *cinfo_auraboost(const void *obj, objtype_t typ, const curse * c,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct curse_type ct_auraboost = {
|
||||
const struct curse_type ct_auraboost = {
|
||||
"auraboost",
|
||||
CURSETYP_NORM, CURSE_SPREADMODULO, (NO_MERGE),
|
||||
cinfo_auraboost
|
||||
};
|
||||
|
||||
/* Magic Boost - Gabe des Chaos */
|
||||
static struct curse_type ct_magicboost = {
|
||||
const struct curse_type ct_magicboost = {
|
||||
"magicboost",
|
||||
CURSETYP_UNIT, CURSE_SPREADMODULO | CURSE_IMMUNE, M_MEN, cinfo_simple
|
||||
};
|
||||
|
@ -92,7 +92,7 @@ static message *cinfo_slave(const void *obj, objtype_t typ, const curse * c,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct curse_type ct_slavery = { "slavery",
|
||||
const struct curse_type ct_slavery = { "slavery",
|
||||
CURSETYP_NORM, 0, NO_MERGE,
|
||||
cinfo_slave
|
||||
};
|
||||
|
@ -120,7 +120,7 @@ static message *cinfo_calm(const void *obj, objtype_t typ, const curse * c,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct curse_type ct_calmmonster = {
|
||||
const struct curse_type ct_calmmonster = {
|
||||
"calmmonster",
|
||||
CURSETYP_NORM, CURSE_SPREADNEVER | CURSE_ONLYONE, NO_MERGE,
|
||||
cinfo_calm
|
||||
|
@ -144,7 +144,7 @@ static message *cinfo_speed(const void *obj, objtype_t typ, const curse * c,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct curse_type ct_speed = {
|
||||
const struct curse_type ct_speed = {
|
||||
"speed",
|
||||
CURSETYP_UNIT, CURSE_SPREADNEVER, M_MEN,
|
||||
cinfo_speed
|
||||
|
@ -168,7 +168,7 @@ message *cinfo_unit(const void *obj, objtype_t typ, const curse * c, int self)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct curse_type ct_orcish = {
|
||||
const struct curse_type ct_orcish = {
|
||||
"orcish",
|
||||
CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN,
|
||||
cinfo_unit
|
||||
|
@ -192,7 +192,7 @@ static message *cinfo_kaelteschutz(const void *obj, objtype_t typ, const curse *
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct curse_type ct_insectfur = {
|
||||
const struct curse_type ct_insectfur = {
|
||||
"insectfur",
|
||||
CURSETYP_UNIT, CURSE_SPREADMODULO, (M_MEN | M_DURATION),
|
||||
cinfo_kaelteschutz
|
||||
|
@ -259,7 +259,7 @@ static message *cinfo_sparkle(const void *obj, objtype_t typ, const curse * c,
|
|||
}
|
||||
}
|
||||
|
||||
static struct curse_type ct_sparkle = { "sparkle",
|
||||
const struct curse_type ct_sparkle = { "sparkle",
|
||||
CURSETYP_UNIT, CURSE_SPREADMODULO, (M_MEN | M_DURATION), cinfo_sparkle
|
||||
};
|
||||
|
||||
|
@ -275,7 +275,7 @@ CURSETYP_UNIT, CURSE_SPREADMODULO, M_MEN, cinfo_simple
|
|||
/*
|
||||
* C_ALLSKILLS (Alp)
|
||||
*/
|
||||
static struct curse_type ct_worse = {
|
||||
const struct curse_type ct_worse = {
|
||||
"worse", CURSETYP_UNIT, CURSE_SPREADMODULO | CURSE_NOAGE, M_MEN, cinfo_unit
|
||||
};
|
||||
|
||||
|
@ -284,20 +284,20 @@ static struct curse_type ct_worse = {
|
|||
/*
|
||||
* C_ITEMCLOAK
|
||||
*/
|
||||
static struct curse_type ct_itemcloak = {
|
||||
const struct curse_type ct_itemcloak = {
|
||||
"itemcloak", CURSETYP_UNIT, CURSE_SPREADNEVER, M_DURATION, cinfo_unit
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static struct curse_type ct_fumble = {
|
||||
const struct curse_type ct_fumble = {
|
||||
"fumble", CURSETYP_NORM, CURSE_SPREADNEVER | CURSE_ONLYONE, NO_MERGE,
|
||||
cinfo_unit
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------- */
|
||||
|
||||
static struct curse_type ct_oldrace = {
|
||||
const struct curse_type ct_oldrace = {
|
||||
"oldrace", CURSETYP_NORM, CURSE_SPREADALWAYS, NO_MERGE, NULL
|
||||
};
|
||||
|
||||
|
@ -339,7 +339,7 @@ static message *cinfo_skillmod(const void *obj, objtype_t typ, const curse * c,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct curse_type ct_skillmod = {
|
||||
const struct curse_type ct_skillmod = {
|
||||
"skillmod", CURSETYP_NORM, CURSE_SPREADMODULO, M_MEN, cinfo_skillmod,
|
||||
NULL, read_skill, write_skill
|
||||
};
|
||||
|
|
|
@ -20,8 +20,24 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct curse;
|
||||
struct curse_type;
|
||||
struct message;
|
||||
extern struct message *cinfo_unit(const void *obj, objtype_t typ,
|
||||
|
||||
extern const struct curse_type ct_slavery;
|
||||
extern const struct curse_type ct_calmmonster;
|
||||
extern const struct curse_type ct_speed;
|
||||
extern const struct curse_type ct_worse;
|
||||
extern const struct curse_type ct_skillmod;
|
||||
extern const struct curse_type ct_oldrace;
|
||||
extern const struct curse_type ct_fumble;
|
||||
extern const struct curse_type ct_orcish;
|
||||
extern const struct curse_type ct_itemcloak;
|
||||
extern const struct curse_type ct_insectfur;
|
||||
extern const struct curse_type ct_sparkle;
|
||||
extern const struct curse_type ct_magicboost;
|
||||
extern const struct curse_type ct_auraboost;
|
||||
|
||||
struct message *cinfo_unit(const void *obj, objtype_t typ,
|
||||
const struct curse *c, int self);
|
||||
|
||||
extern void register_unitcurse(void);
|
||||
|
|
17
src/study.c
17
src/study.c
|
@ -28,6 +28,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "alchemy.h"
|
||||
#include "academy.h"
|
||||
|
||||
#include <spells/regioncurse.h>
|
||||
|
||||
#include <kernel/ally.h>
|
||||
#include <kernel/building.h>
|
||||
#include <kernel/curse.h>
|
||||
|
@ -52,6 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include <util/rand.h>
|
||||
#include <util/rng.h>
|
||||
#include <util/umlaut.h>
|
||||
|
||||
#include <selist.h>
|
||||
|
||||
/* libc includes */
|
||||
|
@ -285,13 +288,11 @@ int teach_cmd(unit * teacher, struct order *ord)
|
|||
skill_t sk_academy = NOSKILL;
|
||||
int teaching, i, j, count, academy = 0;
|
||||
|
||||
if (teacher->region->attribs) {
|
||||
const curse_type *gbdream_ct = ct_find("gbdream");
|
||||
if (gbdream_ct) {
|
||||
if (get_curse(teacher->region->attribs, gbdream_ct)) {
|
||||
ADDMSG(&teacher->faction->msgs, msg_feedback(teacher, ord, "gbdream_noteach", ""));
|
||||
return 0;
|
||||
}
|
||||
if (r->attribs) {
|
||||
if (get_curse(r->attribs, &ct_gbdream)) {
|
||||
ADDMSG(&teacher->faction->msgs,
|
||||
msg_feedback(teacher, ord, "gbdream_noteach", ""));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ((u_race(teacher)->flags & RCF_NOTEACH) || fval(teacher, UFL_WERE)) {
|
||||
|
@ -768,7 +769,7 @@ int study_cmd(unit * u, order * ord)
|
|||
teach->value += u->number * EXPERIENCEDAYS;
|
||||
}
|
||||
|
||||
if (is_cursed(r->attribs, C_BADLEARN, 0)) {
|
||||
if (is_cursed(r->attribs, &ct_badlearn)) {
|
||||
teach->value -= u->number * EXPERIENCEDAYS;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,10 +35,11 @@
|
|||
#define KEYVAL_VERSION 355 /* at_keys has values */
|
||||
#define NOLANDITEM_VERSION 356 /* land_region has no items */
|
||||
#define NORCSPELL_VERSION 357 /* data contains no RC_SPELL units */
|
||||
#define SORTKEYS_VERSION 358 /* at_keys is sorted */
|
||||
/* unfinished: */
|
||||
#define CRYPT_VERSION 400 /* passwords are encrypted */
|
||||
|
||||
#define RELEASE_VERSION NORCSPELL_VERSION /* current datafile */
|
||||
#define RELEASE_VERSION SORTKEYS_VERSION /* current datafile */
|
||||
#define MIN_VERSION INTPAK_VERSION /* minimal datafile we support */
|
||||
#define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */
|
||||
|
||||
|
|
Loading…
Reference in New Issue