Add Transition Configurator plugin for easy exit configuration
Features: - Fuzzy search for finding destination rooms - Lists all TransitionPieces in selected room as arrival points - Bidirectional wiring - updates return transition automatically - Auto-reloads destination scene in editor - UndoRedo support for source scene changes Files added: - addons/transition_configurator/plugin.cfg - addons/transition_configurator/transition_configurator.gd - addons/transition_configurator/transition_inspector_plugin.gd - addons/transition_configurator/config_dialog.gd - addons/transition_configurator/fuzzy_search.gd - addons/transition_configurator/README.md
This commit is contained in:
64
addons/transition_configurator/fuzzy_search.gd
Normal file
64
addons/transition_configurator/fuzzy_search.gd
Normal file
@@ -0,0 +1,64 @@
|
||||
extends RefCounted
|
||||
class_name FuzzySearch
|
||||
|
||||
## Simple fuzzy matching algorithm for text search
|
||||
## Returns a score between 0 (no match) and 1 (perfect match)
|
||||
|
||||
static func match(query: String, target: String) -> float:
|
||||
if query.is_empty():
|
||||
return 1.0
|
||||
|
||||
query = query.to_lower()
|
||||
target = target.to_lower()
|
||||
|
||||
# Exact match
|
||||
if target == query:
|
||||
return 1.0
|
||||
|
||||
# Contains query as substring
|
||||
if target.find(query) != -1:
|
||||
return 0.9
|
||||
|
||||
# Fuzzy match - all characters in query must appear in order in target
|
||||
var query_idx: int = 0
|
||||
var target_idx: int = 0
|
||||
var matches: int = 0
|
||||
var consecutive_bonus: float = 0.0
|
||||
var last_match_idx: int = -1
|
||||
|
||||
while query_idx < query.length() and target_idx < target.length():
|
||||
if query[query_idx] == target[target_idx]:
|
||||
matches += 1
|
||||
if last_match_idx != -1 and target_idx == last_match_idx + 1:
|
||||
consecutive_bonus += 0.1
|
||||
last_match_idx = target_idx
|
||||
query_idx += 1
|
||||
target_idx += 1
|
||||
|
||||
# All characters matched
|
||||
if query_idx == query.length():
|
||||
var base_score: float = float(matches) / float(query.length())
|
||||
var bonus: float = min(consecutive_bonus, 0.3) # Cap bonus at 0.3
|
||||
return base_score * 0.7 + bonus
|
||||
|
||||
return 0.0
|
||||
|
||||
## Sort an array of items by fuzzy match score
|
||||
## items should be Dictionary with at least a "name" or specified key field
|
||||
static func sort_by_match(query: String, items: Array, key: String = "name") -> Array:
|
||||
if query.is_empty():
|
||||
return items.duplicate()
|
||||
|
||||
var scored: Array[Dictionary] = []
|
||||
for item in items:
|
||||
var item_name: String = item.get(key, "")
|
||||
var score: float = match(query, item_name)
|
||||
if score > 0:
|
||||
scored.append({"item": item, "score": score})
|
||||
|
||||
# Sort by score descending
|
||||
scored.sort_custom(func(a: Dictionary, b: Dictionary) -> bool:
|
||||
return a["score"] > b["score"]
|
||||
)
|
||||
|
||||
return scored.map(func(s): return s["item"])
|
||||
Reference in New Issue
Block a user