take best unit and count amulet at most once for guards blocking movement

This commit is contained in:
Steffen Mecke 2014-05-28 17:17:36 +02:00
parent 115d3a8f86
commit dc3eea0c70
2 changed files with 131 additions and 7 deletions

View File

@ -2,6 +2,23 @@ require "lunit"
module("tests.e3.e2features", package.seeall, lunit.testcase ) module("tests.e3.e2features", package.seeall, lunit.testcase )
local function one_unit(r, f)
local u = unit.create(f, r, 1)
u:add_item("money", u.number * 100)
u:clear_orders()
return u
end
local function two_factions()
local f1 = faction.create("one@eressea.de", "human", "de")
local f2 = faction.create("two@eressea.de", "human", "de")
return f1, f2
end
local function two_units(r, f1, f2)
return one_unit(r, f1), one_unit(r, f2)
end
function setup() function setup()
eressea.free_game() eressea.free_game()
eressea.settings.set("nmr.timeout", "0") eressea.settings.set("nmr.timeout", "0")
@ -200,3 +217,92 @@ function test_snowman()
end end
assert_equal(nil, u) assert_equal(nil, u)
end end
function test_block_movement()
eressea.settings.set("rules.guard.base_stop_prob", "0.3")
eressea.settings.set("rules.guard.amulet_stop_prob", "0.0")
eressea.settings.set("rules.guard.skill_stop_prob", "0.1")
local r0 = region.create(0, 0, "plain")
local r1 = region.create(1, 0, "plain")
local r2 = region.create(2, 0, "plain")
local f1, f2 = two_factions()
f1.age=20
f2.age=20
local u11 = one_unit(r1, f1)
local u2 = { }
for i = 1, 20 do
u2[i] = one_unit(r0, f2)
end
u11:add_item("sword", 1)
u11:add_item("money", 1)
u11:set_skill("melee", 1)
u11:set_skill("perception", 7)
u11:clear_orders()
u11:add_order("BEWACHEN")
process_orders()
for i, u in ipairs(u2) do
u:add_item("horse", 1)
u:set_skill("riding", 1)
u:clear_orders()
u:add_order("NACH o o")
end
u2[1]:set_skill("stealth", 8)
process_orders()
assert_equal(r2, u2[1].region, "nobody should see me")
for i, u in ipairs(u2) do
if i > 1 then
assert_equal(r1, u.region, "perception +7 should always stop me")
end
end
end
function test_block_movement_aots()
eressea.settings.set("rules.guard.base_stop_prob", "0.0")
eressea.settings.set("rules.guard.skill_stop_prob", "1.0")
eressea.settings.set("rules.guard.amulet_stop_prob", "1.1")
local r0 = region.create(0, 0, "plain")
local r1 = region.create(1, 0, "plain")
local r2 = region.create(2, 0, "plain")
local f1, f2 = two_factions()
f1.age=20
f2.age=20
local u11, u12 = two_units(r1, f1, f1)
local u21, u22 = two_units(r0, f2, f2)
for i, u in ipairs ({ u11, u12 }) do
u:add_item("sword", 1)
u:add_item("money", 1)
u:set_skill("melee", 1)
u:clear_orders()
u:add_order("BEWACHEN")
end
process_orders()
for i, u in ipairs ({ u21, u22 }) do
u:add_item("horse", 1)
u:set_skill("riding", 1)
u:clear_orders()
u:add_order("NACH o o")
end
u12:add_item("aots", 10)
u22:set_skill("stealth", 1)
process_orders()
assert_equal(r1, u21.region, "unit with amulet should stop me")
assert_equal(r2, u22.region, "nobody should see me")
end

View File

@ -828,9 +828,24 @@ static void caught_target(region * r, unit * u)
static unit *bewegung_blockiert_von(unit * reisender, region * r) static unit *bewegung_blockiert_von(unit * reisender, region * r)
{ {
unit *u; unit *u;
int perception = 0; double prob = 0.0;
bool contact = false; bool contact = false;
unit *guard = NULL; unit *guard = NULL;
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;
if (gamecookie < 0 || gamecookie != global.cookie) {
base_prob =
get_param_flt(global.parameters, "rules.guard.base_stop_prob", .3);
skill_prob =
get_param_flt(global.parameters, "rules.guard.skill_stop_prob", .1);
amulet_prob =
get_param_flt(global.parameters, "rules.guard.amulet_stop_prob", .1);
gamecookie = global.cookie;
}
if (fval(u_race(reisender), RCF_ILLUSIONARY)) if (fval(u_race(reisender), RCF_ILLUSIONARY))
return NULL; return NULL;
@ -845,16 +860,19 @@ static unit *bewegung_blockiert_von(unit * reisender, region * r)
contact = true; contact = true;
else if (alliedunit(u, reisender->faction, HELP_GUARD)) else if (alliedunit(u, reisender->faction, HELP_GUARD))
contact = true; contact = true;
else if (sk >= perception) { else if (sk >= stealth) {
perception = sk; double prob_u = (sk - stealth) * skill_prob;
guard = u; /* amulet counts at most once */
prob_u += _min (1, _min(u->number, get_item(u, I_AMULET_OF_TRUE_SEEING))) * amulet_prob;
if (prob_u >= prob) {
prob = prob_u;
guard = u;
}
} }
} }
} }
if (!contact && guard) { if (!contact && guard) {
double prob = 0.3; /* 30% base chance */ prob += base_prob; /* 30% base chance */
prob += 0.1 * (perception - eff_stealth(reisender, r));
prob += 0.1 * _min(guard->number, get_item(guard, I_AMULET_OF_TRUE_SEEING));
if (chance(prob)) { if (chance(prob)) {
return guard; return guard;