Add scripted lightning weapon mods with interpolated anchored effects
This commit is contained in:
1 parent
98465133aa
commit
c0a6fd3431
50 files changed
+3500
-65
No files matched your search
@@ -0,0 +1,6 @@
|
||||
// Pickups use the same reusable equipment as the shop.
|
||||
fn on_pickup(event, state, random) {
|
||||
let recovered = if state.contains("recovered") { state.recovered % 100000 + 1 } else { 1 };
|
||||
#{ commands: [#{ op: "objective", key: "lightning_shield:recovered", value: recovered }],
|
||||
state: #{ recovered: recovered } }
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
// This is an ordinary non-special weapon: it runs only while Fire is held.
|
||||
// Measure range to the nearest point of an enemy hull, not its center, so large
|
||||
// ships can be zapped at the edge too. The reach is only 12px past our 32px hull.
|
||||
fn on_fire(event, state, random) {
|
||||
if event.hostile {
|
||||
return #{ commands: [], state: state };
|
||||
}
|
||||
let bursts = if state.contains("bursts") { state.bursts % 100000 + 1 } else { 1 };
|
||||
let hits = if state.contains("hits") { state.hits } else { 0 };
|
||||
let commands = [];
|
||||
let struck = [];
|
||||
let from_x = event.player.x + 16;
|
||||
let from_y = event.player.y + 16;
|
||||
|
||||
// An electric halo just outside the hull follows the ship throughout the
|
||||
// recharge. Both endpoints use the public arc anchoring API; it is visual
|
||||
// only, so even an empty pulse still lights the ring without playing audio.
|
||||
let ring = [[19, 0], [18, 7], [13, 13], [7, 18], [0, 19], [-7, 18],
|
||||
[-13, 13], [-18, 7], [-19, 0], [-18, -7], [-13, -13],
|
||||
[-7, -18], [0, -19], [7, -18], [13, -13], [18, -7]];
|
||||
for i in 0..ring.len() {
|
||||
let a = ring[i];
|
||||
let b = ring[(i + 1) % ring.len()];
|
||||
commands.push(#{ op: "arc", x: from_x + a[0], y: from_y + a[1],
|
||||
to_x: from_x + b[0], to_y: from_y + b[1],
|
||||
anchor: 0, to_anchor: 0, ticks: 8 });
|
||||
}
|
||||
|
||||
// Bound each pulse's work and sound: at most four close airborne ships.
|
||||
for target in 0..4 {
|
||||
let selected = #{};
|
||||
let nearest = 1000000;
|
||||
for enemy in event.entities {
|
||||
if enemy.health <= 0 || enemy.ground || struck.contains(enemy.entity) {
|
||||
continue;
|
||||
}
|
||||
let x = max(enemy.x, min(from_x, enemy.x + enemy.width - 1));
|
||||
let y = max(enemy.y, min(from_y, enemy.y + enemy.height - 1));
|
||||
if x < 0 || x >= 320 || y < 0 || y >= 200 { continue; }
|
||||
let dx = x - from_x;
|
||||
let dy = y - from_y;
|
||||
let distance = dx * dx + dy * dy;
|
||||
if distance <= 28 * 28 && distance < nearest {
|
||||
selected = #{ entity: enemy.entity, x: x, y: y };
|
||||
nearest = distance;
|
||||
}
|
||||
}
|
||||
if !selected.contains("entity") { break; }
|
||||
// Start at the halo point facing this hull, not at the player's center.
|
||||
let dx = selected.x - from_x;
|
||||
let dy = selected.y - from_y;
|
||||
let origin = ring[0];
|
||||
let best = -1000000;
|
||||
for point in ring {
|
||||
let facing = point[0] * dx + point[1] * dy;
|
||||
if facing > best { best = facing; origin = point; }
|
||||
}
|
||||
commands.push(#{ op: "arc", x: from_x + origin[0], y: from_y + origin[1],
|
||||
to_x: selected.x, to_y: selected.y,
|
||||
anchor: 0, to_anchor: selected.entity, ticks: 3 });
|
||||
commands.push(#{ op: "damage", entity: selected.entity, amount: 2 });
|
||||
struck.push(selected.entity);
|
||||
hits = hits % 100000 + 1;
|
||||
}
|
||||
if struck.len() > 0 {
|
||||
commands.push(#{ op: "play_sound", sound: "lightning_shield:fire" });
|
||||
commands.push(#{ op: "play_sound", sound: "lightning_shield:impact" });
|
||||
}
|
||||
#{ commands: commands, state: #{ bursts: bursts, hits: hits } }
|
||||
}
|
||||
Reference in new issue
Block a user