Merge pull request #846 from ennorehling/develop

Development ongoing
This commit is contained in:
Enno Rehling 2019-04-27 18:43:50 +02:00 committed by GitHub
commit f42df810d6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 380 additions and 158 deletions

View File

@ -54,7 +54,7 @@ hostname = gethostname()
orderbase = "orders.dir"
sendmail = True
# maximum number of reports per sender:
maxfiles = 20
maxfiles = 30
# write headers to file?
writeheaders = True
# reject all html email?

View File

@ -45,9 +45,7 @@ class EPasswd:
def load_database(self, file):
conn = sqlite3.connect(file)
c = conn.cursor()
c.execute('SELECT MAX(turn) FROM factions')
args = c.fetchone()
for row in c.execute('SELECT no, email, password FROM factions WHERE turn=?', args):
for row in c.execute('SELECT `no`, `email`, `password` FROM `faction`'):
(no, email, passwd) = row
self.set_data(baseconvert(no, 36), email, passwd)
conn.close()

View File

@ -25,7 +25,7 @@
<entry spell="cerddor_destroymagic" level="8" />
<entry spell="cerddorfumbleshield" level="5" />
<entry spell="chaosrow" level="8" />
<entry spell="clone" level="9" />
<!-- <entry spell="clone" level="9" /> -->
<entry spell="coldfront" level="8" />
<entry spell="combatrust" level="6" />
<entry spell="combat_speed" level="9" />

View File

@ -27,7 +27,7 @@
<entry spell="readmind" level="7" />
<entry spell="gooddreams" level="8" />
<entry spell="illaundestroymagic" level="8" />
<entry spell="clone" level="9" />
<!-- <entry spell="clone" level="9" /> -->
<entry spell="bad_dreams" level="10" />
<entry spell="mindblast" level="11" />
<entry spell="create_dreameye" level="14" />

View File

@ -79,13 +79,13 @@
<!-- Traumbilder entwirren -->
<resource name="aura" amount="6" cost="level"/>
</spell>
<!-- Seelenkopie, disabled version 3.20, Bug 1982
<spell name="clone" rank="5">
<!-- Seelenkopie -->
<resource name="aura" amount="100" cost="fixed"/>
<resource name="permaura" amount="20" cost="fixed"/>
<resource name="dragonblood" amount="5" cost="fixed"/>
<resource name="silk" amount="20" cost="fixed"/>
</spell>
</spell> -->
<spell name="bad_dreams" rank="5" far="true">
<!-- Schlechte Träume -->
<resource name="aura" amount="90" cost="fixed"/>

View File

@ -30,7 +30,7 @@
<entry spell="cerddorfumbleshield" level="5" />
<entry spell="chaosrow" level="8" />
<entry spell="chaossuction" level="14" />
<entry spell="clone" level="9" />
<!-- <entry spell="clone" level="9" /> -->
<entry spell="coldfront" level="8" />
<entry spell="cold_protection" level="3" />
<entry spell="combatrust" level="6" />

View File

@ -20,7 +20,7 @@
<entry spell="shadowknights" level="1" />
<entry spell="sparkledream" level="1" />
<entry spell="puttorest" level="2" />
<entry spell="clone" level="9" />
<!-- <entry spell="clone" level="9" /> -->
<entry spell="create_roi" level="6" />
<entry spell="earn_silver#illaun" level="1" />
<entry spell="create_aots" level="6" />

View File

@ -314,7 +314,7 @@
<resource name="aura" amount="10" cost="fixed"/>
</spell>
<spell name="analyse_object" rank="5" parameters="kc+" ship="true" variable="true" regiontarget="true" unittarget="false" buildingtarget="true" shiptarget="true">
<resource name="aura" amount="3" cost="level"/>
<resource name="aura" amount="3" cost="level"/>
</spell>
<spell name="destroy_magic" rank="2" parameters="kc+" los="true" ship="true" far="true" variable="true">
<resource name="aura" amount="4" cost="level"/>
@ -446,12 +446,13 @@
<resource name="permaura" amount="10" cost="fixed"/>
<resource name="toadslime" amount="1" cost="fixed"/>
</spell>
<spell name="clone" rank="5">
<!-- Seelenkopie, disabled version 3.20, Bug 1982
<spell name="clone" rank="5">
<resource name="aura" amount="100" cost="fixed"/>
<resource name="permaura" amount="20" cost="fixed"/>
<resource name="dragonblood" amount="5" cost="fixed"/>
<resource name="lifepotion" amount="5" cost="fixed"/>
</spell>
</spell> -->
<spell name="drain_skills" rank="5" combat="2">
<resource name="aura" amount="4" cost="fixed"/>
</spell>

View File

