Commit eeb3375a007f35aeb1f4b86405b16160dd41fa14

Authored by dg
1 parent 69052394

moss tree


git-svn-id: http://svn.net-core.org/repos/t-engine4@6543 51575b47-30f0-44d4-a5cc-537603b46e54
... ... @@ -1842,6 +1842,43 @@ newDamageType{
1842 1842 end,
1843 1843 }
1844 1844
  1845 +newDamageType{
  1846 + name = "nurishing moss", type = "NURISHING_MOSS",
  1847 + projector = function(src, x, y, type, dam)
  1848 + local target = game.level.map(x, y, Map.ACTOR)
  1849 + if target and src:reactionToward(target) < 0 then
  1850 + local realdam = DamageType:get(DamageType.NATURE).projector(src, x, y, DamageType.NATURE, dam.dam)
  1851 + if realdam > 0 then src:heal(realdam * dam.factor, target) end
  1852 + end
  1853 + end,
  1854 +}
  1855 +
  1856 +newDamageType{
  1857 + name = "slippery moss", type = "SLIPPERY_MOSS",
  1858 + projector = function(src, x, y, type, dam)
  1859 + local target = game.level.map(x, y, Map.ACTOR)
  1860 + if target and src:reactionToward(target) < 0 then
  1861 + DamageType:get(DamageType.NATURE).projector(src, x, y, DamageType.NATURE, dam.dam)
  1862 + target:setEffect(target.EFF_SLIPPERY_MOSS, 2, {apply_power=src:combatMindpower(), fail=dam.fail}, true)
  1863 + end
  1864 + end,
  1865 +}
  1866 +
  1867 +newDamageType{
  1868 + name = "hallucinogenic moss", type = "HALLUCINOGENIC_MOSS",
  1869 + projector = function(src, x, y, type, dam)
  1870 + local target = game.level.map(x, y, Map.ACTOR)
  1871 + if target and src:reactionToward(target) < 0 then
  1872 + DamageType:get(DamageType.NATURE).projector(src, x, y, DamageType.NATURE, dam.dam)
  1873 + if target:canBe("confusion") and rng.percent(dam.chance) then
  1874 + target:setEffect(target.EFF_CONFUSED, 2, {apply_power=src:combatMindpower(), power=dam.power}, true)
  1875 + else
  1876 + game.logSeen(target, "%s resists!", target.name:capitalize())
  1877 + end
  1878 + end
  1879 + end,
  1880 +}
  1881 +
1845 1882 -- Circles
1846 1883 newDamageType{
1847 1884 name = "sanctity", type = "SANCTITY",
... ...
  1 +-- ToME - Tales of Maj'Eyal
  2 +-- Copyright (C) 2009, 2010, 2011, 2012, 2013 Nicolas Casalini
  3 +--
  4 +-- This program is free software: you can redistribute it and/or modify
  5 +-- it under the terms of the GNU General Public License as published by
  6 +-- the Free Software Foundation, either version 3 of the License, or
  7 +-- (at your option) any later version.
  8 +--
  9 +-- This program is distributed in the hope that it will be useful,
  10 +-- but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12 +-- GNU General Public License for more details.
  13 +--
  14 +-- You should have received a copy of the GNU General Public License
  15 +-- along with this program. If not, see <http://www.gnu.org/licenses/>.
  16 +--
  17 +-- Nicolas Casalini "DarkGod"
  18 +-- darkgod@te4.org
  19 +
  20 +base_size = 64
  21 +
  22 +local nb = 0
  23 +
  24 +return { generator = function()
  25 + local ad = rng.range(0, 360)
  26 + local a = math.rad(ad)
  27 + local dir = math.rad(ad)
  28 + local r = rng.range(0, 32)
  29 +
  30 + return {
  31 + life = 120,
  32 + size = rng.range(24, 48), sizev = -0.05, sizea = 0,
  33 +
  34 + x = r * math.cos(a), xv = 0, xa = 0,
  35 + y = r * math.sin(a), yv = 0, ya = 0,
  36 + dir = 0, dirv = 0, dira = 0,
  37 + vel = 0, velv = 0, vela = 0,
  38 +
  39 + r = 0.3, rv = 0, ra = 0,
  40 + g = 0.7, gv = 0, ga = 0,
  41 + b = 0.3, gv = 0, ga = 0,
  42 + a = rng.float(0.01, 0.05), av = 0.032, aa = -0.0006,
  43 + }
  44 +end, },
  45 +function(self)
  46 + if nb == 0 then self.ps:emit(1) end
  47 + nb = nb + 1
  48 + if nb >= 10 then
  49 + nb = 0
  50 + end
  51 +end,
  52 +10, "particles_images/slime"..rng.range(1, 5)
\ No newline at end of file
... ...
... ... @@ -30,11 +30,11 @@ newTalent{
30 30 type = {"wild-gift/moss", 1},
31 31 require = gifts_req1,
32 32 points = 5,
33   - cooldown = 20,
  33 + cooldown = 16,
34 34 equilibrium = 5,
35 35 no_energy = true,
36 36 tactical = { ATTACKAREA = {NATURE=1}, DISABLE = {pin = 1} },
37   - getDamage = function(self, t) return self:combatTalentMindDamage(t, 4, 30) end,
  37 + getDamage = function(self, t) return self:combatTalentMindDamage(t, 6, 40) end,
38 38 getDuration = function(self, t) return 3 + math.ceil(self:getTalentLevel(t)) end,
39 39 getSlow = function(self, t) return 30 + math.ceil(self:getTalentLevel(t) * 6) end,
40 40 getPin = function(self, t) return 20 + math.ceil(self:getTalentLevel(t) * 5) end,
... ... @@ -52,7 +52,7 @@ newTalent{
52 52 DamageType.GRASPING_MOSS, {dam=self:mindCrit(t.getDamage(self, t)), pin=t.getPin(self, t), slow=t.getSlow(self, t)},
53 53 self:getTalentRadius(t),
54 54 5, nil,
55   - engine.Entity.new{alpha=75, display='', color_br=60, color_bg=10, color_bb=60},
  55 + {type="moss"},
56 56 nil, false, false
57 57 )
58 58 activate_moss(self, t.id)
... ... @@ -80,50 +80,46 @@ newTalent{
80 80 type = {"wild-gift/moss", 2},
81 81 require = gifts_req2,
82 82 points = 5,
83   - equilibrium = 1,
84   - cooldown = 12,
85   - tactical = { PROTECT = 2, ATTACKAREA = { ARCANE = 1 } },
86   - getDam = function(self, t) return self:combatTalentMindDamage(t, 15, 200) end,
87   - on_pre_use = function(self, t)
88   - if not game.level then return false end
89   - for _, coor in pairs(util.adjacentCoords(self.x, self.y)) do
90   - local act = game.level.map(coor[1], coor[2], Map.ACTOR)
91   - if act and act.summoner == self and act.bloated_ooze then
92   - return true
93   - end
94   - end
95   - return false
  83 + cooldown = 16,
  84 + equilibrium = 5,
  85 + no_energy = true,
  86 + tactical = { ATTACKAREA = {NATURE=1}, DISABLE = {pin = 1} },
  87 + getDamage = function(self, t) return self:combatTalentMindDamage(t, 6, 40) end,
  88 + getDuration = function(self, t) return 3 + math.ceil(self:getTalentLevel(t)) end,
  89 + getHeal = function(self, t) return 50 + math.ceil(self:getTalentLevel(t) * 15) end,
  90 + range = 0,
  91 + radius = function(self, t)
  92 + return 2 + math.floor(self:getTalentLevelRaw(t)/2)
  93 + end,
  94 + target = function(self, t)
  95 + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)}
96 96 end,
97 97 action = function(self, t)
98   - local possibles = {}
99   - for _, coor in pairs(util.adjacentCoords(self.x, self.y)) do
100   - local act = game.level.map(coor[1], coor[2], Map.ACTOR)
101   - if act and act.summoner == self and act.bloated_ooze then
102   - possibles[#possibles+1] = act
103   - end
104   - end
105   - if #possibles == 0 then return end
106   -
107   - local act = rng.table(possibles)
108   - act:die(self)
109   -
110   - self:setEffect(self.EFF_PAIN_SUPPRESSION, math.ceil(3 + self:getTalentLevel(t)), {power=50})
111   -
112   - local tg = {type="ball", radius=3, range=0, talent=t, selffire=false, friendlyfire=false}
113   - self:project(tg, self.x, self.y, DamageType.MANABURN, self:mindCrit(t.getDam(self, t)))
114   - game.level.map:particleEmitter(self.x, self.y, tg.radius, "acidflash", {radius=tg.radius})
115   -
  98 + -- Add a lasting map effect
  99 + game.level.map:addEffect(self,
  100 + self.x, self.y, self:spellCrit(t.getDuration(self, t)),
  101 + DamageType.NURISHING_MOSS, {dam=self:mindCrit(t.getDamage(self, t)), factor=t.getHeal(self, t)/100},
  102 + self:getTalentRadius(t),
  103 + 5, nil,
  104 + {type="moss"},
  105 + nil, false, false
  106 + )
  107 + activate_moss(self, t.id)
  108 + game:playSoundNear(self, "talents/slime")
116 109 return true
117 110 end,
118 111 info = function(self, t)
119   - return ([[You randomly merge with an adjacent bloated ooze, granting your a 50%% damage resistance for %d turns.
120   - The merging also releases a burst of antimagic all around, dealing %0.2f manaburn damage in radius %d.
121   - The effect will increase with your Mindpower.]]):
122   - format(
123   - math.ceil(3 + self:getTalentLevel(t)),
124   - damDesc(self, DamageType.ARCANE, t.getDam(self, t)),
125   - 3
126   - )
  112 + local damage = t.getDamage(self, t)
  113 + local duration = t.getDuration(self, t)
  114 + local heal = t.getHeal(self, t)
  115 + local radius = self:getTalentRadius(t)
  116 + return ([[Instantly grow a moss circle of radius %d at your feet.
  117 + Each turn the moss deals %0.2f nature damage to any foes with in its radius.
  118 + This moss has vampiric properties, all damage it deals also heals the user for %d%% of the damage done.
  119 + The moss lasts %d turns.
  120 + Using a moss talent takes no turn but places all other moss talents on a 3 turns cooldown.
  121 + The damage will increase with your Mindpower.]]):
  122 + format(radius, damDesc(self, DamageType.NATURE, damage), heal, duration)
127 123 end,
128 124 }
129 125
... ... @@ -132,89 +128,95 @@ newTalent{
132 128 type = {"wild-gift/moss", 3},
133 129 require = gifts_req3,
134 130 points = 5,
  131 + cooldown = 16,
135 132 equilibrium = 5,
136   - cooldown = 8,
  133 + no_energy = true,
  134 + tactical = { ATTACKAREA = {NATURE=1}, DISABLE = {pin = 1} },
  135 + getDamage = function(self, t) return self:combatTalentMindDamage(t, 6, 40) end,
  136 + getDuration = function(self, t) return 3 + math.ceil(self:getTalentLevel(t)) end,
  137 + getFail = function(self, t) return 20 + math.ceil(self:getTalentLevel(t) * 6) end,
  138 + range = 0,
  139 + radius = function(self, t)
  140 + return 2 + math.floor(self:getTalentLevelRaw(t)/2)
  141 + end,
  142 + target = function(self, t)
  143 + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)}
  144 + end,
