forked from github/server
Merge pull request #649 from ennorehling/spellref
allow forward references to spells in configuration data.
This commit is contained in:
commit
d81cb0f9a0
2
clibs
2
clibs
|
@ -1 +1 @@
|
|||
Subproject commit f91ef37f08c5244bf616f1836c0aa9caaf36805c
|
||||
Subproject commit 27c8b3202b52766465743c3324fc0b52c5ba4b11
|
2
cmake
2
cmake
|
@ -1 +1 @@
|
|||
Subproject commit f1fb3943ace59994d90d71a891b80033dc2700a2
|
||||
Subproject commit d88983c7ff4bc3a4884a7c3f74e8190bac5eab23
|
|
@ -8,6 +8,8 @@
|
|||
"jsreport"
|
||||
],
|
||||
"settings": {
|
||||
"game.name" : "Eressea",
|
||||
"game.id" : 2,
|
||||
"orders.default": "work",
|
||||
"NewbieImmunity": 8,
|
||||
"modules.wormholes": true,
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
"jsreport"
|
||||
],
|
||||
"settings": {
|
||||
"game.name" : "Eressea",
|
||||
"game.id" : 3,
|
||||
"orders.default": "work",
|
||||
"database.gameid": 7,
|
||||
"NewbieImmunity": 4,
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE catalog
|
||||
PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
|
||||
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
|
||||
|
||||
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
|
||||
<rewriteURI
|
||||
uriStartString="config://core/"
|
||||
rewritePrefix="../../res/core/" />
|
||||
<rewriteURI
|
||||
uriStartString="config://game/"
|
||||
rewritePrefix="../../res/e3a/" />
|
||||
<rewriteURI
|
||||
uriStartString="config://default/"
|
||||
rewritePrefix="../../res/" />
|
||||
</catalog>
|
|
@ -1,93 +0,0 @@
|
|||
{
|
||||
"include": [
|
||||
"keywords.json",
|
||||
"prefixes.json",
|
||||
"e3/terrains.json"
|
||||
],
|
||||
"disabled": [
|
||||
"herbalism",
|
||||
"alchemy",
|
||||
"entertainment",
|
||||
"espionage",
|
||||
"perception",
|
||||
"stealth",
|
||||
"taxation",
|
||||
"trade",
|
||||
"besiege",
|
||||
"steal",
|
||||
"buy",
|
||||
"teach",
|
||||
"sabotage",
|
||||
"spy",
|
||||
"tax",
|
||||
"entertain",
|
||||
"sell",
|
||||
"jsreport"
|
||||
],
|
||||
"settings": {
|
||||
"orders.default": "work",
|
||||
"database.gameid": 7,
|
||||
"NewbieImmunity": 4,
|
||||
"modules.astralspace": false,
|
||||
"modules.wormholes": false,
|
||||
"modules.markets": true,
|
||||
"magic.regeneration": 0.75,
|
||||
"magic.power": 0.5,
|
||||
"resource.factor": 0.25,
|
||||
"skills.cost.tactics": 500,
|
||||
"entertain.base": 0,
|
||||
"entertain.perlevel": 20,
|
||||
"nmr.timeout": 5,
|
||||
"nmr.removenewbie": 0,
|
||||
"GiveRestriction": 3,
|
||||
"hunger.long": false,
|
||||
"hunger.damage": "1d9+9",
|
||||
"hunger.demons.skill": true,
|
||||
"hunger.demons.peasant_tolerance": true,
|
||||
"init_spells": 0,
|
||||
"recruit.allow_merge": true,
|
||||
"study.expensivemigrants": true,
|
||||
"study.speedup": 2,
|
||||
"study.produceexp": 12,
|
||||
"world.era": 3,
|
||||
"rules.reserve.twophase": true,
|
||||
"rules.owners.force_leave": false,
|
||||
"rules.transfermen": false,
|
||||
"stealth.faction.other": false,
|
||||
"rules.stealth.anon_battle": false,
|
||||
"rules.check_overload": false,
|
||||
"rules.combat.goblinbonus": 3,
|
||||
"rules.alliances": true,
|
||||
"rules.combat.herospeed": 3,
|
||||
"rules.combat.demon_vampire": 5,
|
||||
"rules.combat.skill_bonus": 0,
|
||||
"rules.combat.nat_armor": 1,
|
||||
"rules.items.loot_divisor": 2,
|
||||
"rules.items.give_divisor": 2,
|
||||
"rules.move.owner_leave": true,
|
||||
"rules.region_owners": true,
|
||||
"rules.cavalry.skill": 2,
|
||||
"rules.cavalry.mode": 1,
|
||||
"rules.magic.multipotion": true,
|
||||
"rules.magic.wol_effect": 5,
|
||||
"rules.magic.factionlist": true,
|
||||
"rules.magic.wol_type": 2,
|
||||
"rules.blessed_harvest.flags": 1,
|
||||
"rules.magic.elfpower": true,
|
||||
"rules.magic.playerschools": "gwyrrd illaun draig cerddor",
|
||||
"rules.build.other_buildings": true,
|
||||
"rules.economy.taxation": 1,
|
||||
"rules.food.flags": 2,
|
||||
"rules.economy.roqf": 5,
|
||||
"rules.economy.herbrot": 0,
|
||||
"rules.region_owner_pay_building": "market harbour lighthouse",
|
||||
"rules.dwarf_castles": true,
|
||||
"rules.limit.faction": 250,
|
||||
"rules.grow.formula": 1,
|
||||
"rules.tactics.formula": 1,
|
||||
"rules.help.mask": "fight guard money give",
|
||||
"movement.shipspeed.skillbonus": 6,
|
||||
"alliance.auto": "fight",
|
||||
"alliance.restricted": "fight"
|
||||
}
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
<?xml version="1.0"?>
|
||||
<eressea xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<xi:include href="config://core/messages.xml"/>
|
||||
<xi:include href="config://core/de/strings.xml"/>
|
||||
<xi:include href="config://core/en/strings.xml"/>
|
||||
<xi:include href="config://core/common/items.xml"/>
|
||||
<xi:include href="config://core/common/herbs.xml" />
|
||||
<xi:include href="config://core/spoils.xml"/>
|
||||
<xi:include href="config://core/common/buildings.xml"/>
|
||||
<xi:include href="config://game/familiars.xml"/>
|
||||
|
||||
<xi:include href="config://default/adamantium.xml" />
|
||||
|
||||
<xi:include href="config://game/ships.xml"/>
|
||||
<xi:include href="config://game/shipnames.xml"/>
|
||||
<xi:include href="config://core/calendar.xml"/>
|
||||
<xi:include href="config://game/items.xml" />
|
||||
<xi:include href="config://game/strings.xml"/>
|
||||
<xi:include href="config://game/messages.xml"/>
|
||||
<xi:include href="config://game/races.xml"/>
|
||||
<xi:include href="config://game/buildings.xml"/>
|
||||
<xi:include href="config://game/equipment.xml"/>
|
||||
<xi:include href="config://game/spells.xml"/>
|
||||
<xi:include href="config://game/luxuries.xml" />
|
||||
<xi:include href="config://game/weapons.xml" />
|
||||
<xi:include href="config://game/armor.xml" />
|
||||
<xi:include href="config://game/resources.xml" />
|
||||
|
||||
<calendar name="thirdage" newyear="month_1" start="1"/>
|
||||
<xi:include href="config://default/names-undead.xml"/>
|
||||
<xi:include href="config://default/names-skeletons.xml"/>
|
||||
<xi:include href="config://default/names-zombies.xml"/>
|
||||
<xi:include href="config://default/names-ghouls.xml"/>
|
||||
<xi:include href="config://default/names-dragons.xml"/>
|
||||
|
||||
<rules>
|
||||
<function name="wage" value="minimum_wage"/>
|
||||
</rules>
|
||||
</eressea>
|
11
s/build
11
s/build
|
@ -1,8 +1,5 @@
|
|||
#!/bin/sh
|
||||
ROOT=`pwd`
|
||||
while [ ! -d $ROOT/.git ]; do
|
||||
ROOT=`dirname $ROOT`
|
||||
done
|
||||
ROOT=$(git rev-parse --show-toplevel)
|
||||
|
||||
[ -z "$BUILD" ] && BUILD=Debug
|
||||
if [ -z "$JOBS" ] ; then
|
||||
|
@ -35,7 +32,13 @@ fi
|
|||
|
||||
echo "build eressea"
|
||||
cd $ROOT/$BUILD
|
||||
BRANCH=$(git status -s -b | head -1 | cut -d\ -f 2 | sed 's/\..*//')
|
||||
if [ "$BRANCH"=="master" ] ; then
|
||||
VERSION=$(git describe --match 'v*.*.*' --tags | sed 's/^v//')
|
||||
cmake -DERESSEA_VERSION="$VERSION" ..
|
||||
else
|
||||
REV=$(git rev-parse --short HEAD)
|
||||
cmake -DERESSEA_BUILDNO="$REV" ..
|
||||
fi
|
||||
make $MAKEOPTS && make test
|
||||
cd $OLDPWD
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
#!/bin/sh
|
||||
ROOT=$(pwd)
|
||||
while [ ! -d $ROOT/.git ]; do
|
||||
ROOT=$(dirname $ROOT)
|
||||
if [ "$ROOT" == "/" ; then
|
||||
echo "could not find root, are you in the git repository?"
|
||||
exit
|
||||
fi
|
||||
done
|
||||
|
||||
ROOT=$(git rev-parse --show-toplevel)
|
||||
[ -z $BUILD ] && BUILD=Debug
|
||||
[ -z "$CC" ] && [ ! -z `which clang` ] && CC="clang"
|
||||
[ -z "$CC" ] && [ ! -z `which gcc` ] && CC="gcc"
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
ROOT=$(pwd)
|
||||
while [ ! -d $ROOT/.git ]; do
|
||||
ROOT=$(dirname $ROOT)
|
||||
done
|
||||
|
||||
ROOT=$(git rev-parse --show-toplevel)
|
||||
[ -z $BUILD ] && BUILD=Debug ; export BUILD
|
||||
|
||||
if [ ! -e $ROOT/$BUILD ]; then
|
||||
|
@ -19,7 +15,6 @@ cd $ROOT
|
|||
$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests.lua
|
||||
$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e2.lua
|
||||
$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e3.lua
|
||||
$ROOT/$BUILD/eressea/eressea -v1 scripts/run-tests-e4.lua
|
||||
rm -rf data reports orders.txt score score.alliances datum turn
|
||||
|
||||
cd $OLDWPD
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
ROOT=`pwd`
|
||||
while [ ! -d $ROOT/.git ]; do
|
||||
ROOT=`dirname $ROOT`
|
||||
done
|
||||
|
||||
cd $ROOT
|
||||
git pull
|
||||
git submodule update
|
||||
s/build
|
||||
s/runtests
|
||||
s/install
|
|
@ -1,11 +0,0 @@
|
|||
require 'eressea.e3.rules'
|
||||
require 'eressea.spells'
|
||||
|
||||
eressea.log.debug("rules for game E4")
|
||||
|
||||
return {
|
||||
require('eressea'),
|
||||
-- require('eressea.markets'),
|
||||
require('eressea.frost'),
|
||||
require('eressea.ents')
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
-- Tests that work in E3. With game config of E3.
|
||||
-- Tests are under scripts/test/e3 and all files must be in scripts/test/e3/init.lua
|
||||
|
||||
path = 'scripts'
|
||||
if config.install then
|
||||
path = config.install .. '/' .. path
|
||||
package.path = package.path .. ';' .. config.install .. '/lunit/?.lua'
|
||||
--needed to find lunit if not run form eressea root. Needs right [lua] install setting in eressea.ini (point to eressea root from the start folder)
|
||||
end
|
||||
package.path = package.path .. ';' .. path .. '/?.lua;' .. path .. '/?/init.lua'
|
||||
|
||||
config.rules = 'e4'
|
||||
|
||||
require 'eressea'
|
||||
require 'eressea.path'
|
||||
require 'eressea.xmlconf'
|
||||
require 'tests.e3'
|
||||
require 'lunit'
|
||||
|
||||
eressea.settings.set("rules.alliances", "0")
|
||||
rules = require('eressea.' .. config.rules)
|
||||
result = lunit.main()
|
||||
return result.errors + result.failed
|
|
@ -15,6 +15,11 @@ set_source_files_properties(kernel/version.c PROPERTIES
|
|||
COMPILE_DEFINITIONS ERESSEA_VERSION="${ERESSEA_VERSION}")
|
||||
ENDIF()
|
||||
|
||||
IF(DEFINED ERESSEA_BUILDNO)
|
||||
set_source_files_properties(kernel/version.c PROPERTIES
|
||||
COMPILE_DEFINITIONS ERESSEA_BUILDNO="${ERESSEA_BUILDNO}")
|
||||
ENDIF()
|
||||
|
||||
IF (CMAKE_COMPILER_IS_GNUCC)
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-error=unused-but-set-variable")
|
||||
ENDIF()
|
||||
|
|
|
@ -1858,10 +1858,13 @@ static void do_combatspell(troop at)
|
|||
|
||||
static void do_extra_spell(troop at, const att * a)
|
||||
{
|
||||
const spell *sp = a->data.sp;
|
||||
const spell *sp = spellref_get(a->data.sp);
|
||||
|
||||
if (sp->cast == NULL) {
|
||||
log_error("spell '%s' has no function.\n", sp->sname);
|
||||
if (!sp) {
|
||||
log_error("no such spell: '%s'", a->data.sp->name);
|
||||
}
|
||||
else if (sp->cast == NULL) {
|
||||
log_error("spell '%s' has no function.", sp->sname);
|
||||
}
|
||||
else {
|
||||
assert(a->level > 0);
|
||||
|
|
|
@ -718,6 +718,7 @@ static void cr_output_spells(stream *out, const unit * u, int maxlevel)
|
|||
for (ql = book->spells, qi = 0; ql; selist_advance(&ql, &qi, 1)) {
|
||||
spellbook_entry * sbe = (spellbook_entry *)selist_get(ql, qi);
|
||||
if (sbe->level <= maxlevel) {
|
||||
// TODO: no need to deref spref here, spref->name == sp->sname
|
||||
spell * sp = sbe->sp;
|
||||
const char *name = translate(mkname("spell", sp->sname), spell_name(sp, f->locale));
|
||||
if (!header) {
|
||||
|
|
|
@ -749,13 +749,18 @@ void config_set_from(const dictionary *d)
|
|||
key[slen] = '.';
|
||||
iniparser_getseckeys(d, sec, keys);
|
||||
for (k=0;k!=nkeys;++k) {
|
||||
const char *val;
|
||||
const char *val, *orig;
|
||||
size_t klen = strlen(keys[k]);
|
||||
assert(klen+slen+1<sizeof(key));
|
||||
memcpy(key+slen+1, keys[k]+slen+1, klen-slen);
|
||||
orig = config_get(key);
|
||||
val = iniparser_getstring(d, keys[k], NULL);
|
||||
if (val) {
|
||||
config_set(key, val);
|
||||
if (!orig) {
|
||||
if (val) {
|
||||
config_set(key, val);
|
||||
}
|
||||
} else {
|
||||
log_debug("not overwriting %s=%s with %s", key, orig, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,8 +87,7 @@ void equipment_setskill(equipment * eq, skill_t sk, const char *value)
|
|||
}
|
||||
|
||||
typedef struct lazy_spell {
|
||||
char *name;
|
||||
struct spell *sp;
|
||||
struct spellref *spref;
|
||||
int level;
|
||||
} lazy_spell;
|
||||
|
||||
|
@ -96,9 +95,8 @@ void equipment_addspell(equipment * eq, const char * name, int level)
|
|||
{
|
||||
if (eq) {
|
||||
lazy_spell *ls = malloc(sizeof(lazy_spell));
|
||||
ls->sp = NULL;
|
||||
ls->spref = spellref_create(NULL, name);
|
||||
ls->level = level;
|
||||
ls->name = strdup(name);
|
||||
selist_push(&eq->spells, ls);
|
||||
}
|
||||
}
|
||||
|
@ -162,12 +160,8 @@ void equip_unit_mask(struct unit *u, const struct equipment *eq, int mask)
|
|||
|
||||
for (qi = 0; ql; selist_advance(&ql, &qi, 1)) {
|
||||
lazy_spell *sbe = (lazy_spell *)selist_get(ql, qi);
|
||||
if (!sbe->sp) {
|
||||
sbe->sp = find_spell(sbe->name);
|
||||
free(sbe->name);
|
||||
sbe->name = NULL;
|
||||
}
|
||||
unit_add_spell(u, mage, sbe->sp, sbe->level);
|
||||
spell *sp = spellref_get(sbe->spref);
|
||||
unit_add_spell(u, mage, sp, sbe->level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -238,7 +232,7 @@ void equip_items(struct item **items, const struct equipment *eq)
|
|||
|
||||
void free_ls(void *arg) {
|
||||
lazy_spell *ls = (lazy_spell*)arg;
|
||||
free(ls->name);
|
||||
spellref_free(ls->spref);
|
||||
free(ls);
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
#include "region.h"
|
||||
#include "ship.h"
|
||||
#include "skill.h"
|
||||
#include "spell.h"
|
||||
#include "terrain.h"
|
||||
#include "unit.h"
|
||||
|
||||
|
@ -181,7 +182,13 @@ void racelist_insert(struct race_list **rl, const struct race *r)
|
|||
|
||||
void free_races(void) {
|
||||
while (races) {
|
||||
int i;
|
||||
race * rc = races->next;
|
||||
|
||||
for (i = 0; races->attack[i].type!=AT_NONE; ++i) {
|
||||
spellref_free(races->attack[i].data.sp);
|
||||
}
|
||||
spellref_free(races->precombatspell);
|
||||
free_params(&races->parameters);
|
||||
free(xrefs);
|
||||
xrefs = 0;
|
||||
|
|
|
@ -45,6 +45,7 @@ extern "C" {
|
|||
|
||||
struct param;
|
||||
struct spell;
|
||||
struct spellref;
|
||||
struct locale;
|
||||
|
||||
extern int num_races;
|
||||
|
@ -104,7 +105,7 @@ extern "C" {
|
|||
int type;
|
||||
union {
|
||||
const char *dice;
|
||||
const struct spell *sp;
|
||||
struct spellref *sp;
|
||||
} data;
|
||||
int flags;
|
||||
int level;
|
||||
|
@ -137,7 +138,7 @@ extern "C" {
|
|||
int at_bonus; /* Ver<65>ndert den Angriffsskill (default: 0) */
|
||||
int df_bonus; /* Ver<65>ndert den Verteidigungskill (default: 0) */
|
||||
struct param *parameters; // additional properties, for an example see natural_armor
|
||||
const struct spell *precombatspell;
|
||||
struct spellref *precombatspell;
|
||||
signed char *study_speed; /* study-speed-bonus in points/turn (0=30 Tage) */
|
||||
int flags;
|
||||
int battle_flags;
|
||||
|
|
|
@ -1633,14 +1633,7 @@ int read_game(gamedata *data) {
|
|||
|
||||
READ_INT(store, &gameid);
|
||||
if (gameid != game_id()) {
|
||||
int c;
|
||||
log_warning("game mismatch: datafile contains game %d, but config is for %d", gameid, game_id());
|
||||
printf("WARNING: invalid game id. any key to continue, Ctrl-C to stop\n");
|
||||
c = getchar();
|
||||
if (c == EOF) {
|
||||
log_error("aborting.");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -145,3 +145,39 @@ spell *find_spellbyid(unsigned int id)
|
|||
log_warning("cannot find spell by id: %u\n", id);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct spellref *spellref_create(spell *sp, const char *name)
|
||||
{
|
||||
spellref *spref = malloc(sizeof(spellref));
|
||||
|
||||
if (sp) {
|
||||
spref->sp = sp;
|
||||
spref->name = strdup(sp->sname);
|
||||
}
|
||||
else if (name) {
|
||||
spref->name = strdup(name);
|
||||
spref->sp = NULL;
|
||||
}
|
||||
return spref;
|
||||
}
|
||||
|
||||
void spellref_free(spellref *spref)
|
||||
{
|
||||
if (spref) {
|
||||
free(spref->name);
|
||||
free(spref);
|
||||
}
|
||||
}
|
||||
|
||||
struct spell *spellref_get(struct spellref *spref)
|
||||
{
|
||||
if (!spref->sp) {
|
||||
assert(spref->name);
|
||||
spref->sp = find_spell(spref->name);
|
||||
if (spref->sp) {
|
||||
free(spref->name);
|
||||
spref->name = NULL;
|
||||
}
|
||||
}
|
||||
return spref->sp;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,15 @@ extern "C" {
|
|||
fumble_f fumble;
|
||||
} spell;
|
||||
|
||||
typedef struct spellref {
|
||||
char * name;
|
||||
struct spell *sp;
|
||||
} spellref;
|
||||
|
||||
struct spellref *spellref_create(struct spell *sp, const char *name);
|
||||
void spellref_free(struct spellref *spref);
|
||||
struct spell *spellref_get(struct spellref *spref);
|
||||
|
||||
int sp_antimagiczone(struct castorder *co);
|
||||
|
||||
struct spell * create_spell(const char * name, unsigned int id);
|
||||
|
@ -61,7 +70,7 @@ extern "C" {
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
/* ------------------------------------------------------------- *//* Erläuterungen zu den Spruchdefinitionen
|
||||
/* ------------------------------------------------------------- *//* Erl<EFBFBD>uterungen zu den Spruchdefinitionen
|
||||
*
|
||||
* Spruchstukturdefinition:
|
||||
* spell{
|
||||
|
@ -79,35 +88,35 @@ extern "C" {
|
|||
* id:
|
||||
* SPL_NOSPELL muss der letzte Spruch in der Liste spelldaten sein,
|
||||
* denn nicht auf die Reihenfolge in der Liste sondern auf die id wird
|
||||
* geprüft
|
||||
* gepr<EFBFBD>ft
|
||||
*
|
||||
* sptyp:
|
||||
* besondere Spruchtypen und Flags
|
||||
* (Regionszauber, Kampfzauber, Farcastbar, Stufe variable, ..)
|
||||
*
|
||||
* rank:
|
||||
* gibt die Priorität und damit die Reihenfolge an, in der der Spruch
|
||||
* gibt die Priorit<EFBFBD>t und damit die Reihenfolge an, in der der Spruch
|
||||
* gezaubert wird.
|
||||
* 1: Aura übertragen
|
||||
* 1: Aura <EFBFBD>bertragen
|
||||
* 2: Antimagie
|
||||
* 3: Magierverändernde Sprüche (Magic Boost, ..)
|
||||
* 3: Magierver<EFBFBD>ndernde Spr<EFBFBD>che (Magic Boost, ..)
|
||||
* 4: Monster erschaffen
|
||||
* 5: Standartlevel
|
||||
* 7: Teleport
|
||||
*
|
||||
* Komponenten[Anzahl mögl. Items][Art:Anzahl:Kostentyp]
|
||||
* Komponenten[Anzahl m<EFBFBD>gl. Items][Art:Anzahl:Kostentyp]
|
||||
*
|
||||
* R_AURA:
|
||||
* Grundkosten für einen Zauber. Soviel Mp müssen mindestens investiert
|
||||
* werden, um den Spruch zu wirken. Zusätzliche Mp können unterschiedliche
|
||||
* Grundkosten f<EFBFBD>r einen Zauber. Soviel Mp m<EFBFBD>ssen mindestens investiert
|
||||
* werden, um den Spruch zu wirken. Zus<EFBFBD>tzliche Mp k<EFBFBD>nnen unterschiedliche
|
||||
* Auswirkungen haben, die in der Spruchfunktionsroutine definiert werden.
|
||||
*
|
||||
* R_PERMAURA:
|
||||
* Kosten an permantenter Aura
|
||||
*
|
||||
* Komponenten Kostentyp:
|
||||
* SPC_LEVEL == Spruch mit Levelabhängigen Magiekosten. Die angegeben
|
||||
* Kosten müssen für Stufe 1 berechnet sein.
|
||||
* SPC_LEVEL == Spruch mit Levelabh<EFBFBD>ngigen Magiekosten. Die angegeben
|
||||
* Kosten m<EFBFBD>ssen f<EFBFBD>r Stufe 1 berechnet sein.
|
||||
* SPC_FIX == Feste Kosten
|
||||
*
|
||||
* Wenn keine spezielle Syntax angegeben ist, wird die
|
||||
|
@ -128,34 +137,34 @@ extern "C" {
|
|||
*
|
||||
* u : eine Einheitennummer
|
||||
* r : hier kommen zwei Regionskoordinaten x y
|
||||
* b : Gebäude- oder Burgnummer
|
||||
* b : Geb<EFBFBD>ude- oder Burgnummer
|
||||
* s : Schiffsnummer
|
||||
* c : String, wird ohne Weiterverarbeitung übergeben
|
||||
* i : Zahl (int), wird ohne Weiterverarbeitung übergeben
|
||||
* c : String, wird ohne Weiterverarbeitung <EFBFBD>bergeben
|
||||
* i : Zahl (int), wird ohne Weiterverarbeitung <EFBFBD>bergeben
|
||||
* k : Keywort - dieser String gibt den Paramter an, der folgt. Der
|
||||
* Parameter wird mit findparam() identifiziert.
|
||||
* k muss immer von einem c als Platzhalter für das Objekt gefolgt
|
||||
* k muss immer von einem c als Platzhalter f<EFBFBD>r das Objekt gefolgt
|
||||
* werden.
|
||||
* Ein gutes Beispiel sind hierfür die Sprüche zur Magieanalyse.
|
||||
* Ein gutes Beispiel sind hierf<EFBFBD>r die Spr<EFBFBD>che zur Magieanalyse.
|
||||
* + : gibt an, das der vorherige Parameter mehrfach vorkommen kann. Da
|
||||
* ein Ende nicht definiert werden kann, muss dies immer am Schluss
|
||||
* kommen.
|
||||
*
|
||||
* Flags für das Parsing:
|
||||
* Flags f<EFBFBD>r das Parsing:
|
||||
* TESTRESISTANCE : alle Zielobjekte, also alle Parameter vom Typ Unit,
|
||||
* Burg, Schiff oder Region, werden auf ihre
|
||||
* Magieresistenz überprüft
|
||||
* Magieresistenz <EFBFBD>berpr<EFBFBD>ft
|
||||
* TESTCANSEE : jedes Objekt vom Typ Einheit wird auf seine
|
||||
* Sichtbarkeit überprüft
|
||||
* Sichtbarkeit <EFBFBD>berpr<EFBFBD>ft
|
||||
* SEARCHLOCAL : die Zielobjekte werden nur regional gesucht
|
||||
* REGIONSPELL : Ziel ist die Region, auch wenn kein Zielobjekt
|
||||
* angegeben wird. Ist TESTRESISTANCE gesetzt, so wird
|
||||
* die Magieresistenz der Region überprüft
|
||||
* die Magieresistenz der Region <EFBFBD>berpr<EFBFBD>ft
|
||||
*
|
||||
* Bei fehlendem Ziel oder wenn dieses dem Zauber widersteht, wird die
|
||||
* Spruchfunktion nicht aufgerufen.
|
||||
* Sind zu wenig Parameter vorhanden, wird der Zauber ebenfalls nicht
|
||||
* ausgeführt.
|
||||
* ausgef<EFBFBD>hrt.
|
||||
* Ist eins von mehreren Zielobjekten resistent, so wird das Flag
|
||||
* pa->param[n]->flag == TARGET_RESISTS
|
||||
* Ist eins von mehreren Zielobjekten nicht gefunden worden, so ist
|
||||
|
|
|
@ -69,9 +69,27 @@ static void test_create_spell_with_id(CuTest * tc)
|
|||
test_cleanup();
|
||||
}
|
||||
|
||||
static void test_spellref(CuTest *tc)
|
||||
{
|
||||
spellref *ref;
|
||||
spell *sp;
|
||||
test_setup();
|
||||
ref = spellref_create(NULL, "hodor");
|
||||
CuAssertPtrNotNull(tc, ref);
|
||||
CuAssertPtrEquals(tc, NULL, ref->sp);
|
||||
CuAssertStrEquals(tc, "hodor", ref->name);
|
||||
CuAssertPtrEquals(tc, NULL, spellref_get(ref));
|
||||
sp = create_spell("hodor", 0);
|
||||
CuAssertPtrNotNull(tc, sp);
|
||||
CuAssertPtrEquals(tc, sp, spellref_get(ref));
|
||||
spellref_free(ref);
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
CuSuite *get_spell_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
SUITE_ADD_TEST(suite, test_spellref);
|
||||
SUITE_ADD_TEST(suite, test_create_a_spell);
|
||||
SUITE_ADD_TEST(suite, test_create_duplicate_spell);
|
||||
SUITE_ADD_TEST(suite, test_create_spell_with_id);
|
||||
|
|
|
@ -71,7 +71,7 @@ void write_spellbook(const struct spellbook *book, struct storage *store)
|
|||
WRITE_TOK(store, "end");
|
||||
}
|
||||
|
||||
void spellbook_add(spellbook *sb, struct spell * sp, int level)
|
||||
void spellbook_add(spellbook *sb, spell *sp, int level)
|
||||
{
|
||||
spellbook_entry * sbe;
|
||||
|
||||
|
@ -116,7 +116,7 @@ int spellbook_foreach(spellbook *sb, int(*callback)(spellbook_entry *, void *),
|
|||
return 0;
|
||||
}
|
||||
|
||||
spellbook_entry * spellbook_get(spellbook *sb, const struct spell * sp)
|
||||
spellbook_entry * spellbook_get(spellbook *sb, const struct spell *sp)
|
||||
{
|
||||
if (sb) {
|
||||
selist *ql;
|
||||
|
@ -124,11 +124,10 @@ spellbook_entry * spellbook_get(spellbook *sb, const struct spell * sp)
|
|||
|
||||
for (qi = 0, ql = sb->spells; ql; selist_advance(&ql, &qi, 1)) {
|
||||
spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi);
|
||||
if (sp == sbe->sp) {
|
||||
if (sbe->sp==sp) {
|
||||
return sbe;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
struct selist;
|
||||
|
||||
typedef struct spellbook_entry {
|
||||
struct spell * sp;
|
||||
struct spell *sp;
|
||||
int level;
|
||||
} spellbook_entry;
|
||||
|
||||
|
@ -44,10 +44,10 @@ extern "C" {
|
|||
void read_spellbook(struct spellbook **bookp, struct gamedata *data, int(*get_level)(const struct spell * sp, void *), void * cbdata);
|
||||
void write_spellbook(const struct spellbook *book, struct storage *store);
|
||||
|
||||
void spellbook_add(spellbook *sbp, struct spell * sp, int level);
|
||||
void spellbook_add(spellbook *sbp, struct spell *sp, int level);
|
||||
int spellbook_foreach(spellbook *sb, int(*callback)(spellbook_entry *, void *), void * data);
|
||||
void spellbook_clear(spellbook *sb);
|
||||
spellbook_entry * spellbook_get(spellbook *sb, const struct spell * sp);
|
||||
spellbook_entry * spellbook_get(spellbook *sb, const struct spell *sp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -5,15 +5,18 @@
|
|||
|
||||
#ifndef ERESSEA_VERSION
|
||||
// the version number, if it was not passed to make with -D
|
||||
#define ERESSEA_VERSION "3.11.0-devel"
|
||||
#define ERESSEA_VERSION "3.11.0"
|
||||
#endif
|
||||
|
||||
const char *eressea_version(void) {
|
||||
#ifdef ERESSEA_BUILDNO
|
||||
return ERESSEA_VERSION "-" ERESSEA_BUILDNO;
|
||||
#endif
|
||||
return ERESSEA_VERSION;
|
||||
}
|
||||
|
||||
int version_no(const char *str) {
|
||||
int maj = 0, min = 0, bld = 0;
|
||||
sscanf(str, "%d.%d.%d", &maj, &min, &bld);
|
||||
return (maj << 16) | (min << 8) | bld;
|
||||
int maj = 0, min = 0, pat = 0;
|
||||
sscanf(str, "%d.%d.%d", &maj, &min, &pat);
|
||||
return (maj << 16) | (min << 8) | pat;
|
||||
}
|
||||
|
|
|
@ -75,16 +75,15 @@ static void xml_readtext(xmlNodePtr node, struct locale **lang, xmlChar ** text)
|
|||
*text = xmlNodeListGetString(node->doc, node->children, 1);
|
||||
}
|
||||
|
||||
static const spell *xml_spell(xmlNode * node, const char *name)
|
||||
static spellref *xml_spellref(xmlNode * node, const char *name)
|
||||
{
|
||||
const spell *sp = NULL;
|
||||
xmlChar *propValue = xmlGetProp(node, BAD_CAST name);
|
||||
if (propValue != NULL) {
|
||||
sp = find_spell((const char *)propValue);
|
||||
assert(sp);
|
||||
spellref *ref = spellref_create(NULL, (const char *)propValue);
|
||||
xmlFree(propValue);
|
||||
return ref;
|
||||
}
|
||||
return sp;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static xmlChar *xml_cleanup_string(xmlChar * str)
|
||||
|
@ -1853,7 +1852,7 @@ static int parse_races(xmlDocPtr doc)
|
|||
|| !"precombatspell is already initialized");
|
||||
for (k = 0; k != result->nodesetval->nodeNr; ++k) {
|
||||
xmlNodePtr node = result->nodesetval->nodeTab[k];
|
||||
rc->precombatspell = xml_spell(node, "spell");
|
||||
rc->precombatspell = xml_spellref(node, "spell");
|
||||
}
|
||||
xmlXPathFreeObject(result);
|
||||
|
||||
|
@ -1878,11 +1877,11 @@ static int parse_races(xmlDocPtr doc)
|
|||
xmlFree(propValue);
|
||||
}
|
||||
else {
|
||||
attack->data.sp = xml_spell(node, "spell");
|
||||
attack->data.sp = xml_spellref(node, "spell");
|
||||
if (attack->data.sp) {
|
||||
attack->level = xml_ivalue(node, "level", 0);
|
||||
if (attack->level <= 0) {
|
||||
log_error("magical attack '%s' for race '%s' needs a level: %d\n", attack->data.sp->sname, rc->_name, attack->level);
|
||||
log_error("magical attack '%s' for race '%s' needs a level: %d\n", attack->data.sp->name, rc->_name, attack->level);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2069,17 +2068,20 @@ static int parse_strings(xmlDocPtr doc)
|
|||
|
||||
void register_xmlreader(void)
|
||||
{
|
||||
xml_register_callback(parse_strings);
|
||||
xml_register_callback(parse_messages);
|
||||
xml_register_callback(parse_resources);
|
||||
xml_register_callback(parse_rules);
|
||||
|
||||
xml_register_callback(parse_buildings); /* requires resources */
|
||||
xml_register_callback(parse_ships); /* requires terrains */
|
||||
xml_register_callback(parse_spells); /* requires resources */
|
||||
xml_register_callback(parse_spellbooks); /* requires spells */
|
||||
xml_register_callback(parse_equipment); /* requires spells */
|
||||
xml_register_callback(parse_races); /* requires spells */
|
||||
xml_register_callback(parse_races);
|
||||
xml_register_callback(parse_calendar);
|
||||
xml_register_callback(parse_resources);
|
||||
|
||||
xml_register_callback(parse_buildings); /* requires resources */
|
||||
xml_register_callback(parse_ships); /* requires resources, terrains */
|
||||
xml_register_callback(parse_equipment); /* requires resources */
|
||||
|
||||
xml_register_callback(parse_spells); /* requires resources */
|
||||
xml_register_callback(parse_spellbooks); /* requires spells */
|
||||
|
||||
xml_register_callback(parse_strings);
|
||||
xml_register_callback(parse_messages);
|
||||
}
|
||||
#endif
|
||||
|
|
30
src/magic.c
30
src/magic.c
|
@ -430,7 +430,6 @@ void show_new_spells(faction * f, int level, const spellbook *book)
|
|||
for (qi = 0; ql; selist_advance(&ql, &qi, 1)) {
|
||||
spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi);
|
||||
if (sbe->level <= level) {
|
||||
|
||||
if (!already_seen(f, sbe->sp)) {
|
||||
attrib * a = a_new(&at_reportspell);
|
||||
spellbook_entry * entry = (spellbook_entry *)a->data.v;
|
||||
|
@ -481,13 +480,15 @@ void pick_random_spells(faction * f, int level, spellbook * book, int num_spells
|
|||
commonspells[maxspell] = sbe;
|
||||
sbe = 0;
|
||||
}
|
||||
else if (f->spellbook && spellbook_get(f->spellbook, sbe->sp)) {
|
||||
// already have this spell, remove it from the list of candidates
|
||||
commonspells[spellno] = commonspells[--numspells];
|
||||
if (maxspell > numspells) {
|
||||
maxspell = numspells;
|
||||
else {
|
||||
if (f->spellbook && spellbook_get(f->spellbook, sbe->sp)) {
|
||||
// already have this spell, remove it from the list of candidates
|
||||
commonspells[spellno] = commonspells[--numspells];
|
||||
if (maxspell > numspells) {
|
||||
maxspell = numspells;
|
||||
}
|
||||
sbe = 0;
|
||||
}
|
||||
sbe = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,8 +561,11 @@ const spell *get_combatspell(const unit * u, int nr)
|
|||
if (m) {
|
||||
return m->combatspells[nr].sp;
|
||||
}
|
||||
else if (u_race(u)->precombatspell != NULL) {
|
||||
return u_race(u)->precombatspell;
|
||||
else {
|
||||
const race * rc = u_race(u);
|
||||
if (rc->precombatspell) {
|
||||
return spellref_get(rc->precombatspell);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -2945,6 +2949,7 @@ const char *spell_info(const spell * sp, const struct locale *lang)
|
|||
return LOC(lang, mkname("spellinfo", sp->sname));
|
||||
}
|
||||
|
||||
// TODO: should take the name, not the spell (spellref optimizations)
|
||||
const char *spell_name(const spell * sp, const struct locale *lang)
|
||||
{
|
||||
return LOC(lang, mkname("spell", sp->sname));
|
||||
|
@ -2964,15 +2969,14 @@ static void select_spellbook(void **tokens, spellbook *sb, const struct locale *
|
|||
|
||||
for (qi = 0, ql = sb->spells; ql; selist_advance(&ql, &qi, 1)) {
|
||||
spellbook_entry *sbe = (spellbook_entry *)selist_get(ql, qi);
|
||||
spell *sp = sbe->sp;
|
||||
|
||||
const char *n = spell_name(sp, lang);
|
||||
const char *n = spell_name(sbe->sp, lang);
|
||||
if (!n) {
|
||||
log_error("no translation in locale %s for spell %s\n", locale_name(lang), sp->sname);
|
||||
log_error("no translation in locale %s for spell %s\n", locale_name(lang), sbe->sp->sname);
|
||||
}
|
||||
else {
|
||||
variant token;
|
||||
token.v = sp;
|
||||
token.v = sbe->sp;
|
||||
addtoken((struct tnode **)tokens, n, token);
|
||||
}
|
||||
}
|
||||
|
|
26
src/main.c
26
src/main.c
|
@ -76,10 +76,20 @@ static void load_inifile(dictionary * d)
|
|||
|
||||
static dictionary *parse_config(const char *filename)
|
||||
{
|
||||
dictionary *d = iniparser_load(filename);
|
||||
char path[MAX_PATH];
|
||||
dictionary *d;
|
||||
const char *cfgpath = config_get("config.path");
|
||||
|
||||
if (cfgpath) {
|
||||
join_path(cfgpath, filename, path, sizeof(path));
|
||||
log_debug("reading from configuration file %s\n", path);
|
||||
d = iniparser_load(path);
|
||||
} else {
|
||||
log_debug("reading from configuration file %s\n", filename);
|
||||
d = iniparser_load(filename);
|
||||
}
|
||||
if (d) {
|
||||
load_inifile(d);
|
||||
log_debug("reading from configuration file %s\n", filename);
|
||||
config_set_from(d);
|
||||
|
||||
memdebug = iniparser_getint(d, "game:memcheck", memdebug);
|
||||
|
@ -176,6 +186,10 @@ static int parse_args(int argc, char **argv, int *exitcode)
|
|||
else {
|
||||
const char *arg;
|
||||
switch (argi[1]) {
|
||||
case 'c':
|
||||
i = get_arg(argc, argv, 2, i, &arg, 0);
|
||||
config_set("config.path", arg);
|
||||
break;
|
||||
case 'r':
|
||||
i = get_arg(argc, argv, 2, i, &arg, 0);
|
||||
config_set("config.rules", arg);
|
||||
|
@ -270,15 +284,15 @@ int main(int argc, char **argv)
|
|||
{
|
||||
int err = 0;
|
||||
lua_State *L;
|
||||
dictionary *d;
|
||||
dictionary *d = 0;
|
||||
setup_signal_handler();
|
||||
/* ini file sets defaults for arguments*/
|
||||
/* parse arguments again, to override ini file */
|
||||
parse_args(argc, argv, &err);
|
||||
|
||||
d = parse_config(inifile);
|
||||
if (!d) {
|
||||
log_error("could not open ini configuration %s\n", inifile);
|
||||
}
|
||||
/* parse arguments again, to override ini file */
|
||||
parse_args(argc, argv, &err);
|
||||
|
||||
locale_init();
|
||||
|
||||
|
|
|
@ -234,7 +234,7 @@ paragraph(struct stream *out, const char *str, ptrdiff_t indent, int hanging_ind
|
|||
} while (*begin);
|
||||
}
|
||||
|
||||
static size_t write_spell_modifier(spell * sp, int flag, const char * str, bool cont, char * bufp, size_t size) {
|
||||
static size_t write_spell_modifier(const spell * sp, int flag, const char * str, bool cont, char * bufp, size_t size) {
|
||||
if (sp->sptyp & flag) {
|
||||
size_t bytes = 0;
|
||||
if (cont) {
|
||||
|
@ -255,7 +255,7 @@ void nr_spell_syntax(struct stream *out, spellbook_entry * sbe, const struct loc
|
|||
char buf[4096];
|
||||
char *bufp = buf;
|
||||
size_t size = sizeof(buf) - 1;
|
||||
spell * sp = sbe->sp;
|
||||
const spell * sp = sbe->sp;
|
||||
const char *params = sp->parameter;
|
||||
|
||||
if (sp->sptyp & ISCOMBATSPELL) {
|
||||
|
@ -445,7 +445,7 @@ void nr_spell(struct stream *out, spellbook_entry * sbe, const struct locale *la
|
|||
char buf[4096];
|
||||
char *startp, *bufp = buf;
|
||||
size_t size = sizeof(buf) - 1;
|
||||
spell * sp = sbe->sp;
|
||||
const spell * sp = sbe->sp;
|
||||
|
||||
newline(out);
|
||||
centre(out, spell_name(sp, lang), true);
|
||||
|
|
|
@ -680,6 +680,7 @@ size_t size)
|
|||
if (wrptr(&bufp, &size, result) != 0) {
|
||||
WARN_STATIC_BUFFER();
|
||||
}
|
||||
// TODO: no need to deref the spellref here (spref->name is good)
|
||||
bufp = STRLCPY(bufp, spell_name(sbe->sp, f->locale), size);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,13 @@ static void test_unicode_bug2262(CuTest *tc) {
|
|||
CuAssertIntEquals(tc, EILSEQ, unicode_utf8_trim(name));
|
||||
}
|
||||
|
||||
static void test_unicode_compare(CuTest *tc)
|
||||
{
|
||||
CuAssertIntEquals(tc, 0, unicode_utf8_strcasecmp("ABCDEFG", "abcdefg"));
|
||||
CuAssertIntEquals(tc, 0, unicode_utf8_strcasecmp("abcdefg123", "ABCDEFG123"));
|
||||
CuAssertIntEquals(tc, 1, unicode_utf8_strcasecmp("bacdefg123", "ABCDEFG123"));
|
||||
}
|
||||
|
||||
CuSuite *get_unicode_suite(void)
|
||||
{
|
||||
CuSuite *suite = CuSuiteNew();
|
||||
|
@ -124,5 +131,6 @@ CuSuite *get_unicode_suite(void)
|
|||
SUITE_ADD_TEST(suite, test_unicode_trim);
|
||||
SUITE_ADD_TEST(suite, test_unicode_utf8_to_other);
|
||||
SUITE_ADD_TEST(suite, test_unicode_utf8_to_ucs);
|
||||
SUITE_ADD_TEST(suite, test_unicode_compare);
|
||||
return suite;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ SET SERVER=%BUILD%\eressea.exe
|
|||
%SERVER% ..\scripts\run-tests.lua
|
||||
%SERVER% -re2 ..\scripts\run-tests-e2.lua
|
||||
%SERVER% -re3 ..\scripts\run-tests-e3.lua
|
||||
%SERVER% -re4 ..\scripts\run-tests-e4.lua
|
||||
PAUSE
|
||||
RMDIR /s /q reports
|
||||
DEL score score.alliances datum turn
|
||||
|
|
Loading…
Reference in New Issue