@ -16,22 +16,37 @@ local function tunnel_travelers(b)
end
local function get_target(param)
local ntargets = table.maxn(targets)
if ntargets==0 then
local ntargets = #targets
if ntargets == 0 then
eressea.log.error("Zero tunnel targets for [" .. param .. "]")
return nil
end
local rn = math.fmod(rng_int(), ntargets)
return targets[rn]
local t = targets[rn + 1]
if not t then
eressea.log.error("NULL target for [" .. param .. "]" .. " at index " .. rn)
end
return t
end
local function tunnel_action(b, param)
local units = tunnel_travelers(b)
local rto = get_target(param)
eressea.log.info("Tunnel from " .. tostring(b) .. " [" .. param .. "]")
if rto and units then
eressea.log.debug("Tunnel from " .. tostring(b) .. " [" .. param .. "]")
for key, u in pairs(units) do
for _, u in pairs(units) do
u.region = rto
eressea.log.debug("teleported " .. tostring(u) .. " to " .. tostring(rto))
eressea.log.info("teleported " .. tostring(u) .. " to " .. tostring(rto))
end
elseif not units then
eressea.log.info("No units in tunnel " .. tostring(b) .. " [" .. param .. "]")
elseif not rto then
eressea.log.error("No target for tunnel " .. tostring(b) .. " [" .. param .. "]")
end
-- debug code to find bugs:
for u in b.region.units do
if u.building == b then
eressea.log.error("Did not teleport " .. tostring(u) .. " from tunnel " .. tostring(b))
end
end
end
@ -40,7 +55,7 @@ function tunnels.init()
local r, b
for r in regions() do
if r:get_key('tnnL') then
targets[table.maxn(targets)+1] = r
table.insert(targets, r)
if (r:get_flag(0)) then
-- target region is chaotic? nope.
r:set_flag(0, false)
@ -52,10 +67,11 @@ function tunnels.init()
end
for b in r.buildings do
if b.type == 'portal' then
buildings[table.maxn(buildings)+1] = b
table.insert(buildings, b)
end
end
end
eressea.log.info("Found " .. #targets .. " tunnel targets")
end
function tunnels.update()

View File

@ -15,7 +15,7 @@ local function wedding_travellers(b)
local units = {}
for u in b.units do
if u:get_flag('wdgt') then
if u:get_key('wdgt') then
units[u] = u
end
end

View File

@ -1,9 +1,3 @@
function dump_messages(f)
for k, v in ipairs(f.messages) do
print(v)
end
end
require 'tests.e2.movement'
require 'tests.e2.astral'
require 'tests.e2.spells'

View File

@ -216,21 +216,3 @@ function test_sawmill()
assert_equal(6, u:get_item("log"))
assert_equal(97, r:get_resource("tree"))
end
function test_ent_guards_trees()
local r = region.create(0, 0, "plain")
r:set_resource("tree", 100)
local u = unit.create(faction.create("human"), r)
u:set_skill("mining", 1)
local guard = unit.create(get_monsters(), r, 1, "ent")
u:set_skill("forestry", 1)
guard:clear_orders()
u:clear_orders()
guard:add_order("BEWACHEN")
u:add_order("MACHE HOLZ")
process_orders()
assert_equal(1, u:get_item("log"))
process_orders()
assert_equal(1, u:get_item("log"))
end

View File

@ -54,11 +54,12 @@ static int read_seenspells(variant *var, void *owner, struct gamedata *data)
READ_TOK(store, token, sizeof(token));
while (token[0]) {
spell *sp = find_spell(token);
if (!sp) {
log_info("read_seenspells: could not find spell '%s'\n", token);
return AT_READ_FAIL;
if (sp) {
selist_push(&ql, sp);
}
else {
log_info("read_seenspells: could not find spell '%s'\n", token);
}
selist_push(&ql, sp);
READ_TOK(store, token, sizeof(token));
}
var->v = ql;
@ -70,8 +71,8 @@ static bool cb_write_spell(void *data, void *more) {
storage *store = (storage *)more;
WRITE_TOK(store, sp->sname);
return true;
}
static void
write_seenspells(const variant *var, const void *owner, struct storage *store)
{

View File

@ -760,7 +760,7 @@ static int tolua_unit_has_attrib(lua_State *L) {
return 1;
}
static int tolua_unit_get_flag(lua_State * L)
static int tolua_unit_get_key(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
@ -769,7 +769,7 @@ static int tolua_unit_get_flag(lua_State * L)
return 1;
}
static int tolua_unit_set_flag(lua_State * L)
static int tolua_unit_set_key(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
const char *name = tolua_tostring(L, 2, 0);
@ -784,6 +784,28 @@ static int tolua_unit_set_flag(lua_State * L)
return 0;
}
static int tolua_unit_get_flag(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0);
lua_pushboolean(L, (self->flags & (1 << bit)));
return 1;
}
static int tolua_unit_set_flag(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, NULL);
int bit = (int)tolua_tonumber(L, 2, 0);
int set = tolua_toboolean(L, 3, 1);
if (set)
self->flags |= (1 << bit);
else
self->flags &= ~(1 << bit);
return 0;
}
static int tolua_unit_get_weight(lua_State * L)
{
unit *self = (unit *)tolua_tousertype(L, 1, 0);
@ -959,6 +981,8 @@ void tolua_unit_open(lua_State * L)
tolua_function(L, TOLUA_CAST "has_attrib", tolua_unit_has_attrib);
/* key-attributes for named flags: */
tolua_function(L, TOLUA_CAST "set_key", tolua_unit_set_key);
tolua_function(L, TOLUA_CAST "get_key", tolua_unit_get_key);
tolua_function(L, TOLUA_CAST "set_flag", tolua_unit_set_flag);
tolua_function(L, TOLUA_CAST "get_flag", tolua_unit_get_flag);
tolua_variable(L, TOLUA_CAST "guard", tolua_unit_get_guard,

View File

@ -100,7 +100,7 @@ struct locale *crtag_locale(void) {
static int config;
if (config_changed(&config)) {
const char *lname = config_get("creport.tags");
lang = get_locale(lname ? lname : "de");
lang = lname ? get_locale(lname) : default_locale;
}
return lang;
}
@ -108,8 +108,8 @@ struct locale *crtag_locale(void) {
static const char *crtag(const char *key)
{
const char *result;
result = LOC(crtag_locale(), key);
return result;
result = locale_string(crtag_locale(), key, false);
return result ? result : key;
}
/*
* translation table
@ -848,13 +848,18 @@ void cr_output_unit(stream *out, const faction * f,
pzTmp = get_racename(u->attribs);
if (pzTmp) {
const char *pzRace = LOC(lang, mkname("race", pzTmp));
pzTmp = pzRace ? pzRace : pzTmp;
stream_printf(out, "\"%s\";Typ\n", translate(pzTmp, LOC(lang, pzTmp)));
const char *pzRace = locale_string(lang, mkname("race", pzTmp), false);
if (pzRace) {
pzTmp = pzRace;
}
pzRace = translate(pzTmp, locale_string(lang, pzTmp, false));
if (!pzRace) {
pzRace = pzTmp;
}
stream_printf(out, "\"%s\";Typ\n", pzRace);
if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) {
pzRace = rc_name_s(u_race(u), NAME_PLURAL);
stream_printf(out, "\"%s\";wahrerTyp\n",
translate(pzRace, LOC(lang, pzRace)));
stream_printf(out, "\"%s\";wahrerTyp\n", pzRace);
}
}
else {

View File

@ -9,9 +9,27 @@
#include "kernel/faction.h"
#include "kernel/db/driver.h"
#include "util/strings.h"
static int generate_factions(void *data, db_faction *results, int nresults)
{
int i;
faction **iter = (faction **)data;
for (i = 0; *iter && i != nresults; ++i) {
faction *f = *iter;
const char *pwhash;
results[i].p_uid = &f->uid;
results[i].no = f->no;
results[i].email = faction_getemail(f);
pwhash = faction_getpassword(f);
str_strlcpy(results[i].pwhash, pwhash ? pwhash : "", sizeof(results[i].pwhash));
*iter = f->next;
}
return i;
}
int gamedb_update(void)
{
faction *f;
int err;
const char *dbname;
@ -19,14 +37,9 @@ int gamedb_update(void)
err = db_driver_open(DB_GAME, dbname);
if (err == 0) {
for (f = factions; f; f = f->next) {
int uid = db_driver_faction_save(f->uid, f->no, turn,
faction_getemail(f),
faction_getpassword(f));
if (uid > 0) {
f->uid = uid;
}
}
faction *list = factions;
db_driver_update_factions(generate_factions, &list);
db_driver_compact(turn);
db_driver_close(DB_GAME);
}
return err;

View File

@ -47,19 +47,28 @@ static void test_save_load_order(CuTest *tc) {
static void test_update_faction(CuTest *tc) {
faction *f;
int uid;
int err;
dbrow_id id;
test_setup();
db_driver_open(DB_GAME, NULL);
f = test_create_faction(NULL);
uid = db_driver_faction_save(f->uid, f->no, 0,
CuAssertIntEquals(tc, 0, f->uid);
id = 0;
err = db_driver_faction_save(&id, f->no,
faction_getemail(f),
faction_getpassword(f));
f->uid = uid;
uid = db_driver_faction_save(f->uid, f->no, 0,
CuAssertIntEquals(tc, 0, err);
CuAssertTrue(tc, 0 != id);
f->uid = (int)id;
db_driver_close(DB_GAME);
db_driver_open(DB_GAME, NULL);
err = db_driver_faction_save(&id, f->no,
faction_getemail(f),
faction_getpassword(f));
CuAssertIntEquals(tc, f->uid, uid);
CuAssertIntEquals(tc, 0, err);
CuAssertIntEquals(tc, f->uid, id);
db_driver_close(DB_GAME);
test_teardown();
}

View File

@ -1,6 +1,7 @@
#pragma once
#include <stddef.h>
#include <stdbool.h>
struct order_data;
@ -17,6 +18,17 @@ int db_driver_open(database_t db, const char *dbname);
void db_driver_close(database_t db);
dbrow_id db_driver_order_save(const char *str);
struct order_data *db_driver_order_load(dbrow_id id);
dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email, const char *password);
dbrow_id db_driver_string_save(const char *s);
const char *db_driver_string_load(dbrow_id id, size_t *size);
void db_driver_compact(int turn);
typedef struct db_faction {
int *p_uid;
int no;
const char *email;
char pwhash[128];
} db_faction;
typedef int (*db_faction_generator)(void *, db_faction *, int);
int db_driver_update_factions(db_faction_generator gen, void *data);
int db_driver_faction_save(dbrow_id * p_id, int no, const char *email, const char *password);

View File

@ -3,6 +3,7 @@
#include <kernel/config.h>
#include <util/log.h>
#include <util/base36.h>
#include "driver.h"
@ -95,68 +96,113 @@ dbrow_id db_driver_order_save(const char *str) {
return (dbrow_id)id;
}
dbrow_id db_driver_faction_save(dbrow_id id, int no, int turn, const char *email, const char *password)
int db_driver_faction_save(dbrow_id * p_id, int no, const char *email, const char *password)
{
sqlite3_int64 row_id;
dbrow_id id = *p_id;
int err;
char dbno[4];
size_t len;
const char *str;
sqlite3_stmt *stmt = (id > 0) ? g_stmt_update_faction : g_stmt_insert_faction;
assert(g_game_db);
if (id != 0) {
int rows;
err = sqlite3_reset(g_stmt_update_faction);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_update_faction, 1, no);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_update_faction, 2, turn);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_update_faction, 3, email, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_update_faction, 4, password, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_update_faction, 5, id);
assert(err == SQLITE_OK);
err = sqlite3_step(g_stmt_update_faction);
assert(err == SQLITE_DONE);
rows = sqlite3_changes(g_game_db);
if (rows != 0) {
return id;
}
err = sqlite3_reset(stmt);
if (err != SQLITE_OK) return err;
str = itoa36(no);
len = strlen(str);
assert(len <= 4);
memcpy(dbno, str, len);
err = sqlite3_bind_text(stmt, 1, dbno, len, SQLITE_STATIC);
if (err != SQLITE_OK) return err;
err = sqlite3_bind_text(stmt, 2, email, -1, SQLITE_STATIC);
if (err != SQLITE_OK) return err;
err = sqlite3_bind_text(stmt, 3, password, -1, SQLITE_STATIC);
if (err != SQLITE_OK) return err;
if (id > 0) {
err = sqlite3_bind_int(stmt, 4, id);
if (err != SQLITE_OK) return err;
}
err = sqlite3_reset(g_stmt_insert_faction);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_insert_faction, 1, no);
assert(err == SQLITE_OK);
err = sqlite3_bind_int(g_stmt_insert_faction, 2, turn);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_insert_faction, 3, email, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_bind_text(g_stmt_insert_faction, 4, password, -1, SQLITE_STATIC);
assert(err == SQLITE_OK);
err = sqlite3_step(g_stmt_insert_faction);
assert(err == SQLITE_DONE);
err = sqlite3_step(stmt);
if (err != SQLITE_DONE) return err;
ERRNO_CHECK();
row_id = sqlite3_last_insert_rowid(g_game_db);
assert(row_id>0 && row_id <= UINT_MAX);
return (dbrow_id)row_id;
if (id <= 0) {
sqlite3_int64 row_id;
row_id = sqlite3_last_insert_rowid(g_game_db);
assert(row_id > 0 && row_id <= UINT_MAX);
*p_id = (dbrow_id)row_id;
}
return SQLITE_OK;
}
int db_driver_update_factions(db_faction_generator gen, void *data)
{
db_faction results[32];
int num, err;
err = sqlite3_exec(g_game_db, "BEGIN TRANSACTION", NULL, NULL, NULL);
assert(err == SQLITE_OK);
err = sqlite3_exec(g_game_db, "DELETE FROM `faction`", NULL, NULL, NULL);
if (err != SQLITE_OK) {
sqlite3_exec(g_game_db, "ROLLBACK", NULL, NULL, NULL);
return err;
}
num = gen(data, results, 32);
while (num > 0) {
int i;
for (i = 0; i != num; ++i) {
db_faction *dbf = results + i;
dbrow_id id = (dbrow_id)*dbf->p_uid;
err = db_driver_faction_save(&id, dbf->no, dbf->email, dbf->pwhash);
if (err != SQLITE_OK) {
sqlite3_exec(g_game_db, "ROLLBACK", NULL, NULL, NULL);
return err;
}
assert(id > 0 && id <= INT_MAX);
*dbf->p_uid = (int)id;
}
num = gen(data, results, 32);
}
err = sqlite3_exec(g_game_db, "COMMIT", NULL, NULL, NULL);
return err;
}
static int cb_int_col(void *data, int ncols, char **text, char **name) {
int *p_int = (int *)data;
*p_int = atoi(text[0]);
return SQLITE_OK;
}
static int db_open_game(const char *dbname) {
int err;
int err, version = 0;
err = sqlite3_open(dbname, &g_game_db);
assert(err == SQLITE_OK);
err = sqlite3_exec(g_game_db, "CREATE TABLE IF NOT EXISTS factions (id INTEGER PRIMARY KEY, no INTEGER NOT NULL, email VARCHAR(128), password VARCHAR(128), turn INTEGER NOT NULL)", NULL, NULL, NULL);
err = sqlite3_exec(g_game_db, "PRAGMA user_version", cb_int_col, &version, NULL);
assert(err == SQLITE_OK);
err = sqlite3_prepare_v2(g_game_db, "UPDATE factions SET no=?, turn=?, email=?, password=? WHERE id=?", -1, &g_stmt_update_faction, NULL);
if (version < 1) {
/* drop deprecated table */
err = sqlite3_exec(g_game_db, "DROP TABLE IF EXISTS `factions`", NULL, NULL, NULL);
assert(err == SQLITE_OK);
}
if (version < 2) {
/* install schema version 2: */
err = sqlite3_exec(g_game_db, "CREATE TABLE IF NOT EXISTS `faction` (`id` INTEGER PRIMARY KEY, `no` CHAR(4) NOT NULL UNIQUE, `email` VARCHAR(128), `password` VARCHAR(128))", NULL, NULL, NULL);
assert(err == SQLITE_OK);
err = sqlite3_exec(g_game_db, "PRAGMA user_version = 2", NULL, NULL, NULL);
assert(err == SQLITE_OK);
}
/* create prepared statments: */
err = sqlite3_prepare_v2(g_game_db, "INSERT INTO `faction` (`no`, `email`, `password`, `id`) VALUES (?,?,?,?)", -1, &g_stmt_update_faction, NULL);
assert(err == SQLITE_OK);
err = sqlite3_prepare_v2(g_game_db, "INSERT INTO factions (no, turn, email, password) VALUES (?,?,?,?)", -1, &g_stmt_insert_faction, NULL);
err = sqlite3_prepare_v2(g_game_db, "INSERT INTO `faction` (`no`, `email`, `password`) VALUES (?,?,?)", -1, &g_stmt_insert_faction, NULL);
assert(err == SQLITE_OK);
ERRNO_CHECK();
return 0;
return err;
}
static int db_open_swap(const char *dbname) {
@ -303,3 +349,13 @@ const char *db_driver_string_load(dbrow_id id, size_t *size) {
ERRNO_CHECK();
return NULL;
}
void db_driver_compact(int turn)
{
int err;
/* repack database: */
err = sqlite3_exec(g_game_db, "VACUUM", 0, 0, 0);
assert(err == SQLITE_OK);
}

View File

@ -42,8 +42,9 @@
#define FAMILIAR_FIXMAGE_VERSION 364 /* familiar links are fixed */
#define FAMILIAR_FIXSPELLBOOK_VERSION 365 /* familiar spells are fixed */
#define FIX_STARTLEVEL_VERSION 366 /* fixing resource startlevels */
#define FIX_CLONES_VERSION 367 /* dissolve clones */
#define RELEASE_VERSION FIX_STARTLEVEL_VERSION /* current datafile */
#define RELEASE_VERSION FIX_CLONES_VERSION /* current datafile */
#define MIN_VERSION UIDHASH_VERSION /* minimal datafile we support */
#define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */

View File

@ -1368,6 +1368,72 @@ static void fix_fam_triggers(unit *u) {
}
}
static void fix_clone(unit *uc) {
attrib * a;
assert(uc);
assert(uc->number > 0);
ADDMSG(&uc->faction->msgs, msg_message("dissolve_units_5",
"unit region number race", uc, uc->region, uc->number, u_race(uc)));
a_removeall(&uc->attribs, &at_clonemage);
a = a_new(&at_unitdissolve);
a->data.ca[0] = 0;
a->data.ca[1] = 100;
a_add(&uc->attribs, a);
}
static void fix_clone_mage(unit *um, const item_type *itype) {
i_change(&um->items, itype, 1);
change_maxspellpoints(um, 20);
a_removeall(&um->attribs, &at_clone);
}
static void fix_clones(void) {
const race *rc_clone = rc_find("clone");
const item_type *it_potion = it_find("lifepotion");
if (rc_clone && it_potion) {
region *r;
for (r = regions; r; r = r->next) {
unit * u;
for (u = r->units; u; u = u->next) {
if (!fval(u, UFL_MARK)) {
if (u_race(u) == rc_clone) {
attrib *a = a_find(u->attribs, &at_clonemage);
unit * um = NULL;
fset(u, UFL_MARK);
if (a) {
um = (unit *)a->data.v;
fset(um, UFL_MARK);
}
}
else {
attrib *a = a_find(u->attribs, &at_clone);
if (a) {
unit *uc = (unit *)a->data.v;
fset(u, UFL_MARK);
fset(uc, UFL_MARK);
}
}
}
}
}
for (r = regions; r; r = r->next) {
unit * u;
for (u = r->units; u; u = u->next) {
if (fval(u, UFL_MARK)) {
if (u_race(u) == rc_clone) {
fix_clone(u);
}
else {
fix_clone_mage(u, it_potion);
}
freset(u, UFL_MARK);
}
}
}
}
}
static void fix_familiars(void (*callback)(unit *)) {
region *r;
for (r = regions; r; r = r->next) {
@ -1559,7 +1625,9 @@ int read_game(gamedata *data)
}
}
}
if (data->version < FIX_CLONES_VERSION) {
fix_clones();
}
if (data->version < FAMILIAR_FIX_VERSION) {
fix_familiars(fix_fam_triggers);
}

View File

@ -1488,7 +1488,7 @@ int display_cmd(unit * u, struct order *ord)
{
char token[128];
char **s = NULL;
const char *str;
char *str;
region *r = u->region;
init_order_depr(ord);
@ -1525,11 +1525,19 @@ int display_cmd(unit * u, struct order *ord)
break;
case P_UNIT:
unit_setinfo(u, getstrtoken());
str = getstrtoken();
if (str) {
unicode_utf8_trim(str);
}
unit_setinfo(u, str);
break;
case P_PRIVAT:
usetprivate(u, getstrtoken());
str = getstrtoken();
if (str) {
unicode_utf8_trim(str);
}
usetprivate(u, str);
break;
case P_REGION:
@ -1664,7 +1672,7 @@ int name_cmd(struct unit *u, struct order *ord)
bool foreign = false;
const char *str;
init_order_depr(ord);
init_order(ord, u->faction->locale);
str = gettoken(token, sizeof(token));
p = findparam_ex(str, u->faction->locale);

View File

@ -221,6 +221,21 @@ static void test_display_cmd(CuTest *tc) {
CuAssertStrEquals(tc, "Hodor", unit_getinfo(u));
free_order(ord);
ord = create_order(K_DISPLAY, f->locale, "%s ' Klabautermann '", LOC(f->locale, parameters[P_UNIT]));
CuAssertIntEquals(tc, 0, display_cmd(u, ord));
CuAssertStrEquals(tc, "Klabautermann", unit_getinfo(u));
free_order(ord);
ord = create_order(K_DISPLAY, f->locale, "%s Hodor", LOC(f->locale, parameters[P_PRIVAT]));
CuAssertIntEquals(tc, 0, display_cmd(u, ord));
CuAssertStrEquals(tc, "Hodor", uprivate(u));
free_order(ord);
ord = create_order(K_DISPLAY, f->locale, "%s ' Klabautermann '", LOC(f->locale, parameters[P_PRIVAT]));
CuAssertIntEquals(tc, 0, display_cmd(u, ord));
CuAssertStrEquals(tc, "Klabautermann", uprivate(u));
free_order(ord);
ord = create_order(K_DISPLAY, f->locale, LOC(f->locale, parameters[P_UNIT]));
CuAssertIntEquals(tc, 0, display_cmd(u, ord));
CuAssertPtrEquals(tc, NULL, (void *)unit_getinfo(u));
@ -940,6 +955,12 @@ static void test_name_unit(CuTest *tc) {
u = setup_name_cmd();
f = u->faction;
ord = create_order(K_NAME, f->locale, "%s ' Klabauterfrau '", LOC(f->locale, parameters[P_UNIT]));
name_cmd(u, ord);
CuAssertStrEquals(tc, "Klabauterfrau", u->_name);
free_order(ord);
ord = create_order(K_NAME, f->locale, "%s Hodor", LOC(f->locale, parameters[P_UNIT]));
name_cmd(u, ord);
CuAssertStrEquals(tc, "Hodor", u->_name);
@ -960,10 +981,15 @@ static void test_name_region(CuTest *tc) {
order *ord;
u = setup_name_cmd();
u_set_building(u, test_create_building(u->region, NULL));
f = u->faction;
ord = create_order(K_NAME, f->locale, "%s ' Hodor Hodor '", LOC(f->locale, parameters[P_REGION]));
name_cmd(u, ord);
CuAssertStrEquals(tc, "Hodor Hodor", u->region->land->name);
free_order(ord);
ord = create_order(K_NAME, f->locale, "%s Hodor", LOC(f->locale, parameters[P_REGION]));
u_set_building(u, test_create_building(u->region, NULL));
name_cmd(u, ord);
CuAssertStrEquals(tc, "Hodor", u->region->land->name);
free_order(ord);
@ -980,6 +1006,7 @@ static void test_name_region(CuTest *tc) {
static void test_name_building(CuTest *tc) {
unit *uo, *u, *ux;
faction *f;
order *ord;
u = setup_name_cmd();
u->building = test_create_building(u->region, NULL);
@ -989,29 +1016,33 @@ static void test_name_building(CuTest *tc) {
ux = test_create_unit(f, test_create_region(0, 0, NULL));
u_set_building(ux, u->building);
u->thisorder = create_order(K_NAME, f->locale, "%s Hodor", LOC(f->locale, parameters[P_BUILDING]));
ord = create_order(K_NAME, f->locale, "%s ' Hodor Hodor '", LOC(f->locale, parameters[P_BUILDING]));
building_set_owner(uo);
name_cmd(u, u->thisorder);
name_cmd(u, ord);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error148"));
test_clear_messages(f);
building_set_owner(u);
name_cmd(u, u->thisorder);
name_cmd(u, ord);
CuAssertStrEquals(tc, "Hodor Hodor", u->building->name);
free_order(ord);
ord = create_order(K_NAME, f->locale, "%s Hodor", LOC(f->locale, parameters[P_BUILDING]));
name_cmd(u, ord);
CuAssertStrEquals(tc, "Hodor", u->building->name);
building_setname(u->building, "Home");
building_set_owner(ux);
name_cmd(u, u->thisorder);
name_cmd(u, ord);
CuAssertPtrEquals(tc, NULL, test_find_messagetype(f->msgs, "error148"));
CuAssertStrEquals(tc, "Hodor", u->building->name);
test_clear_messages(f);
free_order(u->thisorder);
u->thisorder = create_order(K_NAME, f->locale, LOC(f->locale, parameters[P_BUILDING]));
name_cmd(u, u->thisorder);
free_order(ord);
ord = create_order(K_NAME, f->locale, LOC(f->locale, parameters[P_BUILDING]));
name_cmd(u, ord);
CuAssertPtrNotNull(tc, test_find_messagetype(f->msgs, "error84"));
CuAssertStrEquals(tc, "Hodor", u->building->name);
free_order(ord);
/* TODO: test BTF_NAMECHANGE:
btype->flags |= BTF_NAMECHANGE;

View File

@ -2237,7 +2237,7 @@ static void equip_familiar(unit *fam) {
snprintf(eqname, sizeof(eqname), "fam_%s", rc->_name);
if (!equip_unit(fam, eqname)) {
log_info("could not perform initialization for familiar %s.\n", rc->_name);
log_debug("could not perform initialization for familiar %s.\n", rc->_name);
}
}

View File

@ -53,7 +53,7 @@ static const char *logfile = "eressea.log";
static const char *luafile = 0;
static const char *inifile = "eressea.ini";
static int memdebug = 0;
static int verbosity = 1;
static int verbosity = 2;
static void load_inifile(void)
{
@ -183,7 +183,7 @@ static int verbosity_to_flags(int verbosity) {
static int parse_args(int argc, char **argv)
{
int i;
int log_stderr, log_flags = 2;
int log_stderr, log_flags = 3;
for (i = 1; i != argc; ++i) {
char *argi = argv[i];

View File

@ -442,7 +442,7 @@ static order *monster_move(region * r, unit * u)
if (fval(u_race(u), RCF_DRAGON)) {
d = richest_neighbour(r, u->faction, 1);
}
else if (get_race(RC_TREEMAN)==u_race(u)) {
else if (get_race(RC_TREEMAN) == u_race(u)) {
d = treeman_neighbour(r);
}
else {

View File

@ -32,9 +32,9 @@ static int age_chance(int a, int b, int p) {
static void evolve_dragon(unit * u, const struct race *rc) {
scale_number(u, 1);
u->hp = unit_max_hp(u);
u_setrace(u, rc);
u->irace = NULL;
u->hp = unit_max_hp(u);
}
void age_firedragon(unit * u)

View File

@ -1607,7 +1607,6 @@ static void allies(struct stream *out, const faction * f)
}
g = g->next;
}
rpline(out);
}
static void guards(struct stream *out, const region * r, const faction * see)
@ -1703,8 +1702,6 @@ static void list_address(struct stream *out, const faction * uf, selist * seenfa
}
selist_advance(&flist, &qi, 1);
}
newline(out);
rpline(out);
}
static void
@ -2130,9 +2127,10 @@ report_plaintext(const char *filename, report_context * ctx,
continue;
/* Beschreibung */
rpline(out);
newline(out);
if (r->seen.mode >= seen_unit) {
anyunits = 1;
newline(out);
report_region(out, r, f);
if (markets_module() && r->land) {
const item_type *lux = r_luxury(r);
@ -2169,20 +2167,21 @@ report_plaintext(const char *filename, report_context * ctx,
newline(out);
report_travelthru(out, r, f);
}
newline(out);
if (wants_stats && r->seen.mode >= seen_travel) {
if (r->land || r->seen.mode >= seen_unit) {
statistics(out, r, f);
newline(out);
statistics(out, r, f);
}
}
/* Nachrichten an REGION in der Region */
if (r->seen.mode >= seen_travel) {
message_list *mlist = r_getmessages(r, f);
newline(out);
if (mlist) {
struct mlist **split = merge_messages(mlist, r->msgs);
newline(out);
rp_messages(out, mlist, f, 0, false);
split_messages(mlist, split);
}
@ -2236,7 +2235,6 @@ report_plaintext(const char *filename, report_context * ctx,
assert(!u);
newline(out);
rpline(out);
ERRNO_CHECK();
}
if (!is_monsters(f)) {

View File

@ -713,7 +713,7 @@ void bufunit(const faction * f, const unit * u, const faction *fv,
pzTmp = get_racename(u->attribs);
if (pzTmp) {
const char *name = LOC(lang, mkname("race", pzTmp));
const char *name = locale_string(lang, mkname("race", pzTmp), false);
sbs_strcat(sbp, name ? name : pzTmp);
if (u->faction == f && fval(u_race(u), RCF_SHAPESHIFTANY)) {
sbs_strcat(sbp, " (");

View File

@ -62,7 +62,7 @@ static const char *spell_damage(int sp)
{
switch (sp) {
case 0:
/* meist toetlich 20-65 HP */
/* meist toedlich 20-65 HP */
return "5d10+15";
case 1:
/* sehr variabel 4-48 HP */
@ -71,7 +71,7 @@ static const char *spell_damage(int sp)
/* leicht verwundet 4-18 HP */
return "2d8+2";
case 3:
/* fast immer toetlich 30-50 HP */
/* fast immer toedlich 30-50 HP */
return "5d5+25";
case 4:
/* verwundet 11-26 HP */

View File

@ -233,12 +233,12 @@ const char *parse_token_depr(const char **str)
return parse_token(str, pbuf, MAXTOKENSIZE);
}
const char *getstrtoken(void)
char *getstrtoken(void)
{
return parse_token((const char **)&states->current_token, pbuf, MAXTOKENSIZE);
}
const char *gettoken(char *lbuf, size_t bufsize)
char *gettoken(char *lbuf, size_t bufsize)
{
return parse_token((const char **)&states->current_token, lbuf, bufsize);
}

View File

@ -26,8 +26,8 @@ extern "C" {
void parser_pushstate(void);
void parser_popstate(void);
bool parser_end(void);
const char *getstrtoken(void);
const char *gettoken(char *lbuf, size_t bufsize);
char *getstrtoken(void);
char *gettoken(char *lbuf, size_t bufsize);
int getuint(void);
int getint(void);
int getid(void);

View File

@ -11,6 +11,7 @@
#include <platform.h>
#include "unicode.h"
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <wctype.h>
@ -36,6 +37,7 @@ int unicode_utf8_trim(utf8_t *buf)
{
int result = 0, ts = 0;
utf8_t *op = buf, *ip = buf, *lc = buf;
assert(buf);
while (*ip) {
size_t size = 1;
wint_t wc = *ip;

View File

@ -7,9 +7,9 @@ IF EXIST ..\build-vs15 SET BUILD=..\build-vs15\eressea\Debug
SET SERVER=%BUILD%\eressea.exe
%BUILD%\test_eressea.exe
%SERVER% ..\scripts\run-tests.lua
%SERVER% -re2 ..\scripts\run-tests-e2.lua
%SERVER% -re3 ..\scripts\run-tests-e3.lua
%SERVER% -v1 ..\scripts\run-tests.lua
%SERVER% -v1 -re2 ..\scripts\run-tests-e2.lua
%SERVER% -v1 -re3 ..\scripts\run-tests-e3.lua
%SERVER% --version
PAUSE
RMDIR /s /q reports

View File

@ -12,5 +12,8 @@ IF exist build-vs%VSVERSION% goto HAVEDIR
mkdir build-vs%VSVERSION%
:HAVEDIR
cd build-vs%VSVERSION%
IF NOT EXIST CMakeCache.txt GOTO NOCACHE
DEL CMakeCache.txt
:NOCACHE
"%CMAKE_ROOT%\bin\cmake.exe" -G "Visual Studio %VSVERSION%" -DCMAKE_PREFIX_PATH="%LUA_DEV%;%WIN32_DEV%" -DCMAKE_MODULE_PATH="%SRCDIR%/cmake/Modules" -DCMAKE_SUPPRESS_REGENERATION=TRUE ..
PAUSE