forked from github/server
commit
715097ae0d
14 changed files with 220 additions and 502 deletions
|
@ -25,20 +25,6 @@ function callbacks(rules, name, ...)
|
|||
end
|
||||
end
|
||||
|
||||
local function dbupdate()
|
||||
update_scores()
|
||||
if config.dbname then
|
||||
dbname = config.basepath..'/'..config.dbname
|
||||
edb = db.open(dbname)
|
||||
if edb~=nil then
|
||||
edb:update_factions()
|
||||
edb:update_scores()
|
||||
else
|
||||
eressea.log.error("could not open "..dbname)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function write_emails(locales)
|
||||
local files = {}
|
||||
local key
|
||||
|
@ -161,7 +147,7 @@ function process(rules, orders)
|
|||
turn_end() -- ageing, etc.
|
||||
|
||||
write_files(config.locales)
|
||||
dbupdate()
|
||||
update_scores()
|
||||
|
||||
file = '' .. get_turn() .. '.dat'
|
||||
if eressea.write_game(file)~=0 then
|
||||
|
|
|
@ -103,3 +103,24 @@ function test_earn_silver()
|
|||
assert_equal(350, u:get_item("money"))
|
||||
assert_equal(0, r:get_resource("money"))
|
||||
end
|
||||
|
||||
function test_familiar()
|
||||
local r = region.create(0, 0, "mountain")
|
||||
local f = faction.create("human")
|
||||
local u = unit.create(f, r)
|
||||
local uid = u.id
|
||||
u.name = 'Hodor'
|
||||
u.magic = "gwyrrd"
|
||||
u.race = "elf"
|
||||
u:set_skill("magic", 10)
|
||||
u.aura = 200
|
||||
local err = u:add_spell("summon_familiar")
|
||||
assert_equal(0, err)
|
||||
u:add_order("ZAUBERE Vertrauten~rufen")
|
||||
process_orders()
|
||||
for u in r.units do
|
||||
if u.id ~= uid then
|
||||
assert_equal('Vertrauter von Hodor (' .. itoa36(uid) ..')', u.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -162,13 +162,6 @@ set(SERVER_SRC
|
|||
bind_unit.c
|
||||
)
|
||||
|
||||
if (SQLITE3_FOUND)
|
||||
set (SERVER_SRC ${SERVER_SRC}
|
||||
sqlite.c
|
||||
bind_sqlite.c
|
||||
)
|
||||
endif (SQLITE3_FOUND)
|
||||
|
||||
if (CURSES_FOUND)
|
||||
set (SERVER_SRC ${SERVER_SRC}
|
||||
gmtool.c
|
||||
|
@ -295,15 +288,13 @@ target_link_libraries(convert ${DB_LIBRARIES})
|
|||
target_link_libraries(eressea ${DB_LIBRARIES})
|
||||
target_link_libraries(test_eressea ${DB_LIBRARIES})
|
||||
add_definitions(-DUSE_DB)
|
||||
endif(DB_FOUND)
|
||||
|
||||
if (SQLITE3_FOUND)
|
||||
elseif (SQLITE3_FOUND)
|
||||
include_directories (${SQLITE3_INCLUDE_DIR})
|
||||
target_link_libraries(eressea ${SQLITE3_LIBRARIES})
|
||||
target_link_libraries(convert ${SQLITE3_LIBRARIES})
|
||||
target_link_libraries(test_eressea ${SQLITE3_LIBRARIES})
|
||||
add_definitions(-DUSE_SQLITE)
|
||||
endif(SQLITE3_FOUND)
|
||||
endif(DB_FOUND)
|
||||
|
||||
if (CURSES_FOUND)
|
||||
include_directories (${CURSES_INCLUDE_DIR})
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
#ifdef _MSC_VER
|
||||
#include <platform.h>
|
||||
#endif
|
||||
|
||||
#include "bind_unit.h"
|
||||
#include "bindings.h"
|
||||
|
||||
#include <kernel/config.h> /* for game_id */
|
||||
#include <util/macros.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
#include <tolua.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LTYPE_DB TOLUA_CAST "db"
|
||||
|
||||
extern int db_update_factions(sqlite3 * db, bool force, int game);
|
||||
static int tolua_db_update_factions(lua_State * L)
|
||||
{
|
||||
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
|
||||
db_update_factions(db, tolua_toboolean(L, 2, 0), game_id());
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int db_update_scores(sqlite3 * db, bool force);
|
||||
static int tolua_db_update_scores(lua_State * L)
|
||||
{
|
||||
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
|
||||
db_update_scores(db, tolua_toboolean(L, 2, 0));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_db_execute(lua_State * L)
|
||||
{
|
||||
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
|
||||
const char *sql = tolua_tostring(L, 2, 0);
|
||||
|
||||
int res = sqlite3_exec(db, sql, 0, 0, 0);
|
||||
|
||||
lua_pushinteger(L, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int tolua_db_close(lua_State * L)
|
||||
{
|
||||
sqlite3 *db = (sqlite3 *)tolua_tousertype(L, 1, 0);
|
||||
sqlite3_close(db);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tolua_db_create(lua_State * L)
|
||||
{
|
||||
sqlite3 *db;
|
||||
const char *dbname = tolua_tostring(L, 1, 0);
|
||||
int result = sqlite3_open_v2(dbname, &db, SQLITE_OPEN_READWRITE, 0);
|
||||
if (result == SQLITE_OK) {
|
||||
tolua_pushusertype(L, (void *)db, LTYPE_DB);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tolua_sqlite_open(lua_State * L)
|
||||
{
|
||||
/* register user types */
|
||||
|
||||
tolua_usertype(L, LTYPE_DB);
|
||||
|
||||
tolua_module(L, NULL, 0);
|
||||
tolua_beginmodule(L, NULL);
|
||||
{
|
||||
tolua_cclass(L, LTYPE_DB, LTYPE_DB, TOLUA_CAST "", NULL);
|
||||
tolua_beginmodule(L, LTYPE_DB);
|
||||
{
|
||||
tolua_function(L, TOLUA_CAST "open", &tolua_db_create);
|
||||
tolua_function(L, TOLUA_CAST "close", &tolua_db_close);
|
||||
|
||||
tolua_function(L, TOLUA_CAST "update_factions",
|
||||
&tolua_db_update_factions);
|
||||
tolua_function(L, TOLUA_CAST "update_scores", &tolua_db_update_scores);
|
||||
tolua_function(L, TOLUA_CAST "execute", &tolua_db_execute);
|
||||
}
|
||||
tolua_endmodule(L);
|
||||
|
||||
}
|
||||
tolua_endmodule(L);
|
||||
return 0;
|
||||
}
|
|
@ -1119,9 +1119,6 @@ lua_State *lua_init(const dictionary *inifile) {
|
|||
register_tolua_helpers();
|
||||
tolua_bindings_open(L, inifile);
|
||||
tolua_eressea_open(L);
|
||||
#ifdef USE_SQLITE
|
||||
tolua_sqlite_open(L);
|
||||
#endif
|
||||
tolua_unit_open(L);
|
||||
tolua_building_open(L);
|
||||
tolua_ship_open(L);
|
||||
|
|
|
@ -19,7 +19,6 @@ extern "C" {
|
|||
struct selist;
|
||||
|
||||
int tolua_toid(struct lua_State *L, int idx, int def);
|
||||
int tolua_sqlite_open(struct lua_State *L);
|
||||
int tolua_bindings_open(struct lua_State *L, const struct _dictionary_ *d);
|
||||
int tolua_itemlist_next(struct lua_State *L);
|
||||
int tolua_selist_push(struct lua_State *L, const char *list_type,
|
||||
|
|
|
@ -38,11 +38,9 @@ SET(_DBFILES db/critbit.c)
|
|||
|
||||
IF(DB_FOUND)
|
||||
SET(_DBFILES db/berkeley.c)
|
||||
ENDIF(DB_FOUND)
|
||||
|
||||
IF(SQLITE3_FOUND)
|
||||
ELSEIF(SQLITE3_FOUND)
|
||||
SET(_DBFILES db/sqlite.c)
|
||||
ENDIF(SQLITE3_FOUND)
|
||||
ENDIF(DB_FOUND)
|
||||
|
||||
SET(_FILES
|
||||
${_DBFILES}
|
||||
|
|
|
@ -38,7 +38,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/bsdstring.h>
|
||||
#include <util/functions.h>
|
||||
#include <util/umlaut.h>
|
||||
#include <util/language.h>
|
||||
|
@ -536,21 +535,18 @@ const char *racename(const struct locale *loc, const unit * u, const race * rc)
|
|||
|
||||
if (prefix != NULL) {
|
||||
static char lbuf[80]; /* FIXME: static return value */
|
||||
char *bufp = lbuf;
|
||||
size_t size = sizeof(lbuf) - 1;
|
||||
int ch, bytes;
|
||||
sbstring sbs;
|
||||
char ch[2];
|
||||
|
||||
bytes = (int)str_strlcpy(bufp, LOC(loc, mkname("prefix", prefix)), size);
|
||||
if (wrptr(&bufp, &size, bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
sbs_init(&sbs, lbuf, sizeof(lbuf));
|
||||
sbs_strcpy(&sbs, LOC(loc, mkname("prefix", prefix)));
|
||||
|
||||
bytes = (int)str_strlcpy(bufp, LOC(loc, rc_name_s(rc, u->number != 1)), size);
|
||||
assert(~bufp[0] & 0x80 || !"unicode/not implemented");
|
||||
ch = tolower(*(unsigned char *)bufp);
|
||||
bufp[0] = (char)ch;
|
||||
if (wrptr(&bufp, &size, bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
*bufp = 0;
|
||||
str = LOC(loc, rc_name_s(rc, u->number != 1));
|
||||
assert(~str[0] & 0x80 || !"unicode/not implemented");
|
||||
ch[0] = (char)tolower(*(unsigned char *)str);
|
||||
ch[1] = 0;
|
||||
sbs_strcat(&sbs, ch);
|
||||
sbs_strcat(&sbs, str + 1);
|
||||
|
||||
return lbuf;
|
||||
}
|
||||
|
|
|
@ -178,6 +178,7 @@ void sk_set(skill * sv, int level)
|
|||
assert(sv && level != 0);
|
||||
sv->weeks = skill_weeks(level);
|
||||
sv->level = level;
|
||||
assert(sv->weeks <= sv->level * 2 + 1);
|
||||
}
|
||||
|
||||
static bool rule_random_progress(void)
|
||||
|
@ -215,6 +216,7 @@ void increase_skill(unit * u, skill_t sk, int weeks)
|
|||
sk_set(sv, sv->level + 1);
|
||||
}
|
||||
sv->weeks -= weeks;
|
||||
assert(sv->weeks <= sv->level * 2 + 1);
|
||||
}
|
||||
|
||||
void reduce_skill(unit * u, skill * sv, int weeks)
|
||||
|
@ -229,11 +231,13 @@ void reduce_skill(unit * u, skill * sv, int weeks)
|
|||
while (sv->level > 0 && sv->weeks > max_weeks) {
|
||||
sv->weeks -= sv->level;
|
||||
--sv->level;
|
||||
max_weeks -= 2;
|
||||
}
|
||||
if (sv->level == 0) {
|
||||
/* reroll */
|
||||
sv->weeks = skill_weeks(sv->level);
|
||||
}
|
||||
assert(sv->weeks <= sv->level * 2 + 1);
|
||||
}
|
||||
|
||||
int skill_compare(const skill * sk, const skill * sc)
|
||||
|
|
144
src/laws.c
144
src/laws.c
|
@ -81,7 +81,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
/* util includes */
|
||||
#include <util/attrib.h>
|
||||
#include <util/base36.h>
|
||||
#include <util/bsdstring.h>
|
||||
#include <util/event.h>
|
||||
#include <util/goodies.h>
|
||||
#include <util/language.h>
|
||||
|
@ -2265,146 +2264,11 @@ static void display_item(unit * u, const item_type * itype)
|
|||
itype->weight, itype->rtype, info));
|
||||
}
|
||||
|
||||
static void display_race(unit * u, const race * rc)
|
||||
static void display_race(faction * f, const race * rc)
|
||||
{
|
||||
faction * f = u->faction;
|
||||
const char *name, *key;
|
||||
const char *info;
|
||||
int a, at_count;
|
||||
char buf[2048], *bufp = buf;
|
||||
size_t size = sizeof(buf) - 1;
|
||||
size_t bytes;
|
||||
char buf[2048];
|
||||
|
||||
name = rc_name_s(rc, NAME_SINGULAR);
|
||||
|
||||
bytes = slprintf(bufp, size, "%s: ", LOC(f->locale, name));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
key = mkname("raceinfo", rc->_name);
|
||||
info = locale_getstring(f->locale, key);
|
||||
if (info == NULL) {
|
||||
info = LOC(f->locale, mkname("raceinfo", "no_info"));
|
||||
}
|
||||
|
||||
if (info) bufp = STRLCPY(bufp, info, size);
|
||||
|
||||
/* hp_p : Trefferpunkte */
|
||||
bytes =
|
||||
slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(f->locale,
|
||||
"stat_hitpoints"));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_attacke : Angriff */
|
||||
bytes =
|
||||
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_attack"),
|
||||
(rc->at_default + rc->at_bonus));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_defense : Verteidigung */
|
||||
bytes =
|
||||
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_defense"),
|
||||
(rc->df_default + rc->df_bonus));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_armor : Rüstung */
|
||||
if (rc->armor > 0) {
|
||||
bytes =
|
||||
slprintf(bufp, size, ", %s: %d", LOC(f->locale, "stat_armor"), rc->armor);
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
|
||||
if (size > 1) {
|
||||
*bufp++ = '.';
|
||||
--size;
|
||||
}
|
||||
else
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_damage : Schaden */
|
||||
at_count = 0;
|
||||
for (a = 0; a < RACE_ATTACKS; a++) {
|
||||
if (rc->attack[a].type != AT_NONE) {
|
||||
at_count++;
|
||||
}
|
||||
}
|
||||
if (rc->battle_flags & BF_EQUIPMENT) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_equipment"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
if (rc->battle_flags & BF_RES_PIERCE) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_pierce"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
if (rc->battle_flags & BF_RES_CUT) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_cut"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
if (rc->battle_flags & BF_RES_BASH) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(f->locale, "stat_bash"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(f->locale, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
for (a = 0; a < RACE_ATTACKS; a++) {
|
||||
if (rc->attack[a].type != AT_NONE) {
|
||||
if (a != 0)
|
||||
bufp = STRLCPY(bufp, ", ", size);
|
||||
else
|
||||
bufp = STRLCPY(bufp, ": ", size);
|
||||
|
||||
switch (rc->attack[a].type) {
|
||||
case AT_STANDARD:
|
||||
bytes =
|
||||
(size_t)snprintf(bufp, size, "%s (%s)",
|
||||
LOC(f->locale, "attack_standard"), rc->def_damage);
|
||||
break;
|
||||
case AT_NATURAL:
|
||||
bytes =
|
||||
(size_t)snprintf(bufp, size, "%s (%s)",
|
||||
LOC(f->locale, "attack_natural"), rc->attack[a].data.dice);
|
||||
break;
|
||||
case AT_SPELL:
|
||||
case AT_COMBATSPELL:
|
||||
case AT_DRAIN_ST:
|
||||
case AT_DRAIN_EXP:
|
||||
case AT_DAZZLE:
|
||||
bytes = (size_t)snprintf(bufp, size, "%s", LOC(f->locale, "attack_magical"));
|
||||
break;
|
||||
case AT_STRUCTURAL:
|
||||
bytes =
|
||||
(size_t)snprintf(bufp, size, "%s (%s)",
|
||||
LOC(f->locale, "attack_structural"), rc->attack[a].data.dice);
|
||||
break;
|
||||
default:
|
||||
bytes = 0;
|
||||
}
|
||||
|
||||
assert(bytes <= INT_MAX);
|
||||
if (bytes && wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 1) {
|
||||
*bufp++ = '.';
|
||||
--size;
|
||||
}
|
||||
else
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
*bufp = 0;
|
||||
report_raceinfo(rc, f->locale, buf, sizeof(buf));
|
||||
addmessage(0, f, buf, MSG_EVENT, ML_IMPORTANT);
|
||||
}
|
||||
|
||||
|
@ -2453,7 +2317,7 @@ static void reshow_other(unit * u, struct order *ord, const char *s) {
|
|||
}
|
||||
|
||||
if (rc && u_race(u) == rc) {
|
||||
display_race(u, rc);
|
||||
display_race(u->faction, rc);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
|
184
src/reports.c
184
src/reports.c
|
@ -363,25 +363,145 @@ static void report_resource(resource_report * result, const resource_type *rtype
|
|||
result->level = level;
|
||||
}
|
||||
|
||||
void report_race(const struct unit *u, const char **name, const char **illusion)
|
||||
void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length)
|
||||
{
|
||||
if (illusion) {
|
||||
const race *irace = u_irace(u);
|
||||
if (irace && irace != u_race(u)) {
|
||||
*illusion = irace->_name;
|
||||
}
|
||||
else {
|
||||
*illusion = NULL;
|
||||
const char *info;
|
||||
int a, at_count;
|
||||
const char *name, *key;
|
||||
char *bufp = buf;
|
||||
size_t size = length - 1;
|
||||
size_t bytes;
|
||||
|
||||
name = rc_name_s(rc, NAME_SINGULAR);
|
||||
|
||||
bytes = slprintf(bufp, size, "%s: ", LOC(lang, name));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
key = mkname("raceinfo", rc->_name);
|
||||
info = locale_getstring(lang, key);
|
||||
if (info == NULL) {
|
||||
info = LOC(lang, mkname("raceinfo", "no_info"));
|
||||
}
|
||||
|
||||
if (info) bufp = STRLCPY(bufp, info, size);
|
||||
|
||||
/* hp_p : Trefferpunkte */
|
||||
bytes =
|
||||
slprintf(bufp, size, " %d %s", rc->hitpoints, LOC(lang,
|
||||
"stat_hitpoints"));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_attacke : Angriff */
|
||||
bytes =
|
||||
slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_attack"),
|
||||
(rc->at_default + rc->at_bonus));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_defense : Verteidigung */
|
||||
bytes =
|
||||
slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_defense"),
|
||||
(rc->df_default + rc->df_bonus));
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_armor : Rüstung */
|
||||
if (rc->armor > 0) {
|
||||
bytes =
|
||||
slprintf(bufp, size, ", %s: %d", LOC(lang, "stat_armor"), rc->armor);
|
||||
assert(bytes <= INT_MAX);
|
||||
if (wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
|
||||
if (size > 1) {
|
||||
*bufp++ = '.';
|
||||
--size;
|
||||
}
|
||||
else
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
/* b_damage : Schaden */
|
||||
at_count = 0;
|
||||
for (a = 0; a < RACE_ATTACKS; a++) {
|
||||
if (rc->attack[a].type != AT_NONE) {
|
||||
at_count++;
|
||||
}
|
||||
}
|
||||
if (name) {
|
||||
*name = u_race(u)->_name;
|
||||
if (fval(u_race(u), RCF_SHAPESHIFTANY)) {
|
||||
const char *str = get_racename(u->attribs);
|
||||
if (str)
|
||||
*name = str;
|
||||
if (rc->battle_flags & BF_EQUIPMENT) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_equipment"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
if (rc->battle_flags & BF_RES_PIERCE) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_pierce"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
if (rc->battle_flags & BF_RES_CUT) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_cut"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
if (rc->battle_flags & BF_RES_BASH) {
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %s", LOC(lang, "stat_bash"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
|
||||
if (wrptr(&bufp, &size, snprintf(bufp, size, " %d %s", at_count, LOC(lang, (at_count == 1) ? "stat_attack" : "stat_attacks"))) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
for (a = 0; a < RACE_ATTACKS; a++) {
|
||||
if (rc->attack[a].type != AT_NONE) {
|
||||
if (a != 0)
|
||||
bufp = STRLCPY(bufp, ", ", size);
|
||||
else
|
||||
bufp = STRLCPY(bufp, ": ", size);
|
||||
|
||||
switch (rc->attack[a].type) {
|
||||
case AT_STANDARD:
|
||||
bytes =
|
||||
(size_t)snprintf(bufp, size, "%s (%s)",
|
||||
LOC(lang, "attack_standard"), rc->def_damage);
|
||||
break;
|
||||
case AT_NATURAL:
|
||||
bytes =
|
||||
(size_t)snprintf(bufp, size, "%s (%s)",
|
||||
LOC(lang, "attack_natural"), rc->attack[a].data.dice);
|
||||
break;
|
||||
case AT_SPELL:
|
||||
case AT_COMBATSPELL:
|
||||
case AT_DRAIN_ST:
|
||||
case AT_DRAIN_EXP:
|
||||
case AT_DAZZLE:
|
||||
bytes = (size_t)snprintf(bufp, size, "%s", LOC(lang, "attack_magical"));
|
||||
break;
|
||||
case AT_STRUCTURAL:
|
||||
bytes =
|
||||
(size_t)snprintf(bufp, size, "%s (%s)",
|
||||
LOC(lang, "attack_structural"), rc->attack[a].data.dice);
|
||||
break;
|
||||
default:
|
||||
bytes = 0;
|
||||
}
|
||||
|
||||
assert(bytes <= INT_MAX);
|
||||
if (bytes && wrptr(&bufp, &size, (int)bytes) != 0)
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
}
|
||||
|
||||
if (size > 1) {
|
||||
*bufp++ = '.';
|
||||
--size;
|
||||
}
|
||||
else
|
||||
WARN_STATIC_BUFFER();
|
||||
|
||||
*bufp = 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -2195,6 +2315,42 @@ static void eval_trail(struct opstack **stack, const void *userdata)
|
|||
#endif
|
||||
}
|
||||
|
||||
void report_race_skills(const race *rc, char *zText, size_t length, const struct locale *lang)
|
||||
{
|
||||
size_t size = length - 1;
|
||||
int dh = 0, dh1 = 0, sk;
|
||||
char *bufp = zText;
|
||||
|
||||
for (sk = 0; sk < MAXSKILLS; ++sk) {
|
||||
if (skill_enabled(sk) && rc->bonus[sk] > -5)
|
||||
dh++;
|
||||
}
|
||||
|
||||
for (sk = 0; sk < MAXSKILLS; sk++) {
|
||||
if (skill_enabled(sk) && rc->bonus[sk] > -5) {
|
||||
size_t bytes;
|
||||
dh--;
|
||||
if (dh1 == 0) {
|
||||
dh1 = 1;
|
||||
}
|
||||
else {
|
||||
if (dh == 0) {
|
||||
bytes = str_strlcpy(bufp, LOC(lang, "list_and"), size);
|
||||
}
|
||||
else {
|
||||
bytes = str_strlcpy(bufp, ", ", size);
|
||||
}
|
||||
assert(bytes <= INT_MAX);
|
||||
BUFFER_STRCAT(bufp, size, bytes);
|
||||
}
|
||||
bytes = str_strlcpy(bufp, skillname((skill_t)sk, lang),
|
||||
size);
|
||||
assert(bytes <= INT_MAX);
|
||||
BUFFER_STRCAT(bufp, size, (int)bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void eval_direction(struct opstack **stack, const void *userdata)
|
||||
{
|
||||
const faction *report = (const faction *)userdata;
|
||||
|
|
|
@ -120,14 +120,13 @@ extern "C" {
|
|||
int report_items(const struct unit *u, struct item *result, int size,
|
||||
const struct unit *owner, const struct faction *viewer);
|
||||
void report_warnings(struct faction *f, const struct gamedate *date);
|
||||
void report_raceinfo(const struct race *rc, const struct locale *lang, char *buf, size_t length);
|
||||
void report_race_skills(const struct race *rc, char *zText, size_t length, const struct locale *lang);
|
||||
void report_item(const struct unit *owner, const struct item *i,
|
||||
const struct faction *viewer, const char **name, const char **basename,
|
||||
int *number, bool singular);
|
||||
void report_building(const struct building *b, const char **btype,
|
||||
const char **billusion);
|
||||
void report_race(const struct unit *u, const char **rcname,
|
||||
const char **rcillusion);
|
||||
|
||||
void add_seen_faction(struct faction *self, struct faction *seen);
|
||||
size_t f_regionid(const struct region *r, const struct faction *f,
|
||||
char *buffer, size_t size);
|
||||
|
|
41
src/spells.c
41
src/spells.c
|
@ -18,6 +18,7 @@
|
|||
#include "spells.h"
|
||||
|
||||
#include "guard.h"
|
||||
#include "reports.h"
|
||||
#include "spy.h"
|
||||
#include "vortex.h"
|
||||
#include "laws.h"
|
||||
|
@ -72,7 +73,6 @@
|
|||
#include <util/assert.h>
|
||||
#include <util/attrib.h>
|
||||
#include <util/base36.h>
|
||||
#include <util/bsdstring.h>
|
||||
#include <util/event.h>
|
||||
#include <util/gamedata.h>
|
||||
#include <util/language.h>
|
||||
|
@ -537,12 +537,9 @@ static int sp_summon_familiar(castorder * co)
|
|||
unit *mage = co->magician.u;
|
||||
int cast_level = co->level;
|
||||
const race *rc;
|
||||
int sk;
|
||||
int dh, dh1;
|
||||
int bytes;
|
||||
int dh;
|
||||
message *msg;
|
||||
char zText[2048], *bufp = zText;
|
||||
size_t size = sizeof(zText) - 1;
|
||||
char zText[2048];
|
||||
|
||||
if (get_familiar(mage) != NULL) {
|
||||
cmistake(mage, co->order, 199, MSG_MAGIC);
|
||||
|
@ -582,37 +579,7 @@ static int sp_summon_familiar(castorder * co)
|
|||
msg_release(msg);
|
||||
make_familiar(mage, r, rc, zText);
|
||||
|
||||
dh = 0;
|
||||
dh1 = 0;
|
||||
for (sk = 0; sk < MAXSKILLS; ++sk) {
|
||||
if (skill_enabled(sk) && rc->bonus[sk] > -5)
|
||||
dh++;
|
||||
}
|
||||
|
||||
for (sk = 0; sk < MAXSKILLS; sk++) {
|
||||
if (skill_enabled(sk) && rc->bonus[sk] > -5) {
|
||||
dh--;
|
||||
if (dh1 == 0) {
|
||||
dh1 = 1;
|
||||
}
|
||||
else {
|
||||
if (dh == 0) {
|
||||
bytes = (int) str_strlcpy(bufp, (const char *)LOC(mage->faction->locale,
|
||||
"list_and"), size);
|
||||
}
|
||||
else {
|
||||
bytes = (int)str_strlcpy(bufp, (const char *)", ", size);
|
||||
}
|
||||
assert(bytes >= 0);
|
||||
BUFFER_STRCAT(bufp, size, bytes);
|
||||
}
|
||||
bytes =
|
||||
str_strlcpy(bufp, (const char *)skillname((skill_t)sk, mage->faction->locale),
|
||||
size);
|
||||
assert(bytes <= INT_MAX);
|
||||
BUFFER_STRCAT(bufp, size, (int)bytes);
|
||||
}
|
||||
}
|
||||
report_race_skills(rc, zText, sizeof(zText), mage->faction->locale);
|
||||
ADDMSG(&mage->faction->msgs, msg_message("familiar_describe",
|
||||
"mage race skills", mage, rc, zText));
|
||||
return cast_level;
|
||||
|
|
172
src/sqlite.c
172
src/sqlite.c
|
@ -1,172 +0,0 @@
|
|||
#ifdef _MSC_VER
|
||||
#include <platform.h>
|
||||
#endif
|
||||
#include <kernel/config.h>
|
||||
#include <kernel/faction.h>
|
||||
#include <kernel/race.h>
|
||||
#include <util/language.h>
|
||||
#include <util/log.h>
|
||||
#include <util/base36.h>
|
||||
#include <util/log.h>
|
||||
#include <util/strings.h>
|
||||
#include <selist.h>
|
||||
#include <sqlite3.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct db_faction {
|
||||
int uid;
|
||||
int no;
|
||||
char *email;
|
||||
char *name;
|
||||
} db_faction;
|
||||
|
||||
static struct selist *
|
||||
read_factions(sqlite3 * db, int game_id) {
|
||||
int res;
|
||||
selist *result = 0;
|
||||
const char * sql =
|
||||
"SELECT f.id, fd.code, fd.name, fd.email FROM faction f"
|
||||
" LEFT OUTER JOIN faction_data fd"
|
||||
" WHERE f.id=fd.faction_id AND f.game_id=? AND"
|
||||
" fd.turn=(SELECT MAX(turn) FROM faction_data fx WHERE fx.faction_id=f.id)"
|
||||
" ORDER BY f.id";
|
||||
sqlite3_stmt *stmt = 0;
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
||||
sqlite3_bind_int(stmt, 1, game_id);
|
||||
|
||||
res = sqlite3_step(stmt);
|
||||
while (res == SQLITE_ROW) {
|
||||
const char * text;
|
||||
db_faction * dbf = (db_faction*)calloc(1, sizeof(db_faction));
|
||||
dbf->uid = (int)sqlite3_column_int64(stmt, 0);
|
||||
text = (const char *)sqlite3_column_text(stmt, 1);
|
||||
if (text) dbf->no = atoi36(text);
|
||||
text = (const char *)sqlite3_column_text(stmt, 2);
|
||||
if (text) dbf->name = str_strdup(text);
|
||||
text = (const char *)sqlite3_column_text(stmt, 3);
|
||||
if (text) dbf->email = str_strdup(text);
|
||||
selist_push(&result, dbf);
|
||||
res = sqlite3_step(stmt);
|
||||
}
|
||||
sqlite3_finalize(stmt);
|
||||
return result;
|
||||
}
|
||||
|
||||
static int insert_faction(sqlite3 *db, int game_id, faction *f) {
|
||||
const char *sql = "INSERT INTO faction (game_id, race) VALUES (?, ?)";
|
||||
sqlite3_stmt *stmt = 0;
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
||||
sqlite3_bind_int(stmt, 1, game_id);
|
||||
sqlite3_bind_text(stmt, 2, f->race->_name, -1, SQLITE_STATIC);
|
||||
sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
return (int)sqlite3_last_insert_rowid(db);
|
||||
}
|
||||
|
||||
static void update_faction(sqlite3 *db, const faction *f) {
|
||||
char code[5];
|
||||
const char *sql =
|
||||
"INSERT INTO faction_data (faction_id, code, name, email, lang, turn)"
|
||||
" VALUES (?, ?, ?, ?, ?, ?)";
|
||||
sqlite3_stmt *stmt = 0;
|
||||
strcpy(code, itoa36(f->no));
|
||||
sqlite3_prepare_v2(db, sql, -1, &stmt, 0);
|
||||
sqlite3_bind_int(stmt, 1, f->subscription);
|
||||
sqlite3_bind_text(stmt, 2, code, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 3, f->name, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 4, f->email, -1, SQLITE_STATIC);
|
||||
sqlite3_bind_text(stmt, 5, locale_name(f->locale), -1, SQLITE_STATIC);
|
||||
sqlite3_bind_int(stmt, 6, turn);
|
||||
sqlite3_step(stmt);
|
||||
sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
struct cb_data {
|
||||
const faction *f;
|
||||
sqlite3 *db;
|
||||
db_faction *dbf;
|
||||
};
|
||||
|
||||
static bool db_faction_cb(void *el, void *arg) {
|
||||
db_faction *df = (db_faction *)el;
|
||||
struct cb_data *cb = (struct cb_data *)arg;
|
||||
const faction *f = cb->f;
|
||||
|
||||
/* FIXME comparing name and email is inaccurate ... */
|
||||
if (f->no == df->no || strcmp(faction_getemail(f), df->email?df->email:"") == 0 || strcmp(f->name, df->name) == 0) {
|
||||
cb->dbf = df;
|
||||
}
|
||||
if (f->subscription == df->uid) {
|
||||
cb->dbf = df;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int db_update_factions(sqlite3 * db, bool force, int game_id) {
|
||||
selist *ql = read_factions(db, game_id);
|
||||
if (ql) {
|
||||
faction *f;
|
||||
struct cb_data cbdata;
|
||||
cbdata.db = db;
|
||||
cbdata.dbf = NULL;
|
||||
sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||
for (f = factions; f; f = f->next) {
|
||||
bool update = force;
|
||||
cbdata.f = f;
|
||||
selist_foreach_ex(ql, db_faction_cb, &cbdata);
|
||||
if (cbdata.dbf) {
|
||||
const db_faction *dbf = cbdata.dbf;
|
||||
if (dbf->uid != f->subscription) {
|
||||
log_warning("faction %s(%d) not found in database, but matches %d\n", itoa36(f->no), f->subscription, dbf->uid);
|
||||
f->subscription = dbf->uid;
|
||||
}
|
||||
update = (dbf->no != f->no) || (strcmp(faction_getemail(f), dbf->email?dbf->email:"") != 0) || (strcmp(f->name, dbf->name) != 0);
|
||||
}
|
||||
else {
|
||||
f->subscription = insert_faction(db, game_id, f);
|
||||
log_warning("faction %s not found in database, created as %d\n", itoa36(f->no), f->subscription);
|
||||
update = true;
|
||||
}
|
||||
if (update) {
|
||||
update_faction(db, f);
|
||||
log_debug("faction %s updated\n", itoa36(f->no));
|
||||
}
|
||||
}
|
||||
sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
}
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
int db_update_scores(sqlite3 * db, bool force)
|
||||
{
|
||||
/*
|
||||
const char *sselist_ins =
|
||||
"INSERT OR FAIL INTO score (value,faction_id,turn) VALUES (?,?,?)";
|
||||
sqlite3_stmt *stmt_ins = stmt_cache_get(db, sselist_ins);
|
||||
const char *sselist_upd =
|
||||
"UPDATE score set value=? WHERE faction_id=? AND turn=?";
|
||||
sqlite3_stmt *stmt_upd = stmt_cache_get(db, sselist_upd);
|
||||
faction *f;
|
||||
sqlite3_exec(db, "BEGIN", 0, 0, 0);
|
||||
for (f = factions; f; f = f->next) {
|
||||
int res;
|
||||
sqlite3_bind_int(stmt_ins, 1, f->score);
|
||||
sqlite3_bind_int64(stmt_ins, 2, f->subscription);
|
||||
sqlite3_bind_int(stmt_ins, 3, turn);
|
||||
res = sqlite3_step(stmt_ins);
|
||||
if (res == SQLITE_CONSTRAINT) {
|
||||
sqlite3_bind_int(stmt_upd, 1, f->score);
|
||||
sqlite3_bind_int64(stmt_upd, 2, f->subscription);
|
||||
sqlite3_bind_int(stmt_upd, 3, turn);
|
||||
res = sqlite3_step(stmt_upd);
|
||||
sqlite3_reset(stmt_upd);
|
||||
}
|
||||
sqlite3_reset(stmt_ins);
|
||||
}
|
||||
sqlite3_exec(db, "COMMIT", 0, 0, 0);
|
||||
*/
|
||||
return SQLITE_OK;
|
||||
}
|
Loading…
Reference in a new issue