Add all files

This commit is contained in:
2025-04-18 22:30:19 +02:00
parent 44aec1a1fb
commit 4ec52c34d4
2477 changed files with 76624 additions and 0 deletions

View File

@@ -0,0 +1,509 @@
extends CharacterBody2D
var tileParticleScene = preload("res://scripts/components/TileParticle.tscn")
var liftable = true
var thrown_by = null
var entity_id = ""
var object_name = "bomb"
@export var is_being_thrown = false
@export var is_being_lifted = false
@export var is_being_put_down = false
@export var is_being_grabbed = false
@export var is_moving = false
@export var is_spawning = false
@export var is_fused = false
var throw_speed = 200
var throw_height = 30
var current_height = 0
var gravity = 800
var holder = null
var flipFromWall = false
# Add Z-axis variables similar to loot.gd
@export var positionZ = 0.0
var velocityZ = 0.0
var accelerationZ = -330.0 # Gravity
var bounceRestitution = 0.3
var minBounceVelocity = 60.0
var destroy_initiated = false
@export var is_destroyed = false
# Smooth lifting variables
var target_position = Vector2.ZERO
var lift_height = 12.0 # Height above player's head
var lift_speed = 10.0 # Speed of smooth movement
var put_down_start_pos = Vector2.ZERO
var put_down_target_pos = Vector2.ZERO
@export var lift_progress = 0.0
var re_enable_collision_after_time = 0.0
var re_enable_time = 0.17
var previousFrameVel = Vector2.ZERO
var hasShownSmokePuffs = false
func _ready() -> void:
if is_spawning:
liftable = false
$Area2DCollision.set_deferred("monitoring", false)
self.set_collision_layer_value(8, false)
self.set_collision_mask_value(9, false)
self.set_collision_mask_value(10, false)
self.set_collision_mask_value(8, false)
update_sprite_scale()
pass
indicate(false)
pass
func _physics_process(delta: float) -> void:
if multiplayer.is_server():
if is_being_thrown:
re_enable_collision_after_time -= delta
if re_enable_collision_after_time <= 0.0:
# enable collisions again
self.set_collision_layer_value(8, true)
self.set_collision_mask_value(9, true)
self.set_collision_mask_value(10, true)
self.set_collision_mask_value(8, true)
re_enable_collision_after_time = 0
# Apply gravity to vertical movement
velocityZ += accelerationZ * delta
positionZ += velocityZ * delta
if positionZ <= 0:
# Pot has hit the ground
positionZ = 0
$SfxLand.play()
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
if abs(velocityZ) > minBounceVelocity:
velocityZ = -velocityZ * bounceRestitution
else:
velocityZ = 0
is_being_thrown = false
velocity = velocity.lerp(Vector2.ZERO, 0.5)
if velocity.x == 0 and velocity.y == 0:
thrown_by = null
# Move horizontally
var collision = move_and_collide(velocity * delta)
if collision:
if positionZ == 0:
is_being_thrown = false
update_sprite_scale()
elif is_being_put_down:
lift_progress -= delta * lift_speed
if lift_progress <= 0.0:
$SfxLand.play()
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
lift_progress = 0
is_being_put_down = false
is_being_lifted = false
holder = null
positionZ = 0
# enable collisions again
self.set_collision_layer_value(8, true)
self.set_collision_mask_value(9, true)
self.set_collision_mask_value(10, true)
self.set_collision_mask_value(7, true)
self.set_collision_mask_value(8, true)
$Area2DCollision.set_deferred("monitoring", true)
else:
global_position = put_down_start_pos.lerp(put_down_target_pos, 1.0 - lift_progress)
positionZ = lift_height * lift_progress
update_sprite_scale()
elif is_being_lifted:
# Smooth lifting animation
if holder:
$GPUParticles2D.emitting = false
target_position = holder.global_position
#target_position.y -= 2
if lift_progress < 1.0:
lift_progress += delta * lift_speed
lift_progress = min(lift_progress, 1.0)
global_position = global_position.lerp(target_position, lift_progress)
positionZ = lift_height * lift_progress
else:
lift_progress = 1.0
global_position = target_position
positionZ = lift_height
update_sprite_scale()
pass
elif is_being_grabbed:
#if velocity != Vector2.ZERO and velocity != previousFrameVel and hasShownSmokePuffs == false:
if velocity != Vector2.ZERO:
is_moving = true
#hasShownSmokePuffs = true
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
if !$SfxDrag2.playing:
$SfxDrag2.play()
else:
is_moving = false
if $SfxDrag2.playing:
$SfxDrag2.stop()
move_and_collide(velocity * delta)
previousFrameVel = velocity
pass
else: # it just spawned:
# Apply gravity to vertical movement
velocityZ += accelerationZ * delta
positionZ += velocityZ * delta
if positionZ <= 0:
if is_spawning:
is_spawning = false
liftable = true
$Area2DCollision.set_deferred("monitoring", true)
self.set_collision_layer_value(8, true)
self.set_collision_mask_value(9, true)
self.set_collision_mask_value(10, true)
self.set_collision_mask_value(8, true)
# Pot has hit the ground
positionZ = 0
if abs(velocityZ) > 30:
$SfxLand.play()
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
if abs(velocityZ) > minBounceVelocity:
velocityZ = -velocityZ * bounceRestitution
else:
velocityZ = 0
velocity = velocity.lerp(Vector2.ZERO, 0.5)
move_and_collide(velocity * delta)
update_sprite_scale()
pass
else:
if is_fused and $AnimationPlayer.current_animation == "idle":
if $SfxBombFuse.playing:
$SfxBombFuse.play()
$AnimationPlayer.play("fused")
# for client:'
if is_being_thrown:
if $SfxDrag2.playing:
$SfxDrag2.stop()
if positionZ <= 0:
if !$SfxLand.playing:
$SfxLand.play()
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
elif is_being_put_down:
if $SfxDrag2.playing:
$SfxDrag2.stop()
if !$SfxLand.playing:
$SfxLand.play()
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
elif is_being_lifted:
if $SfxDrag2.playing:
$SfxDrag2.stop()
$GPUParticles2D.emitting = false
elif is_being_grabbed:
if is_moving:
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
if !$SfxDrag2.playing:
$SfxDrag2.play()
else:
if $SfxDrag2.playing:
$SfxDrag2.stop()
else:
if is_spawning:
if positionZ <= 0:
$SfxLand.play()
$GPUParticles2D.emitting = true
$GPUParticles2D/TimerSmokeParticles.start()
else:
if $SfxLand.playing:
$SfxLand.stop()
if $SfxDrag2.playing:
$SfxDrag2.stop()
pass
update_sprite_scale()
if is_destroyed and !destroy_initiated:
destroy_initiated = true
show_destroy_effect()
pass
pass
func update_sprite_scale() -> void:
# Calculate scale based on height
# Maximum height will have scale 1.3, ground will have scale 1.0
var height_factor = positionZ / 50.0 # Assuming 50 is max height
var posY = positionZ # Direct mapping of Z to Y offset
var sc = 1.0 + (0.1 * height_factor) # Slightly less scale change than loot (0.3 instead of 0.8)
$Sprite2D.scale = Vector2(sc, sc)
$Sprite2D.offset.y = -posY
# Also update shadow position and scale
if is_being_lifted:
$Sprite2D.z_as_relative = false
$Sprite2D.z_index = 12
$Sprite2DShadow.offset.y = 0 # Base shadow position
else:
$Sprite2D.z_as_relative = true
$Sprite2D.z_index = 0
$Sprite2DShadow.offset.y = 0
#$Sprite2DShadow.scale = Vector2(1.125 * sc, 0.5 * sc) # Scale shadow with height
$Sprite2DShadow.scale = Vector2(1,1)
#$Sprite2DShadow.modulate.
func throw(direction: Vector2, initial_velocity: float = 200):
self.set_collision_mask_value(7, true)
$Area2DCollision.set_deferred("monitoring", true)
$SfxThrow.play()
is_being_lifted = false
is_being_thrown = true
is_being_put_down = false
thrown_by = holder
holder = null
velocity = direction * initial_velocity
velocityZ = throw_height
positionZ = lift_height
current_height = 0
re_enable_collision_after_time = re_enable_time
func grab(new_holder: CharacterBody2D) -> bool:
if positionZ <= 0 and holder == null: # only allow grab if no previous owner and position is 0
$GPUParticles2D/TimerSmokeParticles.stop() #reset...
holder = new_holder
is_being_grabbed = true
indicate(false)
return true
return false
func release():
holder = null
is_being_grabbed = false
hasShownSmokePuffs = false
indicate(true)
if $SfxDrag2.playing:
$SfxDrag2.stop()
pass
func lift(new_holder: CharacterBody2D):
if (new_holder != holder and holder != null) and "lose_held_entity" in holder:
# steal from holder
holder.lose_held_entity(self)
indicate(false)
$Area2DCollision.set_deferred("monitoring", false)
thrown_by = null
holder = new_holder
# disable collisions
self.set_collision_layer_value(8, false)
self.set_collision_mask_value(7, false)
self.set_collision_mask_value(8, false)
self.set_collision_mask_value(9, false)
self.set_collision_mask_value(10, false)
is_being_lifted = true
is_being_grabbed = false
is_being_thrown = false
is_being_put_down = false
lift_progress = 0.0
velocityZ = 0
$SfxLand.play()
func put_down() -> bool:
if not is_being_lifted or is_being_put_down:
return false
var dropDir = holder.last_direction
dropDir.x *= 12
if dropDir.y > 0:
dropDir.y *= 10
else:
dropDir.y *= 10
put_down_target_pos = holder.global_position + dropDir
# First check: Direct space state query for walls
var space_state = get_world_2d().direct_space_state
var params = PhysicsPointQueryParameters2D.new()
params.position = put_down_target_pos
params.collision_mask = 64 # Layer for walls (usually layer 7)
params.collide_with_areas = true
params.collide_with_bodies = true
var results = space_state.intersect_point(params)
if results.size() > 0:
# Found overlapping walls at target position
print("Cannot place pot: Wall in the way")
return false
# Second check: Line of sight between player and target position
var query = PhysicsRayQueryParameters2D.create(
holder.global_position,
put_down_target_pos,
64 # Wall collision mask
)
query.collide_with_areas = true
query.collide_with_bodies = true
var result = space_state.intersect_ray(query)
if result:
# Hit something between player and target position
print("Cannot place pot: Path blocked")
return false
# Third check: Make sure we're not placing on top of another pot or object
params.collision_mask = 128 # Layer for pots/objects
results = space_state.intersect_point(params)
if results.size() > 0:
# Found overlapping objects at target position
print("Cannot place pot: Object in the way")
return false
$Area2DCollision.set_deferred("monitoring", false)
# Position is valid, proceed with putting down
self.set_collision_mask_value(7, true) # instantly reenenable collision with wall
is_being_put_down = true
is_being_lifted = false
put_down_start_pos = global_position
thrown_by = null
holder = null
indicate(true)
return true
func remove():
var fade_tween = create_tween()
fade_tween.set_trans(Tween.TRANS_CUBIC)
fade_tween.set_ease(Tween.EASE_OUT)
fade_tween.tween_property($Sprite2D, "modulate:a", 0.0, 0.6)
#await fade_tween.finished
await $SfxShatter.finished
if $SfxLand.playing:
$SfxLand.stop()
if $SfxDrag2.playing:
$SfxDrag2.stop()
$GPUParticles2D.emitting = false
#$SfxShatter.stop()
if multiplayer.is_server():
call_deferred("queue_free")
pass
func create4TileParticles():
var sprite_texture = $Sprite2D.texture
var frame_width = sprite_texture.get_width() / $Sprite2D.hframes
var frame_height = sprite_texture.get_height() / $Sprite2D.vframes
var frame_x = ($Sprite2D.frame % $Sprite2D.hframes) * frame_width
var frame_y = ($Sprite2D.frame / $Sprite2D.hframes) * frame_height
# Create 4 particles with different directions and different parts of the texture
var directions = [
Vector2(-1, -1).normalized(), # Top-left
Vector2(1, -1).normalized(), # Top-right
Vector2(-1, 1).normalized(), # Bottom-left
Vector2(1, 1).normalized() # Bottom-right
]
var regions = [
Rect2(frame_x, frame_y, frame_width / 2, frame_height / 2), # Top-left
Rect2(frame_x + frame_width / 2, frame_y, frame_width / 2, frame_height / 2), # Top-right
Rect2(frame_x, frame_y + frame_height / 2, frame_width / 2, frame_height / 2), # Bottom-left
Rect2(frame_x + frame_width / 2, frame_y + frame_height / 2, frame_width / 2, frame_height / 2) # Bottom-right
]
for i in range(4):
var tp = tileParticleScene.instantiate() as CharacterBody2D
var spr2D = tp.get_node("Sprite2D") as Sprite2D
tp.global_position = global_position
# Set up the sprite's texture and region
spr2D.texture = sprite_texture
spr2D.region_enabled = true
spr2D.region_rect = regions[i]
# Add some randomness to the velocity
var speed = randf_range(170, 200)
var dir = directions[i] + Vector2(randf_range(-0.2, 0.2), randf_range(-0.2, 0.2))
tp.velocity = dir * speed
# Add some rotation
tp.angular_velocity = randf_range(-7, 7)
get_parent().call_deferred("add_child", tp)
func indicate(iIndicate: bool):
$Indicator.visible = iIndicate
if !liftable or is_being_lifted:
$Indicator.visible = false
pass
func _on_area_2d_collision_body_entered(body: Node2D) -> void:
if is_being_thrown == false or body == self or body == thrown_by:
return
if multiplayer.is_server():
var collision_shape = $Area2DCollision.get_overlapping_bodies()
if collision_shape.size() > 0:
var collider = collision_shape[0]
var normal = (global_position - collider.global_position).normalized()
if abs(velocity.x) > 0.05 or abs(velocity.y) > 0.05:
if "take_damage" in body or body is TileMapLayer or collider is TileMapLayer:
if "take_damage" in body:
body.take_damage(self, thrown_by)
elif collider != self and "breakPot" in collider:
collider.take_damage(self, thrown_by)
# create particles from pot:
print("ye body is:", body)
take_damage.rpc(null, null)
pass
normal = velocity.normalized()
velocity = velocity.bounce(normal) * 0.4 # slow down
pass # Replace with function body.
func show_destroy_effect():
$GPUParticles2D.emitting = true
$Sprite2D.frame = 13 + 19 + 19
$Sprite2DShadow.visible = false
liftable = false
indicate(false)
create4TileParticles()
is_being_thrown = false
$Sprite2DShadow.visible = false
# Play shatter sound
$SfxShatter.play()
self.call_deferred("remove")
pass
@rpc("call_local")
func take_damage(_iBody: Node2D, _iByWhoOrWhat: Node2D) -> void:
is_destroyed = true # will trigger show_destroy_effect for clients...
show_destroy_effect()
# remove all kind of collision since it's broken now...
self.set_deferred("monitoring", false)
self.set_collision_layer_value(8, false)
self.set_collision_mask_value(7, false)
self.set_collision_mask_value(8, false)
self.set_collision_mask_value(9, false)
self.set_collision_mask_value(10, false)
pass
func _on_area_2d_collision_body_exited(_body: Node2D) -> void:
pass # Replace with function body.
func _on_area_2d_pickup_body_entered(_body: Node2D) -> void:
indicate(true)
pass # Replace with function body.
func _on_area_2d_pickup_body_exited(_body: Node2D) -> void:
indicate(false)
pass # Replace with function body.
func _on_timer_smoke_particles_timeout() -> void:
$GPUParticles2D.emitting = false
pass # Replace with function body.