forked from github/server
Merge branch 'release-3.7' into develop
Conflicts: src/buildno.h src/monsters.c
This commit is contained in:
commit
5b9333f6d9
|
@ -23,7 +23,6 @@
|
||||||
"world.era": 2,
|
"world.era": 2,
|
||||||
"seed.population.min": 8,
|
"seed.population.min": 8,
|
||||||
"seed.population.max": 8,
|
"seed.population.max": 8,
|
||||||
"rules.ship.damage_drift": 0.00,
|
|
||||||
"rules.reserve.twophase": true,
|
"rules.reserve.twophase": true,
|
||||||
"rules.give.max_men": -1,
|
"rules.give.max_men": -1,
|
||||||
"rules.check_overload": false,
|
"rules.check_overload": false,
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
"rules.stealth.anon_battle": false,
|
"rules.stealth.anon_battle": false,
|
||||||
"rules.check_overload": false,
|
"rules.check_overload": false,
|
||||||
"rules.combat.goblinbonus": 3,
|
"rules.combat.goblinbonus": 3,
|
||||||
"rules.ship.damage_drift": 0.00,
|
|
||||||
"rules.alliances": true,
|
"rules.alliances": true,
|
||||||
"rules.combat.herospeed": 3,
|
"rules.combat.herospeed": 3,
|
||||||
"rules.combat.demon_vampire": 5,
|
"rules.combat.demon_vampire": 5,
|
||||||
|
|
|
@ -58,7 +58,6 @@
|
||||||
"rules.stealth.anon_battle": false,
|
"rules.stealth.anon_battle": false,
|
||||||
"rules.check_overload": false,
|
"rules.check_overload": false,
|
||||||
"rules.combat.goblinbonus": 3,
|
"rules.combat.goblinbonus": 3,
|
||||||
"rules.ship.damage_drift": 0.00,
|
|
||||||
"rules.alliances": true,
|
"rules.alliances": true,
|
||||||
"rules.combat.herospeed": 3,
|
"rules.combat.herospeed": 3,
|
||||||
"rules.combat.demon_vampire": 5,
|
"rules.combat.demon_vampire": 5,
|
||||||
|
|
|
@ -526,7 +526,7 @@ static void disable_feature(const char *str) {
|
||||||
for (k = 0; k != MAXKEYWORDS; ++k) {
|
for (k = 0; k != MAXKEYWORDS; ++k) {
|
||||||
// FIXME: this loop is slow as balls.
|
// FIXME: this loop is slow as balls.
|
||||||
if (strcmp(keywords[k], str) == 0) {
|
if (strcmp(keywords[k], str) == 0) {
|
||||||
log_info("disable keyword %s\n", str);
|
log_debug("disable keyword %s\n", str);
|
||||||
enable_keyword(k, false);
|
enable_keyword(k, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
31
src/laws.c
31
src/laws.c
|
@ -2656,13 +2656,12 @@ int combatspell_cmd(unit * u, struct order *ord)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Beachten: einige Monster sollen auch unbewaffent die Region bewachen
|
|
||||||
* können */
|
|
||||||
guard_t can_start_guarding(const unit * u)
|
guard_t can_start_guarding(const unit * u)
|
||||||
{
|
{
|
||||||
if (u->status >= ST_FLEE || fval(u, UFL_FLEEING))
|
if (u->status >= ST_FLEE || fval(u, UFL_FLEEING))
|
||||||
return E_GUARD_FLEEING;
|
return E_GUARD_FLEEING;
|
||||||
if (fval(u_race(u), RCF_UNARMEDGUARD))
|
/* Monster der Monsterpartei dürfen immer bewachen */
|
||||||
|
if (is_monsters(u->faction) || fval(u_race(u), RCF_UNARMEDGUARD))
|
||||||
return E_GUARD_OK;
|
return E_GUARD_OK;
|
||||||
if (!armedmen(u, true))
|
if (!armedmen(u, true))
|
||||||
return E_GUARD_UNARMED;
|
return E_GUARD_UNARMED;
|
||||||
|
@ -2696,24 +2695,18 @@ int guard_on_cmd(unit * u, struct order *ord)
|
||||||
cmistake(u, ord, 95, MSG_EVENT);
|
cmistake(u, ord, 95, MSG_EVENT);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Monster der Monsterpartei dürfen immer bewachen */
|
int err = can_start_guarding(u);
|
||||||
if (is_monsters(u->faction)) {
|
if (err == E_GUARD_OK) {
|
||||||
guard(u, GUARD_ALL);
|
guard(u, GUARD_ALL);
|
||||||
}
|
}
|
||||||
else {
|
else if (err == E_GUARD_UNARMED) {
|
||||||
int err = can_start_guarding(u);
|
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unit_unarmed", ""));
|
||||||
if (err == E_GUARD_OK) {
|
}
|
||||||
guard(u, GUARD_ALL);
|
else if (err == E_GUARD_FLEEING) {
|
||||||
}
|
cmistake(u, ord, 320, MSG_EVENT);
|
||||||
else if (err == E_GUARD_UNARMED) {
|
}
|
||||||
ADDMSG(&u->faction->msgs, msg_feedback(u, ord, "unit_unarmed", ""));
|
else if (err == E_GUARD_NEWBIE) {
|
||||||
}
|
cmistake(u, ord, 304, MSG_EVENT);
|
||||||
else if (err == E_GUARD_FLEEING) {
|
|
||||||
cmistake(u, ord, 320, MSG_EVENT);
|
|
||||||
}
|
|
||||||
else if (err == E_GUARD_NEWBIE) {
|
|
||||||
cmistake(u, ord, 304, MSG_EVENT);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -635,6 +635,7 @@ static void test_newbie_cannot_guard(CuTest *tc) {
|
||||||
setup_guard(&fix, true);
|
setup_guard(&fix, true);
|
||||||
config_set("NewbieImmunity", "4");
|
config_set("NewbieImmunity", "4");
|
||||||
CuAssertTrue(tc, IsImmune(fix.u->faction));
|
CuAssertTrue(tc, IsImmune(fix.u->faction));
|
||||||
|
CuAssertIntEquals(tc, E_GUARD_NEWBIE, can_start_guarding(fix.u));
|
||||||
update_guards();
|
update_guards();
|
||||||
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
@ -644,6 +645,7 @@ static void test_unarmed_cannot_guard(CuTest *tc) {
|
||||||
guard_fixture fix;
|
guard_fixture fix;
|
||||||
|
|
||||||
setup_guard(&fix, false);
|
setup_guard(&fix, false);
|
||||||
|
CuAssertIntEquals(tc, E_GUARD_UNARMED, can_start_guarding(fix.u));
|
||||||
update_guards();
|
update_guards();
|
||||||
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
@ -656,6 +658,18 @@ static void test_unarmed_races_can_guard(CuTest *tc) {
|
||||||
setup_guard(&fix, false);
|
setup_guard(&fix, false);
|
||||||
rc = rc_get_or_create(fix.u->_race->_name);
|
rc = rc_get_or_create(fix.u->_race->_name);
|
||||||
rc->flags |= RCF_UNARMEDGUARD;
|
rc->flags |= RCF_UNARMEDGUARD;
|
||||||
|
CuAssertIntEquals(tc, E_GUARD_OK, can_start_guarding(fix.u));
|
||||||
|
update_guards();
|
||||||
|
CuAssertTrue(tc, fval(fix.u, UFL_GUARD));
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void test_monsters_can_guard(CuTest *tc) {
|
||||||
|
guard_fixture fix;
|
||||||
|
|
||||||
|
setup_guard(&fix, false);
|
||||||
|
u_setfaction(fix.u, get_or_create_monsters());
|
||||||
|
CuAssertIntEquals(tc, E_GUARD_OK, can_start_guarding(fix.u));
|
||||||
update_guards();
|
update_guards();
|
||||||
CuAssertTrue(tc, fval(fix.u, UFL_GUARD));
|
CuAssertTrue(tc, fval(fix.u, UFL_GUARD));
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
@ -666,7 +680,7 @@ static void test_low_skill_cannot_guard(CuTest *tc) {
|
||||||
|
|
||||||
setup_guard(&fix, true);
|
setup_guard(&fix, true);
|
||||||
set_level(fix.u, SK_MELEE, 1);
|
set_level(fix.u, SK_MELEE, 1);
|
||||||
fix.u->status = ST_FLEE;
|
CuAssertIntEquals(tc, E_GUARD_UNARMED, can_start_guarding(fix.u));
|
||||||
update_guards();
|
update_guards();
|
||||||
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
@ -677,6 +691,7 @@ static void test_fleeing_cannot_guard(CuTest *tc) {
|
||||||
|
|
||||||
setup_guard(&fix, true);
|
setup_guard(&fix, true);
|
||||||
fix.u->status = ST_FLEE;
|
fix.u->status = ST_FLEE;
|
||||||
|
CuAssertIntEquals(tc, E_GUARD_FLEEING, can_start_guarding(fix.u));
|
||||||
update_guards();
|
update_guards();
|
||||||
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
CuAssertTrue(tc, !fval(fix.u, UFL_GUARD));
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
|
@ -1269,6 +1284,7 @@ CuSuite *get_laws_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_newbie_cannot_guard);
|
SUITE_ADD_TEST(suite, test_newbie_cannot_guard);
|
||||||
SUITE_ADD_TEST(suite, test_unarmed_cannot_guard);
|
SUITE_ADD_TEST(suite, test_unarmed_cannot_guard);
|
||||||
SUITE_ADD_TEST(suite, test_unarmed_races_can_guard);
|
SUITE_ADD_TEST(suite, test_unarmed_races_can_guard);
|
||||||
|
SUITE_ADD_TEST(suite, test_monsters_can_guard);
|
||||||
SUITE_ADD_TEST(suite, test_fleeing_cannot_guard);
|
SUITE_ADD_TEST(suite, test_fleeing_cannot_guard);
|
||||||
SUITE_ADD_TEST(suite, test_low_skill_cannot_guard);
|
SUITE_ADD_TEST(suite, test_low_skill_cannot_guard);
|
||||||
SUITE_ADD_TEST(suite, test_reserve_self);
|
SUITE_ADD_TEST(suite, test_reserve_self);
|
||||||
|
|
|
@ -75,16 +75,14 @@
|
||||||
#define DRAGON_RANGE 20 /* Max. Distanz zum nächsten Drachenziel */
|
#define DRAGON_RANGE 20 /* Max. Distanz zum nächsten Drachenziel */
|
||||||
#define MAXILLUSION_TEXTS 3
|
#define MAXILLUSION_TEXTS 3
|
||||||
|
|
||||||
|
static double attack_chance; /* rules.monsters.attack_chance, or default 0.4 */
|
||||||
|
|
||||||
static void give_peasants(unit *u, const item_type *itype, int reduce) {
|
static void give_peasants(unit *u, const item_type *itype, int reduce) {
|
||||||
char buf[64];
|
char buf[64];
|
||||||
slprintf(buf, sizeof(buf), "%s 0 %d %s", LOC(u->faction->locale, keyword(K_GIVE)), reduce, LOC(u->faction->locale, itype->rtype->_name));
|
slprintf(buf, sizeof(buf), "%s 0 %d %s", LOC(u->faction->locale, keyword(K_GIVE)), reduce, LOC(u->faction->locale, itype->rtype->_name));
|
||||||
unit_addorder(u, parse_order(buf, u->faction->locale));
|
unit_addorder(u, parse_order(buf, u->faction->locale));
|
||||||
}
|
}
|
||||||
|
|
||||||
static double monster_attack_chance(void) {
|
|
||||||
return config_get_flt("rules.monsters.attack_chance", 0.4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void reduce_weight(unit * u)
|
static void reduce_weight(unit * u)
|
||||||
{
|
{
|
||||||
int capacity, weight = 0;
|
int capacity, weight = 0;
|
||||||
|
@ -157,15 +155,15 @@ static order *monster_attack(unit * u, const unit * target)
|
||||||
return create_order(K_ATTACK, u->faction->locale, "%i", target->no);
|
return create_order(K_ATTACK, u->faction->locale, "%i", target->no);
|
||||||
}
|
}
|
||||||
|
|
||||||
static order *get_money_for_dragon(region * r, unit * u, int wanted)
|
static order *get_money_for_dragon(region * r, unit * udragon, int wanted)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
bool attacks = monster_attack_chance() > 0.0;
|
bool attacks = attack_chance > 0.0;
|
||||||
|
|
||||||
/* falls genug geld in der region ist, treiben wir steuern ein. */
|
/* falls genug geld in der region ist, treiben wir steuern ein. */
|
||||||
if (rmoney(r) >= wanted) {
|
if (rmoney(r) >= wanted) {
|
||||||
/* 5% chance, dass der drache aus einer laune raus attackiert */
|
/* 5% chance, dass der drache aus einer laune raus attackiert */
|
||||||
if (!attacks || chance(1.0 - u_race(u)->aggression)) {
|
if (!attacks || chance(1.0 - u_race(udragon)->aggression)) {
|
||||||
/* Drachen haben in E3 und E4 keine Einnahmen. Neuer Befehl Pluendern erstmal nur fuer Monster?*/
|
/* Drachen haben in E3 und E4 keine Einnahmen. Neuer Befehl Pluendern erstmal nur fuer Monster?*/
|
||||||
return create_order(K_LOOT, default_locale, NULL);
|
return create_order(K_LOOT, default_locale, NULL);
|
||||||
}
|
}
|
||||||
|
@ -174,15 +172,15 @@ static order *get_money_for_dragon(region * r, unit * u, int wanted)
|
||||||
/* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an
|
/* falls der drache launisch ist, oder das regionssilber knapp, greift er alle an
|
||||||
* und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */
|
* und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */
|
||||||
n = 0;
|
n = 0;
|
||||||
if (attacks && is_guard(u, GUARD_TAX)) {
|
if (attacks && is_guard(udragon, GUARD_TAX)) {
|
||||||
unit *u2;
|
unit *u;
|
||||||
for (u2 = r->units; u2; u2 = u2->next) {
|
for (u = r->units; u; u = u->next) {
|
||||||
if (u2->faction != u->faction && cansee(u->faction, r, u2, 0) && !in_safe_building(u, u2)) {
|
if (u->faction != udragon->faction && cansee(udragon->faction, r, u, 0) && !in_safe_building(u, udragon)) {
|
||||||
int m = get_money(u2);
|
int m = get_money(u);
|
||||||
if (m != 0) {
|
if (m != 0) {
|
||||||
order *ord = monster_attack(u, u2);
|
order *ord = monster_attack(udragon, u);
|
||||||
if (ord) {
|
if (ord) {
|
||||||
addlist(&u->orders, ord);
|
addlist(&udragon->orders, ord);
|
||||||
n += m;
|
n += m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -758,14 +756,13 @@ static order *plan_dragon(unit * u)
|
||||||
void plan_monsters(faction * f)
|
void plan_monsters(faction * f)
|
||||||
{
|
{
|
||||||
region *r;
|
region *r;
|
||||||
double attack_chance = monster_attack_chance();
|
|
||||||
|
|
||||||
assert(f);
|
assert(f);
|
||||||
|
attack_chance = config_get_flt("rules.monsters.attack_chance", 0.4);
|
||||||
f->lastorders = turn;
|
f->lastorders = turn;
|
||||||
|
|
||||||
for (r = regions; r; r = r->next) {
|
for (r = regions; r; r = r->next) {
|
||||||
unit *u;
|
unit *u;
|
||||||
double rchance = attack_chance;
|
|
||||||
bool attacking = false;
|
bool attacking = false;
|
||||||
|
|
||||||
for (u = r->units; u; u = u->next) {
|
for (u = r->units; u; u = u->next) {
|
||||||
|
@ -784,10 +781,8 @@ void plan_monsters(faction * f)
|
||||||
produceexp(u, SK_PERCEPTION, u->number);
|
produceexp(u, SK_PERCEPTION, u->number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rchance > 0.0) {
|
if (!attacking) {
|
||||||
if (chance(rchance))
|
if (chance(attack_chance)) attacking = true;
|
||||||
attacking = true;
|
|
||||||
rchance = 0.0;
|
|
||||||
}
|
}
|
||||||
if (u->status > ST_BEHIND) {
|
if (u->status > ST_BEHIND) {
|
||||||
setstatus(u, ST_FIGHT);
|
setstatus(u, ST_FIGHT);
|
||||||
|
@ -801,8 +796,10 @@ void plan_monsters(faction * f)
|
||||||
if (ta && !monster_is_waiting(u)) {
|
if (ta && !monster_is_waiting(u)) {
|
||||||
unit *tu = (unit *)ta->data.v;
|
unit *tu = (unit *)ta->data.v;
|
||||||
if (tu && tu->region == r) {
|
if (tu && tu->region == r) {
|
||||||
addlist(&u->orders,
|
order * ord = monster_attack(u, tu);
|
||||||
create_order(K_ATTACK, u->faction->locale, "%i", tu->no));
|
if (ord) {
|
||||||
|
addlist(&u->orders, ord);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (tu) {
|
else if (tu) {
|
||||||
tu = findunitg(ta->data.i, NULL);
|
tu = findunitg(ta->data.i, NULL);
|
||||||
|
|
|
@ -260,7 +260,7 @@ int findtoken(const void * root, const char *key, variant * result)
|
||||||
ref = ref->nexthash;
|
ref = ref->nexthash;
|
||||||
str += len;
|
str += len;
|
||||||
if (!ref) {
|
if (!ref) {
|
||||||
log_info("findtoken | token not found '%s'\n", key);
|
log_debug("findtoken | token not found '%s'\n", key);
|
||||||
return E_TOK_NOMATCH;
|
return E_TOK_NOMATCH;
|
||||||
}
|
}
|
||||||
tk = ref->node;
|
tk = ref->node;
|
||||||
|
@ -269,6 +269,6 @@ int findtoken(const void * root, const char *key, variant * result)
|
||||||
*result = tk->id;
|
*result = tk->id;
|
||||||
return E_TOK_SUCCESS;
|
return E_TOK_SUCCESS;
|
||||||
}
|
}
|
||||||
log_info("findtoken | token not found '%s'\n", key);
|
log_debug("findtoken | token not found '%s'\n", key);
|
||||||
return E_TOK_NOMATCH;
|
return E_TOK_NOMATCH;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue