From 4101e7c066bf08b3e1ee27dc260546bf8c6720ce Mon Sep 17 00:00:00 2001 From: Rob Pearce Date: Fri, 7 Oct 2011 02:38:58 +0000 Subject: [PATCH] - [+] shift+backward shouldn't let you attack backwards! - [+] if LFINWAY and not "infront", "you run into somehting" - [+] change tumle to just take a direction - [+] change to take a dir - [+] different dirs should give different messages - [+] abilities should only charge STAMINA if they were successful! - [+] at end of useability() - [+] abilityeffects miust only retur TRUE on cancellation - [+] scroll of awareness not being used up! - [+] lore: at adept level, add "it could potentially kill you in xx hits" - [+] (assume no armour) - [+] need getweapons() - [+] implment 'canuseweapons(lf)' - [-] spells should only charge mp if they were successful??? - [+] move the validatespellcell() call into castspell. - [+] add f_targettedspell, tt_xx to all spell defs - [+] remove validatespellcall() call from dospelleffects - [+] test with player - [+] test with monsters - [ ] special cases: - [ ] blink - [ ] test digging... - [ ] invisibillity? - [ ] light - [ ] darkness - [ ] do i still need "frompot" in spelleffects??? - [+] new ability: flipthrow --- ai.c | 5 + attack.c | 56 +------ data.c | 135 +++++++++++++---- data/hiscores.db | Bin 8192 -> 8192 bytes defs.h | 6 +- flag.c | 1 + io.c | 36 ++++- lf.c | 189 +++++++++++++++++++---- lf.h | 5 +- map.c | 2 +- move.c | 57 ++++--- move.h | 2 +- nexus.c | 2 +- objects.c | 9 +- spell.c | 381 +++++++++++++++++++++++++---------------------- 15 files changed, 564 insertions(+), 322 deletions(-) diff --git a/ai.c b/ai.c index 7d7e56a..675f507 100644 --- a/ai.c +++ b/ai.c @@ -1784,6 +1784,11 @@ int aispellok(lifeform_t *lf, enum OBTYPE spellid, lifeform_t *victim, enum FLAG if ((ot->id == OT_S_DRAINLIFE) && isimmuneto(victim->flags, DT_NECROTIC)) { specificcheckok = B_FALSE; } + if (ot->id == OT_A_FLIP) { + if (getlfsize(victim) > getlfsize(lf)) { + specificcheckok = B_FALSE; + } + } if (ot->id == OT_A_FLURRY) { if (!isdualweilding(lf)) { specificcheckok = B_FALSE; diff --git a/attack.c b/attack.c index 9546da3..1b682b9 100644 --- a/attack.c +++ b/attack.c @@ -151,7 +151,7 @@ void applyarmourdamreduction(lifeform_t *lf, object_t *wep, int reduceamt, int * int attackcell(lifeform_t *lf, cell_t *c, int force) { int validwep[MAXCANDIDATES]; object_t *wep[MAXCANDIDATES]; - flag_t *damflag[MAXCANDIDATES], *f; + flag_t *damflag[MAXCANDIDATES]; obpile_t *op = NULL; enum { AT_NONE = 0, @@ -168,8 +168,6 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { int attacksdone = 0; int lastweaponidx = -1; int saysorry = B_FALSE; - flag_t *retflag[MAXCANDIDATES]; - int nretflags = 0; int attackedhelpless = B_FALSE; int attackedfriend = B_FALSE; int attackedpeaceful = B_FALSE; @@ -295,53 +293,9 @@ int attackcell(lifeform_t *lf, cell_t *c, int force) { } } - // first use our weapon... - nweps = 0; - wep[nweps] = getweapon(lf); - if (wep[nweps]) { - damflag[nweps] = hasflag(wep[nweps]->flags, F_DAM); - validwep[nweps] = B_TRUE; - lastweaponidx = 0; - nweps++; - gotweapon = B_TRUE; - } - - // if we are skilled at twoweaponing, we can attack with our second weapon - // as well, with a possible accuracy penalty depending on our skill level. - if (getskill(lf, SK_TWOWEAPON)) { - wep[nweps] = getsecmeleeweapon(lf); - if (wep[nweps]) { - if ((nweps >= 1) && (wep[nweps] == wep[nweps-1])) { - // can't be the same as first one - } else { - damflag[nweps] = hasflag(wep[nweps]->flags, F_DAM); - validwep[nweps] = B_TRUE; - lastweaponidx = nweps; - nweps++; - gotweapon = B_TRUE; - } - } - } - - // then use all our innate attacks.. - getflags(lf->flags, retflag, &nretflags, F_HASATTACK, F_NONE); - for (i = 0; i < nretflags; i++) { - f = retflag[i]; - if (f->id == F_HASATTACK) { - objecttype_t *ot; - - if (!op) { - op = addobpile(NULL, NULL, NULL); - } - - ot = findot(f->val[0]); - if (ot) { - wep[nweps] = addobfast(op, ot->id); - validwep[nweps] = B_TRUE; - damflag[nweps] = f; - nweps++; - } - } + gotweapon = getweapons(lf, wep, damflag, &lastweaponidx, &op, &nweps); + for (i = 0; i < nweps; i++) { + validwep[i] = B_TRUE; } innateattacks = countinnateattacks(lf); @@ -2511,7 +2465,7 @@ void wepeffects(flagpile_t *fp, cell_t *where, flag_t *damflag, int dam) { int dir; // knock back victim dir = getdirtowards(owner->cell, victim->cell, victim, B_FALSE, DT_COMPASS); - knockback(victim, dir , 2, owner, 30); + knockback(victim, dir , 2, owner, 30, B_TRUE); f->known = B_TRUE; } else if ((f->id == F_HITCONFER) && victim ) { // only works if we did damage diff --git a/data.c b/data.c index 7b4846e..c064d29 100644 --- a/data.c +++ b/data.c @@ -110,7 +110,7 @@ void initjobs(void) { // NOTE: try to always make the job's primary weapon be the first object defined. // this will make sure that they have the letter 'a'. - addjob(J_GOD, "Diety"); + addjob(J_GOD, "Diety", "A divine job mainly known for its importance in debugging. Dieties can use all abilities and are prompted before death. Due to their infinite power, they consider earthly diversions such as high score tables beneath their dignity."); addflag(lastjob->flags, F_STARTATT, A_STR, AT_EXHIGH, NA, NULL); addflag(lastjob->flags, F_STARTATT, A_AGI, AT_EXHIGH, NA, NULL); addflag(lastjob->flags, F_STARTATT, A_IQ, AT_EXHIGH, NA, NULL); @@ -157,7 +157,7 @@ void initjobs(void) { } addflag(lastjob->flags, F_NOSCORE, B_TRUE, NA, NA, NULL); - addjob(J_ADVENTURER, "Adventurer"); + addjob(J_ADVENTURER, "Adventurer", "Adventurers are a basic jack-of-all-trades type job. They can learn all skills, and already have basic Cartography and Lore skills. They start the game with three healing potions. Recommended for beginners."); // stat mods // initial objects addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "2 bananas"); @@ -182,7 +182,8 @@ void initjobs(void) { addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_ALLOMANCER, "Allomancer"); + /* + addjob(J_ALLOMANCER, "Allomancer", "Mages specialising in metal-based magic."); // stat mods addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 2, NA, NULL); // initial objects @@ -212,7 +213,8 @@ void initjobs(void) { addflag(lastjob->flags, F_DETECTMETAL, B_TRUE, NA, NA, NULL); mayusespellschool(lastjob->flags, SS_ALLOMANCY, F_CANCAST); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_COMMANDO, "Commando"); + */ + addjob(J_COMMANDO, "Commando", "An elite modern military fighter. Commandoes are very well equipped and capable of using (or learning to use) all technology. Unfortunately their adreneline-filled lifestyle leaves them a little lacking in wisdom, and they have no magical aptitude."); // stat mods addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 2, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, -3, NA, NULL); @@ -252,7 +254,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_UNARMED, PR_SKILLED, NA, NULL); // abilities addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_DRUID, "Druid"); + addjob(J_DRUID, "Druid", "Druids use the power of nature to aid themselves or harm others. They start with a pet wolf, and their spells are more powerful when near plants. They are willing to eat other lifeforms when neccessary but prefer a vegetable-based diet."); // stats addflag(lastjob->flags, F_MPDICE, 1, 1, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_WIS, 3, NA, NULL); @@ -290,7 +292,7 @@ void initjobs(void) { addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); /////////////////////////////////////// - addjob(J_MONK, "Monk"); + addjob(J_MONK, "Monk", "A life of strict self-discipline from an early age makes Monks masters of unarmed combat. This discipline extends to their minds, sometimes allowing them to develop powerful psionic abilities over time. On the downside, they are useless with most weapons and are strict vegetarians."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 1, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 2, NA, NULL); @@ -306,7 +308,6 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_CARTOGRAPHY, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_EVASION, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_PERCEPTION, PR_NOVICE, NA, NULL); - addflag(lastjob->flags, F_STARTSKILL, SK_STEALTH, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_UNARMED, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SS_MENTAL, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_STAVES, PR_NOVICE, NA, NULL); @@ -316,6 +317,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CANLEARN, SK_FIRSTAID, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SEWING, NA, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_STEALTH, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SWIMMING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_THROWING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TRAPS, PR_ADEPT, NA, NULL); @@ -352,12 +354,12 @@ void initjobs(void) { // 20: tower of iron will // 21: planeshift addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_PLUMBER, "Plumber"); + addjob(J_MECHANIC, "Mechanic", "Mechanics, while highly paid, are not generally very suited for adventuring. Their spanner and metal-working skills might come in handy though."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_CHA, -4, NA, NULL); // initial objects addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "spanner"); - addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "10 gold coins"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "80 gold coins"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "overalls"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "cap"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "3-5 mushrooms"); @@ -365,12 +367,12 @@ void initjobs(void) { // initial skills addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_NOVICE, NA, NULL); // learnable akills - addflag(lastjob->flags, F_CANLEARN, SK_ATHLETICS, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_CLIMBING, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_LISTEN, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_METALWORK, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_TECHUSAGE, NA, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SPELLCASTING, PR_ADEPT, NA, NULL); + addflag(lastjob->flags, F_CANLEARN, SK_SS_ALLOMANCY, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_FIRE, PR_ADEPT, NA, NULL); addflag(lastjob->flags, F_CANLEARN, SK_SS_COLD, PR_ADEPT, NA, NULL); // abilities @@ -378,7 +380,7 @@ void initjobs(void) { addflag(lastjob->flags, F_OBESE, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_CANWILL, OT_A_JUMP, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_PRINCE, "Prince"); + addjob(J_PRINCE, "Prince", "Princes have lived a life of leisure and privilege. Their time is generally spent either hunting (making them quite fit and skilled with a bow) or reading (giving them knowledge about the world around them). As they normally travel with a pack of bodyguards though, their weapons are more for show than actually useful."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_CHA, 4, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_WIS, 2, NA, NULL); @@ -391,6 +393,8 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "silk shirt"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "riding trousers"); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "leather boots"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "short bow"); + addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "15 arrows"); // initial skills addflag(lastjob->flags, F_STARTSKILL, SK_ARMOUR, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SHIELDS, PR_NOVICE, NA, NULL); @@ -398,6 +402,7 @@ void initjobs(void) { addflag(lastjob->flags, F_STARTSKILL, SK_LONGBLADES, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_HUMANOID, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_LORE_NATURE, PR_NOVICE, NA, NULL); + addflag(lastjob->flags, F_STARTSKILL, SK_RANGED, PR_NOVICE, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SWIMMING, PR_BEGINNER, NA, NULL); addflag(lastjob->flags, F_STARTSKILL, SK_SPEECH, PR_SKILLED, NA, NULL); // learnable skills @@ -413,7 +418,7 @@ void initjobs(void) { // abilities addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_PIRATE, "Pirate"); + addjob(J_PIRATE, "Pirate", "Pirates roam the seven seas, their mug of ale in one hand, and... nothing much in the other, since all pirates (in deference to some kind of ancient tale) have had their left hand replaced with a sharp hook. Their lifestyle had made them very wealthy and given them an impressive ability to handle their alcohol. They even start with a pet hawk. On the other hand, they are missing an eye, and not very attractive."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 3, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 2, NA, NULL); @@ -458,7 +463,7 @@ void initjobs(void) { // also: has a hook instead of fists. addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_ROGUE, "Rogue"); + addjob(J_ROGUE, "Rogue", "Rogues (sometimes known as \"thieves\") are criminals who are skilled in the appropriation of valuable goods. They can hide in the shadows, stab unsuspecting victims in the back and foil the most cunning traps."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_STR, -3, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 4, NA, NULL); @@ -502,7 +507,7 @@ void initjobs(void) { // abilities addflag(lastjob->flags, F_MPDICE, 1, NA, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_WARRIOR, "Warrior"); + addjob(J_WARRIOR, "Warrior", "Warriors are good at hitting things, hard."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_STR, 2, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_AGI, 2, NA, NULL); @@ -555,7 +560,7 @@ void initjobs(void) { addflag(lastjob->flags, F_LEVABIL, 10, OT_A_HURRICANESTRIKE, NA, NULL); addflag(lastjob->flags, F_HIRABLE, B_TRUE, NA, NA, NULL); - addjob(J_WIZARD, "Wizard"); + addjob(J_WIZARD, "Wizard", "Wizards specialise in Arcane lore, using their magic to create awe-inspiring effects on the world around them."); // stats addflag(lastjob->flags, F_JOBATTRMOD, A_STR, -4, NA, NULL); addflag(lastjob->flags, F_JOBATTRMOD, A_IQ, 4, NA, NULL); @@ -613,7 +618,7 @@ void initjobs(void) { addflag(lastjob->flags, F_CASTCHANCE, 30, NA, NA, NULL); // non-player jobs - addjob(J_SHOPKEEPER, "Shopkeeper"); + addjob(J_SHOPKEEPER, "Shopkeeper", "Shopkeepers make a living by selling goods to others. Always wary of thieves, most of them keep a shotgun under the counter."); addflag(lastjob->flags, F_NOPLAYER, B_TRUE, NA, NA, NULL); addflag(lastjob->flags, F_STARTATT, A_IQ, AT_AVERAGE, NA, NULL); addflag(lastjob->flags, F_STARTOB, 100, NA, NA, "100-1000 gold coins"); @@ -1783,6 +1788,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); addot(OT_S_ACCELMETAL, "accelerate metal", "Greatly accelerates a metal object thrown by the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -1800,6 +1806,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ALLOMANCY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_MAGSHIELD, "magnetic shield", "Surrounds the caster with magnetic force, repelling metal objects and attacks.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines how long the magnetic shield will last."); @@ -1821,6 +1828,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l2 @@ -1830,12 +1838,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_COMMANDUNDEAD, "command undead", "Compels an undead creature to follow a single simple command.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_FEAR, "cause fear", "Causes intense fear in the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability and duration."); @@ -1843,12 +1853,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_SMITEGOOD, "smite good", "Instantly deals 1-^bpower*2^n damage to good creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l3 @@ -1857,12 +1869,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addot(OT_S_DRAINLIFE, "drain life", "Draws life force from the victim in order to heal the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The amount of life force drained is ^b1d6+power^n."); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addot(OT_S_PAIN, "pain", "Causes extreme pain in the target whenever they move.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -1870,6 +1884,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l4 @@ -1878,12 +1893,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_PARALYZE, "paralyze", "Disables the target's muscles, leaving them unable to move for ^bpower*2^n turns.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l5 @@ -1899,6 +1916,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l6 @@ -1906,6 +1924,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines its resistability."); addflag(lastot->flags, F_SPELLSCHOOL, SS_DEATH, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_INFINITEDEATH, "infinite death", "Annihilates all nearby life, including the caster!", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); @@ -2014,6 +2033,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines its range and the weight of objects affected."); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); addot(OT_S_JOLT, "jolt", "Jolts an adjacent enemy with a short pulse of electricity, dealing 1-^bpower^n damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2021,6 +2041,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 6, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); @@ -2031,6 +2052,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); @@ -2039,6 +2061,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); @@ -2070,12 +2093,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // l5 addot(OT_S_CHAINLIGHTNING, "chain lightning", "Electricity arcs up to 5 times between all nearby enemies. The initial arc deals 3d6 damage, the next deals 3d5 damage, etc.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is based on its power."); addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); /////////////////// @@ -2085,6 +2110,7 @@ void initobjects(void) { addot(OT_S_SPARK, "spark", "Creates a tiny spark of flame, dealing 1-3 fire damage to creatures and objects.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT|TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); @@ -2095,12 +2121,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_FIREDART, "flame dart", "Fires a medium-sized dart of fire, dealing 1d6+^bpower^n fire damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l3 addot(OT_S_FLAMEBURST, "flame burst", "Creates a radial blast of fire out from the caster, inflicting 2d6 fire damage to all within.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2114,6 +2142,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); // l5 @@ -2122,6 +2151,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); @@ -2129,6 +2159,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The damage is lower for enemies further away from the ball's centre."); addflag(lastot->flags, F_SPELLSCHOOL, SS_FIRE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // TODO: should be "near victim" addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); /////////////////// @@ -2139,17 +2170,20 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_GLACIATE, "glaciate", "Slows down molecules in a given area, instantly freezing any water present. Has no effect on living creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_SNOWBALL, "snowball", "Throws a large snowball, dealing 1 cold damage to all within its blast. The remaining snow will quickly melt to water.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); // l2 @@ -2163,6 +2197,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_CRYSTALSHIELD, "crystalline shield", "Summons a shield of ice crystals to protect you from missiles.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2178,6 +2213,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); addot(OT_S_COLDBURST, "cold burst", "Creates a radial blast of coldness out from the caster, dealing 1d8+3 cold damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2190,6 +2226,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_SLIDE, "slipslide", "Generate ice underneath your feet, allowing you to slide along the ground at high speeds.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2204,11 +2241,13 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_WALLOFICE, "wall of ice", "Creates an impassable wall of solid ice.", MT_ICE, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the wall will remain."); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); @@ -2225,12 +2264,14 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's range is determined by its power."); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_WALLSTOP, NA, NULL); addot(OT_S_SNAPFREEZE, "snap freeze", "Instantly freezes the target creature. Cold-resistant creatures will take minor damage instead.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_RANGE, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l6 @@ -2273,6 +2314,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how the maximum hit dice creature which can be affected."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_LESSENPOISON, "lessen poison", "Reduces the effects of poison within the caster's bloodstream.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2280,6 +2322,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_REPELINSECTS, "repel insects", "Surrounds the caster with an insect-repelling smell.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); @@ -2290,6 +2333,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how much mud will be created."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_NONE, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_SUMMONANIMALSSM, "summon small animals", "Summons 2-3 small animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2302,6 +2346,7 @@ void initobjects(void) { addot(OT_S_WARPWOOD, "warp wood", "Causes damage to all wooden object in the target area.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); @@ -2311,6 +2356,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_LIGHTNINGBOLT, "electricity bolt", "Fires a bolt of electricity through multiple enemies, dealing 2d6 damage to each.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2318,6 +2364,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_AIR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); addot(OT_S_ENDUREELEMENTS, "endure elements", "Provides resistance to fire and cold.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2327,22 +2374,26 @@ void initobjects(void) { addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_QUENCH, "quench", "Extinguishes all fires within the given area.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_EVAPORATE, "evaporate", "Instantly converts all water in the given area into steam.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the amount of water affected."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_SLEETSTORM, "sleet storm", "Creates an cloud of sleet, hampering vision and movement.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the size of the storm."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "This spell's power is boosted when cast outside."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 4, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); @@ -2357,6 +2408,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how much webbing is created."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_NEED, NA, NULL); @@ -2372,6 +2424,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_CALMINGSCENT, "calming scent", "Automatically calms any nearby animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); @@ -2382,6 +2435,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addot(OT_S_SUMMONANIMALSMD, "summon medium animals", "Summons 2-3 medium animals.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long the summoned creatures will remain."); @@ -2394,6 +2448,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how far enemies are knocked back."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l5 @@ -2409,6 +2464,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_COLD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); @@ -2431,6 +2487,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the amount of water which appears."); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); /////////////////// // gravity @@ -2441,6 +2498,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_PLAYER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_VARPOWER, B_TRUE, NA, NA, NULL); // l2 @@ -2455,6 +2513,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addot(OT_S_FORCESPHERE, "force sphere", "Radiates a shock wave out from the caster, knocking opponents away.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2467,6 +2526,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long its effects will last."); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addot(OT_S_LEVITATION, "levitation", "Causes the caster hover a metre above the ground.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); @@ -2488,6 +2548,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines how long its effects will last."); addflag(lastot->flags, F_SPELLSCHOOL, SS_GRAVITY, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); /////////////////// @@ -2499,6 +2560,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_TURNUNDEAD, "turn undead", "Instills fear in undead creatures.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2514,6 +2576,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l3 @@ -2522,6 +2585,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_HOLYAURA, "holy aura", "Surrounds the target with a holy aura, causing their weapon to deal holy damage.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2537,6 +2601,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_LIFE, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_SELF, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_CUREPOISON, "cure poison", "Cures the target of all poisons.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2544,6 +2609,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_NATURE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); /////////////////// // mental/psionic @@ -2552,10 +2618,12 @@ void initobjects(void) { addot(OT_S_MINDSCAN, "mind scan", "Reveals detailed information about the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_ALLY, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_STUN, "stun", "Stuns the target, preventing them from taking agressive action for a few seconds.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); // l2 @@ -2564,6 +2632,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 10, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addot(OT_S_LOWERMETAB, "lower metabolism", "Slow your body's functions, decreasing your rate of hunger but also your movement speed.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power level III: your speed penalty is reduced."); @@ -2581,6 +2650,7 @@ void initobjects(void) { addot(OT_S_LETHARGY, "lethargy", "Reduces the target's stamina by ^bpower^n*2.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l3 @@ -2597,6 +2667,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_DONTNEED, NA, NULL); addot(OT_S_SLEEP, "sleep", "Puts the target creature to sleep.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2604,12 +2675,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_HUNGER, "hunger", "Causes the target to become ravenously hungry.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l4 @@ -2618,6 +2691,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_STUNMASS, "mass stun", "Stuns all creatures within sight.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); @@ -2630,6 +2704,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MENTAL, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SPECIAL, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); /////////////////// @@ -2639,6 +2714,7 @@ void initobjects(void) { addot(OT_S_HOLDPORTAL, "seal entrance", "Prevents a door from opening.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ENCHANTMENT, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_DOOR, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_INSCRIBE, "inscribe", "Creates a magical inscription viewable to anyone standing nearby.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2649,6 +2725,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_DOOR|TT_IMPASSABLE, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_LIGHT, "light area", "Creates a temporary light source centred on the caster.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At Power III, you can control where the light appears."); @@ -2675,6 +2752,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "The spell's power determines the size of the grease pool."); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); // l3 @@ -2705,11 +2783,13 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addot(OT_S_POLYMORPH, "polymorph", "Transmutes the target into a new living race.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power V, you can polymorph other creatures."); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power VIII, you can choose what kind of creature to polymorph into."); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_MODIFICATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_SELF, 10, NA, NULL); @@ -2755,6 +2835,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_OBJECT, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l2 addot(OT_S_BLINK, "blink", "Teleports the caster to a random location within view.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2768,12 +2849,14 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_WALLSTOP, NA, NULL); // l3 addot(OT_S_TWIDDLE, "twiddle", "Swaps places with the target creature.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 3, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); // l4 @@ -2782,6 +2865,7 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLLEVEL, 4, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_TELEPORT, "teleportation", "Teleports the caster (and Power-1 adjacent allies) to a new location within the same level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "At power V, you can choose the general direction to teleport in."); @@ -2794,6 +2878,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines resistability."); addflag(lastot->flags, F_SPELLSCHOOL, SS_TRANSLOCATION, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 5, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOFLEE, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); @@ -2817,12 +2902,14 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 1, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); // l2 addot(OT_S_ENERGYBOLT, "energy bolt", "Fires a medium-sized bolt of wild magic, dealing 1d4 damage per power level.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 2, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_MAXPOWER, 3, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_FALSE, LOF_NEED, NA, NULL); @@ -2848,6 +2935,7 @@ void initobjects(void) { addflag(lastot->flags, F_EXTRADESC, NA, NA, NA, "Spell power determines the size of the explosion."); addflag(lastot->flags, F_SPELLSCHOOL, SS_WILD, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER|TT_DOOR, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); @@ -2871,6 +2959,7 @@ void initobjects(void) { addot(OT_S_CONFISCATE, "confiscate", "Takes any object from the target.", MT_NOTHING, 0, OC_SPELL, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_DIVINE, NA, NA, NULL); addflag(lastot->flags, F_SPELLLEVEL, 6, NA, NA, NULL); + addflag(lastot->flags, F_TARGETTEDSPELL, TT_MONSTER, NA, NA, NULL); addflag(lastot->flags, F_AICASTTOATTACK, ST_VICTIM, NA, NA, NULL); addflag(lastot->flags, F_LOSLOF, B_TRUE, LOF_DONTNEED, NA, NULL); addot(OT_S_GIFT, "gift", "Grants the target any item of their choice (with some limitations).", MT_NOTHING, 0, OC_SPELL, SZ_TINY); @@ -2914,6 +3003,10 @@ void initobjects(void) { addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); addot(OT_A_FEIGNDEATH, "feign death", "Pretend to be dead.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addot(OT_A_FLIP, "flip", "Flip your opponent over your head.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); + addflag(lastot->flags, F_STAMCOST, 3, NA, NA, NULL); + addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); + addflag(lastot->flags, F_AICASTTOATTACK, ST_ADJVICTIM, NA, NA, NULL); addot(OT_A_FLURRY, "flurry", "Perform a flurry of attacks, forcing your opponent backwards.", MT_NOTHING, 0, OC_ABILITY, SZ_TINY); addflag(lastot->flags, F_STAMCOST, 3, NA, NA, NULL); addflag(lastot->flags, F_SPELLSCHOOL, SS_ABILITY, NA, NA, NULL); @@ -7959,10 +8052,6 @@ void initrace(void) { addflag(lastrace->flags, F_HITDICE, NA, NA, NA, "2d4+2"); addflag(lastrace->flags, F_HASATTACK, OT_TEETH, NA, NA, "1d3"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); @@ -7988,10 +8077,6 @@ void initrace(void) { addflag(lastrace->flags, F_HASATTACK, OT_CLAWS, NA, NA, "1d5"); addflag(lastrace->flags, F_MAXATTACKS, 1, 1, NA, NULL); addflag(lastrace->flags, F_EVASION, 10, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_WEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SECWEAPON, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_SHOULDERS, NA, NA, NULL); - addflag(lastrace->flags, F_NOBODYPART, BP_HANDS, NA, NA, NULL); addflag(lastrace->flags, F_NOSPELLS, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_CARNIVORE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_WANTSOBFLAG, F_EDIBLE, B_COVETS, NA, NULL); @@ -8085,7 +8170,7 @@ void initrace(void) { addflag(lastrace->flags, F_ATTACKRANGE, 1, 2, NA, NULL); // just buzz around addflag(lastrace->flags, F_MORALE, 0, NA, NA, NULL); addflag(lastrace->flags, F_AWARENESS, B_TRUE, NA, NA, NULL); - addrace(R_STIRGE, "stirge", 10, 'i', C_BROWN, MT_FLESH, RC_INSECT); + addrace(R_STIRGE, "mosquitoid", 10, 'i', C_BROWN, MT_FLESH, RC_INSECT); addflag(lastrace->flags, F_INSECT, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_HOSTILE, B_TRUE, NA, NA, NULL); addflag(lastrace->flags, F_STARTATT, A_IQ, IQ_ANIMAL, NA, NULL); diff --git a/data/hiscores.db b/data/hiscores.db index b7de0b40f752f359017b55d12173be55cb5849de..b5e393595d44567a96755d2a42239c478890bea0 100644 GIT binary patch delta 109 zcmV-z0FwWJK!8Ay8v%r|9OwrFSOQ3s2MDhM0!XoOkO2h*0{{V7vrP)O5fTRiuK)wh z1DXSG13m*30^$O%v2mFK2{Bj(009#zKVFkw6&o30AY);2aAkBLb8ca4WiBvR1^@yR PDLVl4lkOEAlL;U9U9%on delta 69 zcmV-L0J{HxK!8Ay8v%o{9OwrFR{~9w2MDjRahCzJO$xUW5C#I`00YefngeeGJ_8g2 b;<0hg0tzr!1^@yRDLVl4lkOEAlL;U9^}iKj diff --git a/defs.h b/defs.h index 868cce7..e493466 100644 --- a/defs.h +++ b/defs.h @@ -906,9 +906,9 @@ enum JOB { J_WARRIOR, J_COMMANDO, J_DRUID, + J_MECHANIC, J_MONK, J_PIRATE, - J_PLUMBER, J_PRINCE, J_ROGUE, J_SHOPKEEPER, @@ -1283,6 +1283,7 @@ enum OBTYPE { OT_A_DARKWALK, OT_A_DISARM, OT_A_FEIGNDEATH, + OT_A_FLIP, OT_A_FLURRY, OT_A_GRAB, OT_A_CHARGE, @@ -2178,6 +2179,8 @@ enum FLAG { F_FALLDISTANCE, // how many floors this lf has fallen through. // ABILITY/SPELL FLAGS / ability flags / spell flags F_FAILEDINSPECT, // lf has failed an inspect check for item id v0 + F_TARGETTEDSPELL, // this spell needs you to specify a target cell + // v0 is the tt_targettype F_BOOSTSPELL, // v0 is active boost spell, v1 is ongoing mpcost, v2 is power F_SWOOPRANGE, // v0 = how far a flying creature can swoop F_LOSLOF, // v0 = whether this spell needs line of sight @@ -3156,6 +3159,7 @@ typedef struct knowledge_s { typedef struct job_s { enum JOB id; char *name; + char *desc; flagpile_t *flags; struct job_s *next, *prev; } job_t; diff --git a/flag.c b/flag.c index 143584f..4fdd81a 100644 --- a/flag.c +++ b/flag.c @@ -425,6 +425,7 @@ int flagcausesstatredraw(lifeform_t *lf, enum FLAG fid) { case F_EATING: case F_FASTMOVE: case F_FLYING: + case F_GRAVBOOSTED: case F_HASNEWLEVEL: case F_HIDING: case F_ICESLIDE: diff --git a/io.c b/io.c index 9694218..6562ab9 100644 --- a/io.c +++ b/io.c @@ -7607,7 +7607,7 @@ void handleinput(void) { domsghist(); break; case '/': // explain object - doexplain("Select glyph to explain (ESC to cancel):"); + doexplain("Select glyph to explain (v for info, ESC to cancel):"); break; case '\\': // list knowledge doknowledgelist(); @@ -8629,7 +8629,7 @@ void showlfstats(lifeform_t *lf, int showall) { isplayer(lf) ? "" : "^WI^ntems " ); snprintf(cmdchars, BUFLEN, "@asme%s%s",isplayer(lf) ? "g" : "", isplayer(lf) ? "" : "i"); } else { - snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WE^nffects %s ESC=quit]", isplayer(lf) ? "" : "^WI^ntems "); + snprintf(promptstr, BUFLEN, "^h[^W@^n=stats ^WE^nffects %s ^WESC^n=quit]", isplayer(lf) ? "" : "^WI^ntems "); snprintf(cmdchars, BUFLEN, "@ie"); } @@ -9147,6 +9147,35 @@ void showlfstats(lifeform_t *lf, int showall) { // extra info from lore? if (lorelev >= PR_ADEPT) { + int hitstokillyou,hitstokillit; + hitstokillit = gethitstokill(player, lf); + hitstokillyou = gethitstokill(lf, player); + if (hitstokillit || hitstokillyou) { + if (hitstokillit == hitstokillyou) { + setcol(mainwin, lorecol); + mvwprintw(mainwin, y, 0, "You could both kill each other in %d hit%s.", hitstokillit, + (hitstokillit == 1) ? "" : "s"); + unsetcol(mainwin, lorecol); + y++; + } else { + if (hitstokillit) { + setcol(mainwin, lorecol); + mvwprintw(mainwin, y, 0, "You could kill it in %d hit%s.", hitstokillit, + (hitstokillit == 1) ? "" : "s"); + unsetcol(mainwin, lorecol); + y++; + } + if (hitstokillyou) { + setcol(mainwin, lorecol); + mvwprintw(mainwin, y, 0, "It could kill you in %d hit%s.", hitstokillyou, + (hitstokillyou == 1) ? "" : "s"); + unsetcol(mainwin, lorecol); + y++; + } + } + } + } + if (lorelev >= PR_SKILLED) { float rating; // get threat rating rating = comparelfs(player, lf); @@ -9308,8 +9337,7 @@ void showlfstats(lifeform_t *lf, int showall) { wrapprint(mainwin, &y, &x, "%s", buf); } - // missing body parts? - if (lfhasflagval(lf, F_NOBODYPART, BP_WEAPON, NA, NA, NULL)) { + if (!canuseweapons(lf)) { wrapprint(mainwin, &y, &x, "%s cannot use weapons.", you(lf)); } diff --git a/lf.c b/lf.c index 8d773d1..7ac2c23 100644 --- a/lf.c +++ b/lf.c @@ -995,6 +995,13 @@ int cansleep(lifeform_t *lf) { return B_TRUE; } +int canuseweapons(lifeform_t *lf) { + if (lfhasflag(lf, F_HUMANOID)) { + return B_TRUE; + } + return B_TRUE; +} + // where == BP_NONE means "can i wear it anywhere?' int canwear(lifeform_t *lf, object_t *o, enum BODYPART where) { int i; @@ -1137,7 +1144,7 @@ int canweild(lifeform_t *lf, object_t *o) { return B_TRUE; } - if (!lfhasflag(lf, F_HUMANOID)) { + if (!canuseweapons(lf)) { reason = E_IMPOSSIBLE; return B_FALSE; } @@ -1211,6 +1218,8 @@ int cantakeoff(lifeform_t *lf, object_t *o) { int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *targob, cell_t *targcell) { int rv; + int needtovalidate = B_FALSE; + int targettype; int cost; flag_t *f,*willflag; int power; @@ -1294,21 +1303,43 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar } } + // ask for target cell + if ((f = hasflag(sp->flags, F_TARGETTEDSPELL)) != NULL) { + targettype = f->val[0]; + needtovalidate = B_TRUE; + } else if (targcell) { + targettype = TT_NONE; + needtovalidate = B_TRUE; + } + + if (needtovalidate) { + if (!validatespellcell(lf, &targcell,targettype, sid, power, B_FALSE)) { + if (isplayer(lf)) msg("Cancelled."); + return B_TRUE; + } + } + + // stop hiding + killflagsofid(lf->flags, F_HIDING); // take time taketime(lf, getspellspeed(lf)); - // lose mp losemp(lf, cost); + // spell fails? // miscast chance? if (isplayer(lf) && !hasjob(lf, J_GOD)) { if (pctchance(getmiscastchance(lf))) { msg("^WYour cumbersome armour makes you miscast your spell!"); return B_FALSE; } - } - + } + // adjust power? + if (hasjob(lf, J_DRUID)) { + power += countplantsinsight(lf); + limit(&power, NA, 10); + } if (getmr(lf) && skillcheck(lf, SC_RESISTMAG, 20 + power, 0)) { if (power > 1) { // half strength @@ -1321,6 +1352,7 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar } } + // announce if (!isplayer(lf)) { if (cansee(player, lf)) { @@ -1361,15 +1393,6 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar } } - // boost power? - if (hasjob(lf, J_DRUID)) { - power += countplantsinsight(lf); - limit(&power, NA, 10); - } - - // stop hiding - killflagsofid(lf->flags, F_HIDING); - // willing this spell? reset counter! // do this _before_ casting the spell, // in case the spell causes us to lose @@ -1430,6 +1453,8 @@ int castspell(lifeform_t *lf, enum OBTYPE sid, lifeform_t *targlf, object_t *tar // successful cast? if (!rv) { + // TODO: charge mp + practice(lf, SK_SPELLCASTING, 1); if (isplayer(lf)) { switch (getschool(sid)) { @@ -1658,7 +1683,7 @@ int check_rest_ok(lifeform_t *lf) { float comparelfs(lifeform_t *lf1, lifeform_t *lf2) { float avgdam[2]; lifeform_t *lf[2]; - float turnstokill[2]; + float avgturnstokill[2]; int i; float ratio; lf[0] = lf1; @@ -1672,15 +1697,14 @@ float comparelfs(lifeform_t *lf1, lifeform_t *lf2) { avgdam[i] -= pctof(otherevasion, avgdam[i]); // divide other lf's hit points by this lf's avg dam if (avgdam[i] == 0) { - turnstokill[1-i] = 9999; + avgturnstokill[1-i] = 9999; } else { - turnstokill[1-i] = (float)lf[1-i]->hp / avgdam[i]; + avgturnstokill[1-i] = (float)lf[1-i]->hp / avgdam[i]; } } - // compare turnstokill values - ratio = (turnstokill[0] / turnstokill[1]); - + // compare avgturnstokill values + ratio = (avgturnstokill[0] / avgturnstokill[1]); return ratio; } @@ -5158,6 +5182,23 @@ int gethitdicerace(race_t *r) { return 1; } +int gethitstokill(lifeform_t *lf, lifeform_t *victim) { + object_t *wep[MAXCANDIDATES]; + flag_t *damflag[MAXCANDIDATES]; + obpile_t *op = NULL; + int nweps = 0,hitstokill = 0; + getweapons(lf, wep, damflag, NULL, &op, &nweps); + if (nweps) { + int maxdam; + getdamrange(damflag[0], NULL, &maxdam); + hitstokill = victim->hp / maxdam; + limit(&hitstokill, 1, NA); + } + if (op) killobpile(op); + return hitstokill; +} + + int gethppct(lifeform_t *lf) { float pct; pct = (int)(((float)lf->hp / (float)lf->maxhp) * 100); @@ -5896,15 +5937,19 @@ int getmovespeed(lifeform_t *lf) { } else if ((f->id == F_FASTMOVE) || (f->id == F_FASTACTMOVE)) { speed -= f->val[0]; } else if (f->id == F_INJURY) { - switch (f->val[0]) { - case IJ_LEGBROKEN: - case IJ_HAMSTRUNG: - speed += 10; break; - case IJ_LEGBRUISE: - speed += 5; break; + if (!isairborne(lf)) { + switch (f->val[0]) { + case IJ_LEGBROKEN: + case IJ_HAMSTRUNG: + speed += 10; break; + case IJ_LEGBRUISE: + speed += 5; break; + } } } else if (f->id == F_SPRINTING) { - speed -= 10; + if (!isairborne(lf)) { + speed -= 10; + } } } @@ -6969,7 +7014,6 @@ int getturnspeed(lifeform_t *lf) { return speed; } - void getwantdistance(lifeform_t *lf, lifeform_t *victim, int *min, int *max, int attacking) { flag_t *f; // default - run into them @@ -7020,6 +7064,59 @@ object_t *getweapon(lifeform_t *lf) { return NULL; } +// this function MIGHT allocat op! +int getweapons(lifeform_t *lf, object_t **wep, flag_t **damflag, int *lastweaponidx, obpile_t **op, int *nweps) { + int gotweapon = B_FALSE; + flag_t *retflag[MAXCANDIDATES],*f; + int nretflags,i; + // first use our weapon... + *nweps = 0; + wep[*nweps] = getweapon(lf); + if (wep[*nweps]) { + if (damflag) damflag[*nweps] = hasflag(wep[*nweps]->flags, F_DAM); + if (lastweaponidx) *lastweaponidx = 0; + (*nweps)++; + gotweapon = B_TRUE; + } + + // if we are skilled at twoweaponing, we can attack with our second weapon + // as well, with a possible accuracy penalty depending on our skill level. + if (getskill(lf, SK_TWOWEAPON)) { + wep[*nweps] = getsecmeleeweapon(lf); + if (wep[*nweps]) { + if ((*nweps >= 1) && (wep[*nweps] == wep[(*nweps)-1])) { + // can't be the same as first one + } else { + if (damflag) damflag[*nweps] = hasflag(wep[*nweps]->flags, F_DAM); + if (lastweaponidx) *lastweaponidx = *nweps; + (*nweps)++; + gotweapon = B_TRUE; + } + } + } + + // then use all our innate attacks.. + getflags(lf->flags, retflag, &nretflags, F_HASATTACK, F_NONE); + for (i = 0; i < nretflags; i++) { + f = retflag[i]; + if (f->id == F_HASATTACK) { + objecttype_t *ot; + + if (!(*op)) { + *op = addobpile(NULL, NULL, NULL); + } + + ot = findot(f->val[0]); + if (ot) { + wep[*nweps] = addobfast(*op, ot->id); + if (damflag) damflag[*nweps] = f; + (*nweps)++; + } + } + } + return gotweapon; +} + enum SKILLLEVEL getweaponskill(lifeform_t *lf, object_t *o) { skill_t *sk; sk = getobskill(o); @@ -9105,7 +9202,7 @@ object_t *isstuck(lifeform_t *lf) { return NULL; } -job_t *addjob(enum JOB id, char *name) { +job_t *addjob(enum JOB id, char *name, char *desc) { job_t *a; // add to the end of the list @@ -9126,6 +9223,7 @@ job_t *addjob(enum JOB id, char *name) { // props a->id = id; a->name = strdup(name); + a->desc = strdup(desc); a->flags = addflagpile(NULL, NULL); return a; @@ -14670,6 +14768,21 @@ int useability(lifeform_t *lf, enum OBTYPE aid, lifeform_t *who, cell_t *where) cwflag = lfhasflagval(lf, F_CANWILL, aid, NA, NA, NULL); rv = abilityeffects(lf, aid, where, who, cwflag); + + if (!rv) { + objecttype_t *ot; + flag_t *f; + int stamcost = 0; + // success - charge stamina + ot = findot(aid); + f = hasflag(ot->flags, F_STAMCOST); + if (f) stamcost = f->val[0]; + if (stamcost) { + modstamina(lf, -stamcost); + } + + } + return rv; } @@ -15497,14 +15610,20 @@ int wear(lifeform_t *lf, object_t *o) { inway = getequippedob(lf->pack, f->val[0]); getobname(inway,buf, 1); if (isplayer(lf)) { - int ch; + int ch = '\0'; char buf2[BUFLEN]; if (inway->blessknown && iscursed(inway)) { msg("You cannot remove your %s.", noprefix(buf)); } else { // take offending item off first - this takes extra time. snprintf(buf2, BUFLEN, "Remove your %s",noprefix(buf)); - ch = askchar(buf2, "yn","y", B_TRUE); + while (!ch) { + ch = askchar(buf2, "yn?","y", B_TRUE); + if (ch == '?') { + describeob(o); + ch = '\0'; + } + } if (ch == 'y') { if (isarmour(inway)) { if (!takeoff(player, inway)) { @@ -15774,7 +15893,7 @@ int weild(lifeform_t *lf, object_t *o) { if (isarmour(oo)) { char inwayname[BUFLEN]; char buf2[BUFLEN]; - char ch; + char ch = '\0'; if (isplayer(lf)) { if (oo->blessknown && iscursed(oo)) { msg("You cannot remove your %s.", noprefix(inwayname)); @@ -15783,7 +15902,13 @@ int weild(lifeform_t *lf, object_t *o) { getobname(oo, inwayname, oo->amt); // prompt before taking it off. snprintf(buf2, BUFLEN, "Remove your %s",noprefix(inwayname)); - ch = askchar(buf2, "yn","y", B_TRUE); + while (!ch) { + ch = askchar(buf2, "yn?","y", B_TRUE); + if (ch == '?') { + describeob(o); + ch = '\0'; + } + } } } else { ch = 'y'; diff --git a/lf.h b/lf.h index 57c9770..311b053 100644 --- a/lf.h +++ b/lf.h @@ -2,7 +2,7 @@ lifeform_t *addlf(cell_t *cell, enum RACE rid, int level); lifeform_t *real_addlf(cell_t *cell, enum RACE rid, int level, int controller); -job_t *addjob(enum JOB id, char *name); +job_t *addjob(enum JOB id, char *name, char *desc); race_t *addrace(enum RACE id, char *name, float weight, char glyph, int glyphcolour, enum MATERIAL mat, enum RACECLASS raceclass); raceclass_t *addraceclass(enum RACECLASS id, char *name, char *pluralname, enum SKILL skill); skill_t *addskill(enum SKILL id, char *name, char *desc, int traintime); @@ -42,6 +42,7 @@ int canquaff(lifeform_t *lf, object_t *o); int cansee(lifeform_t *viewer, lifeform_t *viewee); int cansee_real(lifeform_t *viewer, lifeform_t *viewee, int uselos); int cansleep(lifeform_t *lf); +int canuseweapons(lifeform_t *lf); int canwear(lifeform_t *lf, object_t *o, enum BODYPART where); int canweild(lifeform_t *lf, object_t *o); int cantakeoff(lifeform_t *lf, object_t *o); @@ -135,6 +136,7 @@ int gethearingrange(lifeform_t *lf); int gethidemodifier(lifeform_t *lf); int gethitdice(lifeform_t *lf); int gethitdicerace(race_t *r); +int gethitstokill(lifeform_t *lf, lifeform_t *victim); int gethppct(lifeform_t *lf); enum COLOUR gethungercol(enum HUNGER hlev); enum HUNGER gethungerlevel(int hunger); @@ -218,6 +220,7 @@ int getthrowspeed(int str); int getturnspeed(lifeform_t *lf); void getwantdistance(lifeform_t *lf, lifeform_t *victim, int *min, int *max, int attacking); object_t *getweapon(lifeform_t *lf); +int getweapons(lifeform_t *lf, object_t **wep, flag_t **damflag, int *lastweaponidx, obpile_t **op, int *nweps); enum SKILLLEVEL getweaponskill(lifeform_t *lf, object_t *o); long getxpforlev(int level); void givejob(lifeform_t *lf, enum JOB jobid); diff --git a/map.c b/map.c index 4debc10..37996e4 100644 --- a/map.c +++ b/map.c @@ -3794,7 +3794,7 @@ void explodecells(cell_t *c, int dam, int killwalls, object_t *o, int range, int } // move away from centre of explosion - knockback(cc->lf, getdiraway(cc, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 2, NULL, 40-(mydist*10)); + knockback(cc->lf, getdiraway(cc, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 2, NULL, 40-(mydist*10), B_TRUE); } } } diff --git a/move.c b/move.c index 5a9765c..26c846f 100644 --- a/move.c +++ b/move.c @@ -706,7 +706,7 @@ int getwalkoffdir(lifeform_t *lf, int dir) { } // use 'n/a' for zero chance of falling. 0 means 'calculate based on distance' -int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff) { +int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff, int wantannounce) { int i,dam; char lfname[BUFLEN]; char newlfname[BUFLEN]; @@ -748,7 +748,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc for (i = 0; i < howfar; i++) { if (moveclear(lf, dir, &reason)) { - if ((i == 0) && seen) { + if ((i == 0) && seen && wantannounce) { msg("%s %s knocked backwards!",lfname,is(lf)); } trymove(lf, dir, B_FALSE, B_FALSE); @@ -805,7 +805,7 @@ int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallc fallcheckdiff += (momentumleft*5); } // confer our remaining momentum on to them - knockback(newcell->lf, dir, momentumleft, lf, fallcheckdiff); // NOTE: recursive call + knockback(newcell->lf, dir, momentumleft, lf, fallcheckdiff, B_TRUE); // NOTE: recursive call } break; default: @@ -2600,28 +2600,45 @@ int trymove(lifeform_t *lf, int dir, int onpurpose, int strafe) { // failed? return B_TRUE; } - if (canswapwith(lf, cell->lf)) { - lifeform_t *lfinway; - // otherwise swap locations. - lfinway = cell->lf; - + // walking backwards/sideways into someone + if (!lfhasflag(lf, F_AWARENESS) && (getrelativedir(lf, dir) != RD_FORWARDS)) { + char lfname[BUFLEN]; + char inwayname[BUFLEN]; + getlfname(cell->lf, inwayname); if (isplayer(lf)) { - char lfname[BUFLEN]; - getlfname(lfinway, lfname); - msg("You swap places with %s.", lfname); - dontclearmsg = B_TRUE; + msg("You bump into %s.", inwayname); + } else if (isplayer(cell->lf)) { + getlfname(lf, lfname); + msg("%s bumps into you.", lfname); + } else if (cansee(player, lf)) { + getlfname(lf, lfname); + msg("%s bumps into %s.", lfname, inwayname); } - - swapplaces(lf, lfinway, B_FALSE, onpurpose); - if (onpurpose) taketime(lf, getmovespeed(lf)); - } else { - if (!onpurpose || canandwillmove(lf, dir, &errcode)) { - return attackcell(lf, cell, B_FALSE); + if (canswapwith(lf, cell->lf)) { + lifeform_t *lfinway; + // otherwise swap locations. + lfinway = cell->lf; + + if (isplayer(lf)) { + char lfname[BUFLEN]; + getlfname(lfinway, lfname); + msg("You swap places with %s.", lfname); + dontclearmsg = B_TRUE; + } + + swapplaces(lf, lfinway, B_FALSE, onpurpose); + + if (onpurpose) taketime(lf, getmovespeed(lf)); + } else { - // won't attack for some reason. - return B_TRUE; + if (!onpurpose || canandwillmove(lf, dir, &errcode)) { + return attackcell(lf, cell, B_FALSE); + } else { + // won't attack for some reason. + return B_TRUE; + } } } break; diff --git a/move.h b/move.h index a0ffa50..c0118bf 100644 --- a/move.h +++ b/move.h @@ -12,7 +12,7 @@ int dorandommove(lifeform_t *lf, int badmovesok, int restonfail); int getdiraway(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype, int keepinlof); int getdirtowards(cell_t *src, cell_t *dst, lifeform_t *srclf, int wantcheck, int dirtype); int getwalkoffdir(lifeform_t *lf, int dir); -int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff); +int knockback(lifeform_t *lf, int dir, int howfar, lifeform_t *pusher, int fallcheckdiff, int wantannounce); int makeorthogonal(int dir); int moveawayfrom(lifeform_t *lf, cell_t *dst, int dirtype, int keepinlof, int strafe); int moveclear(lifeform_t *lf, int dir, enum ERROR *error); diff --git a/nexus.c b/nexus.c index 93a615c..b2e891d 100644 --- a/nexus.c +++ b/nexus.c @@ -217,7 +217,7 @@ int main(int argc, char **argv) { ch = 'a'; for (j = firstjob ; j ; j = j->next) { if (!hasflag(j->flags, F_NOPLAYER)) { - addchoice(&prompt, ch++, j->name, NULL, j, NULL); + addchoice(&prompt, ch++, (j->id == J_GOD) ? "Diety (for debugging)" : j->name, NULL, j, j->desc); } } j = NULL; diff --git a/objects.c b/objects.c index ab7bc78..67f0611 100644 --- a/objects.c +++ b/objects.c @@ -9123,6 +9123,9 @@ int readsomething(lifeform_t *lf, object_t *o) { } } else if (o->type->id == OT_SCR_AWARENESS) { addtempflag(lf->flags, F_AWARENESS, B_TRUE, NA, NA, NULL, getspellduration(30,60,o->blessed)); + if (isplayer(lf)) msg("The scroll crumbles to dust."); + // removeob one of the object + removeob(o, 1); } else if (o->type->id == OT_SCR_NOTHING) { if (isplayer(lf)) { msg("The scroll crumbles to dust."); @@ -9866,8 +9869,8 @@ int real_takedamage(object_t *o, unsigned int howmuch, int damtype, int wantanno if (o->material->id == MT_GLASS) { char buf[BUFLEN]; char buf2[BUFLEN]; - getobname(o, buf2, 1); - snprintf(buf, BUFLEN, "a shattering %s", buf2); + real_getobname(o, buf2, 1, B_FALSE, B_FALSE, B_FALSE, B_FALSE, B_FALSE); + snprintf(buf, BUFLEN, "a shattering %s", noprefix(buf2)); shatter(o, B_TRUE, buf, B_FALSE); return howmuch; } @@ -10606,7 +10609,7 @@ int fireat(lifeform_t *thrower, object_t *o, int amt, cell_t *where, int speed, if ((getobunitweight(o)*amt) >= getlfweight(target, B_NOOBS)) { int dir; dir = getdirtowards(srcloc, target->cell, target, B_FALSE, DT_COMPASS); - knockback(target, dir, 1, thrower, 0); + knockback(target, dir, 1, thrower, 0, B_TRUE); } } diff --git a/spell.c b/spell.c index 6368c59..3e6c15d 100644 --- a/spell.c +++ b/spell.c @@ -30,6 +30,8 @@ extern prompt_t prompt; extern WINDOW *msgwin; +extern void *rdata; + extern job_t *firstjob; extern objecttype_t *objecttype; @@ -48,6 +50,8 @@ extern void (*precalclos)(lifeform_t *); extern int needredraw, statdirty; +// return value of FALSE means that stamina costs should be charged. +// TRUE is a cancellation - don't change stamina int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifeform_t *target, flag_t *cwflag) { char username[BUFLEN]; char killername[BUFLEN]; @@ -105,7 +109,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } return B_TRUE; } - modstamina(user, -stamcost); } @@ -475,6 +478,85 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } needredraw = B_TRUE; statdirty = B_TRUE; + } else if (abilid == OT_A_FLIP) { + // ask for direction + if (!targcell) { + char dirch; + dirch = askchar("Flip from which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + if (dirch == '.') { + if (isplayer(user)) msg("You can't flip yourself!"); + return B_TRUE; + } else { + int dir; + dir = chartodir(dirch); + if (dir == D_NONE) { + if (isplayer(user)) msg("Cancelled."); + return B_TRUE ; + } else { + targcell = getcellindir(user->cell, dir); + } + } + } + + target = targcell->lf; + if (!target) { + if (isplayer(user)) msg("There is nobody there to flip!"); + return B_TRUE; + } + getlfname(target, targetname); + + if (getlfsize(target) > getlfsize(user)) { + if (isplayer(user)) msg("%s is too large for you to flip.", targetname); + return B_TRUE; + } + + taketime(user, getactspeed(user)); + + + if (lfhasflag(target, F_NONCORPOREAL)) { + if (isplayer(user)) { + msg("You grab at %s%s insubstantial body.", targetname, getpossessive(targetname)); + } else if (cansee(player, user)) { + msg("%s grabs at %s%s insubstantial body.", + username, targetname, getpossessive(targetname)); + } + return B_FALSE; + } + + // victim gets a skilcheck to avoid being grabbed - hard. + if (skillcheck(target, SC_DODGE, getattr(user, A_AGI)+18, 0)) { + if (cansee(player, user)) { + msg("%s evade%s %s%s grasp.", targetname, isplayer(target) ? "" : "s", + username, getpossessive(username)); + } + } else { + int dir; + cell_t *c; + // free space behind the flipper? + dir = diropposite(user->facing); + c = getcellindir(user->cell, dir); + + if (c && cellwalkable(target, c, NULL)) { + int dist; + setfacing(user, dir); // turn player to face them + movelf(target, c); // move target behind player + // throw! + if (isplayer(user)) { + msg("You flip %s over your head!", targetname); + } else if (cansee(player, user)) { + msg("%s flips %s!", username, targetname); + } + dist = 2 + (getskill(user, SK_ATHLETICS)/3); + setfacing(target, getrandomdir(DT_COMPASS)); + knockback(target, dir, dist, user, 25, B_FALSE); + } else { + if (isplayer(user)) { + msg("There is no room to flip %s!", targetname); + } else if (cansee(player, user)) { + msg("%s tries to flip %s but fails.", username, targetname); + } + } + } } else if (abilid == OT_A_FLURRY) { int dir; int dirch; @@ -521,7 +603,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } // push them back - knockback(target, dir, 1, user, 5); + knockback(target, dir, 1, user, 5, B_TRUE); // if we succeeded in pushing them... if (target->cell != targcell) { @@ -580,7 +662,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef msg("%s grabs at %s%s insubstantial body.", username, targetname, getpossessive(targetname)); } - return B_TRUE; + return B_FALSE; } // victim gets a skilcheck to avoid being grabbed @@ -605,15 +687,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_TRUE; } - // shouldn't be able to happen! - /* - f = lfhasflag(user, F_GRABBING); - if (!f) { - if (isplayer(user)) msg("You need to hold someone before using this ability."); - return B_TRUE; - } - */ - // announce if (cansee(player, target)) { msg("%s squeeze%s %s tightly!", username, isplayer(user) ? "" : "s", targetname); @@ -907,7 +980,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // in case it's on fire, etc if (touch(user, o)) { taketime(user, getactspeed(user)); - return B_TRUE; + return B_FALSE; } // select cutoff hp @@ -1329,7 +1402,9 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else if (abilid == OT_A_TUMBLE) { cell_t *origcell,*c; cell_t *retcell[MAXRETCELLS]; - int i,nretcell = 0; + char stopthing[BUFLEN],verb[BUFLEN], stopverb[BUFLEN]; + int i,nretcell = 0,dir = D_NONE; + enum RELATIVEDIR reldir; object_t *stopob = NULL; if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { @@ -1340,36 +1415,55 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_TRUE; } - if (!targcell) { - snprintf(buf, BUFLEN, "Tumble where (max distance 2)?"); - while (!targcell) { - // ask where - targcell = askcoords(buf, "Tumble->", TT_NONE, user, 2, LOF_NEED, B_TRUE); - if (!targcell) { - if (isplayer(user)) msg("Cancelled."); + if (targcell) { + dir = getdirtowards(user->cell, targcell, NULL, B_FALSE, DT_ORTH); + } else { + char dirch; + dirch = askchar("Tumble in which direction (- to cancel)", "yuhjklbn.-","-", B_FALSE); + dir = chartodir(dirch); + if (dir == D_NONE) { + if (isplayer(user)) msg("Cancelled."); + return B_TRUE ; + } else { + cell_t *cell1 = NULL,*cell2 = NULL; + + cell1 = getcellindir(user->cell, dir); + if (cell1 && cellwalkable(user, cell1, NULL)) { + cell2 = getcellindir(cell1, dir); + } else { + if (isplayer(user)) msg("There is no room to tumble that way!"); return B_TRUE; - } else if (!haslos(user, targcell)) { - targcell = NULL; - if (isplayer(user)) { - snprintf(buf, BUFLEN, "You can't see where to land! Tumble where (max distance 2)?"); - } - } else if (!haslof(user->cell, targcell, LOF_NEED, NULL)) { - targcell = NULL; - if (isplayer(user)) { - snprintf(buf, BUFLEN, "You don't have a clear line of fire to there!"); - } } + + if (cell2) targcell = cell2; + else targcell = cell1; + + if (!targcell) { + if (isplayer(user)) msg("There is no room to tumble that way!"); + return B_TRUE; + } + } } + reldir = getrelativedir(user, dir); + switch (reldir) { + case RD_FORWARDS: + strcpy(verb, "tumble"); break; + case RD_BACKWARDS: + strcpy(verb, "backflip"); break; + case RD_SIDEWAYS: + strcpy(verb, "cartwheel"); break; + } + if (isburdened(user)) { if (isplayer(user)) { - msg("Your load is too heavy to tumble with!"); + msg("Your load is too heavy to %s with!", verb); } return B_TRUE; } else if (lfhasflag(user, F_GRAVBOOSTED)) { if (isplayer(user)) { - msg("Gravity around you is too strong to tumble!"); + msg("Gravity around you is too strong to %s!", verb); } return B_TRUE; } @@ -1380,6 +1474,8 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // will you be interrupted on the way? + strcpy(stopthing, ""); + strcpy(stopverb, ""); calcbresnham(origcell->map, origcell->x, origcell->y, targcell->x, targcell->y, retcell, &nretcell); for (i = 0; i < nretcell; i++) { c = retcell[i]; @@ -1387,12 +1483,53 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // stop here. targcell = c; stopob = hasobwithflag(c->obpile, F_DEEPWATER); + strcpy(stopverb, "fall"); + getobname(stopob, stopthing, stopob->amt); break; } else if (hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL)) { // stop here. targcell = c; stopob = hasobwithflagval(c->obpile, F_PIT, D_DOWN, NA, NA, NULL); + strcpy(stopverb, "fall"); + getobname(stopob, stopthing, stopob->amt); break; + } + + // run into a person, wall or impassable object? + if (i >= 1) { + enum ERROR why; + if (!cellwalkable(user, c, &why)) { + // stop in previous cell + strcpy(stopverb, "bump"); + targcell = retcell[i-1]; + if (haslos(user, c)) { + switch (why) { + case E_WALLINWAY: + strcpy(stopthing, c->type->name); + break; + case E_OBINWAY: + if (canseeob(user, (object_t *)rdata)) { + getobname((object_t *)rdata, stopthing, ((object_t *)rdata)->amt); + } else { + strcpy(stopthing, "something"); + } + break; + case E_LFINWAY: + if (cansee(user, (lifeform_t *)rdata)) { + getlfname((lifeform_t *)rdata, stopthing); + } else { + strcpy(stopthing, "someone"); + } + break; + default: + strcpy(stopthing, "something"); + break; + } + } else { + strcpy(stopthing, "something"); + } + break; + } } } @@ -1408,30 +1545,36 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef return B_FALSE; } - // announce if (isplayer(user)) { - msg("You tumble across the ground!"); + msg("You %s across the ground!", verb); } else if (cansee(player, user)) { - msg("%s tumbles across the ground!", username); + msg("%s %ss across the ground!", username, verb); } + + // rolling around will put out fires + if (reldir == RD_FORWARDS) { + extinguishlf(user); + } + // go there! movelf(user, targcell); // pits/water? - if (stopob) { - char obname[BUFLEN]; - getobname(stopob, obname, 1); + if (strlen(stopthing)) { if (isplayer(user)) { - msg("Your tumble is interrupted by %s!",obname); + msg("You %s into %s!", stopverb, stopthing); } else if (cansee(player, user)) { - msg("%s%s tumble is interrupted by %s!",username,getpossessive(username), obname); + msg("%s %ss into %s!",username, stopverb, stopthing); + } + + // pass another (harder) skill check or fall + if (!skillcheck(user, SC_TUMBLE, 20, 0)) { + // fail! + fall(user, NULL, B_TRUE); + return B_FALSE; } } - - // rolling around will put out fires - extinguishlf(user); - } else if (abilid == OT_A_POLYREVERT) { flag_t *f; if (!target) target = user; @@ -1442,7 +1585,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef f = lfhasflag(target, F_ORIGRACE); if (!f) { if (isplayer(user)) nothinghappens(); - return B_FALSE; + return B_TRUE; } // this call will also remove this ability... @@ -1499,7 +1642,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } else { msg("Cancelled."); } - return B_FALSE; } else if (abilid == OT_A_LEVELUP) { char buf[BUFLEN]; int lev; @@ -1523,7 +1665,6 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef } } msg("all blinded!"); - return B_FALSE; } else if (abilid == OT_A_AIMEDSTRIKE) { object_t *wep; char dirch; @@ -2026,7 +2167,7 @@ int abilityeffects(lifeform_t *user, enum OBTYPE abilid, cell_t *targcell, lifef // only players can do this if (!isplayer(user)) { - return B_TRUE; + return B_FALSE; } if (isswimming(user) && !lfhasflag(user, F_AQUATIC)) { if (isplayer(user)) msg("That wouldn't be a good idea while swimming."); @@ -2231,8 +2372,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_FALSE; } - - // switch based on spell effects... if (spellid == OT_S_ABSOLUTEZERO) { cell_t *retcell[MAXCANDIDATES]; @@ -2339,7 +2478,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ cell_t *nextc; if (targcell) { - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; dir = getdirtowards(caster->cell, targcell, target, B_FALSE, DT_COMPASS); } else { int dirch; @@ -2377,7 +2515,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (nextc->lf) { targcell = nextc; target = targcell->lf; - knockback(target, dir, power, caster, 0); + knockback(target, dir, power, caster, 0, B_TRUE); } else if (firstobcell) { // objects for (o = firstobcell->obpile->first ;o ; o = nexto) { @@ -2533,7 +2671,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = addtempflag(caster->flags, F_AWARENESS, B_TRUE, NA, NA, NULL, FROMSPELL); f->obfrom = spellid; } else if (spellid == OT_S_BAFFLE) { - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (lfhasflag(target, F_ASLEEP) || !ischarmable(target)) { @@ -2564,7 +2701,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_BLADEBURN) { object_t *wep; enum DAMTYPE dt; - if (!validatespellcell(caster, &targcell, TT_PLAYER | TT_ALLY, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -2592,8 +2728,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ addtempflag(wep->flags, F_ONFIRE, B_TRUE, NA, NA, "1d6", 10 + power*3); } else if (spellid == OT_S_BLINDNESS) { int failed = B_FALSE; - // ask for target - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (isblind(target)) { @@ -2665,8 +2799,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } teleportto(caster, targcell, B_TRUE); } else if (spellid == OT_S_BLINKASS) { - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (!target) { fizzle(caster); @@ -2699,8 +2831,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ cell_t *retcell[MAXRETCELLS]; int nretcell; int i; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - if (cansee(player, caster)) { msg("%s shoot%s a wave of fire!",castername, isplayer(caster) ? "" : "s"); } @@ -2814,9 +2944,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_CALLLIGHTNING) { int failed = B_FALSE; - // ask for a target cell - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (target) { char targname[BUFLEN]; @@ -2959,8 +3086,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int nsides = 6; range = getspellrange(caster, spellid, power); - - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; // create a line of fire towards the target cell animline(caster->cell, targcell, B_FALSE, '/', '\\', C_WHITE); @@ -3037,7 +3162,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // end while narccells } else if (spellid == OT_S_CLOUDKILL) { int radius; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (targcell->type->solid) { fizzle(caster); @@ -3053,7 +3177,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_CHARM) { char targetname[BUFLEN]; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; @@ -3121,7 +3244,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_CHARMANIMAL) { char targetname[BUFLEN]; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; @@ -3194,7 +3316,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_CHILL) { char lfname[BUFLEN]; int exposedlimbs,dam; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -3268,8 +3389,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char lfname[BUFLEN]; cell_t *retcell[MAXRETCELLS]; int nretcell,i; - - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; // animation anim(caster->cell, targcell, '}', C_GREY); if (isplayer(caster) || cansee(player, caster)) { @@ -3309,7 +3428,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); return B_TRUE; } - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target || !isundead(target)) { fizzle(caster); @@ -3536,7 +3654,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_FALSE; } } else if (spellid == OT_S_CUREPOISON) { - if (!validatespellcell(caster, &targcell,TT_ALLY, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -3699,7 +3816,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (isplayer(caster)) nothinghappens(); } } else if (spellid == OT_S_DISORIENT) { - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (lfhasflag(target, F_ASLEEP) || !ischarmable(target)) { @@ -3822,8 +3938,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // end if isplayer } else if (spellid == OT_S_DETONATE) { // don't need line of fire! - if (!validatespellcell(caster, &targcell, TT_MONSTER|TT_DOOR, spellid, power, frompot)) return B_TRUE; - explodecells(targcell, 20, B_TRUE, NULL, power / 4, DT_ORTH, B_TRUE); if (haslos(player, targcell)) { @@ -3835,7 +3949,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int nseen = 0; int nsteamseen = 0; // don't need line of fire! - if (!validatespellcell(caster, &targcell, TT_OBJECT, spellid, power, frompot)) return B_TRUE; getradiuscells(targcell, power, DT_ORTH, B_FALSE, LOF_NEED, B_TRUE, cell, &ncells, B_FALSE); for (i = 0; i < ncells; i++) { @@ -3873,8 +3986,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ float totalmass = 0; object_t *o, *nexto; - if (!validatespellcell(caster, &targcell, TT_OBJECT, spellid, power, frompot)) return B_TRUE; - // how much metal is there? for (o = targcell->obpile->first ; o ; o = nexto) { nexto = o->next; @@ -3904,7 +4015,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ object_t *o, *nexto; int donesomething = B_FALSE; - if (!validatespellcell(caster, &targcell,TT_MONSTER|TT_OBJECT, spellid, power, frompot)) return B_TRUE; if (!targcell) { if (isplayer(caster)) { fizzle(caster); @@ -3979,8 +4089,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ rv = B_FALSE; } else if (spellid == OT_S_DRAINLIFE) { char lfname[BUFLEN]; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = haslf(targcell); if (target) { getlfname(target, lfname); @@ -4057,7 +4165,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_FEAR) { char targname[BUFLEN]; // ask for target - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -4086,8 +4193,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ scare(target, caster, 5+rnd(1,power), 5+power); } } else if (spellid == OT_S_FEEBLEMIND) { - // ask for target - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if ((getattr(target, A_IQ) <= 3) || spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) { @@ -4152,8 +4257,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_FLOOD) { int failed = B_FALSE; - // ask for a target cell - if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power, frompot)) return B_TRUE; if (targcell) { if (!targcell->type->solid) { // create water there @@ -4222,7 +4325,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (retcell[i]->lf) { knockback(retcell[i]->lf, getdiraway(retcell[i], targcell, NULL, B_FALSE, DT_COMPASS, B_FALSE), - 2, target, 27+power); + 2, target, 27+power, B_TRUE); } } } @@ -4231,7 +4334,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char numbuf[BUFLEN]; numtotext(power, numbuf); - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; // animation anim(caster->cell, targcell, '}', C_CYAN); if (isplayer(caster) || cansee(player, caster)) { @@ -4259,8 +4361,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_FIREBALL) { int failed = B_FALSE; - // ask for a target cell - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (targcell) { if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) { int dir; @@ -4352,7 +4452,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_FIREDART) { char lfname[BUFLEN]; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; // animation anim(caster->cell, targcell, '}', C_RED); if (isplayer(caster) || cansee(player, caster)) { @@ -4411,8 +4510,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_FLAMEPILLAR) { int failed = B_FALSE; - // ask for a target cell - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (targcell) { if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) { flag_t *f; @@ -4523,8 +4620,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_ENDUREELEMENTS) { flag_t *f; - // always targetted at caster - if (!validatespellcell(caster, &targcell,TT_ALLY, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -4539,9 +4634,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char targname[BUFLEN]; flag_t *f; object_t *o; - - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (!target) { fizzle(caster); @@ -4691,7 +4783,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_FROSTBITE) { char lfname[BUFLEN]; int exposedlimbs,dam; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -4747,8 +4838,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_GLACIATE) { object_t *o,*nexto; int donesomething = B_FALSE; - if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, spellid, power, frompot)) return B_TRUE; - if (haslos(player, targcell)) { msg("A puff of vapour appears."); if (seenbyplayer) *seenbyplayer = B_TRUE; @@ -4761,8 +4850,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_GREASE) { int radius; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - if (targcell->type->solid) { fizzle(caster); return B_FALSE; @@ -4791,7 +4878,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ limit(&power, NA, 10); } // ask for a target cell - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (targcell) { if (!targcell->type->solid) { object_t *o; @@ -4841,8 +4927,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_HASTE) { int howlong = 15; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (!target) { @@ -4868,7 +4952,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int donesomething = B_FALSE,i; flag_t *retflag[MAXCANDIDATES]; int nretflags; - if (!validatespellcell(caster, &targcell,TT_ALLY, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -4985,7 +5068,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_HOLDPORTAL) { object_t *o; - if (!validatespellcell(caster, &targcell,TT_DOOR, spellid, power, frompot)) return B_TRUE; o = hasobwithflag(targcell->obpile, F_DOOR); if (!o) { @@ -5003,8 +5085,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (seenbyplayer) *seenbyplayer = B_TRUE; } } else if (spellid == OT_S_HUNGER) { - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (!target) { fizzle(caster); @@ -5038,7 +5118,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ object_t *wep; enum DAMTYPE dt; char obname[BUFLEN]; - if (!validatespellcell(caster, &targcell, TT_PLAYER | TT_ALLY, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -5075,8 +5154,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ object_t *o; int donesomething = B_FALSE; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - // create icicle o = addob(targcell->obpile, "huge icicle"); if (o) { @@ -5098,7 +5175,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ // knock lfs away if (targcell->lf) { - knockback(targcell->lf, getdiraway(targcell, targcell, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 25+power); + knockback(targcell->lf, getdiraway(targcell, targcell, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 25+power, B_TRUE); donesomething = B_TRUE; } @@ -5191,7 +5268,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char numbuf[BUFLEN]; numtotext(power, numbuf); - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; // animation anim(caster->cell, targcell, '}', C_CYAN); if (isplayer(caster) || cansee(player, caster)) { @@ -5349,8 +5425,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_MINDSCAN) { int failed = B_FALSE; if (isplayer(caster)) { - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - if (targcell && haslos(caster, targcell) && haslf(targcell)) { char targname[BUFLEN]; lifeform_t *oldplayer; @@ -5454,7 +5528,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_PARALYZE) { int howlong; int saved = B_FALSE; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (lfhasflag(target, F_PARALYZED)) { @@ -5488,8 +5561,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_PAIN) { int failed = B_FALSE; - // ask for target - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (lfhasflag(target, F_PAIN)) { @@ -5524,7 +5595,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); } } else if (spellid == OT_S_PETRIFY) { - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; // some thigns can't be stoned @@ -5554,7 +5624,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ addflag(target->flags, F_BEINGSTONED, 2, NA, NA, NULL); } else if (spellid == OT_S_POISONBOLT) { char lfname[BUFLEN]; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; // animation anim(caster->cell, targcell, '}', C_GREEN); @@ -5581,7 +5650,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_POSSESSION) { char targname[BUFLEN]; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { @@ -5697,7 +5765,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f->obfrom = spellid; } else if (spellid == OT_S_PULLMETAL) { int donesomething = B_FALSE; - if (!validatespellcell(caster, &targcell,TT_OBJECT, spellid, power, frompot)) return B_TRUE; if (targcell->lf) { object_t *o; @@ -5942,8 +6009,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ if (seenbyplayer) *seenbyplayer = B_TRUE; } } else if (spellid == OT_S_JOLT) { - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = haslf(targcell); if (target) { int dam; @@ -5962,15 +6027,13 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_KNOCK) { object_t *o; - if (!validatespellcell(caster, &targcell,TT_DOOR|TT_IMPASSABLE, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; // high powered knock can knock back monsters if (target && (power >= 7)) { int dir; dir = getdirtowards(caster->cell, targcell, target, B_FALSE, DT_COMPASS); - knockback(target, dir, 2, caster, 0); + knockback(target, dir, 2, caster, 0, B_TRUE); } else { int donesomething = B_FALSE; object_t *nexto; @@ -6089,8 +6152,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int nretcells; int i; int nhits = power; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - // create a line of fire towards the target cell calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcells); animcells(caster->cell, &retcell[1], nretcells-1, B_FALSE, '/', '\\', C_WHITE); @@ -6290,8 +6351,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ return B_FALSE; } } else if (spellid == OT_S_GRAVBOOST) { - // ask for target - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (target) { int howlong = 15; @@ -6358,9 +6417,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int i; char targname[BUFLEN]; - - if (!validatespellcell(caster, &targcell, TT_MONSTER|TT_OBJECT, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (isoutdoors(targcell->map)) { @@ -6529,8 +6585,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_PACIFY) { char targetname[BUFLEN]; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (!target) { @@ -6578,8 +6632,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ breakgrabs(target, B_TRUE, B_TRUE); } else if (spellid == OT_S_POLYMORPH) { race_t *r = NULL; - - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { @@ -6753,9 +6805,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_QUENCH) { object_t *o,*nexto; int ndone = 0; - - if (!validatespellcell(caster, &targcell,TT_OBJECT, spellid, power, frompot)) return B_TRUE; - if (!targcell) { fizzle(caster); } @@ -6809,7 +6858,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_LESSENPOISON) { flag_t *f; int ndone = 0; - if (!validatespellcell(caster, &targcell,TT_ALLY, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -6840,7 +6888,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_LETHARGY) { int amttolose; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -6930,7 +6977,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_SATEHUNGER) { int hunger; - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { @@ -6964,8 +7010,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int nretcells; int i; int nhits = power; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; - // create a line of fire towards the target cell calcbresnham(caster->cell->map, caster->cell->x, caster->cell->y, targcell->x, targcell->y, retcell, &nretcells); animcells(caster->cell, &retcell[1], nretcells-1, B_FALSE, '*', '\0', C_WHITE); @@ -6989,8 +7033,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_SHATTER) { char buf[BUFLEN]; - if (!validatespellcell(caster, &targcell,TT_NONE, spellid, power, frompot)) return B_TRUE; - snprintf(buf, BUFLEN, "%s%s shatter spell", castername, getpossessive(castername)); if (!shattercell(targcell, caster, buf)) { fizzle(caster); @@ -7001,7 +7043,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_SLEEP) { int howlong; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (lfhasflag(target, F_ASLEEP) || !cansleep(target)) { @@ -7044,8 +7085,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ power += 3; limit(&power, NA, 10); } - // ask for a target cell - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (targcell) { if (!targcell->type->solid) { int radius; @@ -7085,7 +7124,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_SLOW) { int howlong = 15; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) { @@ -7112,7 +7150,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else { wantalign = AL_GOOD; } - if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target || (getalignment(target) != wantalign)) { fizzle(caster); @@ -7129,7 +7166,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ // due to vulnerabilities losehp(target, rnd(1,power*2), DT_DIRECT, caster, "a smiting"); } else if (spellid == OT_S_SNAPFREEZE) { - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = haslf(targcell); if (target) { if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) { @@ -7147,7 +7183,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_SNOWBALL) { int failed = B_FALSE; // ask for a target cell - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (targcell) { if (!targcell->type->solid || hasflag(targcell->type->material->flags, F_FLAMMABLE)) { int dir; @@ -7206,7 +7241,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int ndone = 0; int powerleft = power; // ask for a target cell - if (!validatespellcell(caster, &targcell, TT_NONE, spellid, power, frompot)) return B_TRUE; if (targcell) { object_t *o; enum OBTYPE badoid[2]; @@ -7247,7 +7281,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } else if (spellid == OT_S_SPARK) { object_t *o,*nexto; int donesomething = B_FALSE; - if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, spellid, power, frompot)) return B_TRUE; if (haslos(player, targcell)) { if (targcell->lf && cansee(player, targcell->lf)) { @@ -7321,7 +7354,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } else if (spellid == OT_S_STENCH) { int howlong; - if (!validatespellcell(caster, &targcell,TT_OBJECT | TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { @@ -7477,7 +7509,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); } } else if (spellid == OT_S_STUN) { - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (lfhasflag(target, F_ASLEEP) || !ischarmable(target)) { @@ -7523,8 +7554,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); } } else if (spellid == OT_S_SUCK) { - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - target = targcell->lf; if (target) { @@ -7862,7 +7891,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ f = addtempflag(target->flags, F_RETALIATE, 1, 4, DT_PIERCE, "sharp thorns", FROMSPELL); f->obfrom = spellid; } else if (spellid == OT_S_TRUESTRIKE) { - if (!validatespellcell(caster, &targcell, TT_PLAYER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target) { fizzle(caster); @@ -7893,7 +7921,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } } } else if (spellid == OT_S_TWIDDLE) { - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (!target || (target == caster)) { @@ -8030,10 +8057,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int walldir; int seen = B_FALSE; flag_t *f; - - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; - - // get vert distance for (c = targcell ; c->lf || (cellwalkable(NULL, c, NULL)); c = getcellindir(c, D_N)) { vdist++; @@ -8079,7 +8102,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // knock lfs away if (c->lf) { - knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power); + knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power, B_TRUE); donesomething = B_TRUE; } } @@ -8095,7 +8118,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // knock lfs away if (c->lf) { - knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power); + knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power, B_TRUE); donesomething = B_TRUE; } } @@ -8111,7 +8134,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // knock lfs away if (c->lf) { - knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power); + knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power, B_TRUE); donesomething = B_TRUE; } } @@ -8127,7 +8150,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ } // knock lfs away if (c->lf) { - knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power); + knockback(c->lf, getdiraway(c, c, NULL, B_FALSE, DT_COMPASS, B_FALSE), 1, NULL, 30+power, B_TRUE); donesomething = B_TRUE; } } @@ -8144,7 +8167,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ char lfname[BUFLEN]; cell_t *retcell[MAXRETCELLS]; int nretcell,i; - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; // animation //anim(caster->cell, targcell, '}', C_BLUE); if (isplayer(caster) || cansee(player, caster)) { @@ -8172,7 +8194,7 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ // knock backwards dir = getdirtowards(caster->cell, target->cell, target, B_FALSE, DT_COMPASS); amt = (power/3); if (amt < 2) amt = 2; - knockback(target, dir, amt, caster, 0); + knockback(target, dir, amt, caster, 0, B_TRUE); // rust getallouterarmour(target, arm, &narm); for (i = 0; i < narm; i++) { @@ -8192,8 +8214,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ flag_t *f; int ndone = 0; - if (!validatespellcell(caster, &targcell,TT_OBJECT, spellid, power, frompot)) return B_TRUE; - if (!targcell) { fizzle(caster); } @@ -8243,8 +8263,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ fizzle(caster); } } else if (spellid == OT_S_WEAKEN) { - // ask for target - if (!validatespellcell(caster, &targcell, TT_MONSTER, spellid, power, frompot)) return B_TRUE; target = targcell->lf; if (spellresisted(target, caster, spellid, power, seenbyplayer, B_FALSE)) { @@ -8285,7 +8303,6 @@ int dospelleffects(lifeform_t *caster, enum OBTYPE spellid, int power, lifeform_ int i; numtotext(power, numbuf); - if (!validatespellcell(caster, &targcell,TT_MONSTER, spellid, power, frompot)) return B_TRUE; // animation anim(caster->cell, targcell, '^', C_GREY); if (isplayer(caster) || cansee(player, caster)) {