forked from github/server
remove struct equipment from the code entirely.
This commit is contained in:
parent
9dd38a6593
commit
269030082c
16 changed files with 174 additions and 755 deletions
|
@ -7,7 +7,6 @@
|
||||||
"config://conf/e3/terrains.json",
|
"config://conf/e3/terrains.json",
|
||||||
"config://conf/e3/items.json",
|
"config://conf/e3/items.json",
|
||||||
"config://conf/e3/races.json",
|
"config://conf/e3/races.json",
|
||||||
"config://res/e3a/familiars.xml",
|
|
||||||
"config://res/e3a/ships.xml",
|
"config://res/e3a/ships.xml",
|
||||||
"config://res/e3a/buildings.xml",
|
"config://res/e3a/buildings.xml",
|
||||||
"config://res/e3a/spells.xml",
|
"config://res/e3a/spells.xml",
|
||||||
|
|
|
@ -1,105 +0,0 @@
|
||||||
<?xml version="1.0"?>
|
|
||||||
<eressea>
|
|
||||||
<equipment>
|
|
||||||
|
|
||||||
<!-- equipment given to familiars -->
|
|
||||||
<set name="fam_lynx">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_tunnelworm">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<skill name="mining" level="1"/>
|
|
||||||
<skill name="forestry" level="1"/>
|
|
||||||
<skill name="stamina" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_eagle">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_rat">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<skill name="stamina" level="6"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_songdragon">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<!-- spells -->
|
|
||||||
<spell name="flee" level="2"/>
|
|
||||||
<spell name="sleep" level="7"/>
|
|
||||||
<spell name="frighten" level="8"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_nymph">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<skill name="bow" level="1"/>
|
|
||||||
<skill name="training" level="1"/>
|
|
||||||
<skill name="riding" level="1"/>
|
|
||||||
<!-- spells -->
|
|
||||||
<spell name="seduction" level="6"/>
|
|
||||||
<spell name="calm_monster" level="6"/>
|
|
||||||
<spell name="song_of_confusion" level="4"/>
|
|
||||||
<spell name="appeasement" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_unicorn">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<!-- spells -->
|
|
||||||
<spell name="resist_magic" level="3"/>
|
|
||||||
<spell name="song_of_peace" level="12"/>
|
|
||||||
<spell name="calm_monster" level="6"/>
|
|
||||||
<spell name="heroic_song" level="5"/>
|
|
||||||
<spell name="song_of_healing" level="2"/>
|
|
||||||
<spell name="appeasement" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_direwolf">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_ghost">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<!-- spells -->
|
|
||||||
<spell name="steal_aura" level="6"/>
|
|
||||||
<spell name="frighten" level="8"/>
|
|
||||||
<spell name="summonundead" level="6"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_imp">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<!-- spells -->
|
|
||||||
<spell name="steal_aura" level="6"/>
|
|
||||||
<spell name="shapeshift" level="3"/>
|
|
||||||
<spell name="seduction" level="6"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_dreamcat">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<!-- spells -->
|
|
||||||
<spell name="shapeshift" level="3"/>
|
|
||||||
<spell name="transferauratraum" level="3"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_fairy">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
<!-- spells -->
|
|
||||||
<spell name="appeasement" level="1"/>
|
|
||||||
<spell name="calm_monster" level="6"/>
|
|
||||||
<spell name="seduction" level="6"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_owl">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_hellcat">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
<set name="fam_tiger">
|
|
||||||
<skill name="magic" level="1"/>
|
|
||||||
</set>
|
|
||||||
|
|
||||||
</equipment>
|
|
||||||
</eressea>
|
|
127
scripts/eressea/e3/familiars.lua
Normal file
127
scripts/eressea/e3/familiars.lua
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
eressea.log.debug("rules for game E3")
|
||||||
|
|
||||||
|
local equipment = require('eressea.equipment')
|
||||||
|
local sets = {
|
||||||
|
['fam_lynx'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_eagle'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_direwolf'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_owl'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_hellcat'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_tiger'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_rat'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
['stamina'] = 6,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_tunnelworm'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
['mining'] = 1,
|
||||||
|
['forestry'] = 1,
|
||||||
|
['stamina'] = 1,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_dreamcat'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
},
|
||||||
|
['spells'] = {
|
||||||
|
['shapeshift'] = 3,
|
||||||
|
['transferauratraum'] = 3,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_imp'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
},
|
||||||
|
['spells'] = {
|
||||||
|
['shapeshift'] = 3,
|
||||||
|
['seduction'] = 6,
|
||||||
|
['steal_aura'] = 6,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_ghost'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
},
|
||||||
|
['spells'] = {
|
||||||
|
['steal_aura'] = 6,
|
||||||
|
['summonundead'] = 6,
|
||||||
|
['frighten'] = 8,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_fairy'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
},
|
||||||
|
['spells'] = {
|
||||||
|
['appeasement'] = 1,
|
||||||
|
['seduction'] = 6,
|
||||||
|
['calm_monster'] = 6,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_songdragon'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
},
|
||||||
|
['spells'] = {
|
||||||
|
['flee'] = 2,
|
||||||
|
['sleep'] = 7,
|
||||||
|
['frighten'] = 8,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_unicorn'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
},
|
||||||
|
['spells'] = {
|
||||||
|
['appeasement'] = 1,
|
||||||
|
['song_of_healing'] = 2,
|
||||||
|
['resist_magic'] = 3,
|
||||||
|
['heroic_song'] = 5,
|
||||||
|
['calm_monster'] = 6,
|
||||||
|
['song_of_peace'] = 12,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
['fam_nymph'] = {
|
||||||
|
['skills'] = {
|
||||||
|
['magic'] = 1,
|
||||||
|
['bow'] = 1,
|
||||||
|
['training'] = 1,
|
||||||
|
['riding'] = 1,
|
||||||
|
},
|
||||||
|
['spells'] = {
|
||||||
|
['appeasement'] = 1,
|
||||||
|
['song_of_confusion'] = 4,
|
||||||
|
['calm_monster'] = 6,
|
||||||
|
['seduction'] = 6,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
equipment.add_multiple(sets)
|
|
@ -17,5 +17,6 @@ return {
|
||||||
require('eressea'),
|
require('eressea'),
|
||||||
require('eressea.xmasitems'),
|
require('eressea.xmasitems'),
|
||||||
require('eressea.frost'),
|
require('eressea.frost'),
|
||||||
require('eressea.ents')
|
require('eressea.ents'),
|
||||||
|
require('eressea.e3.familiars'),
|
||||||
}
|
}
|
||||||
|
|
|
@ -916,17 +916,13 @@ void kill_troop(troop dt)
|
||||||
rmtroop(dt);
|
rmtroop(dt);
|
||||||
if (!df->alive) {
|
if (!df->alive) {
|
||||||
char eqname[64];
|
char eqname[64];
|
||||||
const struct equipment *eq;
|
|
||||||
const race *rc = u_race(du);
|
const race *rc = u_race(du);
|
||||||
item *drops = item_spoil(rc, du->number - df->run.number);
|
item *drops = item_spoil(rc, du->number - df->run.number);
|
||||||
if (drops != NULL) {
|
if (drops != NULL) {
|
||||||
i_merge(&du->items, &drops);
|
i_merge(&du->items, &drops);
|
||||||
}
|
}
|
||||||
sprintf(eqname, "spo_%s", rc->_name);
|
sprintf(eqname, "spo_%s", rc->_name);
|
||||||
eq = get_equipment(eqname);
|
equip_unit_mask(du, eqname, EQUIP_ITEMS);
|
||||||
if (eq != NULL) {
|
|
||||||
equip_items(&du->items, eq);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
|
|
||||||
#include <spells/flyingship.h>
|
#include <spells/flyingship.h>
|
||||||
|
|
||||||
#include <kernel/equipment.h>
|
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/race.h>
|
#include <kernel/race.h>
|
||||||
#include <kernel/ship.h>
|
#include <kernel/ship.h>
|
||||||
|
|
|
@ -31,7 +31,6 @@ without prior permission by the authors of Eressea.
|
||||||
#include <kernel/callbacks.h>
|
#include <kernel/callbacks.h>
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include <kernel/callbacks.h>
|
#include <kernel/callbacks.h>
|
||||||
#include <kernel/equipment.h>
|
|
||||||
#include <kernel/faction.h>
|
#include <kernel/faction.h>
|
||||||
#include <kernel/spell.h>
|
#include <kernel/spell.h>
|
||||||
#include <kernel/race.h>
|
#include <kernel/race.h>
|
||||||
|
|
|
@ -30,7 +30,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "building.h"
|
#include "building.h"
|
||||||
#include "direction.h"
|
#include "direction.h"
|
||||||
#include "equipment.h"
|
|
||||||
#include "faction.h"
|
#include "faction.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
@ -564,7 +563,6 @@ void kernel_done(void)
|
||||||
attrib_done();
|
attrib_done();
|
||||||
item_done();
|
item_done();
|
||||||
message_done();
|
message_done();
|
||||||
equipment_done();
|
|
||||||
reports_done();
|
reports_done();
|
||||||
curses_done();
|
curses_done();
|
||||||
crmessage_done();
|
crmessage_done();
|
||||||
|
|
|
@ -41,59 +41,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void equipment_setskill(equipment * eq, skill_t sk, const char *value)
|
|
||||||
{
|
|
||||||
if (eq != NULL) {
|
|
||||||
if (value != NULL) {
|
|
||||||
eq->skills[sk] = str_strdup(value);
|
|
||||||
}
|
|
||||||
else if (eq->skills[sk]) {
|
|
||||||
free(eq->skills[sk]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct lazy_spell {
|
|
||||||
struct spellref *spref;
|
|
||||||
int level;
|
|
||||||
} lazy_spell;
|
|
||||||
|
|
||||||
void equipment_addspell(equipment * eq, const char * name, int level)
|
|
||||||
{
|
|
||||||
if (eq) {
|
|
||||||
lazy_spell *ls = malloc(sizeof(lazy_spell));
|
|
||||||
ls->spref = spellref_create(NULL, name);
|
|
||||||
ls->level = level;
|
|
||||||
selist_push(&eq->spells, ls);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
equipment_setitem(equipment * eq, const item_type * itype, const char *value)
|
|
||||||
{
|
|
||||||
if (eq != NULL) {
|
|
||||||
if (itype != NULL) {
|
|
||||||
itemdata *idata = eq->items;
|
|
||||||
while (idata && idata->itype != itype) {
|
|
||||||
idata = idata->next;
|
|
||||||
}
|
|
||||||
if (idata == NULL) {
|
|
||||||
idata = (itemdata *)malloc(sizeof(itemdata));
|
|
||||||
idata->itype = itype;
|
|
||||||
idata->value = str_strdup(value);
|
|
||||||
idata->next = eq->items;
|
|
||||||
eq->items = idata;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
equipment_setcallback(struct equipment *eq, equip_callback_fun callback)
|
|
||||||
{
|
|
||||||
eq->callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool equip_unit(struct unit *u, const char *eqname)
|
bool equip_unit(struct unit *u, const char *eqname)
|
||||||
{
|
{
|
||||||
return equip_unit_mask(u, eqname, EQUIP_ALL);
|
return equip_unit_mask(u, eqname, EQUIP_ALL);
|
||||||
|
@ -101,228 +48,8 @@ bool equip_unit(struct unit *u, const char *eqname)
|
||||||
|
|
||||||
bool equip_unit_mask(struct unit *u, const char *eqname, int mask)
|
bool equip_unit_mask(struct unit *u, const char *eqname, int mask)
|
||||||
{
|
{
|
||||||
const equipment * eq = get_equipment(eqname);
|
|
||||||
if (eq) {
|
|
||||||
equip_unit_set(u, eq, mask);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (callbacks.equip_unit) {
|
if (callbacks.equip_unit) {
|
||||||
return callbacks.equip_unit(u, eqname, mask);
|
return callbacks.equip_unit(u, eqname, mask);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void equip_unit_set(struct unit *u, const equipment *eq, int mask)
|
|
||||||
{
|
|
||||||
if (mask & EQUIP_SKILLS) {
|
|
||||||
int sk;
|
|
||||||
for (sk = 0; sk != MAXSKILLS; ++sk) {
|
|
||||||
if (eq->skills[sk] != NULL) {
|
|
||||||
int i = dice_rand(eq->skills[sk]);
|
|
||||||
if (i > 0) {
|
|
||||||
set_level(u, (skill_t)sk, i);
|
|
||||||
if (sk == SK_STAMINA) {
|
|
||||||
u->hp = unit_max_hp(u) * u->number;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & EQUIP_SPELLS) {
|
|
||||||
if (eq->spells) {
|
|
||||||
selist * ql = eq->spells;
|
|
||||||
int qi;
|
|
||||||
sc_mage * mage = get_mage_depr(u);
|
|
||||||
|
|
||||||
for (qi = 0; ql; selist_advance(&ql, &qi, 1)) {
|
|
||||||
lazy_spell *sbe = (lazy_spell *)selist_get(ql, qi);
|
|
||||||
spell *sp = spellref_get(sbe->spref);
|
|
||||||
unit_add_spell(u, mage, sp, sbe->level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eq->items && mask & EQUIP_ITEMS) {
|
|
||||||
itemdata *idata;
|
|
||||||
for (idata = eq->items; idata != NULL; idata = idata->next) {
|
|
||||||
int i = u->number * dice_rand(idata->value);
|
|
||||||
if (i > 0) {
|
|
||||||
i_add(&u->items, i_new(idata->itype, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (eq->subsets) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; eq->subsets[i].sets; ++i) {
|
|
||||||
if (chance(eq->subsets[i].chance)) {
|
|
||||||
double rnd = (1 + rng_int() % 1000) / 1000.0;
|
|
||||||
int k;
|
|
||||||
for (k = 0; eq->subsets[i].sets[k].set; ++k) {
|
|
||||||
if (rnd <= eq->subsets[i].sets[k].chance) {
|
|
||||||
equip_unit_set(u, eq->subsets[i].sets[k].set, mask);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rnd -= eq->subsets[i].sets[k].chance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mask & EQUIP_SPECIAL) {
|
|
||||||
if (eq->callback) {
|
|
||||||
eq->callback(eq, u);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void equip_items(struct item **items, const struct equipment *eq)
|
|
||||||
{
|
|
||||||
if (eq) {
|
|
||||||
itemdata *idata;
|
|
||||||
|
|
||||||
for (idata = eq->items; idata != NULL; idata = idata->next) {
|
|
||||||
int i = dice_rand(idata->value);
|
|
||||||
if (i > 0) {
|
|
||||||
i_add(items, i_new(idata->itype, i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (eq->subsets) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; eq->subsets[i].sets; ++i) {
|
|
||||||
if (chance(eq->subsets[i].chance)) {
|
|
||||||
double rnd = (1 + rng_int() % 1000) / 1000.0;
|
|
||||||
int k;
|
|
||||||
for (k = 0; eq->subsets[i].sets[k].set; ++k) {
|
|
||||||
if (rnd <= eq->subsets[i].sets[k].chance) {
|
|
||||||
equip_items(items, eq->subsets[i].sets[k].set);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rnd -= eq->subsets[i].sets[k].chance;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_ls(void *arg) {
|
|
||||||
lazy_spell *ls = (lazy_spell*)arg;
|
|
||||||
spellref_free(ls->spref);
|
|
||||||
free(ls);
|
|
||||||
}
|
|
||||||
|
|
||||||
static critbit_tree cb_equipments = { 0 };
|
|
||||||
|
|
||||||
#define EQNAMELEN 24
|
|
||||||
|
|
||||||
typedef struct eq_entry {
|
|
||||||
char key[EQNAMELEN];
|
|
||||||
equipment *value;
|
|
||||||
} eq_entry;
|
|
||||||
|
|
||||||
typedef struct name_cb_data {
|
|
||||||
const equipment *find;
|
|
||||||
const char *result;
|
|
||||||
} name_cb_data;
|
|
||||||
|
|
||||||
|
|
||||||
static int equipment_name_cb(const void * match, const void * key, size_t keylen, void *cbdata) {
|
|
||||||
const eq_entry *ent = (const eq_entry *)match;
|
|
||||||
name_cb_data *query = (name_cb_data *)cbdata;
|
|
||||||
if (ent->value == query->find) {
|
|
||||||
query->result = ent->key;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *equipment_name(const struct equipment *eq)
|
|
||||||
{
|
|
||||||
name_cb_data data;
|
|
||||||
|
|
||||||
data.find = eq;
|
|
||||||
data.result = NULL;
|
|
||||||
cb_foreach(&cb_equipments, "", 0, equipment_name_cb, &data);
|
|
||||||
return data.result;
|
|
||||||
}
|
|
||||||
|
|
||||||
equipment *get_equipment(const char *eqname)
|
|
||||||
{
|
|
||||||
const void *match;
|
|
||||||
|
|
||||||
if (strlen(eqname) >= EQNAMELEN) {
|
|
||||||
log_warning("equipment name is longer than %d bytes: %s", EQNAMELEN - 1, eqname);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
match = cb_find_str(&cb_equipments, eqname);
|
|
||||||
if (match) {
|
|
||||||
const eq_entry *ent = (const eq_entry *)match;
|
|
||||||
return ent->value;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
equipment *create_equipment(const char *eqname)
|
|
||||||
{
|
|
||||||
size_t len = strlen(eqname);
|
|
||||||
eq_entry ent;
|
|
||||||
|
|
||||||
if (len >= EQNAMELEN) {
|
|
||||||
log_error("equipment name is longer than %d bytes: %s", EQNAMELEN-1, eqname);
|
|
||||||
len = EQNAMELEN-1;
|
|
||||||
}
|
|
||||||
memset(ent.key, 0, EQNAMELEN);
|
|
||||||
memcpy(ent.key, eqname, len);
|
|
||||||
|
|
||||||
ent.value = (equipment *)calloc(1, sizeof(equipment));
|
|
||||||
|
|
||||||
cb_insert(&cb_equipments, &ent, sizeof(ent));
|
|
||||||
return ent.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
equipment *get_or_create_equipment(const char *eqname)
|
|
||||||
{
|
|
||||||
equipment *eq = get_equipment(eqname);
|
|
||||||
if (!eq) {
|
|
||||||
return create_equipment(eqname);
|
|
||||||
}
|
|
||||||
return eq;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_equipment(equipment *eq) {
|
|
||||||
int i;
|
|
||||||
if (eq->spells) {
|
|
||||||
selist_foreach(eq->spells, free_ls);
|
|
||||||
selist_free(eq->spells);
|
|
||||||
}
|
|
||||||
while (eq->items) {
|
|
||||||
itemdata *next = eq->items->next;
|
|
||||||
free(eq->items->value);
|
|
||||||
free(eq->items);
|
|
||||||
eq->items = next;
|
|
||||||
}
|
|
||||||
if (eq->subsets) {
|
|
||||||
for (i = 0; eq->subsets[i].sets; ++i) {
|
|
||||||
free(eq->subsets[i].sets);
|
|
||||||
}
|
|
||||||
free(eq->subsets);
|
|
||||||
}
|
|
||||||
for (i = 0; i != MAXSKILLS; ++i) {
|
|
||||||
free(eq->skills[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int free_equipment_cb(const void * match, const void * key, size_t keylen, void *cbdata) {
|
|
||||||
const eq_entry * ent = (const eq_entry *)match;
|
|
||||||
free_equipment(ent->value);
|
|
||||||
free(ent->value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void equipment_done(void) {
|
|
||||||
cb_foreach(&cb_equipments, "", 0, free_equipment_cb, 0);
|
|
||||||
cb_clear(&cb_equipments);
|
|
||||||
}
|
|
||||||
|
|
|
@ -19,64 +19,18 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#ifndef H_KRNL_EQUIPMENT_H
|
#ifndef H_KRNL_EQUIPMENT_H
|
||||||
#define H_KRNL_EQUIPMENT_H
|
#define H_KRNL_EQUIPMENT_H
|
||||||
|
|
||||||
#include "skill.h"
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
struct spell;
|
|
||||||
struct item;
|
|
||||||
struct unit;
|
struct unit;
|
||||||
|
|
||||||
typedef struct itemdata {
|
|
||||||
const struct item_type *itype;
|
|
||||||
char *value;
|
|
||||||
struct itemdata *next;
|
|
||||||
} itemdata;
|
|
||||||
|
|
||||||
typedef struct subsetitem {
|
|
||||||
struct equipment *set;
|
|
||||||
float chance;
|
|
||||||
} subsetitem;
|
|
||||||
|
|
||||||
typedef struct subset {
|
|
||||||
float chance;
|
|
||||||
subsetitem *sets;
|
|
||||||
} subset;
|
|
||||||
|
|
||||||
typedef void(*equip_callback_fun) (const struct equipment *, struct unit *);
|
|
||||||
|
|
||||||
typedef struct equipment {
|
|
||||||
struct itemdata *items;
|
|
||||||
char *skills[MAXSKILLS];
|
|
||||||
struct selist *spells;
|
|
||||||
struct subset *subsets;
|
|
||||||
equip_callback_fun callback;
|
|
||||||
} equipment;
|
|
||||||
|
|
||||||
void equipment_done(void);
|
|
||||||
|
|
||||||
const char *equipment_name(const struct equipment *eq);
|
|
||||||
struct equipment *get_or_create_equipment(const char *eqname);
|
|
||||||
struct equipment *get_equipment(const char *eqname);
|
|
||||||
struct equipment *create_equipment(const char *eqname);
|
|
||||||
|
|
||||||
void equipment_setitem(struct equipment *eq,
|
|
||||||
const struct item_type *itype, const char *value);
|
|
||||||
void equipment_setskill(struct equipment *eq, skill_t sk,
|
|
||||||
const char *value);
|
|
||||||
void equipment_addspell(struct equipment *eq, const char *name, int level);
|
|
||||||
void equipment_setcallback(struct equipment *eq, equip_callback_fun callback);
|
|
||||||
|
|
||||||
#define EQUIP_SKILLS (1<<1)
|
#define EQUIP_SKILLS (1<<1)
|
||||||
#define EQUIP_SPELLS (1<<2)
|
#define EQUIP_SPELLS (1<<2)
|
||||||
#define EQUIP_ITEMS (1<<3)
|
#define EQUIP_ITEMS (1<<3)
|
||||||
#define EQUIP_SPECIAL (1<<4)
|
#define EQUIP_SPECIAL (1<<4)
|
||||||
#define EQUIP_ALL (0xFF)
|
#define EQUIP_ALL (0xFF)
|
||||||
void equip_items(struct item **items, const struct equipment *eq);
|
|
||||||
void equip_unit_set(struct unit *u, const struct equipment *eq, int mask);
|
|
||||||
bool equip_unit_mask(struct unit *u, const char *eqname, int mask);
|
bool equip_unit_mask(struct unit *u, const char *eqname, int mask);
|
||||||
bool equip_unit(struct unit *u, const char *eqname);
|
bool equip_unit(struct unit *u, const char *eqname);
|
||||||
|
|
||||||
|
|
|
@ -11,86 +11,40 @@
|
||||||
#include <CuTest.h>
|
#include <CuTest.h>
|
||||||
#include <tests.h>
|
#include <tests.h>
|
||||||
|
|
||||||
|
static unit *eq_unit;
|
||||||
|
static const char *eq_name;
|
||||||
|
static int eq_mask;
|
||||||
|
|
||||||
|
static bool equip_callback(unit *u, const char *eqname, int mask) {
|
||||||
|
eq_unit = u;
|
||||||
|
eq_name = eqname;
|
||||||
|
eq_mask = mask;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_equipment(CuTest * tc)
|
static void test_equipment(CuTest * tc)
|
||||||
{
|
{
|
||||||
equipment * eq;
|
callbacks.equip_unit = equip_callback;
|
||||||
unit * u;
|
unit * u;
|
||||||
const item_type * it_horses;
|
|
||||||
spell *sp;
|
|
||||||
sc_mage * mage;
|
|
||||||
|
|
||||||
test_setup();
|
test_setup();
|
||||||
test_create_race("human");
|
|
||||||
enable_skill(SK_MAGIC, true);
|
|
||||||
it_horses = test_create_itemtype("horse");
|
|
||||||
CuAssertPtrNotNull(tc, it_horses);
|
|
||||||
sp = create_spell("testspell");
|
|
||||||
CuAssertPtrNotNull(tc, sp);
|
|
||||||
|
|
||||||
CuAssertPtrEquals(tc, 0, get_equipment("herpderp"));
|
|
||||||
eq = get_or_create_equipment("herpderp");
|
|
||||||
CuAssertPtrEquals(tc, eq, get_equipment("herpderp"));
|
|
||||||
|
|
||||||
equipment_setitem(eq, it_horses, "1");
|
|
||||||
equipment_setskill(eq, SK_MAGIC, "5");
|
|
||||||
equipment_addspell(eq, sp->sname, 1);
|
|
||||||
|
|
||||||
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
u = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
||||||
equip_unit_set(u, eq, EQUIP_ALL);
|
CuAssertIntEquals(tc, true, equip_unit_mask(u, "hodor", EQUIP_ALL));
|
||||||
CuAssertIntEquals(tc, 1, i_get(u->items, it_horses));
|
CuAssertIntEquals(tc, EQUIP_ALL, eq_mask);
|
||||||
CuAssertIntEquals(tc, 5, get_level(u, SK_MAGIC));
|
CuAssertPtrEquals(tc, u, eq_unit);
|
||||||
|
CuAssertStrEquals(tc, "hodor", eq_name);
|
||||||
|
|
||||||
mage = get_mage_depr(u);
|
CuAssertIntEquals(tc, true, equip_unit_mask(u, "foobar", EQUIP_ITEMS));
|
||||||
CuAssertPtrNotNull(tc, mage);
|
CuAssertIntEquals(tc, EQUIP_ITEMS, eq_mask);
|
||||||
CuAssertPtrNotNull(tc, mage->spellbook);
|
CuAssertPtrEquals(tc, u, eq_unit);
|
||||||
CuAssertTrue(tc, u_hasspell(u, sp));
|
CuAssertStrEquals(tc, "foobar", eq_name);
|
||||||
test_teardown();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_get_equipment(CuTest * tc)
|
CuAssertIntEquals(tc, true, equip_unit(u, "unknown"));
|
||||||
{
|
CuAssertIntEquals(tc, EQUIP_ALL, eq_mask);
|
||||||
equipment * eq;
|
CuAssertPtrEquals(tc, u, eq_unit);
|
||||||
|
CuAssertStrEquals(tc, "unknown", eq_name);
|
||||||
|
|
||||||
test_setup();
|
|
||||||
eq = create_equipment("catapultammo123");
|
|
||||||
CuAssertPtrNotNull(tc, eq);
|
|
||||||
CuAssertStrEquals(tc, "catapultammo123", equipment_name(eq));
|
|
||||||
eq = get_equipment("catapultammo123");
|
|
||||||
CuAssertPtrNotNull(tc, eq);
|
|
||||||
CuAssertStrEquals(tc, "catapultammo123", equipment_name(eq));
|
|
||||||
eq = get_equipment("catapult");
|
|
||||||
CuAssertPtrEquals(tc, NULL, eq);
|
|
||||||
eq = create_equipment("catapult");
|
|
||||||
CuAssertPtrNotNull(tc, eq);
|
|
||||||
CuAssertPtrEquals(tc, eq, get_equipment("catapult"));
|
|
||||||
CuAssertStrEquals(tc, "catapult", equipment_name(eq));
|
|
||||||
eq = get_equipment("catapultammo123");
|
|
||||||
CuAssertPtrNotNull(tc, eq);
|
|
||||||
CuAssertStrEquals(tc, "catapultammo123", equipment_name(eq));
|
|
||||||
test_teardown();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool equip_test(unit *u, const char *name, int mask) {
|
|
||||||
if (mask & EQUIP_ITEMS) {
|
|
||||||
i_change(&u->items, it_find("horse"), 1);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_equipment_callback(CuTest *tc) {
|
|
||||||
unit *u;
|
|
||||||
item_type *itype;
|
|
||||||
test_setup();
|
|
||||||
itype = test_create_horse();
|
|
||||||
u = test_create_unit(test_create_faction(NULL), test_create_plain(0, 0));
|
|
||||||
CuAssertTrue(tc, !equip_unit_mask(u, "horse", EQUIP_ITEMS));
|
|
||||||
CuAssertPtrEquals(tc, NULL, u->items);
|
|
||||||
callbacks.equip_unit = equip_test;
|
|
||||||
CuAssertTrue(tc, equip_unit(u, "horse"));
|
|
||||||
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
|
|
||||||
CuAssertTrue(tc, !equip_unit_mask(u, "horse", EQUIP_SPELLS));
|
|
||||||
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
|
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,7 +52,5 @@ CuSuite *get_equipment_suite(void)
|
||||||
{
|
{
|
||||||
CuSuite *suite = CuSuiteNew();
|
CuSuite *suite = CuSuiteNew();
|
||||||
SUITE_ADD_TEST(suite, test_equipment);
|
SUITE_ADD_TEST(suite, test_equipment);
|
||||||
SUITE_ADD_TEST(suite, test_get_equipment);
|
|
||||||
SUITE_ADD_TEST(suite, test_equipment_callback);
|
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
|
@ -285,7 +285,6 @@ unit *addplayer(region * r, faction * f)
|
||||||
{
|
{
|
||||||
unit *u;
|
unit *u;
|
||||||
const char * name;
|
const char * name;
|
||||||
const struct equipment* eq;
|
|
||||||
|
|
||||||
assert(r->land);
|
assert(r->land);
|
||||||
if (rpeasants(r) < PEASANT_MIN) {
|
if (rpeasants(r) < PEASANT_MIN) {
|
||||||
|
@ -296,10 +295,7 @@ unit *addplayer(region * r, faction * f)
|
||||||
faction_setorigin(f, 0, r->x, r->y);
|
faction_setorigin(f, 0, r->x, r->y);
|
||||||
u = create_unit(r, f, 1, f->race, 0, NULL, NULL);
|
u = create_unit(r, f, 1, f->race, 0, NULL, NULL);
|
||||||
name = config_get("rules.equip_first");
|
name = config_get("rules.equip_first");
|
||||||
eq = get_equipment(name ? name : "first_unit");
|
equip_unit(u, name ? name : "first_unit");
|
||||||
if (eq) {
|
|
||||||
equip_items(&u->items, eq);
|
|
||||||
}
|
|
||||||
u->hp = unit_max_hp(u) * u->number;
|
u->hp = unit_max_hp(u) * u->number;
|
||||||
fset(u, UFL_ISNEW);
|
fset(u, UFL_ISNEW);
|
||||||
if (f->race == get_race(RC_DAEMON)) {
|
if (f->race == get_race(RC_DAEMON)) {
|
||||||
|
|
|
@ -27,7 +27,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include "building.h"
|
#include "building.h"
|
||||||
#include "calendar.h"
|
#include "calendar.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "equipment.h"
|
|
||||||
#include "faction.h"
|
#include "faction.h"
|
||||||
#include "group.h"
|
#include "group.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
|
@ -1331,29 +1330,7 @@ static void fix_familiars(void) {
|
||||||
/* unit is potentially a familiar */
|
/* unit is potentially a familiar */
|
||||||
attrib * a = a_find(u->attribs, &at_mage);
|
attrib * a = a_find(u->attribs, &at_mage);
|
||||||
attrib * am = a_find(u->attribs, &at_familiarmage);
|
attrib * am = a_find(u->attribs, &at_familiarmage);
|
||||||
if (am) {
|
if (!am && a) {
|
||||||
sc_mage *mage = a ? (sc_mage *)a->data.v : NULL;
|
|
||||||
/* a familiar */
|
|
||||||
if (!mage) {
|
|
||||||
log_error("%s seems to be a familiar with no magic.",
|
|
||||||
unitname(u));
|
|
||||||
mage = create_mage(u, M_GRAY);
|
|
||||||
}
|
|
||||||
if (!mage->spellbook) {
|
|
||||||
char eqname[32];
|
|
||||||
equipment *eq;
|
|
||||||
|
|
||||||
snprintf(eqname, sizeof(eqname), "fam_%s", u->_race->_name);
|
|
||||||
eq = get_equipment(eqname);
|
|
||||||
if (eq && eq->spells) {
|
|
||||||
log_error("%s seems to be a familiar with no spells.",
|
|
||||||
unitname(u));
|
|
||||||
/* magical familiar, no spells */
|
|
||||||
equip_unit_set(u, eq, EQUIP_SPELLS);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (a) {
|
|
||||||
/* not a familiar, but magical */
|
/* not a familiar, but magical */
|
||||||
attrib * ae = a_find(u->attribs, &at_eventhandler);
|
attrib * ae = a_find(u->attribs, &at_eventhandler);
|
||||||
if (ae) {
|
if (ae) {
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "teleport.h"
|
#include "teleport.h"
|
||||||
#include "give.h"
|
#include "give.h"
|
||||||
|
|
||||||
|
#include <kernel/callbacks.h>
|
||||||
#include <kernel/building.h>
|
#include <kernel/building.h>
|
||||||
#include <kernel/race.h>
|
#include <kernel/race.h>
|
||||||
#include <kernel/equipment.h>
|
#include <kernel/equipment.h>
|
||||||
|
@ -556,39 +557,32 @@ static void test_familiar_age(CuTest *tc) {
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unit *eq_unit;
|
||||||
|
static char *eq_name;
|
||||||
|
static int eq_mask;
|
||||||
|
|
||||||
|
static bool equip_callback(unit *u, const char *eqname, int mask) {
|
||||||
|
eq_unit = u;
|
||||||
|
eq_name = str_strdup(eqname);
|
||||||
|
eq_mask = mask;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void test_familiar_equip(CuTest *tc) {
|
static void test_familiar_equip(CuTest *tc) {
|
||||||
unit *mag, *u;
|
unit *mag, *u;
|
||||||
equipment *eq;
|
|
||||||
const item_type * itype;
|
|
||||||
spell *sp;
|
|
||||||
sc_mage * mage;
|
|
||||||
|
|
||||||
test_setup();
|
test_setup();
|
||||||
|
callbacks.equip_unit = equip_callback;
|
||||||
itype = test_create_itemtype("horse");
|
|
||||||
CuAssertPtrNotNull(tc, itype);
|
|
||||||
sp = create_spell("testspell");
|
|
||||||
CuAssertPtrNotNull(tc, sp);
|
|
||||||
|
|
||||||
eq = get_or_create_equipment("fam_human");
|
|
||||||
equipment_setitem(eq, itype, "1");
|
|
||||||
equipment_setskill(eq, SK_ENTERTAINMENT, "5");
|
|
||||||
equipment_addspell(eq, sp->sname, 1);
|
|
||||||
|
|
||||||
mag = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
mag = test_create_unit(test_create_faction(NULL), test_create_region(0, 0, NULL));
|
||||||
u = test_create_unit(mag->faction, test_create_region(0, 0, NULL));
|
u = test_create_unit(mag->faction, test_create_region(0, 0, NULL));
|
||||||
|
CuAssertStrEquals(tc, "human", u->_race->_name);
|
||||||
set_familiar(mag, u);
|
set_familiar(mag, u);
|
||||||
create_newfamiliar(mag, u);
|
create_newfamiliar(mag, u);
|
||||||
CuAssertIntEquals(tc, 1, i_get(u->items, itype));
|
|
||||||
CuAssertIntEquals(tc, 5, get_level(u, SK_ENTERTAINMENT));
|
|
||||||
CuAssertIntEquals(tc, 0, get_level(u, SK_MAGIC));
|
|
||||||
|
|
||||||
mage = get_mage(u);
|
CuAssertIntEquals(tc, EQUIP_ALL, eq_mask);
|
||||||
CuAssertPtrNotNull(tc, mage);
|
CuAssertPtrEquals(tc, u, eq_unit);
|
||||||
CuAssertPtrNotNull(tc, mage->spellbook);
|
CuAssertStrEquals(tc, "fam_human", eq_name);
|
||||||
set_level(u, SK_MAGIC, 1);
|
free(eq_name);
|
||||||
CuAssertPtrEquals(tc, mage, get_mage_depr(u));
|
|
||||||
CuAssertTrue(tc, u_hasspell(u, sp));
|
|
||||||
|
|
||||||
test_teardown();
|
test_teardown();
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,6 @@ static void test_reset(void) {
|
||||||
free_config();
|
free_config();
|
||||||
default_locale = 0;
|
default_locale = 0;
|
||||||
calendar_cleanup();
|
calendar_cleanup();
|
||||||
equipment_done();
|
|
||||||
close_orders();
|
close_orders();
|
||||||
free_special_directions();
|
free_special_directions();
|
||||||
free_locales();
|
free_locales();
|
||||||
|
|
194
src/xmlreader.c
194
src/xmlreader.c
|
@ -16,7 +16,6 @@ without prior permission by the authors of Eressea.
|
||||||
#include "xmlreader.h"
|
#include "xmlreader.h"
|
||||||
|
|
||||||
#include "kernel/building.h"
|
#include "kernel/building.h"
|
||||||
#include "kernel/equipment.h"
|
|
||||||
#include "kernel/item.h"
|
#include "kernel/item.h"
|
||||||
#include "kernel/messages.h"
|
#include "kernel/messages.h"
|
||||||
#include "kernel/race.h"
|
#include "kernel/race.h"
|
||||||
|
@ -838,198 +837,6 @@ static int parse_resources(xmlDocPtr doc)
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_items(equipment * eq, xmlNodeSetPtr nsetItems)
|
|
||||||
{
|
|
||||||
if (nsetItems != NULL && nsetItems->nodeNr > 0) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i != nsetItems->nodeNr; ++i) {
|
|
||||||
xmlNodePtr node = nsetItems->nodeTab[i];
|
|
||||||
xmlChar *propValue;
|
|
||||||
const struct item_type *itype;
|
|
||||||
|
|
||||||
propValue = xmlGetProp(node, BAD_CAST "name");
|
|
||||||
assert(propValue != NULL);
|
|
||||||
itype = it_find((const char *)propValue);
|
|
||||||
xmlFree(propValue);
|
|
||||||
if (itype != NULL) {
|
|
||||||
propValue = xmlGetProp(node, BAD_CAST "amount");
|
|
||||||
if (propValue != NULL) {
|
|
||||||
equipment_setitem(eq, itype, (const char *)propValue);
|
|
||||||
xmlFree(propValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_spells(equipment * eq, xmlNodeSetPtr nsetItems)
|
|
||||||
{
|
|
||||||
if (nsetItems != NULL && nsetItems->nodeNr > 0) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i != nsetItems->nodeNr; ++i) {
|
|
||||||
xmlNodePtr node = nsetItems->nodeTab[i];
|
|
||||||
xmlChar *propValue;
|
|
||||||
int level;
|
|
||||||
const char *name;
|
|
||||||
|
|
||||||
propValue = xmlGetProp(node, BAD_CAST "name");
|
|
||||||
assert(propValue != NULL);
|
|
||||||
name = (const char *)propValue;
|
|
||||||
level = xml_ivalue(node, "level", 0);
|
|
||||||
if (level > 0) {
|
|
||||||
equipment_addspell(eq, name, level);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
log_error("spell '%s' for equipment-set '%s' has no level\n", name, equipment_name(eq));
|
|
||||||
}
|
|
||||||
xmlFree(propValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void add_skills(equipment * eq, xmlNodeSetPtr nsetSkills)
|
|
||||||
{
|
|
||||||
if (nsetSkills != NULL && nsetSkills->nodeNr > 0) {
|
|
||||||
int i;
|
|
||||||
for (i = 0; i != nsetSkills->nodeNr; ++i) {
|
|
||||||
xmlNodePtr node = nsetSkills->nodeTab[i];
|
|
||||||
xmlChar *propValue;
|
|
||||||
skill_t sk;
|
|
||||||
|
|
||||||
propValue = xmlGetProp(node, BAD_CAST "name");
|
|
||||||
assert(propValue != NULL);
|
|
||||||
sk = findskill((const char *)propValue);
|
|
||||||
if (sk == NOSKILL) {
|
|
||||||
log_error("unknown skill '%s' in equipment-set %s\n", (const char *)propValue, equipment_name(eq));
|
|
||||||
xmlFree(propValue);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xmlFree(propValue);
|
|
||||||
propValue = xmlGetProp(node, BAD_CAST "level");
|
|
||||||
if (propValue != NULL) {
|
|
||||||
equipment_setskill(eq, sk, (const char *)propValue);
|
|
||||||
xmlFree(propValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
add_subsets(xmlDocPtr doc, equipment * eq, xmlNodeSetPtr nsetSubsets)
|
|
||||||
{
|
|
||||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
|
||||||
if (nsetSubsets != NULL && nsetSubsets->nodeNr > 0) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
eq->subsets = calloc(nsetSubsets->nodeNr + 1, sizeof(subset));
|
|
||||||
for (i = 0; i != nsetSubsets->nodeNr; ++i) {
|
|
||||||
xmlXPathObjectPtr xpathResult;
|
|
||||||
xmlNodePtr node = nsetSubsets->nodeTab[i];
|
|
||||||
xmlChar *propValue;
|
|
||||||
|
|
||||||
eq->subsets[i].chance = 1.0f;
|
|
||||||
propValue = xmlGetProp(node, BAD_CAST "chance");
|
|
||||||
if (propValue != NULL) {
|
|
||||||
eq->subsets[i].chance = (float)atof((const char *)propValue);
|
|
||||||
xmlFree(propValue);
|
|
||||||
}
|
|
||||||
xpath->node = node;
|
|
||||||
xpathResult = xmlXPathEvalExpression(BAD_CAST "set", xpath);
|
|
||||||
if (xpathResult->nodesetval) {
|
|
||||||
xmlNodeSetPtr nsetSets = xpathResult->nodesetval;
|
|
||||||
float totalChance = 0.0f;
|
|
||||||
|
|
||||||
if (nsetSets->nodeNr > 0) {
|
|
||||||
int set;
|
|
||||||
eq->subsets[i].sets =
|
|
||||||
calloc(nsetSets->nodeNr + 1, sizeof(subsetitem));
|
|
||||||
for (set = 0; set != nsetSets->nodeNr; ++set) {
|
|
||||||
xmlNodePtr nodeSet = nsetSets->nodeTab[set];
|
|
||||||
float chance = 1.0f;
|
|
||||||
|
|
||||||
propValue = xmlGetProp(nodeSet, BAD_CAST "chance");
|
|
||||||
if (propValue != NULL) {
|
|
||||||
chance = (float)atof((const char *)propValue);
|
|
||||||
xmlFree(propValue);
|
|
||||||
}
|
|
||||||
totalChance += chance;
|
|
||||||
|
|
||||||
propValue = xmlGetProp(nodeSet, BAD_CAST "name");
|
|
||||||
assert(propValue != NULL);
|
|
||||||
eq->subsets[i].sets[set].chance = chance;
|
|
||||||
eq->subsets[i].sets[set].set =
|
|
||||||
get_or_create_equipment((const char *)propValue);
|
|
||||||
xmlFree(propValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (totalChance > 1.0f) {
|
|
||||||
log_error("total chance exceeds 1.0: %f in equipment set %s.\n", totalChance, equipment_name(eq));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xmlXPathFreeObject(xpathResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
xmlXPathFreeContext(xpath);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_equipment(xmlDocPtr doc)
|
|
||||||
{
|
|
||||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
|
||||||
xmlXPathObjectPtr xpathRaces;
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
/* reading eressea/equipment/set */
|
|
||||||
xpathRaces = xmlXPathEvalExpression(BAD_CAST "/eressea/equipment/set", xpath);
|
|
||||||
if (xpathRaces->nodesetval) {
|
|
||||||
xmlNodeSetPtr nsetRaces = xpathRaces->nodesetval;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
result += nsetRaces->nodeNr;
|
|
||||||
for (i = 0; i != nsetRaces->nodeNr; ++i) {
|
|
||||||
xmlNodePtr node = nsetRaces->nodeTab[i];
|
|
||||||
xmlChar *propName = xmlGetProp(node, BAD_CAST "name");
|
|
||||||
|
|
||||||
if (propName != NULL) {
|
|
||||||
equipment *eq = get_equipment((const char *)propName);
|
|
||||||
xmlXPathObjectPtr xpathResult;
|
|
||||||
|
|
||||||
if (!eq) {
|
|
||||||
eq = create_equipment((const char *)propName);
|
|
||||||
}
|
|
||||||
|
|
||||||
xpath->node = node;
|
|
||||||
|
|
||||||
xpathResult = xmlXPathEvalExpression(BAD_CAST "item", xpath);
|
|
||||||
assert(!eq->items);
|
|
||||||
add_items(eq, xpathResult->nodesetval);
|
|
||||||
xmlXPathFreeObject(xpathResult);
|
|
||||||
|
|
||||||
xpathResult = xmlXPathEvalExpression(BAD_CAST "spell", xpath);
|
|
||||||
assert(!eq->spells);
|
|
||||||
add_spells(eq, xpathResult->nodesetval);
|
|
||||||
xmlXPathFreeObject(xpathResult);
|
|
||||||
|
|
||||||
xpathResult = xmlXPathEvalExpression(BAD_CAST "skill", xpath);
|
|
||||||
add_skills(eq, xpathResult->nodesetval);
|
|
||||||
xmlXPathFreeObject(xpathResult);
|
|
||||||
|
|
||||||
xpathResult = xmlXPathEvalExpression(BAD_CAST "subset", xpath);
|
|
||||||
assert(!eq->subsets);
|
|
||||||
add_subsets(doc, eq, xpathResult->nodesetval);
|
|
||||||
xmlXPathFreeObject(xpathResult);
|
|
||||||
|
|
||||||
xmlFree(propName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlXPathFreeObject(xpathRaces);
|
|
||||||
xmlXPathFreeContext(xpath);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int parse_spellbooks(xmlDocPtr doc)
|
static int parse_spellbooks(xmlDocPtr doc)
|
||||||
{
|
{
|
||||||
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
xmlXPathContextPtr xpath = xmlXPathNewContext(doc);
|
||||||
|
@ -1670,7 +1477,6 @@ void register_xmlreader(void)
|
||||||
|
|
||||||
xml_register_callback(parse_buildings); /* requires resources */
|
xml_register_callback(parse_buildings); /* requires resources */
|
||||||
xml_register_callback(parse_ships); /* requires resources, terrains */
|
xml_register_callback(parse_ships); /* requires resources, terrains */
|
||||||
xml_register_callback(parse_equipment); /* requires resources */
|
|
||||||
|
|
||||||
xml_register_callback(parse_spellbooks); /* requires spells */
|
xml_register_callback(parse_spellbooks); /* requires spells */
|
||||||
xml_register_callback(parse_spells); /* requires resources */
|
xml_register_callback(parse_spells); /* requires resources */
|
||||||
|
|
Loading…
Reference in a new issue