forked from github/server
fix healing for elves in a forest.
rename _magres back to magres. rc->parameters is not linked to config_changed invalidation. add tests.
This commit is contained in:
parent
7750297dc2
commit
fd9583df3d
|
@ -352,12 +352,12 @@ static void test_magic_resistance(CuTest *tc)
|
||||||
calculate_armor(dt, 0, 0, &magres);
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
CuAssertDblEquals_Msg(tc, "skill bonus", 0.1, magic_resistance(du), 0.01);
|
CuAssertDblEquals_Msg(tc, "skill bonus", 0.1, magic_resistance(du), 0.01);
|
||||||
CuAssertDblEquals_Msg(tc, "skill reduction", 0.9, magres, 0.01);
|
CuAssertDblEquals_Msg(tc, "skill reduction", 0.9, magres, 0.01);
|
||||||
rc->_magres = 50; /* percentage, gets added to skill bonus */
|
rc->magres = 50; /* percentage, gets added to skill bonus */
|
||||||
calculate_armor(dt, 0, 0, &magres);
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
CuAssertDblEquals_Msg(tc, "race bonus", 0.6, magic_resistance(du), 0.01);
|
CuAssertDblEquals_Msg(tc, "race bonus", 0.6, magic_resistance(du), 0.01);
|
||||||
CuAssertDblEquals_Msg(tc, "race reduction", 0.4, magres, 0.01);
|
CuAssertDblEquals_Msg(tc, "race reduction", 0.4, magres, 0.01);
|
||||||
|
|
||||||
rc->_magres = 150; /* should not cause negative damage multiplier */
|
rc->magres = 150; /* should not cause negative damage multiplier */
|
||||||
CuAssertDblEquals_Msg(tc, "magic resistance is never > 0.9", 0.9, magic_resistance(du), 0.01);
|
CuAssertDblEquals_Msg(tc, "magic resistance is never > 0.9", 0.9, magic_resistance(du), 0.01);
|
||||||
calculate_armor(dt, 0, 0, &magres);
|
calculate_armor(dt, 0, 0, &magres);
|
||||||
CuAssertDblEquals_Msg(tc, "damage reduction is never < 0.1", 0.1, magres, 0.01);
|
CuAssertDblEquals_Msg(tc, "damage reduction is never < 0.1", 0.1, magres, 0.01);
|
||||||
|
|
|
@ -458,7 +458,7 @@ static void json_race(cJSON *json, race *rc) {
|
||||||
break;
|
break;
|
||||||
case cJSON_Number:
|
case cJSON_Number:
|
||||||
if (strcmp(child->string, "magres") == 0) {
|
if (strcmp(child->string, "magres") == 0) {
|
||||||
rc->_magres = child->valueint;
|
rc->magres = child->valueint;
|
||||||
}
|
}
|
||||||
else if (strcmp(child->string, "maxaura") == 0) {
|
else if (strcmp(child->string, "maxaura") == 0) {
|
||||||
rc->maxaura = (float)child->valuedouble;
|
rc->maxaura = (float)child->valuedouble;
|
||||||
|
|
|
@ -163,7 +163,7 @@ static void test_races(CuTest * tc)
|
||||||
CuAssertPtrNotNull(tc, rc);
|
CuAssertPtrNotNull(tc, rc);
|
||||||
CuAssertIntEquals(tc, RCF_NPC | RCF_WALK | RCF_UNDEAD, rc->flags);
|
CuAssertIntEquals(tc, RCF_NPC | RCF_WALK | RCF_UNDEAD, rc->flags);
|
||||||
CuAssertStrEquals(tc, "1d4", rc->def_damage);
|
CuAssertStrEquals(tc, "1d4", rc->def_damage);
|
||||||
CuAssertIntEquals(tc, 100, rc->_magres);
|
CuAssertIntEquals(tc, 100, rc->magres);
|
||||||
CuAssertDblEquals(tc, 1.0, rc_magres(rc), 0.0);
|
CuAssertDblEquals(tc, 1.0, rc_magres(rc), 0.0);
|
||||||
CuAssertDblEquals(tc, 2.0, rc->maxaura, 0.0);
|
CuAssertDblEquals(tc, 2.0, rc->maxaura, 0.0);
|
||||||
CuAssertDblEquals(tc, 3.0, rc->regaura, 0.0);
|
CuAssertDblEquals(tc, 3.0, rc->regaura, 0.0);
|
||||||
|
|
|
@ -283,7 +283,7 @@ bool r_insectstalled(const region * r)
|
||||||
}
|
}
|
||||||
|
|
||||||
double rc_magres(const struct race *rc) {
|
double rc_magres(const struct race *rc) {
|
||||||
return rc->_magres / 100.0;
|
return rc->magres / 100.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* rc_name(const race * rc, name_t n, char *name, size_t size) {
|
const char* rc_name(const race * rc, name_t n, char *name, size_t size) {
|
||||||
|
|
|
@ -116,7 +116,7 @@ extern "C" {
|
||||||
|
|
||||||
typedef struct race {
|
typedef struct race {
|
||||||
char *_name;
|
char *_name;
|
||||||
int _magres;
|
int magres;
|
||||||
float healing;
|
float healing;
|
||||||
double maxaura; /* Faktor auf Maximale Aura */
|
double maxaura; /* Faktor auf Maximale Aura */
|
||||||
double regaura; /* Faktor auf Regeneration */
|
double regaura; /* Faktor auf Regeneration */
|
||||||
|
|
|
@ -23,8 +23,9 @@ static void test_rc_defaults(CuTest *tc) {
|
||||||
test_setup();
|
test_setup();
|
||||||
rc = rc_get_or_create("human");
|
rc = rc_get_or_create("human");
|
||||||
CuAssertStrEquals(tc, "human", rc->_name);
|
CuAssertStrEquals(tc, "human", rc->_name);
|
||||||
CuAssertIntEquals(tc, 0, rc->_magres);
|
CuAssertIntEquals(tc, 0, rc->magres);
|
||||||
CuAssertDblEquals(tc, 0.0, rc_magres(rc), 0.0);
|
CuAssertDblEquals(tc, 0.0, rc_magres(rc), 0.0);
|
||||||
|
CuAssertDblEquals(tc, 0.0, rc->healing, 0.0);
|
||||||
CuAssertDblEquals(tc, 0.0, rc->maxaura, 0.0);
|
CuAssertDblEquals(tc, 0.0, rc->maxaura, 0.0);
|
||||||
CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0);
|
CuAssertDblEquals(tc, 1.0, rc->recruit_multi, 0.0);
|
||||||
CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0);
|
CuAssertDblEquals(tc, 1.0, rc->regaura, 0.0);
|
||||||
|
|
|
@ -2047,3 +2047,25 @@ bool has_limited_skills(const struct unit * u)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double u_heal_factor(const unit * u)
|
||||||
|
{
|
||||||
|
const race * rc = u_race(u);
|
||||||
|
if (rc->healing>0) {
|
||||||
|
return rc->healing;
|
||||||
|
}
|
||||||
|
if (r_isforest(u->region)) {
|
||||||
|
static int rc_cache;
|
||||||
|
static const race *rc_elf;
|
||||||
|
if (rc_changed(&rc_cache)) {
|
||||||
|
rc_elf = get_race(RC_ELF);
|
||||||
|
}
|
||||||
|
if (rc == rc_elf) {
|
||||||
|
double elf_regen = 1.0;
|
||||||
|
if (rc->parameters) {
|
||||||
|
elf_regen = get_param_flt(rc->parameters, "regen.forest", elf_regen);
|
||||||
|
}
|
||||||
|
return elf_regen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
|
@ -190,6 +190,7 @@ extern "C" {
|
||||||
bool leave(struct unit *u, bool force);
|
bool leave(struct unit *u, bool force);
|
||||||
bool can_leave(struct unit *u);
|
bool can_leave(struct unit *u);
|
||||||
|
|
||||||
|
double u_heal_factor(const struct unit * u);
|
||||||
void u_set_building(struct unit * u, struct building * b);
|
void u_set_building(struct unit * u, struct building * b);
|
||||||
void u_set_ship(struct unit * u, struct ship * sh);
|
void u_set_ship(struct unit * u, struct ship * sh);
|
||||||
void leave_ship(struct unit * u);
|
void leave_ship(struct unit * u);
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <kernel/race.h>
|
#include <kernel/race.h>
|
||||||
#include <kernel/region.h>
|
#include <kernel/region.h>
|
||||||
#include <kernel/spell.h>
|
#include <kernel/spell.h>
|
||||||
|
#include <kernel/terrain.h>
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
#include <util/base36.h>
|
#include <util/base36.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
|
@ -483,6 +484,32 @@ static void test_name_unit(CuTest *tc) {
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_heal_factor(CuTest *tc) {
|
||||||
|
unit * u;
|
||||||
|
region *r;
|
||||||
|
race *rc;
|
||||||
|
terrain_type *t_plain;
|
||||||
|
|
||||||
|
test_setup();
|
||||||
|
t_plain = test_create_terrain("plain", LAND_REGION|FOREST_REGION);
|
||||||
|
rc = rc_get_or_create("human");
|
||||||
|
u = test_create_unit(test_create_faction(rc), r = test_create_region(0, 0, t_plain));
|
||||||
|
rsettrees(r, 1, r->terrain->size / TREESIZE);
|
||||||
|
rsettrees(r, 2, 0);
|
||||||
|
CuAssertTrue(tc, r_isforest(r));
|
||||||
|
CuAssertDblEquals(tc, 1.0, u_heal_factor(u), 0.0);
|
||||||
|
rc->healing = 2.0;
|
||||||
|
CuAssertDblEquals(tc, 2.0, u_heal_factor(u), 0.0);
|
||||||
|
rc->healing = 0.0;
|
||||||
|
rc = rc_get_or_create("elf");
|
||||||
|
CuAssertPtrEquals(tc, (void *)rc, (void *)get_race(RC_ELF));
|
||||||
|
u_setrace(u, get_race(RC_ELF));
|
||||||
|
CuAssertDblEquals(tc, 1.0, u_heal_factor(u), 0.0);
|
||||||
|
set_param(&rc->parameters, "regen.forest", "1.5");
|
||||||
|
CuAssertDblEquals(tc, 1.5, u_heal_factor(u), 0.0);
|
||||||
|
test_cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
CuSuite *get_unit_suite(void)
|
CuSuite *get_unit_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
|
@ -507,5 +534,6 @@ CuSuite *get_unit_suite(void)
|
||||||
SUITE_ADD_TEST(suite, test_limited_skills);
|
SUITE_ADD_TEST(suite, test_limited_skills);
|
||||||
SUITE_ADD_TEST(suite, test_renumber_unit);
|
SUITE_ADD_TEST(suite, test_renumber_unit);
|
||||||
SUITE_ADD_TEST(suite, test_name_unit);
|
SUITE_ADD_TEST(suite, test_name_unit);
|
||||||
|
SUITE_ADD_TEST(suite, test_heal_factor);
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1635,7 +1635,7 @@ static int parse_races(xmlDocPtr doc)
|
||||||
rc->def_damage = strdup((const char *)propValue);
|
rc->def_damage = strdup((const char *)propValue);
|
||||||
xmlFree(propValue);
|
xmlFree(propValue);
|
||||||
|
|
||||||
rc->_magres = xml_ivalue(node, "magres", rc->_magres);
|
rc->magres = xml_ivalue(node, "magres", rc->magres);
|
||||||
rc->healing = (float)xml_fvalue(node, "healing", rc->healing);
|
rc->healing = (float)xml_fvalue(node, "healing", rc->healing);
|
||||||
rc->maxaura = (float)xml_fvalue(node, "maxaura", rc->maxaura);
|
rc->maxaura = (float)xml_fvalue(node, "maxaura", rc->maxaura);
|
||||||
rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura);
|
rc->regaura = (float)xml_fvalue(node, "regaura", rc->regaura);
|
||||||
|
|
26
src/laws.c
26
src/laws.c
|
@ -3271,30 +3271,6 @@ static int use_item(unit * u, const item_type * itype, int amount, struct order
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static double heal_factor(const unit * u)
|
|
||||||
{
|
|
||||||
const race * rc = u_race(u);
|
|
||||||
if (rc->healing>0) {
|
|
||||||
return rc->healing;
|
|
||||||
}
|
|
||||||
if (r_isforest(u->region)) {
|
|
||||||
static int rc_cache;
|
|
||||||
static const race *rc_elf;
|
|
||||||
if (rc_changed(&rc_cache)) {
|
|
||||||
rc_elf = get_race(RC_ELF);
|
|
||||||
}
|
|
||||||
if (rc==rc_elf) {
|
|
||||||
static int config;
|
|
||||||
static double elf_regen = 1.0;
|
|
||||||
if (config_changed(&config)) {
|
|
||||||
elf_regen = get_param_flt(u_race(u)->parameters, "regen.forest", 1.0F);
|
|
||||||
}
|
|
||||||
return elf_regen;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 1.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void monthly_healing(void)
|
void monthly_healing(void)
|
||||||
{
|
{
|
||||||
region *r;
|
region *r;
|
||||||
|
@ -3334,7 +3310,7 @@ void monthly_healing(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
p *= heal_factor(u);
|
p *= u_heal_factor(u);
|
||||||
if (u->hp < umhp) {
|
if (u->hp < umhp) {
|
||||||
double maxheal = MAX(u->number, umhp / 20.0);
|
double maxheal = MAX(u->number, umhp / 20.0);
|
||||||
int addhp;
|
int addhp;
|
||||||
|
|
|
@ -413,11 +413,11 @@ static void test_magic_resistance(CuTest *tc) {
|
||||||
test_setup();
|
test_setup();
|
||||||
rc = test_create_race("human");
|
rc = test_create_race("human");
|
||||||
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
|
u = test_create_unit(test_create_faction(rc), test_create_region(0, 0, 0));
|
||||||
CuAssertDblEquals(tc, rc->_magres/100.0, magic_resistance(u), 0.01);
|
CuAssertDblEquals(tc, rc->magres/100.0, magic_resistance(u), 0.01);
|
||||||
rc->_magres = 100;
|
rc->magres = 100;
|
||||||
CuAssertDblEquals_Msg(tc, "magic resistance is capped at 0.9", 0.9, magic_resistance(u), 0.01);
|
CuAssertDblEquals_Msg(tc, "magic resistance is capped at 0.9", 0.9, magic_resistance(u), 0.01);
|
||||||
rc = test_create_race("braineater");
|
rc = test_create_race("braineater");
|
||||||
rc->_magres = 100;
|
rc->magres = 100;
|
||||||
u_setrace(u, rc);
|
u_setrace(u, rc);
|
||||||
CuAssertDblEquals_Msg(tc, "brain eaters outside astral space have 50% magres", 0.5, magic_resistance(u), 0.01);
|
CuAssertDblEquals_Msg(tc, "brain eaters outside astral space have 50% magres", 0.5, magic_resistance(u), 0.01);
|
||||||
u->region->_plane = get_astralplane();
|
u->region->_plane = get_astralplane();
|
||||||
|
|
|
@ -217,6 +217,9 @@ terrain_type *
|
||||||
test_create_terrain(const char * name, unsigned int flags)
|
test_create_terrain(const char * name, unsigned int flags)
|
||||||
{
|
{
|
||||||
terrain_type * t = get_or_create_terrain(name);
|
terrain_type * t = get_or_create_terrain(name);
|
||||||
|
if (flags & LAND_REGION) {
|
||||||
|
t->size = 1000;
|
||||||
|
}
|
||||||
t->flags = flags;
|
t->flags = flags;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue