Bewegung durch Region blockieren

Etwas größerer Umbau. Befreundete Wachen erlauben nicht mehr automatisch
die Durchreise.  Es werden sowohl die Befreundeten als auch die
Feindlichen Bewacher in der Region gezählt, und die Differenz mit
rules.guard.guard_number_stop_prob multipliziert. Bei 700 Feindlichen
und keinen freundlichen Wachen ist die Chance dann 100%. Bei 100
Feindlichen und 400 freundlichen ist sie 0.
Zusätzlich gibt rules.guard.castle_stop_prob 10% pro Burgenlevel für den
Burgenbesitzer.
rules.guard.region_type_stop_prob gibt 10% für Regionen mit weniger
Begehbaren Pfaden (Berge und Vulkane) und das doppelte für sehr schwer
passierbare Regionen (Sümpfe und Gletscher).

Für Spiele mit Wahrnehmung (E2) sollten die Werte für:
rules.guard.skill_stop_prob
rules.guard.castle_stop_prob
rules.guard.region_type_stop_prob

auf 5% Angepasst werden.
This commit is contained in:
CTD 2014-08-14 12:37:59 +02:00
parent bdbffba68e
commit 7dd86959a9
1 changed files with 32 additions and 20 deletions

View File

@ -42,6 +42,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "ship.h" #include "ship.h"
#include "skill.h" #include "skill.h"
#include "terrain.h" #include "terrain.h"
#include "terrainid.h"
#include "teleport.h" #include "teleport.h"
#include "unit.h" #include "unit.h"
@ -839,48 +840,48 @@ static void caught_target(region * r, unit * u)
} }
} }
/* TODO: Unsichtbarkeit bedenken ! */
static unit *bewegung_blockiert_von(unit * reisender, region * r) static unit *bewegung_blockiert_von(unit * reisender, region * r)
{ {
unit *u; unit *u;
double prob = 0.0; double prob = 0.0;
bool contact = false;
unit *guard = NULL; unit *guard = NULL;
int guard_count = 0;
int stealth = eff_stealth(reisender, r); int stealth = eff_stealth(reisender, r);
static int gamecookie = -1; static int gamecookie = -1;
static double base_prob = -999; static double base_prob = -999;
static double skill_prob = -999; static double skill_prob = -999;
static double amulet_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) { if (gamecookie < 0 || gamecookie != global.cookie) {
base_prob = base_prob = get_param_flt(global.parameters, "rules.guard.base_stop_prob", .3f);
get_param_flt(global.parameters, "rules.guard.base_stop_prob", .3f); skill_prob = get_param_flt(global.parameters, "rules.guard.skill_stop_prob", .1f);
skill_prob = amulet_prob = get_param_flt(global.parameters, "rules.guard.amulet_stop_prob", .1f);
get_param_flt(global.parameters, "rules.guard.skill_stop_prob", .1f); guard_number_prob = get_param_flt(global.parameters, "rules.guard.guard_number_stop_prob", .001f);
amulet_prob = castle_prob = get_param_flt(global.parameters, "rules.guard.castle_stop_prob", .1f);
get_param_flt(global.parameters, "rules.guard.amulet_stop_prob", .1f); region_type_prob = get_param_flt(global.parameters, "rules.guard.region_type_stop_prob", .1f);
gamecookie = global.cookie; gamecookie = global.cookie;
} }
if (fval(u_race(reisender), RCF_ILLUSIONARY)) if (fval(u_race(reisender), RCF_ILLUSIONARY))
return NULL; return NULL;
for (u = r->units; u && !contact; u = u->next) { for (u = r->units; u; u = u->next) {
if (is_guard(u, GUARD_TRAVELTHRU)) { if (is_guard(u, GUARD_TRAVELTHRU)) {
int sk = eff_skill(u, SK_PERCEPTION, r); int sk = eff_skill(u, SK_PERCEPTION, r);
if (invisible(reisender, u) >= reisender->number) if (invisible(reisender, u) >= reisender->number)
continue; continue;
if (u->faction == reisender->faction) if ((u->faction == reisender->faction) || (ucontact(u, reisender)) || (alliedunit(u, reisender->faction, HELP_GUARD)))
contact = true; guard_count = guard_count - u->number;
else if (ucontact(u, reisender))
contact = true;
else if (alliedunit(u, reisender->faction, HELP_GUARD))
contact = true;
else if (sk >= stealth) { else if (sk >= stealth) {
guard_count =+ u->number;
double prob_u = (sk - stealth) * skill_prob; double prob_u = (sk - stealth) * skill_prob;
/* amulet counts at most once */ /* amulet counts at most once */
prob_u += _min(1, _min(u->number, i_get(u->items, ramulet->itype))) * amulet_prob; prob_u += _min (1, _min(u->number, i_get(u->items, ramulet->itype))) * amulet_prob;
if (u->building && (u->building->type == bt_find("castle")) && u == building_owner(u->building))
prob_u += castle_prob*buildingeffsize(u->building, 0);
if (prob_u >= prob) { if (prob_u >= prob) {
prob = prob_u; prob = prob_u;
guard = u; guard = u;
@ -888,14 +889,25 @@ static unit *bewegung_blockiert_von(unit * reisender, region * r)
} }
} }
} }
if (!contact && guard) { if (guard) {
prob += base_prob; /* 30% base chance */ prob += base_prob; /* 30% base chance */
prob = +guard_count*guard_number_prob;
if (r->terrain = newterrain(T_GLACIER))
prob = +region_type_prob*2;
if (r->terrain = newterrain(T_SWAMP))
prob = +region_type_prob*2;
if (r->terrain = newterrain(T_MOUNTAIN))
prob = +region_type_prob;
if (r->terrain = newterrain(T_VOLCANO))
prob = +region_type_prob;
if (r->terrain = newterrain(T_VOLCANO_SMOKING))
prob = +region_type_prob;
if (chance(prob)) { if (prob > 0 && chance(prob)) {
return guard; return guard;
} }
} }
return NULL; return NULL;
} }
static bool is_guardian_u(const unit * guard, unit * u, unsigned int mask) static bool is_guardian_u(const unit * guard, unit * u, unsigned int mask)