137 145 action = function(self, t)
138   - local ot = self:getTalentFromId(self.T_MITOSIS)
139   - for i = 1, math.floor(self:getTalentLevel(t)) do
140   - ot.spawn(self, ot, self:combatTalentMindDamage(t, 30, 300))
141   - end
142   -
143   - local list = {}
144   - if game.party:hasMember(self) then
145   - for act, def in pairs(game.party.members) do
146   - if act.summoner and act.summoner == self and act.bloated_ooze then list[#list+1] = act end
147   - end
148   - else
149   - for _, act in pairs(game.level.entities) do
150   - if act.summoner and act.summoner == self and act.is_mucus_ooze then list[#list+1] = act end
151   - end
152   - end
153   -
154   - local tg = {type="ball", radius=self.sight}
155   - local grids = self:project(tg, self.x, self.y, function() end)
156   - local tgts = {}
157   - for x, ys in pairs(grids) do for y, _ in pairs(ys) do
158   - local target = game.level.map(x, y, Map.ACTOR)
159   - if target and self:reactionToward(target) < 0 then tgts[#tgts+1] = target end
160   - end end
161   -
162   - while #tgts > 0 and #list > 0 do
163   - local ooze = rng.tableRemove(list)
164   - local target = rng.tableRemove(tgts)
165   -
166   - local tx, ty = util.findFreeGrid(target.x, target.y, 10, true, {[Map.ACTOR]=true})
167   - if tx then
168   - local ox, oy = ooze.x, ooze.y
169   - ooze:move(tx, ty, true)
170   - if config.settings.tome.smooth_move > 0 then
171   - ooze:resetMoveAnim()
172   - ooze:setMoveAnim(ox, oy, 8, 5)
173   - end
174   - if core.fov.distance(tx, ty, target.x, target.y) <= 1 then
175   - target:setTarget(ooze)
176   - self:attackTarget(target, DamageType.ACID, self:combatTalentWeaponDamage(t, 0.6, 2.2), true)
177   - end
178   - end
179   - end
180   -
  146 + -- Add a lasting map effect
  147 + game.level.map:addEffect(self,
  148 + self.x, self.y, self:spellCrit(t.getDuration(self, t)),
  149 + DamageType.SLIPPERY_MOSS, {dam=self:mindCrit(t.getDamage(self, t)), fail=t.getFail(self, t)},
  150 + self:getTalentRadius(t),
  151 + 5, nil,
  152 + {type="moss"},
  153 + nil, false, false
  154 + )
  155 + activate_moss(self, t.id)
181 156 game:playSoundNear(self, "talents/slime")
182 157 return true
183 158 end,
184 159 info = function(self, t)
185   - return ([[Instantly call all your bloated oozes to fight and if below the maximum number of oozes allowed by the Mitosis talent, at most %d will be created (with %d life).
186   - Each of them will be transported near a random foe in sight grab its attention.
187   - Taking advantage of the situation you channel a melee attack though all of them to their foes dealing %d%% weapon damage as acid.]]):
188   - format(self:getTalentLevel(t), self:combatTalentMindDamage(t, 30, 300), self:combatTalentWeaponDamage(t, 0.6, 2.2) * 100)
  160 + local damage = t.getDamage(self, t)
  161 + local duration = t.getDuration(self, t)
  162 + local fail = t.getFail(self, t)
  163 + local radius = self:getTalentRadius(t)
  164 + return ([[Instantly grow a moss circle of radius %d at your feet.
  165 + Each turn the moss deals %0.2f nature damage to any foes with in its radius.
  166 + This moss is very slippery, any foes trying to perform complex actions has %d%% chances of failing.
  167 + The moss lasts %d turns.
  168 + Using a moss talent takes no turn but places all other moss talents on a 3 turns cooldown.
  169 + The damage will increase with your Mindpower.]]):
  170 + format(radius, damDesc(self, DamageType.NATURE, damage), fail, duration)
189 171 end,
190 172 }
191 173
192 174 newTalent{
193   - name = "Halucigenic Moss",
  175 + name = "Hallucinogenic Moss",
194 176 type = {"wild-gift/moss", 4},
195 177 require = gifts_req4,
196 178 points = 5,
197   - mode = "passive",
198   - on_learn = function(self, t)
199   - self:attr("blind_immune", 0.2)
200   - self:attr("poison_immune", 0.2)
201   - self:attr("disease_immune", 0.2)
202   - self:attr("cut_immune", 0.2)
203   - self:attr("confusion_immune", 0.2)
204   - self:attr("ignore_direct_crits", 15)
205   - end,
206   - on_unlearn = function(self, t)
207   - self:attr("blind_immune", -0.2)
208   - self:attr("poison_immune", -0.2)
209   - self:attr("disease_immune", -0.2)
210   - self:attr("cut_immune", -0.2)
211   - self:attr("confusion_immune", -0.2)
212   - self:attr("ignore_direct_crits", -15)
  179 + cooldown = 16,
  180 + equilibrium = 5,
  181 + no_energy = true,
  182 + tactical = { ATTACKAREA = {NATURE=1}, DISABLE = {pin = 1} },
  183 + getDamage = function(self, t) return self:combatTalentMindDamage(t, 6, 40) end,
  184 + getDuration = function(self, t) return 3 + math.ceil(self:getTalentLevel(t)) end,
  185 + getChance = function(self, t) return 20 + math.ceil(self:getTalentLevel(t) * 5.5) end,
  186 + getPower = function(self, t) return 15 + math.ceil(self:getTalentLevel(t) * 5) end,
  187 + range = 0,
  188 + radius = function(self, t)
  189 + return 2 + math.floor(self:getTalentLevelRaw(t)/2)
  190 + end,
  191 + target = function(self, t)
  192 + return {type="ball", range=self:getTalentRange(t), radius=self:getTalentRadius(t)}
  193 + end,
  194 + action = function(self, t)
  195 + -- Add a lasting map effect
  196 + game.level.map:addEffect(self,
  197 + self.x, self.y, self:spellCrit(t.getDuration(self, t)),
  198 + DamageType.HALLUCINOGENIC_MOSS, {dam=self:mindCrit(t.getDamage(self, t)), chance=t.getChance(self, t), power=t.getPower(self, t)},
  199 + self:getTalentRadius(t),
  200 + 5, nil,
  201 + {type="moss"},
  202 + nil, false, false
  203 + )
  204 + activate_moss(self, t.id)
  205 + game:playSoundNear(self, "talents/slime")
  206 + return true
213 207 end,
214 208 info = function(self, t)
215   - return ([[Your body's internal organs are melted together, making it much harder to suffer critical hits.
216   - All direct critical hits (physical, mental, spells) against you have a %d%% chance to instead do their normal damage.
217   - In addition you gain %d%% disease, poison, cuts, confusion and blindness resistances.]]):
218   - format(self:getTalentLevelRaw(t) * 15, self:getTalentLevelRaw(t) * 20)
  209 + local damage = t.getDamage(self, t)
  210 + local duration = t.getDuration(self, t)
  211 + local chance = t.getChance(self, t)
  212 + local power = t.getPower(self, t)
  213 + local radius = self:getTalentRadius(t)
  214 + return ([[Instantly grow a moss circle of radius %d at your feet.
  215 + Each turn the moss deals %0.2f nature damage to any foes with in its radius.
  216 + This moss is coated with strange fluids, any foes passing through it has %d%% chances to be confused (power %d%%) for 2 turns.
  217 + The moss lasts %d turns.
  218 + Using a moss talent takes no turn but places all other moss talents on a 3 turns cooldown.
  219 + The damage will increase with your Mindpower.]]):
  220 + format(radius, damDesc(self, DamageType.NATURE, damage), chance, power, duration)
219 221 end,
220 222 }
... ...
... ... @@ -2046,3 +2046,21 @@ newEffect{
2046 2046 self:effectTemporaryValue(eff, "combat_def", -eff.defense)
2047 2047 end,
2048 2048 }
  2049 +
  2050 +newEffect{
  2051 + name = "SLIPPERY_MOSS", image = "talents/slippery_moss.png",
  2052 + desc = "Slippery Moss",
  2053 + long_desc = function(self, eff) return ("The target is covered in slippery moss. Each time it tries to use a talent there is %d%% chance of failure."):format(eff.fail) end,
  2054 + type = "physical",
  2055 + subtype = { moss=true, nature=true },
  2056 + status = "detrimental",
  2057 + parameters = {fail=5},
  2058 + on_gain = function(self, err) return "#Target# is covered in slippery moss!", "+Slippery Moss" end,
  2059 + on_lose = function(self, err) return "#Target# is free from the slippery moss.", "-Slippery Moss" end,
  2060 + activate = function(self, eff)
  2061 + eff.tmpid = self:addTemporaryValue("talent_fail_chance", eff.fail)
  2062 + end,
  2063 + deactivate = function(self, eff)
  2064 + self:removeTemporaryValue("talent_fail_chance", eff.tmpid)
  2065 + end,
  2066 +}
... ...