Skip to content

Commit

Permalink
cr import, spells and familiars
Browse files Browse the repository at this point in the history
  • Loading branch information
ennorehling committed Jan 7, 2025
1 parent fa1ad7e commit 8ee53ce
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 39 deletions.
55 changes: 53 additions & 2 deletions src/crimport.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <kernel/ship.h>
#include <kernel/skill.h>
#include <kernel/skills.h>
#include <kernel/spellbook.h>
#include <kernel/terrain.h>
#include <kernel/types.h>
#include <kernel/unit.h>
Expand Down Expand Up @@ -88,6 +89,8 @@ typedef enum tag_t {
TAG_DESCRIPTION,
TAG_MEMO,
TAG_GUARD,
TAG_AURA,
TAG_FAMILIAR,
TAG_BUILDING,
TAG_SHIP,
TAG_SIZE,
Expand Down Expand Up @@ -184,6 +187,8 @@ static void init_tags(void)
add_tag("Status", TAG_STATUS);
add_tag("privat", TAG_MEMO);
add_tag("bewacht", TAG_GUARD);
add_tag("Aura", TAG_AURA);
add_tag("familiarmage", TAG_FAMILIAR);
add_tag("Burg", TAG_BUILDING);
add_tag("Schiff", TAG_SHIP);
add_tag("Groesse", TAG_SIZE);
Expand Down Expand Up @@ -640,6 +645,23 @@ static enum CR_Error handle_unit(context *ctx, tag_t key, const char *value)
case TAG_GUARD:
setguard(u, true);
break;
case TAG_AURA: {
struct sc_mage *scm = get_mage(u);
if (!scm) scm = create_mage(u, u->faction->magiegebiet);
mage_set_spellpoints(scm, atoi(value));
break;
}
case TAG_FAMILIAR: {
int no = atoi(value);
unit * magician = findunit(no);
struct sc_mage *scm = get_mage(u);
if (!scm) scm = create_mage(u, M_GRAY);
if (!magician) {
log_warning("cannot set familiar mage for %s", itoa36(u->no));
}
set_familiar(magician, u);
break;
}
case TAG_STATUS:
unit_setstatus(u, atoi(value));
break;
Expand Down Expand Up @@ -934,9 +956,8 @@ static enum CR_Error handle_property(void *udata, const char *name, const char *
context *ctx = (context *)udata;
enum CR_Error err = CR_ERROR_NONE;
switch (ctx->block) {
case BLOCK_EFFECTS:
case BLOCK_SPELLS:
case BLOCK_COMBATSPELLS:
break;
case BLOCK_BORDER:
err = handle_border(ctx, get_tag(name), value);
break;
Expand Down Expand Up @@ -1009,10 +1030,40 @@ static enum CR_Error handle_property(void *udata, const char *name, const char *
return err;
}


struct spell *findspell(unit *u, const char *name)
{
magic_t m;
for (m = M_GRAY; m != MAXMAGIETYP; ++m) {
spellbook *sb = get_spellbook(magic_school[m]);
struct spell * sp = spellbook_getspell(sb, name, default_locale);
if (sp) {
return sp;
}
}
return NULL;
}

static enum CR_Error handle_text(void *udata, const char *value) {
context *ctx = (context *)udata;
enum CR_Error err = CR_ERROR_NONE;
switch (ctx->block) {
case BLOCK_EFFECTS:
break;
case BLOCK_SPELLS: {
struct spell *sp;
unit *u = ctx->unit;
if (!u) {
return CR_ERROR_GRAMMAR;
}
if (NULL != (sp = findspell(u, value))) {
unit_add_spell(u, sp, 1);
}
else {
log_error("unknown spell %s", value);
}
break;
}
case BLOCK_COMMANDS: {
unit *u = ctx->unit;
if (!u) {
Expand Down
13 changes: 9 additions & 4 deletions src/kernel/spellbook.c
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
#include <kernel/spell.h>
#include "spellbook.h"

#include <util/log.h>
#include <kernel/gamedata.h>
#include "gamedata.h"
#include "spell.h"

#include "spellbook.h"
#include <util/aliases.h>
#include <util/language.h>
#include <util/log.h>
#include <util/umlaut.h>
#include <util/variant.h>

#include <stb_ds.h>
#include <storage.h>
Expand Down Expand Up @@ -135,3 +139,4 @@ spellbook_entry * spellbook_get(spellbook *sb, const struct spell *sp)
}
return 0;
}

75 changes: 42 additions & 33 deletions src/magic.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include <util/resolve.h>
#include <util/rng.h>
#include <util/umlaut.h>
#include <util/variant.h>

#include <critbit.h>
#include <selist.h>
Expand Down Expand Up @@ -156,7 +157,7 @@ void unit_add_spell(unit * u, struct spell * sp, int level)
sc_mage *mage = get_mage(u);

if (!mage) {
log_error("adding new spell %s to a previously non-magical unit %s\n", sp->sname, unitname(u));
log_warning("adding new spell %s to a previously non-magical unit %s\n", sp->sname, unitname(u));
mage = create_mage(u, M_GRAY);
}
if (!mage->spellbook) {
Expand Down Expand Up @@ -2086,35 +2087,38 @@ static int sm_familiar(const unit * u, const region * r, skill_t sk, int value)
void set_familiar(unit * mage, unit * familiar)
{
/* if the skill modifier for the mage does not yet exist, add it */
attrib *a = a_find(mage->attribs, &at_skillmod);
while (a && a->type == &at_skillmod) {
skillmod_data *smd = (skillmod_data *)a->data.v;
if (smd->special == sm_familiar)
break;
a = a->next;
}
if (a == NULL) {
a = make_skillmod(NOSKILL, sm_familiar, 0.0, 0);
a_add(&mage->attribs, a);
}

a = a_find(mage->attribs, &at_familiar);
if (a == NULL) {
a = a_add(&mage->attribs, a_new(&at_familiar));
a->data.v = familiar;
}
else {
assert(!a->data.v || a->data.v == familiar);
}
if (mage) {
attrib *a = a_find(mage->attribs, &at_skillmod);
while (a && a->type == &at_skillmod) {
skillmod_data *smd = (skillmod_data *)a->data.v;
if (smd->special == sm_familiar)
break;
a = a->next;
}
if (a == NULL) {
a = make_skillmod(NOSKILL, sm_familiar, 0.0, 0);
a_add(&mage->attribs, a);
}

/* TODO: Diese Attribute beim Tod des Familiars entfernen: */
a = a_find(familiar->attribs, &at_familiarmage);
if (a == NULL) {
a = a_add(&familiar->attribs, a_new(&at_familiarmage));
a->data.v = mage;
a = a_find(mage->attribs, &at_familiar);
if (a == NULL) {
a = a_add(&mage->attribs, a_new(&at_familiar));
a->data.v = familiar;
}
else {
assert(!a->data.v || a->data.v == familiar);
}
}
else {
assert(!a->data.v || a->data.v == mage);
if (familiar) {
/* TODO: Diese Attribute beim Tod des Familiars entfernen: */
attrib *a = a_find(familiar->attribs, &at_familiarmage);
if (a == NULL) {
a = a_add(&familiar->attribs, a_new(&at_familiarmage));
a->data.v = mage;
}
else {
assert(!a->data.v || a->data.v == mage);
}
}
}

Expand Down Expand Up @@ -2905,13 +2909,10 @@ static void select_spellbook(void **tokens, spellbook *sb, const struct locale *
}
}

spell *unit_getspell(struct unit *u, const char *name, const struct locale * lang)
spell *spellbook_getspell(spellbook *sb, const char *name, const struct locale *lang)
{
spellbook *sb;

sb = unit_get_spellbook(u);
if (sb) {
void * tokens = NULL;
void *tokens = NULL;
select_spellbook(&tokens, sb, lang);
if (tokens) {
variant token;
Expand All @@ -2925,6 +2926,14 @@ spell *unit_getspell(struct unit *u, const char *name, const struct locale * lan
return NULL;
}

spell *unit_getspell(struct unit *u, const char *name, const struct locale * lang)
{
spellbook *sb;

sb = unit_get_spellbook(u);
return spellbook_getspell(sb, name, lang);
}

int cast_spell(struct castorder *co)
{
const char *fname = co->sp->sname;
Expand Down
2 changes: 2 additions & 0 deletions src/magic.h
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,8 @@ extern "C" {
int bonus_percent);
/* gibt false zurueck, wenn der Zauber gelingt, true, wenn das Ziel
* widersteht */

struct spell *spellbook_getspell(struct spellbook *sb, const char *name, const struct locale *lang);
struct spell * unit_getspell(struct unit *u, const char *s,
const struct locale *lang);
const char *magic_name(magic_t mtype, const struct locale *lang);
Expand Down
2 changes: 2 additions & 0 deletions src/study.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ bool is_migrant(unit * u)

if (u_race(u) == u->faction->race)
return false;
if (is_familiar(u))
return false;

if (fval(u_race(u), RCF_UNDEAD | RCF_ILLUSIONARY))
return false;
Expand Down

0 comments on commit 8ee53ce

Please sign in to comment.