Merge pull request #406 from ennorehling/critbit-params

config_get/config_set refactoring, kill cache logic
This commit is contained in:
Enno Rehling 2015-11-23 12:25:16 +01:00
commit dcfc1d1f15
65 changed files with 678 additions and 992 deletions

View file

@ -52,7 +52,6 @@
"world.era": 3,
"seed.population.min": 8,
"seed.population.max": 8,
"rules.migrants.max": 0,
"rules.reserve.twophase": true,
"rules.owners.force_leave": false,
"rules.monsters.attack_chance": 0.1,

View file

@ -51,7 +51,6 @@
"study.speedup": 2,
"study.from_use": 0.4,
"world.era": 3,
"rules.migrants.max": 0,
"rules.reserve.twophase": true,
"rules.owners.force_leave": false,
"rules.transfermen": false,
@ -64,7 +63,7 @@
"rules.combat.herospeed": 3,
"rules.combat.demon_vampire": 5,
"rules.combat.skill_bonus": 0,
"rules.combat.nat_armor": true,
"rules.combat.nat_armor": 1,
"rules.items.loot_divisor": 2,
"rules.items.give_divisor": 2,
"rules.move.owner_leave": true,
@ -78,7 +77,7 @@
"rules.blessed_harvest.flags": 1,
"rules.magic.elfpower": true,
"rules.magic.playerschools": "gwyrrd illaun draig cerddor",
"rules.build.other_buildings": 1,
"rules.build.other_buildings": true,
"rules.economy.taxation": 1,
"rules.food.flags": 2,
"rules.economy.roqf": 5,

@ -1 +1 @@
Subproject commit dfe57a077222c6b572da61a79dc0687f81c10055
Subproject commit 934c2dd94d41da19637a76a1a8b3dfeb7aa8524d

View file

@ -13,6 +13,7 @@
<race name="human" magres="0.000000" maxaura="1.000000" regaura="1.000000" recruitcost="75" maintenance="10" weight="1000" capacity="540" speed="1.000000" hp="20" damage="1d5" unarmedattack="-2" unarmeddefense="-2" playerrace="yes" walk="yes" giveperson="yes" giveunit="yes" getitem="yes" equipment="yes">
<ai splitsize="10000" moverandom="yes" learn="yes"/>
<function name="itemdrop" value="defaultdrops"/>
<param name="migrants.formula" value="1"/>
<skill name="trade" modifier="1"/>
<skill name="herbalism" modifier="-1"/>
<skill name="shipcraft" modifier="1"/>

View file

