Demon Wall Model Changes, Added pulsing to Pipes

This commit is contained in:
Pal
2025-09-18 18:50:43 -07:00
parent 94c6c212ca
commit 13cd16f9e0
25 changed files with 624 additions and 139 deletions

View File

@@ -28,53 +28,53 @@ public partial class DemonWall : CharacterBody3D, IEnemy
public void OnReady()
{
CurrentHP = new AutoProp<double>(_enemyStatResource.MaximumHP);
_attackTimer = new Timer { WaitTime = 5f };
_attackTimer.Timeout += AttackTimer_Timeout;
AddChild(_attackTimer);
_damageCalculator = new DamageCalculator();
CurrentHP.Sync += CurrentHP_Sync;
CurrentHP = new AutoProp<double>(_enemyStatResource.MaximumHP);
_attackTimer = new Timer { WaitTime = 5f };
_attackTimer.Timeout += AttackTimer_Timeout;
AddChild(_attackTimer);
_damageCalculator = new DamageCalculator();
CurrentHP.Sync += CurrentHP_Sync;
}
private void CurrentHP_Sync(double newHP)
{
if (newHP <= 0)
Die();
if (newHP <= 0)
Die();
}
public void Activate()
{
EnemyModelView.Activate();
SetPhysicsProcess(true);
StartAttackTimer();
EnemyModelView.Activate();
SetPhysicsProcess(true);
StartAttackTimer();
}
private void AttackTimer_Timeout()
{
TakeAction();
TakeAction();
}
public void TakeAction()
{
EnemyModelView.Attack(_maximumWallMoveAmount);
EnemyModelView.Attack(_maximumWallMoveAmount);
}
public void Move(Vector3 velocity) => throw new System.NotImplementedException();
public void TakeDamage(double damage, ElementType elementType = ElementType.None, bool isCriticalHit = false, bool ignoreDefense = false, bool ignoreElementalResistance = false)
{
var damageTaken = _damageCalculator.CalculateDamage(
damage,
elementType,
_enemyStatResource.CurrentDefense,
_enemyStatResource.ElementalResistance,
isCriticalHit,
ignoreDefense,
ignoreElementalResistance);
var damageTaken = _damageCalculator.CalculateDamage(
damage,
elementType,
_enemyStatResource.CurrentDefense,
_enemyStatResource.ElementalResistance,
isCriticalHit,
ignoreDefense,
ignoreElementalResistance);
CurrentHP.OnNext(CurrentHP.Value - damageTaken);
GD.Print($"Demon Wall HP Left: {CurrentHP.Value}");
EnemyModelView.PlayHitAnimation();
CurrentHP.OnNext(CurrentHP.Value - damageTaken);
GD.Print($"Demon Wall HP Left: {CurrentHP.Value}");
EnemyModelView.PlayHitAnimation();
}
public void Knockback(float impulse, Vector3 direction) => throw new System.NotImplementedException();
@@ -89,9 +89,9 @@ public partial class DemonWall : CharacterBody3D, IEnemy
public async void Die()
{
CurrentHP.OnCompleted();
EnemyModelView.PlayDeathAnimation();
await ToSignal(GetTree().CreateTimer(0.8f), "timeout");
CallDeferred(MethodName.QueueFree);
CurrentHP.OnCompleted();
EnemyModelView.PlayDeathAnimation();
await ToSignal(GetTree().CreateTimer(0.8f), "timeout");
CallDeferred(MethodName.QueueFree);
}
}

View File

