sorcery  Diff

Differences From Artifact [720c3d8102]:

To Artifact [47aa367750]:


    32     32   						name = 'Arrival';
    33     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";
    34     34   					};
    35     35   				};
    36     36   			};
    37     37   			sapphire = {
    38     38   				name = 'Return';
    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.';
           39  +				desc = 'Use this amulet once to bind it to a particular place, then discharge its spell to translocate yourself back to that point from anywhere in the world.';
    40     40   				remove = function(ctx)
    41     41   					ctx.meta:set_string('rune_return_dest','')
    42     42   				end;
    43     43   				cast = function(ctx)
    44     44   					if not ctx.meta:contains('rune_return_dest') then
    45     45   						local pos = ctx.caster:get_pos()
    46     46   						ctx.meta:set_string('rune_return_dest',minetest.pos_to_string(pos))
................................................................................
    47     47   						return true -- play effects but do not break spell
    48     48   					else
    49     49   						local pos = minetest.string_to_pos(ctx.meta:get_string('rune_return_dest'))
    50     50   						ctx.meta:set_string('rune_return_dest','')
    51     51   						local subjects = { ctx.caster }
    52     52   						local center = ctx.caster:get_pos()
    53     53   						ctx.sparkle = false
           54  +						local delay = math.max(3,10 - ctx.stats.power) + 3*(math.random()*2-1)
           55  +						print('teledelay',delay,ctx.stats.power)
    54     56   						for _,s in pairs(subjects) do
    55     57   							local offset = vector.subtract(s:get_pos(), center)
    56     58   							local pt = sorcery.lib.node.get_arrival_point(vector.add(pos,offset))
    57     59   							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)
           60  +								minetest.sound_play('sorcery_stutter', {
           61  +									object = s, gain = 0.8;
           62  +								},true)
           63  +								local windup = minetest.sound_play('sorcery_windup',{
           64  +									object = s, gain = 0.4;
           65  +								})
           66  +								local mydelay = delay + math.random(-10,10)*.1;
           67  +								local spark = sorcery.lib.image('sorcery_spark.png')
           68  +								local sh = s:get_properties().eye_height
           69  +								local sparkle = function(amt,time,minsize,maxsize)
           70  +									minetest.add_particlespawner {
           71  +										amount = amt, time = time, attached = s;
           72  +										minpos = { x = -0.3, y = -0.5, z = -0.3 };
           73  +										maxpos = { x =  0.3, y = sh*1.1, z = 0.3 };
           74  +										minvel = { x = -0.4, y = -0.2, z = -0.4 };
           75  +										maxvel = { x =  0.4, y =  0.2, z =  0.4 };
           76  +										minacc = { x = -0.5, y = -0.4, z = -0.5 };
           77  +										maxacc = { x =  0.5, y =  0.4, z =  0.5 };
           78  +										minexptime = 1.0, maxexptime = 2.0;
           79  +										minsize = minsize, maxsize = maxsize, glow = 14;
           80  +										texture = spark:blit(spark:multiply(sorcery.lib.color(29,205,247))):render();
           81  +										animation = {
           82  +											type = 'vertical_frames';
           83  +											aspect_w = 16, aspect_h = 16;
           84  +										};
           85  +									}
           86  +								end
           87  +								sparkle(mydelay*100,mydelay,0.3,1.3)
           88  +								minetest.after(mydelay*0.4, function()
           89  +									local timeleft = mydelay - (mydelay*0.4)
           90  +									sparkle(timeleft*150, timeleft, 0.6,1.8)
           91  +								end)
           92  +								minetest.after(mydelay*0.7, function()
           93  +									local timeleft = mydelay - (mydelay*0.7)
           94  +									sparkle(timeleft*80, timeleft, 2,4)
           95  +								end)
           96  +								sorcery.lib.node.preload(pt,s)
           97  +								minetest.after(mydelay, function()
           98  +									minetest.sound_stop(windup)
           99  +									minetest.sound_play('sorcery_zap', { pos = pt, gain = 0.4 },true)
          100  +									minetest.sound_play('sorcery_zap', { pos = s:get_pos(), gain = 0.4 },true)
          101  +									sorcery.vfx.body_sparkle(nil,sorcery.lib.color(20,255,120),2,s:get_pos())
          102  +									s:set_pos(pt)
          103  +									sorcery.vfx.body_sparkle(s,sorcery.lib.color(20,120,255),2)
          104  +								end)
    61    105   							end
    62    106   						end
    63    107   					end
    64    108   				end;
    65    109   				frame = {
    66    110   					iridium = {
    67    111   						name = 'Mass Return';
    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';
          112  +						desc = 'Use this amulet once to bind it to a particular place, then carry yourself and everyone around you back to that point in a flash simply by using it again';
    69    113   					};
    70    114   				};
    71    115   			};
    72    116   			emerald = {
    73    117   				name = 'Banishment';
    74    118   				desc = 'Use this amulet once to bind it to a particular point in the world, then wield it against a foe to whisk them away immediately to your chosen prison';
    75    119   				frame = {
    76    120   					iridium = {
    77    121   						name = 'Mass Banishment';
    78    122   						desc = 'Use this amulet once to bind it to a particular point in the world, then use it again to seize up everyone surrounding you in the grip of a fearsome magic that will deport them all in the blink of an eye to whatever destination you have chosen';
    79    123   					};
    80    124   				};
    81    125   			};
    82         -			ruby = {
          126  +			ruby = minetest.get_modpath('beds') and {
    83    127   				name = 'Escape';
    84    128   				desc = 'Immediately transport yourself out of a dangerous situation back to the last place you slept';
          129  +				cast = function(ctx)
          130  +					-- if not beds.spawns then beds.read_spawns() end
          131  +					local subjects = {ctx.caster}
          132  +					for _,s in pairs(subjects) do
          133  +						local spp = beds.spawn[ctx.caster:get_player_name()]
          134  +						if spp then
          135  +							local oldpos = s:get_pos()
          136  +							minetest.sound_play('sorcery_splunch', {pos=oldpos}, true)
          137  +							sorcery.vfx.body_sparkle(nil,sorcery.lib.color(244,38,131),2,oldpos)
          138  +							s:set_pos(spp)
          139  +							minetest.sound_play('sorcery_splunch', {pos=spp}, true)
          140  +							sorcery.vfx.body_sparkle(nil,sorcery.lib.color(244,38,89),2,spp)
          141  +						end
          142  +						-- TODO decide what happens to the people who don't have
          143  +						-- respawn points already set
          144  +					end
          145  +				end;
    85    146   				frame = {
    86    147   					cobalt = {
    87    148   						name = 'Vengeful Exit';
    88    149   						desc = 'Translocate away to the safety of your boudoir with a fearsome blast of dangerous radiance that will send bodies flying and deal heavy damage to those nearby';
    89    150   					};
    90    151   					iridium = {
    91    152   						name = 'Mass Escape';
................................................................................
   121    182   		minpower = 1;
   122    183   		rarity = 7;
   123    184   		amulets = {
   124    185   			amethyst = {
   125    186   				name = 'Hurling';
   126    187   				desc = 'Wielding this amulet, a mere flick of your fingers will lift any target of your choice bodily into the air and press upon them with tremendous repulsive force, throwing them like a hapless ragdoll out of your path';
   127    188   			};
   128         -			diamond = {
          189  +			sapphire = {
          190  +				name = 'Flinging';
          191  +				desc = 'Toss an enemy violently into the air, and allow the inevitable impact to do your dirty work for you';
          192  +			};
          193  +			emerald = {
   129    194   				name = 'Shockwave';
          195  +				desc = 'Let loose a stream of concussive force that slams into everything in your path and sends them hurtling away from you';
          196  +			};
          197  +			luxite = {
          198  +				name = 'Repulsive Aura';
          199  +				desc = 'For a period of time, anyone who approaches you will be violently thrust aside';
          200  +			};
          201  +			diamond = {
          202  +				name = 'Blastwave';
   130    203   				desc = 'Unleash a tidal wave of force in every direction, blasting friends and foes alike away from you with enough violence to sprain and fracture bone';
   131    204   			};
   132    205   		};
   133    206   	};
   134    207   	obliterate = {
   135    208   		name = 'Obliterate';
   136    209   		tone = {255,0,10};
................................................................................
   141    214   				name = 'Sapping';
   142    215   				desc = 'Punch a hole in enemy fortifications big enough to slip through but small enough to avoid immediate attention';
   143    216   			};
   144    217   			ruby = {
   145    218   				name = 'Shattering';
   146    219   				desc = 'Tear a violent wound in the earth with the destructive force of this amulet';
   147    220   			};
          221  +			emerald = {
          222  +				name = 'Detonate';
          223  +				desc = 'Wielding this amulet, you can loose an extraordinarily powerful bolt of flame from your fingertips that will explode violently on impact, wreaking total havoc wherever it lands';
          224  +				cast = function(ctx)
          225  +					local speed = 40
          226  +					local radius = math.random(math.floor(ctx.stats.power*0.5),math.ceil(ctx.stats.power))
          227  +					local heading = ctx.heading
          228  +					heading.pos.y = heading.pos.y + heading.eyeheight*0.9
          229  +					local vel = vector.multiply(heading.yaw,speed)
          230  +					local bolt = minetest.add_entity(vector.add(heading.pos,vector.multiply(heading.yaw,2.5)),'sorcery:spell_projectile_flamebolt')
          231  +					bolt:set_rotation(heading.yaw)
          232  +					bolt:get_luaentity()._blastradius = radius
          233  +					bolt:set_velocity(vel)
          234  +				end;
          235  +			};
          236  +			luxite = {
          237  +				name = 'Lethal Aura';
          238  +				desc = 'For a time, anyone who approaches you, whether friend or foe, will suffer immediate retaliation as they are quickly sapped of their life force';
          239  +			};
   148    240   			diamond = {
   149    241   				name = 'Killing';
          242  +				mingrade = 4;
   150    243   				desc = 'Wield this amulet against a foe to instantly snuff the life out of their mortal form, regardless of their physical protections.';
   151    244   				cast = function(ctx)
   152    245   					if not (ctx.target and ctx.target.type == 'object') then return false end
   153    246   					local tgt = ctx.target.ref
   154    247   					if not minetest.is_player(obj) then return false end
   155    248   					local tgth = tgt:get_properties().eye_height
   156    249   					sorcery.vfx.bloodburst(vector.add(tgt:get_pos(),{x=0,y=tgth/2,z=0}),20)
................................................................................
   206    299   			};
   207    300   			diamond = {
   208    301   				name = 'Radiance';
   209    302   				desc = 'Set the air around you alight with a mystic luminance, letting you see clearly a great distance in every direction for several minutes';
   210    303   				frame = {
   211    304   					iridium = {
   212    305   						name = 'Sunshine';
          306  +						mingrade = 5;
   213    307   						desc = 'Unleash the power of this amulet to seize ultimate control over the forces of nature and summon the Sun high into the nighttime sky';
   214    308   					};
   215    309   				};
   216    310   			};
   217    311   		};
   218    312   	};
   219    313   	dominate = {
................................................................................
   222    316   		minpower = 4;
   223    317   		rarity = 40;
   224    318   		amulets = {
   225    319   			amethyst = {
   226    320   				name = 'Suffocation';
   227    321   				desc = 'Wrap this spell tightly around your victim\'s throat, cutting off their oxygen until you release them.';
   228    322   			};
          323  +			emerald = {
          324  +				name = 'Caging';
          325  +				desc = 'Trap your victim in an impenetrable field of force, leaving them with no way out but translocation or waiting for the field to release them';
          326  +			};
   229    327   			ruby = {
   230    328   				name = 'Exsanguination';
   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';
          329  +				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 being';
   232    330   				cast = function(ctx)
   233    331   					if not (ctx.target and ctx.target.type == 'object') then return false end
   234    332   					local tgt = ctx.target.ref
   235    333   					local takefac = math.min(99,50 + (ctx.stats.power * 5)) / 100
   236    334   					local dmg = tgt:get_hp() * takefac
   237    335   					print("!!! dmg calc",takefac,dmg,tgt:get_hp())
   238    336