@ -73,7 +73,7 @@ TOLUA_BINDING(config.pkg bind_config.h)
TOLUA_BINDING(process.pkg bind_process.h)
TOLUA_BINDING(game.pkg bind_eressea.h config.h)
TOLUA_BINDING(eressea.pkg bind_eressea.h)
TOLUA_BINDING(settings.pkg bind_settings.h)
TOLUA_BINDING(settings.pkg kenel/config.h)
ENDIF()
set (ERESSEA_SRC
@ -144,7 +144,6 @@ set(SERVER_SRC
bind_monsters.c
bind_process.c
bind_region.c
bind_settings.c
bind_ship.c
bind_storage.c
bind_unit.c

View file

@ -93,14 +93,11 @@ void herbsearch(unit * u, int max)
static int begin_potion(unit * u, const potion_type * ptype, struct order *ord)
{
static int rule_multipotion = -1;
bool rule_multipotion;
assert(ptype != NULL);
if (rule_multipotion < 0) {
/* should we allow multiple different potions to be used the same turn? */
rule_multipotion =
get_param_int(global.parameters, "rules.magic.multipotion", 0);
}
/* should we allow multiple different potions to be used the same turn? */
rule_multipotion = config_get_int("rules.magic.multipotion", 0) != 0;
if (!rule_multipotion) {
const potion_type *use = ugetpotionuse(u);
if (use != NULL && use != ptype) {
@ -123,61 +120,83 @@ static void end_potion(unit * u, const potion_type * ptype, int amount)
"unit potion", u, ptype->itype->rtype));
}
static int potion_water_of_life(unit * u, region *r, int amount) {
int wood = 0;
int tree_type = config_get_int("rules.magic.wol_type", 1);
int tree_count = config_get_int("rules.magic.wol_effect", 10);
/* mallorn is required to make mallorn forests, wood for regular ones */
if (fval(r, RF_MALLORN)) {
wood = use_pooled(u, rt_find("mallorn"),
GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount);
}
else {
wood = use_pooled(u, rt_find("log"),
GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount);
}
if (r->land == 0)
wood = 0;
if (wood < tree_count * amount) {
int x = wood / tree_count;
if (wood % tree_count)
++x;
if (x < amount)
amount = x;
}
rsettrees(r, tree_type, rtrees(r, tree_type) + wood);
ADDMSG(&u->faction->msgs, msg_message("growtree_effect",
"mage amount", u, wood));
return amount;
}
static int potion_healing(unit * u, int amount) {
u->hp = _min(unit_max_hp(u) * u->number, u->hp + 400 * amount);
return amount;
}
static int potion_luck(unit *u, region *r, attrib_type *atype, int amount) {
attrib *a = (attrib *)a_find(r->attribs, atype);
if (!a) {
a = a_add(&r->attribs, a_new(atype));
}
a->data.i += amount;
return amount;
}
static int potion_truth(unit *u) {
fset(u, UFL_DISBELIEVES);
return 1;
}
static int potion_power(unit *u, int amount) {
int use = u->number / 10;
if (use < amount) {
if (u->number % 10 > 0) ++use;
amount = use;
}
/* Verfünffacht die HP von max. 10 Personen in der Einheit */
u->hp += _min(u->number, 10 * amount) * unit_max_hp(u) * 4;
return amount;
}
static int do_potion(unit * u, region *r, const potion_type * ptype, int amount)
{
if (ptype == oldpotiontype[P_LIFE]) {
int holz = 0;
static int tree_type = -1;
static int tree_count = -1;
if (tree_type < 0) {
tree_type = get_param_int(global.parameters, "rules.magic.wol_type", 1);
tree_count =
get_param_int(global.parameters, "rules.magic.wol_effect", 10);
}
/* mallorn is required to make mallorn forests, wood for regular ones */
if (fval(r, RF_MALLORN)) {
holz = use_pooled(u, rt_find("mallorn"),
GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount);
}
else {
holz = use_pooled(u, rt_find("log"),
GET_SLACK | GET_RESERVE | GET_POOLED_SLACK, tree_count * amount);
}
if (r->land == 0)
holz = 0;
if (holz < tree_count * amount) {
int x = holz / tree_count;
if (holz % tree_count)
++x;
if (x < amount)
amount = x;
}
rsettrees(r, tree_type, rtrees(r, tree_type) + holz);
ADDMSG(&u->faction->msgs, msg_message("growtree_effect",
"mage amount", u, holz));
return potion_water_of_life(u, r, amount);
}
else if (ptype == oldpotiontype[P_HEILWASSER]) {
u->hp = _min(unit_max_hp(u) * u->number, u->hp + 400 * amount);
return potion_healing(u, amount);
}
else if (ptype == oldpotiontype[P_PEOPLE]) {
attrib *a = (attrib *)a_find(r->attribs, &at_peasantluck);
if (!a)
a = a_add(&r->attribs, a_new(&at_peasantluck));
a->data.i += amount;
return potion_luck(u, r, &at_peasantluck, amount);
}
else if (ptype == oldpotiontype[P_HORSE]) {
attrib *a = (attrib *)a_find(r->attribs, &at_horseluck);
if (!a)
a = a_add(&r->attribs, a_new(&at_horseluck));
a->data.i += amount;
return potion_luck(u, r, &at_horseluck, amount);
}
else if (ptype == oldpotiontype[P_WAHRHEIT]) {
fset(u, UFL_DISBELIEVES);
amount = 1;
return potion_truth(u);
}
else if (ptype == oldpotiontype[P_MACHT]) {
/* Verfünffacht die HP von max. 10 Personen in der Einheit */
u->hp += _min(u->number, 10 * amount) * unit_max_hp(u) * 4;
return potion_power(u, amount);
}
else {
change_effect(u, ptype, 10 * amount);

View file

@ -17,18 +17,18 @@
static void test_rules(CuTest *tc) {
test_cleanup();
set_param(&global.parameters, "stealth.faction.other", NULL);
config_set("stealth.faction.other", NULL);
CuAssertIntEquals(tc, true, rule_stealth_other());
set_param(&global.parameters, "stealth.faction.other", "0");
config_set("stealth.faction.other", "0");
CuAssertIntEquals(tc, false, rule_stealth_other());
set_param(&global.parameters, "stealth.faction.other", "1");
config_set("stealth.faction.other", "1");
CuAssertIntEquals(tc, true, rule_stealth_other());
set_param(&global.parameters, "stealth.faction.anon", NULL);
config_set("stealth.faction.anon", NULL);
CuAssertIntEquals(tc, true, rule_stealth_anon());
set_param(&global.parameters, "stealth.faction.anon", "0");
config_set("stealth.faction.anon", "0");
CuAssertIntEquals(tc, false, rule_stealth_anon());
set_param(&global.parameters, "stealth.faction.anon", "1");
config_set("stealth.faction.anon", "1");
CuAssertIntEquals(tc, true, rule_stealth_anon());
test_cleanup();
}
@ -40,7 +40,7 @@ static void test_otherfaction(CuTest *tc) {
test_cleanup();
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
f = test_create_faction(0);
set_param(&global.parameters, "stealth.faction.other", "1");
config_set("stealth.faction.other", "1");
CuAssertIntEquals(tc, true, rule_stealth_other());
CuAssertPtrEquals(tc, u->faction, visible_faction(f, u));
a_add(&u->attribs, make_otherfaction(f));

View file

@ -114,11 +114,6 @@ static message *msg_separator;
const troop no_troop = { 0, 0 };
static int max_turns = 0;
static int damage_rules = 0;
static int loot_rules = 0;
static int skill_formula = 0;
#define FORMULA_ORIG 0
#define FORMULA_NEW 1
@ -131,31 +126,55 @@ static int skill_formula = 0;
#define DAMAGE_MELEE_BONUS (1<<1)
#define DAMAGE_MISSILE_BONUS (1<<2)
#define DAMAGE_SKILL_BONUS (1<<4)
static int max_turns;
static int damage_rules;
static int loot_rules;
static int skill_formula;
static int rule_cavalry_skill;
static int rule_population_damage;
static int rule_hero_speed;
static bool rule_anon_battle;
static int rule_goblin_bonus;
static int rule_tactics_formula;
static int rule_nat_armor;
static int rule_cavalry_mode;
static const curse_type *peace_ct, *slave_ct, *calm_ct;
/** initialize rules from configuration.
*/
static void static_rules(void)
static void init_rules(void)
{
loot_rules =
get_param_int(global.parameters, "rules.combat.loot",
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);
rule_hero_speed = config_get_int("rules.combat.herospeed", 10);
rule_population_damage = config_get_int("rules.combat.populationdamage", 20);
rule_anon_battle = config_get_int("rules.stealth.anon_battle", 1) != 0;
rule_cavalry_mode = config_get_int("rules.cavalry.mode", 1);
rule_cavalry_skill = config_get_int("rules.cavalry.skill", 2);
loot_rules = config_get_int("rules.combat.loot",
LOOT_MONSTERS | LOOT_OTHERS | LOOT_KEEPLOOT);
/* new formula to calculate to-hit-chance */
skill_formula =
get_param_int(global.parameters, "rules.combat.skill_formula",
skill_formula = config_get_int("rules.combat.skill_formula",
FORMULA_ORIG);
/* maximum number of combat turns */
max_turns =
get_param_int(global.parameters, "rules.combat.turns", COMBAT_TURNS);
max_turns = config_get_int("rules.combat.turns", COMBAT_TURNS);
/* damage calculation */
if (get_param_int(global.parameters, "rules.combat.critical", 1)) {
if (config_get_int("rules.combat.critical", 1)) {
damage_rules |= DAMAGE_CRITICAL;
}
if (get_param_int(global.parameters, "rules.combat.melee_bonus", 1)) {
if (config_get_int("rules.combat.melee_bonus", 1)) {
damage_rules |= DAMAGE_MELEE_BONUS;
}
if (get_param_int(global.parameters, "rules.combat.missile_bonus", 1)) {
if (config_get_int("rules.combat.missile_bonus", 1)) {
damage_rules |= DAMAGE_MISSILE_BONUS;
}
if (get_param_int(global.parameters, "rules.combat.skill_bonus", 1)) {
if (config_get_int("rules.combat.skill_bonus", 1)) {
damage_rules |= DAMAGE_SKILL_BONUS;
}
}
@ -664,24 +683,14 @@ weapon_skill(const weapon_type * wtype, const unit * u, bool attacking)
static int CavalrySkill(void)
{
static int skill = -1;
if (skill < 0) {
skill = get_param_int(global.parameters, "rules.cavalry.skill", 2);
}
return skill;
return rule_cavalry_skill;
}
#define BONUS_SKILL 1
#define BONUS_DAMAGE 2
static int CavalryBonus(const unit * u, troop enemy, int type)
{
static int mode = -1;
if (mode < 0) {
mode = get_param_int(global.parameters, "rules.cavalry.mode", 1);
}
if (mode == 0) {
if (rule_cavalry_mode == 0) {
/* old rule, Eressea 1.0 compat */
return (type == BONUS_SKILL) ? 2 : 0;
}
@ -1006,9 +1015,7 @@ const char *rel_dam(int dam, int hp)
static void vampirism(troop at, int damage)
{
static int vampire = -1;
if (vampire < 0)
vampire = get_param_int(global.parameters, "rules.combat.demon_vampire", 0);
int vampire = config_get_int("rules.combat.demon_vampire", 0);
if (vampire > 0) {
int gain = damage / vampire;
int chance = damage - vampire * gain;
@ -1024,30 +1031,20 @@ static void vampirism(troop at, int damage)
#define MAXRACES 128
static int natural_armor(unit * du)
static int armor_bonus(const race *rc) {
return get_param_int(rc->parameters, "armor.stamina", -1);
}
int natural_armor(unit * du)
{
static int cookie = -1;
static int bonus[MAXRACES];
const race *rc = u_race(du);
int index, an = rc->armor;
int bonus, an = rc->armor;
assert(rc);
if (cookie!=global.cookie) {
cookie = global.cookie;
memset(bonus, 0, sizeof(bonus));
}
assert(num_races < MAXRACES);
index = rc->index;
assert(index >= 0 && index < num_races);
if (bonus[index] == 0) {
bonus[index] =
get_param_int(rc->parameters, "armor.stamina", -1);
if (bonus[index] == 0)
bonus[index] = -1;
}
if (bonus[index] > 0) {
bonus = armor_bonus(rc);
if (bonus > 0) {
int sk = effskill(du, SK_STAMINA, 0);
sk /= bonus[index];
sk /= bonus;
an += sk;
}
return an;
@ -1089,7 +1086,6 @@ static int rc_specialdamage(const unit *au, const unit *du, const struct weapon_
}
int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype, double *magres) {
static int rule_armor = -1;
fighter *df = dt.fighter;
unit *du = df->unit;
int ar = 0, an, am;
@ -1117,10 +1113,7 @@ int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awty
/* Momentan nur Trollgürtel und Werwolf-Eigenschaft */
am = select_magicarmor(dt);
if (rule_armor < 0) {
rule_armor = get_param_int(global.parameters, "rules.combat.nat_armor", 0);
}
if (rule_armor == 0) {
if (rule_nat_armor == 0) {
/* natürliche Rüstung ist halbkumulativ */
if (ar > 0) {
ar += an / 2;
@ -1622,13 +1615,7 @@ static troop select_opponent(battle * b, troop at, int mindist, int maxdist)
}
if (b->turn == 0 && dt.fighter) {
int tactics_formula = -1;
if (tactics_formula < 0) {
tactics_formula =
get_param_int(global.parameters, "rules.tactics.formula", 0);
}
if (tactics_formula == 1) {
if (rule_tactics_formula == 1) {
int tactics = get_tactics(at.fighter->side, dt.fighter->side);
/* percentage chance to get this attack */
@ -1949,11 +1936,7 @@ int skilldiff(troop at, troop dt, int dist)
}
if (u_race(au) == get_race(RC_GOBLIN)) {
static int goblin_bonus = -1;
if (goblin_bonus < 0)
goblin_bonus =
get_param_int(global.parameters, "rules.combat.goblinbonus", 10);
if (af->side->size[SUM_ROW] >= df->side->size[SUM_ROW] * goblin_bonus) {
if (af->side->size[SUM_ROW] >= df->side->size[SUM_ROW] * rule_goblin_bonus) {
skdiff += 1;
}
}
@ -2150,10 +2133,6 @@ static int attacks_per_round(troop t)
static void make_heroes(battle * b)
{
side *s;
static int hero_speed = 0;
if (hero_speed == 0) {
hero_speed = get_param_int(global.parameters, "rules.combat.herospeed", 10);
}
for (s = b->sides; s != b->sides + b->nsides; ++s) {
fighter *fig;
for (fig = s->fighters; fig; fig = fig->next) {
@ -2164,7 +2143,7 @@ static void make_heroes(battle * b)
log_error("Hero %s is a %s.\n", unitname(u), u_race(u)->_name);
}
for (i = 0; i != u->number; ++i) {
fig->person[i].speed += (hero_speed - 1);
fig->person[i].speed += (rule_hero_speed - 1);
}
}
}
@ -2553,12 +2532,9 @@ troop select_ally(fighter * af, int minrow, int maxrow, int allytype)
static int loot_quota(const unit * src, const unit * dst,
const item_type * type, int n)
{
static double divisor = -1;
if (dst && src && src->faction != dst->faction) {
if (divisor < 0) {
divisor = get_param_flt(global.parameters, "rules.items.loot_divisor", 1);
assert(divisor == 0 || divisor >= 1);
}
double divisor = config_get_flt("rules.items.loot_divisor", 1);
assert(divisor == 0 || divisor >= 1);
if (divisor >= 1) {
double r = n / divisor;
int x = (int)r;
@ -2661,14 +2637,7 @@ static bool seematrix(const faction * f, const side * s)
static double PopulationDamage(void)
{
static double value = -1.0;
if (value < 0) {
int damage =
get_param_int(global.parameters, "rules.combat.populationdamage",
BATTLE_KILLS_PEASANTS);
value = damage / 100.0;
}
return value;
return rule_population_damage / 100.0;
}
static void battle_effects(battle * b, int dead_players)
@ -2918,7 +2887,7 @@ static void aftermath(battle * b)
int n = b->turn - 2;
if (n > 0) {
double dmg =
get_param_flt(global.parameters, "rules.ship.damage.battleround",
config_get_flt("rules.ship.damage.battleround",
0.05F);
damage_ship(sh, dmg * n);
freset(sh, SF_DAMAGED);
@ -3223,16 +3192,11 @@ side * get_side(battle * b, const struct unit * u)
side * find_side(battle * b, const faction * f, const group * g, unsigned int flags, const faction * stealthfaction)
{
side * s;
static int rule_anon_battle = -1;
if (rule_anon_battle < 0) {
rule_anon_battle = get_param_int(global.parameters, "rules.stealth.anon_battle", 1);
}
for (s = b->sides; s != b->sides + b->nsides; ++s) {
if (s->faction == f && s->group == g) {
unsigned int s1flags = flags | SIDE_HASGUARDS;
unsigned int s2flags = s->flags | SIDE_HASGUARDS;
if (rule_anon_battle!=0 && s->stealthfaction != stealthfaction) {
if (rule_anon_battle && s->stealthfaction != stealthfaction) {
continue;
}
if (s1flags == s2flags) {
@ -3621,7 +3585,6 @@ battle *make_battle(region * r)
unit *u;
bfaction *bf;
building * bld;
static int max_fac_no = 0; /* need this only once */
/* Alle Mann raus aus der Burg! */
for (bld = r->buildings; bld != NULL; bld = bld->next)
@ -3673,7 +3636,6 @@ battle *make_battle(region * r)
for (bf = b->factions; bf; bf = bf->next) {
faction *f = bf->faction;
max_fac_no = _max(max_fac_no, f->no);
freset(f, FFL_MARK);
}
return b;
@ -3719,17 +3681,13 @@ static void battle_free(battle * b) {
void free_battle(battle * b)
{
int max_fac_no = 0;
if (bdebug) {
fclose(bdebug);
}
while (b->factions) {
bfaction *bf = b->factions;
faction *f = bf->faction;
b->factions = bf->next;
max_fac_no = _max(max_fac_no, f->no);
free(bf);
}
@ -3976,15 +3934,6 @@ static bool start_battle(region * r, battle ** bp)
order *ord;
for (ord = u->orders; ord; ord = ord->next) {
static bool init = false;
static const curse_type *peace_ct, *slave_ct, *calm_ct;
if (!init) {
init = true;
peace_ct = ct_find("peacezone");
slave_ct = ct_find("slavery");
calm_ct = ct_find("calmmonster");
}
if (getkeyword(ord) == K_ATTACK) {
unit *u2;
fighter *c1, *c2;
@ -4308,12 +4257,6 @@ void do_battle(region * r)
battle *b = NULL;
bool fighting = false;
ship *sh;
static int init_rules = 0;
if (!init_rules) {
static_rules();
init_rules = 1;
}
if (msg_separator == NULL) {
msg_separator = msg_message("battle::section", "");
}
@ -4381,3 +4324,10 @@ void do_battle(region * r)
}
}
void do_battles(void) {
region *r;
init_rules();
for (r = regions; r; r = r->next) {
do_battle(r);
}
}

View file

@ -230,7 +230,7 @@ extern "C" {
fighter * get_fighter(battle * b, const struct unit * u);
/* END battle interface */
extern void do_battle(struct region *r);
extern void do_battles(void);
/* for combat spells and special attacks */
enum { SELECT_ADVANCE = 0x1, SELECT_DISTANCE = 0x2, SELECT_FIND = 0x4 };
@ -243,6 +243,7 @@ extern "C" {
int count_enemies(struct battle *b, const struct fighter *af,
int minrow, int maxrow, int select);
int natural_armor(struct unit * u);
int calculate_armor(troop dt, const struct weapon_type *dwtype, const struct weapon_type *awtype, double *magres);
bool terminate(troop dt, troop at, int type, const char *damage,
bool missile);

View file

@ -3,6 +3,7 @@
#include "battle.h"
#include "skill.h"
#include <kernel/config.h>
#include <kernel/building.h>
#include <kernel/faction.h>
#include <kernel/item.h>
@ -201,13 +202,30 @@ static void test_building_defence_bonus(CuTest * tc)
test_cleanup();
}
fighter *setup_fighter(battle **bp, unit *u) {
static fighter *setup_fighter(battle **bp, unit *u) {
battle *b;
*bp = b = make_battle(u->region);
return make_fighter(b, u, make_side(b, u->faction, 0, 0, 0), false);
}
static void test_natural_armor(CuTest * tc)
{
race *rc;
unit *u;
test_cleanup();
rc = test_create_race("human");
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
set_level(u, SK_STAMINA, 2);
CuAssertIntEquals(tc, 0, natural_armor(u));
set_param(&rc->parameters, "armor.stamina", "1");
CuAssertIntEquals(tc, 2, natural_armor(u));
set_param(&rc->parameters, "armor.stamina", "2");
CuAssertIntEquals(tc, 1, natural_armor(u));
test_cleanup();
}
static void test_calculate_armor(CuTest * tc)
{
troop dt;
@ -321,6 +339,7 @@ CuSuite *get_battle_suite(void)
SUITE_ADD_TEST(suite, test_building_bonus_respects_size);
SUITE_ADD_TEST(suite, test_building_defence_bonus);
SUITE_ADD_TEST(suite, test_calculate_armor);
SUITE_ADD_TEST(suite, test_natural_armor);
SUITE_ADD_TEST(suite, test_projectile_armor);
return suite;
}

View file

@ -70,10 +70,7 @@ void process_produce(void) {
}
void process_battle(void) {
struct region *r;
for (r = regions; r; r = r->next) {
do_battle(r);
}
do_battles();
}
void process_siege(void) {
@ -223,7 +220,7 @@ void process_explain(void) {
}
void process_reserve(void) {
int rule = get_param_int(global.parameters, "rules.reserve.twophase", 0);
int rule = config_get_int("rules.reserve.twophase", 0);
if (rule) {
process_cmd(K_RESERVE, reserve_self, 0);
}

View file

@ -1,14 +0,0 @@
#include "bind_settings.h"
#include <platform.h>
#include <kernel/config.h>
const char * settings_get(const char *key)
{
return get_param(global.parameters, key);
}
void settings_set(const char *key, const char *value)
{
set_param(&global.parameters, key, value);
}

View file

@ -1,13 +0,0 @@
#ifndef BIND_ERESSEA_SETTINGS_H
#define BIND_ERESSEA_SETTINGS_H
#ifdef __cplusplus
extern "C" {
#endif
const char * settings_get(const char *key);
void settings_set(const char *key, const char *value);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1006,7 +1006,7 @@ static void parse_inifile(lua_State * L, dictionary * d, const char *section)
lua_pushstring(L, "reportpath");
lua_pushstring(L, reportpath());
lua_rawset(L, -3);
arg = get_param(global.parameters, "config.rules");
arg = config_get("config.rules");
if (arg) {
lua_pushstring(L, "rules");
lua_pushstring(L, arg);

View file

@ -193,7 +193,7 @@ static void chaos(region * r)
while (sh) {
ship *nsh = sh->next;
double dmg =
get_param_flt(global.parameters, "rules.ship.damage.atlantis",
config_get_flt("rules.ship.damage.atlantis",
0.50);
damage_ship(sh, dmg);
if (sh->damage >= sh->size * DAMAGE_SCALE) {

View file

@ -1505,7 +1505,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
FILE *F = fopen(filename, "wt");
if (era < 0) {
era = get_param_int(global.parameters, "world.era", 1);
era = config_get_int("world.era", 1);
}
if (F == NULL) {
perror(filename);

View file

@ -104,7 +104,7 @@ static void recruit_init(void)
{
if (rules_recruit < 0) {
rules_recruit = 0;
if (get_param_int(global.parameters, "recruit.allow_merge", 1)) {
if (config_get_int("recruit.allow_merge", 1)) {
rules_recruit |= RECRUIT_MERGE;
}
}
@ -731,7 +731,7 @@ static bool maintain(building * b, bool first)
return false;
}
/* If the owner is the region owner, check if dontpay flag is set for the building where he is in */
if (check_param(global.parameters, "rules.region_owner_pay_building", b->type->_name)) {
if (config_token("rules.region_owner_pay_building", b->type->_name)) {
if (fval(u->building, BLD_DONTPAY)) {
return false;
}
@ -2360,16 +2360,12 @@ static void breedtrees(unit * u, int raw)
{
int n, i, skill, planted = 0;
const resource_type *rtype;
static int gamecookie = -1;
static int current_season;
int current_season;
region *r = u->region;
if (gamecookie != global.cookie) {
gamedate date;
get_gamedate(turn, &date);
current_season = date.season;
gamecookie = global.cookie;
}
gamedate date;
get_gamedate(turn, &date);
current_season = date.season;
/* Bäume züchten geht nur im Frühling */
if (current_season != SEASON_SPRING) {
@ -2749,11 +2745,11 @@ void entertain_cmd(unit * u, struct order *ord)
kwd = init_order(ord);
assert(kwd == K_ENTERTAIN);
if (!entertainbase) {
const char *str = get_param(global.parameters, "entertain.base");
const char *str = config_get("entertain.base");
entertainbase = str ? atoi(str) : 0;
}
if (!entertainperlevel) {
const char *str = get_param(global.parameters, "entertain.perlevel");
const char *str = config_get("entertain.perlevel");
entertainperlevel = str ? atoi(str) : 0;
}
if (fval(u, UFL_WERE)) {
@ -3024,7 +3020,7 @@ void loot_cmd(unit * u, struct order *ord, request ** lootorders)
kwd = init_order(ord);
assert(kwd == K_LOOT);
if (get_param_int(global.parameters, "rules.enable_loot", 0) == 0 && !is_monsters(u->faction)) {
if (config_get_int("rules.enable_loot", 0) == 0 && !is_monsters(u->faction)) {
return;
}
@ -3138,12 +3134,20 @@ static void peasant_taxes(region * r)
}
}
static bool rule_auto_taxation(void)
{
return config_get_int("rules.economy.taxation", 0) != 0;
}
static bool rule_autowork(void) {
return config_get_int("work.auto", 0) != 0;
}
void produce(struct region *r)
{
request workers[MAX_WORKERS];
request *taxorders, *lootorders, *sellorders, *stealorders, *buyorders;
unit *u;
static int rule_autowork = -1;
bool limited = true;
request *nextworker = workers;
assert(r);
@ -3158,10 +3162,6 @@ void produce(struct region *r)
*
* lehren vor lernen. */
if (rule_autowork < 0) {
rule_autowork = get_param_int(global.parameters, "work.auto", 0);
}
assert(rmoney(r) >= 0);
assert(rpeasants(r) >= 0);
@ -3235,7 +3235,7 @@ void produce(struct region *r)
break;
case K_WORK:
if (!rule_autowork && do_work(u, u->thisorder, nextworker) == 0) {
if (!rule_autowork() && do_work(u, u->thisorder, nextworker) == 0) {
assert(nextworker - workers < MAX_WORKERS);
++nextworker;
}
@ -3280,7 +3280,7 @@ void produce(struct region *r)
* auszugeben bereit sind. */
if (entertaining)
expandentertainment(r);
if (!rule_autowork) {
if (!rule_autowork()) {
expandwork(r, workers, nextworker, maxworkingpeasants(r));
}
if (taxorders)

View file

@ -52,12 +52,12 @@
#define RESERVE_GIVE /* reserve anything that's given from one unit to another? */
static int max_transfers(void) {
return get_param_int(global.parameters, "rules.give.max_men", 5);
return config_get_int("rules.give.max_men", 5);
}
static int GiveRestriction(void)
{
return get_param_int(global.parameters, "GiveRestriction", 0);
return config_get_int("GiveRestriction", 0);
}
static void feedback_give_not_allowed(unit * u, order * ord)
@ -132,7 +132,7 @@ int give_quota(const unit * src, const unit * dst, const item_type * type,
return n;
}
if (dst && src && src->faction != dst->faction) {
divisor = get_param_flt(global.parameters, "rules.items.give_divisor", 1);
divisor = config_get_flt("rules.items.give_divisor", 1);
assert(divisor == 0 || divisor >= 1);
if (divisor >= 1) {
/* predictable > correct: */
@ -233,6 +233,12 @@ static bool can_give_men(const unit *u, order *ord, message **msg) {
return false;
}
static bool rule_transfermen(void)
{
int rule = config_get_int("rules.transfermen", 1);
return rule != 0;
}
message * give_men(int n, unit * u, unit * u2, struct order *ord)
{
ship *sh;

View file

@ -75,11 +75,11 @@ static void test_give_unit(CuTest * tc) {
env.f2 = test_create_faction(0);
setup_give(&env);
env.r->terrain = test_create_terrain("ocean", SEA_REGION);
set_param(&global.parameters, "rules.give.max_men", "0");
config_set("rules.give.max_men", "0");
give_unit(env.src, env.dst, NULL);
CuAssertPtrEquals(tc, env.f1, env.src->faction);
CuAssertIntEquals(tc, 0, env.f2->newbies);
set_param(&global.parameters, "rules.give.max_men", "-1");
config_set("rules.give.max_men", "-1");
give_unit(env.src, env.dst, NULL);
CuAssertPtrEquals(tc, env.f2, env.src->faction);
CuAssertIntEquals(tc, 1, env.f2->newbies);
@ -117,7 +117,7 @@ static void test_give_men_limit(CuTest * tc) {
env.f2 = test_create_faction(0);
env.f1 = test_create_faction(0);
setup_give(&env);
set_param(&global.parameters, "rules.give.max_men", "1");
config_set("rules.give.max_men", "1");
/* below the limit, give men, increase newbies counter */
usetcontact(env.dst, env.src);
@ -308,7 +308,7 @@ static void test_give_okay(CuTest * tc) {
env.f2 = env.f1 = test_create_faction(0);
setup_give(&env);
set_param(&global.parameters, "rules.give.flags", "0");
config_set("rules.give.flags", "0");
CuAssertPtrEquals(tc, 0, check_give(env.src, env.dst, 0));
test_cleanup();
}
@ -322,7 +322,7 @@ static void test_give_denied_by_rules(CuTest * tc) {
env.f2 = test_create_faction(0);
setup_give(&env);
set_param(&global.parameters, "rules.give.flags", "0");
config_set("rules.give.flags", "0");
CuAssertPtrNotNull(tc, msg = check_give(env.src, env.dst, 0));
msg_release(msg);
test_cleanup();

View file

@ -853,8 +853,8 @@ static void handlekey(state * st, int c)
new_players = read_newfactions(sbuffer);
}
cnormalize(&st->cursor, &nx, &ny);
minpop = get_param_int(global.parameters, "seed.population.min", 8);
maxpop = get_param_int(global.parameters, "seed.population.max", minpop);
minpop = config_get_int("seed.population.min", 8);
maxpop = config_get_int("seed.population.max", minpop);
if (maxpop > minpop) {
n = rng_int() % (maxpop - minpop) + minpop;
}

View file

@ -320,33 +320,28 @@ static int lua_getresource(unit * u, const struct resource_type *rtype)
static bool lua_canuse_item(const unit * u, const struct item_type *itype)
{
static int function_exists = 1;
bool result = true;
lua_State *L = (lua_State *)global.vm_state;
const char *fname = "item_canuse";
if (function_exists) {
lua_State *L = (lua_State *)global.vm_state;
const char *fname = "item_canuse";
lua_getglobal(L, fname);
if (lua_isfunction(L, -1)) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
tolua_pushstring(L, itype->rtype->_name);
lua_getglobal(L, fname);
if (lua_isfunction(L, -1)) {
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
tolua_pushstring(L, itype->rtype->_name);
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("get(%s) calling '%s': %s.\n", unitname(u), fname, error);
lua_pop(L, 1);
}
else {
result = lua_toboolean(L, -1);
lua_pop(L, 1);
}
}
else {
function_exists = 0;
log_error("get(%s) calling '%s': not a function.\n", unitname(u), fname);
if (lua_pcall(L, 2, 1, 0) != 0) {
const char *error = lua_tostring(L, -1);
log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error);
lua_pop(L, 1);
}
else {
result = lua_toboolean(L, -1);
lua_pop(L, 1);
}
}
else {
log_error("use(%s) calling '%s': not a function.\n", unitname(u), fname);
lua_pop(L, 1);
}
return result;
}

View file

@ -141,13 +141,11 @@ int *casualties)
d += terminate(dt, *at, AT_STANDARD, wp->type->damage[0], true);
#ifdef CATAPULT_STRUCTURAL_DAMAGE
if (dt.fighter->unit->building && rng_int() % 100 < 5) {
float dmg =
get_param_flt(global.parameters, "rules.building.damage.catapult", 1);
double dmg = config_get_flt("rules.building.damage.catapult", 1);
damage_building(b, dt.fighter->unit->building, dmg);
}
else if (dt.fighter->unit->ship && rng_int() % 100 < 5) {
float dmg =
get_param_flt(global.parameters, "rules.ship.damage.catapult", 0.01);
double dmg = config_get_flt("rules.ship.damage.catapult", 0.01);
damage_ship(dt.fighter->unit->ship, dmg)
}
#endif

View file

@ -25,7 +25,7 @@ static void coor_from_tiled(int *x, int *y) {
static int report_json(const char *filename, report_context * ctx, const char *charset)
{
if (get_param_int(global.parameters, "jsreport.enabled", 0) != 0) {
if (config_get_int("jsreport.enabled", 0) != 0) {
FILE * F = fopen(filename, "w");
if (F) {
int x, y, minx = INT_MAX, maxx = INT_MIN, miny = INT_MAX, maxy = INT_MIN;

View file

@ -419,7 +419,7 @@ int roqf_factor(void)
{
int value = -1;
if (value < 0) {
value = get_param_int(global.parameters, "rules.economy.roqf", 10);
value = config_get_int("rules.economy.roqf", 10);
}
return value;
}
@ -685,7 +685,6 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
const char *btname;
order *new_order = NULL;
const struct locale *lang = u->faction->locale;
static int rule_other = -1;
assert(u->number);
assert(btype->construction);
@ -749,10 +748,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
n = 1;
}
if (b) {
if (rule_other < 0) {
rule_other =
get_param_int(global.parameters, "rules.build.other_buildings", 1);
}
bool rule_other = config_get_int("rules.build.other_buildings", 1) != 0;
if (!rule_other) {
unit *owner = building_owner(b);
if (!owner || owner->faction != u->faction) {

View file

@ -531,7 +531,7 @@ int bt_effsize(const building_type * btype, const building * b, int bsize)
const construction *cons = btype->construction;
/* TECH DEBT: simplest thing that works for E3 dwarf/halfling faction rules */
if (b && get_param_int(global.parameters, "rules.dwarf_castles", 0)
if (b && config_get_int("rules.dwarf_castles", 0)
&& strcmp(btype->_name, "castle") == 0) {
unit *u = building_owner(b);
if (u && u->faction->race == get_race(RC_HALFLING)) {
@ -591,7 +591,7 @@ static unit *building_owner_ex(const building * bld, const struct faction * last
}
}
}
if (!heir && check_param(global.parameters, "rules.region_owner_pay_building", bld->type->_name)) {
if (!heir && config_token("rules.region_owner_pay_building", bld->type->_name)) {
if (rule_region_owners()) {
u = building_owner(largestbuilding(bld->region, &cmp_taxes, false));
}

View file

@ -94,7 +94,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <math.h>
#include <limits.h>
#include <time.h>
#include <errno.h>
@ -110,13 +109,7 @@ int turn = -1;
int NewbieImmunity(void)
{
static int value = -1;
static int gamecookie = -1;
if (value < 0 || gamecookie != global.cookie) {
gamecookie = global.cookie;
value = get_param_int(global.parameters, "NewbieImmunity", 0);
}
return value;
return config_get_int("NewbieImmunity", 0);
}
bool IsImmune(const faction * f)
@ -143,13 +136,7 @@ static int ally_flag(const char *s, int help_mask)
bool ExpensiveMigrants(void)
{
static int value = -1;
static int gamecookie = -1;
if (value < 0 || gamecookie != global.cookie) {
gamecookie = global.cookie;
value = get_param_int(global.parameters, "study.expensivemigrants", 0);
}
return value != 0;
return config_get_int("study.expensivemigrants", 0) != 0;
}
/** Specifies automatic alliance modes.
@ -158,21 +145,17 @@ bool ExpensiveMigrants(void)
*/
int AllianceAuto(void)
{
static int value = -1;
static int gamecookie = -1;
if (value < 0 || gamecookie != global.cookie) {
const char *str = get_param(global.parameters, "alliance.auto");
gamecookie = global.cookie;
value = 0;
if (str != NULL) {
char *sstr = _strdup(str);
char *tok = strtok(sstr, " ");
while (tok) {
value |= ally_flag(tok, -1);
tok = strtok(NULL, " ");
}
free(sstr);
int value;
const char *str = config_get("alliance.auto");
value = 0;
if (str != NULL) {
char *sstr = _strdup(str);
char *tok = strtok(sstr, " ");
while (tok) {
value |= ally_flag(tok, -1);
tok = strtok(NULL, " ");
}
free(sstr);
}
return value & HelpMask();
}
@ -185,89 +168,60 @@ int AllianceAuto(void)
*/
int HelpMask(void)
{
static int rule = -1;
static int gamecookie = -1;
if (rule < 0 || gamecookie != global.cookie) {
const char *str = get_param(global.parameters, "rules.help.mask");
gamecookie = global.cookie;
rule = 0;
if (str != NULL) {
char *sstr = _strdup(str);
char *tok = strtok(sstr, " ");
while (tok) {
rule |= ally_flag(tok, -1);
tok = strtok(NULL, " ");
}
free(sstr);
}
else {
rule = HELP_ALL;
const char *str = config_get("rules.help.mask");
int rule = 0;
if (str != NULL) {
char *sstr = _strdup(str);
char *tok = strtok(sstr, " ");
while (tok) {
rule |= ally_flag(tok, -1);
tok = strtok(NULL, " ");
}
free(sstr);
}
else {
rule = HELP_ALL;
}
return rule;
}
int AllianceRestricted(void)
{
static int rule = -1;
static int gamecookie = -1;
if (rule < 0 || gamecookie != global.cookie) {
const char *str = get_param(global.parameters, "alliance.restricted");
gamecookie = global.cookie;
rule = 0;
if (str != NULL) {
char *sstr = _strdup(str);
char *tok = strtok(sstr, " ");
while (tok) {
rule |= ally_flag(tok, -1);
tok = strtok(NULL, " ");
}
free(sstr);
const char *str = config_get("alliance.restricted");
int rule = 0;
if (str != NULL) {
char *sstr = _strdup(str);
char *tok = strtok(sstr, " ");
while (tok) {
rule |= ally_flag(tok, -1);
tok = strtok(NULL, " ");
}
rule &= HelpMask();
free(sstr);
}
rule &= HelpMask();
return rule;
}
int LongHunger(const struct unit *u)
{
static int gamecookie = -1;
static int rule = -1;
if (u != NULL) {
if (!fval(u, UFL_HUNGER))
return false;
if (u_race(u) == get_race(RC_DAEMON))
return false;
}
if (rule < 0 || gamecookie != global.cookie) {
gamecookie = global.cookie;
rule = get_param_int(global.parameters, "hunger.long", 0);
}
return rule;
return config_get_int("hunger.long", 0);
}
int SkillCap(skill_t sk)
{
static int gamecookie = -1;
static int rule = -1;
if (sk == SK_MAGIC)
return 0; /* no caps on magic */
if (rule < 0 || gamecookie != global.cookie) {
gamecookie = global.cookie;
rule = get_param_int(global.parameters, "skill.maxlevel", 0);
}
return rule;
if (sk == SK_MAGIC) return 0; /* no caps on magic */
return config_get_int("skill.maxlevel", 0);
}
int NMRTimeout(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
gamecookie = global.cookie;
rule = get_param_int(global.parameters, "nmr.timeout", 0);
}
return rule;
return config_get_int("nmr.timeout", 0);
}
race_t old_race(const struct race * rc)
@ -416,8 +370,7 @@ static attrib_type at_maxmagicians = {
int max_magicians(const faction * f)
{
int m =
get_param_int(global.parameters, "rules.maxskills.magic", MAXMAGICIANS);
int m = config_get_int("rules.maxskills.magic", MAXMAGICIANS);
attrib *a;
if ((a = a_find(f->attribs, &at_maxmagicians)) != NULL) {
@ -498,7 +451,7 @@ static int ally_mode(const ally * sf, int mode)
int
alliedgroup(const struct plane *pl, const struct faction *f,
const struct faction *f2, const struct ally *sf, int mode)
const struct faction *f2, const struct ally *sf, int mode)
{
while (sf && sf->faction != f2)
sf = sf->next;
@ -522,7 +475,7 @@ const struct faction *f2, const struct ally *sf, int mode)
int
alliedfaction(const struct plane *pl, const struct faction *f,
const struct faction *f2, int mode)
const struct faction *f2, int mode)
{
return alliedgroup(pl, f, f2, f->allies, mode);
}
@ -567,68 +520,6 @@ int alliedunit(const unit * u, const faction * f2, int mode)
}
return 0;
}
int count_faction(const faction * f, int flags)
{
unit *u;
int n = 0;
for (u = f->units; u; u = u->nextF) {
const race *rc = u_race(u);
int x = (flags&COUNT_UNITS) ? 1 : u->number;
if (f->race != rc) {
if (!playerrace(rc)) {
if (flags&COUNT_MONSTERS) {
n += x;
}
}
else if (flags&COUNT_MIGRANTS) {
if (!is_cursed(u->attribs, C_SLAVE, 0)) {
n += x;
}
}
}
else if (flags&COUNT_DEFAULT) {
n += x;
}
}
return n;
}
int count_units(const faction * f)
{
return count_faction(f, COUNT_ALL | COUNT_UNITS);
}
int count_all(const faction * f)
{
return count_faction(f, COUNT_ALL);
}
int count_migrants(const faction * f)
{
return count_faction(f, COUNT_MIGRANTS);
}
int count_maxmigrants(const faction * f)
{
static int migrants = -1;
if (migrants < 0) {
migrants = get_param_int(global.parameters, "rules.migrants.max", INT_MAX);
}
if (migrants == INT_MAX) {
int x = 0;
if (f->race == get_race(RC_HUMAN)) {
int nsize = count_all(f);
if (nsize > 0) {
x = (int)(log10(nsize / 50.0) * 20);
if (x < 0)
x = 0;
}
}
return x;
}
return migrants;
}
void
parse(keyword_t kword, int(*dofun) (unit *, struct order *), bool thisorder)
{
@ -976,7 +867,7 @@ void init_locale(struct locale *lang)
tokens = get_translations(lang, UT_MAGIC);
if (tokens) {
const char *str = get_param(global.parameters, "rules.magic.playerschools");
const char *str = config_get("rules.magic.playerschools");
char *sstr, *tok;
if (str == NULL) {
str = "gwyrrd illaun draig cerddor tybied";
@ -1024,32 +915,58 @@ void init_locale(struct locale *lang)
}
typedef struct param {
struct param *next;
char *name;
char *data;
critbit_tree cb;
} param;
size_t pack_keyval(const char *key, const char *value, char *data, size_t len) {
size_t klen = strlen(key);
size_t vlen = strlen(value);
assert(klen + vlen + 2 + sizeof(vlen) <= len);
memcpy(data, key, klen + 1);
memcpy(data + klen + 1, value, vlen + 1);
return klen + vlen + 2;
}
void set_param(struct param **p, const char *key, const char *value)
{
struct param *par;
assert(p);
par = *p;
if (!par && value) {
*p = par = calloc(1, sizeof(param));
}
if (par) {
void *match;
size_t klen = strlen(key) + 1;
if (cb_find_prefix(&par->cb, key, klen, &match, 1, 0) > 0) {
const char * kv = (const char *)match;
size_t vlen = strlen(kv + klen) + 1;
cb_erase(&par->cb, kv, klen + vlen);
}
}
if (value) {
char data[512];
size_t sz = pack_keyval(key, value, data, sizeof(data));
cb_insert(&par->cb, data, sz);
}
}
void free_params(struct param **pp) {
while (*pp) {
param *p = *pp;
free(p->name);
free(p->data);
*pp = p->next;
param *p = *pp;
if (p) {
cb_clear(&p->cb);
free(p);
}
*pp = 0;
}
const char *get_param(const struct param *p, const char *key)
{
while (p != NULL) {
int cmp = strcmp(p->name, key);
if (cmp == 0) {
return p->data;
}
else if (cmp > 0) {
break;
}
p = p->next;
void *match;
if (p && cb_find_prefix(&p->cb, key, strlen(key) + 1, &match, 1, 0) > 0) {
cb_get_kv_ex(match, &match);
return (const char *)match;
}
return NULL;
}
@ -1135,40 +1052,6 @@ double get_param_flt(const struct param *p, const char *key, double def)
return str ? atof(str) : def;
}
void set_param(struct param **p, const char *key, const char *data)
{
struct param *par;
++global.cookie;
while (*p != NULL) {
int cmp = strcmp((*p)->name, key);
if (cmp == 0) {
par = *p;
free(par->data);
if (data) {
par->data = _strdup(data);
}
else {
*p = par->next;
free(par->name);
free(par);
}
return;
}
else if (cmp > 0) {
break;
}
p = &(*p)->next;
}
if (data) {
par = malloc(sizeof(param));
par->name = _strdup(key);
par->data = _strdup(data);
par->next = *p;
*p = par;
}
}
void kernel_done(void)
{
/* calling this function releases memory assigned to static variables, etc.
@ -1203,11 +1086,6 @@ char *_strdup(const char *s)
}
#endif
bool faction_id_is_unused(int id)
{
return findfaction(id) == NULL;
}
int besieged(const unit * u)
{
/* belagert kann man in schiffen und burgen werden */
@ -1331,103 +1209,44 @@ int cmp_current_owner(const building * b, const building * a)
bool rule_stealth_other(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule = get_param_int(global.parameters, "stealth.faction.other", 1);
gamecookie = global.cookie;
assert(rule >= 0);
}
int rule = config_get_int("stealth.faction.other", 1);
return rule != 0;
}
bool rule_stealth_anon(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule = get_param_int(global.parameters, "stealth.faction.anon", 1);
gamecookie = global.cookie;
assert(rule >= 0);
}
return rule!=0;
int rule = config_get_int("stealth.faction.anon", 1);
return rule != 0;
}
bool rule_region_owners(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule = get_param_int(global.parameters, "rules.region_owners", 0);
gamecookie = global.cookie;
assert(rule >= 0);
}
return rule!=0;
}
bool rule_auto_taxation(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule =
get_param_int(global.parameters, "rules.economy.taxation", 0);
gamecookie = global.cookie;
assert(rule >= 0);
}
return rule;
int rule = config_get_int("rules.region_owners", 0);
return rule != 0;
}
int rule_blessed_harvest(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule =
get_param_int(global.parameters, "rules.blessed_harvest.flags",
HARVEST_WORK);
gamecookie = global.cookie;
assert(rule >= 0);
}
int rule = config_get_int("rules.blessed_harvest.flags",
HARVEST_WORK);
assert(rule >= 0);
return rule;
}
int rule_alliance_limit(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule = get_param_int(global.parameters, "rules.limit.alliance", 0);
gamecookie = global.cookie;
assert(rule >= 0);
}
int rule = config_get_int("rules.limit.alliance", 0);
assert(rule >= 0);
return rule;
}
int rule_faction_limit(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule = get_param_int(global.parameters, "rules.limit.faction", 0);
gamecookie = global.cookie;
assert(rule >= 0);
}
int rule = config_get_int("rules.limit.faction", 0);
assert(rule >= 0);
return rule;
}
bool rule_transfermen(void)
{
static int gamecookie = -1;
static int rule = -1;
if (rule < 0 || gamecookie != global.cookie) {
rule = get_param_int(global.parameters, "rules.transfermen", 1);
gamecookie = global.cookie;
assert(rule >= 0);
}
return rule!=0;
}
static int
default_wage(const region * r, const faction * f, const race * rc, int in_turn)
{
@ -1637,7 +1456,7 @@ order *default_order(const struct locale *lang)
order *result = 0;
assert(i < MAXLOCALES);
if (default_keyword!=NOKEYWORD) {
if (default_keyword != NOKEYWORD) {
return create_order(default_keyword, lang, 0);
}
@ -1673,12 +1492,40 @@ int entertainmoney(const region * r)
int rule_give(void)
{
return get_param_int(global.parameters, "rules.give.flags", GIVE_DEFAULT);
return config_get_int("rules.give.flags", GIVE_DEFAULT);
}
bool markets_module(void)
{
return get_param_int(global.parameters, "modules.markets", 0);
return config_get_int("modules.markets", 0);
}
static struct param *configuration;
void config_set(const char *key, const char *value) {
set_param(&configuration, key, value);
}
const char *config_get(const char *key) {
return get_param(configuration, key);
}
int config_get_int(const char *key, int def) {
return get_param_int(configuration, key, def);
}
double config_get_flt(const char *key, double def) {
return get_param_flt(configuration, key, def);
}
bool config_token(const char *key, const char *tok) {
return !!check_param(configuration, key, tok);
}
void free_config(void) {
global.functions.maintenance = NULL;
global.functions.wage = NULL;
free_params(&configuration);
}
/** releases all memory associated with the game state.
@ -1718,15 +1565,14 @@ void free_gamedata(void)
while (global.attribs) {
a_remove(&global.attribs, global.attribs);
}
++global.cookie; /* readgame() already does this, but sjust in case */
}
const char * game_name(void) {
const char * param = get_param(global.parameters, "game.name");
const char * param = config_get("game.name");
return param ? param : global.gamename;
}
int game_id(void) {
return get_param_int(global.parameters, "game.id", 0);
return config_get_int("game.id", 0);
}

View file

@ -25,57 +25,12 @@ extern "C" {
/* this should always be the first thing included after platform.h */
#include "types.h"
/* experimental gameplay features (that don't affect the savefile) */
/* TODO: move these settings to settings.h or into configuration files */
#define GOBLINKILL /* Goblin-Spezialklau kann tödlich enden */
#define HERBS_ROT /* herbs owned by units have a chance to rot. */
#define INSECT_POTION /* Spezialtrank für Insekten */
#define ORCIFICATION /* giving snotlings to the peasants gets counted */
/* for some good prime numbers, check http://www.math.niu.edu/~rusin/known-math/98/pi_x */
#ifndef MAXREGIONS
# define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */
#endif
#ifndef MAXUNITS
# define MAXUNITS 1048573 /* must be prime for hashing. 524287 was >90% full */
#endif
#define MAXLUXURIES 16 /* there must be no more than MAXLUXURIES kinds of luxury goods in any game */
#define TREESIZE (8) /* space used by trees (in #peasants) */
#define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */
#define HERBROTCHANCE 5 /* Verrottchance für Kräuter (ifdef HERBS_ROT) */
/* Gebäudegröße = Minimalbelagerer */
#define SIEGEFACTOR 2
/** Magic */
#define MAXMAGICIANS 3
#define MAXALCHEMISTS 3
struct param;
/* getunit results: */
#define GET_UNIT 0
#define GET_NOTFOUND 1
#define GET_PEASANTS 2
/* Bewegungsweiten: */
#define BP_WALKING 4
#define BP_RIDING 6
#define BP_UNICORN 9
#define BP_DRAGON 4
#define BP_NORMAL 3
#define BP_ROAD 2
#define PERSON_WEIGHT 1000 /* weight of a "normal" human unit */
#define STAMINA_AFFECTS_HP 1<<0
/**
* Hier endet der Teil von config.h, der die defines für die
* Spielwelt Eressea enthält, und beginnen die allgemeinen Routinen
*/
#define ENCCHANCE 10 /* %-Chance für einmalige Zufallsbegegnung */
#define DISPLAYSIZE 8192 /* max. Länge einer Beschreibung, incl trailing 0 */
#define ORDERSIZE (DISPLAYSIZE*2) /* max. length of an order */
@ -84,8 +39,6 @@ extern "C" {
#define OBJECTIDSIZE (NAMESIZE+5+IDSIZE) /* max. Länge der Strings, die
* von struct unitname, etc. zurückgegeben werden. ohne die 0 */
#define BAGCAPACITY 20000 /* soviel paßt in einen Bag of Holding */
/* ----------------- Befehle ----------------------------------- */
#define want(option) (1<<option)
@ -97,9 +50,6 @@ extern "C" {
#define fset(u, i) ((u)->flags |= (i))
#define freset(u, i) ((u)->flags &= ~(i))
/* parteinummern */
bool faction_id_is_unused(int);
int max_magicians(const struct faction * f);
int findoption(const char *s, const struct locale *lang);
@ -151,7 +101,6 @@ extern "C" {
int cmp_current_owner(const struct building *b,
const struct building *bother);
bool rule_transfermen(void);
bool rule_region_owners(void);
bool rule_stealth_other(void); // units can pretend to be another faction, TARNE PARTEI <no>
bool rule_stealth_anon(void); // units can anonymize their faction, TARNE PARTEI [NICHT]
@ -160,7 +109,6 @@ extern "C" {
#define HARVEST_WORK 0x00
#define HARVEST_TAXES 0x01
int rule_blessed_harvest(void);
bool rule_auto_taxation(void);
#define GIVE_SELF 1
#define GIVE_PEASANTS 2
#define GIVE_LUXURIES 4
@ -171,18 +119,6 @@ extern "C" {
#define GIVE_DEFAULT (GIVE_SELF|GIVE_PEASANTS|GIVE_LUXURIES|GIVE_HERBS|GIVE_GOODS)
int rule_give(void);
#define COUNT_MONSTERS 0x01
#define COUNT_MIGRANTS 0x02
#define COUNT_DEFAULT 0x04
#define COUNT_ALL 0x07
#define COUNT_UNITS 0x10
int count_faction(const struct faction * f, int flags);
int count_migrants(const struct faction * f);
int count_maxmigrants(const struct faction * f);
int count_all(const struct faction * f);
int count_units(const struct faction * f);
bool has_limited_skills(const struct unit *u);
const struct race *findrace(const char *, const struct locale *);
@ -248,7 +184,6 @@ extern "C" {
const char *gamename;
struct attrib *attribs;
unsigned int data_turn;
struct param *parameters;
void *vm_state;
int data_version; /* TODO: eliminate in favor of gamedata.version */
struct _dictionary_ *inifile;
@ -258,10 +193,6 @@ extern "C" {
const struct race * rc, int in_turn);
int(*maintenance) (const struct unit * u);
} functions;
/* the following are some cached values, because get_param can be slow.
* you should almost never need to touch them */
int cookie;
double producexpchance_;
} settings;
typedef struct helpmode {
@ -271,13 +202,19 @@ extern "C" {
const char *dbrace(const struct race *rc);
void set_param(struct param **p, const char *key, const char *data);
void set_param(struct param **p, const char *key, const char *value);
const char *get_param(const struct param *p, const char *key);
int get_param_int(const struct param *p, const char *key, int def);
int check_param(const struct param *p, const char *key, const char *searchvalue);
double get_param_flt(const struct param *p, const char *key, double def);
void free_params(struct param **pp);
void config_set(const char *key, const char *value);
const char *config_get(const char *key);
int config_get_int(const char *key, int def);
double config_get_flt(const char *key, double def);
bool config_token(const char *key, const char *tok);
bool ExpensiveMigrants(void);
int NMRTimeout(void);
int LongHunger(const struct unit *u);
@ -294,6 +231,7 @@ extern "C" {
void init_parameters(struct locale *lang);
void free_gamedata(void);
void free_config(void);
extern struct helpmode helpmodes[];
extern const char *parameters[];

View file

@ -130,6 +130,8 @@ static void test_get_set_param(CuTest * tc)
set_param(&par, "bar", "foo");
CuAssertStrEquals(tc, "bar", get_param(par, "foo"));
CuAssertStrEquals(tc, "foo", get_param(par, "bar"));
set_param(&par, "bar", "bar");
CuAssertStrEquals(tc, "bar", get_param(par, "bar"));
set_param(&par, "bar", NULL);
CuAssertPtrEquals(tc, NULL, (void *)get_param(par, "bar"));
free_params(&par);
@ -175,11 +177,11 @@ static void test_forbiddenid(CuTest *tc) {
CuSuite *get_config_suite(void)
{
CuSuite *suite = CuSuiteNew();
SUITE_ADD_TEST(suite, test_forbiddenid);
SUITE_ADD_TEST(suite, test_getunit);
SUITE_ADD_TEST(suite, test_read_unitid);
SUITE_ADD_TEST(suite, test_get_set_param);
SUITE_ADD_TEST(suite, test_param_int);
SUITE_ADD_TEST(suite, test_param_flt);
SUITE_ADD_TEST(suite, test_forbiddenid);
SUITE_ADD_TEST(suite, test_getunit);
SUITE_ADD_TEST(suite, test_read_unitid);
return suite;
}

View file

@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "alliance.h"
#include "ally.h"
#include "curse.h"
#include "equipment.h"
#include "group.h"
#include "item.h"
@ -54,10 +55,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* libc includes */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
faction *factions;
@ -208,6 +210,11 @@ int resolve_faction(variant id, void *address)
return result;
}
bool faction_id_is_unused(int id)
{
return findfaction(id) == NULL;
}
#define MAX_FACTION_ID (36*36*36*36)
static int unused_faction_id(void)
@ -568,7 +575,7 @@ static int allied_skilllimit(const faction * f, skill_t sk)
{
static int value = -1;
if (value < 0) {
value = get_param_int(global.parameters, "alliance.skilllimit", 0);
value = config_get_int("alliance.skilllimit", 0);
}
return value;
}
@ -611,8 +618,7 @@ int skill_limit(faction * f, skill_t sk)
m = max_magicians(f);
}
else if (sk == SK_ALCHEMY) {
m = get_param_int(global.parameters, "rules.maxskills.alchemy",
MAXALCHEMISTS);
m = config_get_int("rules.maxskills.alchemy", MAXALCHEMISTS);
}
return m;
}
@ -708,3 +714,62 @@ void faction_setorigin(faction * f, int id, int x, int y)
addlist(&f->ursprung, ur);
}
int count_faction(const faction * f, int flags)
{
unit *u;
int n = 0;
for (u = f->units; u; u = u->nextF) {
const race *rc = u_race(u);
int x = (flags&COUNT_UNITS) ? 1 : u->number;
if (f->race != rc) {
if (!playerrace(rc)) {
if (flags&COUNT_MONSTERS) {
n += x;
}
}
else if (flags&COUNT_MIGRANTS) {
if (!is_cursed(u->attribs, C_SLAVE, 0)) {
n += x;
}
}
}
else if (flags&COUNT_DEFAULT) {
n += x;
}
}
return n;
}
int count_units(const faction * f)
{
return count_faction(f, COUNT_ALL | COUNT_UNITS);
}
int count_all(const faction * f)
{
return count_faction(f, COUNT_ALL);
}
int count_migrants(const faction * f)
{
return count_faction(f, COUNT_MIGRANTS);
}
#define MIGRANTS_NONE 0
#define MIGRANTS_LOG10 1
int count_maxmigrants(const faction * f)
{
int formula = get_param_int(f->race->parameters, "migrants.formula", 0);
if (formula == MIGRANTS_LOG10) {
int nsize = count_all(f);
if (nsize > 0) {
int x = (int)(log10(nsize / 50.0) * 20);
if (x < 0) x = 0;
return x;
}
}
return 0;
}

View file

@ -160,6 +160,20 @@ extern "C" {
/* skills */
int skill_limit(struct faction *f, skill_t sk);
int count_skill(struct faction *f, skill_t sk);
bool faction_id_is_unused(int);
#define COUNT_MONSTERS 0x01
#define COUNT_MIGRANTS 0x02
#define COUNT_DEFAULT 0x04
#define COUNT_ALL 0x07
#define COUNT_UNITS 0x10
int count_faction(const struct faction * f, int flags);
int count_migrants(const struct faction * f);
int count_maxmigrants(const struct faction * f);
int count_all(const struct faction * f);
int count_units(const struct faction * f);
#ifdef __cplusplus
}

View file

@ -533,7 +533,7 @@ static void disable_feature(const char *str) {
}
_snprintf(name, sizeof(name), "%s.enabled", str);
log_info("disable feature %s\n", name);
set_param(&global.parameters, name, "0");
config_set(name, "0");
}
static void json_disable_features(cJSON *json) {
@ -788,7 +788,7 @@ static void json_settings(cJSON *json) {
}
for (child = json->child; child; child = child->next) {
if (child->valuestring) {
set_param(&global.parameters, child->string, child->valuestring);
config_set(child->string, child->valuestring);
}
else {
char value[32];
@ -798,7 +798,7 @@ static void json_settings(cJSON *json) {
else {
_snprintf(value, sizeof(value), "%d", child->valueint);
}
set_param(&global.parameters, child->string, value);
config_set(child->string, value);
}
}
}

View file

@ -74,11 +74,11 @@ static void test_settings(CuTest * tc)
test_cleanup();
json_config(json);
CuAssertStrEquals(tc, "1", get_param(global.parameters, "true"));
CuAssertStrEquals(tc, "0", get_param(global.parameters, "false"));
CuAssertStrEquals(tc, "1d4", get_param(global.parameters, "string"));
CuAssertIntEquals(tc, 14, get_param_int(global.parameters, "integer", 0));
CuAssertDblEquals(tc, 1.5f, get_param_flt(global.parameters, "float", 0), 0.01);
CuAssertStrEquals(tc, "1", config_get("true"));
CuAssertStrEquals(tc, "0", config_get("false"));
CuAssertStrEquals(tc, "1d4", config_get("string"));
CuAssertIntEquals(tc, 14, config_get_int("integer", 0));
CuAssertDblEquals(tc, 1.5f, config_get_flt("float", 0), 0.01);
cJSON_Delete(json);
test_cleanup();
}
@ -117,13 +117,13 @@ static void test_disable(CuTest * tc)
CuAssertTrue(tc, !keyword_disabled(K_BANNER));
CuAssertTrue(tc, !keyword_disabled(K_PAY));
CuAssertTrue(tc, !keyword_disabled(K_BESIEGE));
CuAssertIntEquals(tc, 1, get_param_int(global.parameters, "module.enabled", 1));
CuAssertIntEquals(tc, 1, config_get_int("module.enabled", 1));
json_config(json);
CuAssertTrue(tc, !skill_enabled(SK_ALCHEMY));
CuAssertTrue(tc, !keyword_disabled(K_BANNER));
CuAssertTrue(tc, keyword_disabled(K_PAY));
CuAssertTrue(tc, keyword_disabled(K_BESIEGE));
CuAssertIntEquals(tc, 0, get_param_int(global.parameters, "module.enabled", 1));
CuAssertIntEquals(tc, 0, config_get_int("module.enabled", 1));
cJSON_Delete(json);
test_cleanup();
}

View file

@ -26,6 +26,9 @@ extern "C" {
#include "types.h"
#include "direction.h"
#define MAXLUXURIES 16 /* there must be no more than MAXLUXURIES kinds of luxury goods in any game */
#define MAXREGIONS 524287 /* must be prime for hashing. 262139 was a little small */
/* FAST_CONNECT: regions are directly connected to neighbours, saves doing
a hash-access each time a neighbour is needed, 6 extra pointers per hex */
#define FAST_CONNECT

View file

@ -29,12 +29,7 @@
static double ResourceFactor(void)
{
static double value = -1.0;
if (value < 0) {
const char *str = get_param(global.parameters, "resource.factor");
value = str ? atof(str) : 1.0;
}
return value;
return config_get_flt("resource.factor", 1.0);
}
void update_resources(region * r)
@ -82,10 +77,7 @@ void terraform_resources(region * r)
{
int i;
const terrain_type *terrain = r->terrain;
static int terraform_all = -1;
if (terraform_all < 0) {
terraform_all = get_param_int(global.parameters, "rules.terraform.all", 0);
}
bool terraform_all = config_get_int("rules.terraform.all", 0) != 0;
if (terrain->production == NULL)
return;

View file

@ -1449,7 +1449,6 @@ int readgame(const char *filename, bool backup)
global.data_turn = turn;
log_debug(" - reading turn %d\n", turn);
rng_init(turn);
++global.cookie;
READ_INT(&store, &nread); /* max_unique_id = ignore */
READ_INT(&store, &nextborder);

View file

@ -42,6 +42,7 @@ static void test_readwrite_unit(CuTest * tc)
sprintf(path, "%s/%s", datapath(), filename);
data = gamedata_open(path, "wb");
CuAssertPtrNotNull(tc, data); // TODO: intermittent test
write_unit(data, u);
gamedata_close(data);

View file

@ -271,7 +271,7 @@ const char *write_shipname(const ship * sh, char *ibuf, size_t size)
static int ShipSpeedBonus(const unit * u)
{
int level = get_param_int(global.parameters, "movement.shipspeed.skillbonus", 0);
int level = config_get_int("movement.shipspeed.skillbonus", 0);
if (level > 0) {
ship *sh = u->ship;
int skl = effskill(u, SK_SAILING, 0);

View file

@ -399,7 +399,7 @@ static ship *setup_ship(void) {
region *r;
ship_type *stype;
set_param(&global.parameters, "movement.shipspeed.skillbonus", "0");
config_set("movement.shipspeed.skillbonus", "0");
r = test_create_region(0, 0, test_create_terrain("ocean", 0));
stype = test_create_shiptype("longboat");
stype->cptskill = 1;
@ -558,7 +558,7 @@ static void test_shipspeed_max_range(CuTest *tc) {
test_cleanup();
sh = setup_ship();
setup_crew(sh, 0, &cap, &crew);
set_param(&global.parameters, "movement.shipspeed.skillbonus", "5");
config_set("movement.shipspeed.skillbonus", "5");
r = sh->region;
f = test_create_faction(0);
assert(r && f);

View file

@ -212,7 +212,7 @@ void sk_set(skill * sv, int level)
static int rule_random_progress(void)
{
return get_param_int(global.parameters, "study.random_progress", 1);
return config_get_int("study.random_progress", 1);
}
int skill_weeks(int level)

View file

@ -181,22 +181,16 @@ bool is_astral(const region * r)
plane *get_astralplane(void)
{
static plane *astralspace;
static int rule_astralplane = -1;
static int gamecookie = -1;
if (rule_astralplane < 0) {
rule_astralplane =
get_param_int(global.parameters, "modules.astralspace", 1);
}
plane *astralspace = 0;
int rule_astralplane = config_get_int("modules.astralspace", 1);
if (!rule_astralplane) {
return NULL;
}
if (gamecookie != global.cookie) {
if (!astralspace) {
astralspace = getplanebyname("Astralraum");
gamecookie = global.cookie;
}
if (astralspace == NULL) {
if (!astralspace) {
astralspace = create_new_plane(1, "Astralraum",
TE_CENTER_X - 500, TE_CENTER_X + 500,
TE_CENTER_Y - 500, TE_CENTER_Y + 500, 0);

View file

@ -232,7 +232,7 @@ static buddy *get_friends(const unit * u, int *numfriends)
for (u2 = r->units; u2; u2 = u2->next) {
if (u2->faction != f && u2->number > 0) {
int allied = 0;
if (get_param_int(global.parameters, "rules.alliances", 0) != 0) {
if (config_get_int("rules.alliances", 0) != 0) {
allied = (f->alliance && f->alliance == u2->faction->alliance);
}
else if (alliedunit(u, u2->faction, HELP_MONEY)
@ -850,17 +850,13 @@ void leave_building(unit * u)
bool can_leave(unit * u)
{
static int gamecookie = -1;
static int rule_leave = -1;
int rule_leave;
if (!u->building) {
return true;
}
if (rule_leave < 0 || gamecookie != global.cookie) {
gamecookie = global.cookie;
rule_leave = get_param_int(global.parameters, "rules.move.owner_leave", 0);
}
rule_leave = config_get_int("rules.move.owner_leave", 0);
if (rule_leave!=0 && u->building && u == building_owner(u->building)) {
return false;
@ -1347,7 +1343,7 @@ int get_modifier(const unit * u, skill_t sk, int level, const region * r, bool n
skill = skillmod(u->attribs, u, r, sk, skill, SMF_ALWAYS);
if (hunger_red_skill == -1) {
hunger_red_skill = get_param_int(global.parameters, "rules.hunger.reduces_skill", 2);
hunger_red_skill = config_get_int("rules.hunger.reduces_skill", 2);
}
if (fval(u, UFL_HUNGER) && hunger_red_skill) {
@ -1370,7 +1366,7 @@ int eff_skill(const unit * u, const skill *sv, const region *r)
if (mlevel > 0) {
int skillcap = SkillCap(sv->id);
if (skillcap && mlevel > skillcap) {
if (skillcap>0 && mlevel > skillcap) {
return skillcap;
}
return mlevel;
@ -1725,18 +1721,13 @@ void unit_addorder(unit * u, order * ord)
int unit_max_hp(const unit * u)
{
static int rules_stamina = -1;
int h;
double p;
static const curse_type *heal_ct = NULL;
if (rules_stamina < 0) {
rules_stamina =
get_param_int(global.parameters, "rules.stamina", STAMINA_AFFECTS_HP);
}
int rule_stamina = config_get_int("rules.stamina", STAMINA_AFFECTS_HP);
h = u_race(u)->hitpoints;
if (rules_stamina & 1) {
if (rule_stamina & 1) {
p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2;
h += (int)(h * p + 0.5);
}
@ -1935,12 +1926,7 @@ bool unit_can_study(const unit *u) {
}
static double produceexp_chance(void) {
static int update = 0;
if (update != global.cookie) {
global.producexpchance_ = get_param_flt(global.parameters, "study.from_use", 1.0 / 3);
update = global.cookie;
}
return global.producexpchance_;
return config_get_flt("study.from_use", 1.0 / 3);
}
void produceexp_ex(struct unit *u, skill_t sk, int n, bool (*learn)(unit *, skill_t, double))

View file

@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern "C" {
#endif
#define MAXUNITS 1048573 /* must be prime for hashing. 524287 was >90% full */
struct skill;
struct item;
struct sc_mage;

View file

@ -284,15 +284,15 @@ static void test_skill_hunger(CuTest *tc) {
set_level(u, SK_SAILING, 6);
fset(u, UFL_HUNGER);
set_param(&global.parameters, "rules.hunger.reduces_skill", "0");
config_set("rules.hunger.reduces_skill", "0");
CuAssertIntEquals(tc, 6, effskill(u, SK_ARMORER, 0));
CuAssertIntEquals(tc, 6, effskill(u, SK_SAILING, 0));
set_param(&global.parameters, "rules.hunger.reduces_skill", "1");
config_set("rules.hunger.reduces_skill", "1");
CuAssertIntEquals(tc, 3, effskill(u, SK_ARMORER, 0));
CuAssertIntEquals(tc, 3, effskill(u, SK_SAILING, 0));
set_param(&global.parameters, "rules.hunger.reduces_skill", "2");
config_set("rules.hunger.reduces_skill", "2");
CuAssertIntEquals(tc, 3, effskill(u, SK_ARMORER, 0));
CuAssertIntEquals(tc, 5, effskill(u, SK_SAILING, 0));
set_level(u, SK_SAILING, 2);
@ -371,7 +371,7 @@ static void test_produceexp(CuTest *tc) {
g_tc = tc;
test_cleanup();
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
set_param(&global.parameters, "study.from_use", "0.5");
config_set("study.from_use", "0.5");
produceexp_ex(u, SK_ALCHEMY, 1, cb_learn_one);
produceexp_ex(u, SK_ALCHEMY, 2, cb_learn_two);
test_cleanup();

View file

@ -117,14 +117,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
static bool RemoveNMRNewbie(void)
{
static int value = -1;
static int gamecookie = -1;
if (value < 0 || gamecookie != global.cookie) {
value = get_param_int(global.parameters, "nmr.removenewbie", 0);
gamecookie = global.cookie;
}
return value!=0;
int value = config_get_int("nmr.removenewbie", 0);
return value != 0;
}
static void age_unit(region * r, unit * u)
@ -251,12 +245,12 @@ static void calculate_emigration(region * r)
static double peasant_growth_factor(void)
{
return get_param_flt(global.parameters, "rules.peasants.growth.factor", 0.0001F * PEASANTGROWTH);
return config_get_flt("rules.peasants.growth.factor", 0.0001F * PEASANTGROWTH);
}
#ifdef SLOWLUCK
int peasant_luck_effect(int peasants, int luck, int maxp, double variance) {
int n, births=0;
int n, births = 0;
double factor = peasant_growth_factor();
for (n = peasants; n && luck; --n) {
int chances = 0;
@ -281,7 +275,7 @@ int peasant_luck_effect(int peasants, int luck, int maxp, double variance) {
#else
static double peasant_luck_factor(void)
{
return get_param_flt(global.parameters, "rules.peasants.peasantluck.factor", PEASANTLUCK);
return config_get_flt("rules.peasants.peasantluck.factor", PEASANTLUCK);
}
int peasant_luck_effect(int peasants, int luck, int maxp, double variance)
@ -311,7 +305,7 @@ static void peasants(region * r)
int n, satiated;
int dead = 0;
if (peasants > 0 && get_param_int(global.parameters, "rules.peasants.growth", 1)) {
if (peasants > 0 && config_get_int("rules.peasants.growth", 1)) {
int luck = 0;
double fraction = peasants * peasant_growth_factor();
int births = RAND_ROUND(fraction);
@ -336,7 +330,7 @@ static void peasants(region * r)
* Großteil. dead kann nie größer als rpeasants(r) - satiated werden,
* so dass rpeasants(r) >= 0 bleiben muß. */
/* Es verhungert maximal die unterernährten Bevölkerung. */
/* Es verhungert maximal die unterernährten Bevölkerung. */
n = _min(peasants - satiated, rpeasants(r));
dead += (int)(0.5 + n * PEASANT_STARVATION_CHANCE);
@ -429,7 +423,7 @@ static void horses(region * r)
int i;
double growth =
(RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses -
horses)) / maxhorses;
horses)) / maxhorses;
if (growth > 0) {
if (a_find(r->attribs, &at_horseluck))
@ -488,7 +482,7 @@ extern struct attrib_type at_germs;
static void
growing_trees_e3(region * r, const int current_season,
const int last_weeks_season)
const int last_weeks_season)
{
static const int transform[4][3] = {
{ -1, -1, 0 },
@ -698,7 +692,7 @@ void immigration(void)
{
region *r;
log_info(" - Einwanderung...");
int repopulate = get_param_int(global.parameters, "rules.economy.repopulate_maximum", 90);
int repopulate = config_get_int("rules.economy.repopulate_maximum", 90);
for (r = regions; r; r = r->next) {
if (r->land && r->land->newpeasants) {
int rp = rpeasants(r) + r->land->newpeasants;
@ -744,7 +738,7 @@ void nmr_warnings(void)
message *msg = NULL;
for (fa = factions; fa; fa = fa->next) {
int warn = 0;
if (get_param_int(global.parameters, "rules.alliances", 0) != 0) {
if (config_get_int("rules.alliances", 0) != 0) {
if (f->alliance && f->alliance == fa->alliance) {
warn = 1;
}
@ -757,7 +751,7 @@ void nmr_warnings(void)
if (msg == NULL) {
msg =
msg_message("warn_dropout", "faction turns", f,
turn - f->lastorders);
turn - f->lastorders);
}
add_message(&fa->msgs, msg);
}
@ -791,12 +785,7 @@ void demographics(void)
/* die Nachfrage nach Produkten steigt. */
struct demand *dmd;
if (r->land) {
static int plant_rules = -1;
if (plant_rules < 0) {
plant_rules =
get_param_int(global.parameters, "rules.grow.formula", 0);
}
int plant_rules = config_get_int("rules.grow.formula", 0);
for (dmd = r->land->demands; dmd; dmd = dmd->next) {
if (dmd->value > 0 && dmd->value < MAXDEMAND) {
float rise = DMRISE;
@ -994,11 +983,7 @@ static int mayboard(const unit * u, ship * sh)
static bool CheckOverload(void)
{
static int value = -1;
if (value < 0) {
value = get_param_int(global.parameters, "rules.check_overload", 0);
}
return value != 0;
return config_get_int("rules.check_overload", 0) != 0;
}
int enter_ship(unit * u, struct order *ord, int id, bool report)
@ -1215,9 +1200,7 @@ int *age = NULL;
static void nmr_death(faction * f)
{
static int rule = -1;
if (rule < 0)
rule = get_param_int(global.parameters, "rules.nmr.destroy", 0);
int rule = config_get_int("rules.nmr.destroy", 0) != 0;
if (rule) {
unit *u;
for (u = f->units; u; u = u->nextF) {
@ -1317,7 +1300,7 @@ int ally_cmd(unit * u, struct order *ord)
if (!s || !s[0]) {
keyword = P_ANY;
}
}
else {
keyword = findparam(s, u->faction->locale);
}
@ -1498,9 +1481,9 @@ int prefix_cmd(unit * u, struct order *ord)
if (fval(u, UFL_GROUP)) {
attrib *a = a_find(u->attribs, &at_group);
if (a) {
group *g = (group *)a->data.v;
group *g = (group *)a->data.v;
ap = &g->attribs;
}
}
}
set_prefix(ap, race_prefixes[var.i]);
}
@ -1926,7 +1909,7 @@ deliverMail(faction * f, region * r, unit * u, const char *s, unit * receiver)
else { /* BOTSCHAFT an EINHEIT */
ADDMSG(&f->msgs,
msg_message("unitmessage", "region unit sender string", r,
receiver, u, s));
receiver, u, s));
}
}
@ -2310,7 +2293,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
/* hp_p : Trefferpunkte */
bytes =
slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(f->locale,
"stat_hitpoints"));
"stat_hitpoints"));
assert(bytes <= INT_MAX);
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
@ -2318,7 +2301,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
/* b_attacke : Angriff */
bytes =
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_attack"),
(rc->at_default + rc->at_bonus));
(rc->at_default + rc->at_bonus));
assert(bytes <= INT_MAX);
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
@ -2326,7 +2309,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
/* b_defense : Verteidigung */
bytes =
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_defense"),
(rc->df_default + rc->df_bonus));
(rc->df_default + rc->df_bonus));
assert(bytes <= INT_MAX);
if (wrptr(&bufp, &size, (int)bytes) != 0)
WARN_STATIC_BUFFER();
@ -2385,12 +2368,12 @@ static bool display_race(faction * f, unit * u, const race * rc)
case AT_STANDARD:
bytes =
(size_t)_snprintf(bufp, size, "%s (%s)",
LOC(f->locale, "attack_standard"), rc->def_damage);
LOC(f->locale, "attack_standard"), rc->def_damage);
break;
case AT_NATURAL:
bytes =
(size_t)_snprintf(bufp, size, "%s (%s)",
LOC(f->locale, "attack_natural"), rc->attack[a].data.dice);
LOC(f->locale, "attack_natural"), rc->attack[a].data.dice);
break;
case AT_SPELL:
case AT_COMBATSPELL:
@ -2402,7 +2385,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
case AT_STRUCTURAL:
bytes =
(size_t)_snprintf(bufp, size, "%s (%s)",
LOC(f->locale, "attack_structural"), rc->attack[a].data.dice);
LOC(f->locale, "attack_structural"), rc->attack[a].data.dice);
break;
default:
bytes = 0;
@ -2506,7 +2489,7 @@ int promotion_cmd(unit * u, struct order *ord)
if (maxheroes(u->faction) < countheroes(u->faction) + u->number) {
ADDMSG(&u->faction->msgs,
msg_feedback(u, ord, "heroes_maxed", "max count",
maxheroes(u->faction), countheroes(u->faction)));
maxheroes(u->faction), countheroes(u->faction)));
return 0;
}
if (!valid_race(u->faction, u_race(u))) {
@ -2748,14 +2731,13 @@ void sinkships(struct region * r)
if (fval(r->terrain, SEA_REGION)) {
if (!enoughsailors(sh, crew_skill(sh))) {
// ship is at sea, but not enough people to control it
double dmg = get_param_flt(global.parameters,
"rules.ship.damage.nocrewocean",
0.30F);
double dmg = config_get_flt("rules.ship.damage.nocrewocean", 0.3);
damage_ship(sh, dmg);
}
} else if (!ship_owner(sh)) {
}
else if (!ship_owner(sh)) {
// any ship lying around without an owner slowly rots
double dmg = get_param_flt(global.parameters, "rules.ship.damage.nocrew", 0.05F);
double dmg = config_get_flt("rules.ship.damage.nocrew", 0.05);
damage_ship(sh, dmg);
}
}
@ -3288,14 +3270,14 @@ void new_units(void)
if (err == 1) {
ADDMSG(&u->faction->msgs,
msg_feedback(u, makeord,
"too_many_units_in_alliance",
"allowed", maxunits(u->faction)));
"too_many_units_in_alliance",
"allowed", maxunits(u->faction)));
}
else {
ADDMSG(&u->faction->msgs,
msg_feedback(u, makeord,
"too_many_units_in_faction",
"allowed", maxunits(u->faction)));
"too_many_units_in_faction",
"allowed", maxunits(u->faction)));
}
ordp = &makeord->next;
@ -3368,7 +3350,7 @@ void update_long_order(unit * u)
}
// hungry units do not get long orders:
if (hunger) {
if (hunger) {
if (u->old_orders) {
// keep looking for repeated orders that might clear the old_orders
continue;
@ -3440,7 +3422,8 @@ void update_long_order(unit * u)
if (hunger) {
// Hungernde Einheiten führen NUR den default-Befehl aus
set_order(&u->thisorder, default_order(u->faction->locale));
} else if (!exclusive) {
}
else if (!exclusive) {
// Wenn die Einheit handelt oder zaubert, muss der Default-Befehl gelöscht werden.
set_order(&u->thisorder, NULL);
}
@ -3467,7 +3450,7 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order
return EUNUSABLE;
}
result = itype->use ? itype->use(u, itype, amount, ord) : EUNUSABLE;
if (result>0) {
if (result > 0) {
use_pooled(u, itype->rtype, GET_DEFAULT, result);
}
return result;
@ -3482,7 +3465,8 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order
static double heal_factor(const unit * u)
{
static double elf_regen = -1;
double elf_regen;
switch (old_race(u_race(u))) {
case RC_TROLL:
case RC_DAEMON:
@ -3490,8 +3474,7 @@ static double heal_factor(const unit * u)
case RC_GOBLIN:
return 2.0;
case RC_ELF:
if (elf_regen < 0)
elf_regen = get_param_flt(u_race(u)->parameters, "regen.forest", 1.0F);
elf_regen = get_param_flt(u_race(u)->parameters, "regen.forest", 1.0F);
if (elf_regen != 1.0 && r_isforest(u->region)) {
return elf_regen;
}
@ -4266,7 +4249,7 @@ static void do_force_leave(region *r) {
}
bool rule_force_leave(int flags) {
int rules = get_param_int(global.parameters, "rules.owners.force_leave", 0);
int rules = config_get_int("rules.owners.force_leave", 0);
return (rules&flags) == flags;
}
@ -4337,7 +4320,7 @@ void init_processor(void)
add_proc_order(p, K_GUARD, guard_off_cmd, 0, NULL);
add_proc_order(p, K_RESHOW, reshow_cmd, 0, NULL);
if (get_param_int(global.parameters, "rules.alliances", 0) == 1) {
if (config_get_int("rules.alliances", 0) == 1) {
p += 10;
add_proc_global(p, alliance_cmd, NULL);
}
@ -4360,7 +4343,7 @@ void init_processor(void)
add_proc_region(p, enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */
p += 10;
add_proc_region(p, do_battle, "Attackieren");
add_proc_global(p, do_battles, "Attackieren");
if (!keyword_disabled(K_BESIEGE)) {
p += 10;
@ -4369,7 +4352,7 @@ void init_processor(void)
p += 10; /* can't allow reserve before siege (weapons) */
add_proc_region(p, enter_1, "Betreten (3. Versuch)"); /* to claim a castle after a victory and to be able to DESTROY it in the same turn */
if (get_param_int(global.parameters, "rules.reserve.twophase", 0)) {
if (config_get_int("rules.reserve.twophase", 0)) {
add_proc_order(p, K_RESERVE, reserve_self, 0, "RESERVE (self)");
p += 10;
}
@ -4421,7 +4404,7 @@ void init_processor(void)
p += 10;
add_proc_global(p, movement, "Bewegungen");
if (get_param_int(global.parameters, "work.auto", 0)) {
if (config_get_int("work.auto", 0)) {
p += 10;
add_proc_region(p, auto_work, "Arbeiten (auto)");
}
@ -4429,7 +4412,7 @@ void init_processor(void)
p += 10;
add_proc_order(p, K_GUARD, guard_on_cmd, 0, "Bewache (an)");
if (get_param_int(global.parameters, "rules.encounters", 0)) {
if (config_get_int("rules.encounters", 0)) {
p += 10;
add_proc_global(p, encounters, "Zufallsbegegnungen");
}
@ -4467,7 +4450,7 @@ void processorders(void)
process();
/*************************************************/
if (get_param_int(global.parameters, "modules.markets", 0)) {
if (config_get_int("modules.markets", 0)) {
do_markets();
}
@ -4476,7 +4459,7 @@ void processorders(void)
remove_empty_units();
/* must happen AFTER age, because that would destroy them right away */
if (get_param_int(global.parameters, "modules.wormholes", 0)) {
if (config_get_int("modules.wormholes", 0)) {
wormholes_update();
}
@ -4551,7 +4534,7 @@ void update_subscriptions(void)
bool
cansee(const faction * f, const region * r, const unit * u, int modifier)
/* r kann != u->region sein, wenn es um Durchreisen geht,
/* r kann != u->region sein, wenn es um Durchreisen geht,
* oder Zauber (sp_generous, sp_fetchastral).
* Es muss auch niemand aus f in der region sein, wenn sie vom Turm
* erblickt wird */
@ -4653,10 +4636,10 @@ bool cansee_unit(const unit * u, const unit * target, int modifier)
bool
cansee_durchgezogen(const faction * f, const region * r, const unit * u,
int modifier)
/* r kann != u->region sein, wenn es um durchreisen geht */
/* und es muss niemand aus f in der region sein, wenn sie vom Turm
* erblickt wird */
int modifier)
/* r kann != u->region sein, wenn es um durchreisen geht */
/* und es muss niemand aus f in der region sein, wenn sie vom Turm
* erblickt wird */
{
int n;
unit *u2;

View file

@ -233,16 +233,16 @@ static void test_display_cmd(CuTest *tc) {
}
static void test_rule_force_leave(CuTest *tc) {
set_param(&global.parameters, "rules.owners.force_leave", "0");
config_set("rules.owners.force_leave", "0");
CuAssertIntEquals(tc, false, rule_force_leave(FORCE_LEAVE_ALL));
CuAssertIntEquals(tc, false, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
set_param(&global.parameters, "rules.owners.force_leave", "1");
config_set("rules.owners.force_leave", "1");
CuAssertIntEquals(tc, false, rule_force_leave(FORCE_LEAVE_ALL));
CuAssertIntEquals(tc, true, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
set_param(&global.parameters, "rules.owners.force_leave", "2");
config_set("rules.owners.force_leave", "2");
CuAssertIntEquals(tc, true, rule_force_leave(FORCE_LEAVE_ALL));
CuAssertIntEquals(tc, false, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
set_param(&global.parameters, "rules.owners.force_leave", "3");
config_set("rules.owners.force_leave", "3");
CuAssertIntEquals(tc, true, rule_force_leave(FORCE_LEAVE_ALL));
CuAssertIntEquals(tc, true, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
}
@ -413,13 +413,13 @@ static void test_fishing_gets_reset(CuTest * tc)
static void test_unit_limit(CuTest * tc)
{
set_param(&global.parameters, "rules.limit.faction", "250");
config_set("rules.limit.faction", "250");
CuAssertIntEquals(tc, 250, rule_faction_limit());
set_param(&global.parameters, "rules.limit.faction", "200");
config_set("rules.limit.faction", "200");
CuAssertIntEquals(tc, 200, rule_faction_limit());
set_param(&global.parameters, "rules.limit.alliance", "250");
config_set("rules.limit.alliance", "250");
CuAssertIntEquals(tc, 250, rule_alliance_limit());
}
@ -432,12 +432,12 @@ static void test_cannot_create_unit_above_limit(CuTest * tc)
test_cleanup();
test_create_world();
f = test_create_faction(NULL);
set_param(&global.parameters, "rules.limit.faction", "4");
config_set("rules.limit.faction", "4");
CuAssertIntEquals(tc, 0, checkunitnumber(f, 4));
CuAssertIntEquals(tc, 2, checkunitnumber(f, 5));
set_param(&global.parameters, "rules.limit.alliance", "3");
config_set("rules.limit.alliance", "3");
CuAssertIntEquals(tc, 0, checkunitnumber(f, 3));
CuAssertIntEquals(tc, 1, checkunitnumber(f, 4));
}
@ -533,8 +533,8 @@ static void test_pay_cmd_other_building(CuTest *tc) {
setup_pay_cmd(&fix);
f = fix.u1->faction;
b = test_create_building(fix.u1->region, bt_get_or_create("lighthouse"));
set_param(&global.parameters, "rules.region_owners", "1");
set_param(&global.parameters, "rules.region_owner_pay_building", "lighthouse");
config_set("rules.region_owners", "1");
config_set("rules.region_owner_pay_building", "lighthouse");
update_owners(b->region);
_snprintf(cmd, sizeof(cmd), "NOT %s", itoa36(b->no));
@ -633,7 +633,7 @@ static void test_newbie_cannot_guard(CuTest *tc) {
guard_fixture fix;
setup_guard(&fix, true);
set_param(&global.parameters, "NewbieImmunity", "4");
config_set("NewbieImmunity", "4");
CuAssertTrue(tc, IsImmune(fix.u->faction));
update_guards();
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
@ -726,15 +726,15 @@ static void statistic_test(CuTest *tc, int peasants, int luck, int maxp,
static void test_peasant_luck_effect(CuTest *tc) {
test_cleanup();
set_param(&global.parameters, "rules.peasants.peasantluck.factor", "10");
set_param(&global.parameters, "rules.peasants.growth.factor", "0.001");
config_set("rules.peasants.peasantluck.factor", "10");
config_set("rules.peasants.growth.factor", "0.001");
statistic_test(tc, 100, 0, 1000, 0, 0, 0);
statistic_test(tc, 100, 2, 1000, 0, 1, 1);
statistic_test(tc, 1000, 400, 1000, 0, 3, 3);
statistic_test(tc, 1000, 1000, 2000, .5, 1, 501);
set_param(&global.parameters, "rules.peasants.growth.factor", "1");
config_set("rules.peasants.growth.factor", "1");
statistic_test(tc, 1000, 1000, 1000, 0, 501, 501);
test_cleanup();
}
@ -1003,7 +1003,7 @@ static void test_long_order_hungry(CuTest *tc) {
// see also default_order
unit *u;
test_cleanup();
set_param(&global.parameters, "hunger.long", "1");
config_set("hunger.long", "1");
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
fset(u, UFL_HUNGER);
u->faction->locale = get_or_create_locale("de");
@ -1081,7 +1081,7 @@ static void test_ally_cmd(CuTest *tc) {
static void test_nmr_warnings(CuTest *tc) {
faction *f1, *f2;
test_cleanup();
set_param(&global.parameters, "nmr.timeout", "3");
config_set("nmr.timeout", "3");
f1 = test_create_faction(0);
f2 = test_create_faction(0);
f2->age = 2;

View file

@ -108,20 +108,15 @@ attrib_type at_reportspell = {
** TODO: separate castle-appearance from illusion-effects
**/
static float MagicRegeneration(void)
static double MagicRegeneration(void)
{
static float value = -1.0;
if (value < 0) {
const char *str = get_param(global.parameters, "magic.regeneration");
value = str ? (float)atof(str) : 1.0F;
}
return value;
return config_get_flt("magic.regeneration", 1.0);
}
static double MagicPower(double force)
{
if (force > 0) {
const char *str = get_param(global.parameters, "magic.power");
const char *str = config_get("magic.power");
double value = str ? atof(str) : 1.0;
return _max(value * force, 1.0f);
}
@ -215,16 +210,11 @@ static void free_mage(attrib * a)
bool FactionSpells(void)
{
static int rules_factionspells = -1;
if (rules_factionspells < 0) {
rules_factionspells =
get_param_int(global.parameters, "rules.magic.factionlist", 0);
}
return rules_factionspells!=0;
return config_get_int("rules.magic.factionlist", 0) != 0;
}
void read_spells(struct quicklist **slistp, magic_t mtype,
struct storage *store)
void read_spells(struct quicklist **slistp, magic_t mtype,
struct storage *store)
{
for (;;) {
spell *sp;
@ -1034,7 +1024,7 @@ spellpower(region * r, unit * u, const spell * sp, int cast_level, struct order
if (btype && btype->flags & BTF_MAGIC) ++force;
}
elf_power = get_param_int(global.parameters, "rules.magic.elfpower", 0);
elf_power = config_get_int("rules.magic.elfpower", 0);
if (elf_power && u_race(u) == get_race(RC_ELF) && r_isforest(r)) {
++force;
@ -1291,7 +1281,7 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade)
int effsk = effskill(u, SK_MAGIC, r);
struct building *b = inside_building(u);
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
int fumble_enabled = get_param_int(global.parameters, "magic.fumble.enable", 1);
int fumble_enabled = config_get_int("magic.fumble.enable", 1);
sc_mage * mage;
if (effsk<=0 || !fumble_enabled) {
@ -1463,7 +1453,7 @@ void regenerate_aura(void)
double reg_aura;
int regen;
double mod;
int regen_enabled = get_param_int(global.parameters, "magic.regeneration.enable", 1);
int regen_enabled = config_get_int("magic.regeneration.enable", 1);
if (!regen_enabled) return;

View file

@ -162,7 +162,7 @@ static int parse_args(int argc, char **argv, int *exitcode)
switch (argi[1]) {
case 'r':
i = get_arg(argc, argv, 2, i, &arg, 0);
set_param(&global.parameters, "config.rules", arg);
config_set("config.rules", arg);
break;
case 'f':
i = get_arg(argc, argv, 2, i, &luafile, 0);

View file

@ -43,7 +43,7 @@ static void test_market_curse(CuTest * tc)
ltype->rtype->flags |= (RTF_ITEM | RTF_POOLED);
lux = new_luxurytype(ltype, 0);
set_param(&global.parameters, "rules.region_owners", "1");
config_set("rules.region_owners", "1");
btype = (building_type *)calloc(1, sizeof(building_type));
btype->_name = _strdup("market");

View file

@ -222,7 +222,7 @@ faction *get_or_create_monsters(void)
faction *f = findfaction(MONSTER_ID);
if (!f) {
const race *rc = rc_get_or_create("dragon");
const char *email = get_param(global.parameters, "monster.email");
const char *email = config_get("monster.email");
f = addfaction(email ? email : "noreply@eressea.de", NULL, rc, default_locale, 0);
renumber_faction(f, MONSTER_ID);
faction_setname(f, "Monster");

View file

@ -82,7 +82,7 @@ static void give_peasants(unit *u, const item_type *itype, int reduce) {
}
static double monster_attack_chance(void) {
return get_param_flt(global.parameters, "rules.monsters.attack_chance", 0.4f);
return config_get_flt("rules.monsters.attack_chance", 0.4);
}
static void reduce_weight(unit * u)
@ -685,14 +685,13 @@ static order *plan_dragon(unit * u)
/* dragon gets bored and looks for a different place to go */
ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
}
else
ta = a_find(u->attribs, &at_targetregion);
if (ta != NULL) {
tr = (region *)ta->data.v;
if (tr == NULL || !path_exists(u->region, tr, DRAGON_RANGE, allowed_dragon)) {
ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
if (ta)
if (ta) {
tr = findregion(ta->data.sa[0], ta->data.sa[1]);
}
}
}
if (tr != NULL) {

View file

@ -81,6 +81,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <string.h>
#include <limits.h>
/* Bewegungsweiten: */
#define BP_WALKING 4
#define BP_RIDING 6
#define BP_UNICORN 9
#define BP_DRAGON 4
#define BP_NORMAL 3
#define BP_ROAD 2
int *storms;
typedef struct traveldir {
@ -319,7 +327,7 @@ int walkingcapacity(const struct unit *u)
if (rbelt) {
int belts = i_get(u->items, rbelt->itype);
if (belts) {
int multi = get_param_int(global.parameters, "rules.trollbelt.multiplier", STRENGTHMULTIPLIER);
int multi = config_get_int("rules.trollbelt.multiplier", STRENGTHMULTIPLIER);
n += _min(people, belts) * (multi - 1) * u_race(u)->capacity;
}
}
@ -692,17 +700,13 @@ static void set_coast(ship * sh, region * r, region * rnext)
static float damage_drift(void)
{
static float value = -1.0F;
if (value < 0) {
value = (float)get_param_flt(global.parameters, "rules.ship.damage_drift", 0.02F);
}
return value;
return (float)config_get_flt("rules.ship.damage_drift", 0.02);
}
static void drifting_ships(region * r)
{
direction_t d;
bool drift = get_param_int(global.parameters, "rules.ship.drifting", 1) != 0;
bool drift = config_get_int("rules.ship.drifting", 1) != 0;
if (fval(r->terrain, SEA_REGION)) {
ship **shp = &r->ships;
@ -837,24 +841,14 @@ static unit *bewegung_blockiert_von(unit * reisender, region * r)
unit *guard = NULL;
int guard_count = 0;
int stealth = eff_stealth(reisender, r);
static int gamecookie = -1;
static double base_prob = -999;
static double skill_prob = -999;
static double amulet_prob = -999;
static double guard_number_prob = -999;
static double castle_prob = -999;
static double region_type_prob = -999;
const struct resource_type *ramulet = get_resourcetype(R_AMULET_OF_TRUE_SEEING);
if (gamecookie < 0 || gamecookie != global.cookie) {
base_prob = get_param_flt(global.parameters, "rules.guard.base_stop_prob", .3f);
skill_prob = get_param_flt(global.parameters, "rules.guard.skill_stop_prob", .1f);
amulet_prob = get_param_flt(global.parameters, "rules.guard.amulet_stop_prob", .1f);
guard_number_prob = get_param_flt(global.parameters, "rules.guard.guard_number_stop_prob", .001f);
castle_prob = get_param_flt(global.parameters, "rules.guard.castle_stop_prob", .1f);
region_type_prob = get_param_flt(global.parameters, "rules.guard.region_type_stop_prob", .1f);
gamecookie = global.cookie;
}
double base_prob = config_get_flt("rules.guard.base_stop_prob", .3);
double skill_prob = config_get_flt("rules.guard.skill_stop_prob", .1);
double amulet_prob = config_get_flt("rules.guard.amulet_stop_prob", .1);
double guard_number_prob = config_get_flt("rules.guard.guard_number_stop_prob", .001);
double castle_prob = config_get_flt("rules.guard.castle_stop_prob", .1);
double region_type_prob = config_get_flt("rules.guard.region_type_stop_prob", .1);
if (fval(u_race(reisender), RCF_ILLUSIONARY))
return NULL;
@ -948,77 +942,28 @@ bool is_guard(const struct unit * u, unsigned int mask)
return is_guardian_r(u) && (getguard(u) & mask) != 0;
}
#define MAXGUARDCACHE 16
/** returns the guard which prevents 'u' from doing 'mask' actions in 'r'.
*/
unit *is_guarded(region * r, unit * u, unsigned int mask)
{
unit *u2 = NULL;
int i, noguards = 1;
static unit *guardcache[MAXGUARDCACHE], *lastguard; /* STATIC_XCALL: used across calls */
static int gamecookie = -1;
unit *u2;
int noguards = 1;
if (!fval(r, RF_GUARDED)) {
return NULL;
}
if (gamecookie != global.cookie) {
if (gamecookie >= 0) {
/* clear the previous turn's cache */
memset(guardcache, 0, sizeof(guardcache));
lastguard = NULL;
}
gamecookie = global.cookie;
}
if (lastguard && lastguard->region == r) {
if (is_guardian_u(lastguard, u, mask)) {
return lastguard;
}
}
for (i = 0; i != MAXGUARDCACHE; ++i) {
unit *guard = guardcache[i];
if (guard && guard != lastguard && guard->region == r) {
noguards = 0;
if (is_guardian_u(guard, u, mask)) {
lastguard = guard;
return guard;
}
if (u2 == guard) {
/* same guard twice signals we've tested everyone */
return NULL;
}
u2 = guard;
}
else {
/* exhausted all the guards in the cache, but maybe we'll find one later? */
break;
}
}
/* at this point, u2 is the last unit we tested to
* be a guard (and failed), or NULL
* i is the position of the first free slot in the cache */
for (u2 = (u2 ? u2->next : r->units); u2; u2 = u2->next) {
for (u2 = r->units; u2; u2 = u2->next) {
if (is_guardian_r(u2)) {
noguards = 0;
/* u2 is a guard, so worth remembering */
if (i < MAXGUARDCACHE)
guardcache[i++] = u2;
if (is_guardian_u(u2, u, mask)) {
/* u2 is our guard. stop processing (we might have to go further next time) */
lastguard = u2;
return u2;
}
}
}
/* there are no more guards. we signal this by duplicating the last one.
* i is still the position of the first free slot in the cache */
if (i > 0 && i < MAXGUARDCACHE) {
guardcache[i] = guardcache[i - 1];
}
if (noguards) {
/* you are mistaken, sir. there are no guards in these lands */
@ -1844,7 +1789,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
if (!flying_ship(sh)) {
int stormchance = 0;
int reason;
bool storms_enabled = get_param_int(global.parameters, "rules.ship.storms", 1) != 0;
bool storms_enabled = config_get_int("rules.ship.storms", 1) != 0;
if (storms_enabled) {
int stormyness;
gamedate date;
@ -1854,7 +1799,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
/* storms should be the first thing we do. */
stormchance = stormyness / shipspeed(sh, u);
if (check_leuchtturm(next_point, NULL)) {
int param = get_param_int(global.parameters, "rules.lighthous.stormchancedevisor", 0);
int param = config_get_int("rules.lighthous.stormchancedevisor", 0);
if (param > 0) {
stormchance /= param;
}
@ -1944,9 +1889,7 @@ sail(unit * u, order * ord, bool move_on_land, region_list ** routep)
ADDMSG(&f->msgs, msg_message("sailnolandingstorm", "ship region", sh, next_point));
}
else {
double dmg =
get_param_flt(global.parameters, "rules.ship.damage.nolanding",
0.10F);
double dmg = config_get_flt("rules.ship.damage.nolanding", 0.1);
ADDMSG(&f->msgs, msg_message("sailnolanding", "ship region", sh,
next_point));
damage_ship(sh, dmg);

View file

@ -217,7 +217,7 @@ static void test_walkingcapacity(CuTest *tc) {
assert(itype);
i_change(&u->items, itype, 1);
CuAssertIntEquals(tc, cap + (STRENGTHMULTIPLIER-1) * u->_race->capacity, walkingcapacity(u));
set_param(&global.parameters, "rules.trollbelt.multiplier", "5");
config_set("rules.trollbelt.multiplier", "5");
CuAssertIntEquals(tc, cap + 4 * u->_race->capacity, walkingcapacity(u));
test_cleanup();

View file

@ -21,7 +21,7 @@ static void setup_piracy(void) {
ship_type *st_boat;
test_cleanup();
set_param(&global.parameters, "rules.ship.storms", "0");
config_set("rules.ship.storms", "0");
lang = get_or_create_locale("de");
locale_setstring(lang, directions[D_EAST], "OSTEN");
init_directions(lang);

View file

@ -738,9 +738,7 @@ static void move_iceberg(region * r)
for (sh = r->ships; sh; sh = sh->next) {
/* Meldung an Kapitän */
double dmg =
get_param_flt(global.parameters, "rules.ship.damage.intoiceberg",
0.10F);
double dmg = config_get_flt("rules.ship.damage.intoiceberg", 0.1);
damage_ship(sh, dmg);
fset(sh, SF_SELECT);
}
@ -751,9 +749,7 @@ static void move_iceberg(region * r)
translist(&rc->buildings, &r->buildings, rc->buildings);
}
while (rc->ships) {
double dmg =
get_param_flt(global.parameters, "rules.ship.damage.withiceberg",
0.10F);
double dmg = config_get_flt("rules.ship.damage.withiceberg", 0.1);
fset(rc->ships, SF_SELECT);
damage_ship(rc->ships, dmg);
move_ship(rc->ships, rc, r, NULL);
@ -885,9 +881,7 @@ static void godcurse(void)
ship *sh;
for (sh = r->ships; sh;) {
ship *shn = sh->next;
double dmg =
get_param_flt(global.parameters, "rules.ship.damage.godcurse",
0.10F);
double dmg = config_get_flt("rules.ship.damage.godcurse", 0.1);
damage_ship(sh, dmg);
if (sh->damage >= sh->size * DAMAGE_SCALE) {
unit *u = ship_owner(sh);
@ -968,11 +962,7 @@ static void demon_skillchanges(void)
if (fval(u, UFL_HUNGER)) {
/* hungry demons only go down, never up in skill */
static int rule_hunger = -1;
if (rule_hunger < 0) {
rule_hunger =
get_param_int(global.parameters, "hunger.demon.skill", 0);
}
int rule_hunger = config_get_int("hunger.demon.skill", 0) != 0;
if (rule_hunger) {
upchance = 0;
downchance = 15;
@ -1016,16 +1006,13 @@ static void icebergs(void)
}
}
#define HERBS_ROT /* herbs owned by units have a chance to rot. */
#define HERBROTCHANCE 5 /* Verrottchance für Kräuter (ifdef HERBS_ROT) */
#ifdef HERBS_ROT
static void rotting_herbs(void)
{
static int rule_rot = -1;
region *r;
if (rule_rot < 0) {
rule_rot =
get_param_int(global.parameters, "rules.economy.herbrot", HERBROTCHANCE);
}
int rule_rot = config_get_int("rules.economy.herbrot", HERBROTCHANCE);
if (rule_rot == 0) return;
for (r = regions; r; r = r->next) {

View file

@ -2054,19 +2054,14 @@ const char *charset)
char *bufp;
bool utf8 = _strcmpl(charset, "utf8") == 0 || _strcmpl(charset, "utf-8") == 0;
size_t size;
/* static variables can cope with writing for different turns */
static int thisseason = -1;
static int nextseason = -1;
static int gamecookie = -1;
if (gamecookie != global.cookie) {
gamedate date;
get_gamedate(turn + 1, &date);
thisseason = date.season;
get_gamedate(turn + 2, &date);
nextseason = date.season;
gamecookie = global.cookie;
}
int thisseason;
int nextseason;
gamedate date;
get_gamedate(turn + 1, &date);
thisseason = date.season;
get_gamedate(turn + 2, &date);
nextseason = date.season;
if (F == NULL) {
perror(filename);

View file

@ -1397,7 +1397,7 @@ static void prepare_reports(void)
}
/* Region owner get always the Lighthouse report */
if (bt_lighthouse && check_param(global.parameters, "rules.region_owner_pay_building", bt_lighthouse->_name)) {
if (bt_lighthouse && config_token("rules.region_owner_pay_building", bt_lighthouse->_name)) {
for (b = rbuildings(r); b; b = b->next) {
if (b && b->type == bt_lighthouse) {
u = building_owner(b);
@ -1547,6 +1547,7 @@ static void mkreportdir(const char *rpath) {
abort();
}
}
errno = 0;
}
int write_reports(faction * f, time_t ltime)
@ -1563,11 +1564,7 @@ int write_reports(faction * f, time_t ltime)
}
prepare_report(&ctx, f);
get_addresses(&ctx);
mkreportdir(path);
if (errno) {
log_warning("errno was %d before writing reports", errno);
errno = 0;
}
mkreportdir(path); // FIXME: too many mkdir calls! init_reports is enough
log_debug("Reports for %s:", factionname(f));
for (rtype = report_types; rtype != NULL; rtype = rtype->next) {
if (f->options & rtype->flag) {
@ -1662,7 +1659,7 @@ int reports(void)
report_donations();
remove_empty_units();
mkreportdir(rpath);
mkreportdir(rpath); // FIXME: init_reports already does this?
sprintf(path, "%s/reports.txt", rpath);
mailit = fopen(path, "w");
if (mailit == NULL) {
@ -1681,7 +1678,7 @@ int reports(void)
free_seen();
#ifdef GLOBAL_REPORT
{
const char *str = get_param(global.parameters, "globalreport");
const char *str = config_get("globalreport");
if (str != NULL) {
sprintf(path, "%s/%s.%u.cr", reportpath(), str, turn);
global_report(path);

View file

@ -26,7 +26,6 @@
/* Vermehrungsrate Bauern in 1/10000.
* TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen höher. */
#define PEASANTGROWTH 10
#define BATTLE_KILLS_PEASANTS 20
#define PEASANTLUCK 10
#define ROW_FACTOR 3 /* factor for combat row advancement rule */
@ -39,3 +38,25 @@
#define ARENA_MODULE 1
#undef REGIONOWNERS /* (WIP) region-owner uses HELP_TRAVEL to control entry to region */
/* experimental gameplay features (that don't affect the savefile) */
/* TODO: move these settings to settings.h or into configuration files */
#define GOBLINKILL /* Goblin-Spezialklau kann tödlich enden */
#define INSECT_POTION /* Spezialtrank für Insekten */
#define ORCIFICATION /* giving snotlings to the peasants gets counted */
#define TREESIZE (8) /* space used by trees (in #peasants) */
#define PEASANTFORCE 0.75 /* Chance einer Vermehrung trotz 90% Auslastung */
/* Gebäudegröße = Minimalbelagerer */
#define SIEGEFACTOR 2
/** Magic */
#define MAXMAGICIANS 3
#define MAXALCHEMISTS 3
#define ENCCHANCE 10 /* %-Chance für einmalige Zufallsbegegnung */
#define BAGCAPACITY 20000 /* soviel paßt in einen Bag of Holding */
#define PERSON_WEIGHT 1000 /* weight of a "normal" human unit */
#define STAMINA_AFFECTS_HP 1<<0

View file

@ -1,10 +1,10 @@
$#undef tolua_reg_types
$#define tolua_reg_types tolua_reg_types_config
$#include "bind_settings.h"
$#include <kernel/config.h>
module eressea {
module settings {
void settings_set @ set(const char *key, const char *value);
const char * settings_get @ get(const char *key);
void config_set @ set(const char *key, const char *value);
const char * config_get @ get(const char *key);
}
}

View file

@ -20,7 +20,7 @@ LUALIB_API int luaopen_settings (lua_State* tolua_S);
#undef tolua_reg_types
#define tolua_reg_types tolua_reg_types_settings
#include "bind_settings.h"
#include <kernel/config.h>
/* function to register type */
static void tolua_reg_types (lua_State* tolua_S)
@ -44,7 +44,7 @@ static int tolua_settings_eressea_settings_set00(lua_State* tolua_S)
const char* key = ((const char*) tolua_tostring(tolua_S,1,0));
const char* value = ((const char*) tolua_tostring(tolua_S,2,0));
{
settings_set(key,value);
config_set(key,value);
}
}
return 0;
@ -70,7 +70,7 @@ static int tolua_settings_eressea_settings_get00(lua_State* tolua_S)
{
const char* key = ((const char*) tolua_tostring(tolua_S,1,0));
{
const char* tolua_ret = (const char*) settings_get(key);
const char* tolua_ret = (const char*) config_get(key);
tolua_pushstring(tolua_S,(const char*)tolua_ret);
}
}

View file

@ -121,7 +121,7 @@ int study_cost(unit * u, skill_t sk)
if (cost[sk] == 0) {
char buffer[256];
sprintf(buffer, "skills.cost.%s", skillnames[sk]);
cost[sk] = get_param_int(global.parameters, buffer, -1);
cost[sk] = config_get_int(buffer, -1);
}
if (cost[sk] >= 0) {
return cost[sk];
@ -184,7 +184,7 @@ static building *active_building(const unit *u, const struct building_type *btyp
static int
teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
bool report, int *academy)
bool report, int *academy)
{
teaching_info *teach = NULL;
attrib *a;
@ -343,7 +343,8 @@ int teach_cmd(unit * u, struct order *ord)
for (student = r->units; teaching && student; student = student->next) {
if (LongHunger(student)) {
continue;
} else if (student->faction == u->faction) {
}
else if (student->faction == u->faction) {
if (getkeyword(student->thisorder) == K_STUDY) {
/* Input ist nun von student->thisorder !! */
init_order(student->thisorder);
@ -509,7 +510,7 @@ static double study_speedup(unit * u, skill_t s, study_rule_t rule)
if (rule == STUDY_FASTER) {
for (i = 0; i != u->skill_size; ++i) {
skill *sv = u->skills + i;
if (sv->id == s){
if (sv->id == s) {
learnweeks = sv->level * (sv->level + 1) / 2.0;
if (learnweeks < turn / 3.0) {
return 2.0;
@ -534,7 +535,7 @@ static double study_speedup(unit * u, skill_t s, study_rule_t rule)
int study_cmd(unit * u, order * ord)
{
region *r = u->region;
int p;
int p, cap;
magic_t mtyp;
int l;
int studycost, days;
@ -544,18 +545,11 @@ int study_cmd(unit * u, order * ord)
int money = 0;
skill_t sk;
int maxalchemy = 0;
int speed_rule = (study_rule_t)get_param_int(global.parameters, "study.speedup", 0);
static int learn_newskills = -1;
int speed_rule = (study_rule_t)config_get_int("study.speedup", 0);
struct building *b = inside_building(u);
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
bool learn_newskills = config_get_int("study.newskills", 1) != 0;
if (learn_newskills < 0) {
const char *str = get_param(global.parameters, "study.newskills");
if (str && strcmp(str, "false") == 0)
learn_newskills = 0;
else
learn_newskills = 1;
}
if (!unit_can_study(u)) {
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_race_nolearn", "race",
u_race(u)));
@ -569,7 +563,8 @@ int study_cmd(unit * u, order * ord)
cmistake(u, ord, 77, MSG_EVENT);
return 0;
}
if (SkillCap(sk) && SkillCap(sk) <= effskill(u, sk, 0)) {
cap = SkillCap(sk);
if (cap > 0 && cap <= effskill(u, sk, 0)) {
cmistake(u, ord, 771, MSG_EVENT);
return 0;
}
@ -578,7 +573,7 @@ int study_cmd(unit * u, order * ord)
cmistake(u, ord, 771, MSG_EVENT);
return 0;
}
if (learn_newskills == 0) {
if (!learn_newskills) {
skill *sv = unit_skill(u, sk);
if (sv == NULL) {
/* we can only learn skills we already have */

View file

@ -27,7 +27,7 @@ static void setup_study(study_fixture *fix, skill_t sk) {
assert(fix);
test_cleanup();
set_param(&global.parameters, "study.random_progress", "0");
config_set("study.random_progress", "0");
test_create_world();
r = test_create_region(0, 0, 0);
f = test_create_faction(0);

View file

@ -78,9 +78,7 @@ void test_cleanup(void)
free_terrains();
free_resources();
global.functions.maintenance = NULL;
global.functions.wage = NULL;
free_params(&global.parameters);
free_config();
default_locale = 0;
close_orders();
free_locales();

View file

@ -24,10 +24,6 @@ int lifestyle(const unit * u)
{
int need;
plane *pl;
static int gamecookie = -1;
if (gamecookie != global.cookie) {
gamecookie = global.cookie;
}
if (is_monsters(u->faction))
return 0;
@ -71,7 +67,7 @@ static bool hunger(int number, unit * u)
static const race *rc = 0;
if (!damage) {
damage = get_param(global.parameters, "hunger.damage");
damage = config_get("hunger.damage");
if (damage == NULL)
damage = "1d12+12";
}
@ -116,13 +112,7 @@ void get_food(region * r)
plane *pl = rplane(r);
unit *u;
int peasantfood = rpeasants(r) * 10;
static int food_rules = -1;
static int gamecookie = -1;
if (food_rules < 0 || gamecookie != global.cookie) {
gamecookie = global.cookie;
food_rules = get_param_int(global.parameters, "rules.food.flags", 0);
}
int food_rules = config_get_int("rules.food.flags", 0);
if (food_rules & FOOD_IS_FREE) {
return;
@ -280,11 +270,8 @@ void get_food(region * r)
peasantfood = 0;
}
if (hungry > 0) {
static int demon_hunger = -1;
if (demon_hunger < 0) {
demon_hunger = get_param_int(global.parameters, "hunger.demons", 0);
}
if (demon_hunger == 0) {
bool demon_hunger = config_get_int("hunger.demons", 0) != 0;
if (demon_hunger) {
/* demons who don't feed are hungry */
if (hunger(hungry, u))
fset(u, UFL_HUNGER);

View file

@ -32,7 +32,7 @@ void test_upkeep_default(CuTest * tc)
u2 = test_create_unit(f2, r);
assert(r && u1 && u2);
set_param(&global.parameters, "rules.food.flags", "0");
config_set("rules.food.flags", "0");
i_change(&u1->items, i_silver, 20);
get_food(r);
// since u1 and u2 are not allied, u1 should not help u2 with upkeep
@ -60,7 +60,7 @@ void test_upkeep_hunger_damage(CuTest * tc)
u1 = test_create_unit(f1, r);
assert(r && u1);
set_param(&global.parameters, "rules.food.flags", "0");
config_set("rules.food.flags", "0");
u1->hp = 100;
get_food(r);
// since u1 and u2 are not allied, u1 should not help u2 with upkeep
@ -86,7 +86,7 @@ void test_upkeep_from_pool(CuTest * tc)
u2 = test_create_unit(u1->faction, r);
assert(r && u1 && u2);
set_param(&global.parameters, "rules.food.flags", "0");
config_set("rules.food.flags", "0");
i_change(&u1->items, i_silver, 30);
get_food(r);
CuAssertIntEquals(tc, 10, i_get(u1->items, i_silver));
@ -122,7 +122,7 @@ void test_upkeep_from_friend(CuTest * tc)
u2 = test_create_unit(f2, r);
assert(r && u1 && u2);
set_param(&global.parameters, "rules.food.flags", "0");
config_set("rules.food.flags", "0");
i_change(&u1->items, i_silver, 30);
get_food(r);
CuAssertIntEquals(tc, 10, i_get(u1->items, i_silver));
@ -151,7 +151,7 @@ void test_upkeep_free(CuTest * tc)
u = test_create_unit(test_create_faction(test_create_race("human")), r);
assert(r && u);
set_param(&global.parameters, "rules.food.flags", "4"); // FOOD_IS_FREE
config_set("rules.food.flags", "4"); // FOOD_IS_FREE
get_food(r);
CuAssertIntEquals(tc, 0, i_get(u->items, i_silver));
CuAssertIntEquals(tc, 0, fval(u, UFL_HUNGER));

View file

@ -26,8 +26,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include <float.h>
#include <ctype.h>
#define M_PIl 3.1415926535897932384626433832795029L /* pi */
/* NormalRand aus python, random.py geklaut, dort ist Referenz auf
* den Algorithmus. mu = Mittelwert, sigma = Standardabweichung.
* http://de.wikipedia.org/wiki/Standardabweichung#Diskrete_Gleichverteilung.2C_W.C3.BCrfel