forked from github/server
Merge pull request #406 from ennorehling/critbit-params
config_get/config_set refactoring, kill cache logic
This commit is contained in:
commit
dcfc1d1f15
65 changed files with 678 additions and 992 deletions
|
@ -52,7 +52,6 @@
|
||||||
"world.era": 3,
|
"world.era": 3,
|
||||||
"seed.population.min": 8,
|
"seed.population.min": 8,
|
||||||
"seed.population.max": 8,
|
"seed.population.max": 8,
|
||||||
"rules.migrants.max": 0,
|
|
||||||
"rules.reserve.twophase": true,
|
"rules.reserve.twophase": true,
|
||||||
"rules.owners.force_leave": false,
|
"rules.owners.force_leave": false,
|
||||||
"rules.monsters.attack_chance": 0.1,
|
"rules.monsters.attack_chance": 0.1,
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"study.speedup": 2,
|
"study.speedup": 2,
|
||||||
"study.from_use": 0.4,
|
"study.from_use": 0.4,
|
||||||
"world.era": 3,
|
"world.era": 3,
|
||||||
"rules.migrants.max": 0,
|
|
||||||
"rules.reserve.twophase": true,
|
"rules.reserve.twophase": true,
|
||||||
"rules.owners.force_leave": false,
|
"rules.owners.force_leave": false,
|
||||||
"rules.transfermen": false,
|
"rules.transfermen": false,
|
||||||
|
@ -64,7 +63,7 @@
|
||||||
"rules.combat.herospeed": 3,
|
"rules.combat.herospeed": 3,
|
||||||
"rules.combat.demon_vampire": 5,
|
"rules.combat.demon_vampire": 5,
|
||||||
"rules.combat.skill_bonus": 0,
|
"rules.combat.skill_bonus": 0,
|
||||||
"rules.combat.nat_armor": true,
|
"rules.combat.nat_armor": 1,
|
||||||
"rules.items.loot_divisor": 2,
|
"rules.items.loot_divisor": 2,
|
||||||
"rules.items.give_divisor": 2,
|
"rules.items.give_divisor": 2,
|
||||||
"rules.move.owner_leave": true,
|
"rules.move.owner_leave": true,
|
||||||
|
@ -78,7 +77,7 @@
|
||||||
"rules.blessed_harvest.flags": 1,
|
"rules.blessed_harvest.flags": 1,
|
||||||
"rules.magic.elfpower": true,
|
"rules.magic.elfpower": true,
|
||||||
"rules.magic.playerschools": "gwyrrd illaun draig cerddor",
|
"rules.magic.playerschools": "gwyrrd illaun draig cerddor",
|
||||||
"rules.build.other_buildings": 1,
|
"rules.build.other_buildings": true,
|
||||||
"rules.economy.taxation": 1,
|
"rules.economy.taxation": 1,
|
||||||
"rules.food.flags": 2,
|
"rules.food.flags": 2,
|
||||||
"rules.economy.roqf": 5,
|
"rules.economy.roqf": 5,
|
||||||
|
|
2
critbit
2
critbit
|
@ -1 +1 @@
|
||||||
Subproject commit dfe57a077222c6b572da61a79dc0687f81c10055
|
Subproject commit 934c2dd94d41da19637a76a1a8b3dfeb7aa8524d
|
|
@ -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">
|
<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"/>
|
<ai splitsize="10000" moverandom="yes" learn="yes"/>
|
||||||
<function name="itemdrop" value="defaultdrops"/>
|
<function name="itemdrop" value="defaultdrops"/>
|
||||||
|
<param name="migrants.formula" value="1"/>
|
||||||
<skill name="trade" modifier="1"/>
|
<skill name="trade" modifier="1"/>
|
||||||
<skill name="herbalism" modifier="-1"/>
|
<skill name="herbalism" modifier="-1"/>
|
||||||
<skill name="shipcraft" modifier="1"/>
|
<skill name="shipcraft" modifier="1"/>
|
||||||
|
|
|
@ -73,7 +73,7 @@ TOLUA_BINDING(config.pkg bind_config.h)
|
||||||
TOLUA_BINDING(process.pkg bind_process.h)
|
TOLUA_BINDING(process.pkg bind_process.h)
|
||||||
TOLUA_BINDING(game.pkg bind_eressea.h config.h)
|
TOLUA_BINDING(game.pkg bind_eressea.h config.h)
|
||||||
TOLUA_BINDING(eressea.pkg bind_eressea.h)
|
TOLUA_BINDING(eressea.pkg bind_eressea.h)
|
||||||
TOLUA_BINDING(settings.pkg bind_settings.h)
|
TOLUA_BINDING(settings.pkg kenel/config.h)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
set (ERESSEA_SRC
|
set (ERESSEA_SRC
|
||||||
|
@ -144,7 +144,6 @@ set(SERVER_SRC
|
||||||
bind_monsters.c
|
bind_monsters.c
|
||||||
bind_process.c
|
bind_process.c
|
||||||
bind_region.c
|
bind_region.c
|
||||||
bind_settings.c
|
|
||||||
bind_ship.c
|
bind_ship.c
|
||||||
bind_storage.c
|
bind_storage.c
|
||||||
bind_unit.c
|
bind_unit.c
|
||||||
|
|
115
src/alchemy.c
115
src/alchemy.c
|
@ -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 begin_potion(unit * u, const potion_type * ptype, struct order *ord)
|
||||||
{
|
{
|
||||||
static int rule_multipotion = -1;
|
bool rule_multipotion;
|
||||||
assert(ptype != NULL);
|
assert(ptype != NULL);
|
||||||
|
|
||||||
if (rule_multipotion < 0) {
|
/* should we allow multiple different potions to be used the same turn? */
|
||||||
/* should we allow multiple different potions to be used the same turn? */
|
rule_multipotion = config_get_int("rules.magic.multipotion", 0) != 0;
|
||||||
rule_multipotion =
|
|
||||||
get_param_int(global.parameters, "rules.magic.multipotion", 0);
|
|
||||||
}
|
|
||||||
if (!rule_multipotion) {
|
if (!rule_multipotion) {
|
||||||
const potion_type *use = ugetpotionuse(u);
|
const potion_type *use = ugetpotionuse(u);
|
||||||
if (use != NULL && use != ptype) {
|
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));
|
"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)
|
static int do_potion(unit * u, region *r, const potion_type * ptype, int amount)
|
||||||
{
|
{
|
||||||
if (ptype == oldpotiontype[P_LIFE]) {
|
if (ptype == oldpotiontype[P_LIFE]) {
|
||||||
int holz = 0;
|
return potion_water_of_life(u, r, amount);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
else if (ptype == oldpotiontype[P_HEILWASSER]) {
|
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]) {
|
else if (ptype == oldpotiontype[P_PEOPLE]) {
|
||||||
attrib *a = (attrib *)a_find(r->attribs, &at_peasantluck);
|
return potion_luck(u, r, &at_peasantluck, amount);
|
||||||
if (!a)
|
|
||||||
a = a_add(&r->attribs, a_new(&at_peasantluck));
|
|
||||||
a->data.i += amount;
|
|
||||||
}
|
}
|
||||||
else if (ptype == oldpotiontype[P_HORSE]) {
|
else if (ptype == oldpotiontype[P_HORSE]) {
|
||||||
attrib *a = (attrib *)a_find(r->attribs, &at_horseluck);
|
return potion_luck(u, r, &at_horseluck, amount);
|
||||||
if (!a)
|
|
||||||
a = a_add(&r->attribs, a_new(&at_horseluck));
|
|
||||||
a->data.i += amount;
|
|
||||||
}
|
}
|
||||||
else if (ptype == oldpotiontype[P_WAHRHEIT]) {
|
else if (ptype == oldpotiontype[P_WAHRHEIT]) {
|
||||||
fset(u, UFL_DISBELIEVES);
|
return potion_truth(u);
|
||||||
amount = 1;
|
|
||||||
}
|
}
|
||||||
else if (ptype == oldpotiontype[P_MACHT]) {
|
else if (ptype == oldpotiontype[P_MACHT]) {
|
||||||
/* Verfünffacht die HP von max. 10 Personen in der Einheit */
|
return potion_power(u, amount);
|
||||||
u->hp += _min(u->number, 10 * amount) * unit_max_hp(u) * 4;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
change_effect(u, ptype, 10 * amount);
|
change_effect(u, ptype, 10 * amount);
|
||||||
|
|
|
@ -17,18 +17,18 @@
|
||||||
|
|
||||||
static void test_rules(CuTest *tc) {
|
static void test_rules(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
set_param(&global.parameters, "stealth.faction.other", NULL);
|
config_set("stealth.faction.other", NULL);
|
||||||
CuAssertIntEquals(tc, true, rule_stealth_other());
|
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());
|
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());
|
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());
|
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());
|
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());
|
CuAssertIntEquals(tc, true, rule_stealth_anon());
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ static void test_otherfaction(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
f = test_create_faction(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());
|
CuAssertIntEquals(tc, true, rule_stealth_other());
|
||||||
CuAssertPtrEquals(tc, u->faction, visible_faction(f, u));
|
CuAssertPtrEquals(tc, u->faction, visible_faction(f, u));
|
||||||
a_add(&u->attribs, make_otherfaction(f));
|
a_add(&u->attribs, make_otherfaction(f));
|
||||||
|
|
176
src/battle.c
176
src/battle.c
|
@ -114,11 +114,6 @@ static message *msg_separator;
|
||||||
|
|
||||||
const troop no_troop = { 0, 0 };
|
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_ORIG 0
|
||||||
#define FORMULA_NEW 1
|
#define FORMULA_NEW 1
|
||||||
|
|
||||||
|
@ -131,31 +126,55 @@ static int skill_formula = 0;
|
||||||
#define DAMAGE_MELEE_BONUS (1<<1)
|
#define DAMAGE_MELEE_BONUS (1<<1)
|
||||||
#define DAMAGE_MISSILE_BONUS (1<<2)
|
#define DAMAGE_MISSILE_BONUS (1<<2)
|
||||||
#define DAMAGE_SKILL_BONUS (1<<4)
|
#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.
|
/** initialize rules from configuration.
|
||||||
*/
|
*/
|
||||||
static void static_rules(void)
|
static void init_rules(void)
|
||||||
{
|
{
|
||||||
loot_rules =
|
peace_ct = ct_find("peacezone");
|
||||||
get_param_int(global.parameters, "rules.combat.loot",
|
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);
|
LOOT_MONSTERS | LOOT_OTHERS | LOOT_KEEPLOOT);
|
||||||
/* new formula to calculate to-hit-chance */
|
/* new formula to calculate to-hit-chance */
|
||||||
skill_formula =
|
skill_formula = config_get_int("rules.combat.skill_formula",
|
||||||
get_param_int(global.parameters, "rules.combat.skill_formula",
|
|
||||||
FORMULA_ORIG);
|
FORMULA_ORIG);
|
||||||
/* maximum number of combat turns */
|
/* maximum number of combat turns */
|
||||||
max_turns =
|
max_turns = config_get_int("rules.combat.turns", COMBAT_TURNS);
|
||||||
get_param_int(global.parameters, "rules.combat.turns", COMBAT_TURNS);
|
|
||||||
/* damage calculation */
|
/* damage calculation */
|
||||||
if (get_param_int(global.parameters, "rules.combat.critical", 1)) {
|
if (config_get_int("rules.combat.critical", 1)) {
|
||||||
damage_rules |= DAMAGE_CRITICAL;
|
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;
|
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;
|
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;
|
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 CavalrySkill(void)
|
||||||
{
|
{
|
||||||
static int skill = -1;
|
return rule_cavalry_skill;
|
||||||
|
|
||||||
if (skill < 0) {
|
|
||||||
skill = get_param_int(global.parameters, "rules.cavalry.skill", 2);
|
|
||||||
}
|
|
||||||
return skill;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BONUS_SKILL 1
|
#define BONUS_SKILL 1
|
||||||
#define BONUS_DAMAGE 2
|
#define BONUS_DAMAGE 2
|
||||||
static int CavalryBonus(const unit * u, troop enemy, int type)
|
static int CavalryBonus(const unit * u, troop enemy, int type)
|
||||||
{
|
{
|
||||||
static int mode = -1;
|
if (rule_cavalry_mode == 0) {
|
||||||
|
|
||||||
if (mode < 0) {
|
|
||||||
mode = get_param_int(global.parameters, "rules.cavalry.mode", 1);
|
|
||||||
}
|
|
||||||
if (mode == 0) {
|
|
||||||
/* old rule, Eressea 1.0 compat */
|
/* old rule, Eressea 1.0 compat */
|
||||||
return (type == BONUS_SKILL) ? 2 : 0;
|
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 void vampirism(troop at, int damage)
|
||||||
{
|
{
|
||||||
static int vampire = -1;
|
int vampire = config_get_int("rules.combat.demon_vampire", 0);
|
||||||
if (vampire < 0)
|
|
||||||
vampire = get_param_int(global.parameters, "rules.combat.demon_vampire", 0);
|
|
||||||
if (vampire > 0) {
|
if (vampire > 0) {
|
||||||
int gain = damage / vampire;
|
int gain = damage / vampire;
|
||||||
int chance = damage - vampire * gain;
|
int chance = damage - vampire * gain;
|
||||||
|
@ -1024,30 +1031,20 @@ static void vampirism(troop at, int damage)
|
||||||
|
|
||||||
#define MAXRACES 128
|
#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);
|
const race *rc = u_race(du);
|
||||||
int index, an = rc->armor;
|
int bonus, an = rc->armor;
|
||||||
|
|
||||||
assert(rc);
|
assert(rc);
|
||||||
if (cookie!=global.cookie) {
|
bonus = armor_bonus(rc);
|
||||||
cookie = global.cookie;
|
if (bonus > 0) {
|
||||||
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) {
|
|
||||||
int sk = effskill(du, SK_STAMINA, 0);
|
int sk = effskill(du, SK_STAMINA, 0);
|
||||||
sk /= bonus[index];
|
sk /= bonus;
|
||||||
an += sk;
|
an += sk;
|
||||||
}
|
}
|
||||||
return an;
|
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) {
|
int calculate_armor(troop dt, const weapon_type *dwtype, const weapon_type *awtype, double *magres) {
|
||||||
static int rule_armor = -1;
|
|
||||||
fighter *df = dt.fighter;
|
fighter *df = dt.fighter;
|
||||||
unit *du = df->unit;
|
unit *du = df->unit;
|
||||||
int ar = 0, an, am;
|
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 */
|
/* Momentan nur Trollgürtel und Werwolf-Eigenschaft */
|
||||||
am = select_magicarmor(dt);
|
am = select_magicarmor(dt);
|
||||||
|
|
||||||
if (rule_armor < 0) {
|
if (rule_nat_armor == 0) {
|
||||||
rule_armor = get_param_int(global.parameters, "rules.combat.nat_armor", 0);
|
|
||||||
}
|
|
||||||
if (rule_armor == 0) {
|
|
||||||
/* natürliche Rüstung ist halbkumulativ */
|
/* natürliche Rüstung ist halbkumulativ */
|
||||||
if (ar > 0) {
|
if (ar > 0) {
|
||||||
ar += an / 2;
|
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) {
|
if (b->turn == 0 && dt.fighter) {
|
||||||
int tactics_formula = -1;
|
if (rule_tactics_formula == 1) {
|
||||||
|
|
||||||
if (tactics_formula < 0) {
|
|
||||||
tactics_formula =
|
|
||||||
get_param_int(global.parameters, "rules.tactics.formula", 0);
|
|
||||||
}
|
|
||||||
if (tactics_formula == 1) {
|
|
||||||
int tactics = get_tactics(at.fighter->side, dt.fighter->side);
|
int tactics = get_tactics(at.fighter->side, dt.fighter->side);
|
||||||
|
|
||||||
/* percentage chance to get this attack */
|
/* 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)) {
|
if (u_race(au) == get_race(RC_GOBLIN)) {
|
||||||
static int goblin_bonus = -1;
|
if (af->side->size[SUM_ROW] >= df->side->size[SUM_ROW] * rule_goblin_bonus) {
|
||||||
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) {
|
|
||||||
skdiff += 1;
|
skdiff += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2150,10 +2133,6 @@ static int attacks_per_round(troop t)
|
||||||
static void make_heroes(battle * b)
|
static void make_heroes(battle * b)
|
||||||
{
|
{
|
||||||
side *s;
|
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) {
|
for (s = b->sides; s != b->sides + b->nsides; ++s) {
|
||||||
fighter *fig;
|
fighter *fig;
|
||||||
for (fig = s->fighters; fig; fig = fig->next) {
|
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);
|
log_error("Hero %s is a %s.\n", unitname(u), u_race(u)->_name);
|
||||||
}
|
}
|
||||||
for (i = 0; i != u->number; ++i) {
|
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,
|
static int loot_quota(const unit * src, const unit * dst,
|
||||||
const item_type * type, int n)
|
const item_type * type, int n)
|
||||||
{
|
{
|
||||||
static double divisor = -1;
|
|
||||||
if (dst && src && src->faction != dst->faction) {
|
if (dst && src && src->faction != dst->faction) {
|
||||||
if (divisor < 0) {
|
double divisor = config_get_flt("rules.items.loot_divisor", 1);
|
||||||
divisor = get_param_flt(global.parameters, "rules.items.loot_divisor", 1);
|
assert(divisor == 0 || divisor >= 1);
|
||||||
assert(divisor == 0 || divisor >= 1);
|
|
||||||
}
|
|
||||||
if (divisor >= 1) {
|
if (divisor >= 1) {
|
||||||
double r = n / divisor;
|
double r = n / divisor;
|
||||||
int x = (int)r;
|
int x = (int)r;
|
||||||
|
@ -2661,14 +2637,7 @@ static bool seematrix(const faction * f, const side * s)
|
||||||
|
|
||||||
static double PopulationDamage(void)
|
static double PopulationDamage(void)
|
||||||
{
|
{
|
||||||
static double value = -1.0;
|
return rule_population_damage / 100.0;
|
||||||
if (value < 0) {
|
|
||||||
int damage =
|
|
||||||
get_param_int(global.parameters, "rules.combat.populationdamage",
|
|
||||||
BATTLE_KILLS_PEASANTS);
|
|
||||||
value = damage / 100.0;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void battle_effects(battle * b, int dead_players)
|
static void battle_effects(battle * b, int dead_players)
|
||||||
|
@ -2918,7 +2887,7 @@ static void aftermath(battle * b)
|
||||||
int n = b->turn - 2;
|
int n = b->turn - 2;
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
double dmg =
|
double dmg =
|
||||||
get_param_flt(global.parameters, "rules.ship.damage.battleround",
|
config_get_flt("rules.ship.damage.battleround",
|
||||||
0.05F);
|
0.05F);
|
||||||
damage_ship(sh, dmg * n);
|
damage_ship(sh, dmg * n);
|
||||||
freset(sh, SF_DAMAGED);
|
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 * find_side(battle * b, const faction * f, const group * g, unsigned int flags, const faction * stealthfaction)
|
||||||
{
|
{
|
||||||
side * s;
|
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) {
|
for (s = b->sides; s != b->sides + b->nsides; ++s) {
|
||||||
if (s->faction == f && s->group == g) {
|
if (s->faction == f && s->group == g) {
|
||||||
unsigned int s1flags = flags | SIDE_HASGUARDS;
|
unsigned int s1flags = flags | SIDE_HASGUARDS;
|
||||||
unsigned int s2flags = s->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;
|
continue;
|
||||||
}
|
}
|
||||||
if (s1flags == s2flags) {
|
if (s1flags == s2flags) {
|
||||||
|
@ -3621,7 +3585,6 @@ battle *make_battle(region * r)
|
||||||
unit *u;
|
unit *u;
|
||||||
bfaction *bf;
|
bfaction *bf;
|
||||||
building * bld;
|
building * bld;
|
||||||
static int max_fac_no = 0; /* need this only once */
|
|
||||||
|
|
||||||
/* Alle Mann raus aus der Burg! */
|
/* Alle Mann raus aus der Burg! */
|
||||||
for (bld = r->buildings; bld != NULL; bld = bld->next)
|
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) {
|
for (bf = b->factions; bf; bf = bf->next) {
|
||||||
faction *f = bf->faction;
|
faction *f = bf->faction;
|
||||||
max_fac_no = _max(max_fac_no, f->no);
|
|
||||||
freset(f, FFL_MARK);
|
freset(f, FFL_MARK);
|
||||||
}
|
}
|
||||||
return b;
|
return b;
|
||||||
|
@ -3719,17 +3681,13 @@ static void battle_free(battle * b) {
|
||||||
|
|
||||||
void free_battle(battle * b)
|
void free_battle(battle * b)
|
||||||
{
|
{
|
||||||
int max_fac_no = 0;
|
|
||||||
|
|
||||||
if (bdebug) {
|
if (bdebug) {
|
||||||
fclose(bdebug);
|
fclose(bdebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (b->factions) {
|
while (b->factions) {
|
||||||
bfaction *bf = b->factions;
|
bfaction *bf = b->factions;
|
||||||
faction *f = bf->faction;
|
|
||||||
b->factions = bf->next;
|
b->factions = bf->next;
|
||||||
max_fac_no = _max(max_fac_no, f->no);
|
|
||||||
free(bf);
|
free(bf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3976,15 +3934,6 @@ static bool start_battle(region * r, battle ** bp)
|
||||||
order *ord;
|
order *ord;
|
||||||
|
|
||||||
for (ord = u->orders; ord; ord = ord->next) {
|
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) {
|
if (getkeyword(ord) == K_ATTACK) {
|
||||||
unit *u2;
|
unit *u2;
|
||||||
fighter *c1, *c2;
|
fighter *c1, *c2;
|
||||||
|
@ -4308,12 +4257,6 @@ void do_battle(region * r)
|
||||||
battle *b = NULL;
|
battle *b = NULL;
|
||||||
bool fighting = false;
|
bool fighting = false;
|
||||||
ship *sh;
|
ship *sh;
|
||||||
static int init_rules = 0;
|
|
||||||
|
|
||||||
if (!init_rules) {
|
|
||||||
static_rules();
|
|
||||||
init_rules = 1;
|
|
||||||
}
|
|
||||||
if (msg_separator == NULL) {
|
if (msg_separator == NULL) {
|
||||||
msg_separator = msg_message("battle::section", "");
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ extern "C" {
|
||||||
fighter * get_fighter(battle * b, const struct unit * u);
|
fighter * get_fighter(battle * b, const struct unit * u);
|
||||||
/* END battle interface */
|
/* END battle interface */
|
||||||
|
|
||||||
extern void do_battle(struct region *r);
|
extern void do_battles(void);
|
||||||
|
|
||||||
/* for combat spells and special attacks */
|
/* for combat spells and special attacks */
|
||||||
enum { SELECT_ADVANCE = 0x1, SELECT_DISTANCE = 0x2, SELECT_FIND = 0x4 };
|
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 count_enemies(struct battle *b, const struct fighter *af,
|
||||||
int minrow, int maxrow, int select);
|
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);
|
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 terminate(troop dt, troop at, int type, const char *damage,
|
||||||
bool missile);
|
bool missile);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "battle.h"
|
#include "battle.h"
|
||||||
#include "skill.h"
|
#include "skill.h"
|
||||||
|
|
||||||
|
#include <kernel/config.h>
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/item.h>
|
#include <kernel/item.h>
|
||||||
|
@ -201,13 +202,30 @@ static void test_building_defence_bonus(CuTest * tc)
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
fighter *setup_fighter(battle **bp, unit *u) {
|
static fighter *setup_fighter(battle **bp, unit *u) {
|
||||||
battle *b;
|
battle *b;
|
||||||
|
|
||||||
*bp = b = make_battle(u->region);
|
*bp = b = make_battle(u->region);
|
||||||
return make_fighter(b, u, make_side(b, u->faction, 0, 0, 0), false);
|
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)
|
static void test_calculate_armor(CuTest * tc)
|
||||||
{
|
{
|
||||||
troop dt;
|
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_bonus_respects_size);
|
||||||
SUITE_ADD_TEST(suite, test_building_defence_bonus);
|
SUITE_ADD_TEST(suite, test_building_defence_bonus);
|
||||||
SUITE_ADD_TEST(suite, test_calculate_armor);
|
SUITE_ADD_TEST(suite, test_calculate_armor);
|
||||||
|
SUITE_ADD_TEST(suite, test_natural_armor);
|
||||||
SUITE_ADD_TEST(suite, test_projectile_armor);
|
SUITE_ADD_TEST(suite, test_projectile_armor);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,10 +70,7 @@ void process_produce(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_battle(void) {
|
void process_battle(void) {
|
||||||
struct region *r;
|
do_battles();
|
||||||
for (r = regions; r; r = r->next) {
|
|
||||||
do_battle(r);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_siege(void) {
|
void process_siege(void) {
|
||||||
|
@ -223,7 +220,7 @@ void process_explain(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_reserve(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) {
|
if (rule) {
|
||||||
process_cmd(K_RESERVE, reserve_self, 0);
|
process_cmd(K_RESERVE, reserve_self, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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
|
|
|
@ -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_pushstring(L, reportpath());
|
lua_pushstring(L, reportpath());
|
||||||
lua_rawset(L, -3);
|
lua_rawset(L, -3);
|
||||||
arg = get_param(global.parameters, "config.rules");
|
arg = config_get("config.rules");
|
||||||
if (arg) {
|
if (arg) {
|
||||||
lua_pushstring(L, "rules");
|
lua_pushstring(L, "rules");
|
||||||
lua_pushstring(L, arg);
|
lua_pushstring(L, arg);
|
||||||
|
|
|
@ -193,7 +193,7 @@ static void chaos(region * r)
|
||||||
while (sh) {
|
while (sh) {
|
||||||
ship *nsh = sh->next;
|
ship *nsh = sh->next;
|
||||||
double dmg =
|
double dmg =
|
||||||
get_param_flt(global.parameters, "rules.ship.damage.atlantis",
|
config_get_flt("rules.ship.damage.atlantis",
|
||||||
0.50);
|
0.50);
|
||||||
damage_ship(sh, dmg);
|
damage_ship(sh, dmg);
|
||||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||||
|
|
|
@ -1505,7 +1505,7 @@ report_computer(const char *filename, report_context * ctx, const char *charset)
|
||||||
FILE *F = fopen(filename, "wt");
|
FILE *F = fopen(filename, "wt");
|
||||||
|
|
||||||
if (era < 0) {
|
if (era < 0) {
|
||||||
era = get_param_int(global.parameters, "world.era", 1);
|
era = config_get_int("world.era", 1);
|
||||||
}
|
}
|
||||||
if (F == NULL) {
|
if (F == NULL) {
|
||||||
perror(filename);
|
perror(filename);
|
||||||
|
|
|
@ -104,7 +104,7 @@ static void recruit_init(void)
|
||||||
{
|
{
|
||||||
if (rules_recruit < 0) {
|
if (rules_recruit < 0) {
|
||||||
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;
|
rules_recruit |= RECRUIT_MERGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -731,7 +731,7 @@ static bool maintain(building * b, bool first)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
/* If the owner is the region owner, check if dontpay flag is set for the building where he is in */
|
/* 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)) {
|
if (fval(u->building, BLD_DONTPAY)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2360,16 +2360,12 @@ static void breedtrees(unit * u, int raw)
|
||||||
{
|
{
|
||||||
int n, i, skill, planted = 0;
|
int n, i, skill, planted = 0;
|
||||||
const resource_type *rtype;
|
const resource_type *rtype;
|
||||||
static int gamecookie = -1;
|
int current_season;
|
||||||
static int current_season;
|
|
||||||
region *r = u->region;
|
region *r = u->region;
|
||||||
|
gamedate date;
|
||||||
if (gamecookie != global.cookie) {
|
|
||||||
gamedate date;
|
get_gamedate(turn, &date);
|
||||||
get_gamedate(turn, &date);
|
current_season = date.season;
|
||||||
current_season = date.season;
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bäume züchten geht nur im Frühling */
|
/* Bäume züchten geht nur im Frühling */
|
||||||
if (current_season != SEASON_SPRING) {
|
if (current_season != SEASON_SPRING) {
|
||||||
|
@ -2749,11 +2745,11 @@ void entertain_cmd(unit * u, struct order *ord)
|
||||||
kwd = init_order(ord);
|
kwd = init_order(ord);
|
||||||
assert(kwd == K_ENTERTAIN);
|
assert(kwd == K_ENTERTAIN);
|
||||||
if (!entertainbase) {
|
if (!entertainbase) {
|
||||||
const char *str = get_param(global.parameters, "entertain.base");
|
const char *str = config_get("entertain.base");
|
||||||
entertainbase = str ? atoi(str) : 0;
|
entertainbase = str ? atoi(str) : 0;
|
||||||
}
|
}
|
||||||
if (!entertainperlevel) {
|
if (!entertainperlevel) {
|
||||||
const char *str = get_param(global.parameters, "entertain.perlevel");
|
const char *str = config_get("entertain.perlevel");
|
||||||
entertainperlevel = str ? atoi(str) : 0;
|
entertainperlevel = str ? atoi(str) : 0;
|
||||||
}
|
}
|
||||||
if (fval(u, UFL_WERE)) {
|
if (fval(u, UFL_WERE)) {
|
||||||
|
@ -3024,7 +3020,7 @@ void loot_cmd(unit * u, struct order *ord, request ** lootorders)
|
||||||
kwd = init_order(ord);
|
kwd = init_order(ord);
|
||||||
assert(kwd == K_LOOT);
|
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;
|
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)
|
void produce(struct region *r)
|
||||||
{
|
{
|
||||||
request workers[MAX_WORKERS];
|
request workers[MAX_WORKERS];
|
||||||
request *taxorders, *lootorders, *sellorders, *stealorders, *buyorders;
|
request *taxorders, *lootorders, *sellorders, *stealorders, *buyorders;
|
||||||
unit *u;
|
unit *u;
|
||||||
static int rule_autowork = -1;
|
|
||||||
bool limited = true;
|
bool limited = true;
|
||||||
request *nextworker = workers;
|
request *nextworker = workers;
|
||||||
assert(r);
|
assert(r);
|
||||||
|
@ -3158,10 +3162,6 @@ void produce(struct region *r)
|
||||||
*
|
*
|
||||||
* lehren vor lernen. */
|
* lehren vor lernen. */
|
||||||
|
|
||||||
if (rule_autowork < 0) {
|
|
||||||
rule_autowork = get_param_int(global.parameters, "work.auto", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(rmoney(r) >= 0);
|
assert(rmoney(r) >= 0);
|
||||||
assert(rpeasants(r) >= 0);
|
assert(rpeasants(r) >= 0);
|
||||||
|
|
||||||
|
@ -3235,7 +3235,7 @@ void produce(struct region *r)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case K_WORK:
|
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);
|
assert(nextworker - workers < MAX_WORKERS);
|
||||||
++nextworker;
|
++nextworker;
|
||||||
}
|
}
|
||||||
|
@ -3280,7 +3280,7 @@ void produce(struct region *r)
|
||||||
* auszugeben bereit sind. */
|
* auszugeben bereit sind. */
|
||||||
if (entertaining)
|
if (entertaining)
|
||||||
expandentertainment(r);
|
expandentertainment(r);
|
||||||
if (!rule_autowork) {
|
if (!rule_autowork()) {
|
||||||
expandwork(r, workers, nextworker, maxworkingpeasants(r));
|
expandwork(r, workers, nextworker, maxworkingpeasants(r));
|
||||||
}
|
}
|
||||||
if (taxorders)
|
if (taxorders)
|
||||||
|
|
12
src/give.c
12
src/give.c
|
@ -52,12 +52,12 @@
|
||||||
#define RESERVE_GIVE /* reserve anything that's given from one unit to another? */
|
#define RESERVE_GIVE /* reserve anything that's given from one unit to another? */
|
||||||
|
|
||||||
static int max_transfers(void) {
|
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)
|
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)
|
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;
|
return n;
|
||||||
}
|
}
|
||||||
if (dst && src && src->faction != dst->faction) {
|
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);
|
assert(divisor == 0 || divisor >= 1);
|
||||||
if (divisor >= 1) {
|
if (divisor >= 1) {
|
||||||
/* predictable > correct: */
|
/* predictable > correct: */
|
||||||
|
@ -233,6 +233,12 @@ static bool can_give_men(const unit *u, order *ord, message **msg) {
|
||||||
return false;
|
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)
|
message * give_men(int n, unit * u, unit * u2, struct order *ord)
|
||||||
{
|
{
|
||||||
ship *sh;
|
ship *sh;
|
||||||
|
|
|
@ -75,11 +75,11 @@ static void test_give_unit(CuTest * tc) {
|
||||||
env.f2 = test_create_faction(0);
|
env.f2 = test_create_faction(0);
|
||||||
setup_give(&env);
|
setup_give(&env);
|
||||||
env.r->terrain = test_create_terrain("ocean", SEA_REGION);
|
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);
|
give_unit(env.src, env.dst, NULL);
|
||||||
CuAssertPtrEquals(tc, env.f1, env.src->faction);
|
CuAssertPtrEquals(tc, env.f1, env.src->faction);
|
||||||
CuAssertIntEquals(tc, 0, env.f2->newbies);
|
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);
|
give_unit(env.src, env.dst, NULL);
|
||||||
CuAssertPtrEquals(tc, env.f2, env.src->faction);
|
CuAssertPtrEquals(tc, env.f2, env.src->faction);
|
||||||
CuAssertIntEquals(tc, 1, env.f2->newbies);
|
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.f2 = test_create_faction(0);
|
||||||
env.f1 = test_create_faction(0);
|
env.f1 = test_create_faction(0);
|
||||||
setup_give(&env);
|
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 */
|
/* below the limit, give men, increase newbies counter */
|
||||||
usetcontact(env.dst, env.src);
|
usetcontact(env.dst, env.src);
|
||||||
|
@ -308,7 +308,7 @@ static void test_give_okay(CuTest * tc) {
|
||||||
env.f2 = env.f1 = test_create_faction(0);
|
env.f2 = env.f1 = test_create_faction(0);
|
||||||
setup_give(&env);
|
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));
|
CuAssertPtrEquals(tc, 0, check_give(env.src, env.dst, 0));
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ static void test_give_denied_by_rules(CuTest * tc) {
|
||||||
env.f2 = test_create_faction(0);
|
env.f2 = test_create_faction(0);
|
||||||
setup_give(&env);
|
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));
|
CuAssertPtrNotNull(tc, msg = check_give(env.src, env.dst, 0));
|
||||||
msg_release(msg);
|
msg_release(msg);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
|
|
@ -853,8 +853,8 @@ static void handlekey(state * st, int c)
|
||||||
new_players = read_newfactions(sbuffer);
|
new_players = read_newfactions(sbuffer);
|
||||||
}
|
}
|
||||||
cnormalize(&st->cursor, &nx, &ny);
|
cnormalize(&st->cursor, &nx, &ny);
|
||||||
minpop = get_param_int(global.parameters, "seed.population.min", 8);
|
minpop = config_get_int("seed.population.min", 8);
|
||||||
maxpop = get_param_int(global.parameters, "seed.population.max", minpop);
|
maxpop = config_get_int("seed.population.max", minpop);
|
||||||
if (maxpop > minpop) {
|
if (maxpop > minpop) {
|
||||||
n = rng_int() % (maxpop - minpop) + minpop;
|
n = rng_int() % (maxpop - minpop) + minpop;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 bool lua_canuse_item(const unit * u, const struct item_type *itype)
|
||||||
{
|
{
|
||||||
static int function_exists = 1;
|
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
lua_State *L = (lua_State *)global.vm_state;
|
||||||
|
const char *fname = "item_canuse";
|
||||||
|
|
||||||
if (function_exists) {
|
lua_getglobal(L, fname);
|
||||||
lua_State *L = (lua_State *)global.vm_state;
|
if (lua_isfunction(L, -1)) {
|
||||||
const char *fname = "item_canuse";
|
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
|
||||||
|
tolua_pushstring(L, itype->rtype->_name);
|
||||||
|
|
||||||
lua_getglobal(L, fname);
|
if (lua_pcall(L, 2, 1, 0) != 0) {
|
||||||
if (lua_isfunction(L, -1)) {
|
const char *error = lua_tostring(L, -1);
|
||||||
tolua_pushusertype(L, (void *)u, TOLUA_CAST "unit");
|
log_error("use(%s) calling '%s': %s.\n", unitname(u), fname, error);
|
||||||
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);
|
|
||||||
lua_pop(L, 1);
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,13 +141,11 @@ int *casualties)
|
||||||
d += terminate(dt, *at, AT_STANDARD, wp->type->damage[0], true);
|
d += terminate(dt, *at, AT_STANDARD, wp->type->damage[0], true);
|
||||||
#ifdef CATAPULT_STRUCTURAL_DAMAGE
|
#ifdef CATAPULT_STRUCTURAL_DAMAGE
|
||||||
if (dt.fighter->unit->building && rng_int() % 100 < 5) {
|
if (dt.fighter->unit->building && rng_int() % 100 < 5) {
|
||||||
float dmg =
|
double dmg = config_get_flt("rules.building.damage.catapult", 1);
|
||||||
get_param_flt(global.parameters, "rules.building.damage.catapult", 1);
|
|
||||||
damage_building(b, dt.fighter->unit->building, dmg);
|
damage_building(b, dt.fighter->unit->building, dmg);
|
||||||
}
|
}
|
||||||
else if (dt.fighter->unit->ship && rng_int() % 100 < 5) {
|
else if (dt.fighter->unit->ship && rng_int() % 100 < 5) {
|
||||||
float dmg =
|
double dmg = config_get_flt("rules.ship.damage.catapult", 0.01);
|
||||||
get_param_flt(global.parameters, "rules.ship.damage.catapult", 0.01);
|
|
||||||
damage_ship(dt.fighter->unit->ship, dmg)
|
damage_ship(dt.fighter->unit->ship, dmg)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -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)
|
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");
|
FILE * F = fopen(filename, "w");
|
||||||
if (F) {
|
if (F) {
|
||||||
int x, y, minx = INT_MAX, maxx = INT_MIN, miny = INT_MAX, maxy = INT_MIN;
|
int x, y, minx = INT_MAX, maxx = INT_MIN, miny = INT_MAX, maxy = INT_MIN;
|
||||||
|
|
|
@ -419,7 +419,7 @@ int roqf_factor(void)
|
||||||
{
|
{
|
||||||
int value = -1;
|
int value = -1;
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
value = get_param_int(global.parameters, "rules.economy.roqf", 10);
|
value = config_get_int("rules.economy.roqf", 10);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,6 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
|
||||||
const char *btname;
|
const char *btname;
|
||||||
order *new_order = NULL;
|
order *new_order = NULL;
|
||||||
const struct locale *lang = u->faction->locale;
|
const struct locale *lang = u->faction->locale;
|
||||||
static int rule_other = -1;
|
|
||||||
|
|
||||||
assert(u->number);
|
assert(u->number);
|
||||||
assert(btype->construction);
|
assert(btype->construction);
|
||||||
|
@ -749,10 +748,7 @@ build_building(unit * u, const building_type * btype, int id, int want, order *
|
||||||
n = 1;
|
n = 1;
|
||||||
}
|
}
|
||||||
if (b) {
|
if (b) {
|
||||||
if (rule_other < 0) {
|
bool rule_other = config_get_int("rules.build.other_buildings", 1) != 0;
|
||||||
rule_other =
|
|
||||||
get_param_int(global.parameters, "rules.build.other_buildings", 1);
|
|
||||||
}
|
|
||||||
if (!rule_other) {
|
if (!rule_other) {
|
||||||
unit *owner = building_owner(b);
|
unit *owner = building_owner(b);
|
||||||
if (!owner || owner->faction != u->faction) {
|
if (!owner || owner->faction != u->faction) {
|
||||||
|
|
|
@ -531,7 +531,7 @@ int bt_effsize(const building_type * btype, const building * b, int bsize)
|
||||||
const construction *cons = btype->construction;
|
const construction *cons = btype->construction;
|
||||||
|
|
||||||
/* TECH DEBT: simplest thing that works for E3 dwarf/halfling faction rules */
|
/* 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) {
|
&& strcmp(btype->_name, "castle") == 0) {
|
||||||
unit *u = building_owner(b);
|
unit *u = building_owner(b);
|
||||||
if (u && u->faction->race == get_race(RC_HALFLING)) {
|
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()) {
|
if (rule_region_owners()) {
|
||||||
u = building_owner(largestbuilding(bld->region, &cmp_taxes, false));
|
u = building_owner(largestbuilding(bld->region, &cmp_taxes, false));
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,7 +94,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -110,13 +109,7 @@ int turn = -1;
|
||||||
|
|
||||||
int NewbieImmunity(void)
|
int NewbieImmunity(void)
|
||||||
{
|
{
|
||||||
static int value = -1;
|
return config_get_int("NewbieImmunity", 0);
|
||||||
static int gamecookie = -1;
|
|
||||||
if (value < 0 || gamecookie != global.cookie) {
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
value = get_param_int(global.parameters, "NewbieImmunity", 0);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsImmune(const faction * f)
|
bool IsImmune(const faction * f)
|
||||||
|
@ -143,13 +136,7 @@ static int ally_flag(const char *s, int help_mask)
|
||||||
|
|
||||||
bool ExpensiveMigrants(void)
|
bool ExpensiveMigrants(void)
|
||||||
{
|
{
|
||||||
static int value = -1;
|
return config_get_int("study.expensivemigrants", 0) != 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Specifies automatic alliance modes.
|
/** Specifies automatic alliance modes.
|
||||||
|
@ -158,21 +145,17 @@ bool ExpensiveMigrants(void)
|
||||||
*/
|
*/
|
||||||
int AllianceAuto(void)
|
int AllianceAuto(void)
|
||||||
{
|
{
|
||||||
static int value = -1;
|
int value;
|
||||||
static int gamecookie = -1;
|
const char *str = config_get("alliance.auto");
|
||||||
if (value < 0 || gamecookie != global.cookie) {
|
value = 0;
|
||||||
const char *str = get_param(global.parameters, "alliance.auto");
|
if (str != NULL) {
|
||||||
gamecookie = global.cookie;
|
char *sstr = _strdup(str);
|
||||||
value = 0;
|
char *tok = strtok(sstr, " ");
|
||||||
if (str != NULL) {
|
while (tok) {
|
||||||
char *sstr = _strdup(str);
|
value |= ally_flag(tok, -1);
|
||||||
char *tok = strtok(sstr, " ");
|
tok = strtok(NULL, " ");
|
||||||
while (tok) {
|
|
||||||
value |= ally_flag(tok, -1);
|
|
||||||
tok = strtok(NULL, " ");
|
|
||||||
}
|
|
||||||
free(sstr);
|
|
||||||
}
|
}
|
||||||
|
free(sstr);
|
||||||
}
|
}
|
||||||
return value & HelpMask();
|
return value & HelpMask();
|
||||||
}
|
}
|
||||||
|
@ -185,89 +168,60 @@ int AllianceAuto(void)
|
||||||
*/
|
*/
|
||||||
int HelpMask(void)
|
int HelpMask(void)
|
||||||
{
|
{
|
||||||
static int rule = -1;
|
const char *str = config_get("rules.help.mask");
|
||||||
static int gamecookie = -1;
|
int rule = 0;
|
||||||
if (rule < 0 || gamecookie != global.cookie) {
|
if (str != NULL) {
|
||||||
const char *str = get_param(global.parameters, "rules.help.mask");
|
char *sstr = _strdup(str);
|
||||||
gamecookie = global.cookie;
|
char *tok = strtok(sstr, " ");
|
||||||
rule = 0;
|
while (tok) {
|
||||||
if (str != NULL) {
|
rule |= ally_flag(tok, -1);
|
||||||
char *sstr = _strdup(str);
|
tok = strtok(NULL, " ");
|
||||||
char *tok = strtok(sstr, " ");
|
|
||||||
while (tok) {
|
|
||||||
rule |= ally_flag(tok, -1);
|
|
||||||
tok = strtok(NULL, " ");
|
|
||||||
}
|
|
||||||
free(sstr);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
rule = HELP_ALL;
|
|
||||||
}
|
}
|
||||||
|
free(sstr);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rule = HELP_ALL;
|
||||||
}
|
}
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AllianceRestricted(void)
|
int AllianceRestricted(void)
|
||||||
{
|
{
|
||||||
static int rule = -1;
|
const char *str = config_get("alliance.restricted");
|
||||||
static int gamecookie = -1;
|
int rule = 0;
|
||||||
if (rule < 0 || gamecookie != global.cookie) {
|
if (str != NULL) {
|
||||||
const char *str = get_param(global.parameters, "alliance.restricted");
|
char *sstr = _strdup(str);
|
||||||
gamecookie = global.cookie;
|
char *tok = strtok(sstr, " ");
|
||||||
rule = 0;
|
while (tok) {
|
||||||
if (str != NULL) {
|
rule |= ally_flag(tok, -1);
|
||||||
char *sstr = _strdup(str);
|
tok = strtok(NULL, " ");
|
||||||
char *tok = strtok(sstr, " ");
|
|
||||||
while (tok) {
|
|
||||||
rule |= ally_flag(tok, -1);
|
|
||||||
tok = strtok(NULL, " ");
|
|
||||||
}
|
|
||||||
free(sstr);
|
|
||||||
}
|
}
|
||||||
rule &= HelpMask();
|
free(sstr);
|
||||||
}
|
}
|
||||||
|
rule &= HelpMask();
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LongHunger(const struct unit *u)
|
int LongHunger(const struct unit *u)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
|
||||||
static int rule = -1;
|
|
||||||
if (u != NULL) {
|
if (u != NULL) {
|
||||||
if (!fval(u, UFL_HUNGER))
|
if (!fval(u, UFL_HUNGER))
|
||||||
return false;
|
return false;
|
||||||
if (u_race(u) == get_race(RC_DAEMON))
|
if (u_race(u) == get_race(RC_DAEMON))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (rule < 0 || gamecookie != global.cookie) {
|
return config_get_int("hunger.long", 0);
|
||||||
gamecookie = global.cookie;
|
|
||||||
rule = get_param_int(global.parameters, "hunger.long", 0);
|
|
||||||
}
|
|
||||||
return rule;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SkillCap(skill_t sk)
|
int SkillCap(skill_t sk)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
if (sk == SK_MAGIC) return 0; /* no caps on magic */
|
||||||
static int rule = -1;
|
return config_get_int("skill.maxlevel", 0);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int NMRTimeout(void)
|
int NMRTimeout(void)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
return config_get_int("nmr.timeout", 0);
|
||||||
static int rule = -1;
|
|
||||||
if (rule < 0 || gamecookie != global.cookie) {
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
rule = get_param_int(global.parameters, "nmr.timeout", 0);
|
|
||||||
}
|
|
||||||
return rule;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
race_t old_race(const struct race * rc)
|
race_t old_race(const struct race * rc)
|
||||||
|
@ -416,8 +370,7 @@ static attrib_type at_maxmagicians = {
|
||||||
|
|
||||||
int max_magicians(const faction * f)
|
int max_magicians(const faction * f)
|
||||||
{
|
{
|
||||||
int m =
|
int m = config_get_int("rules.maxskills.magic", MAXMAGICIANS);
|
||||||
get_param_int(global.parameters, "rules.maxskills.magic", MAXMAGICIANS);
|
|
||||||
attrib *a;
|
attrib *a;
|
||||||
|
|
||||||
if ((a = a_find(f->attribs, &at_maxmagicians)) != NULL) {
|
if ((a = a_find(f->attribs, &at_maxmagicians)) != NULL) {
|
||||||
|
@ -498,7 +451,7 @@ static int ally_mode(const ally * sf, int mode)
|
||||||
|
|
||||||
int
|
int
|
||||||
alliedgroup(const struct plane *pl, const struct faction *f,
|
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)
|
while (sf && sf->faction != f2)
|
||||||
sf = sf->next;
|
sf = sf->next;
|
||||||
|
@ -522,7 +475,7 @@ const struct faction *f2, const struct ally *sf, int mode)
|
||||||
|
|
||||||
int
|
int
|
||||||
alliedfaction(const struct plane *pl, const struct faction *f,
|
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);
|
return alliedgroup(pl, f, f2, f->allies, mode);
|
||||||
}
|
}
|
||||||
|
@ -567,68 +520,6 @@ int alliedunit(const unit * u, const faction * f2, int mode)
|
||||||
}
|
}
|
||||||
return 0;
|
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
|
void
|
||||||
parse(keyword_t kword, int(*dofun) (unit *, struct order *), bool thisorder)
|
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);
|
tokens = get_translations(lang, UT_MAGIC);
|
||||||
if (tokens) {
|
if (tokens) {
|
||||||
const char *str = get_param(global.parameters, "rules.magic.playerschools");
|
const char *str = config_get("rules.magic.playerschools");
|
||||||
char *sstr, *tok;
|
char *sstr, *tok;
|
||||||
if (str == NULL) {
|
if (str == NULL) {
|
||||||
str = "gwyrrd illaun draig cerddor tybied";
|
str = "gwyrrd illaun draig cerddor tybied";
|
||||||
|
@ -1024,32 +915,58 @@ void init_locale(struct locale *lang)
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct param {
|
typedef struct param {
|
||||||
struct param *next;
|
critbit_tree cb;
|
||||||
char *name;
|
|
||||||
char *data;
|
|
||||||
} param;
|
} 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) {
|
void free_params(struct param **pp) {
|
||||||
while (*pp) {
|
param *p = *pp;
|
||||||
param *p = *pp;
|
if (p) {
|
||||||
free(p->name);
|
cb_clear(&p->cb);
|
||||||
free(p->data);
|
|
||||||
*pp = p->next;
|
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
*pp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *get_param(const struct param *p, const char *key)
|
const char *get_param(const struct param *p, const char *key)
|
||||||
{
|
{
|
||||||
while (p != NULL) {
|
void *match;
|
||||||
int cmp = strcmp(p->name, key);
|
if (p && cb_find_prefix(&p->cb, key, strlen(key) + 1, &match, 1, 0) > 0) {
|
||||||
if (cmp == 0) {
|
cb_get_kv_ex(match, &match);
|
||||||
return p->data;
|
return (const char *)match;
|
||||||
}
|
|
||||||
else if (cmp > 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
p = p->next;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1135,40 +1052,6 @@ double get_param_flt(const struct param *p, const char *key, double def)
|
||||||
return str ? atof(str) : 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)
|
void kernel_done(void)
|
||||||
{
|
{
|
||||||
/* calling this function releases memory assigned to static variables, etc.
|
/* calling this function releases memory assigned to static variables, etc.
|
||||||
|
@ -1203,11 +1086,6 @@ char *_strdup(const char *s)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool faction_id_is_unused(int id)
|
|
||||||
{
|
|
||||||
return findfaction(id) == NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int besieged(const unit * u)
|
int besieged(const unit * u)
|
||||||
{
|
{
|
||||||
/* belagert kann man in schiffen und burgen werden */
|
/* 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)
|
bool rule_stealth_other(void)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
int rule = config_get_int("stealth.faction.other", 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);
|
|
||||||
}
|
|
||||||
return rule != 0;
|
return rule != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rule_stealth_anon(void)
|
bool rule_stealth_anon(void)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
int rule = config_get_int("stealth.faction.anon", 1);
|
||||||
static int rule = -1;
|
return rule != 0;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rule_region_owners(void)
|
bool rule_region_owners(void)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
int rule = config_get_int("rules.region_owners", 0);
|
||||||
static int rule = -1;
|
return rule != 0;
|
||||||
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_blessed_harvest(void)
|
int rule_blessed_harvest(void)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
int rule = config_get_int("rules.blessed_harvest.flags",
|
||||||
static int rule = -1;
|
HARVEST_WORK);
|
||||||
if (rule < 0 || gamecookie != global.cookie) {
|
assert(rule >= 0);
|
||||||
rule =
|
|
||||||
get_param_int(global.parameters, "rules.blessed_harvest.flags",
|
|
||||||
HARVEST_WORK);
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
assert(rule >= 0);
|
|
||||||
}
|
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rule_alliance_limit(void)
|
int rule_alliance_limit(void)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
int rule = config_get_int("rules.limit.alliance", 0);
|
||||||
static int rule = -1;
|
assert(rule >= 0);
|
||||||
if (rule < 0 || gamecookie != global.cookie) {
|
|
||||||
rule = get_param_int(global.parameters, "rules.limit.alliance", 0);
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
assert(rule >= 0);
|
|
||||||
}
|
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
|
|
||||||
int rule_faction_limit(void)
|
int rule_faction_limit(void)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
int rule = config_get_int("rules.limit.faction", 0);
|
||||||
static int rule = -1;
|
assert(rule >= 0);
|
||||||
if (rule < 0 || gamecookie != global.cookie) {
|
|
||||||
rule = get_param_int(global.parameters, "rules.limit.faction", 0);
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
assert(rule >= 0);
|
|
||||||
}
|
|
||||||
return rule;
|
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
|
static int
|
||||||
default_wage(const region * r, const faction * f, const race * rc, int in_turn)
|
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;
|
order *result = 0;
|
||||||
assert(i < MAXLOCALES);
|
assert(i < MAXLOCALES);
|
||||||
|
|
||||||
if (default_keyword!=NOKEYWORD) {
|
if (default_keyword != NOKEYWORD) {
|
||||||
return create_order(default_keyword, lang, 0);
|
return create_order(default_keyword, lang, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1673,12 +1492,40 @@ int entertainmoney(const region * r)
|
||||||
|
|
||||||
int rule_give(void)
|
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)
|
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.
|
/** releases all memory associated with the game state.
|
||||||
|
@ -1718,15 +1565,14 @@ void free_gamedata(void)
|
||||||
while (global.attribs) {
|
while (global.attribs) {
|
||||||
a_remove(&global.attribs, 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 * game_name(void) {
|
||||||
const char * param = get_param(global.parameters, "game.name");
|
const char * param = config_get("game.name");
|
||||||
return param ? param : global.gamename;
|
return param ? param : global.gamename;
|
||||||
}
|
}
|
||||||
|
|
||||||
int game_id(void) {
|
int game_id(void) {
|
||||||
return get_param_int(global.parameters, "game.id", 0);
|
return config_get_int("game.id", 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,57 +25,12 @@ extern "C" {
|
||||||
|
|
||||||
/* this should always be the first thing included after platform.h */
|
/* this should always be the first thing included after platform.h */
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
struct param;
|
||||||
/* 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
|
|
||||||
|
|
||||||
/* getunit results: */
|
/* getunit results: */
|
||||||
#define GET_UNIT 0
|
#define GET_UNIT 0
|
||||||
#define GET_NOTFOUND 1
|
#define GET_NOTFOUND 1
|
||||||
#define GET_PEASANTS 2
|
#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 DISPLAYSIZE 8192 /* max. Länge einer Beschreibung, incl trailing 0 */
|
||||||
#define ORDERSIZE (DISPLAYSIZE*2) /* max. length of an order */
|
#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
|
#define OBJECTIDSIZE (NAMESIZE+5+IDSIZE) /* max. Länge der Strings, die
|
||||||
* von struct unitname, etc. zurückgegeben werden. ohne die 0 */
|
* von struct unitname, etc. zurückgegeben werden. ohne die 0 */
|
||||||
|
|
||||||
#define BAGCAPACITY 20000 /* soviel paßt in einen Bag of Holding */
|
|
||||||
|
|
||||||
/* ----------------- Befehle ----------------------------------- */
|
/* ----------------- Befehle ----------------------------------- */
|
||||||
|
|
||||||
#define want(option) (1<<option)
|
#define want(option) (1<<option)
|
||||||
|
@ -97,9 +50,6 @@ extern "C" {
|
||||||
#define fset(u, i) ((u)->flags |= (i))
|
#define fset(u, i) ((u)->flags |= (i))
|
||||||
#define freset(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 max_magicians(const struct faction * f);
|
||||||
int findoption(const char *s, const struct locale *lang);
|
int findoption(const char *s, const struct locale *lang);
|
||||||
|
|
||||||
|
@ -151,7 +101,6 @@ extern "C" {
|
||||||
int cmp_current_owner(const struct building *b,
|
int cmp_current_owner(const struct building *b,
|
||||||
const struct building *bother);
|
const struct building *bother);
|
||||||
|
|
||||||
bool rule_transfermen(void);
|
|
||||||
bool rule_region_owners(void);
|
bool rule_region_owners(void);
|
||||||
bool rule_stealth_other(void); // units can pretend to be another faction, TARNE PARTEI <no>
|
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]
|
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_WORK 0x00
|
||||||
#define HARVEST_TAXES 0x01
|
#define HARVEST_TAXES 0x01
|
||||||
int rule_blessed_harvest(void);
|
int rule_blessed_harvest(void);
|
||||||
bool rule_auto_taxation(void);
|
|
||||||
#define GIVE_SELF 1
|
#define GIVE_SELF 1
|
||||||
#define GIVE_PEASANTS 2
|
#define GIVE_PEASANTS 2
|
||||||
#define GIVE_LUXURIES 4
|
#define GIVE_LUXURIES 4
|
||||||
|
@ -171,18 +119,6 @@ extern "C" {
|
||||||
#define GIVE_DEFAULT (GIVE_SELF|GIVE_PEASANTS|GIVE_LUXURIES|GIVE_HERBS|GIVE_GOODS)
|
#define GIVE_DEFAULT (GIVE_SELF|GIVE_PEASANTS|GIVE_LUXURIES|GIVE_HERBS|GIVE_GOODS)
|
||||||
int rule_give(void);
|
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);
|
bool has_limited_skills(const struct unit *u);
|
||||||
const struct race *findrace(const char *, const struct locale *);
|
const struct race *findrace(const char *, const struct locale *);
|
||||||
|
|
||||||
|
@ -248,7 +184,6 @@ extern "C" {
|
||||||
const char *gamename;
|
const char *gamename;
|
||||||
struct attrib *attribs;
|
struct attrib *attribs;
|
||||||
unsigned int data_turn;
|
unsigned int data_turn;
|
||||||
struct param *parameters;
|
|
||||||
void *vm_state;
|
void *vm_state;
|
||||||
int data_version; /* TODO: eliminate in favor of gamedata.version */
|
int data_version; /* TODO: eliminate in favor of gamedata.version */
|
||||||
struct _dictionary_ *inifile;
|
struct _dictionary_ *inifile;
|
||||||
|
@ -258,10 +193,6 @@ extern "C" {
|
||||||
const struct race * rc, int in_turn);
|
const struct race * rc, int in_turn);
|
||||||
int(*maintenance) (const struct unit * u);
|
int(*maintenance) (const struct unit * u);
|
||||||
} functions;
|
} 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;
|
} settings;
|
||||||
|
|
||||||
typedef struct helpmode {
|
typedef struct helpmode {
|
||||||
|
@ -271,13 +202,19 @@ extern "C" {
|
||||||
|
|
||||||
const char *dbrace(const struct race *rc);
|
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);
|
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 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);
|
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);
|
double get_param_flt(const struct param *p, const char *key, double def);
|
||||||
void free_params(struct param **pp);
|
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);
|
bool ExpensiveMigrants(void);
|
||||||
int NMRTimeout(void);
|
int NMRTimeout(void);
|
||||||
int LongHunger(const struct unit *u);
|
int LongHunger(const struct unit *u);
|
||||||
|
@ -294,6 +231,7 @@ extern "C" {
|
||||||
void init_parameters(struct locale *lang);
|
void init_parameters(struct locale *lang);
|
||||||
|
|
||||||
void free_gamedata(void);
|
void free_gamedata(void);
|
||||||
|
void free_config(void);
|
||||||
|
|
||||||
extern struct helpmode helpmodes[];
|
extern struct helpmode helpmodes[];
|
||||||
extern const char *parameters[];
|
extern const char *parameters[];
|
||||||
|
|
|
@ -130,6 +130,8 @@ static void test_get_set_param(CuTest * tc)
|
||||||
set_param(&par, "bar", "foo");
|
set_param(&par, "bar", "foo");
|
||||||
CuAssertStrEquals(tc, "bar", get_param(par, "foo"));
|
CuAssertStrEquals(tc, "bar", get_param(par, "foo"));
|
||||||
CuAssertStrEquals(tc, "foo", get_param(par, "bar"));
|
CuAssertStrEquals(tc, "foo", get_param(par, "bar"));
|
||||||
|
set_param(&par, "bar", "bar");
|
||||||
|
CuAssertStrEquals(tc, "bar", get_param(par, "bar"));
|
||||||
set_param(&par, "bar", NULL);
|
set_param(&par, "bar", NULL);
|
||||||
CuAssertPtrEquals(tc, NULL, (void *)get_param(par, "bar"));
|
CuAssertPtrEquals(tc, NULL, (void *)get_param(par, "bar"));
|
||||||
free_params(&par);
|
free_params(&par);
|
||||||
|
@ -175,11 +177,11 @@ static void test_forbiddenid(CuTest *tc) {
|
||||||
CuSuite *get_config_suite(void)
|
CuSuite *get_config_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
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_get_set_param);
|
||||||
SUITE_ADD_TEST(suite, test_param_int);
|
SUITE_ADD_TEST(suite, test_param_int);
|
||||||
SUITE_ADD_TEST(suite, test_param_flt);
|
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;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
#include "alliance.h"
|
#include "alliance.h"
|
||||||
#include "ally.h"
|
#include "ally.h"
|
||||||
|
#include "curse.h"
|
||||||
#include "equipment.h"
|
#include "equipment.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
@ -54,10 +55,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
/* libc includes */
|
/* libc includes */
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
faction *factions;
|
faction *factions;
|
||||||
|
|
||||||
|
@ -208,6 +210,11 @@ int resolve_faction(variant id, void *address)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool faction_id_is_unused(int id)
|
||||||
|
{
|
||||||
|
return findfaction(id) == NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#define MAX_FACTION_ID (36*36*36*36)
|
#define MAX_FACTION_ID (36*36*36*36)
|
||||||
|
|
||||||
static int unused_faction_id(void)
|
static int unused_faction_id(void)
|
||||||
|
@ -568,7 +575,7 @@ static int allied_skilllimit(const faction * f, skill_t sk)
|
||||||
{
|
{
|
||||||
static int value = -1;
|
static int value = -1;
|
||||||
if (value < 0) {
|
if (value < 0) {
|
||||||
value = get_param_int(global.parameters, "alliance.skilllimit", 0);
|
value = config_get_int("alliance.skilllimit", 0);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
@ -611,8 +618,7 @@ int skill_limit(faction * f, skill_t sk)
|
||||||
m = max_magicians(f);
|
m = max_magicians(f);
|
||||||
}
|
}
|
||||||
else if (sk == SK_ALCHEMY) {
|
else if (sk == SK_ALCHEMY) {
|
||||||
m = get_param_int(global.parameters, "rules.maxskills.alchemy",
|
m = config_get_int("rules.maxskills.alchemy", MAXALCHEMISTS);
|
||||||
MAXALCHEMISTS);
|
|
||||||
}
|
}
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
@ -708,3 +714,62 @@ void faction_setorigin(faction * f, int id, int x, int y)
|
||||||
addlist(&f->ursprung, ur);
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -160,6 +160,20 @@ extern "C" {
|
||||||
/* skills */
|
/* skills */
|
||||||
int skill_limit(struct faction *f, skill_t sk);
|
int skill_limit(struct faction *f, skill_t sk);
|
||||||
int count_skill(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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -533,7 +533,7 @@ static void disable_feature(const char *str) {
|
||||||
}
|
}
|
||||||
_snprintf(name, sizeof(name), "%s.enabled", str);
|
_snprintf(name, sizeof(name), "%s.enabled", str);
|
||||||
log_info("disable feature %s\n", name);
|
log_info("disable feature %s\n", name);
|
||||||
set_param(&global.parameters, name, "0");
|
config_set(name, "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void json_disable_features(cJSON *json) {
|
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) {
|
for (child = json->child; child; child = child->next) {
|
||||||
if (child->valuestring) {
|
if (child->valuestring) {
|
||||||
set_param(&global.parameters, child->string, child->valuestring);
|
config_set(child->string, child->valuestring);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char value[32];
|
char value[32];
|
||||||
|
@ -798,7 +798,7 @@ static void json_settings(cJSON *json) {
|
||||||
else {
|
else {
|
||||||
_snprintf(value, sizeof(value), "%d", child->valueint);
|
_snprintf(value, sizeof(value), "%d", child->valueint);
|
||||||
}
|
}
|
||||||
set_param(&global.parameters, child->string, value);
|
config_set(child->string, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,11 +74,11 @@ static void test_settings(CuTest * tc)
|
||||||
|
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
json_config(json);
|
json_config(json);
|
||||||
CuAssertStrEquals(tc, "1", get_param(global.parameters, "true"));
|
CuAssertStrEquals(tc, "1", config_get("true"));
|
||||||
CuAssertStrEquals(tc, "0", get_param(global.parameters, "false"));
|
CuAssertStrEquals(tc, "0", config_get("false"));
|
||||||
CuAssertStrEquals(tc, "1d4", get_param(global.parameters, "string"));
|
CuAssertStrEquals(tc, "1d4", config_get("string"));
|
||||||
CuAssertIntEquals(tc, 14, get_param_int(global.parameters, "integer", 0));
|
CuAssertIntEquals(tc, 14, config_get_int("integer", 0));
|
||||||
CuAssertDblEquals(tc, 1.5f, get_param_flt(global.parameters, "float", 0), 0.01);
|
CuAssertDblEquals(tc, 1.5f, config_get_flt("float", 0), 0.01);
|
||||||
cJSON_Delete(json);
|
cJSON_Delete(json);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
@ -117,13 +117,13 @@ static void test_disable(CuTest * tc)
|
||||||
CuAssertTrue(tc, !keyword_disabled(K_BANNER));
|
CuAssertTrue(tc, !keyword_disabled(K_BANNER));
|
||||||
CuAssertTrue(tc, !keyword_disabled(K_PAY));
|
CuAssertTrue(tc, !keyword_disabled(K_PAY));
|
||||||
CuAssertTrue(tc, !keyword_disabled(K_BESIEGE));
|
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);
|
json_config(json);
|
||||||
CuAssertTrue(tc, !skill_enabled(SK_ALCHEMY));
|
CuAssertTrue(tc, !skill_enabled(SK_ALCHEMY));
|
||||||
CuAssertTrue(tc, !keyword_disabled(K_BANNER));
|
CuAssertTrue(tc, !keyword_disabled(K_BANNER));
|
||||||
CuAssertTrue(tc, keyword_disabled(K_PAY));
|
CuAssertTrue(tc, keyword_disabled(K_PAY));
|
||||||
CuAssertTrue(tc, keyword_disabled(K_BESIEGE));
|
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);
|
cJSON_Delete(json);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,9 @@ extern "C" {
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "direction.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
|
/* FAST_CONNECT: regions are directly connected to neighbours, saves doing
|
||||||
a hash-access each time a neighbour is needed, 6 extra pointers per hex */
|
a hash-access each time a neighbour is needed, 6 extra pointers per hex */
|
||||||
#define FAST_CONNECT
|
#define FAST_CONNECT
|
||||||
|
|
|
@ -29,12 +29,7 @@
|
||||||
|
|
||||||
static double ResourceFactor(void)
|
static double ResourceFactor(void)
|
||||||
{
|
{
|
||||||
static double value = -1.0;
|
return config_get_flt("resource.factor", 1.0);
|
||||||
if (value < 0) {
|
|
||||||
const char *str = get_param(global.parameters, "resource.factor");
|
|
||||||
value = str ? atof(str) : 1.0;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_resources(region * r)
|
void update_resources(region * r)
|
||||||
|
@ -82,10 +77,7 @@ void terraform_resources(region * r)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
const terrain_type *terrain = r->terrain;
|
const terrain_type *terrain = r->terrain;
|
||||||
static int terraform_all = -1;
|
bool terraform_all = config_get_int("rules.terraform.all", 0) != 0;
|
||||||
if (terraform_all < 0) {
|
|
||||||
terraform_all = get_param_int(global.parameters, "rules.terraform.all", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (terrain->production == NULL)
|
if (terrain->production == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1449,7 +1449,6 @@ int readgame(const char *filename, bool backup)
|
||||||
global.data_turn = turn;
|
global.data_turn = turn;
|
||||||
log_debug(" - reading turn %d\n", turn);
|
log_debug(" - reading turn %d\n", turn);
|
||||||
rng_init(turn);
|
rng_init(turn);
|
||||||
++global.cookie;
|
|
||||||
READ_INT(&store, &nread); /* max_unique_id = ignore */
|
READ_INT(&store, &nread); /* max_unique_id = ignore */
|
||||||
READ_INT(&store, &nextborder);
|
READ_INT(&store, &nextborder);
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ static void test_readwrite_unit(CuTest * tc)
|
||||||
sprintf(path, "%s/%s", datapath(), filename);
|
sprintf(path, "%s/%s", datapath(), filename);
|
||||||
|
|
||||||
data = gamedata_open(path, "wb");
|
data = gamedata_open(path, "wb");
|
||||||
|
CuAssertPtrNotNull(tc, data); // TODO: intermittent test
|
||||||
write_unit(data, u);
|
write_unit(data, u);
|
||||||
gamedata_close(data);
|
gamedata_close(data);
|
||||||
|
|
||||||
|
|
|
@ -271,7 +271,7 @@ const char *write_shipname(const ship * sh, char *ibuf, size_t size)
|
||||||
|
|
||||||
static int ShipSpeedBonus(const unit * u)
|
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) {
|
if (level > 0) {
|
||||||
ship *sh = u->ship;
|
ship *sh = u->ship;
|
||||||
int skl = effskill(u, SK_SAILING, 0);
|
int skl = effskill(u, SK_SAILING, 0);
|
||||||
|
|
|
@ -399,7 +399,7 @@ static ship *setup_ship(void) {
|
||||||
region *r;
|
region *r;
|
||||||
ship_type *stype;
|
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));
|
r = test_create_region(0, 0, test_create_terrain("ocean", 0));
|
||||||
stype = test_create_shiptype("longboat");
|
stype = test_create_shiptype("longboat");
|
||||||
stype->cptskill = 1;
|
stype->cptskill = 1;
|
||||||
|
@ -558,7 +558,7 @@ static void test_shipspeed_max_range(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
sh = setup_ship();
|
sh = setup_ship();
|
||||||
setup_crew(sh, 0, &cap, &crew);
|
setup_crew(sh, 0, &cap, &crew);
|
||||||
set_param(&global.parameters, "movement.shipspeed.skillbonus", "5");
|
config_set("movement.shipspeed.skillbonus", "5");
|
||||||
r = sh->region;
|
r = sh->region;
|
||||||
f = test_create_faction(0);
|
f = test_create_faction(0);
|
||||||
assert(r && f);
|
assert(r && f);
|
||||||
|
|
|
@ -212,7 +212,7 @@ void sk_set(skill * sv, int level)
|
||||||
|
|
||||||
static int rule_random_progress(void)
|
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)
|
int skill_weeks(int level)
|
||||||
|
|
|
@ -181,22 +181,16 @@ bool is_astral(const region * r)
|
||||||
|
|
||||||
plane *get_astralplane(void)
|
plane *get_astralplane(void)
|
||||||
{
|
{
|
||||||
static plane *astralspace;
|
plane *astralspace = 0;
|
||||||
static int rule_astralplane = -1;
|
int rule_astralplane = config_get_int("modules.astralspace", 1);
|
||||||
static int gamecookie = -1;
|
|
||||||
if (rule_astralplane < 0) {
|
|
||||||
rule_astralplane =
|
|
||||||
get_param_int(global.parameters, "modules.astralspace", 1);
|
|
||||||
}
|
|
||||||
if (!rule_astralplane) {
|
if (!rule_astralplane) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (gamecookie != global.cookie) {
|
if (!astralspace) {
|
||||||
astralspace = getplanebyname("Astralraum");
|
astralspace = getplanebyname("Astralraum");
|
||||||
gamecookie = global.cookie;
|
|
||||||
}
|
}
|
||||||
|
if (!astralspace) {
|
||||||
if (astralspace == NULL) {
|
|
||||||
astralspace = create_new_plane(1, "Astralraum",
|
astralspace = create_new_plane(1, "Astralraum",
|
||||||
TE_CENTER_X - 500, TE_CENTER_X + 500,
|
TE_CENTER_X - 500, TE_CENTER_X + 500,
|
||||||
TE_CENTER_Y - 500, TE_CENTER_Y + 500, 0);
|
TE_CENTER_Y - 500, TE_CENTER_Y + 500, 0);
|
||||||
|
|
|
@ -232,7 +232,7 @@ static buddy *get_friends(const unit * u, int *numfriends)
|
||||||
for (u2 = r->units; u2; u2 = u2->next) {
|
for (u2 = r->units; u2; u2 = u2->next) {
|
||||||
if (u2->faction != f && u2->number > 0) {
|
if (u2->faction != f && u2->number > 0) {
|
||||||
int allied = 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);
|
allied = (f->alliance && f->alliance == u2->faction->alliance);
|
||||||
}
|
}
|
||||||
else if (alliedunit(u, u2->faction, HELP_MONEY)
|
else if (alliedunit(u, u2->faction, HELP_MONEY)
|
||||||
|
@ -850,17 +850,13 @@ void leave_building(unit * u)
|
||||||
|
|
||||||
bool can_leave(unit * u)
|
bool can_leave(unit * u)
|
||||||
{
|
{
|
||||||
static int gamecookie = -1;
|
int rule_leave;
|
||||||
static int rule_leave = -1;
|
|
||||||
|
|
||||||
if (!u->building) {
|
if (!u->building) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rule_leave < 0 || gamecookie != global.cookie) {
|
rule_leave = config_get_int("rules.move.owner_leave", 0);
|
||||||
gamecookie = global.cookie;
|
|
||||||
rule_leave = get_param_int(global.parameters, "rules.move.owner_leave", 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rule_leave!=0 && u->building && u == building_owner(u->building)) {
|
if (rule_leave!=0 && u->building && u == building_owner(u->building)) {
|
||||||
return false;
|
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);
|
skill = skillmod(u->attribs, u, r, sk, skill, SMF_ALWAYS);
|
||||||
|
|
||||||
if (hunger_red_skill == -1) {
|
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) {
|
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) {
|
if (mlevel > 0) {
|
||||||
int skillcap = SkillCap(sv->id);
|
int skillcap = SkillCap(sv->id);
|
||||||
if (skillcap && mlevel > skillcap) {
|
if (skillcap>0 && mlevel > skillcap) {
|
||||||
return skillcap;
|
return skillcap;
|
||||||
}
|
}
|
||||||
return mlevel;
|
return mlevel;
|
||||||
|
@ -1725,18 +1721,13 @@ void unit_addorder(unit * u, order * ord)
|
||||||
|
|
||||||
int unit_max_hp(const unit * u)
|
int unit_max_hp(const unit * u)
|
||||||
{
|
{
|
||||||
static int rules_stamina = -1;
|
|
||||||
int h;
|
int h;
|
||||||
double p;
|
double p;
|
||||||
static const curse_type *heal_ct = NULL;
|
static const curse_type *heal_ct = NULL;
|
||||||
|
int rule_stamina = config_get_int("rules.stamina", STAMINA_AFFECTS_HP);
|
||||||
if (rules_stamina < 0) {
|
|
||||||
rules_stamina =
|
|
||||||
get_param_int(global.parameters, "rules.stamina", STAMINA_AFFECTS_HP);
|
|
||||||
}
|
|
||||||
h = u_race(u)->hitpoints;
|
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;
|
p = pow(effskill(u, SK_STAMINA, u->region) / 2.0, 1.5) * 0.2;
|
||||||
h += (int)(h * p + 0.5);
|
h += (int)(h * p + 0.5);
|
||||||
}
|
}
|
||||||
|
@ -1935,12 +1926,7 @@ bool unit_can_study(const unit *u) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static double produceexp_chance(void) {
|
static double produceexp_chance(void) {
|
||||||
static int update = 0;
|
return config_get_flt("study.from_use", 1.0 / 3);
|
||||||
if (update != global.cookie) {
|
|
||||||
global.producexpchance_ = get_param_flt(global.parameters, "study.from_use", 1.0 / 3);
|
|
||||||
update = global.cookie;
|
|
||||||
}
|
|
||||||
return global.producexpchance_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void produceexp_ex(struct unit *u, skill_t sk, int n, bool (*learn)(unit *, skill_t, double))
|
void produceexp_ex(struct unit *u, skill_t sk, int n, bool (*learn)(unit *, skill_t, double))
|
||||||
|
|
|
@ -26,6 +26,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAXUNITS 1048573 /* must be prime for hashing. 524287 was >90% full */
|
||||||
struct skill;
|
struct skill;
|
||||||
struct item;
|
struct item;
|
||||||
struct sc_mage;
|
struct sc_mage;
|
||||||
|
|
|
@ -284,15 +284,15 @@ static void test_skill_hunger(CuTest *tc) {
|
||||||
set_level(u, SK_SAILING, 6);
|
set_level(u, SK_SAILING, 6);
|
||||||
fset(u, UFL_HUNGER);
|
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_ARMORER, 0));
|
||||||
CuAssertIntEquals(tc, 6, effskill(u, SK_SAILING, 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_ARMORER, 0));
|
||||||
CuAssertIntEquals(tc, 3, effskill(u, SK_SAILING, 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, 3, effskill(u, SK_ARMORER, 0));
|
||||||
CuAssertIntEquals(tc, 5, effskill(u, SK_SAILING, 0));
|
CuAssertIntEquals(tc, 5, effskill(u, SK_SAILING, 0));
|
||||||
set_level(u, SK_SAILING, 2);
|
set_level(u, SK_SAILING, 2);
|
||||||
|
@ -371,7 +371,7 @@ static void test_produceexp(CuTest *tc) {
|
||||||
g_tc = tc;
|
g_tc = tc;
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
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, 1, cb_learn_one);
|
||||||
produceexp_ex(u, SK_ALCHEMY, 2, cb_learn_two);
|
produceexp_ex(u, SK_ALCHEMY, 2, cb_learn_two);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
|
125
src/laws.c
125
src/laws.c
|
@ -117,14 +117,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
static bool RemoveNMRNewbie(void)
|
static bool RemoveNMRNewbie(void)
|
||||||
{
|
{
|
||||||
static int value = -1;
|
int value = config_get_int("nmr.removenewbie", 0);
|
||||||
static int gamecookie = -1;
|
return value != 0;
|
||||||
|
|
||||||
if (value < 0 || gamecookie != global.cookie) {
|
|
||||||
value = get_param_int(global.parameters, "nmr.removenewbie", 0);
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
}
|
|
||||||
return value!=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void age_unit(region * r, unit * u)
|
static void age_unit(region * r, unit * u)
|
||||||
|
@ -251,12 +245,12 @@ static void calculate_emigration(region * r)
|
||||||
|
|
||||||
static double peasant_growth_factor(void)
|
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
|
#ifdef SLOWLUCK
|
||||||
int peasant_luck_effect(int peasants, int luck, int maxp, double variance) {
|
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();
|
double factor = peasant_growth_factor();
|
||||||
for (n = peasants; n && luck; --n) {
|
for (n = peasants; n && luck; --n) {
|
||||||
int chances = 0;
|
int chances = 0;
|
||||||
|
@ -281,7 +275,7 @@ int peasant_luck_effect(int peasants, int luck, int maxp, double variance) {
|
||||||
#else
|
#else
|
||||||
static double peasant_luck_factor(void)
|
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)
|
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 n, satiated;
|
||||||
int dead = 0;
|
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;
|
int luck = 0;
|
||||||
double fraction = peasants * peasant_growth_factor();
|
double fraction = peasants * peasant_growth_factor();
|
||||||
int births = RAND_ROUND(fraction);
|
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,
|
* Großteil. dead kann nie größer als rpeasants(r) - satiated werden,
|
||||||
* so dass rpeasants(r) >= 0 bleiben muß. */
|
* so dass rpeasants(r) >= 0 bleiben muß. */
|
||||||
|
|
||||||
/* Es verhungert maximal die unterernährten Bevölkerung. */
|
/* Es verhungert maximal die unterernährten Bevölkerung. */
|
||||||
|
|
||||||
n = _min(peasants - satiated, rpeasants(r));
|
n = _min(peasants - satiated, rpeasants(r));
|
||||||
dead += (int)(0.5 + n * PEASANT_STARVATION_CHANCE);
|
dead += (int)(0.5 + n * PEASANT_STARVATION_CHANCE);
|
||||||
|
@ -429,7 +423,7 @@ static void horses(region * r)
|
||||||
int i;
|
int i;
|
||||||
double growth =
|
double growth =
|
||||||
(RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses -
|
(RESOURCE_QUANTITY * HORSEGROWTH * 200 * (maxhorses -
|
||||||
horses)) / maxhorses;
|
horses)) / maxhorses;
|
||||||
|
|
||||||
if (growth > 0) {
|
if (growth > 0) {
|
||||||
if (a_find(r->attribs, &at_horseluck))
|
if (a_find(r->attribs, &at_horseluck))
|
||||||
|
@ -488,7 +482,7 @@ extern struct attrib_type at_germs;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
growing_trees_e3(region * r, const int current_season,
|
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] = {
|
static const int transform[4][3] = {
|
||||||
{ -1, -1, 0 },
|
{ -1, -1, 0 },
|
||||||
|
@ -698,7 +692,7 @@ void immigration(void)
|
||||||
{
|
{
|
||||||
region *r;
|
region *r;
|
||||||
log_info(" - Einwanderung...");
|
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) {
|
for (r = regions; r; r = r->next) {
|
||||||
if (r->land && r->land->newpeasants) {
|
if (r->land && r->land->newpeasants) {
|
||||||
int rp = rpeasants(r) + r->land->newpeasants;
|
int rp = rpeasants(r) + r->land->newpeasants;
|
||||||
|
@ -744,7 +738,7 @@ void nmr_warnings(void)
|
||||||
message *msg = NULL;
|
message *msg = NULL;
|
||||||
for (fa = factions; fa; fa = fa->next) {
|
for (fa = factions; fa; fa = fa->next) {
|
||||||
int warn = 0;
|
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) {
|
if (f->alliance && f->alliance == fa->alliance) {
|
||||||
warn = 1;
|
warn = 1;
|
||||||
}
|
}
|
||||||
|
@ -757,7 +751,7 @@ void nmr_warnings(void)
|
||||||
if (msg == NULL) {
|
if (msg == NULL) {
|
||||||
msg =
|
msg =
|
||||||
msg_message("warn_dropout", "faction turns", f,
|
msg_message("warn_dropout", "faction turns", f,
|
||||||
turn - f->lastorders);
|
turn - f->lastorders);
|
||||||
}
|
}
|
||||||
add_message(&fa->msgs, msg);
|
add_message(&fa->msgs, msg);
|
||||||
}
|
}
|
||||||
|
@ -791,12 +785,7 @@ void demographics(void)
|
||||||
/* die Nachfrage nach Produkten steigt. */
|
/* die Nachfrage nach Produkten steigt. */
|
||||||
struct demand *dmd;
|
struct demand *dmd;
|
||||||
if (r->land) {
|
if (r->land) {
|
||||||
static int plant_rules = -1;
|
int plant_rules = config_get_int("rules.grow.formula", 0);
|
||||||
|
|
||||||
if (plant_rules < 0) {
|
|
||||||
plant_rules =
|
|
||||||
get_param_int(global.parameters, "rules.grow.formula", 0);
|
|
||||||
}
|
|
||||||
for (dmd = r->land->demands; dmd; dmd = dmd->next) {
|
for (dmd = r->land->demands; dmd; dmd = dmd->next) {
|
||||||
if (dmd->value > 0 && dmd->value < MAXDEMAND) {
|
if (dmd->value > 0 && dmd->value < MAXDEMAND) {
|
||||||
float rise = DMRISE;
|
float rise = DMRISE;
|
||||||
|
@ -994,11 +983,7 @@ static int mayboard(const unit * u, ship * sh)
|
||||||
|
|
||||||
static bool CheckOverload(void)
|
static bool CheckOverload(void)
|
||||||
{
|
{
|
||||||
static int value = -1;
|
return config_get_int("rules.check_overload", 0) != 0;
|
||||||
if (value < 0) {
|
|
||||||
value = get_param_int(global.parameters, "rules.check_overload", 0);
|
|
||||||
}
|
|
||||||
return value != 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int enter_ship(unit * u, struct order *ord, int id, bool report)
|
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 void nmr_death(faction * f)
|
||||||
{
|
{
|
||||||
static int rule = -1;
|
int rule = config_get_int("rules.nmr.destroy", 0) != 0;
|
||||||
if (rule < 0)
|
|
||||||
rule = get_param_int(global.parameters, "rules.nmr.destroy", 0);
|
|
||||||
if (rule) {
|
if (rule) {
|
||||||
unit *u;
|
unit *u;
|
||||||
for (u = f->units; u; u = u->nextF) {
|
for (u = f->units; u; u = u->nextF) {
|
||||||
|
@ -1317,7 +1300,7 @@ int ally_cmd(unit * u, struct order *ord)
|
||||||
|
|
||||||
if (!s || !s[0]) {
|
if (!s || !s[0]) {
|
||||||
keyword = P_ANY;
|
keyword = P_ANY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
keyword = findparam(s, u->faction->locale);
|
keyword = findparam(s, u->faction->locale);
|
||||||
}
|
}
|
||||||
|
@ -1498,9 +1481,9 @@ int prefix_cmd(unit * u, struct order *ord)
|
||||||
if (fval(u, UFL_GROUP)) {
|
if (fval(u, UFL_GROUP)) {
|
||||||
attrib *a = a_find(u->attribs, &at_group);
|
attrib *a = a_find(u->attribs, &at_group);
|
||||||
if (a) {
|
if (a) {
|
||||||
group *g = (group *)a->data.v;
|
group *g = (group *)a->data.v;
|
||||||
ap = &g->attribs;
|
ap = &g->attribs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
set_prefix(ap, race_prefixes[var.i]);
|
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 */
|
else { /* BOTSCHAFT an EINHEIT */
|
||||||
ADDMSG(&f->msgs,
|
ADDMSG(&f->msgs,
|
||||||
msg_message("unitmessage", "region unit sender string", r,
|
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 */
|
/* hp_p : Trefferpunkte */
|
||||||
bytes =
|
bytes =
|
||||||
slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(f->locale,
|
slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(f->locale,
|
||||||
"stat_hitpoints"));
|
"stat_hitpoints"));
|
||||||
assert(bytes <= INT_MAX);
|
assert(bytes <= INT_MAX);
|
||||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||||
WARN_STATIC_BUFFER();
|
WARN_STATIC_BUFFER();
|
||||||
|
@ -2318,7 +2301,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
|
||||||
/* b_attacke : Angriff */
|
/* b_attacke : Angriff */
|
||||||
bytes =
|
bytes =
|
||||||
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_attack"),
|
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);
|
assert(bytes <= INT_MAX);
|
||||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||||
WARN_STATIC_BUFFER();
|
WARN_STATIC_BUFFER();
|
||||||
|
@ -2326,7 +2309,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
|
||||||
/* b_defense : Verteidigung */
|
/* b_defense : Verteidigung */
|
||||||
bytes =
|
bytes =
|
||||||
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_defense"),
|
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);
|
assert(bytes <= INT_MAX);
|
||||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||||
WARN_STATIC_BUFFER();
|
WARN_STATIC_BUFFER();
|
||||||
|
@ -2385,12 +2368,12 @@ static bool display_race(faction * f, unit * u, const race * rc)
|
||||||
case AT_STANDARD:
|
case AT_STANDARD:
|
||||||
bytes =
|
bytes =
|
||||||
(size_t)_snprintf(bufp, size, "%s (%s)",
|
(size_t)_snprintf(bufp, size, "%s (%s)",
|
||||||
LOC(f->locale, "attack_standard"), rc->def_damage);
|
LOC(f->locale, "attack_standard"), rc->def_damage);
|
||||||
break;
|
break;
|
||||||
case AT_NATURAL:
|
case AT_NATURAL:
|
||||||
bytes =
|
bytes =
|
||||||
(size_t)_snprintf(bufp, size, "%s (%s)",
|
(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;
|
break;
|
||||||
case AT_SPELL:
|
case AT_SPELL:
|
||||||
case AT_COMBATSPELL:
|
case AT_COMBATSPELL:
|
||||||
|
@ -2402,7 +2385,7 @@ static bool display_race(faction * f, unit * u, const race * rc)
|
||||||
case AT_STRUCTURAL:
|
case AT_STRUCTURAL:
|
||||||
bytes =
|
bytes =
|
||||||
(size_t)_snprintf(bufp, size, "%s (%s)",
|
(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;
|
break;
|
||||||
default:
|
default:
|
||||||
bytes = 0;
|
bytes = 0;
|
||||||
|
@ -2506,7 +2489,7 @@ int promotion_cmd(unit * u, struct order *ord)
|
||||||
if (maxheroes(u->faction) < countheroes(u->faction) + u->number) {
|
if (maxheroes(u->faction) < countheroes(u->faction) + u->number) {
|
||||||
ADDMSG(&u->faction->msgs,
|
ADDMSG(&u->faction->msgs,
|
||||||
msg_feedback(u, ord, "heroes_maxed", "max count",
|
msg_feedback(u, ord, "heroes_maxed", "max count",
|
||||||
maxheroes(u->faction), countheroes(u->faction)));
|
maxheroes(u->faction), countheroes(u->faction)));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (!valid_race(u->faction, u_race(u))) {
|
if (!valid_race(u->faction, u_race(u))) {
|
||||||
|
@ -2748,14 +2731,13 @@ void sinkships(struct region * r)
|
||||||
if (fval(r->terrain, SEA_REGION)) {
|
if (fval(r->terrain, SEA_REGION)) {
|
||||||
if (!enoughsailors(sh, crew_skill(sh))) {
|
if (!enoughsailors(sh, crew_skill(sh))) {
|
||||||
// ship is at sea, but not enough people to control it
|
// ship is at sea, but not enough people to control it
|
||||||
double dmg = get_param_flt(global.parameters,
|
double dmg = config_get_flt("rules.ship.damage.nocrewocean", 0.3);
|
||||||
"rules.ship.damage.nocrewocean",
|
|
||||||
0.30F);
|
|
||||||
damage_ship(sh, dmg);
|
damage_ship(sh, dmg);
|
||||||
}
|
}
|
||||||
} else if (!ship_owner(sh)) {
|
}
|
||||||
|
else if (!ship_owner(sh)) {
|
||||||
// any ship lying around without an owner slowly rots
|
// 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);
|
damage_ship(sh, dmg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3288,14 +3270,14 @@ void new_units(void)
|
||||||
if (err == 1) {
|
if (err == 1) {
|
||||||
ADDMSG(&u->faction->msgs,
|
ADDMSG(&u->faction->msgs,
|
||||||
msg_feedback(u, makeord,
|
msg_feedback(u, makeord,
|
||||||
"too_many_units_in_alliance",
|
"too_many_units_in_alliance",
|
||||||
"allowed", maxunits(u->faction)));
|
"allowed", maxunits(u->faction)));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ADDMSG(&u->faction->msgs,
|
ADDMSG(&u->faction->msgs,
|
||||||
msg_feedback(u, makeord,
|
msg_feedback(u, makeord,
|
||||||
"too_many_units_in_faction",
|
"too_many_units_in_faction",
|
||||||
"allowed", maxunits(u->faction)));
|
"allowed", maxunits(u->faction)));
|
||||||
}
|
}
|
||||||
ordp = &makeord->next;
|
ordp = &makeord->next;
|
||||||
|
|
||||||
|
@ -3368,7 +3350,7 @@ void update_long_order(unit * u)
|
||||||
}
|
}
|
||||||
|
|
||||||
// hungry units do not get long orders:
|
// hungry units do not get long orders:
|
||||||
if (hunger) {
|
if (hunger) {
|
||||||
if (u->old_orders) {
|
if (u->old_orders) {
|
||||||
// keep looking for repeated orders that might clear the old_orders
|
// keep looking for repeated orders that might clear the old_orders
|
||||||
continue;
|
continue;
|
||||||
|
@ -3440,7 +3422,8 @@ void update_long_order(unit * u)
|
||||||
if (hunger) {
|
if (hunger) {
|
||||||
// Hungernde Einheiten führen NUR den default-Befehl aus
|
// Hungernde Einheiten führen NUR den default-Befehl aus
|
||||||
set_order(&u->thisorder, default_order(u->faction->locale));
|
set_order(&u->thisorder, default_order(u->faction->locale));
|
||||||
} else if (!exclusive) {
|
}
|
||||||
|
else if (!exclusive) {
|
||||||
// Wenn die Einheit handelt oder zaubert, muss der Default-Befehl gelöscht werden.
|
// Wenn die Einheit handelt oder zaubert, muss der Default-Befehl gelöscht werden.
|
||||||
set_order(&u->thisorder, NULL);
|
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;
|
return EUNUSABLE;
|
||||||
}
|
}
|
||||||
result = itype->use ? itype->use(u, itype, amount, ord) : 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);
|
use_pooled(u, itype->rtype, GET_DEFAULT, result);
|
||||||
}
|
}
|
||||||
return 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 heal_factor(const unit * u)
|
||||||
{
|
{
|
||||||
static double elf_regen = -1;
|
double elf_regen;
|
||||||
|
|
||||||
switch (old_race(u_race(u))) {
|
switch (old_race(u_race(u))) {
|
||||||
case RC_TROLL:
|
case RC_TROLL:
|
||||||
case RC_DAEMON:
|
case RC_DAEMON:
|
||||||
|
@ -3490,8 +3474,7 @@ static double heal_factor(const unit * u)
|
||||||
case RC_GOBLIN:
|
case RC_GOBLIN:
|
||||||
return 2.0;
|
return 2.0;
|
||||||
case RC_ELF:
|
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)) {
|
if (elf_regen != 1.0 && r_isforest(u->region)) {
|
||||||
return elf_regen;
|
return elf_regen;
|
||||||
}
|
}
|
||||||
|
@ -4266,7 +4249,7 @@ static void do_force_leave(region *r) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rule_force_leave(int flags) {
|
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;
|
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_GUARD, guard_off_cmd, 0, NULL);
|
||||||
add_proc_order(p, K_RESHOW, reshow_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;
|
p += 10;
|
||||||
add_proc_global(p, alliance_cmd, NULL);
|
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 */
|
add_proc_region(p, enter_1, "Betreten (2. Versuch)"); /* to allow a buildingowner to enter the castle pre combat */
|
||||||
|
|
||||||
p += 10;
|
p += 10;
|
||||||
add_proc_region(p, do_battle, "Attackieren");
|
add_proc_global(p, do_battles, "Attackieren");
|
||||||
|
|
||||||
if (!keyword_disabled(K_BESIEGE)) {
|
if (!keyword_disabled(K_BESIEGE)) {
|
||||||
p += 10;
|
p += 10;
|
||||||
|
@ -4369,7 +4352,7 @@ void init_processor(void)
|
||||||
|
|
||||||
p += 10; /* can't allow reserve before siege (weapons) */
|
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 */
|
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)");
|
add_proc_order(p, K_RESERVE, reserve_self, 0, "RESERVE (self)");
|
||||||
p += 10;
|
p += 10;
|
||||||
}
|
}
|
||||||
|
@ -4421,7 +4404,7 @@ void init_processor(void)
|
||||||
p += 10;
|
p += 10;
|
||||||
add_proc_global(p, movement, "Bewegungen");
|
add_proc_global(p, movement, "Bewegungen");
|
||||||
|
|
||||||
if (get_param_int(global.parameters, "work.auto", 0)) {
|
if (config_get_int("work.auto", 0)) {
|
||||||
p += 10;
|
p += 10;
|
||||||
add_proc_region(p, auto_work, "Arbeiten (auto)");
|
add_proc_region(p, auto_work, "Arbeiten (auto)");
|
||||||
}
|
}
|
||||||
|
@ -4429,7 +4412,7 @@ void init_processor(void)
|
||||||
p += 10;
|
p += 10;
|
||||||
add_proc_order(p, K_GUARD, guard_on_cmd, 0, "Bewache (an)");
|
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;
|
p += 10;
|
||||||
add_proc_global(p, encounters, "Zufallsbegegnungen");
|
add_proc_global(p, encounters, "Zufallsbegegnungen");
|
||||||
}
|
}
|
||||||
|
@ -4467,7 +4450,7 @@ void processorders(void)
|
||||||
process();
|
process();
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
|
|
||||||
if (get_param_int(global.parameters, "modules.markets", 0)) {
|
if (config_get_int("modules.markets", 0)) {
|
||||||
do_markets();
|
do_markets();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4476,7 +4459,7 @@ void processorders(void)
|
||||||
remove_empty_units();
|
remove_empty_units();
|
||||||
|
|
||||||
/* must happen AFTER age, because that would destroy them right away */
|
/* 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();
|
wormholes_update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4551,7 +4534,7 @@ void update_subscriptions(void)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
cansee(const faction * f, const region * r, const unit * u, int modifier)
|
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).
|
* oder Zauber (sp_generous, sp_fetchastral).
|
||||||
* Es muss auch niemand aus f in der region sein, wenn sie vom Turm
|
* Es muss auch niemand aus f in der region sein, wenn sie vom Turm
|
||||||
* erblickt wird */
|
* erblickt wird */
|
||||||
|
@ -4653,10 +4636,10 @@ bool cansee_unit(const unit * u, const unit * target, int modifier)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
cansee_durchgezogen(const faction * f, const region * r, const unit * u,
|
cansee_durchgezogen(const faction * f, const region * r, const unit * u,
|
||||||
int modifier)
|
int modifier)
|
||||||
/* r kann != u->region sein, wenn es um durchreisen geht */
|
/* r kann != u->region sein, wenn es um durchreisen geht */
|
||||||
/* und es muss niemand aus f in der region sein, wenn sie vom Turm
|
/* und es muss niemand aus f in der region sein, wenn sie vom Turm
|
||||||
* erblickt wird */
|
* erblickt wird */
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
unit *u2;
|
unit *u2;
|
||||||
|
|
|
@ -233,16 +233,16 @@ static void test_display_cmd(CuTest *tc) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_rule_force_leave(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_ALL));
|
||||||
CuAssertIntEquals(tc, false, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
|
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, false, rule_force_leave(FORCE_LEAVE_ALL));
|
||||||
CuAssertIntEquals(tc, true, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
|
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, true, rule_force_leave(FORCE_LEAVE_ALL));
|
||||||
CuAssertIntEquals(tc, false, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
|
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_ALL));
|
||||||
CuAssertIntEquals(tc, true, rule_force_leave(FORCE_LEAVE_POSTCOMBAT));
|
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)
|
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());
|
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());
|
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());
|
CuAssertIntEquals(tc, 250, rule_alliance_limit());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -432,12 +432,12 @@ static void test_cannot_create_unit_above_limit(CuTest * tc)
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
test_create_world();
|
test_create_world();
|
||||||
f = test_create_faction(NULL);
|
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, 0, checkunitnumber(f, 4));
|
||||||
CuAssertIntEquals(tc, 2, checkunitnumber(f, 5));
|
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, 0, checkunitnumber(f, 3));
|
||||||
CuAssertIntEquals(tc, 1, checkunitnumber(f, 4));
|
CuAssertIntEquals(tc, 1, checkunitnumber(f, 4));
|
||||||
}
|
}
|
||||||
|
@ -533,8 +533,8 @@ static void test_pay_cmd_other_building(CuTest *tc) {
|
||||||
setup_pay_cmd(&fix);
|
setup_pay_cmd(&fix);
|
||||||
f = fix.u1->faction;
|
f = fix.u1->faction;
|
||||||
b = test_create_building(fix.u1->region, bt_get_or_create("lighthouse"));
|
b = test_create_building(fix.u1->region, bt_get_or_create("lighthouse"));
|
||||||
set_param(&global.parameters, "rules.region_owners", "1");
|
config_set("rules.region_owners", "1");
|
||||||
set_param(&global.parameters, "rules.region_owner_pay_building", "lighthouse");
|
config_set("rules.region_owner_pay_building", "lighthouse");
|
||||||
update_owners(b->region);
|
update_owners(b->region);
|
||||||
|
|
||||||
_snprintf(cmd, sizeof(cmd), "NOT %s", itoa36(b->no));
|
_snprintf(cmd, sizeof(cmd), "NOT %s", itoa36(b->no));
|
||||||
|
@ -633,7 +633,7 @@ static void test_newbie_cannot_guard(CuTest *tc) {
|
||||||
guard_fixture fix;
|
guard_fixture fix;
|
||||||
|
|
||||||
setup_guard(&fix, true);
|
setup_guard(&fix, true);
|
||||||
set_param(&global.parameters, "NewbieImmunity", "4");
|
config_set("NewbieImmunity", "4");
|
||||||
CuAssertTrue(tc, IsImmune(fix.u->faction));
|
CuAssertTrue(tc, IsImmune(fix.u->faction));
|
||||||
update_guards();
|
update_guards();
|
||||||
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
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) {
|
static void test_peasant_luck_effect(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
|
||||||
set_param(&global.parameters, "rules.peasants.peasantluck.factor", "10");
|
config_set("rules.peasants.peasantluck.factor", "10");
|
||||||
set_param(&global.parameters, "rules.peasants.growth.factor", "0.001");
|
config_set("rules.peasants.growth.factor", "0.001");
|
||||||
|
|
||||||
statistic_test(tc, 100, 0, 1000, 0, 0, 0);
|
statistic_test(tc, 100, 0, 1000, 0, 0, 0);
|
||||||
statistic_test(tc, 100, 2, 1000, 0, 1, 1);
|
statistic_test(tc, 100, 2, 1000, 0, 1, 1);
|
||||||
statistic_test(tc, 1000, 400, 1000, 0, 3, 3);
|
statistic_test(tc, 1000, 400, 1000, 0, 3, 3);
|
||||||
statistic_test(tc, 1000, 1000, 2000, .5, 1, 501);
|
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);
|
statistic_test(tc, 1000, 1000, 1000, 0, 501, 501);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
@ -1003,7 +1003,7 @@ static void test_long_order_hungry(CuTest *tc) {
|
||||||
// see also default_order
|
// see also default_order
|
||||||
unit *u;
|
unit *u;
|
||||||
test_cleanup();
|
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));
|
u = test_create_unit(test_create_faction(0), test_create_region(0, 0, 0));
|
||||||
fset(u, UFL_HUNGER);
|
fset(u, UFL_HUNGER);
|
||||||
u->faction->locale = get_or_create_locale("de");
|
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) {
|
static void test_nmr_warnings(CuTest *tc) {
|
||||||
faction *f1, *f2;
|
faction *f1, *f2;
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
set_param(&global.parameters, "nmr.timeout", "3");
|
config_set("nmr.timeout", "3");
|
||||||
f1 = test_create_faction(0);
|
f1 = test_create_faction(0);
|
||||||
f2 = test_create_faction(0);
|
f2 = test_create_faction(0);
|
||||||
f2->age = 2;
|
f2->age = 2;
|
||||||
|
|
28
src/magic.c
28
src/magic.c
|
@ -108,20 +108,15 @@ attrib_type at_reportspell = {
|
||||||
** TODO: separate castle-appearance from illusion-effects
|
** TODO: separate castle-appearance from illusion-effects
|
||||||
**/
|
**/
|
||||||
|
|
||||||
static float MagicRegeneration(void)
|
static double MagicRegeneration(void)
|
||||||
{
|
{
|
||||||
static float value = -1.0;
|
return config_get_flt("magic.regeneration", 1.0);
|
||||||
if (value < 0) {
|
|
||||||
const char *str = get_param(global.parameters, "magic.regeneration");
|
|
||||||
value = str ? (float)atof(str) : 1.0F;
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static double MagicPower(double force)
|
static double MagicPower(double force)
|
||||||
{
|
{
|
||||||
if (force > 0) {
|
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;
|
double value = str ? atof(str) : 1.0;
|
||||||
return _max(value * force, 1.0f);
|
return _max(value * force, 1.0f);
|
||||||
}
|
}
|
||||||
|
@ -215,16 +210,11 @@ static void free_mage(attrib * a)
|
||||||
|
|
||||||
bool FactionSpells(void)
|
bool FactionSpells(void)
|
||||||
{
|
{
|
||||||
static int rules_factionspells = -1;
|
return config_get_int("rules.magic.factionlist", 0) != 0;
|
||||||
if (rules_factionspells < 0) {
|
|
||||||
rules_factionspells =
|
|
||||||
get_param_int(global.parameters, "rules.magic.factionlist", 0);
|
|
||||||
}
|
|
||||||
return rules_factionspells!=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_spells(struct quicklist **slistp, magic_t mtype,
|
void read_spells(struct quicklist **slistp, magic_t mtype,
|
||||||
struct storage *store)
|
struct storage *store)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
spell *sp;
|
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;
|
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)) {
|
if (elf_power && u_race(u) == get_race(RC_ELF) && r_isforest(r)) {
|
||||||
++force;
|
++force;
|
||||||
|
@ -1291,7 +1281,7 @@ bool fumble(region * r, unit * u, const spell * sp, int cast_grade)
|
||||||
int effsk = effskill(u, SK_MAGIC, r);
|
int effsk = effskill(u, SK_MAGIC, r);
|
||||||
struct building *b = inside_building(u);
|
struct building *b = inside_building(u);
|
||||||
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
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;
|
sc_mage * mage;
|
||||||
|
|
||||||
if (effsk<=0 || !fumble_enabled) {
|
if (effsk<=0 || !fumble_enabled) {
|
||||||
|
@ -1463,7 +1453,7 @@ void regenerate_aura(void)
|
||||||
double reg_aura;
|
double reg_aura;
|
||||||
int regen;
|
int regen;
|
||||||
double mod;
|
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;
|
if (!regen_enabled) return;
|
||||||
|
|
||||||
|
|
|
@ -162,7 +162,7 @@ static int parse_args(int argc, char **argv, int *exitcode)
|
||||||
switch (argi[1]) {
|
switch (argi[1]) {
|
||||||
case 'r':
|
case 'r':
|
||||||
i = get_arg(argc, argv, 2, i, &arg, 0);
|
i = get_arg(argc, argv, 2, i, &arg, 0);
|
||||||
set_param(&global.parameters, "config.rules", arg);
|
config_set("config.rules", arg);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
i = get_arg(argc, argv, 2, i, &luafile, 0);
|
i = get_arg(argc, argv, 2, i, &luafile, 0);
|
||||||
|
|
|
@ -43,7 +43,7 @@ static void test_market_curse(CuTest * tc)
|
||||||
ltype->rtype->flags |= (RTF_ITEM | RTF_POOLED);
|
ltype->rtype->flags |= (RTF_ITEM | RTF_POOLED);
|
||||||
lux = new_luxurytype(ltype, 0);
|
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 = (building_type *)calloc(1, sizeof(building_type));
|
||||||
btype->_name = _strdup("market");
|
btype->_name = _strdup("market");
|
||||||
|
|
|
@ -222,7 +222,7 @@ faction *get_or_create_monsters(void)
|
||||||
faction *f = findfaction(MONSTER_ID);
|
faction *f = findfaction(MONSTER_ID);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
const race *rc = rc_get_or_create("dragon");
|
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);
|
f = addfaction(email ? email : "noreply@eressea.de", NULL, rc, default_locale, 0);
|
||||||
renumber_faction(f, MONSTER_ID);
|
renumber_faction(f, MONSTER_ID);
|
||||||
faction_setname(f, "Monster");
|
faction_setname(f, "Monster");
|
||||||
|
|
|
@ -82,7 +82,7 @@ static void give_peasants(unit *u, const item_type *itype, int reduce) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static double monster_attack_chance(void) {
|
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)
|
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 */
|
/* dragon gets bored and looks for a different place to go */
|
||||||
ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
|
ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
ta = a_find(u->attribs, &at_targetregion);
|
|
||||||
if (ta != NULL) {
|
if (ta != NULL) {
|
||||||
tr = (region *)ta->data.v;
|
tr = (region *)ta->data.v;
|
||||||
if (tr == NULL || !path_exists(u->region, tr, DRAGON_RANGE, allowed_dragon)) {
|
if (tr == NULL || !path_exists(u->region, tr, DRAGON_RANGE, allowed_dragon)) {
|
||||||
ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
|
ta = set_new_dragon_target(u, u->region, DRAGON_RANGE);
|
||||||
if (ta)
|
if (ta) {
|
||||||
tr = findregion(ta->data.sa[0], ta->data.sa[1]);
|
tr = findregion(ta->data.sa[0], ta->data.sa[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tr != NULL) {
|
if (tr != NULL) {
|
||||||
|
|
103
src/move.c
103
src/move.c
|
@ -81,6 +81,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.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;
|
int *storms;
|
||||||
|
|
||||||
typedef struct traveldir {
|
typedef struct traveldir {
|
||||||
|
@ -319,7 +327,7 @@ int walkingcapacity(const struct unit *u)
|
||||||
if (rbelt) {
|
if (rbelt) {
|
||||||
int belts = i_get(u->items, rbelt->itype);
|
int belts = i_get(u->items, rbelt->itype);
|
||||||
if (belts) {
|
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;
|
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 damage_drift(void)
|
||||||
{
|
{
|
||||||
static float value = -1.0F;
|
return (float)config_get_flt("rules.ship.damage_drift", 0.02);
|
||||||
if (value < 0) {
|
|
||||||
value = (float)get_param_flt(global.parameters, "rules.ship.damage_drift", 0.02F);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void drifting_ships(region * r)
|
static void drifting_ships(region * r)
|
||||||
{
|
{
|
||||||
direction_t d;
|
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)) {
|
if (fval(r->terrain, SEA_REGION)) {
|
||||||
ship **shp = &r->ships;
|
ship **shp = &r->ships;
|
||||||
|
@ -837,24 +841,14 @@ static unit *bewegung_blockiert_von(unit * reisender, region * r)
|
||||||
unit *guard = NULL;
|
unit *guard = NULL;
|
||||||
int guard_count = 0;
|
int guard_count = 0;
|
||||||
int stealth = eff_stealth(reisender, r);
|
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);
|
const struct resource_type *ramulet = get_resourcetype(R_AMULET_OF_TRUE_SEEING);
|
||||||
|
|
||||||
if (gamecookie < 0 || gamecookie != global.cookie) {
|
double base_prob = config_get_flt("rules.guard.base_stop_prob", .3);
|
||||||
base_prob = get_param_flt(global.parameters, "rules.guard.base_stop_prob", .3f);
|
double skill_prob = config_get_flt("rules.guard.skill_stop_prob", .1);
|
||||||
skill_prob = get_param_flt(global.parameters, "rules.guard.skill_stop_prob", .1f);
|
double amulet_prob = config_get_flt("rules.guard.amulet_stop_prob", .1);
|
||||||
amulet_prob = get_param_flt(global.parameters, "rules.guard.amulet_stop_prob", .1f);
|
double guard_number_prob = config_get_flt("rules.guard.guard_number_stop_prob", .001);
|
||||||
guard_number_prob = get_param_flt(global.parameters, "rules.guard.guard_number_stop_prob", .001f);
|
double castle_prob = config_get_flt("rules.guard.castle_stop_prob", .1);
|
||||||
castle_prob = get_param_flt(global.parameters, "rules.guard.castle_stop_prob", .1f);
|
double region_type_prob = config_get_flt("rules.guard.region_type_stop_prob", .1);
|
||||||
region_type_prob = get_param_flt(global.parameters, "rules.guard.region_type_stop_prob", .1f);
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fval(u_race(reisender), RCF_ILLUSIONARY))
|
if (fval(u_race(reisender), RCF_ILLUSIONARY))
|
||||||
return NULL;
|
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;
|
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 *is_guarded(region * r, unit * u, unsigned int mask)
|
||||||
{
|
{
|
||||||
unit *u2 = NULL;
|
unit *u2;
|
||||||
int i, noguards = 1;
|
int noguards = 1;
|
||||||
static unit *guardcache[MAXGUARDCACHE], *lastguard; /* STATIC_XCALL: used across calls */
|
|
||||||
static int gamecookie = -1;
|
|
||||||
|
|
||||||
if (!fval(r, RF_GUARDED)) {
|
if (!fval(r, RF_GUARDED)) {
|
||||||
return NULL;
|
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
|
/* at this point, u2 is the last unit we tested to
|
||||||
* be a guard (and failed), or NULL
|
* be a guard (and failed), or NULL
|
||||||
* i is the position of the first free slot in the cache */
|
* 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)) {
|
if (is_guardian_r(u2)) {
|
||||||
noguards = 0;
|
noguards = 0;
|
||||||
/* u2 is a guard, so worth remembering */
|
|
||||||
if (i < MAXGUARDCACHE)
|
|
||||||
guardcache[i++] = u2;
|
|
||||||
if (is_guardian_u(u2, u, mask)) {
|
if (is_guardian_u(u2, u, mask)) {
|
||||||
/* u2 is our guard. stop processing (we might have to go further next time) */
|
/* u2 is our guard. stop processing (we might have to go further next time) */
|
||||||
lastguard = u2;
|
|
||||||
return 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) {
|
if (noguards) {
|
||||||
/* you are mistaken, sir. there are no guards in these lands */
|
/* 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)) {
|
if (!flying_ship(sh)) {
|
||||||
int stormchance = 0;
|
int stormchance = 0;
|
||||||
int reason;
|
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) {
|
if (storms_enabled) {
|
||||||
int stormyness;
|
int stormyness;
|
||||||
gamedate date;
|
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. */
|
/* storms should be the first thing we do. */
|
||||||
stormchance = stormyness / shipspeed(sh, u);
|
stormchance = stormyness / shipspeed(sh, u);
|
||||||
if (check_leuchtturm(next_point, NULL)) {
|
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) {
|
if (param > 0) {
|
||||||
stormchance /= param;
|
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));
|
ADDMSG(&f->msgs, msg_message("sailnolandingstorm", "ship region", sh, next_point));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
double dmg =
|
double dmg = config_get_flt("rules.ship.damage.nolanding", 0.1);
|
||||||
get_param_flt(global.parameters, "rules.ship.damage.nolanding",
|
|
||||||
0.10F);
|
|
||||||
ADDMSG(&f->msgs, msg_message("sailnolanding", "ship region", sh,
|
ADDMSG(&f->msgs, msg_message("sailnolanding", "ship region", sh,
|
||||||
next_point));
|
next_point));
|
||||||
damage_ship(sh, dmg);
|
damage_ship(sh, dmg);
|
||||||
|
|
|
@ -217,7 +217,7 @@ static void test_walkingcapacity(CuTest *tc) {
|
||||||
assert(itype);
|
assert(itype);
|
||||||
i_change(&u->items, itype, 1);
|
i_change(&u->items, itype, 1);
|
||||||
CuAssertIntEquals(tc, cap + (STRENGTHMULTIPLIER-1) * u->_race->capacity, walkingcapacity(u));
|
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));
|
CuAssertIntEquals(tc, cap + 4 * u->_race->capacity, walkingcapacity(u));
|
||||||
|
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
|
|
@ -21,7 +21,7 @@ static void setup_piracy(void) {
|
||||||
ship_type *st_boat;
|
ship_type *st_boat;
|
||||||
|
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
set_param(&global.parameters, "rules.ship.storms", "0");
|
config_set("rules.ship.storms", "0");
|
||||||
lang = get_or_create_locale("de");
|
lang = get_or_create_locale("de");
|
||||||
locale_setstring(lang, directions[D_EAST], "OSTEN");
|
locale_setstring(lang, directions[D_EAST], "OSTEN");
|
||||||
init_directions(lang);
|
init_directions(lang);
|
||||||
|
|
|
@ -738,9 +738,7 @@ static void move_iceberg(region * r)
|
||||||
|
|
||||||
for (sh = r->ships; sh; sh = sh->next) {
|
for (sh = r->ships; sh; sh = sh->next) {
|
||||||
/* Meldung an Kapitän */
|
/* Meldung an Kapitän */
|
||||||
double dmg =
|
double dmg = config_get_flt("rules.ship.damage.intoiceberg", 0.1);
|
||||||
get_param_flt(global.parameters, "rules.ship.damage.intoiceberg",
|
|
||||||
0.10F);
|
|
||||||
damage_ship(sh, dmg);
|
damage_ship(sh, dmg);
|
||||||
fset(sh, SF_SELECT);
|
fset(sh, SF_SELECT);
|
||||||
}
|
}
|
||||||
|
@ -751,9 +749,7 @@ static void move_iceberg(region * r)
|
||||||
translist(&rc->buildings, &r->buildings, rc->buildings);
|
translist(&rc->buildings, &r->buildings, rc->buildings);
|
||||||
}
|
}
|
||||||
while (rc->ships) {
|
while (rc->ships) {
|
||||||
double dmg =
|
double dmg = config_get_flt("rules.ship.damage.withiceberg", 0.1);
|
||||||
get_param_flt(global.parameters, "rules.ship.damage.withiceberg",
|
|
||||||
0.10F);
|
|
||||||
fset(rc->ships, SF_SELECT);
|
fset(rc->ships, SF_SELECT);
|
||||||
damage_ship(rc->ships, dmg);
|
damage_ship(rc->ships, dmg);
|
||||||
move_ship(rc->ships, rc, r, NULL);
|
move_ship(rc->ships, rc, r, NULL);
|
||||||
|
@ -885,9 +881,7 @@ static void godcurse(void)
|
||||||
ship *sh;
|
ship *sh;
|
||||||
for (sh = r->ships; sh;) {
|
for (sh = r->ships; sh;) {
|
||||||
ship *shn = sh->next;
|
ship *shn = sh->next;
|
||||||
double dmg =
|
double dmg = config_get_flt("rules.ship.damage.godcurse", 0.1);
|
||||||
get_param_flt(global.parameters, "rules.ship.damage.godcurse",
|
|
||||||
0.10F);
|
|
||||||
damage_ship(sh, dmg);
|
damage_ship(sh, dmg);
|
||||||
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
if (sh->damage >= sh->size * DAMAGE_SCALE) {
|
||||||
unit *u = ship_owner(sh);
|
unit *u = ship_owner(sh);
|
||||||
|
@ -968,11 +962,7 @@ static void demon_skillchanges(void)
|
||||||
|
|
||||||
if (fval(u, UFL_HUNGER)) {
|
if (fval(u, UFL_HUNGER)) {
|
||||||
/* hungry demons only go down, never up in skill */
|
/* hungry demons only go down, never up in skill */
|
||||||
static int rule_hunger = -1;
|
int rule_hunger = config_get_int("hunger.demon.skill", 0) != 0;
|
||||||
if (rule_hunger < 0) {
|
|
||||||
rule_hunger =
|
|
||||||
get_param_int(global.parameters, "hunger.demon.skill", 0);
|
|
||||||
}
|
|
||||||
if (rule_hunger) {
|
if (rule_hunger) {
|
||||||
upchance = 0;
|
upchance = 0;
|
||||||
downchance = 15;
|
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
|
#ifdef HERBS_ROT
|
||||||
static void rotting_herbs(void)
|
static void rotting_herbs(void)
|
||||||
{
|
{
|
||||||
static int rule_rot = -1;
|
|
||||||
region *r;
|
region *r;
|
||||||
|
int rule_rot = config_get_int("rules.economy.herbrot", HERBROTCHANCE);
|
||||||
if (rule_rot < 0) {
|
|
||||||
rule_rot =
|
|
||||||
get_param_int(global.parameters, "rules.economy.herbrot", HERBROTCHANCE);
|
|
||||||
}
|
|
||||||
if (rule_rot == 0) return;
|
if (rule_rot == 0) return;
|
||||||
|
|
||||||
for (r = regions; r; r = r->next) {
|
for (r = regions; r; r = r->next) {
|
||||||
|
|
21
src/report.c
21
src/report.c
|
@ -2054,19 +2054,14 @@ const char *charset)
|
||||||
char *bufp;
|
char *bufp;
|
||||||
bool utf8 = _strcmpl(charset, "utf8") == 0 || _strcmpl(charset, "utf-8") == 0;
|
bool utf8 = _strcmpl(charset, "utf8") == 0 || _strcmpl(charset, "utf-8") == 0;
|
||||||
size_t size;
|
size_t size;
|
||||||
|
int thisseason;
|
||||||
/* static variables can cope with writing for different turns */
|
int nextseason;
|
||||||
static int thisseason = -1;
|
gamedate date;
|
||||||
static int nextseason = -1;
|
|
||||||
static int gamecookie = -1;
|
get_gamedate(turn + 1, &date);
|
||||||
if (gamecookie != global.cookie) {
|
thisseason = date.season;
|
||||||
gamedate date;
|
get_gamedate(turn + 2, &date);
|
||||||
get_gamedate(turn + 1, &date);
|
nextseason = date.season;
|
||||||
thisseason = date.season;
|
|
||||||
get_gamedate(turn + 2, &date);
|
|
||||||
nextseason = date.season;
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (F == NULL) {
|
if (F == NULL) {
|
||||||
perror(filename);
|
perror(filename);
|
||||||
|
|
|
@ -1397,7 +1397,7 @@ static void prepare_reports(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Region owner get always the Lighthouse report */
|
/* 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) {
|
for (b = rbuildings(r); b; b = b->next) {
|
||||||
if (b && b->type == bt_lighthouse) {
|
if (b && b->type == bt_lighthouse) {
|
||||||
u = building_owner(b);
|
u = building_owner(b);
|
||||||
|
@ -1547,6 +1547,7 @@ static void mkreportdir(const char *rpath) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
errno = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_reports(faction * f, time_t ltime)
|
int write_reports(faction * f, time_t ltime)
|
||||||
|
@ -1563,11 +1564,7 @@ int write_reports(faction * f, time_t ltime)
|
||||||
}
|
}
|
||||||
prepare_report(&ctx, f);
|
prepare_report(&ctx, f);
|
||||||
get_addresses(&ctx);
|
get_addresses(&ctx);
|
||||||
mkreportdir(path);
|
mkreportdir(path); // FIXME: too many mkdir calls! init_reports is enough
|
||||||
if (errno) {
|
|
||||||
log_warning("errno was %d before writing reports", errno);
|
|
||||||
errno = 0;
|
|
||||||
}
|
|
||||||
log_debug("Reports for %s:", factionname(f));
|
log_debug("Reports for %s:", factionname(f));
|
||||||
for (rtype = report_types; rtype != NULL; rtype = rtype->next) {
|
for (rtype = report_types; rtype != NULL; rtype = rtype->next) {
|
||||||
if (f->options & rtype->flag) {
|
if (f->options & rtype->flag) {
|
||||||
|
@ -1662,7 +1659,7 @@ int reports(void)
|
||||||
report_donations();
|
report_donations();
|
||||||
remove_empty_units();
|
remove_empty_units();
|
||||||
|
|
||||||
mkreportdir(rpath);
|
mkreportdir(rpath); // FIXME: init_reports already does this?
|
||||||
sprintf(path, "%s/reports.txt", rpath);
|
sprintf(path, "%s/reports.txt", rpath);
|
||||||
mailit = fopen(path, "w");
|
mailit = fopen(path, "w");
|
||||||
if (mailit == NULL) {
|
if (mailit == NULL) {
|
||||||
|
@ -1681,7 +1678,7 @@ int reports(void)
|
||||||
free_seen();
|
free_seen();
|
||||||
#ifdef GLOBAL_REPORT
|
#ifdef GLOBAL_REPORT
|
||||||
{
|
{
|
||||||
const char *str = get_param(global.parameters, "globalreport");
|
const char *str = config_get("globalreport");
|
||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
sprintf(path, "%s/%s.%u.cr", reportpath(), str, turn);
|
sprintf(path, "%s/%s.%u.cr", reportpath(), str, turn);
|
||||||
global_report(path);
|
global_report(path);
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
/* Vermehrungsrate Bauern in 1/10000.
|
/* Vermehrungsrate Bauern in 1/10000.
|
||||||
* TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen höher. */
|
* TODO: Evt. Berechnungsfehler, reale Vermehrungsraten scheinen höher. */
|
||||||
#define PEASANTGROWTH 10
|
#define PEASANTGROWTH 10
|
||||||
#define BATTLE_KILLS_PEASANTS 20
|
|
||||||
#define PEASANTLUCK 10
|
#define PEASANTLUCK 10
|
||||||
|
|
||||||
#define ROW_FACTOR 3 /* factor for combat row advancement rule */
|
#define ROW_FACTOR 3 /* factor for combat row advancement rule */
|
||||||
|
@ -39,3 +38,25 @@
|
||||||
#define ARENA_MODULE 1
|
#define ARENA_MODULE 1
|
||||||
|
|
||||||
#undef REGIONOWNERS /* (WIP) region-owner uses HELP_TRAVEL to control entry to region */
|
#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
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
$#undef tolua_reg_types
|
$#undef tolua_reg_types
|
||||||
$#define tolua_reg_types tolua_reg_types_config
|
$#define tolua_reg_types tolua_reg_types_config
|
||||||
$#include "bind_settings.h"
|
$#include <kernel/config.h>
|
||||||
|
|
||||||
module eressea {
|
module eressea {
|
||||||
module settings {
|
module settings {
|
||||||
void settings_set @ set(const char *key, const char *value);
|
void config_set @ set(const char *key, const char *value);
|
||||||
const char * settings_get @ get(const char *key);
|
const char * config_get @ get(const char *key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ LUALIB_API int luaopen_settings (lua_State* tolua_S);
|
||||||
|
|
||||||
#undef tolua_reg_types
|
#undef tolua_reg_types
|
||||||
#define tolua_reg_types tolua_reg_types_settings
|
#define tolua_reg_types tolua_reg_types_settings
|
||||||
#include "bind_settings.h"
|
#include <kernel/config.h>
|
||||||
|
|
||||||
/* function to register type */
|
/* function to register type */
|
||||||
static void tolua_reg_types (lua_State* tolua_S)
|
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* key = ((const char*) tolua_tostring(tolua_S,1,0));
|
||||||
const char* value = ((const char*) tolua_tostring(tolua_S,2,0));
|
const char* value = ((const char*) tolua_tostring(tolua_S,2,0));
|
||||||
{
|
{
|
||||||
settings_set(key,value);
|
config_set(key,value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
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* 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);
|
tolua_pushstring(tolua_S,(const char*)tolua_ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
27
src/study.c
27
src/study.c
|
@ -121,7 +121,7 @@ int study_cost(unit * u, skill_t sk)
|
||||||
if (cost[sk] == 0) {
|
if (cost[sk] == 0) {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
sprintf(buffer, "skills.cost.%s", skillnames[sk]);
|
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) {
|
if (cost[sk] >= 0) {
|
||||||
return cost[sk];
|
return cost[sk];
|
||||||
|
@ -184,7 +184,7 @@ static building *active_building(const unit *u, const struct building_type *btyp
|
||||||
|
|
||||||
static int
|
static int
|
||||||
teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
teach_unit(unit * teacher, unit * student, int nteaching, skill_t sk,
|
||||||
bool report, int *academy)
|
bool report, int *academy)
|
||||||
{
|
{
|
||||||
teaching_info *teach = NULL;
|
teaching_info *teach = NULL;
|
||||||
attrib *a;
|
attrib *a;
|
||||||
|
@ -343,7 +343,8 @@ int teach_cmd(unit * u, struct order *ord)
|
||||||
for (student = r->units; teaching && student; student = student->next) {
|
for (student = r->units; teaching && student; student = student->next) {
|
||||||
if (LongHunger(student)) {
|
if (LongHunger(student)) {
|
||||||
continue;
|
continue;
|
||||||
} else if (student->faction == u->faction) {
|
}
|
||||||
|
else if (student->faction == u->faction) {
|
||||||
if (getkeyword(student->thisorder) == K_STUDY) {
|
if (getkeyword(student->thisorder) == K_STUDY) {
|
||||||
/* Input ist nun von student->thisorder !! */
|
/* Input ist nun von student->thisorder !! */
|
||||||
init_order(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) {
|
if (rule == STUDY_FASTER) {
|
||||||
for (i = 0; i != u->skill_size; ++i) {
|
for (i = 0; i != u->skill_size; ++i) {
|
||||||
skill *sv = u->skills + i;
|
skill *sv = u->skills + i;
|
||||||
if (sv->id == s){
|
if (sv->id == s) {
|
||||||
learnweeks = sv->level * (sv->level + 1) / 2.0;
|
learnweeks = sv->level * (sv->level + 1) / 2.0;
|
||||||
if (learnweeks < turn / 3.0) {
|
if (learnweeks < turn / 3.0) {
|
||||||
return 2.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)
|
int study_cmd(unit * u, order * ord)
|
||||||
{
|
{
|
||||||
region *r = u->region;
|
region *r = u->region;
|
||||||
int p;
|
int p, cap;
|
||||||
magic_t mtyp;
|
magic_t mtyp;
|
||||||
int l;
|
int l;
|
||||||
int studycost, days;
|
int studycost, days;
|
||||||
|
@ -544,18 +545,11 @@ int study_cmd(unit * u, order * ord)
|
||||||
int money = 0;
|
int money = 0;
|
||||||
skill_t sk;
|
skill_t sk;
|
||||||
int maxalchemy = 0;
|
int maxalchemy = 0;
|
||||||
int speed_rule = (study_rule_t)get_param_int(global.parameters, "study.speedup", 0);
|
int speed_rule = (study_rule_t)config_get_int("study.speedup", 0);
|
||||||
static int learn_newskills = -1;
|
|
||||||
struct building *b = inside_building(u);
|
struct building *b = inside_building(u);
|
||||||
const struct building_type *btype = building_is_active(b) ? b->type : NULL;
|
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)) {
|
if (!unit_can_study(u)) {
|
||||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_race_nolearn", "race",
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "error_race_nolearn", "race",
|
||||||
u_race(u)));
|
u_race(u)));
|
||||||
|
@ -569,7 +563,8 @@ int study_cmd(unit * u, order * ord)
|
||||||
cmistake(u, ord, 77, MSG_EVENT);
|
cmistake(u, ord, 77, MSG_EVENT);
|
||||||
return 0;
|
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);
|
cmistake(u, ord, 771, MSG_EVENT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -578,7 +573,7 @@ int study_cmd(unit * u, order * ord)
|
||||||
cmistake(u, ord, 771, MSG_EVENT);
|
cmistake(u, ord, 771, MSG_EVENT);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (learn_newskills == 0) {
|
if (!learn_newskills) {
|
||||||
skill *sv = unit_skill(u, sk);
|
skill *sv = unit_skill(u, sk);
|
||||||
if (sv == NULL) {
|
if (sv == NULL) {
|
||||||
/* we can only learn skills we already have */
|
/* we can only learn skills we already have */
|
||||||
|
|
|
@ -27,7 +27,7 @@ static void setup_study(study_fixture *fix, skill_t sk) {
|
||||||
|
|
||||||
assert(fix);
|
assert(fix);
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
set_param(&global.parameters, "study.random_progress", "0");
|
config_set("study.random_progress", "0");
|
||||||
test_create_world();
|
test_create_world();
|
||||||
r = test_create_region(0, 0, 0);
|
r = test_create_region(0, 0, 0);
|
||||||
f = test_create_faction(0);
|
f = test_create_faction(0);
|
||||||
|
|
|
@ -78,9 +78,7 @@ void test_cleanup(void)
|
||||||
|
|
||||||
free_terrains();
|
free_terrains();
|
||||||
free_resources();
|
free_resources();
|
||||||
global.functions.maintenance = NULL;
|
free_config();
|
||||||
global.functions.wage = NULL;
|
|
||||||
free_params(&global.parameters);
|
|
||||||
default_locale = 0;
|
default_locale = 0;
|
||||||
close_orders();
|
close_orders();
|
||||||
free_locales();
|
free_locales();
|
||||||
|
|
21
src/upkeep.c
21
src/upkeep.c
|
@ -24,10 +24,6 @@ int lifestyle(const unit * u)
|
||||||
{
|
{
|
||||||
int need;
|
int need;
|
||||||
plane *pl;
|
plane *pl;
|
||||||
static int gamecookie = -1;
|
|
||||||
if (gamecookie != global.cookie) {
|
|
||||||
gamecookie = global.cookie;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_monsters(u->faction))
|
if (is_monsters(u->faction))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -71,7 +67,7 @@ static bool hunger(int number, unit * u)
|
||||||
static const race *rc = 0;
|
static const race *rc = 0;
|
||||||
|
|
||||||
if (!damage) {
|
if (!damage) {
|
||||||
damage = get_param(global.parameters, "hunger.damage");
|
damage = config_get("hunger.damage");
|
||||||
if (damage == NULL)
|
if (damage == NULL)
|
||||||
damage = "1d12+12";
|
damage = "1d12+12";
|
||||||
}
|
}
|
||||||
|
@ -116,13 +112,7 @@ void get_food(region * r)
|
||||||
plane *pl = rplane(r);
|
plane *pl = rplane(r);
|
||||||
unit *u;
|
unit *u;
|
||||||
int peasantfood = rpeasants(r) * 10;
|
int peasantfood = rpeasants(r) * 10;
|
||||||
static int food_rules = -1;
|
int food_rules = config_get_int("rules.food.flags", 0);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (food_rules & FOOD_IS_FREE) {
|
if (food_rules & FOOD_IS_FREE) {
|
||||||
return;
|
return;
|
||||||
|
@ -280,11 +270,8 @@ void get_food(region * r)
|
||||||
peasantfood = 0;
|
peasantfood = 0;
|
||||||
}
|
}
|
||||||
if (hungry > 0) {
|
if (hungry > 0) {
|
||||||
static int demon_hunger = -1;
|
bool demon_hunger = config_get_int("hunger.demons", 0) != 0;
|
||||||
if (demon_hunger < 0) {
|
if (demon_hunger) {
|
||||||
demon_hunger = get_param_int(global.parameters, "hunger.demons", 0);
|
|
||||||
}
|
|
||||||
if (demon_hunger == 0) {
|
|
||||||
/* demons who don't feed are hungry */
|
/* demons who don't feed are hungry */
|
||||||
if (hunger(hungry, u))
|
if (hunger(hungry, u))
|
||||||
fset(u, UFL_HUNGER);
|
fset(u, UFL_HUNGER);
|
||||||
|
|
|
@ -32,7 +32,7 @@ void test_upkeep_default(CuTest * tc)
|
||||||
u2 = test_create_unit(f2, r);
|
u2 = test_create_unit(f2, r);
|
||||||
assert(r && u1 && u2);
|
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);
|
i_change(&u1->items, i_silver, 20);
|
||||||
get_food(r);
|
get_food(r);
|
||||||
// since u1 and u2 are not allied, u1 should not help u2 with upkeep
|
// 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);
|
u1 = test_create_unit(f1, r);
|
||||||
assert(r && u1);
|
assert(r && u1);
|
||||||
|
|
||||||
set_param(&global.parameters, "rules.food.flags", "0");
|
config_set("rules.food.flags", "0");
|
||||||
u1->hp = 100;
|
u1->hp = 100;
|
||||||
get_food(r);
|
get_food(r);
|
||||||
// since u1 and u2 are not allied, u1 should not help u2 with upkeep
|
// 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);
|
u2 = test_create_unit(u1->faction, r);
|
||||||
assert(r && u1 && u2);
|
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);
|
i_change(&u1->items, i_silver, 30);
|
||||||
get_food(r);
|
get_food(r);
|
||||||
CuAssertIntEquals(tc, 10, i_get(u1->items, i_silver));
|
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);
|
u2 = test_create_unit(f2, r);
|
||||||
assert(r && u1 && u2);
|
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);
|
i_change(&u1->items, i_silver, 30);
|
||||||
get_food(r);
|
get_food(r);
|
||||||
CuAssertIntEquals(tc, 10, i_get(u1->items, i_silver));
|
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);
|
u = test_create_unit(test_create_faction(test_create_race("human")), r);
|
||||||
assert(r && u);
|
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);
|
get_food(r);
|
||||||
CuAssertIntEquals(tc, 0, i_get(u->items, i_silver));
|
CuAssertIntEquals(tc, 0, i_get(u->items, i_silver));
|
||||||
CuAssertIntEquals(tc, 0, fval(u, UFL_HUNGER));
|
CuAssertIntEquals(tc, 0, fval(u, UFL_HUNGER));
|
||||||
|
|
|
@ -26,8 +26,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
#define M_PIl 3.1415926535897932384626433832795029L /* pi */
|
|
||||||
|
|
||||||
/* NormalRand aus python, random.py geklaut, dort ist Referenz auf
|
/* NormalRand aus python, random.py geklaut, dort ist Referenz auf
|
||||||
* den Algorithmus. mu = Mittelwert, sigma = Standardabweichung.
|
* den Algorithmus. mu = Mittelwert, sigma = Standardabweichung.
|
||||||
* http://de.wikipedia.org/wiki/Standardabweichung#Diskrete_Gleichverteilung.2C_W.C3.BCrfel
|
* http://de.wikipedia.org/wiki/Standardabweichung#Diskrete_Gleichverteilung.2C_W.C3.BCrfel
|
||||||
|
|
Loading…
Reference in a new issue