Differences From
Artifact [bd35ca52e8]:
- File
data/runes.lua
— part of check-in
[96c5289a2a]
at
2020-10-21 03:35:35
on branch trunk
— add rune forges, runes, amulet frames, write sacrifice spell, touch up amulet graphics, enable enchantment of amulets (though spells cannot yet be cast), defuckulate syncresis core icon, unfuckitize sneaky leycalc bug that's probably been the cause of some long-standing wackiness, add item classes, add some more textures, disbungle various other asstastrophes, remove sneaky old debug code, improve library code, add utility for uploading merge requests
(user:
lexi,
size: 6898)
[annotate]
[blame]
[check-ins using]
9 9 name = 'Translocate';
10 10 tone = {0,235,233};
11 11 minpower = 3;
12 12 rarity = 15;
13 13 amulets = {
14 14 amethyst = {
15 15 name = 'Joining';
16 - desc = 'Give this amulet to another and they can arrive at your side in a flash from anywhere in the world — though returning whence they came may be a more difficult matter';
16 + desc = 'Give this amulet to another and they can arrive safely at your side in a flash from anywhere in the world — though returning whence they came may be a more difficult matter';
17 + apply = function(ctx)
18 + local maker = ctx.user:get_player_name()
19 + ctx.meta:set_string('rune_join_target',maker)
20 + end;
21 + remove = function(ctx) ctx.meta:set_string('rune_join_target','') end;
17 22 frame = {
18 23 gold = {
19 24 name = 'Exchange';
20 25 desc = 'Give this amulet to another and they will be able to trade places with you no matter where in the world each of you might be.';
21 26 };
22 27 cobalt = {
23 28 name = 'Sending';
................................................................................
27 32 name = 'Arrival';
28 33 desc = "Give this amulet to another and they will be able to arrive at your side in a flash from anywhere in the world, carrying others with them in the spell's grip";
29 34 };
30 35 };
31 36 };
32 37 sapphire = {
33 38 name = 'Return';
34 - desc = 'Use this amulet once to bind it to a particular point in the world, then use it again to return instantly to that point.';
39 + desc = 'Use this amulet once to bind it to a particular point in the world, then discharge its spell to return instantly to that point.';
40 + remove = function(ctx)
41 + ctx.meta:set_string('rune_return_dest','')
42 + end;
43 + cast = function(ctx)
44 + if not ctx.meta:contains('rune_return_dest') then
45 + local pos = ctx.caster:get_pos()
46 + ctx.meta:set_string('rune_return_dest',minetest.pos_to_string(pos))
47 + return true -- play effects but do not break spell
48 + else
49 + local pos = minetest.string_to_pos(ctx.meta:get_string('rune_return_dest'))
50 + ctx.meta:set_string('rune_return_dest','')
51 + local subjects = { ctx.caster }
52 + local center = ctx.caster:get_pos()
53 + ctx.sparkle = false
54 + for _,s in pairs(subjects) do
55 + local offset = vector.subtract(s:get_pos(), center)
56 + local pt = sorcery.lib.node.get_arrival_point(vector.add(pos,offset))
57 + if pt then
58 + sorcery.vfx.body_sparkle(s,sorcery.lib.color(20,120,255),2)
59 + sorcery.vfx.body_sparkle(nil,sorcery.lib.color(20,255,120),2,pt)
60 + s:set_pos(pt)
61 + end
62 + end
63 + end
64 + end;
35 65 frame = {
36 66 iridium = {
37 67 name = 'Mass Return';
38 68 desc = 'Use this amulet once to bind it to a particular point in the world, then carry yourself and everyone around you back to that point in a flash simply by using it again';
39 69 };
40 70 };
41 71 };
................................................................................
114 144 ruby = {
115 145 name = 'Shattering';
116 146 desc = 'Tear a violent wound in the earth with the destructive force of this amulet';
117 147 };
118 148 diamond = {
119 149 name = 'Killing';
120 150 desc = 'Wield this amulet against a foe to instantly snuff the life out of their mortal form, regardless of their physical protections.';
151 + cast = function(ctx)
152 + if not (ctx.target and ctx.target.type == 'object') then return false end
153 + local tgt = ctx.target.ref
154 + if not minetest.is_player(obj) then return false end
155 + local tgth = tgt:get_properties().eye_height
156 + sorcery.vfx.bloodburst(vector.add(tgt:get_pos(),{x=0,y=tgth/2,z=0}),20)
157 + minetest.sound_play('sorcery_bloody_burst', { pos = pos, gain = 1.5 })
158 + tgt:set_hp(0)
159 + end;
121 160 frame = {
122 161 iridium = {
123 162 name = 'Massacre';
124 163 desc = "Unleash the dark and wicked force that lurks within this fell amulet to instantaneously slay all those who surround you, friend and foe alike";
125 164 };
126 165 };
127 166 };
................................................................................
179 218 };
180 219 dominate = {
181 220 name = 'Dominate';
182 221 tone = {235,0,228};
183 222 minpower = 4;
184 223 rarity = 40;
185 224 amulets = {
225 + amethyst = {
226 + name = 'Suffocation';
227 + desc = 'Wrap this spell tightly around your victim\'s throat, cutting off their oxygen until you release them.';
228 + };
186 229 ruby = {
187 230 name = 'Exsanguination';
188 231 desc = 'Rip the life force out of another, leaving them on the brink of death, and use it to mend your own wounds and invigorate your own being';
232 + cast = function(ctx)
233 + if not (ctx.target and ctx.target.type == 'object') then return false end
234 + local tgt = ctx.target.ref
235 + local takefac = math.min(99,50 + (ctx.stats.power * 5)) / 100
236 + local dmg = tgt:get_hp() * takefac
237 + print("!!! dmg calc",takefac,dmg,tgt:get_hp())
238 +
239 + local numhits = math.random(6,10+ctx.stats.power/2)
240 + local function dohit(hitsleft)
241 + if tgt == nil or tgt:get_properties() == nil then return end
242 + tgt:punch(ctx.caster, 1, {
243 + full_punch_interval = 1;
244 + damage_groups = { fleshy = dmg / numhits }
245 + })
246 + local tgth = tgt:get_properties().eye_height
247 + sorcery.vfx.bloodburst(vector.add(tgt:get_pos(),{x=0,y=tgth/2,z=0}),math.random(10 * takefac, 40 * takefac))
248 + ctx.caster:set_hp(ctx.caster:get_hp() + math.max(1,(dmg/numhits)*takefac))
249 +
250 + local sound = {'sorcery_bloody_hit','sorcery_crunch',false}
251 + sound = sound[math.random(#sound)]
252 + if sound ~= false then
253 + minetest.sound_play(sound, { pos = pos, gain = math.random(5,15)*0.1 })
254 + end
255 +
256 + local nexthit = math.random() * 0.4 + 0.1
257 + local dir = vector.subtract(ctx.caster:get_pos(), tgt:get_pos())
258 + local spark = sorcery.lib.image('sorcery_spark.png')
259 + minetest.add_particlespawner {
260 + amount = math.random(80*takefac,150*takefac);
261 + texture = spark:blit(spark:multiply(sorcery.lib.color(255,20,10))):render();
262 + time = nexthit;
263 + attached = tgt;
264 + minpos = {x = -0.3, y = -0.5, z = -0.3};
265 + maxpos = {x = 0.3, y = tgth, z = 0.3};
266 + minvel = vector.multiply(dir,0.5);
267 + maxvel = vector.multiply(dir,0.9);
268 + minacc = vector.multiply(dir,0.1);
269 + maxacc = vector.multiply(dir,0.2);
270 + minexptime = nexthit * 1.5;
271 + maxexptime = nexthit * 2;
272 + minsize = 0.5;
273 + maxsize = 5 * takefac;
274 + glow = 14;
275 + animation = {
276 + type = 'vertical_frames';
277 + aspect_w = 16, aspect_h = 16;
278 + length = nexthit*2 + 0.1;
279 + };
280 + }
281 +
282 + if hitsleft > 0 then
283 + minetest.after(nexthit, function() dohit(hitsleft-1) end)
284 + end
285 + end
286 + dohit(numhits)
287 + end;
189 288 };
190 289 amethyst = {
191 290 name = 'Disarming';
192 291 desc = 'Wield this amulet against a foe to rip all the weapons in their possession out of their grasp';
193 292 frame = {
194 293 iridium = {
195 294 name = 'Peacemaking';