@@ -1,4 +1,4 @@
using Chickensoft.AutoInject;
using Chickensoft.AutoInject;
using Chickensoft.Introspection;
using Godot;
using System.Linq;
@@ -26,79 +26,79 @@ public partial class DemonWallModelView : EnemyModelView3D
public void Activate()
{
_opposingWall.Show();
var collisionShape = _opposingWall.GetChildren().OfType<CollisionShape3D>().Single();
collisionShape.SetDeferred(CollisionShape3D.PropertyName.Disabled, false);
SetPhysicsProcess(true);
_opposingWall.Show();
var collisionShape = _opposingWall.GetChildren().OfType<CollisionShape3D>().Single();
collisionShape.SetDeferred(CollisionShape3D.PropertyName.Disabled, false);
SetPhysicsProcess(true);
}
public void OnPhysicsProcess(double delta)
{
var direction = GlobalPosition.DirectionTo(_player.CurrentPosition).Normalized();
var rotationAngle = GetRotationAngle(_rotation);
RotateToPlayer(Eye, rotationAngle, 1f);
var direction = GlobalPosition.DirectionTo(_player.CurrentPosition).Normalized();
var rotationAngle = GetRotationAngle(_rotation);
RotateToPlayer(Eye, rotationAngle, 1f);
}
public void RotateToPlayer(Node3D rotateObject, float rotationAngle, float timeInSeconds)
{
var tweener = CreateTween();
tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(rotateObject, x)), rotateObject.Rotation.Y, rotationAngle, timeInSeconds);
var tweener = CreateTween();
tweener.TweenMethod(Callable.From((float x) => RotateTowardsPlayer(rotateObject, x)), rotateObject.Rotation.Y, rotationAngle, timeInSeconds);
}
public async void Attack(double maximumWallMoveAmount)
{
var rng = new RandomNumberGenerator();
rng.Randomize();
var rng = new RandomNumberGenerator();
rng.Randomize();
var leftArms = new Godot.Collections.Array<DemonWallArm>(LeftArms.GetChildren().Cast<DemonWallArm>());
var rightArms = new Godot.Collections.Array<DemonWallArm>(RightArms.GetChildren().Cast<DemonWallArm>());
var leftArms = new Godot.Collections.Array<DemonWallArm>(LeftArms.GetChildren().Cast<DemonWallArm>());
var rightArms = new Godot.Collections.Array<DemonWallArm>(RightArms.GetChildren().Cast<DemonWallArm>());
var leftArm = leftArms.PickRandom();
var rightArm = rightArms.PickRandom();
var leftArm = leftArms.PickRandom();
var rightArm = rightArms.PickRandom();
leftArm.PrimaryAttack();
rightArm.PrimaryAttack();
leftArm.PrimaryAttack();
rightArm.PrimaryAttack();
var arm1 = GetNode<DemonWallArm>("%Arm1");
var arm2 = GetNode<DemonWallArm>("%Arm2");
var arm7 = GetNode<DemonWallArm>("%Arm2");
var arm1 = GetNode<DemonWallArm>("%Arm1");
var arm2 = GetNode<DemonWallArm>("%Arm2");
var arm7 = GetNode<DemonWallArm>("%Arm2");
if (leftArm == arm1)
await AimAtPlayer(arm1, 2.1);
if (leftArm == arm2)
await AimAtPlayer(arm2, 1.5);
if (leftArm == GetNode<DemonWallArm>("%Arm3") && _opposingWall.Position.Z > -maximumWallMoveAmount)
MoveWall();
if (rightArm == arm7)
await AimAtPlayer(arm7, 2.5);
if (leftArm == arm1)
await AimAtPlayer(arm1, 2.1);
if (leftArm == arm2)
await AimAtPlayer(arm2, 1.5);
if (leftArm == GetNode<DemonWallArm>("%Arm3") && _opposingWall.Position.Z > -maximumWallMoveAmount)
MoveWall();
if (rightArm == arm7)
await AimAtPlayer(arm7, 2.5);
}
private async Task AimAtPlayer(DemonWallArm arm, double animationLengthInSeconds)
{
var rotationAngle = GetRotationAngle(arm.GetNode<Node3D>("%Rotation"));
RotateToPlayer(arm.GetNode<Node3D>("%Pivot"), rotationAngle, 0.3f);
await ToSignal(GetTree().CreateTimer(animationLengthInSeconds), "timeout");
RotateToPlayer(arm.GetNode<Node3D>("%Pivot"), 0, 0.3f);
var rotationAngle = GetRotationAngle(arm.GetNode<Node3D>("%Rotation"));
RotateToPlayer(arm.GetNode<Node3D>("%Pivot"), rotationAngle, 0.3f);
await ToSignal(GetTree().CreateTimer(animationLengthInSeconds), "timeout");
RotateToPlayer(arm.GetNode<Node3D>("%Pivot"), 0, 0.3f);
}
private async void MoveWall()
{
await ToSignal(GetTree().CreateTimer(1.5f), "timeout");
var tweener = CreateTween();
tweener.TweenMethod(Callable.From((float x) => MoveWallTowardsPlayer(x)), _opposingWall.Position.Z, _opposingWall.Position.Z - 2, 3f);
await ToSignal(GetTree().CreateTimer(1.5f), "timeout");
var tweener = CreateTween();
tweener.TweenMethod(Callable.From((float x) => MoveWallTowardsPlayer(x)), _opposingWall.Position.Z, _opposingWall.Position.Z - 2, 3f);
}
private void MoveWallTowardsPlayer(float moveAmount)
{
_opposingWall.Position = new Vector3(_opposingWall.Position.X, _opposingWall.Position.Y, moveAmount);
_opposingWall.Position = new Vector3(_opposingWall.Position.X, _opposingWall.Position.Y, moveAmount);
}
private float GetRotationAngle(Node3D rotationNode)
{
var target = new Vector3(_player.CurrentPosition.X, Position.Y, _player.CurrentPosition.Z);
rotationNode.LookAt(target, Vector3.Up, true);
rotationNode.RotateY(Rotation.Y);
return rotationNode.Rotation.Y;
var target = new Vector3(_player.CurrentPosition.X, Position.Y, _player.CurrentPosition.Z);
rotationNode.LookAt(target, Vector3.Up, true);
rotationNode.RotateY(Rotation.Y);
return rotationNode.Rotation.Y;
}
private void RotateTowardsPlayer(Node3D rotationNode, float angle) => rotationNode.Rotation = new Vector3(rotationNode.Rotation.X, angle, rotationNode.Rotation.Z);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,37 @@
[remap]
importer="scene"
importer_version=1
type="PackedScene"
uid="uid://c0fn82t1wj1n8"
path="res://.godot/imported/PIPE.glb-7590e7f2105c4683b379eab1c3387fa2.scn"
[deps]
source_file="res://src/enemy/enemy_types/16. demon wall/PIPE.glb"
dest_files=["res://.godot/imported/PIPE.glb-7590e7f2105c4683b379eab1c3387fa2.scn"]
[params]
nodes/root_type=""
nodes/root_name=""
nodes/apply_root_scale=true
nodes/root_scale=1.0
nodes/import_as_skeleton_bones=false
nodes/use_node_type_suffixes=true
meshes/ensure_tangents=true
meshes/generate_lods=true
meshes/create_shadow_meshes=true
meshes/light_baking=1
meshes/lightmap_texel_size=0.2
meshes/force_disable_compression=false
skins/use_named_skins=true
animation/import=true
animation/fps=30
animation/trimming=false
animation/remove_immutable_tracks=true
animation/import_rest_as_RESET=false
import_script/path=""
_subresources={}
gltf/naming_version=1
gltf/embedded_image_handling=1

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://b1srfcp1sq3ac"
path="res://.godot/imported/PIPE_PIPE2.jpg-668ab49b527fd993ab05c17abeac6017.ctex"
metadata={
"vram_texture": false
}
generator_parameters={
"md5": "f280b1532a0419eb2c045449bd6c39a2"
}
[deps]
source_file="res://src/enemy/enemy_types/16. demon wall/PIPE_PIPE2.jpg"
dest_files=["res://.godot/imported/PIPE_PIPE2.jpg-668ab49b527fd993ab05c17abeac6017.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dkh83g7ce40i7"
path="res://.godot/imported/concrete_0003_ao_1k.jpg-530c7acb835ff34efe84f61c02a9922a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/enemy/enemy_types/16. demon wall/concrete_0003_ao_1k.jpg"
dest_files=["res://.godot/imported/concrete_0003_ao_1k.jpg-530c7acb835ff34efe84f61c02a9922a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bmdaqk0y2gl2t"
path="res://.godot/imported/concrete_0003_height_1k.png-f60f5b034d6c0e67cadb64776839ef83.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/enemy/enemy_types/16. demon wall/concrete_0003_height_1k.png"
dest_files=["res://.godot/imported/concrete_0003_height_1k.png-f60f5b034d6c0e67cadb64776839ef83.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cpvgy5t6shoex"
path="res://.godot/imported/concrete_0003_normal_directx_1k.png-b850d518177cb5b9898e69e54975f28a.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/enemy/enemy_types/16. demon wall/concrete_0003_normal_directx_1k.png"
dest_files=["res://.godot/imported/concrete_0003_normal_directx_1k.png-b850d518177cb5b9898e69e54975f28a.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bx25c4uynoy1r"
path="res://.godot/imported/concrete_0003_normal_opengl_1k.png-def589fd13e0639a920cfab0bdd72e91.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/enemy/enemy_types/16. demon wall/concrete_0003_normal_opengl_1k.png"
dest_files=["res://.godot/imported/concrete_0003_normal_opengl_1k.png-def589fd13e0639a920cfab0bdd72e91.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=1
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=1
roughness/src_normal="res://src/enemy/enemy_types/16. demon wall/concrete_0003_normal_opengl_1k.png"
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View File

@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://brgmdx0p03syp"
path="res://.godot/imported/concrete_0003_roughness_1k.jpg-fb7d820aa45576bf2b879bf8f51bdc43.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://src/enemy/enemy_types/16. demon wall/concrete_0003_roughness_1k.jpg"
dest_files=["res://.godot/imported/concrete_0003_roughness_1k.jpg-fb7d820aa45576bf2b879bf8f51bdc43.ctex"]
[params]
compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0