Detonate rifle grenades on impact with original Half-Life fireball
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
extends Node3D
|
||||
## Original Half-Life fireball, 15 frames at 15 FPS, additive camera-facing quad.
|
||||
## A PNG atlas avoids the native GoldSrc importer in Web exports.
|
||||
const ATLAS = preload("res://assets/effects/explosion/zerogxplode_atlas.png")
|
||||
const FRAME_COUNT := 15
|
||||
const FPS := 15.0
|
||||
const DURATION := FRAME_COUNT / FPS
|
||||
const SIZE := 3.2
|
||||
var elapsed := 0.0
|
||||
var frame_index := 0
|
||||
var fireball: MeshInstance3D
|
||||
var material: StandardMaterial3D
|
||||
|
||||
func _ready() -> void:
|
||||
name = "GrenadeExplosion"
|
||||
material = StandardMaterial3D.new()
|
||||
material.shading_mode = BaseMaterial3D.SHADING_MODE_UNSHADED
|
||||
material.transparency = BaseMaterial3D.TRANSPARENCY_ALPHA
|
||||
material.blend_mode = BaseMaterial3D.BLEND_MODE_ADD
|
||||
material.billboard_mode = BaseMaterial3D.BILLBOARD_ENABLED
|
||||
material.cull_mode = BaseMaterial3D.CULL_DISABLED
|
||||
material.albedo_texture = ATLAS
|
||||
material.texture_filter = BaseMaterial3D.TEXTURE_FILTER_LINEAR
|
||||
material.texture_repeat = false
|
||||
# Two-pixel black gutters prevent adjacent frames bleeding under filtering.
|
||||
material.uv1_scale = Vector3(64.0 / 340.0, 64.0 / 204.0, 1)
|
||||
fireball = MeshInstance3D.new()
|
||||
fireball.name = "Fireball"
|
||||
fireball.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
||||
var quad := QuadMesh.new()
|
||||
quad.size = Vector2(SIZE, SIZE)
|
||||
quad.material = material
|
||||
fireball.mesh = quad
|
||||
# Raise the fireball, but leave the damage origin at the physical impact.
|
||||
fireball.position.y = 0.8
|
||||
add_child(fireball)
|
||||
_set_frame(0)
|
||||
var light := OmniLight3D.new()
|
||||
light.name = "Flash"
|
||||
light.light_color = Color(1, 0.45, 0.08)
|
||||
light.light_energy = 8
|
||||
light.omni_range = 10
|
||||
light.shadow_enabled = false
|
||||
add_child(light)
|
||||
create_tween().tween_property(light, "light_energy", 0.0, 0.3)
|
||||
# Keep the node alive for the original explosion sound to finish.
|
||||
get_tree().create_timer(4).timeout.connect(queue_free)
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
elapsed += delta
|
||||
if elapsed >= DURATION:
|
||||
fireball.hide()
|
||||
set_process(false)
|
||||
return
|
||||
_set_frame(mini(int(elapsed * FPS), FRAME_COUNT - 1))
|
||||
|
||||
func _set_frame(index: int) -> void:
|
||||
frame_index = index
|
||||
material.uv1_offset = Vector3(
|
||||
(float(index % 5) * 68 + 2) / 340.0,
|
||||
(float(index / 5) * 68 + 2) / 204.0, 0)
|
||||
Reference in New Issue
Block a user