Commit eeb3375a007f35aeb1f4b86405b16160dd41fa14
1 parent
69052394
moss tree
git-svn-id: http://svn.net-core.org/repos/t-engine4@6543 51575b47-30f0-44d4-a5cc-537603b46e54
Showing
8 changed files
with
220 additions
and
111 deletions
... | ... | @@ -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 | ... | ... |

3.82 KB

3.81 KB

4.17 KB

4.26 KB
... | ... | @@ -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 | +} | ... | ... |
-
Please register or login to post a comment