forked from github/server
commit
1ce051549c
|
@ -0,0 +1,15 @@
|
|||
# Befehlsverarbeitung in Eressea
|
||||
|
||||
Einheiten haben zwei Listen von Befehlen: orders und old_orders.
|
||||
|
||||
1. `read_unit`: Aus dem Datenfile gelesene (Default-)Befehl der Vorwoche werden in u->orders gespeichert.
|
||||
2. `begin_orders`: Wenn die Einheit neue Befehle erhält, werden "wiederholbare" Befehle (Handel, lange Befehle ausser NACH) aus u->orders nach u->old_orders kopiert.
|
||||
3. `unitorders`: Die neuen Befehle werden in u->orders gelesen.
|
||||
4. `update_long_order`: u->thisorder wird auf den ersten "langen" Befehl in u->orders gesetzt.
|
||||
5. Auswertung: Für lange Befehle wird in u->thisorder geschaut, für kurze und andere (inkl. KAUFE/ATTACKIERE) in u->orders.
|
||||
6. `movement`: NACH löscht u->thisorder, damit es nicht bei Auswertung der Zielregion ein zweites Mal ausgeführt werden kann. Das hat allerdings keine Auswirkung auf die beiden Listen.
|
||||
7. `build_building`: Wenn ein MACHE GEBAEUDE Befehl "fertig" ist, wird der Befehl in u->orders durch ein ARBEITE ersetzt (aber u->thisorder nicht geändert, das sollte also nichts tun).
|
||||
8. `defaultorders`: Nach allen langen Befehlen wird der DEFAULT Befehl gesetzt. Dieser löscht zuerst alle nicht-kurzen Befehle aus u->orders und u->old_orders, und hängt dann den neuen Befehl in u->old_orders an.
|
||||
9.1: `cr_output_unit`: In den CR werden alle "dauerhaften" Befehle aus u->old_orders geschrieben, d.h. kurze Befehle mit @ Prefix, Kommentare mit // und lange Befehle ausser NACH.
|
||||
9.2: `cr_output_unit`: In den CR werden alle "dauerhaften" Befehle aus u->orders geschrieben, d.h. kurze Befehle mit @ Prefix, Kommentare mit // und lange Befehle ausser NACH. Wenn u->old_orders nicht leer ist, werden "wiederholbare" Befehle dabei ignoriert.
|
||||
|
|
@ -1187,7 +1187,6 @@ function test_promote_after_recruit()
|
|||
local r1 = region.create(0, 0, 'plain')
|
||||
local r2 = region.create(1, 0, 'plain')
|
||||
local u1 = unit.create(f, r1, 1)
|
||||
u1.name = 'Xolgrim'
|
||||
local u2 = unit.create(f, r2, 55)
|
||||
u2:add_order('REKRUTIERE 1')
|
||||
u1:add_order('BEFOERDERE')
|
||||
|
|
|
@ -2,16 +2,8 @@ require "lunit"
|
|||
|
||||
module("tests.e2.allies", package.seeall, lunit.testcase)
|
||||
|
||||
function skip_test_get_set_ally()
|
||||
local f1 = faction.create("human")
|
||||
local f2 = faction.create("human")
|
||||
|
||||
assert_equal(false, f1:get_ally(f2, "guard"))
|
||||
f1:set_ally(f2, "guard", true)
|
||||
assert_equal(true, f1:get_ally(f2, "guard"))
|
||||
assert_equal(false, f1:get_ally(f2, "give"))
|
||||
f1:set_ally(f2, "give", true)
|
||||
assert_equal(true, f1:get_ally(f2, "give"))
|
||||
function setup()
|
||||
eressea.free_game()
|
||||
end
|
||||
|
||||
function test_get_allies()
|
||||
|
@ -28,3 +20,16 @@ function test_get_allies()
|
|||
assert_equal(1, #allies[f2.id])
|
||||
assert_equal("give", allies[f2.id][1])
|
||||
end
|
||||
|
||||
function test_get_set_ally()
|
||||
local f1 = faction.create("human")
|
||||
local f2 = faction.create("human")
|
||||
|
||||
assert_equal(false, f1:get_ally(f2, "guard"))
|
||||
f1:set_ally(f2, "guard", true)
|
||||
assert_equal(true, f1:get_ally(f2, "guard"))
|
||||
assert_equal(false, f1:get_ally(f2, "give"))
|
||||
f1:set_ally(f2, "give", true)
|
||||
assert_equal(true, f1:get_ally(f2, "give"))
|
||||
end
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@ function test_build_tunnel_limited()
|
|||
u:add_item('iron', 2)
|
||||
u:add_item('money', 700)
|
||||
u.building = b
|
||||
u.name = 'Xolgrim'
|
||||
u:add_order('MACHE 2 BURG ' .. itoa36(b.id))
|
||||
b.size = 99
|
||||
process_orders()
|
||||
|
|
|
@ -12,6 +12,26 @@ function setup()
|
|||
eressea.settings.set("rules.peasants.growth.factor", "0")
|
||||
end
|
||||
|
||||
function disabled_double_default()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r, 1)
|
||||
region.create(1, 0, "plain")
|
||||
region.create(2, 0, "plain")
|
||||
region.create(3, 0, "plain")
|
||||
|
||||
u:add_order('NACH O')
|
||||
u:add_order('DEFAULT "NACH O"')
|
||||
u:add_order('DEFAULT "DEFAULT ARBEITE"')
|
||||
process_orders()
|
||||
assert_equal(1, u.region.x)
|
||||
process_orders()
|
||||
assert_equal(2, u.region.x)
|
||||
process_orders()
|
||||
assert_equal(2, u.region.x)
|
||||
assert_equal("ARBEITE", u:get_order())
|
||||
end
|
||||
|
||||
function test_give_unit()
|
||||
local r = region.create(0, 0, "plain")
|
||||
local f1 = faction.create('elf')
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
require 'tests.e2.trolls'
|
||||
require 'tests.e2.trees'
|
||||
require 'tests.e2.buildings'
|
||||
require 'tests.e2.allies'
|
||||
require 'tests.e2.quit'
|
||||
require 'tests.e2.movement'
|
||||
require 'tests.e2.carts'
|
||||
require 'tests.e2.quit'
|
||||
|
@ -10,6 +9,7 @@ require 'tests.e2.spells'
|
|||
require 'tests.e2.e2features'
|
||||
require 'tests.e2.insects'
|
||||
require 'tests.e2.production'
|
||||
require 'tests.e2.allies'
|
||||
require 'tests.e2.adamantium'
|
||||
require 'tests.e2.undead'
|
||||
require 'tests.e2.shiplanding'
|
||||
|
|
|
@ -3,7 +3,7 @@ require "lunit"
|
|||
module("tests.e2.spells", package.seeall, lunit.testcase)
|
||||
|
||||
function setup()
|
||||
eressea.free_game()
|
||||
eressea.game.reset()
|
||||
eressea.settings.set("nmr.removenewbie", "0")
|
||||
eressea.settings.set("nmr.timeout", "0")
|
||||
eressea.settings.set("NewbieImmunity", "0")
|
||||
|
@ -21,9 +21,6 @@ function test_undead_cannot_enter_holyground()
|
|||
local u1 = unit.create(f, r1, 1)
|
||||
local u2 = unit.create(f, r2, 1)
|
||||
|
||||
u2.name = "Xolgrim's Magier"
|
||||
u1.name = "Xolgrim's Opfer"
|
||||
|
||||
u2.magic = 'gwyrrd'
|
||||
u2:set_skill('magic', 100)
|
||||
u2.aura = 200
|
||||
|
@ -227,7 +224,6 @@ function test_bug_2517()
|
|||
local uf = nil
|
||||
eressea.settings.set("magic.familiar.race", "lynx")
|
||||
f.magic = 'gwyrrd'
|
||||
um.name = 'Xolgrim'
|
||||
um.magic = 'gwyrrd'
|
||||
um.race = 'elf'
|
||||
um:set_skill('magic', 10)
|
||||
|
|
|
@ -15,7 +15,7 @@ function test_no_growth()
|
|||
set_turn(204)
|
||||
assert_equal('spring', get_season())
|
||||
local r = region.create(0, 0, 'plain')
|
||||
r:set_flag(2, 0) -- no mallorn
|
||||
r:set_flag(1, false) -- no mallorn
|
||||
r:set_resource('seed', 0)
|
||||
r:set_resource('sapling', 0)
|
||||
r:set_resource('tree', 0)
|
||||
|
@ -30,7 +30,7 @@ function test_spring_growth()
|
|||
set_turn(204)
|
||||
assert_equal('spring', get_season())
|
||||
local r = region.create(0, 0, 'plain')
|
||||
r:set_flag(2, 0) -- no mallorn
|
||||
r:set_flag(1, false) -- no mallorn
|
||||
r:set_resource('seed', 6)
|
||||
r:set_resource('sapling', 17)
|
||||
r:set_resource('tree', 0)
|
||||
|
@ -46,7 +46,7 @@ function test_plant_fail()
|
|||
assert_equal('summer', get_season())
|
||||
local f = faction.create('goblin')
|
||||
local r = region.create(0, 0, 'plain')
|
||||
r:set_flag(2, 0) -- no mallorn
|
||||
r:set_flag(1, false) -- no mallorn
|
||||
r:set_resource('seed', 0)
|
||||
r:set_resource('sapling', 0)
|
||||
r:set_resource('tree', 0)
|
||||
|
@ -67,7 +67,7 @@ function test_plant_summer()
|
|||
assert_equal('summer', get_season())
|
||||
local f = faction.create('goblin')
|
||||
local r = region.create(0, 0, 'plain')
|
||||
r:set_flag(2, 0) -- no mallorn
|
||||
r:set_flag(1, false) -- no mallorn
|
||||
r:set_resource('seed', 0)
|
||||
r:set_resource('sapling', 0)
|
||||
r:set_resource('tree', 0)
|
||||
|
@ -89,7 +89,7 @@ function test_plant_spring_saplings()
|
|||
local f = faction.create('goblin')
|
||||
local r = region.create(0, 0, 'plain')
|
||||
local u = unit.create(f, r)
|
||||
r:set_flag(2, 0) -- no mallorn
|
||||
r:set_flag(1, false) -- no mallorn
|
||||
r:set_resource('seed', 0)
|
||||
r:set_resource('sapling', 0)
|
||||
r:set_resource('tree', 0)
|
||||
|
@ -117,7 +117,7 @@ function test_plant_spring_seeds()
|
|||
local f = faction.create('goblin')
|
||||
local r = region.create(0, 0, 'plain')
|
||||
local u = unit.create(f, r)
|
||||
r:set_flag(2, 0) -- no mallorn
|
||||
r:set_flag(1, false) -- no mallorn
|
||||
r:set_resource('seed', 0)
|
||||
r:set_resource('sapling', 0)
|
||||
r:set_resource('tree', 0)
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
require "lunit"
|
||||
|
||||
module("tests.e2.trolls", package.seeall, lunit.testcase )
|
||||
|
||||
function setup()
|
||||
eressea.free_game()
|
||||
end
|
||||
|
||||
function test_trolls_with_horses()
|
||||
local r0 = region.create(0, 0, 'plain')
|
||||
local r1 = region.create(1, 0, 'plain')
|
||||
local r2 = region.create(2, 0, 'plain')
|
||||
local r3 = region.create(3, 0, 'plain')
|
||||
local r4 = region.create(4, 0, 'plain')
|
||||
local r5 = region.create(5, 0, 'plain')
|
||||
|
||||
local f = faction.create('troll')
|
||||
-- 1. 20 trolls can pull 5 loaded carts:
|
||||
assert_not_nil(r0)
|
||||
local u1 = unit.create(f, r0, 20)
|
||||
u1:add_item('cart', 5)
|
||||
-- trolls carry 10.8 GE, carts carry 100 GE:
|
||||
u1:add_item('money', 100 * (5 * 100 + 2 * 108))
|
||||
u1:add_order('NACH O O O')
|
||||
|
||||
process_orders()
|
||||
assert_equal(r1, u1.region)
|
||||
|
||||
-- 20 trolls can also lead 20 horses
|
||||
u1:add_item('horse', 20)
|
||||
u1:add_item('money', 100 * 20 * 20)
|
||||
|
||||
process_orders()
|
||||
assert_equal(r2, u1.region)
|
||||
|
||||
-- test if trolls are still "lazy". If yes they should still manage 10 full carts behind the 20 horses (5 more)
|
||||
u1:add_item('cart', 5)
|
||||
u1:add_item('money', 100 * 5 * 100)
|
||||
|
||||
process_orders()
|
||||
assert_equal(r3, u1.region)
|
||||
|
||||
-- test if trolls are still "lazy". If not they should manage 15 full carts, 5 behind trolls and 10 behind 20 horses (again 5 more)
|
||||
u1:add_item('cart', 5)
|
||||
u1:add_item('money', 100 * 5 * 100)
|
||||
|
||||
process_orders()
|
||||
assert_equal(r4, u1.region)
|
||||
|
||||
end
|
|
@ -28,7 +28,6 @@ function test_undead_reserve_other()
|
|||
u1.race = "undead"
|
||||
u1:clear_orders()
|
||||
u1:add_order("RESERVIERE 1 Holz")
|
||||
u1.name = 'Xolgrim'
|
||||
process_orders()
|
||||
|
||||
if 0 ~= u1:get_item("log") then
|
||||
|
|
|
@ -294,7 +294,7 @@ static race *rc_find_i(const char *name)
|
|||
return rc;
|
||||
}
|
||||
|
||||
const race * rc_find(const char *name) {
|
||||
race * rc_find(const char *name) {
|
||||
return rc_find_i(name);
|
||||
}
|
||||
|
||||
|
|
|
@ -155,7 +155,7 @@ extern "C" {
|
|||
race *rc_create(const char *zName);
|
||||
race *rc_get_or_create(const char *name);
|
||||
bool rc_changed(int *cache);
|
||||
const race *rc_find(const char *);
|
||||
race *rc_find(const char *);
|
||||
void free_races(void);
|
||||
|
||||
bool rc_can_use(const struct race *rc, const struct item_type *itype);
|
||||
|
|
|
@ -980,7 +980,7 @@ int quit_cmd(unit * u, struct order *ord)
|
|||
if (p == P_FACTION) {
|
||||
#ifdef QUIT_WITH_TRANSFER
|
||||
faction *f2 = getfaction();
|
||||
if (f2 == NULL) {
|
||||
if (f2 == NULL || f2 == u->faction) {
|
||||
cmistake(u, ord, 66, MSG_EVENT);
|
||||
flags = 0;
|
||||
}
|
||||
|
|
|
@ -142,18 +142,39 @@ static void reduce_weight(unit * u)
|
|||
}
|
||||
}
|
||||
|
||||
static bool monster_is_waiting(const unit * u)
|
||||
{
|
||||
int test = fval(u_race(u), RCF_ATTACK_MOVED) ? UFL_ISNEW : UFL_ISNEW | UFL_MOVED;
|
||||
if (fval(u, test))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool monster_can_attack(const unit * u)
|
||||
{
|
||||
if (u->status >= ST_AVOID) {
|
||||
return false;
|
||||
}
|
||||
if (u->region->land) {
|
||||
return is_guard(u);
|
||||
}
|
||||
else if (fval(u->region->terrain, SEA_REGION)) {
|
||||
return fval(u_race(u), RCF_SWIM);
|
||||
}
|
||||
return fval(u_race(u), RCF_FLY);
|
||||
}
|
||||
|
||||
static order *monster_attack(unit * u, const unit * target)
|
||||
{
|
||||
assert(u->region == target->region);
|
||||
assert(u->faction != target->faction);
|
||||
if (!cansee(u->faction, u->region, target, 0))
|
||||
return NULL;
|
||||
if (monster_is_waiting(u))
|
||||
return NULL;
|
||||
|
||||
if (u->region->land && (u->region->flags & RF_GUARDED) == 0) {
|
||||
if (!cansee(u->faction, u->region, target, 0)) {
|
||||
return NULL;
|
||||
}
|
||||
if (monster_is_waiting(u)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return create_order(K_ATTACK, u->faction->locale, "%i", target->no);
|
||||
}
|
||||
|
||||
|
@ -185,7 +206,8 @@ int monster_attacks(unit * monster, bool rich_only)
|
|||
{
|
||||
const race *rc_serpent = get_race(RC_SEASERPENT);
|
||||
int result = -1;
|
||||
if (monster->status < ST_AVOID) {
|
||||
|
||||
if (monster_can_attack(monster)) {
|
||||
region *r = monster->region;
|
||||
unit *u2;
|
||||
int money = 0;
|
||||
|
@ -231,7 +253,7 @@ 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
|
||||
* und holt sich Silber von Einheiten, vorausgesetzt er bewacht bereits */
|
||||
money = 0;
|
||||
if (attacks && is_guard(u)) {
|
||||
if (attacks && monster_can_attack(u)) {
|
||||
int m = monster_attacks(u, true);
|
||||
if (m > 0) money += m;
|
||||
}
|
||||
|
@ -774,7 +796,7 @@ void plan_monsters(faction * f)
|
|||
ta = a_find(u->attribs, &at_hate);
|
||||
if (ta && !monster_is_waiting(u)) {
|
||||
unit *tu = (unit *)ta->data.v;
|
||||
if (tu && tu->region == r) {
|
||||
if (tu && tu->region == r && monster_can_attack(u)) {
|
||||
order * ord = monster_attack(u, tu);
|
||||
if (ord) {
|
||||
unit_addorder(u, ord);
|
||||
|
@ -792,7 +814,7 @@ void plan_monsters(faction * f)
|
|||
else
|
||||
a_remove(&u->attribs, ta);
|
||||
}
|
||||
else if (!r->land || guarding) {
|
||||
else if (monster_can_attack(u)) {
|
||||
if (chance(attack_chance)) {
|
||||
int m = monster_attacks(u, false);
|
||||
if (m >= 0) {
|
||||
|
@ -1013,14 +1035,6 @@ void spawn_undead(void)
|
|||
}
|
||||
}
|
||||
|
||||
bool monster_is_waiting(const unit * u)
|
||||
{
|
||||
int test = fval(u_race(u), RCF_ATTACK_MOVED) ? UFL_ISNEW : UFL_ISNEW | UFL_MOVED;
|
||||
if (fval(u, test))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void eaten_by_monster(unit * u)
|
||||
{
|
||||
/* adjustment for smaller worlds */
|
||||
|
|
|
@ -18,7 +18,6 @@ extern "C" {
|
|||
void monsters_desert(struct faction *monsters);
|
||||
|
||||
void monster_kills_peasants(struct unit *u);
|
||||
bool monster_is_waiting(const struct unit *u);
|
||||
void make_zombie(struct unit * u);
|
||||
|
||||
void spawn_undead(void);
|
||||
|
|
|
@ -97,6 +97,7 @@ static void test_monsters_attack_ocean(CuTest * tc)
|
|||
{
|
||||
region *r;
|
||||
unit *u, *m;
|
||||
race *rc;
|
||||
|
||||
test_setup();
|
||||
create_monsters(&u, &m);
|
||||
|
@ -107,10 +108,16 @@ static void test_monsters_attack_ocean(CuTest * tc)
|
|||
assert(!m->region->land);
|
||||
|
||||
config_set("rules.monsters.attack_chance", "1");
|
||||
rc = rc_find(m->_race->_name);
|
||||
|
||||
freset(rc, RCF_SWIM);
|
||||
plan_monsters(m->faction);
|
||||
CuAssertPtrEquals(tc, NULL, find_order("attack 2", m));
|
||||
|
||||
fset(rc, RCF_SWIM);
|
||||
plan_monsters(m->faction);
|
||||
CuAssertPtrNotNull(tc, find_order("attack 2", m));
|
||||
|
||||
test_teardown();
|
||||
}
|
||||
|
||||
|
@ -145,7 +152,7 @@ static void test_seaserpent_piracy(CuTest * tc)
|
|||
u_setrace(m, rc = test_create_race("seaserpent"));
|
||||
assert(!m->region->land);
|
||||
fset(m, UFL_MOVED);
|
||||
fset(rc, RCF_ATTACK_MOVED);
|
||||
fset(rc, RCF_ATTACK_MOVED|RCF_SWIM);
|
||||
|
||||
config_set("rules.monsters.attack_chance", "1");
|
||||
|
||||
|
|
|
@ -1718,23 +1718,23 @@ nr_ship(struct stream *out, const region *r, const ship * sh, const faction * f,
|
|||
char buffer[1024];
|
||||
char ch;
|
||||
sbstring sbs;
|
||||
const char *stname;
|
||||
|
||||
sbs_init(&sbs, buffer, sizeof(buffer));
|
||||
newline(out);
|
||||
|
||||
stname = locale_plural(f->locale, sh->type->_name, sh->number, true);
|
||||
if (captain && captain->faction == f) {
|
||||
int n = 0, p = 0;
|
||||
const char *stname;
|
||||
|
||||
getshipweight(sh, &n, &p);
|
||||
n = (n + 99) / 100; /* 1 Silber = 1 GE */
|
||||
|
||||
stname = locale_plural(f->locale, sh->type->_name, sh->number, true);
|
||||
sbs_printf(&sbs, "%s, %d %s, (%d/%d)", shipname(sh), sh->number,
|
||||
stname, n, ship_capacity(sh) / 100);
|
||||
}
|
||||
else {
|
||||
sbs_printf(&sbs, "%s, %s", shipname(sh), LOC(f->locale, sh->type->_name));
|
||||
sbs_printf(&sbs, "%s, %d %s", shipname(sh), sh->number, stname);
|
||||
}
|
||||
|
||||
if (!ship_finished(sh)) {
|
||||
|
|
|
@ -2358,9 +2358,8 @@ static void patzer_peasantmob(const castorder * co)
|
|||
rsetpeasants(r, rpeasants(r) - n);
|
||||
assert(rpeasants(r) >= 0);
|
||||
|
||||
u =
|
||||
create_unit(r, f, n, get_race(RC_PEASANT), 0, LOC(f->locale, "angry_mob"),
|
||||
NULL);
|
||||
u = create_unit(r, f, n, get_race(RC_PEASANT), 0,
|
||||
LOC(f->locale, "angry_mob"), NULL);
|
||||
fset(u, UFL_ISNEW);
|
||||
unit_addorder(u, create_order(K_GUARD, lang, NULL));
|
||||
set_order(&u->thisorder, default_order(lang));
|
||||
|
|
|
@ -106,10 +106,9 @@ param_t findparam_block(const char *s, const struct locale *lang, bool any_local
|
|||
|
||||
bool isparam(const char *s, const struct locale * lang, param_t param)
|
||||
{
|
||||
assert(s);
|
||||
assert(param != P_GEBAEUDE);
|
||||
assert(param != P_BUILDING);
|
||||
if (s[0] > '@') {
|
||||
if (s && s[0] > '@') {
|
||||
param_t p = findparam(s, lang);
|
||||
return p == param;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue