-- | Blast definitions. module Content.ItemKindBlast ( -- * Group name patterns pattern S_FIRECRACKER, pattern S_VIOLENT_FRAGMENTATION, pattern S_FRAGMENTATION, pattern S_FOCUSED_FRAGMENTATION, pattern S_VIOLENT_CONCUSSION, pattern S_CONCUSSION, pattern S_FOCUSED_CONCUSSION, pattern S_VIOLENT_FLASH, pattern S_FOCUSED_FLASH, pattern S_GLASS_HAIL, pattern S_FOCUSED_GLASS_HAIL, pattern S_PHEROMONE, pattern S_CALMING_MIST, pattern S_DISTRESSING_ODOR, pattern S_HEALING_MIST, pattern S_HEALING_MIST_2, pattern S_WOUNDING_MIST, pattern S_DISTORTION, pattern S_SMOKE, pattern S_BOILING_WATER, pattern S_GLUE, pattern S_WASTE, pattern S_ANTI_SLOW_MIST, pattern S_ANTIDOTE_MIST, pattern S_SLEEP_MIST, pattern S_DENSE_SHOWER, pattern S_SPARSE_SHOWER, pattern S_MELEE_PROTECTIVE_BALM, pattern S_RANGE_PROTECTIVE_BALM, pattern S_DEFENSELESSNESS_RUNOUT, pattern S_RESOLUTION_DUST, pattern S_HASTE_SPRAY, pattern S_VIOLENT_SLOWNESS_MIST, pattern S_SLOWNESS_MIST, pattern S_FOCUSED_SLOWNESS_MIST, pattern S_EYE_DROP, pattern S_IRON_FILING, pattern S_SMELLY_DROPLET, pattern S_EYE_SHINE, pattern S_WHISKEY_SPRAY, pattern S_YOUTH_SPRINKLE, pattern S_POISON_CLOUD, pattern S_PING_PLASH, pattern S_VIOLENT_BURNING_OIL_2, pattern S_VIOLENT_BURNING_OIL_3, pattern S_VIOLENT_BURNING_OIL_4, pattern S_BURNING_OIL_2, pattern S_BURNING_OIL_3, pattern S_BURNING_OIL_4, pattern S_FOCUSED_BURNING_OIL_2, pattern S_FOCUSED_BURNING_OIL_3, pattern S_FOCUSED_BURNING_OIL_4 , blastNoStatOf, blastBonusStatOf , pattern ARMOR_MISC , blastsGNSingleton, blastsGN , -- * Content blasts ) where import Prelude () import Game.LambdaHack.Core.Prelude import Content.ItemKindTemporary import Game.LambdaHack.Content.ItemKind import Game.LambdaHack.Core.Dice import Game.LambdaHack.Definition.Ability import Game.LambdaHack.Definition.Color import Game.LambdaHack.Definition.Defs import Game.LambdaHack.Definition.DefsInternal import Game.LambdaHack.Definition.Flavour -- * Group name patterns blastsGNSingleton :: [GroupName ItemKind] blastsGNSingleton = [S_FIRECRACKER, S_VIOLENT_FRAGMENTATION, S_FRAGMENTATION, S_FOCUSED_FRAGMENTATION, S_VIOLENT_CONCUSSION, S_CONCUSSION, S_FOCUSED_CONCUSSION, S_VIOLENT_FLASH, S_FOCUSED_FLASH, S_GLASS_HAIL, S_FOCUSED_GLASS_HAIL, S_PHEROMONE, S_CALMING_MIST, S_DISTRESSING_ODOR, S_HEALING_MIST, S_HEALING_MIST_2, S_WOUNDING_MIST, S_DISTORTION, S_SMOKE, S_BOILING_WATER, S_GLUE, S_WASTE, S_ANTI_SLOW_MIST, S_ANTIDOTE_MIST, S_SLEEP_MIST, S_DENSE_SHOWER, S_SPARSE_SHOWER, S_MELEE_PROTECTIVE_BALM, S_RANGE_PROTECTIVE_BALM, S_DEFENSELESSNESS_RUNOUT, S_RESOLUTION_DUST, S_HASTE_SPRAY, S_VIOLENT_SLOWNESS_MIST, S_SLOWNESS_MIST, S_FOCUSED_SLOWNESS_MIST, S_EYE_DROP, S_IRON_FILING, S_SMELLY_DROPLET, S_EYE_SHINE, S_WHISKEY_SPRAY, S_YOUTH_SPRINKLE, S_POISON_CLOUD, S_PING_PLASH, S_VIOLENT_BURNING_OIL_2, S_VIOLENT_BURNING_OIL_3, S_VIOLENT_BURNING_OIL_4, S_BURNING_OIL_2, S_BURNING_OIL_3, S_BURNING_OIL_4, S_FOCUSED_BURNING_OIL_2, S_FOCUSED_BURNING_OIL_3, S_FOCUSED_BURNING_OIL_4] ++ map firecrackerAt [1..4] ++ map blastNoStatOf noStatGN ++ map blastBonusStatOf bonusStatGN pattern S_FIRECRACKER, S_VIOLENT_FRAGMENTATION, S_FRAGMENTATION, S_FOCUSED_FRAGMENTATION, S_VIOLENT_CONCUSSION, S_CONCUSSION, S_FOCUSED_CONCUSSION, S_VIOLENT_FLASH, S_FOCUSED_FLASH, S_GLASS_HAIL, S_FOCUSED_GLASS_HAIL, S_PHEROMONE, S_CALMING_MIST, S_DISTRESSING_ODOR, S_HEALING_MIST, S_HEALING_MIST_2, S_WOUNDING_MIST, S_DISTORTION, S_SMOKE, S_BOILING_WATER, S_GLUE, S_WASTE, S_ANTI_SLOW_MIST, S_ANTIDOTE_MIST, S_SLEEP_MIST, S_DENSE_SHOWER, S_SPARSE_SHOWER, S_MELEE_PROTECTIVE_BALM, S_RANGE_PROTECTIVE_BALM, S_DEFENSELESSNESS_RUNOUT, S_RESOLUTION_DUST, S_HASTE_SPRAY, S_VIOLENT_SLOWNESS_MIST, S_SLOWNESS_MIST, S_FOCUSED_SLOWNESS_MIST, S_EYE_DROP, S_IRON_FILING, S_SMELLY_DROPLET, S_EYE_SHINE, S_WHISKEY_SPRAY, S_YOUTH_SPRINKLE, S_POISON_CLOUD, S_PING_PLASH, S_VIOLENT_BURNING_OIL_2, S_VIOLENT_BURNING_OIL_3, S_VIOLENT_BURNING_OIL_4, S_BURNING_OIL_2, S_BURNING_OIL_3, S_BURNING_OIL_4, S_FOCUSED_BURNING_OIL_2, S_FOCUSED_BURNING_OIL_3, S_FOCUSED_BURNING_OIL_4 :: GroupName ItemKind blastsGN :: [GroupName ItemKind] blastsGN = [ARMOR_MISC] pattern ARMOR_MISC :: GroupName ItemKind pattern S_FIRECRACKER = GroupName "firecracker" pattern S_VIOLENT_FRAGMENTATION = GroupName "violent fragmentation" pattern S_FRAGMENTATION = GroupName "fragmentation" pattern S_FOCUSED_FRAGMENTATION = GroupName "focused fragmentation" pattern S_VIOLENT_CONCUSSION = GroupName "violent concussion" pattern S_CONCUSSION = GroupName "concussion" pattern S_FOCUSED_CONCUSSION = GroupName "focused concussion" pattern S_VIOLENT_FLASH = GroupName "violent flash" pattern S_FOCUSED_FLASH = GroupName "focused flash" pattern S_GLASS_HAIL = GroupName "glass hail" pattern S_FOCUSED_GLASS_HAIL = GroupName "focused glass hail" pattern S_PHEROMONE = GroupName "pheromone" pattern S_CALMING_MIST = GroupName "calming mist" pattern S_DISTRESSING_ODOR = GroupName "distressing odor" pattern S_HEALING_MIST = GroupName "healing mist" pattern S_HEALING_MIST_2 = GroupName "strong healing mist" pattern S_WOUNDING_MIST = GroupName "wounding mist" pattern S_DISTORTION = GroupName "distortion" pattern S_SMOKE = GroupName "smoke" pattern S_BOILING_WATER = GroupName "boiling water" pattern S_GLUE = GroupName "glue" pattern S_WASTE = GroupName "waste" pattern S_ANTI_SLOW_MIST = GroupName "anti-slow mist" pattern S_ANTIDOTE_MIST = GroupName "antidote mist" pattern S_SLEEP_MIST = GroupName "sleep mist" pattern S_DENSE_SHOWER = GroupName "dense shower" pattern S_SPARSE_SHOWER = GroupName "sparse shower" pattern S_MELEE_PROTECTIVE_BALM = GroupName "melee protective balm" pattern S_RANGE_PROTECTIVE_BALM = GroupName "ranged protective balm" pattern S_DEFENSELESSNESS_RUNOUT = GroupName "PhD defense question" pattern S_RESOLUTION_DUST = GroupName "resolution dust" pattern S_HASTE_SPRAY = GroupName "haste spray" pattern S_VIOLENT_SLOWNESS_MIST = GroupName "violent nitrogen mist" pattern S_SLOWNESS_MIST = GroupName "nitrogen mist" pattern S_FOCUSED_SLOWNESS_MIST = GroupName "focused nitrogen mist" pattern S_EYE_DROP = GroupName "eye drop" pattern S_IRON_FILING = GroupName "iron filing" pattern S_SMELLY_DROPLET = GroupName "smelly droplet" pattern S_EYE_SHINE = GroupName "eye shine" pattern S_WHISKEY_SPRAY = GroupName "whiskey spray" pattern S_YOUTH_SPRINKLE = GroupName "youth sprinkle" pattern S_POISON_CLOUD = GroupName "poison cloud" pattern S_PING_PLASH = GroupName "ping and flash" pattern S_VIOLENT_BURNING_OIL_2 = GroupName "violent burning oil 2" pattern S_VIOLENT_BURNING_OIL_3 = GroupName "violent burning oil 3" pattern S_VIOLENT_BURNING_OIL_4 = GroupName "violent burning oil 4" pattern S_BURNING_OIL_2 = GroupName "burning oil 2" pattern S_BURNING_OIL_3 = GroupName "burning oil 3" pattern S_BURNING_OIL_4 = GroupName "burning oil 4" pattern S_FOCUSED_BURNING_OIL_2 = GroupName "focused burning oil 2" pattern S_FOCUSED_BURNING_OIL_3 = GroupName "focused burning oil 3" pattern S_FOCUSED_BURNING_OIL_4 = GroupName "focused burning oil 4" firecrackerAt :: Int -> GroupName ItemKind firecrackerAt n = GroupName $ "firecracker" <+> tshow n blastNoStatOf :: GroupName ItemKind -> GroupName ItemKind blastNoStatOf grp = GroupName $ fromGroupName grp <+> "mist" blastBonusStatOf :: GroupName ItemKind -> GroupName ItemKind blastBonusStatOf grp = GroupName $ fromGroupName grp <+> "dew" pattern ARMOR_MISC = GroupName "miscellaneous armor" -- * Content blasts :: [ItemKind] blasts = [spreadBurningOil2, spreadBurningOil3, spreadBurningOil4, spreadBurningOil82, spreadBurningOil83, spreadBurningOil84, focusedBurningOil2, focusedBurningOil3, focusedBurningOil4, firecracker1, firecracker2, firecracker3, firecracker4, firecracker5, spreadFragmentation, spreadFragmentation8, focusedFragmentation, spreadConcussion, spreadConcussion8, focusedConcussion, spreadFlash, spreadFlash8, focusedFlash, singleSpark, glassPiece, focusedGlass, fragrance, pheromone, mistCalming, odorDistressing, mistHealing, mistHealing2, mistWounding, distortion, smoke, boilingWater, glue, waste, mistAntiSlow, mistAntidote, mistSleep, denseShower, sparseShower, protectingBalmMelee, protectingBalmRanged, defenselessnessRunout, resolutionDust, hasteSpray, spreadNitrogen, spreadNitrogen8, focusedNitrogen, eyeDrop, ironFiling, smellyDroplet, eyeShine, whiskeySpray, youthSprinkle, poisonCloud, pingFlash, blastNoSkMove, blastNoSkMelee, blastNoSkDisplace, blastNoSkAlter, blastNoSkWait, blastNoSkMoveItem, blastNoSkProject, blastNoSkApply, blastBonusSkMove, blastBonusSkMelee, blastBonusSkDisplace, blastBonusSkAlter, blastBonusSkWait, blastBonusSkMoveItem, blastBonusSkProject, blastBonusSkApply] spreadBurningOil2, spreadBurningOil3, spreadBurningOil4, spreadBurningOil82, spreadBurningOil83, spreadBurningOil84, focusedBurningOil2, focusedBurningOil3, focusedBurningOil4, firecracker1, firecracker2, firecracker3, firecracker4, firecracker5, spreadFragmentation, spreadFragmentation8, focusedFragmentation, spreadConcussion, spreadConcussion8, focusedConcussion, spreadFlash, spreadFlash8, focusedFlash, singleSpark, glassPiece, focusedGlass, fragrance, pheromone, mistCalming, odorDistressing, mistHealing, mistHealing2, mistWounding, distortion, smoke, boilingWater, glue, waste, mistAntiSlow, mistAntidote, mistSleep, denseShower, sparseShower, protectingBalmMelee, protectingBalmRanged, defenselessnessRunout, resolutionDust, hasteSpray, spreadNitrogen, spreadNitrogen8, focusedNitrogen, eyeDrop, ironFiling, smellyDroplet, eyeShine, whiskeySpray, youthSprinkle, poisonCloud, pingFlash, blastNoSkMove, blastNoSkMelee, blastNoSkDisplace, blastNoSkAlter, blastNoSkWait, blastNoSkMoveItem, blastNoSkProject, blastNoSkApply, blastBonusSkMove, blastBonusSkMelee, blastBonusSkDisplace, blastBonusSkAlter, blastBonusSkWait, blastBonusSkMoveItem, blastBonusSkProject, blastBonusSkApply :: ItemKind -- We take care (e.g., in burningOil below) that blasts are not faster -- than 100% fastest natural speed, or some frames would be skipped, -- which is a waste of perfectly good frames. -- * Parameterized blasts spreadBurningOil :: Int -> GroupName ItemKind -> ItemKind spreadBurningOil n grp = ItemKind { isymbol = toContentSymbol '*' , iname = "burning oil" , ifreq = [(grp, 1)] , iflavour = zipPlain [BrYellow] , icount = intToDice (4 + n * 2) , irarity = [(1, 1)] , iverbHit = "sear" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity (max 10 $ min 100 $ n `div` 2 * 10) , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 2 ] , ieffects = [ Burn 1 , toOrganBad S_PACIFIED (2 + 1 `d` 2) ] -- slips and frantically puts out fire , idesc = "Sticky oil, burning brightly." , ikit = [] } spreadBurningOil2 = spreadBurningOil 2 S_VIOLENT_BURNING_OIL_2 -- 2 steps, 2 turns spreadBurningOil3 = spreadBurningOil 3 S_VIOLENT_BURNING_OIL_3 -- 2 steps, 2 turns spreadBurningOil4 = spreadBurningOil 4 S_VIOLENT_BURNING_OIL_4 -- 4 steps, 2 turns spreadBurningOil8 :: Int -> GroupName ItemKind -> ItemKind spreadBurningOil8 n grp = (spreadBurningOil (n `div` 2) grp) { icount = 7 -- 8 was too deadly } spreadBurningOil82 = spreadBurningOil8 2 S_BURNING_OIL_2 spreadBurningOil83 = spreadBurningOil8 3 S_BURNING_OIL_3 spreadBurningOil84 = spreadBurningOil8 4 S_BURNING_OIL_4 focusedBurningOil :: Int -> GroupName ItemKind -> GroupName ItemKind -> ItemKind focusedBurningOil n grp grpExplode = ItemKind { isymbol = toContentSymbol '`' , iname = "igniting oil" , ifreq = [(grp, 1)] , iflavour = zipPlain [BrYellow] -- all ignitions yellow to avoid appearing -- as a small vial explosion , icount = intToDice n , irarity = [(1, 1)] , iverbHit = "ignite" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] -- when the target position is occupied, the explosion starts one step -- away, hence we set range to 0 steps, to limit dispersal , ieffects = [OnSmash $ Explode grpExplode] , idesc = idesc spreadBurningOil2 , ikit = [] } focusedBurningOil2 = focusedBurningOil 2 S_FOCUSED_BURNING_OIL_2 S_BURNING_OIL_2 focusedBurningOil3 = focusedBurningOil 3 S_FOCUSED_BURNING_OIL_3 S_BURNING_OIL_3 focusedBurningOil4 = focusedBurningOil 4 S_FOCUSED_BURNING_OIL_4 S_BURNING_OIL_4 firecracker :: Int -> ItemKind firecracker n = ItemKind { isymbol = toContentSymbol '*' , iname = "firecracker" , ifreq = [(if n == 5 then S_FIRECRACKER else firecrackerAt n, 1)] , iflavour = zipPlain [brightCol !! ((n + 2) `mod` length brightCol)] , icount = if n <= 3 then 1 `d` min 2 n else 2 + 1 `d` 2 , irarity = [(1, 1)] , iverbHit = if n >= 4 then "singe" else "crack" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine $ intToDice $ 1 + n `div` 2 ] , ieffects = [if n >= 4 then Burn 1 else RefillCalm (-2)] ++ [Discharge 1 30 | n >= 3] ++ [OnSmash $ Explode $ firecrackerAt (n - 1) | n >= 2] , idesc = "Scraps of burnt paper, covering little pockets of black powder, buffeted by colorful explosions." , ikit = [] } firecracker5 = firecracker 5 firecracker4 = firecracker 4 firecracker3 = firecracker 3 firecracker2 = firecracker 2 firecracker1 = firecracker 1 -- * Focused blasts spreadFragmentation = ItemKind { isymbol = toContentSymbol '*' , iname = "fragmentation burst" , ifreq = [(S_VIOLENT_FRAGMENTATION, 1)] , iflavour = zipPlain [Red] , icount = 8 -- strong but few, so not always hits target , irarity = [(1, 1)] , iverbHit = "tear apart" , iweight = 1 , idamage = 3 `d` 1 -- deadly and adjacent actor hit by 2 on average; -- however, moderate armour blocks completely , iaspects = [ ToThrow $ ThrowMod 100 20 4 -- 4 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -12 * 5 ] , ieffects = [DropItem 1 1 COrgan CONDITION] , idesc = "Flying shards, flame and smoke." , ikit = [] } spreadFragmentation8 = spreadFragmentation { ifreq = [(S_FRAGMENTATION, 1)] , icount = 5 , iaspects = [ ToThrow $ ThrowMod 100 10 2 -- 2 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -12 * 5 ] -- smaller radius, so worse for area effect, but twice the direct damage } focusedFragmentation = ItemKind { isymbol = toContentSymbol '`' , iname = "deflagration ignition" -- black powder , ifreq = [(S_FOCUSED_FRAGMENTATION, 1)] , iflavour = zipPlain [BrYellow] , icount = 3 -- 15 in total vs 8, higher spread , irarity = [(1, 1)] , iverbHit = "ignite" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] -- when the target position is occupied, the explosion starts one step -- away, hence we set range to 0 steps, to limit dispersal , ieffects = [OnSmash $ Explode S_FRAGMENTATION] , idesc = idesc spreadFragmentation , ikit = [] } spreadConcussion = ItemKind { isymbol = toContentSymbol '*' , iname = "concussion blast" , ifreq = [(S_VIOLENT_CONCUSSION, 1)] , iflavour = zipPlain [Magenta] , icount = 12 -- pushing sometimes gets the victim out of attacker range, -- but also sometimes moves to a position hit again later , irarity = [(1, 1)] , iverbHit = "shock" , iweight = 1 , idamage = 1 `d` 1 -- only air pressure, so not as deadly as fragmentation, -- but armour can't block completely that easily , iaspects = [ ToThrow $ ThrowMod 100 20 4 -- 4 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -8 * 5 ] -- outdoors it has short range, but we only model indoors in the game; -- it's much faster than black powder shock wave, but we are beyond -- human-noticeable speed differences on short distances anyway , ieffects = [ DropItem maxBound 1 CEqp ARMOR_MISC , PushActor (ThrowMod 400 25 1) -- 1 step, fast; after DropItem -- this produces spam for braced actors; too bad , toOrganBad S_IMMOBILE 1 -- no balance , toOrganBad S_DEAFENED 23 ] , idesc = "Shock wave, hot gases, some fire and smoke." , ikit = [] } spreadConcussion8 = spreadConcussion { ifreq = [(S_CONCUSSION, 1)] , icount = 6 , iaspects = [ ToThrow $ ThrowMod 100 10 2 -- 2 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3, AddSkill SkHurtMelee $ -8 * 5 ] } focusedConcussion = ItemKind { isymbol = toContentSymbol '`' , iname = "detonation ignition" -- nitroglycerine , ifreq = [(S_FOCUSED_CONCUSSION, 1)] , iflavour = zipPlain [BrYellow] , icount = 4 -- 24 in total vs 12, higher spread, less harm from pushing , irarity = [(1, 1)] , iverbHit = "ignite" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [OnSmash $ Explode S_CONCUSSION] , idesc = idesc spreadConcussion , ikit = [] } spreadFlash = ItemKind { isymbol = toContentSymbol '`' , iname = "magnesium flash" , ifreq = [(S_VIOLENT_FLASH, 1)] , iflavour = zipPlain [BrWhite] , icount = 13 , irarity = [(1, 1)] , iverbHit = "dazzle" , iweight = 1 , idamage = 0 , iaspects = [ ToThrow $ ThrowMod 100 20 4 -- 4 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 5 ] , ieffects = [ toOrganBad S_BLIND 5 , toOrganBad S_WEAKENED 20 ] -- Wikipedia says: blind for five seconds and afterimage -- for much longer, harming aim , idesc = "A very bright flash of fire, causing long-lasting afterimages." , ikit = [] } spreadFlash8 = spreadFlash { iname = "spark" , ifreq = [(S_SPARK, 1)] , icount = 5 , iverbHit = "singe" , iaspects = [ ToThrow $ ThrowMod 100 10 2 -- 2 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 5 ] } focusedFlash = ItemKind { isymbol = toContentSymbol '`' , iname = "magnesium ignition" , ifreq = [(S_FOCUSED_FLASH, 1)] , iflavour = zipPlain [BrYellow] , icount = 5 -- 25 in total vs 13, higher spread , irarity = [(1, 1)] , iverbHit = "ignite" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [OnSmash $ Explode S_SPARK] , idesc = idesc spreadFlash , ikit = [] } singleSpark = spreadFlash { iname = "single spark" , ifreq = [(S_SINGLE_SPARK, 1)] -- too weak to start a fire , icount = 1 , iverbHit = "spark" , iaspects = [ toLinger 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 3 ] , ieffects = [] , idesc = "A glowing ember." , ikit = [] } glassPiece = ItemKind { isymbol = toContentSymbol '*' , iname = "glass piece" , ifreq = [(S_GLASS_HAIL, 1)] , iflavour = zipPlain [Blue] , icount = 6 , irarity = [(1, 1)] , iverbHit = "cut" , iweight = 1 , idamage = 2 `d` 1 , iaspects = [ ToThrow $ ThrowMod 100 10 4 -- 2 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkHurtMelee $ -15 * 5 ] -- brittle, not too dense; armor blocks , ieffects = [] , idesc = "Swift, sharp edges." , ikit = [] } focusedGlass = glassPiece -- when blowing up windows { ifreq = [(S_FOCUSED_GLASS_HAIL, 1)] , icount = 2 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkHurtMelee $ -15 * 5 ] , ieffects = [OnSmash $ Explode S_GLASS_HAIL] } -- * Assorted blasts that don't induce conditions or not used mainly for them fragrance = ItemKind { isymbol = toContentSymbol '`' , iname = "fragrance" -- instant, fast fragrance , ifreq = [(S_FRAGRANCE, 1)] , iflavour = zipPlain [Magenta] , icount = 8 , irarity = [(1, 1)] , iverbHit = "engulf" , iweight = 1 , idamage = 0 , iaspects = [ ToThrow $ ThrowMod 200 5 1 -- 2 steps, .5 turn (necklaces) , SetFlag Fragile, SetFlag Blast ] , ieffects = [Impress, toOrganGood S_ROSE_SMELLING 45] -- Linger 10, because sometimes it takes 2 turns due to starting just -- before actor turn's end (e.g., via a necklace). , idesc = "A pleasant scent." , ikit = [] } pheromone = ItemKind { isymbol = toContentSymbol '`' , iname = "musky whiff" -- a kind of mist rather than fragrance , ifreq = [(S_PHEROMONE, 1)] , iflavour = zipPlain [BrMagenta] , icount = 16 , irarity = [(1, 1)] , iverbHit = "tempt" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [Dominate] , idesc = "A sharp, strong scent." , ikit = [] } mistCalming = ItemKind -- unused { isymbol = toContentSymbol '`' , iname = "mist" , ifreq = [(S_CALMING_MIST, 1)] , iflavour = zipPlain [BrGreen] , icount = 8 , irarity = [(1, 1)] , iverbHit = "sooth" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [RefillCalm 2] , idesc = "A soothing, gentle cloud." , ikit = [] } odorDistressing = ItemKind { isymbol = toContentSymbol '`' , iname = "distressing whiff" , ifreq = [(S_DISTRESSING_ODOR, 1)] , iflavour = zipFancy [BrRed] -- salmon , icount = 8 , irarity = [(1, 1)] , iverbHit = "distress" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 10 -- 2 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [ RefillCalm (-10) , toOrganBad S_FOUL_SMELLING (20 + 1 `d` 5) , toOrganBad S_IMPATIENT (2 + 1 `d` 2) ] , idesc = "It turns the stomach." -- and so can't stand still , ikit = [] } mistHealing = ItemKind { isymbol = toContentSymbol '`' , iname = "mist" -- powerful, so slow and narrow , ifreq = [(S_HEALING_MIST, 1)] , iflavour = zipFancy [BrGreen] , icount = 8 , irarity = [(1, 1)] , iverbHit = "revitalize" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 1 ] , ieffects = [RefillHP 2] , idesc = "It fills the air with light and life." , ikit = [] } mistHealing2 = ItemKind { isymbol = toContentSymbol '`' , iname = "mist" , ifreq = [(S_HEALING_MIST_2, 1)] , iflavour = zipPlain [Green] , icount = 8 , irarity = [(1, 1)] , iverbHit = "revitalize" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 2 ] , ieffects = [RefillHP 4] , idesc = "At its touch, wounds close and bruises fade." , ikit = [] } mistWounding = ItemKind { isymbol = toContentSymbol '`' , iname = "mist" , ifreq = [(S_WOUNDING_MIST, 1)] , iflavour = zipPlain [BrRed] , icount = 8 , irarity = [(1, 1)] , iverbHit = "devitalize" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [RefillHP (-2)] , idesc = "The air itself stings and itches." , ikit = [] } distortion = ItemKind { isymbol = toContentSymbol 'v' , iname = "vortex" , ifreq = [(S_DISTORTION, 1)] , iflavour = zipPlain [White] , icount = 8 -- braced are immune to Teleport; avoid failure messages , irarity = [(1, 1)] , iverbHit = "engulf" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 10 -- 2 steps, 1 turn , SetFlag Lobable, SetFlag Fragile, SetFlag Blast ] , ieffects = [Teleport $ 15 + 1 `d` 10] , idesc = "The air shifts oddly, as though light is being warped." , ikit = [] } smoke = ItemKind -- when stuff burns out -- unused { isymbol = toContentSymbol '`' , iname = "smoke fume" -- pluralizes better than 'smokes' , ifreq = [(S_SMOKE, 1)] , iflavour = zipPlain [BrBlack] , icount = 16 , irarity = [(1, 1)] , iverbHit = "choke" -- or "obscure" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 20 -- 4 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganBad S_WITHHOLDING (5 + 1 `d` 3)] -- choking and tears, can roughly see, but not aim , idesc = "Twirling clouds of grey smoke." , ikit = [] } boilingWater = ItemKind { isymbol = toContentSymbol '*' , iname = "boiling water" , ifreq = [(S_BOILING_WATER, 1)] , iflavour = zipPlain [White] , icount = 18 , irarity = [(1, 1)] , iverbHit = "boil" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 30 -- 6 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [Burn 1] , idesc = "It bubbles and hisses." , ikit = [] } glue = ItemKind { isymbol = toContentSymbol '*' , iname = "hoof glue" , ifreq = [(S_GLUE, 1)] , iflavour = zipPlain [Cyan] , icount = 8 -- Paralyze doesn't stack; avoid failure messages , irarity = [(1, 1)] , iverbHit = "glue" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [Paralyze 10] , idesc = "Thick and clinging." , ikit = [] } waste = ItemKind { isymbol = toContentSymbol '*' , iname = "waste piece" , ifreq = [(S_WASTE, 1)] , iflavour = zipPlain [Brown] , icount = 16 , irarity = [(1, 1)] , iverbHit = "splosh" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [ toOrganBad S_FOUL_SMELLING (30 + 1 `d` 10) , toOrganBad S_DISPOSSESSED (10 + 1 `d` 5) ] , idesc = "Sodden and foul-smelling." , ikit = [] } mistAntiSlow = ItemKind { isymbol = toContentSymbol '`' , iname = "mist" , ifreq = [(S_ANTI_SLOW_MIST, 1)] , iflavour = zipFancy [BrYellow] , icount = 8 , irarity = [(1, 1)] , iverbHit = "propel" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [DropItem 1 1 COrgan S_SLOWED] , idesc = "A cleansing rain." , ikit = [] } mistAntidote = ItemKind { isymbol = toContentSymbol '`' , iname = "mist" , ifreq = [(S_ANTIDOTE_MIST, 1)] , iflavour = zipFancy [BrBlue] , icount = 8 , irarity = [(1, 1)] , iverbHit = "cure" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [DropItem 1 maxBound COrgan S_POISONED] , idesc = "Washes away death's dew." , ikit = [] } mistSleep = ItemKind { isymbol = toContentSymbol '`' , iname = "mist" , ifreq = [(S_SLEEP_MIST, 1)] , iflavour = zipFancy [BrMagenta] , icount = 8 , irarity = [(1, 1)] , iverbHit = "put to sleep" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 5 -- 1 step, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [PutToSleep] , idesc = "Lulls weary warriors." , ikit = [] } -- * Condition-inducing blasts -- Almost all have @toLinger 10@, that travels 2 steps in 1 turn. -- These are very fast projectiles, not getting into the way of big -- actors and not burdening the engine for long. -- A few are slower 'mists'. denseShower = ItemKind { isymbol = toContentSymbol '`' , iname = "dense shower" , ifreq = [(S_DENSE_SHOWER, 1)] , iflavour = zipFancy [Green] , icount = 12 , irarity = [(1, 1)] , iverbHit = "strengthen" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_STRENGTHENED 5] , idesc = "A thick rain of droplets." , ikit = [] } sparseShower = ItemKind { isymbol = toContentSymbol '`' , iname = "sparse shower" , ifreq = [(S_SPARSE_SHOWER, 1)] , iflavour = zipFancy [Red] , icount = 8 , irarity = [(1, 1)] , iverbHit = "weaken" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganBad S_WEAKENED 7] , idesc = "Light droplets that cling to clothing." , ikit = [] } protectingBalmMelee = ItemKind { isymbol = toContentSymbol '`' , iname = "balm droplet" , ifreq = [(S_MELEE_PROTECTIVE_BALM, 1)] , iflavour = zipFancy [Brown] , icount = 6 , irarity = [(1, 1)] , iverbHit = "balm" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganGood S_PROTECTED_FROM_MELEE (3 + 1 `d` 3)] , idesc = "A thick ointment that hardens the skin." , ikit = [] } protectingBalmRanged = ItemKind { isymbol = toContentSymbol '`' , iname = "balm droplet" , ifreq = [(S_RANGE_PROTECTIVE_BALM, 1)] , iflavour = zipPlain [BrYellow] , icount = 16 , irarity = [(1, 1)] , iverbHit = "balm" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_PROTECTED_FROM_RANGED (3 + 1 `d` 3)] , idesc = "Grease that protects from flying death." , ikit = [] } defenselessnessRunout = ItemKind { isymbol = toContentSymbol '?' , iname = "PhD defense question" , ifreq = [(S_DEFENSELESSNESS_RUNOUT, 1)] , iflavour = zipFancy [BrRed] , icount = 16 , irarity = [(1, 1)] , iverbHit = "nag" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganBad S_DEFENSELESS (3 + 1 `d` 3)] , idesc = "Only the most learned make use of this." , ikit = [] } resolutionDust = ItemKind { isymbol = toContentSymbol '`' , iname = "resolution dust" , ifreq = [(S_RESOLUTION_DUST, 1)] , iflavour = zipPlain [Brown] , icount = 16 , irarity = [(1, 1)] , iverbHit = "calm" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_RESOLUTE (3 + 1 `d` 3)] -- short enough duration that @calmEnough@ not a big problem , idesc = "A handful of honest earth, to strengthen the soul." , ikit = [] } hasteSpray = ItemKind { isymbol = toContentSymbol '`' , iname = "haste spray" , ifreq = [(S_HASTE_SPRAY, 1)] , iflavour = zipFancy [BrYellow] , icount = 16 , irarity = [(1, 1)] , iverbHit = "haste" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_HASTED (3 + 1 `d` 3)] , idesc = "A quick spurt." , ikit = [] } spreadNitrogen = ItemKind { isymbol = toContentSymbol '`' , iname = "slowness mist" , ifreq = [(S_VIOLENT_SLOWNESS_MIST, 1)] , iflavour = zipPlain [BrBlack] , icount = 15 , irarity = [(1, 1)] , iverbHit = "freeze" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns, mist, slow , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganBad S_SLOWED (2 + 1 `d` 3)] , idesc = "Colourless cold clammy fog, making each movement an effort." , ikit = [] } spreadNitrogen8 = spreadNitrogen { ifreq = [(S_SLOWNESS_MIST, 1)] , icount = 7 , iaspects = [ toVelocity 5 -- 1 step, 1 turn, mist, slow , SetFlag Fragile, SetFlag Blast ] } focusedNitrogen = ItemKind { isymbol = toContentSymbol '`' , iname = "slowness mist droplet" , ifreq = [(S_FOCUSED_SLOWNESS_MIST, 1)] , iflavour = zipFancy [White] , icount = 4 -- 28 in total vs 15, higher spread , irarity = [(1, 1)] , iverbHit = "freeze" , iweight = 1 , idamage = 0 , iaspects = [ toLinger 0 -- 0 steps, 1 turn , SetFlag Fragile, SetFlag Blast ] , ieffects = [ OnSmash $ Explode S_SLOWNESS_MIST , toOrganBad S_SLOWED (2 + 1 `d` 3) ] , idesc = "Colourless and colder than ice." , ikit = [] } eyeDrop = ItemKind { isymbol = toContentSymbol '`' , iname = "eye drop" , ifreq = [(S_EYE_DROP, 1)] , iflavour = zipFancy [BrCyan] , icount = 16 , irarity = [(1, 1)] , iverbHit = "cleanse" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_FAR_SIGHTED (3 + 1 `d` 3)] , idesc = "Not to be taken orally." , ikit = [] } ironFiling = ItemKind -- fast, short, strongly blinding blast { isymbol = toContentSymbol '`' , iname = "iron filing" , ifreq = [(S_IRON_FILING, 1)] , iflavour = zipPlain [Red] , icount = 16 , irarity = [(1, 1)] , iverbHit = "blind" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganBad S_BLIND (10 + 1 `d` 10)] , idesc = "A shaving of bright metal." , ikit = [] } smellyDroplet = ItemKind { isymbol = toContentSymbol '`' , iname = "smelly droplet" , ifreq = [(S_SMELLY_DROPLET, 1)] , iflavour = zipFancy [Blue] , icount = 16 , irarity = [(1, 1)] , iverbHit = "sensitize" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_KEEN_SMELLING (5 + 1 `d` 3)] , idesc = "A viscous lump that stains the skin." , ikit = [] } eyeShine = ItemKind { isymbol = toContentSymbol '`' , iname = "eye shine" , ifreq = [(S_EYE_SHINE, 1)] , iflavour = zipFancy [Cyan] , icount = 16 , irarity = [(1, 1)] , iverbHit = "smear" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_SHINY_EYED (3 + 1 `d` 3)] , idesc = "They almost glow in the dark." , ikit = [] } whiskeySpray = ItemKind { isymbol = toContentSymbol '`' , iname = "whiskey spray" , ifreq = [(S_WHISKEY_SPRAY, 1)] , iflavour = zipFancy [Brown] , icount = 16 , irarity = [(1, 1)] , iverbHit = "inebriate" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [toOrganGood S_DRUNK (3 + 1 `d` 3)] , idesc = "It burns in the best way." , ikit = [] } youthSprinkle = ItemKind { isymbol = toContentSymbol '`' , iname = "youth sprinkle" , ifreq = [(S_YOUTH_SPRINKLE, 1)] , iflavour = zipFancy [BrGreen] , icount = 16 , irarity = [(1, 1)] , iverbHit = "sprinkle" , iweight = 1 , idamage = 0 , iaspects = [toLinger 10, SetFlag Fragile, SetFlag Blast] , ieffects = [ toOrganGood S_ROSE_SMELLING (40 + 1 `d` 20) , toOrganNoTimer S_REGENERATING ] , idesc = "Bright and smelling of the Spring." , ikit = [] } poisonCloud = ItemKind { isymbol = toContentSymbol '`' , iname = "poison cloud" , ifreq = [(S_POISON_CLOUD, 1)] , iflavour = zipFancy [BrMagenta] , icount = 11 -- low, to be less deadly in a tunnel, compared to single hit , irarity = [(1, 1)] , iverbHit = "poison" , iweight = 0 -- lingers, blocking path , idamage = 0 , iaspects = [ ToThrow $ ThrowMod 10 100 2 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganNoTimer S_POISONED] , idesc = "Choking gas that stings the eyes." , ikit = [] } pingFlash = ItemKind { isymbol = toContentSymbol '`' , iname = "flash" , ifreq = [(S_PING_PLASH, 1)] , iflavour = zipFancy [Green] , icount = 1 , irarity = [(1, 1)] , iverbHit = "ping" , iweight = 1 -- to prevent blocking the way , idamage = 0 , iaspects = [ ToThrow $ ThrowMod 200 0 1 -- 1 step, .5 turn (necklaces) , SetFlag Fragile, SetFlag Blast , AddSkill SkShine 2 ] , ieffects = [OnSmash Yell] , idesc = "A ping and a display flash from an echolocator out of sync momentarily." , ikit = [] } blastNoStat :: GroupName ItemKind -> ItemKind blastNoStat grp = ItemKind { isymbol = toContentSymbol '`' , iname = "mist" , ifreq = [(blastNoStatOf grp, 1)] , iflavour = zipFancy [White] , icount = 12 , irarity = [(1, 1)] , iverbHit = "drain" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganBad grp (3 + 1 `d` 3)] , idesc = "Completely disables one personal faculty." , ikit = [] } blastNoSkMove = blastNoStat S_IMMOBILE blastNoSkMelee = blastNoStat S_PACIFIED blastNoSkDisplace = blastNoStat S_IRREPLACEABLE blastNoSkAlter = blastNoStat S_RETAINING blastNoSkWait = blastNoStat S_IMPATIENT blastNoSkMoveItem = blastNoStat S_DISPOSSESSED blastNoSkProject = blastNoStat S_WITHHOLDING blastNoSkApply = blastNoStat S_PARSIMONIOUS blastBonusStat :: GroupName ItemKind -> ItemKind blastBonusStat grp = ItemKind { isymbol = toContentSymbol '`' , iname = "dew" , ifreq = [(blastBonusStatOf grp, 1)] , iflavour = zipFancy [White] , icount = 12 , irarity = [(1, 1)] , iverbHit = "elevate" , iweight = 1 , idamage = 0 , iaspects = [ toVelocity 10 -- 2 steps, 2 turns , SetFlag Fragile, SetFlag Blast ] , ieffects = [toOrganGood grp (20 + 1 `d` 5)] , idesc = "Temporarily enhances the given personal faculty." , ikit = [] } blastBonusSkMove = blastBonusStat S_MORE_MOBILE blastBonusSkMelee = blastBonusStat S_MORE_COMBATIVE blastBonusSkDisplace = blastBonusStat S_MORE_DISPLACING blastBonusSkAlter = blastBonusStat S_MORE_MODIFYING blastBonusSkWait = blastBonusStat S_MORE_PATIENT blastBonusSkMoveItem = blastBonusStat S_MORE_TIDY blastBonusSkProject = blastBonusStat S_MORE_PROJECTING blastBonusSkApply = blastBonusStat S_MORE_PRACTICAL