From 83db798ccec9ec426345db687360c6bd96352010 Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Tue, 29 Apr 2025 15:46:54 +0300 Subject: [PATCH 1/8] add NetworkArea nodes as physics extras --- .../netfox.extras/physics/network-area-2d.gd | 68 +++++++++++++++++++ .../netfox.extras/physics/network-area-3d.gd | 68 +++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 addons/netfox.extras/physics/network-area-2d.gd create mode 100644 addons/netfox.extras/physics/network-area-3d.gd diff --git a/addons/netfox.extras/physics/network-area-2d.gd b/addons/netfox.extras/physics/network-area-2d.gd new file mode 100644 index 00000000..4b0b792d --- /dev/null +++ b/addons/netfox.extras/physics/network-area-2d.gd @@ -0,0 +1,68 @@ +class_name NetworkArea2D +extends Area2D + +## Emitted when a body enters this area. +signal rollback_body_entered(body: Node2D, tick: int) +## Emitted when a body exits this area. +signal rollback_body_exited(body: Node2D, tick: int) + +## Emitted when the received area enters this area. Requires monitoring to be set to true. +signal rollback_area_entered(area: Area2D, tick: int) +## Emitted when the received area exits this area. Requires monitoring to be set to true. +signal rollback_area_exited(area: Area2D, tick: int) + +var _overlapping_bodies := _HistoryBuffer.new() +var _overlapping_areas := _HistoryBuffer.new() + +func _notification(what: int): + if what == NOTIFICATION_READY: + NetworkTime.on_tick.connect(_tick) + +func _tick(_d: float, tick: int): + _update_bodies(tick) + _update_areas(tick) + +func _update_bodies(tick: int): + var current := self.get_overlapping_bodies() + _overlapping_bodies.set_snapshot(tick, current) + + if not _overlapping_bodies.has(tick - 1): + for body in current: + rollback_body_entered.emit(body, tick) + return + + var prev: Array = _overlapping_bodies.get_snapshot(tick - 1) + + if current.hash() != prev.hash(): + for body in current: + if not prev.has(body): + rollback_body_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_body_exited.emit(body, tick) + + _overlapping_bodies.trim(NetworkRollback.history_start) + + +func _update_areas(tick: int): + var current := self.get_overlapping_areas() + _overlapping_areas.set_snapshot(tick, current) + + if not _overlapping_areas.has(tick - 1): + for body in current: + rollback_body_entered.emit(body, tick) + return + + var prev: Array = _overlapping_areas.get_snapshot(tick - 1) + + if current.hash() != prev.hash(): + for body in current: + if not prev.has(body): + rollback_area_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_area_exited.emit(body, tick) + + _overlapping_areas.trim(NetworkRollback.history_start) diff --git a/addons/netfox.extras/physics/network-area-3d.gd b/addons/netfox.extras/physics/network-area-3d.gd new file mode 100644 index 00000000..88c4d310 --- /dev/null +++ b/addons/netfox.extras/physics/network-area-3d.gd @@ -0,0 +1,68 @@ +class_name NetworkArea3D +extends Area3D + +## Emitted when a body enters this area. +signal rollback_body_entered(body: Node3D, tick: int) +## Emitted when a body exits this area. +signal rollback_body_exited(body: Node3D, tick: int) + +## Emitted when the received area enters this area. Requires monitoring to be set to true. +signal rollback_area_entered(area: Area3D, tick: int) +## Emitted when the received area exits this area. Requires monitoring to be set to true. +signal rollback_area_exited(area: Area3D, tick: int) + +var _overlapping_bodies := _HistoryBuffer.new() +var _overlapping_areas := _HistoryBuffer.new() + +func _notification(what: int): + if what == NOTIFICATION_READY: + NetworkTime.on_tick.connect(_tick) + +func _tick(_d: float, tick: int): + _update_bodies(tick) + _update_areas(tick) + +func _update_bodies(tick: int): + var current := self.get_overlapping_bodies() + _overlapping_bodies.set_snapshot(tick, current) + + if not _overlapping_bodies.has(tick - 1): + for body in current: + rollback_body_entered.emit(body, tick) + return + + var prev: Array = _overlapping_bodies.get_snapshot(tick - 1) + + if current.hash() != prev.hash(): + for body in current: + if not prev.has(body): + rollback_body_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_body_exited.emit(body, tick) + + _overlapping_bodies.trim(NetworkRollback.history_start) + + +func _update_areas(tick: int): + var current := self.get_overlapping_areas() + _overlapping_areas.set_snapshot(tick, current) + + if not _overlapping_areas.has(tick - 1): + for body in current: + rollback_body_entered.emit(body, tick) + return + + var prev: Array = _overlapping_areas.get_snapshot(tick - 1) + + if current.hash() != prev.hash(): + for body in current: + if not prev.has(body): + rollback_area_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_area_exited.emit(body, tick) + + _overlapping_areas.trim(NetworkRollback.history_start) From 77c14f5429f3186c9e2b315c9f133fc2d85c3446 Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Tue, 29 Apr 2025 16:01:03 +0300 Subject: [PATCH 2/8] add missing uids --- addons/netfox.extras/physics/network-area-2d.gd.uid | 1 + addons/netfox.extras/physics/network-area-3d.gd.uid | 1 + 2 files changed, 2 insertions(+) create mode 100644 addons/netfox.extras/physics/network-area-2d.gd.uid create mode 100644 addons/netfox.extras/physics/network-area-3d.gd.uid diff --git a/addons/netfox.extras/physics/network-area-2d.gd.uid b/addons/netfox.extras/physics/network-area-2d.gd.uid new file mode 100644 index 00000000..b1b0ca84 --- /dev/null +++ b/addons/netfox.extras/physics/network-area-2d.gd.uid @@ -0,0 +1 @@ +uid://hdeqysxd3lql diff --git a/addons/netfox.extras/physics/network-area-3d.gd.uid b/addons/netfox.extras/physics/network-area-3d.gd.uid new file mode 100644 index 00000000..bed62975 --- /dev/null +++ b/addons/netfox.extras/physics/network-area-3d.gd.uid @@ -0,0 +1 @@ +uid://bgui8a67mb51l From a2a976d2a68065031cd7ece35261a95ccb27dcee Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Tue, 13 May 2025 13:57:43 +0300 Subject: [PATCH 3/8] remove unnecessary hash check --- .../netfox.extras/physics/network-area-2d.gd | 30 +++++++++---------- .../netfox.extras/physics/network-area-3d.gd | 30 +++++++++---------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/addons/netfox.extras/physics/network-area-2d.gd b/addons/netfox.extras/physics/network-area-2d.gd index 4b0b792d..aa5aa6d0 100644 --- a/addons/netfox.extras/physics/network-area-2d.gd +++ b/addons/netfox.extras/physics/network-area-2d.gd @@ -33,14 +33,13 @@ func _update_bodies(tick: int): var prev: Array = _overlapping_bodies.get_snapshot(tick - 1) - if current.hash() != prev.hash(): - for body in current: - if not prev.has(body): - rollback_body_entered.emit(body, tick) - - for body in prev: - if not current.has(body): - rollback_body_exited.emit(body, tick) + for body in current: + if not prev.has(body): + rollback_body_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_body_exited.emit(body, tick) _overlapping_bodies.trim(NetworkRollback.history_start) @@ -56,13 +55,12 @@ func _update_areas(tick: int): var prev: Array = _overlapping_areas.get_snapshot(tick - 1) - if current.hash() != prev.hash(): - for body in current: - if not prev.has(body): - rollback_area_entered.emit(body, tick) - - for body in prev: - if not current.has(body): - rollback_area_exited.emit(body, tick) + for body in current: + if not prev.has(body): + rollback_area_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_area_exited.emit(body, tick) _overlapping_areas.trim(NetworkRollback.history_start) diff --git a/addons/netfox.extras/physics/network-area-3d.gd b/addons/netfox.extras/physics/network-area-3d.gd index 88c4d310..8862f47c 100644 --- a/addons/netfox.extras/physics/network-area-3d.gd +++ b/addons/netfox.extras/physics/network-area-3d.gd @@ -33,14 +33,13 @@ func _update_bodies(tick: int): var prev: Array = _overlapping_bodies.get_snapshot(tick - 1) - if current.hash() != prev.hash(): - for body in current: - if not prev.has(body): - rollback_body_entered.emit(body, tick) - - for body in prev: - if not current.has(body): - rollback_body_exited.emit(body, tick) + for body in current: + if not prev.has(body): + rollback_body_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_body_exited.emit(body, tick) _overlapping_bodies.trim(NetworkRollback.history_start) @@ -56,13 +55,12 @@ func _update_areas(tick: int): var prev: Array = _overlapping_areas.get_snapshot(tick - 1) - if current.hash() != prev.hash(): - for body in current: - if not prev.has(body): - rollback_area_entered.emit(body, tick) - - for body in prev: - if not current.has(body): - rollback_area_exited.emit(body, tick) + for body in current: + if not prev.has(body): + rollback_area_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_area_exited.emit(body, tick) _overlapping_areas.trim(NetworkRollback.history_start) From 6dfd723d46d1545b50733bb3aea959e712cfb2e9 Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Wed, 14 May 2025 19:24:11 +0300 Subject: [PATCH 4/8] implement Area2/3D functions --- .../netfox.extras/physics/network-area-2d.gd | 28 +++++++++++++++++++ .../netfox.extras/physics/network-area-3d.gd | 28 +++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/addons/netfox.extras/physics/network-area-2d.gd b/addons/netfox.extras/physics/network-area-2d.gd index aa5aa6d0..75c8c109 100644 --- a/addons/netfox.extras/physics/network-area-2d.gd +++ b/addons/netfox.extras/physics/network-area-2d.gd @@ -14,14 +14,42 @@ signal rollback_area_exited(area: Area2D, tick: int) var _overlapping_bodies := _HistoryBuffer.new() var _overlapping_areas := _HistoryBuffer.new() + +## Returns the result of [code]Area2D.get_overlapping_areas()[/code] for [param tick] +func rollback_get_overlapping_areas(tick: int) -> Array[Area2D]: + return _overlapping_areas.get_snapshot(tick) if _overlapping_areas.has(tick) else [] + +## Returns the result of [code]Area2D.get_overlapping_bodies()[/code] for [param tick] +func rollback_get_overlapping_bodies(tick: int) -> Array[Node2D]: + return _overlapping_bodies.get_snapshot(tick) if _overlapping_bodies.has(tick) else [] + +## Returns the result of [code]Area2D.has_overlapping_areas()[/code] for [param tick] +func rollback_has_overlapping_areas(tick: int) -> bool: + return rollback_get_overlapping_areas(tick).size() > 0 + +## Returns the result of [code]Area2D.has_overlapping_bodies()[/code] for [param tick] +func rollback_has_overlapping_bodies(tick: int) -> bool: + return rollback_get_overlapping_bodies(tick).size() > 0 + +## Returns the result of [code]Area2D.overlaps_area(area)[/code] for [param tick] +func rollback_overlaps_area(area: Area2D, tick: int) -> bool: + return rollback_get_overlapping_areas(tick).has(area) + +## Returns the result of [code]Area2D.overlaps_body(body)[/code] for [param tick] +func rollback_overlaps_body(body: Node2D, tick: int) -> bool: + return rollback_get_overlapping_bodies(tick).has(body) + + func _notification(what: int): if what == NOTIFICATION_READY: NetworkTime.on_tick.connect(_tick) + func _tick(_d: float, tick: int): _update_bodies(tick) _update_areas(tick) + func _update_bodies(tick: int): var current := self.get_overlapping_bodies() _overlapping_bodies.set_snapshot(tick, current) diff --git a/addons/netfox.extras/physics/network-area-3d.gd b/addons/netfox.extras/physics/network-area-3d.gd index 8862f47c..327a6f7b 100644 --- a/addons/netfox.extras/physics/network-area-3d.gd +++ b/addons/netfox.extras/physics/network-area-3d.gd @@ -14,14 +14,42 @@ signal rollback_area_exited(area: Area3D, tick: int) var _overlapping_bodies := _HistoryBuffer.new() var _overlapping_areas := _HistoryBuffer.new() + +## Returns the result of [code]Area3D.get_overlapping_areas()[/code] for [param tick] +func rollback_get_overlapping_areas(tick: int) -> Array[Area3D]: + return _overlapping_areas.get_snapshot(tick) if _overlapping_areas.has(tick) else [] + +## Returns the result of [code]Area3D.get_overlapping_bodies()[/code] for [param tick] +func rollback_get_overlapping_bodies(tick: int) -> Array[Node3D]: + return _overlapping_bodies.get_snapshot(tick) if _overlapping_bodies.has(tick) else [] + +## Returns the result of [code]Area3D.has_overlapping_areas()[/code] for [param tick] +func rollback_has_overlapping_areas(tick: int) -> bool: + return rollback_get_overlapping_areas(tick).size() > 0 + +## Returns the result of [code]Area3D.has_overlapping_bodies()[/code] for [param tick] +func rollback_has_overlapping_bodies(tick: int) -> bool: + return rollback_get_overlapping_bodies(tick).size() > 0 + +## Returns the result of [code]Area3D.overlaps_area(area)[/code] for [param tick] +func rollback_overlaps_area(area: Area3D, tick: int) -> bool: + return rollback_get_overlapping_areas(tick).has(area) + +## Returns the result of [code]Area3D.overlaps_body(body)[/code] for [param tick] +func rollback_overlaps_body(body: Node3D, tick: int) -> bool: + return rollback_get_overlapping_bodies(tick).has(body) + + func _notification(what: int): if what == NOTIFICATION_READY: NetworkTime.on_tick.connect(_tick) + func _tick(_d: float, tick: int): _update_bodies(tick) _update_areas(tick) + func _update_bodies(tick: int): var current := self.get_overlapping_bodies() _overlapping_bodies.set_snapshot(tick, current) From cd1982da739dc557f81f1444d4a8b0b0edc80b3b Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Wed, 14 May 2025 19:30:50 +0300 Subject: [PATCH 5/8] add gddoc references to function comments, adjust wording --- addons/netfox.extras/physics/network-area-2d.gd | 12 ++++++------ addons/netfox.extras/physics/network-area-3d.gd | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/addons/netfox.extras/physics/network-area-2d.gd b/addons/netfox.extras/physics/network-area-2d.gd index 75c8c109..5fa17cb7 100644 --- a/addons/netfox.extras/physics/network-area-2d.gd +++ b/addons/netfox.extras/physics/network-area-2d.gd @@ -15,27 +15,27 @@ var _overlapping_bodies := _HistoryBuffer.new() var _overlapping_areas := _HistoryBuffer.new() -## Returns the result of [code]Area2D.get_overlapping_areas()[/code] for [param tick] +## Returns the result of [method Area2D.get_overlapping_areas] at [param tick] func rollback_get_overlapping_areas(tick: int) -> Array[Area2D]: return _overlapping_areas.get_snapshot(tick) if _overlapping_areas.has(tick) else [] -## Returns the result of [code]Area2D.get_overlapping_bodies()[/code] for [param tick] +## Returns the result of [method Area2D.get_overlapping_bodies] at [param tick] func rollback_get_overlapping_bodies(tick: int) -> Array[Node2D]: return _overlapping_bodies.get_snapshot(tick) if _overlapping_bodies.has(tick) else [] -## Returns the result of [code]Area2D.has_overlapping_areas()[/code] for [param tick] +## Returns the result of [method Area2D.has_overlapping_areas] at [param tick] func rollback_has_overlapping_areas(tick: int) -> bool: return rollback_get_overlapping_areas(tick).size() > 0 -## Returns the result of [code]Area2D.has_overlapping_bodies()[/code] for [param tick] +## Returns the result of [method Area2D.has_overlapping_bodies] at [param tick] func rollback_has_overlapping_bodies(tick: int) -> bool: return rollback_get_overlapping_bodies(tick).size() > 0 -## Returns the result of [code]Area2D.overlaps_area(area)[/code] for [param tick] +## Returns the result of [method Area2D.overlaps_area] at [param tick] func rollback_overlaps_area(area: Area2D, tick: int) -> bool: return rollback_get_overlapping_areas(tick).has(area) -## Returns the result of [code]Area2D.overlaps_body(body)[/code] for [param tick] +## Returns the result of [method Area2D.overlaps_body] at [param tick] func rollback_overlaps_body(body: Node2D, tick: int) -> bool: return rollback_get_overlapping_bodies(tick).has(body) diff --git a/addons/netfox.extras/physics/network-area-3d.gd b/addons/netfox.extras/physics/network-area-3d.gd index 327a6f7b..b1d2bac0 100644 --- a/addons/netfox.extras/physics/network-area-3d.gd +++ b/addons/netfox.extras/physics/network-area-3d.gd @@ -15,27 +15,27 @@ var _overlapping_bodies := _HistoryBuffer.new() var _overlapping_areas := _HistoryBuffer.new() -## Returns the result of [code]Area3D.get_overlapping_areas()[/code] for [param tick] +## Returns the result of [method Area3D.get_overlapping_areas] at [param tick] func rollback_get_overlapping_areas(tick: int) -> Array[Area3D]: return _overlapping_areas.get_snapshot(tick) if _overlapping_areas.has(tick) else [] -## Returns the result of [code]Area3D.get_overlapping_bodies()[/code] for [param tick] +## Returns the result of [method Area3D.get_overlapping_bodies] at [param tick] func rollback_get_overlapping_bodies(tick: int) -> Array[Node3D]: return _overlapping_bodies.get_snapshot(tick) if _overlapping_bodies.has(tick) else [] -## Returns the result of [code]Area3D.has_overlapping_areas()[/code] for [param tick] +## Returns the result of [method Area3D.has_overlapping_areas] at [param tick] func rollback_has_overlapping_areas(tick: int) -> bool: return rollback_get_overlapping_areas(tick).size() > 0 -## Returns the result of [code]Area3D.has_overlapping_bodies()[/code] for [param tick] +## Returns the result of [method Area3D.has_overlapping_bodies] at [param tick] func rollback_has_overlapping_bodies(tick: int) -> bool: return rollback_get_overlapping_bodies(tick).size() > 0 -## Returns the result of [code]Area3D.overlaps_area(area)[/code] for [param tick] +## Returns the result of [method Area3D.overlaps_area] at [param tick] func rollback_overlaps_area(area: Area3D, tick: int) -> bool: return rollback_get_overlapping_areas(tick).has(area) -## Returns the result of [code]Area3D.overlaps_body(body)[/code] for [param tick] +## Returns the result of [method Area3D.overlaps_body] at [param tick] func rollback_overlaps_body(body: Node3D, tick: int) -> bool: return rollback_get_overlapping_bodies(tick).has(body) From a00042311fb512303b30b970f8e834ad2c13cf62 Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Thu, 22 May 2025 18:08:56 +0300 Subject: [PATCH 6/8] fix wrong initial area entered emit --- addons/netfox.extras/physics/network-area-2d.gd | 16 ++++++++-------- addons/netfox.extras/physics/network-area-3d.gd | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/addons/netfox.extras/physics/network-area-2d.gd b/addons/netfox.extras/physics/network-area-2d.gd index 5fa17cb7..58fc3c75 100644 --- a/addons/netfox.extras/physics/network-area-2d.gd +++ b/addons/netfox.extras/physics/network-area-2d.gd @@ -77,18 +77,18 @@ func _update_areas(tick: int): _overlapping_areas.set_snapshot(tick, current) if not _overlapping_areas.has(tick - 1): - for body in current: - rollback_body_entered.emit(body, tick) + for area in current: + rollback_area_entered.emit(area, tick) return var prev: Array = _overlapping_areas.get_snapshot(tick - 1) - for body in current: - if not prev.has(body): - rollback_area_entered.emit(body, tick) + for area in current: + if not prev.has(area): + rollback_area_entered.emit(area, tick) - for body in prev: - if not current.has(body): - rollback_area_exited.emit(body, tick) + for area in prev: + if not current.has(area): + rollback_area_exited.emit(area, tick) _overlapping_areas.trim(NetworkRollback.history_start) diff --git a/addons/netfox.extras/physics/network-area-3d.gd b/addons/netfox.extras/physics/network-area-3d.gd index b1d2bac0..2b1f7a0e 100644 --- a/addons/netfox.extras/physics/network-area-3d.gd +++ b/addons/netfox.extras/physics/network-area-3d.gd @@ -77,18 +77,18 @@ func _update_areas(tick: int): _overlapping_areas.set_snapshot(tick, current) if not _overlapping_areas.has(tick - 1): - for body in current: - rollback_body_entered.emit(body, tick) + for area in current: + rollback_area_entered.emit(area, tick) return var prev: Array = _overlapping_areas.get_snapshot(tick - 1) - for body in current: - if not prev.has(body): - rollback_area_entered.emit(body, tick) + for area in current: + if not prev.has(area): + rollback_area_entered.emit(area, tick) - for body in prev: - if not current.has(body): - rollback_area_exited.emit(body, tick) + for area in prev: + if not current.has(area): + rollback_area_exited.emit(area, tick) _overlapping_areas.trim(NetworkRollback.history_start) From 428caf95fa4121e92494b7558576a0f1cbe21a33 Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Thu, 22 May 2025 18:10:23 +0300 Subject: [PATCH 7/8] add _notification comment --- addons/netfox.extras/physics/network-area-2d.gd | 2 ++ addons/netfox.extras/physics/network-area-3d.gd | 2 ++ 2 files changed, 4 insertions(+) diff --git a/addons/netfox.extras/physics/network-area-2d.gd b/addons/netfox.extras/physics/network-area-2d.gd index 58fc3c75..e4a9d7aa 100644 --- a/addons/netfox.extras/physics/network-area-2d.gd +++ b/addons/netfox.extras/physics/network-area-2d.gd @@ -41,6 +41,8 @@ func rollback_overlaps_body(body: Node2D, tick: int) -> bool: func _notification(what: int): + # Use notification instead of _ready, so users can write their own _ready + # callback without having to call super() if what == NOTIFICATION_READY: NetworkTime.on_tick.connect(_tick) diff --git a/addons/netfox.extras/physics/network-area-3d.gd b/addons/netfox.extras/physics/network-area-3d.gd index 2b1f7a0e..76812923 100644 --- a/addons/netfox.extras/physics/network-area-3d.gd +++ b/addons/netfox.extras/physics/network-area-3d.gd @@ -41,6 +41,8 @@ func rollback_overlaps_body(body: Node3D, tick: int) -> bool: func _notification(what: int): + # Use notification instead of _ready, so users can write their own _ready + # callback without having to call super() if what == NOTIFICATION_READY: NetworkTime.on_tick.connect(_tick) From 6c34dd00caddbdaf41246ab698ff921a8bc889fd Mon Sep 17 00:00:00 2001 From: Matias Kumpulainen Date: Tue, 7 Oct 2025 21:43:33 +0300 Subject: [PATCH 8/8] fix: update network area state during _after_prepare_tick, fix cast errors --- .../netfox.extras/physics/network-area-2d.gd | 64 ++++++++++++------- .../netfox.extras/physics/network-area-3d.gd | 64 ++++++++++++------- 2 files changed, 80 insertions(+), 48 deletions(-) diff --git a/addons/netfox.extras/physics/network-area-2d.gd b/addons/netfox.extras/physics/network-area-2d.gd index e4a9d7aa..c7a27d7d 100644 --- a/addons/netfox.extras/physics/network-area-2d.gd +++ b/addons/netfox.extras/physics/network-area-2d.gd @@ -17,11 +17,21 @@ var _overlapping_areas := _HistoryBuffer.new() ## Returns the result of [method Area2D.get_overlapping_areas] at [param tick] func rollback_get_overlapping_areas(tick: int) -> Array[Area2D]: - return _overlapping_areas.get_snapshot(tick) if _overlapping_areas.has(tick) else [] + if not _overlapping_areas.has(tick): + return [] + + var areas: Array[Area2D] = [] + areas.assign((_overlapping_areas.get_snapshot(tick) as _Set).values()) + return areas ## Returns the result of [method Area2D.get_overlapping_bodies] at [param tick] func rollback_get_overlapping_bodies(tick: int) -> Array[Node2D]: - return _overlapping_bodies.get_snapshot(tick) if _overlapping_bodies.has(tick) else [] + if not _overlapping_bodies.has(tick): + return [] + + var bodies: Array[Node2D] = [] + bodies.assign((_overlapping_bodies.get_snapshot(tick) as _Set).values()) + return bodies ## Returns the result of [method Area2D.has_overlapping_areas] at [param tick] func rollback_has_overlapping_areas(tick: int) -> bool: @@ -44,16 +54,19 @@ func _notification(what: int): # Use notification instead of _ready, so users can write their own _ready # callback without having to call super() if what == NOTIFICATION_READY: - NetworkTime.on_tick.connect(_tick) + NetworkRollback.after_prepare_tick.connect(_after_prepare_tick) -func _tick(_d: float, tick: int): +func _after_prepare_tick(tick: int): _update_bodies(tick) _update_areas(tick) func _update_bodies(tick: int): - var current := self.get_overlapping_bodies() + if not self.monitoring: + return + + var current := _Set.of(self.get_overlapping_bodies()) _overlapping_bodies.set_snapshot(tick, current) if not _overlapping_bodies.has(tick - 1): @@ -61,21 +74,24 @@ func _update_bodies(tick: int): rollback_body_entered.emit(body, tick) return - var prev: Array = _overlapping_bodies.get_snapshot(tick - 1) - - for body in current: - if not prev.has(body): - rollback_body_entered.emit(body, tick) - - for body in prev: - if not current.has(body): - rollback_body_exited.emit(body, tick) + var prev: _Set = _overlapping_bodies.get_snapshot(tick - 1) + if not prev.equals(current): + for body in current: + if not prev.has(body): + rollback_body_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_body_exited.emit(body, tick) _overlapping_bodies.trim(NetworkRollback.history_start) func _update_areas(tick: int): - var current := self.get_overlapping_areas() + if not self.monitoring: + return + + var current := _Set.of(self.get_overlapping_areas()) _overlapping_areas.set_snapshot(tick, current) if not _overlapping_areas.has(tick - 1): @@ -83,14 +99,14 @@ func _update_areas(tick: int): rollback_area_entered.emit(area, tick) return - var prev: Array = _overlapping_areas.get_snapshot(tick - 1) - - for area in current: - if not prev.has(area): - rollback_area_entered.emit(area, tick) - - for area in prev: - if not current.has(area): - rollback_area_exited.emit(area, tick) + var prev: _Set = _overlapping_areas.get_snapshot(tick - 1) + if not prev.equals(current): + for area in current: + if not prev.has(area): + rollback_area_entered.emit(area, tick) + + for area in prev: + if not current.has(area): + rollback_area_exited.emit(area, tick) _overlapping_areas.trim(NetworkRollback.history_start) diff --git a/addons/netfox.extras/physics/network-area-3d.gd b/addons/netfox.extras/physics/network-area-3d.gd index 76812923..6f8a70a0 100644 --- a/addons/netfox.extras/physics/network-area-3d.gd +++ b/addons/netfox.extras/physics/network-area-3d.gd @@ -17,11 +17,21 @@ var _overlapping_areas := _HistoryBuffer.new() ## Returns the result of [method Area3D.get_overlapping_areas] at [param tick] func rollback_get_overlapping_areas(tick: int) -> Array[Area3D]: - return _overlapping_areas.get_snapshot(tick) if _overlapping_areas.has(tick) else [] + if not _overlapping_areas.has(tick): + return [] + + var areas: Array[Area3D] = [] + areas.assign((_overlapping_areas.get_snapshot(tick) as _Set).values()) + return areas ## Returns the result of [method Area3D.get_overlapping_bodies] at [param tick] func rollback_get_overlapping_bodies(tick: int) -> Array[Node3D]: - return _overlapping_bodies.get_snapshot(tick) if _overlapping_bodies.has(tick) else [] + if not _overlapping_bodies.has(tick): + return [] + + var bodies: Array[Node3D] = [] + bodies.assign((_overlapping_bodies.get_snapshot(tick) as _Set).values()) + return bodies ## Returns the result of [method Area3D.has_overlapping_areas] at [param tick] func rollback_has_overlapping_areas(tick: int) -> bool: @@ -44,16 +54,19 @@ func _notification(what: int): # Use notification instead of _ready, so users can write their own _ready # callback without having to call super() if what == NOTIFICATION_READY: - NetworkTime.on_tick.connect(_tick) + NetworkRollback.after_prepare_tick.connect(_after_prepare_tick) -func _tick(_d: float, tick: int): +func _after_prepare_tick(tick: int): _update_bodies(tick) _update_areas(tick) func _update_bodies(tick: int): - var current := self.get_overlapping_bodies() + if not self.monitoring: + return + + var current := _Set.of(self.get_overlapping_bodies()) _overlapping_bodies.set_snapshot(tick, current) if not _overlapping_bodies.has(tick - 1): @@ -61,21 +74,24 @@ func _update_bodies(tick: int): rollback_body_entered.emit(body, tick) return - var prev: Array = _overlapping_bodies.get_snapshot(tick - 1) - - for body in current: - if not prev.has(body): - rollback_body_entered.emit(body, tick) - - for body in prev: - if not current.has(body): - rollback_body_exited.emit(body, tick) + var prev: _Set = _overlapping_bodies.get_snapshot(tick - 1) + if not prev.equals(current): + for body in current: + if not prev.has(body): + rollback_body_entered.emit(body, tick) + + for body in prev: + if not current.has(body): + rollback_body_exited.emit(body, tick) _overlapping_bodies.trim(NetworkRollback.history_start) func _update_areas(tick: int): - var current := self.get_overlapping_areas() + if not self.monitoring: + return + + var current := _Set.of(self.get_overlapping_areas()) _overlapping_areas.set_snapshot(tick, current) if not _overlapping_areas.has(tick - 1): @@ -83,14 +99,14 @@ func _update_areas(tick: int): rollback_area_entered.emit(area, tick) return - var prev: Array = _overlapping_areas.get_snapshot(tick - 1) - - for area in current: - if not prev.has(area): - rollback_area_entered.emit(area, tick) - - for area in prev: - if not current.has(area): - rollback_area_exited.emit(area, tick) + var prev: _Set = _overlapping_areas.get_snapshot(tick - 1) + if not prev.equals(current): + for area in current: + if not prev.has(area): + rollback_area_entered.emit(area, tick) + + for area in prev: + if not current.has(area): + rollback_area_exited.emit(area, tick) _overlapping_areas.trim(NetworkRollback.history_start)