forked from github/server
- make mindblast less crazy
This commit is contained in:
parent
3e475d63ad
commit
536b177387
6 changed files with 182 additions and 69 deletions
src
|
@ -206,16 +206,29 @@ read_mage(attrib * a, FILE * F)
|
||||||
fscanf(F, "%d %d %d", &mtype, &mage->spellpoints, &mage->spchange);
|
fscanf(F, "%d %d %d", &mtype, &mage->spellpoints, &mage->spchange);
|
||||||
mage->magietyp = (magic_t)mtype;
|
mage->magietyp = (magic_t)mtype;
|
||||||
for (i=0;i!=MAXCOMBATSPELLS;++i) {
|
for (i=0;i!=MAXCOMBATSPELLS;++i) {
|
||||||
|
spell * sp = NULL;
|
||||||
|
int level = 0;
|
||||||
if (global.data_version<SPELLNAME_VERSION) {
|
if (global.data_version<SPELLNAME_VERSION) {
|
||||||
int spid;
|
int spid;
|
||||||
fscanf (F, "%d %d", &spid, &mage->combatspells[i].level);
|
fscanf (F, "%d %d", &spid, &level);
|
||||||
if (spid>=0) {
|
if (spid>=0) {
|
||||||
mage->combatspells[i].sp = find_spellbyid(mage->magietyp, (spellid_t)spid);
|
sp = find_spellbyid(mage->magietyp, (spellid_t)spid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fscanf (F, "%s %d", spname, &mage->combatspells[i].level);
|
fscanf (F, "%s %d", spname, &level);
|
||||||
|
|
||||||
if (strcmp("none", spname)!=0) {
|
if (strcmp("none", spname)!=0) {
|
||||||
mage->combatspells[i].sp = find_spell(mage->magietyp, spname);
|
sp = find_spell(mage->magietyp, spname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sp && level>0) {
|
||||||
|
int slot = -1;
|
||||||
|
if (sp->sptyp & PRECOMBATSPELL) slot = 0;
|
||||||
|
else if (sp->sptyp & COMBATSPELL) slot = 1;
|
||||||
|
else if (sp->sptyp & POSTCOMBATSPELL) slot = 2;
|
||||||
|
if (slot>=0) {
|
||||||
|
mage->combatspells[slot].level = level;
|
||||||
|
mage->combatspells[slot].sp = sp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -524,50 +537,50 @@ get_combatspelllevel(const unit *u, int nr)
|
||||||
const spell*
|
const spell*
|
||||||
get_combatspell(const unit *u, int nr)
|
get_combatspell(const unit *u, int nr)
|
||||||
{
|
{
|
||||||
sc_mage *m;
|
sc_mage *m;
|
||||||
|
|
||||||
assert(nr < MAXCOMBATSPELLS);
|
assert(nr < MAXCOMBATSPELLS);
|
||||||
m = get_mage(u);
|
m = get_mage(u);
|
||||||
if (m) {
|
if (m) {
|
||||||
return m->combatspells[nr].sp;
|
return m->combatspells[nr].sp;
|
||||||
} else if (u->race->precombatspell != NULL) {
|
} else if (u->race->precombatspell != NULL) {
|
||||||
return u->race->precombatspell;
|
return u->race->precombatspell;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
set_combatspell(unit *u, spell *sp, struct order * ord, int level)
|
set_combatspell(unit *u, spell *sp, struct order * ord, int level)
|
||||||
{
|
{
|
||||||
sc_mage *m = get_mage(u);
|
sc_mage *m = get_mage(u);
|
||||||
int i = -1;
|
int i = -1;
|
||||||
if (!m) return;
|
if (!m) return;
|
||||||
|
|
||||||
/* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */
|
/* knowsspell prüft auf ist_magier, ist_spruch, kennt_spruch */
|
||||||
if (knowsspell(u->region, u, sp) == false){
|
if (knowsspell(u->region, u, sp) == false){
|
||||||
/* Fehler 'Spell not found' */
|
/* Fehler 'Spell not found' */
|
||||||
cmistake(u, ord, 173, MSG_MAGIC);
|
cmistake(u, ord, 173, MSG_MAGIC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!has_spell(u, sp)) {
|
if (!has_spell(u, sp)) {
|
||||||
/* Diesen Zauber kennt die Einheit nicht */
|
/* Diesen Zauber kennt die Einheit nicht */
|
||||||
cmistake(u, ord, 169, MSG_MAGIC);
|
cmistake(u, ord, 169, MSG_MAGIC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!(sp->sptyp & ISCOMBATSPELL)) {
|
if (!(sp->sptyp & ISCOMBATSPELL)) {
|
||||||
/* Diesen Kampfzauber gibt es nicht */
|
/* Diesen Kampfzauber gibt es nicht */
|
||||||
cmistake(u, ord, 171, MSG_MAGIC);
|
cmistake(u, ord, 171, MSG_MAGIC);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sp->sptyp & PRECOMBATSPELL) i = 0;
|
if (sp->sptyp & PRECOMBATSPELL) i = 0;
|
||||||
else if (sp->sptyp & COMBATSPELL) i = 1;
|
else if (sp->sptyp & COMBATSPELL) i = 1;
|
||||||
else if (sp->sptyp & POSTCOMBATSPELL) i = 2;
|
else if (sp->sptyp & POSTCOMBATSPELL) i = 2;
|
||||||
assert(i>=0);
|
assert(i>=0);
|
||||||
m->combatspells[i].sp = sp;
|
m->combatspells[i].sp = sp;
|
||||||
m->combatspells[i].level = level;
|
m->combatspells[i].level = level;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -580,7 +593,6 @@ unset_combatspell(unit *u, spell *sp)
|
||||||
m = get_mage(u);
|
m = get_mage(u);
|
||||||
if (!m) return;
|
if (!m) return;
|
||||||
|
|
||||||
/* Kampfzauber löschen */
|
|
||||||
if (!sp) {
|
if (!sp) {
|
||||||
for (i=0;i<MAXCOMBATSPELLS;i++) {
|
for (i=0;i<MAXCOMBATSPELLS;i++) {
|
||||||
m->combatspells[i].sp = NULL;
|
m->combatspells[i].sp = NULL;
|
||||||
|
|
|
@ -127,6 +127,7 @@ finalize_skillmod(attrib * a)
|
||||||
free(a->data.v);
|
free(a->data.v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** temporary skill modification (NOT SAVED!). */
|
||||||
attrib_type at_skillmod = {
|
attrib_type at_skillmod = {
|
||||||
"skillmod",
|
"skillmod",
|
||||||
init_skillmod,
|
init_skillmod,
|
||||||
|
|
|
@ -457,23 +457,32 @@ sp_speed(fighter * fi, int level, double power, spell * sp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static skill_t
|
static skill_t
|
||||||
random_skill(unit *u)
|
random_skill(unit *u, boolean weighted)
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
skill * sv;
|
skill * sv;
|
||||||
|
|
||||||
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
||||||
if (sv->level>0) ++n;
|
if (sv->level>0) {
|
||||||
|
if (weighted) n+= sv->level;
|
||||||
|
else ++n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(n == 0)
|
if (n == 0)
|
||||||
return NOSKILL;
|
return NOSKILL;
|
||||||
|
|
||||||
n = rng_int()%n;
|
n = rng_int()%n;
|
||||||
|
|
||||||
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
for (sv = u->skills; sv != u->skills + u->skill_size; ++sv) {
|
||||||
if (sv->level>0) {
|
if (sv->level>0) {
|
||||||
if (n-- == 0) return sv->id;
|
if (weighted) {
|
||||||
|
if (n<sv->level) return sv->id;
|
||||||
|
n-=sv->level;
|
||||||
|
} else {
|
||||||
|
if (n == 0) return sv->id;
|
||||||
|
--n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,22 +490,19 @@ random_skill(unit *u)
|
||||||
return NOSKILL;
|
return NOSKILL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** The mind blast spell for regular folks.
|
||||||
|
* This spell temporarily reduces the skill of the victims
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
sp_mindblast(fighter * fi, int level, double power, spell * sp)
|
sp_mindblast_temp(fighter * fi, int level, double power, spell * sp)
|
||||||
{
|
{
|
||||||
battle *b = fi->side->battle;
|
battle *b = fi->side->battle;
|
||||||
unit *mage = fi->unit;
|
unit *mage = fi->unit;
|
||||||
troop dt;
|
int k = 0, reset = 0, maxloss = (level+2)/3;
|
||||||
unit *du;
|
|
||||||
skill_t sk;
|
|
||||||
int killed = 0;
|
|
||||||
int force, enemies;
|
|
||||||
int k = 0;
|
|
||||||
message * m;
|
message * m;
|
||||||
|
int force = lovar(power * 25);
|
||||||
|
int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
|
||||||
|
|
||||||
force = lovar(power * 25);
|
|
||||||
|
|
||||||
enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
|
|
||||||
if (!enemies) {
|
if (!enemies) {
|
||||||
m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
|
m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
|
||||||
message_all(b, m);
|
message_all(b, m);
|
||||||
|
@ -504,26 +510,110 @@ sp_mindblast(fighter * fi, int level, double power, spell * sp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (force && enemies) {
|
while (force>0 && enemies>0) {
|
||||||
dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
|
unit *du;
|
||||||
|
troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
|
||||||
|
|
||||||
assert(dt.fighter);
|
assert(dt.fighter);
|
||||||
du = dt.fighter->unit;
|
du = dt.fighter->unit;
|
||||||
if (humanoidrace(du->race) && !is_magic_resistant(mage, du, 0)) {
|
if (fval(du, UFL_MARK)) {
|
||||||
sk = random_skill(du);
|
/* not this one again */
|
||||||
if (sk != NOSKILL) {
|
continue;
|
||||||
skill * sv = get_skill(du, sk);
|
}
|
||||||
int n = 1 + rng_int() % 3;
|
|
||||||
/* Skill abziehen */
|
if (humanoidrace(du->race) && force>=du->number) {
|
||||||
reduce_skill(du, sv, n);
|
if (!is_magic_resistant(mage, du, 0)) {
|
||||||
} else {
|
skill_t sk = random_skill(du, true);
|
||||||
/* Keine Skills mehr, Einheit töten */
|
if (sk != NOSKILL) {
|
||||||
kill_troop(dt);
|
int n = 1 + rng_int() % maxloss;
|
||||||
++killed;
|
attrib * a = make_skillmod(sk, SMF_ALWAYS, NULL, 0.0, n);
|
||||||
}
|
/* neat: you can add a whole lot of these to a unit, they stack */
|
||||||
--enemies;
|
a_add(&du->attribs, a);
|
||||||
++k;
|
}
|
||||||
|
k += du->number;
|
||||||
|
}
|
||||||
|
force -= du->number;
|
||||||
|
}
|
||||||
|
fset(du, UFL_MARK);
|
||||||
|
reset = 1;
|
||||||
|
enemies -= du->number;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reset) {
|
||||||
|
unit * u;
|
||||||
|
for (u=b->region->units;u;u=u->next) {
|
||||||
|
freset(u, UFL_MARK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m = msg_message("sp_mindblast_temp_effect", "mage spell amount", mage, sp, k);
|
||||||
|
message_all(b, m);
|
||||||
|
msg_release(m);
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** A mind blast spell for monsters.
|
||||||
|
* This spell PERMANENTLY reduces the skill of the victims or kills them
|
||||||
|
* when they have no skills left. Not currently in use.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
sp_mindblast(fighter * fi, int level, double power, spell * sp)
|
||||||
|
{
|
||||||
|
battle *b = fi->side->battle;
|
||||||
|
unit *mage = fi->unit;
|
||||||
|
int killed = 0, k = 0, reset = 0;
|
||||||
|
message * m;
|
||||||
|
int force = lovar(power * 25);
|
||||||
|
int enemies = count_enemies(b, fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
|
||||||
|
|
||||||
|
if (!enemies) {
|
||||||
|
m = msg_message("battle::out_of_range", "mage spell", fi->unit, sp);
|
||||||
|
message_all(b, m);
|
||||||
|
msg_release(m);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (enemies>0 && force>0) {
|
||||||
|
unit *du;
|
||||||
|
troop dt = select_enemy(fi, FIGHT_ROW, BEHIND_ROW, SELECT_ADVANCE);
|
||||||
|
|
||||||
|
assert(dt.fighter);
|
||||||
|
du = dt.fighter->unit;
|
||||||
|
if (fval(du, UFL_MARK)) {
|
||||||
|
/* not this one again */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (humanoidrace(du->race) && force>=du->number) {
|
||||||
|
if (!is_magic_resistant(mage, du, 0)) {
|
||||||
|
skill_t sk = random_skill(du, false);
|
||||||
|
if (sk != NOSKILL) {
|
||||||
|
skill * sv = get_skill(du, sk);
|
||||||
|
int n = 1 + rng_int() % 3;
|
||||||
|
|
||||||
|
reduce_skill(du, sv, n);
|
||||||
|
k+=du->number;
|
||||||
|
} else {
|
||||||
|
/* unit has no skill. kill it. */
|
||||||
|
kill_troop(dt);
|
||||||
|
++killed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
force -= du->number;
|
||||||
|
} else {
|
||||||
|
/* only works against humanoids, don't try others. but do remove them
|
||||||
|
* from 'force' once or we may never terminate. */
|
||||||
|
fset(du, UFL_MARK);
|
||||||
|
reset = 1;
|
||||||
|
}
|
||||||
|
enemies -= du->number;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (reset) {
|
||||||
|
unit * u;
|
||||||
|
for (u=b->region->units;u;u=u->next) {
|
||||||
|
freset(u, UFL_MARK);
|
||||||
}
|
}
|
||||||
--force;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m = msg_message("sp_mindblast_effect", "mage spell amount dead", mage, sp, k, killed);
|
m = msg_message("sp_mindblast_effect", "mage spell amount dead", mage, sp, k, killed);
|
||||||
|
|
|
@ -40,6 +40,7 @@ extern "C" {
|
||||||
extern int sp_hero(struct fighter * fi, int level, double power, struct spell * sp);
|
extern int sp_hero(struct fighter * fi, int level, double power, struct spell * sp);
|
||||||
extern int sp_frighten(struct fighter * fi, int level, double power, struct spell * sp);
|
extern int sp_frighten(struct fighter * fi, int level, double power, struct spell * sp);
|
||||||
extern int sp_mindblast(struct fighter * fi, int level, double power, struct spell * sp);
|
extern int sp_mindblast(struct fighter * fi, int level, double power, struct spell * sp);
|
||||||
|
extern int sp_mindblast_temp(struct fighter * fi, int level, double power, struct spell * sp);
|
||||||
extern int sp_speed(struct fighter * fi, int level, double power, struct spell * sp);
|
extern int sp_speed(struct fighter * fi, int level, double power, struct spell * sp);
|
||||||
extern int sp_wolfhowl(struct fighter * fi, int level, double power, struct spell * sp);
|
extern int sp_wolfhowl(struct fighter * fi, int level, double power, struct spell * sp);
|
||||||
extern int sp_dragonodem(struct fighter * fi, int level, double power, struct spell * sp);
|
extern int sp_dragonodem(struct fighter * fi, int level, double power, struct spell * sp);
|
||||||
|
|
|
@ -7907,7 +7907,7 @@ static spelldata spelldaten[] =
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SPL_MINDBLAST, "mindblast", NULL, NULL, NULL,
|
SPL_MINDBLAST, "mindblast", NULL, NULL, NULL,
|
||||||
M_TRAUM, (COMBATSPELL | SPELLLEVEL), 5, 11,
|
M_TRAUM, (PRECOMBATSPELL | SPELLLEVEL), 5, 11,
|
||||||
{
|
{
|
||||||
{ "aura", 2, SPC_LEVEL },
|
{ "aura", 2, SPC_LEVEL },
|
||||||
{ 0, 0, 0 },
|
{ 0, 0, 0 },
|
||||||
|
@ -7915,7 +7915,7 @@ static spelldata spelldaten[] =
|
||||||
{ 0, 0, 0 },
|
{ 0, 0, 0 },
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
},
|
},
|
||||||
(spell_f)sp_mindblast, NULL
|
(spell_f)sp_mindblast_temp, NULL
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
SPL_ORKDREAM, "orkdream", NULL, NULL,
|
SPL_ORKDREAM, "orkdream", NULL, NULL,
|
||||||
|
|
|
@ -7598,6 +7598,15 @@
|
||||||
<text locale="de">"$unit($mage) zaubert $spell($spell). $int($amount) Krieger verloren Erinnerungen, $int($dead) wurden getötet."</text>
|
<text locale="de">"$unit($mage) zaubert $spell($spell). $int($amount) Krieger verloren Erinnerungen, $int($dead) wurden getötet."</text>
|
||||||
</message>
|
</message>
|
||||||
|
|
||||||
|
<message name="sp_mindblast_temp_effect" section="magic">
|
||||||
|
<type>
|
||||||
|
<arg name="mage" type="unit"/>
|
||||||
|
<arg name="spell" type="spell"/>
|
||||||
|
<arg name="amount" type="int"/>
|
||||||
|
</type>
|
||||||
|
<text locale="de">"$unit($mage) zaubert $spell($spell). $int($amount) Krieger verloren kurzzeitig ihr Gedächtnis."</text>
|
||||||
|
</message>
|
||||||
|
|
||||||
<message name="sp_shadowcall_effect" section="magic">
|
<message name="sp_shadowcall_effect" section="magic">
|
||||||
<type>
|
<type>
|
||||||
<arg name="mage" type="unit"/>
|
<arg name="mage" type="unit"/>
|
||||||
|
|
Loading…
Add table
Reference in a new issue