From 5b0803f85f502587b727a78b417ae51638cfe9dc Mon Sep 17 00:00:00 2001 From: Cold-Mint Date: Sun, 25 Aug 2024 18:49:48 +0800 Subject: [PATCH] =?UTF-8?q?After=20the=20player=20leaves=20the=20room,=20t?= =?UTF-8?q?he=20previous=20room=20vision=20is=20deprived=20and=20enemies?= =?UTF-8?q?=20are=20frozen.=20=E7=8E=A9=E5=AE=B6=E7=A6=BB=E5=BC=80?= =?UTF-8?q?=E6=88=BF=E9=97=B4=E5=90=8E=E4=B8=8A=E4=B8=AA=E6=88=BF=E9=97=B4?= =?UTF-8?q?=E8=A7=86=E9=87=8E=E5=B0=86=E8=A2=AB=E5=89=A5=E5=A4=BA=EF=BC=8C?= =?UTF-8?q?=E6=95=8C=E4=BA=BA=E8=A2=AB=E5=86=BB=E7=BB=93=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locals/Log.csv | 6 +- .../entitys/BlackenedAboriginalWarrior.tscn | 4 - prefab/entitys/Character.tscn | 1 + prefab/entitys/DelivererOfDarkMagic.tscn | 6 +- project.godot | 1 - scripts/character/AiCharacter.cs | 22 +--- scripts/character/Player.cs | 2 + scripts/debug/LogCat.cs | 10 +- scripts/map/PlayerSpawn.cs | 3 +- scripts/map/room/Room.cs | 83 ++++++++++-- scripts/utils/LightMaskUtils.cs | 123 ++++++++++++++++++ 11 files changed, 219 insertions(+), 42 deletions(-) create mode 100644 scripts/utils/LightMaskUtils.cs diff --git a/locals/Log.csv b/locals/Log.csv index d2d5b1f..13d482d 100644 --- a/locals/Log.csv +++ b/locals/Log.csv @@ -113,4 +113,8 @@ log_dll_type_length,位于{0}的dll文件内,共包含{1}个类型。,"The DLL log_item_pickup_disables_collision_damage,物品捡起禁用碰撞伤害。,Item pickup disables collision damage.,アイテムのピックアップが衝突によるダメージを無効にする log_item_thrown_restore_collision_damage,物品扔出恢复碰撞伤害。,Item Throw restores collision damage.,アイテム投げは衝突ダメージを回復する。 log_after_no_longer_in_contact_with_any_tiles,不再与任何瓦片接触后,可以造成伤害。,"After no longer coming into contact with any tiles, it can cause damage",タイルと接触しなくなった後、損傷を引き起こす可能性があります。 -log_contact_with_tiles_disables_damage,与瓦片接触禁用伤害。,"Disabling damage on contact with tiles",タイルとの接触によるダメージの無効化 \ No newline at end of file +log_contact_with_tiles_disables_damage,与瓦片接触禁用伤害。,"Disabling damage on contact with tiles",タイルとの接触によるダメージの無効化 +log_hide_all_node,隐藏{0}个节点。,Hide {0} nodes.,{0}ノードを非表示にします。 +log_show_all_node,显示{0}个节点。,Show {0} nodes.,{0}ノードが表示されます。 +log_enter_the_screen,进入屏幕。,Enter screen,画面に移動。 +log_exit_the_screen,退出屏幕。,Exit screen,画面を終了します。 \ No newline at end of file diff --git a/prefab/entitys/BlackenedAboriginalWarrior.tscn b/prefab/entitys/BlackenedAboriginalWarrior.tscn index 19e71a8..67ceb30 100644 --- a/prefab/entitys/BlackenedAboriginalWarrior.tscn +++ b/prefab/entitys/BlackenedAboriginalWarrior.tscn @@ -88,10 +88,6 @@ shape = SubResource("CircleShape2D_c61vr") position = Vector2(0, -79) script = ExtResource("5_y2fh5") -[node name="VisibleOnScreenEnabler2D" type="VisibleOnScreenEnabler2D" parent="."] -position = Vector2(0, 5.5) -scale = Vector2(2.04, 3.05) - [node name="ScoutArea2D" type="Area2D" parent="."] collision_layer = 0 collision_mask = 76 diff --git a/prefab/entitys/Character.tscn b/prefab/entitys/Character.tscn index 024247a..0ab5716 100644 --- a/prefab/entitys/Character.tscn +++ b/prefab/entitys/Character.tscn @@ -23,6 +23,7 @@ animations = [{ }] [node name="Player" type="CharacterBody2D"] +light_mask = 2 collision_layer = 4 collision_mask = 162 platform_floor_layers = 4294967042 diff --git a/prefab/entitys/DelivererOfDarkMagic.tscn b/prefab/entitys/DelivererOfDarkMagic.tscn index fc50fc5..e550bad 100644 --- a/prefab/entitys/DelivererOfDarkMagic.tscn +++ b/prefab/entitys/DelivererOfDarkMagic.tscn @@ -44,7 +44,7 @@ position = Vector2(0, 4) shape = SubResource("CapsuleShape2D_bb8wt") [node name="Area2DPickingArea" type="Area2D" parent="."] -collision_layer = 0 +collision_layer = 64 collision_mask = 8 [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2DPickingArea"] @@ -89,10 +89,6 @@ shape = SubResource("CircleShape2D_c61vr") position = Vector2(0, -79) script = ExtResource("5_y2fh5") -[node name="VisibleOnScreenEnabler2D" type="VisibleOnScreenEnabler2D" parent="."] -position = Vector2(0, 5.5) -scale = Vector2(2.04, 3.05) - [node name="ScoutArea2D" type="Area2D" parent="."] collision_layer = 0 collision_mask = 76 diff --git a/project.godot b/project.godot index 7874440..36ed46e 100644 --- a/project.godot +++ b/project.godot @@ -154,7 +154,6 @@ locale/translations=PackedStringArray("res://locals/DeathInfo.en.translation", " [layer_names] -2d_render/layer_1="Fog" 2d_physics/layer_1="RoomArea" 2d_physics/layer_2="Floor" 2d_physics/layer_3="Player" diff --git a/scripts/character/AiCharacter.cs b/scripts/character/AiCharacter.cs index 32190e1..a5b5093 100644 --- a/scripts/character/AiCharacter.cs +++ b/scripts/character/AiCharacter.cs @@ -62,9 +62,6 @@ public sealed partial class AiCharacter : CharacterTemplate /// private RayCast2D? _attackObstacleDetection; - - private VisibleOnScreenEnabler2D? _screenEnabler2D; - /// /// Navigation agent /// 导航代理 @@ -118,22 +115,9 @@ public sealed partial class AiCharacter : CharacterTemplate { base._Ready(); - _enemyInTheAttackRange = new List(); - _enemyInTheScoutRange = new List(); - _weaponInTheScoutRange = new List(); - _screenEnabler2D = GetNode("VisibleOnScreenEnabler2D"); - _screenEnabler2D.ScreenEntered += () => - { - //When the character enters the screen. - //当角色进入屏幕。 - ProcessMode = ProcessModeEnum.Disabled; - }; - _screenEnabler2D.ScreenExited += () => - { - //When the character leaves the screen. - //当角色离开屏幕。 - ProcessMode = ProcessModeEnum.Inherit; - }; + _enemyInTheAttackRange = []; + _enemyInTheScoutRange = []; + _weaponInTheScoutRange = []; _bubbleMarker = GetNode("BubbleMarker"); if (_bubbleMarker != null) { diff --git a/scripts/character/Player.cs b/scripts/character/Player.cs index 94c6143..400c845 100644 --- a/scripts/character/Player.cs +++ b/scripts/character/Player.cs @@ -392,6 +392,8 @@ public partial class Player : CharacterTemplate //将Hp设置为当前Hp的目的是,使生命条刷新。 healthBarUi.CurrentHp = CurrentHp; } + ProcessMode = ProcessModeEnum.Inherit; + Show(); } /// diff --git a/scripts/debug/LogCat.cs b/scripts/debug/LogCat.cs index bc5b2db..0a85c53 100644 --- a/scripts/debug/LogCat.cs +++ b/scripts/debug/LogCat.cs @@ -70,18 +70,24 @@ public static class LogCat /// 模组加载器 /// public const string ModLoader = "ModLoader"; - + /// /// PickAble Template /// 可拾取物模板 /// public const string PickAbleTemplate = "PickAbleTemplate"; - + /// /// ContactInjury /// 物品碰撞伤害 /// public const string ContactInjury = "ContactInjury"; + + /// + /// Room + /// 房间 + /// + public const string Room = "Room"; } diff --git a/scripts/map/PlayerSpawn.cs b/scripts/map/PlayerSpawn.cs index a1c3df4..6b82b34 100644 --- a/scripts/map/PlayerSpawn.cs +++ b/scripts/map/PlayerSpawn.cs @@ -27,9 +27,8 @@ public partial class PlayerSpawn : Marker2D { if (GameSceneNodeHolder.Player != null) { - GameSceneNodeHolder.Player.ProcessMode = ProcessModeEnum.Inherit; - GameSceneNodeHolder.Player.GlobalPosition = GlobalPosition; GameSceneNodeHolder.Player.Revive(GameSceneNodeHolder.Player.MaxHp); + GameSceneNodeHolder.Player.GlobalPosition = GlobalPosition; return; } diff --git a/scripts/map/room/Room.cs b/scripts/map/room/Room.cs index c1954ae..8882826 100644 --- a/scripts/map/room/Room.cs +++ b/scripts/map/room/Room.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using ColdMint.scripts.character; using ColdMint.scripts.debug; using ColdMint.scripts.map.dateBean; using ColdMint.scripts.utils; @@ -25,6 +26,8 @@ public class Room private Area2D? _area2D; private PointLight2D? _pointLight2D; private CollisionShape2D? _collisionShape2D; + private bool _hasPlayer; + private readonly List _characterTemplateList = []; public string? EnterRoomEventHandlerId { get; set; } @@ -47,6 +50,34 @@ public class Room return _tileMapLayers?.FirstOrDefault(tileMapLayer => tileMapLayer.Name == layerName); } + /// + /// ShowAllCharacterTemplate + /// 显示所有角色模板 + /// + private void ShowAllCharacterTemplate() + { + LogCat.LogWithFormat("show_all_node", LogCat.LogLabel.Room, LogCat.UploadFormat, + _characterTemplateList.Count); + foreach (var characterTemplate in _characterTemplateList) + { + characterTemplate.Show(); + } + } + + /// + /// HideAllCharacterTemplate + /// 隐藏所有角色模板 + /// + private void HideAllCharacterTemplate() + { + LogCat.LogWithFormat("hide_all_node", LogCat.LogLabel.Room, LogCat.UploadFormat, + _characterTemplateList.Count); + foreach (var characterTemplate in _characterTemplateList) + { + characterTemplate.Hide(); + } + } + /// /// When a node enters the room /// 当有节点进入房间时 @@ -60,12 +91,31 @@ public class Room _rootNode.Name); } - if (_pointLight2D != null && GameSceneNodeHolder.Player != null && node == GameSceneNodeHolder.Player) + if (node is Player player) { + _characterTemplateList.Add(player); + _hasPlayer = true; //The player enters the room, opening up their view. //玩家进入了房间,开放视野。 - _pointLight2D.Show(); - _pointLight2D.Texture = AssetHolder.White100; + if (_pointLight2D != null) + { + _pointLight2D.Show(); + _pointLight2D.Texture = AssetHolder.White100; + } + + ShowAllCharacterTemplate(); + }else if (node is CharacterTemplate characterTemplate) + { + if (_hasPlayer) + { + characterTemplate.Show(); + } + else + { + characterTemplate.Hide(); + } + + _characterTemplateList.Add(characterTemplate); } if (string.IsNullOrEmpty(EnterRoomEventHandlerId)) @@ -91,12 +141,24 @@ public class Room _rootNode.Name); } - if (_pointLight2D != null && GameSceneNodeHolder.Player != null && node == GameSceneNodeHolder.Player) + + if (node is Player player) { - //The player enters the room, opening up their view. - //玩家进入了房间,开放视野。 - _pointLight2D.Show(); - _pointLight2D.Texture = AssetHolder.White25; + //The player leaves the room, hiding the view. + //玩家离开了房间,隐藏视野。 + _characterTemplateList.Remove(player); + _hasPlayer = false; + if (_pointLight2D != null) + { + _pointLight2D.Show(); + _pointLight2D.Texture = AssetHolder.White25; + } + + HideAllCharacterTemplate(); + } + else if (node is CharacterTemplate characterTemplate && characterTemplate.Visible) + { + _characterTemplateList.Remove(characterTemplate); } if (string.IsNullOrEmpty(ExitRoomEventHandlerId)) @@ -166,12 +228,17 @@ public class Room //Sets the collision layer that can be detected in the current room area. //设置当前房间区域可检测到的碰撞层。 _area2D.SetCollisionMaskValue(Config.LayerNumber.Player, true); + _area2D.SetCollisionMaskValue(Config.LayerNumber.Mob, true); _area2D.BodyExited += OnExitRoom; _area2D.BodyEntered += OnEnterRoom; _collisionShape2D = _area2D.GetChild(0); _roomSlots = GetRoomSlots(GetTileMapLayer(Config.TileMapLayerName.Ground), _area2D, node2D.GetNode("RoomSlotList")); _pointLight2D = node2D.GetNodeOrNull("PointLight2D"); + if (_pointLight2D != null) + { + _pointLight2D.BlendMode = Light2D.BlendModeEnum.Mix; + } } public Node2D? RootNode => _rootNode; diff --git a/scripts/utils/LightMaskUtils.cs b/scripts/utils/LightMaskUtils.cs new file mode 100644 index 0000000..c41bba8 --- /dev/null +++ b/scripts/utils/LightMaskUtils.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace ColdMint.scripts.utils; + +/// +/// Light layer utils +/// 光照层工具 +/// +public static class LightMaskUtils +{ + private static readonly int[] PowInts = + [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072, 262144, 524288]; + + /// + /// Pass in a number and return the largest subscript that matches it. + /// 传入一个数字,返回与其匹配的最大下标 + /// + /// + /// + /// + private static int GetMaxPow(int number, int startIndex) + { + for (var i = startIndex - 1; i >= 0; i--) + { + var pow = PowInts[i]; + if (number >= pow) + { + return i; + } + } + + return -1; + } + + /// + /// ParseMaskValue + /// 解析Mask的值 + /// + /// + ///maskValue + /// + /// + /// + ///This callback returns true when the value is parsed, stopping the parsing immediately. + ///当解析到值时,此回调返回true,立即停止解析。 + /// + /// + ///The position of the element corresponding to its value, For example, passing in 10, returning [1,3] + ///与其值对应的元素位置,例如传入10,返回[1,3] + /// + public static int[] ParseMaskValue(int maskValue, Func? afterParsingTheValue = null) + { + var result = new List(); + var startIndex = PowInts.Length; + var indexInPowIntArray = GetMaxPow(maskValue, startIndex); + while (indexInPowIntArray > -1) + { + result.Insert(0, indexInPowIntArray); + if (afterParsingTheValue != null) + { + if (afterParsingTheValue.Invoke(indexInPowIntArray)) + { + //If it needs to be stopped, then the result is returned directly. + //如果需要停止,那么直接返回结果。 + return result.ToArray(); + } + } + + maskValue -= PowInts[indexInPowIntArray]; + startIndex = indexInPowIntArray; + indexInPowIntArray = GetMaxPow(maskValue, startIndex); + } + + return result.ToArray(); + } + + /// + /// Is there a location within the mask value? + /// mask值内是否包含某个位置? + /// + /// + /// + /// + public static bool ContainsMaskValue(int maskValue, int index) + { + var result = false; + ParseMaskValue(maskValue, i => + { + result = i == index; + return result; + }); + return result; + } + + /// + /// Add a location to MaskValue + /// 为MaskValue添加某个位置 + /// + /// + /// + /// + public static int AddIndexToMaskValue(int maskValue, int index) + { + if (ContainsMaskValue(maskValue,index)) + { + return maskValue; + } + return maskValue + PowInts[index]; + } + + /// + /// Converting an array to its corresponding value + /// 将数组转化为与其对应的值 + /// + /// + /// + public static int ArrayToMaskValue(int[] array) + { + return array.Sum(index => PowInts[index]); + } +} \ No newline at end of file