Commit 8b5bef6ab679cbb10a81e0c1533ddac095f090ee
1 parent
66159192
New awesome effect on body of ice and stone skin
Showing
8 changed files
with
172 additions
and
2 deletions
... | ... | @@ -62,6 +62,9 @@ newBirthDescriptor{ |
62 | 62 | function(actor) |
63 | 63 | actor:addShaderAura("body_of_fire", "awesomeaura", {time_factor=3500, alpha=1, flame_scale=1.1}, "particles_images/wings.png") |
64 | 64 | end, |
65 | + function(actor) | |
66 | + actor:addShaderAura("body_of_ice", "crystalineaura", {}, "particles_images/spikes.png") | |
67 | + end, | |
65 | 68 | }, |
66 | 69 | talents_types = { |
67 | 70 | ["spell/explosives"]={true, 0.3}, | ... | ... |
1 | +-- ToME - Tales of Maj'Eyal | |
2 | +-- Copyright (C) 2009 - 2014 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 = 32 | |
21 | +toback = true | |
22 | + | |
23 | +return { generator = function() | |
24 | + local ad = rng.range(0, 360) | |
25 | + local a = math.rad(ad) | |
26 | + local dir = math.rad(90) | |
27 | + local r = rng.range(18, 22) | |
28 | + local dirchance = rng.chance(2) | |
29 | + local x = rng.range(-16, 16) | |
30 | + local y = -20 + math.abs(math.sin(x / 16) * 8) | |
31 | + | |
32 | + return { | |
33 | + trail = 1, | |
34 | + life = rng.range(20, 28), | |
35 | + size = rng.range(3, 4), sizev = 0, sizea = -0.005, | |
36 | + | |
37 | + x = x, xv = 0, xa = 0, | |
38 | + y = y, yv = 0.5, ya = 0.06, | |
39 | + dir = 0, dirv = 0, dira = 0, | |
40 | + vel = 0, velv = 0, vela = 0, | |
41 | + | |
42 | + r = 0.624, rv = 0, ra = 0, | |
43 | + g = 0.820, gv = 0, ga = 0, | |
44 | + b = 0.933, bv = 0, ba = 0, | |
45 | + a = 0.2, av = 0.1, aa = 0, | |
46 | + } | |
47 | +end, }, | |
48 | +function(self) | |
49 | + self.ps:emit(1) | |
50 | +end, | |
51 | +10, | |
52 | +"weather/snowflake" | ... | ... |

12.5 KB
1 | +uniform sampler2D displMapTex; | |
2 | +uniform sampler2D normalMapTex; | |
3 | + | |
4 | +uniform float spikeLength; | |
5 | +uniform float spikeWidth; | |
6 | +uniform float spikeOffset; | |
7 | + | |
8 | +uniform float growthSpeed; | |
9 | + | |
10 | +uniform float tick; | |
11 | +uniform float tick_start; | |
12 | +uniform float time_factor; | |
13 | + | |
14 | +uniform vec3 color; | |
15 | + | |
16 | +void main(void) | |
17 | +{ | |
18 | + vec2 radius = gl_TexCoord[0].xy - vec2(0.5, 0.5); | |
19 | + float innerRadius = 0.25; | |
20 | + float outerRadius = 0.5; | |
21 | + | |
22 | + vec2 planarPos; | |
23 | + vec4 displacement = texture2D(displMapTex, gl_TexCoord[0].xy); | |
24 | + | |
25 | + vec2 point = gl_TexCoord[0].xy; | |
26 | + float eps = 0.05; | |
27 | + vec2 basisY = vec2( | |
28 | + texture2D(displMapTex, point + vec2(eps, 0.0)).a - texture2D(displMapTex, point + vec2(-eps, 0.0)).a, | |
29 | + -texture2D(displMapTex, point + vec2(0.0, eps)).a + texture2D(displMapTex, point + vec2(0.0, -eps)).a); | |
30 | + basisY /= length(basisY) + 0.001; | |
31 | + vec2 basisX = vec2(basisY.y, -basisY.x); | |
32 | + | |
33 | + planarPos.x = displacement.b * 6.0 / spikeWidth + spikeOffset; | |
34 | + planarPos.y = displacement.a * 20.0 / (spikeLength * clamp((tick - tick_start) / time_factor * growthSpeed, 0.0, 1.0) + 0.001); | |
35 | + | |
36 | + vec4 normalMap = texture2D(normalMapTex, vec2(planarPos.x, clamp(1.0 - planarPos.y, 0.01, 0.99))); | |
37 | + vec3 localNormal = normalMap.rgb; | |
38 | + localNormal -= vec3(0.5, 0.5, 0.5); | |
39 | + localNormal.x = -localNormal.x; | |
40 | + localNormal.z = -localNormal.z; | |
41 | + localNormal /= length(localNormal); | |
42 | + | |
43 | + vec3 globalNormal; | |
44 | + globalNormal.xy = basisX * localNormal.x + basisY * localNormal.y; | |
45 | + globalNormal.z = localNormal.z; | |
46 | + | |
47 | + vec2 lightDir2 = vec2(cos(tick / time_factor), sin(tick / time_factor)); | |
48 | + float ang = 3.1415 * 0.2; | |
49 | + vec3 lightDir3 = vec3(lightDir2 * sin(ang), cos(ang)); | |
50 | + | |
51 | + float diffuse = clamp(-dot(lightDir3, globalNormal), 0.0, 1.0); | |
52 | + float specular = 0.0; | |
53 | + if(dot(lightDir3, globalNormal) < 0.0) | |
54 | + { | |
55 | + vec3 reflectedLight = lightDir3 - globalNormal * dot(lightDir3, globalNormal) * 2.0; | |
56 | + specular += pow(clamp(-dot(reflectedLight, vec3(0.0, 0.0, 1.0)), 0.0, 1.0), 30.0); | |
57 | + } | |
58 | + //vec3(0.624, 0.820, 0.933); | |
59 | + vec4 resultColor = vec4(color * diffuse + vec3(1.0, 1.0, 1.0) * specular, normalMap.a * gl_Color.a); | |
60 | + | |
61 | + gl_FragColor = resultColor;/// | |
62 | +} | |
\ No newline at end of file | ... | ... |
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 | +return { | |
21 | + frag = "crystalineaura", | |
22 | + vert = nil, | |
23 | + args = { | |
24 | + displMapTex = { texture = 0 }, | |
25 | + normalMapTex = { texture = 1 }, | |
26 | + | |
27 | + spikeLength = spikeLength or 1.0, -- 1.0 means normal length, 0.5 is half-sized spikes, 2.0 is double-sized, etc | |
28 | + spikeWidth = spikeWidth or 1.0, -- use different values for different effects. 1.0 is normal width | |
29 | + spikeOffset = spikeOffset or 0.0, -- use different values for different effects. such as offset = 0.0 for ice spikes and 0.123123 for rock spikes | |
30 | + | |
31 | + growthSpeed = growthSpeed or 1.0, -- 1.0 is normal growth speed | |
32 | + | |
33 | + time_factor = time_factor or 500, | |
34 | + | |
35 | + color = color or {0.624, 0.820, 0.933}, | |
36 | + }, | |
37 | + resetargs = { | |
38 | + tick_start = function() return core.game.getTime() end, | |
39 | + }, | |
40 | + clone = false, | |
41 | +} | ... | ... |
... | ... | @@ -31,12 +31,16 @@ newTalent{ |
31 | 31 | getArmor = function(self, t) return self:combatTalentSpellDamage(t, 10, 23) end, |
32 | 32 | activate = function(self, t) |
33 | 33 | game:playSoundNear(self, "talents/earth") |
34 | - return { | |
34 | + local ret = { | |
35 | 35 | armor = self:addTemporaryValue("combat_armor", t.getArmor(self, t)), |
36 | - particle = self:addParticles(Particles.new("stone_skin", 1)), | |
37 | 36 | } |
37 | + if not self:addShaderAura("stone_skin", "crystalineaura", {time_factor=1500, spikeOffset=0.123123, spikeLength=0.9, spikeWidth=3, growthSpeed=2, color={0xD7/255, 0x8E/255, 0x45/255}}, "particles_images/spikes.png") then | |
38 | + ret.particle = self:addParticles(Particles.new("stone_skin", 1)) | |
39 | + end | |
40 | + return ret | |
38 | 41 | end, |
39 | 42 | deactivate = function(self, t, p) |
43 | + self:removeShaderAura("stone_skin") | |
40 | 44 | self:removeParticles(p.particle) |
41 | 45 | self:removeTemporaryValue("combat_armor", p.armor) |
42 | 46 | return true | ... | ... |
... | ... | @@ -120,12 +120,16 @@ newTalent{ |
120 | 120 | activate = function(self, t) |
121 | 121 | game:playSoundNear(self, "talents/ice") |
122 | 122 | local ret = {} |
123 | + self:addShaderAura("body_of_ice", "crystalineaura", {}, "particles_images/spikes.png") | |
124 | + ret.particle = self:addParticles(Particles.new("snowfall", 1)) | |
123 | 125 | self:talentTemporaryValue(ret, "resists", {[DamageType.PHYSICAL] = t.getResistance(self, t) * 0.6}) |
124 | 126 | self:talentTemporaryValue(ret, "damage_affinity", {[DamageType.COLD] = t.getAffinity(self, t)}) |
125 | 127 | self:talentTemporaryValue(ret, "ignore_direct_crits", t.critResist(self, t)) |
126 | 128 | return ret |
127 | 129 | end, |
128 | 130 | deactivate = function(self, t, p) |
131 | + self:removeParticles(p.particle) | |
132 | + self:removeShaderAura("body_of_ice") | |
129 | 133 | return true |
130 | 134 | end, |
131 | 135 | info = function(self, t) | ... | ... |
... | ... | @@ -2414,8 +2414,12 @@ newEffect{ |
2414 | 2414 | self:effectTemporaryValue(eff, "on_melee_hit", {[DamageType.COLD]=eff.dam}) |
2415 | 2415 | self:effectTemporaryValue(eff, "all_damage_convert", DamageType.COLD) |
2416 | 2416 | self:effectTemporaryValue(eff, "all_damage_convert_percent", 50) |
2417 | + self:addShaderAura("ice_armour", "crystalineaura", {}, "particles_images/spikes.png") | |
2418 | + eff.particle = self:addParticles(Particles.new("snowfall", 1)) | |
2417 | 2419 | end, |
2418 | 2420 | deactivate = function(self, eff) |
2421 | + self:removeShaderAura("ice_armour") | |
2422 | + self:removeParticles(eff.particle) | |
2419 | 2423 | end, |
2420 | 2424 | } |
2421 | 2425 | ... | ... |
-
Please register or login to post a comment