Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion process/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
install(PROGRAMS create-orders backup-box backup-onedrive
run-turn send-zip-report
run-turn send-zip-report updatelist.sh
send-bz2-report compress.py compress.sh epasswd.py
accept-orders.py getemail.py checkpasswd.py
sendreport.sh sendreports.sh orders-accept DESTINATION bin)
Expand Down
1 change: 1 addition & 0 deletions process/cron/run-eressea.cron
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ backup BACKUP "$GAME" "$TURN"
upload "$BACKUP"
rm -f execute.lock
"$BIN/run-turn" "$GAME" "$TURN"
"$BIN/updatelist.sh" "$TURN"
touch execute.lock

(( NEXTTURN=TURN+1 )) || true
Expand Down
9 changes: 9 additions & 0 deletions process/updatelist.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/sh

TURN=$1
LIST=eressea-announce@kn-bremen.de
awk '{ if ($2 =="'$TURN'") print $5 }' deadlog.txt |\
mailman delmembers -f- -l$LIST
tail reports/reports.txt | cut -d: -f2 | sed -e 's/email=//' | \
mailman addmembers - $LIST

2 changes: 1 addition & 1 deletion res/e3a/races.xml
Original file line number Diff line number Diff line change
Expand Up @@ -714,7 +714,7 @@
<skill name="building" modifier="-99"/>
<skill name="forestry" modifier="-99"/>
<skill name="catapult" modifier="-99"/>
<skill name="magic" modifier="-99"/>
<skill name="magic" modifier="-99"/>
<skill name="training" modifier="-99"/>
<skill name="riding" modifier="-99"/>
<skill name="armorer" modifier="-99"/>
Expand Down
3 changes: 2 additions & 1 deletion src/battle.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "kernel/region.h"
#include "kernel/ship.h"
#include "kernel/skill.h"
#include "kernel/skills.h"
#include "kernel/terrain.h"
#include "kernel/unit.h"
#include "kernel/spell.h"
Expand Down Expand Up @@ -938,7 +939,7 @@ void kill_troop(troop dt)
*/
void drain_exp(struct unit *u, int n)
{
skill_t sk = (skill_t)(rng_int() % MAXSKILLS);
skill_t sk = (skill_t)(rng_uint() % MAXSKILLS);
skill_t ssk;

/* TODO (enno): we can use u->skill_size to find a random skill */
Expand Down
1 change: 1 addition & 0 deletions src/battle.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,7 @@ static void test_combat_rosthauch(CuTest *tc) {
const resource_type *rtype;

test_setup();
random_source_inject_constants(1.0, 0xdeadbeef);
init_resources();
rtype = rt_get_or_create("iron");
it_rust1 = create_weapon("sword", rtype);
Expand Down
16 changes: 9 additions & 7 deletions src/bind_region.c
Original file line number Diff line number Diff line change
Expand Up @@ -273,15 +273,17 @@ static int tolua_region_has_border(lua_State *L)
if (btype) {
direction_t dir = (direction_t)tolua_tonumber(L, 3, 0);
region *r2 = rconnect(r, dir);
connection *b;
for (b = get_borders(r, r2); b; b = b->next) {
if (b->type == btype) {
lua_pushboolean(L, true);
return 1;
if (r2) {
connection *b;
for (b = get_borders(r, r2); b; b = b->next) {
if (b->type == btype) {
lua_pushboolean(L, true);
return 1;
}
}
lua_pushboolean(L, false);
return 1;
}
lua_pushboolean(L, false);
return 1;
}
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion src/crimport.c
Original file line number Diff line number Diff line change
Expand Up @@ -898,7 +898,7 @@ static enum CR_Error handle_skill(context *ctx, const char *value, const char *n
int level = atoi(val + 1) - rc_skillmod(rc, sk) - terrain_mod(rc, sk, u->region);
if (level > 0) {
struct skill *sv = add_skill(u, sk);
sk_set_level(sv, level);
sk_set_level(u, sv, level);
sv->old = sv->level;
}
if (sk == SK_STAMINA) {
Expand Down
7 changes: 4 additions & 3 deletions src/exparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <stb_ds.h>

#include <assert.h>
#include <limits.h>
#include <string.h>

#ifdef XML_LARGE_SIZE
Expand Down Expand Up @@ -1070,7 +1071,7 @@ static void start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr
}
else if (xml_strequal(el, "skill")) {
const XML_Char *name = NULL;
int i, speed = 0, mod = 0;
int i, speed = INT_MAX, mod = 0;

for (i = 0; attr[i]; i += 2) {
const XML_Char *key = attr[i], *val = attr[i + 1];
Expand All @@ -1090,8 +1091,8 @@ static void start_races(parseinfo *pi, const XML_Char *el, const XML_Char **attr
if (name) {
skill_t sk = find_skill(name);
if (sk != NOSKILL) {
rc->bonus[sk] = (char)mod;
if (speed != 0) {
rc->bonus[sk] = (signed char)mod;
if (speed != INT_MAX) {
set_study_speed(rc, sk, speed);
}
}
Expand Down
1 change: 1 addition & 0 deletions src/kernel/build.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ static void test_build_with_potion_and_ring(CuTest *tc)
set_level(u, bf.cons.skill, bf.cons.minskill);
CuAssertIntEquals(tc, 1, build(u, 1, &bf.cons, 0, 200, 0));

set_level(u, bf.cons.skill, bf.cons.minskill);
i_change(&u->items, ring, 1);
change_effect(u, ptype, 4);
CuAssertIntEquals(tc, 11, build(u, 1, &bf.cons, 0, 200, 0));
Expand Down
7 changes: 5 additions & 2 deletions src/kernel/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,11 @@ static connection **get_borders_i(const region * r1, const region * r2)

connection *get_borders(const region * r1, const region * r2)
{
connection **bp = get_borders_i(r1, r2);
return *bp;
if (r1 && r2) {
connection **bp = get_borders_i(r1, r2);
return *bp;
}
return NULL;
}

connection *border_create(region *from)
Expand Down
3 changes: 1 addition & 2 deletions src/kernel/messages.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

#include "util/message.h"
#include "util/keyword.h" // for K_ENTERTAIN, K_MOVE
#include "util/variant.h" // for variant

#include <CuTest.h>
#include <tests.h>
Expand Down Expand Up @@ -88,7 +87,7 @@ void test_add_message(CuTest *tc) {
CuAssertPtrEquals(tc, msg, mlist->begin->msg);
CuAssertPtrEquals(tc, NULL, mlist->begin->next);
CuAssertIntEquals(tc, 2, msg->refcount);
msg->is_silent = 1;
msg->is_silent = -1;
add_message(&mlist, msg);
CuAssertIntEquals(tc, 2, msg->refcount);
CuAssertPtrEquals(tc, NULL, mlist->begin->next);
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/race.c
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ void set_study_speed(race *rc, skill_t sk, int modifier) {
rc->study_speed = calloc(1, MAXSKILLS);
if (!rc->study_speed) abort();
}
rc->study_speed[sk] = (char)modifier;
rc->study_speed[sk] = (signed char)modifier;
}

const race *rc_otherrace(const race *rc)
Expand Down
1 change: 0 additions & 1 deletion src/kernel/race.test.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

#include <attributes/raceprefix.h>
#include <util/language.h>
#include <util/variant.h>

#include <tests.h>
#include <CuTest.h>
Expand Down
4 changes: 2 additions & 2 deletions src/kernel/region.c
Original file line number Diff line number Diff line change
Expand Up @@ -1097,8 +1097,8 @@ void init_region(region *r)
t_plain = get_terrain(terrainnames[T_PLAIN]);
}
if (terrain->size>0) {
horses = rng_int() % (terrain->size / 50);
trees = terrain->size * (30 + rng_int() % 40) / 1000;
horses = rng_uint() % (terrain->size / 50);
trees = terrain->size * (30 + rng_uint() % 40) / 1000;
}
if (t_plain && terrain == t_plain) {
rsethorses(r, horses);
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/save.c
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ static void write_skills(gamedata *data, const unit *u) {
#ifndef NDEBUG
assert(SK_SKILL(sv) > sk);
sk = SK_SKILL(sv);
assert(sv->days <= MAX_DAYS_TO_NEXT_LEVEL(sv->level));
ASSERT_VALID_SKILL(sv, u_race(u));
#endif
WRITE_INT(data->store, sv->id);
WRITE_INT(data->store, sv->level);
Expand Down
96 changes: 66 additions & 30 deletions src/kernel/skills.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "unit.h"

#include <kernel/attrib.h>
#include <kernel/race.h>
#include <kernel/skills.h>

#include <util/goodies.h>
Expand Down Expand Up @@ -80,62 +81,96 @@ static bool rule_random_progress(void)
return rule != 0;
}

static int progress_weeks(unsigned int level)
static unsigned int progress_weeks(unsigned int level)
/* how many weeks must i study to get from level-1 to level */
{
unsigned int coins = MAX_WEEKS_TO_NEXT_LEVEL(level - 1) - 1;
int heads = 1;
unsigned int heads = 1;
while (coins--) {
heads += rng_int() % 2;
heads += rng_uint() % 2;
}
return heads;
}

static void skill_set(skill *sv, unsigned int level, unsigned int days)
{
assert(days <= MAX_DAYS_TO_NEXT_LEVEL(level));
sv->level = level;
sv->days = days;
assert(sv->days == days && sv->level == level);
}

void sk_set_level(skill *sv, int level)
int study_speed(const struct race *rc, enum skill_t sk)
{
int weeks = rule_random_progress() ? progress_weeks(level + 1) : (level + 1);
skill_set(sv, level, weeks * SKILL_DAYS_PER_WEEK);
int mod = (rc && rc->study_speed) ? rc->study_speed[sk] : 0;
return SKILL_DAYS_PER_WEEK - mod;
}

void increase_skill_weeks(unit * u, enum skill_t sk, const unsigned int weeks)
void sk_set_level(const struct unit *u, skill *sv, unsigned int level)
{
skill *sv = unit_skill(u, sk);
unsigned int days = weeks * SKILL_DAYS_PER_WEEK;
if (!sv) {
sv = add_skill(u, sk);
}
while (sv->days <= days) {
days -= sv->days;
sk_set_level(sv, sv->level + 1);
unsigned int weeks = rule_random_progress() ? progress_weeks(level + 1) : (level + 1);
const struct race *rc = u ? u_race(u) : NULL;
int speed = rc ? study_speed(rc, sv->id) : SKILL_DAYS_PER_WEEK;
unsigned int days = SKILL_DAYS_PER_WEEK + (weeks - 1) * speed;
ASSERT_VALID_SKILL(sv, rc);
skill_set(sv, level, days);
}

static void increase_skill_days(unit *u, skill *sv, unsigned int days) {
if (days > 0) {
unsigned int leveldays = sv->days;
while (leveldays <= days) {
sk_set_level(u, sv, sv->level + 1);
days -= leveldays;
leveldays = sv->days;
}
sv->days = leveldays - days;
ASSERT_VALID_SKILL(sv, u_race(u));
}
sv->days -= days;
assert(sv->days <= MAX_DAYS_TO_NEXT_LEVEL(sv->level));
}

void reduce_skill_weeks(unit * u, skill * sv, const unsigned int weeks)
static void reduce_skill_days(unit *u, skill *sv, unsigned int days)
{
unsigned int days = weeks * SKILL_DAYS_PER_WEEK;
unsigned int max_days = MAX_DAYS_TO_NEXT_LEVEL(sv->level);
if (sv) {
// first, strip full levels off the skill:
// max_days = maximum days I can have "to do" at current level
unsigned int max_days = MAX_DAYS_TO_NEXT_LEVEL(sv->level);
days += sv->days;
while (sv->level > 0 && max_days < days) {
// level_days = expected time to complete current level.
unsigned int level_days = SKILL_DAYS_PER_WEEK * (1 + sv->level);
days -= level_days;
--sv->level;
max_days = MAX_DAYS_TO_NEXT_LEVEL(sv->level);
}
// store the remaining days
sv->days = days;
if (sv->level == 0 && sv->days >= SKILL_DAYS_PER_WEEK) {
remove_skill(u, (skill_t)sv->id);
}
}
}

sv->days += days;
while (sv->level > 0 && sv->days > max_days) {
sv->days -= sv->level * SKILL_DAYS_PER_WEEK;
--sv->level;
max_days -= 2 * SKILL_DAYS_PER_WEEK;
void change_skill(unit *u, skill *sv, int days)
{
assert(sv);
if (days < 0) {
reduce_skill_days(u, sv, -days);
}
else {
increase_skill_days(u, sv, days);
}
if (sv->level == 0) {
/* reroll */
sk_set_level(sv, sv->level + 1);
}

void change_skill_days(struct unit *u, enum skill_t sk, int days)
{
assert(sk >= 0 && sk < MAXSKILLS);
if (days != 0) {
skill *sv = unit_skill(u, sk);
if (!sv && days > 0) {
sv = add_skill(u, sk);
}
change_skill(u, sv, days);
}
assert(sv->days <= MAX_DAYS_TO_NEXT_LEVEL(sv->level));
}

int skill_compare(const skill * sk, const skill * sc)
Expand Down Expand Up @@ -232,3 +267,4 @@ int skill_days(unit *u, enum skill_t sk)
const skill *sv = unit_skill(u, sk);
return sv ? sv->days : 1;
}

12 changes: 8 additions & 4 deletions src/kernel/skills.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@

#define MAX_WEEKS_TO_NEXT_LEVEL(level) ((level) * 2 + 1)
#define MAX_DAYS_TO_NEXT_LEVEL(level) (SKILL_DAYS_PER_WEEK * MAX_WEEKS_TO_NEXT_LEVEL(level))

#define MAX_DAYS_TO_NEXT_LEVEL_EX(level, speed) (SKILL_DAYS_PER_WEEK + (speed) * (MAX_WEEKS_TO_NEXT_LEVEL(level) - 1))
#define ASSERT_VALID_SKILL(sv, rc) \
assert((sv)->days <= MAX_DAYS_TO_NEXT_LEVEL_EX((sv)->level, study_speed((rc), (sv)->id)))
typedef struct skill {
unsigned int id : 5;
unsigned int level : 7;
Expand Down Expand Up @@ -35,14 +37,16 @@ int skillmod(const struct unit *u, const struct region *r,
struct attrib *make_skillmod(enum skill_t sk, skillmod_fun special,
double multiplier, int bonus);

void increase_skill_weeks(struct unit * u, enum skill_t sk, const unsigned int weeks);
void reduce_skill_weeks(struct unit *u, skill * sv, const unsigned int weeks);
void change_skill_days(struct unit *u, enum skill_t sk, int days);
void change_skill(struct unit *u, skill *sv, int days);
int merge_skill(const skill* sv, const skill* sn, skill* result, int n, int add);
void sk_set_level(skill * sv, int level);
void sk_set_level(const struct unit *u, skill * sv, unsigned int level);
int skill_compare(const skill* sk, const skill* sc);

int skill_level(struct unit *u, enum skill_t sk);
/** number of days-equivalent the unit must STUDY to reach the next level: */
int skill_days(struct unit *u, enum skill_t sk);
/** number of days in a week for this learner */
int study_speed(const struct race *rc, enum skill_t sk);

#define SK_SKILL(sv) ((skill_t) (sv->id))
Loading