RapidGameFramework
Reusable Godot managers for data-driven small games
Loading...
Searching...
No Matches
event_manager.gd
Go to the documentation of this file.
2
8
9const RARITY_WEIGHTS = {"common":20,"uncommon":10,"rare":4,"epic":1}
10const DEFAULT_EVENT_PACK_DIR = "res://data/games/reflecting_pool/events"
11const DataCacheManager = preload("res://scripts/systems/dataCacheManager/data_cache_manager.gd")
12
13var all_events = []
14var events_by_pack = {}
15var current_event = {}
16var data_cache_manager = DataCacheManager.new()
17
18
19func load_events(event_pack_dir:String = DEFAULT_EVENT_PACK_DIR) -> void:
20 load_event_packs(event_pack_dir)
21
22func load_event_packs(event_pack_dir:String = DEFAULT_EVENT_PACK_DIR) -> void:
23 all_events.clear()
24 events_by_pack.clear()
25 current_event = {}
26 var dir = DirAccess.open(event_pack_dir)
27 if dir:
28 dir.list_dir_begin()
29 var f = dir.get_next()
30 while f != "":
31 if f.ends_with(".json"):
32 var pack_id = f.substr(0, f.length() - 5)
33 load_event_pack(pack_id, event_pack_dir + "/" + f)
34 f = dir.get_next()
35
36
37func load_event_pack(pack_id:String, file_path:String) -> void:
38 load_event_pack_data(pack_id, data_cache_manager.load_root_array(file_path))
39
40
41
42func load_event_pack_data(pack_id:String, data:Array) -> void:
43 if not events_by_pack.has(pack_id):
44 events_by_pack[pack_id] = []
45 for raw_event in data:
46 if not raw_event is Dictionary:
47 continue
48 var event = raw_event.duplicate(true)
49 if not event.has("pack"):
50 event["pack"] = pack_id
51 events_by_pack[pack_id].append(event)
52 all_events.append(event)
53
54
55func get_events(filters:Dictionary = {}) -> Array:
56 var events = []
57 for event in all_events:
58 if _event_matches_filters(event, filters):
59 events.append(event)
60 return events
61
62func get_pack_ids() -> Array:
63 return events_by_pack.keys()
64
65func get_events_in_pack(pack_id:String) -> Array:
66 return events_by_pack.get(pack_id, [])
67
68func _event_matches_filters(event:Dictionary, filters:Dictionary) -> bool:
69 if filters.has("pack") and event.get("pack", "") != filters["pack"]:
70 return false
71 if filters.has("packs") and not filters["packs"].has(event.get("pack", "")):
72 return false
73 if filters.has("rarity") and event.get("rarity", "common") != filters["rarity"]:
74 return false
75 if filters.has("rarities") and not filters["rarities"].has(event.get("rarity", "common")):
76 return false
77 if filters.has("repeatable") and bool(event.get("repeatable", true)) != bool(filters["repeatable"]):
78 return false
79 return true
80
81
82func get_weighted_event(filters:Dictionary = {}) -> Dictionary:
83 var event_pool = get_events(filters)
84 if event_pool.is_empty():
85 return {}
86 var total = 0
87 for e in event_pool:
88 total += RARITY_WEIGHTS.get(e.get("rarity", "common"), 20)
89 if total <= 0:
90 return event_pool[0]
91 var roll = randi_range(1, total)
92 var running = 0
93 for e in event_pool:
94 running += RARITY_WEIGHTS.get(e.get("rarity", "common"), 20)
95 if roll <= running:
96 return e
97 return event_pool[0]
98
99
100func next_event(filters:Dictionary = {}) -> Dictionary:
101 current_event = get_weighted_event(filters)
102 return current_event
103
104func get_event_by_id(event_id:String) -> Dictionary:
105 for event in all_events:
106 if str(event.get("id", "")) == event_id:
107 return event
108 return {}
109
110
111func set_current_event_by_id(event_id:String) -> bool:
112 var event = get_event_by_id(event_id)
113 if event.is_empty():
114 return false
115 current_event = event
116 return true
117
118
119func draw_events(count:int, filters:Dictionary = {}, allow_duplicates:bool = false) -> Array:
120 var drawn_events = []
121 var event_pool = get_events(filters)
122 for i in range(count):
123 if event_pool.is_empty():
124 break
125 var event = _get_weighted_event_from_pool(event_pool)
126 drawn_events.append(event)
127 if not allow_duplicates:
128 event_pool.erase(event)
129 return drawn_events
130
131func _get_weighted_event_from_pool(event_pool:Array) -> Dictionary:
132 var total = 0
133 for e in event_pool:
134 total += RARITY_WEIGHTS.get(e.get("rarity", "common"), 20)
135 if total <= 0:
136 return event_pool[0]
137 var roll = randi_range(1, total)
138 var running = 0
139 for e in event_pool:
140 running += RARITY_WEIGHTS.get(e.get("rarity", "common"), 20)
141 if roll <= running:
142 return e
143 return event_pool[0]
144
145func get_current_event() -> Dictionary:
146 return current_event
147
148func get_current_event_id() -> String:
149 return str(current_event.get("id", ""))
150
151func get_current_title() -> String:
152 return current_event.get("title", "Event")
153
154func get_current_description() -> String:
155 return current_event.get("description", "")
156
157func get_current_choices() -> Array:
158 return current_event.get("choices", [])
159
160func get_choice_text(choice:Dictionary) -> String:
161 return choice.get("text", "Choice")
162
163func get_choice_effects(choice:Dictionary) -> Array:
164 return choice.get("effects", [])
165
166func get_choice_outcome(choice:Dictionary) -> String:
167 return choice.get("outcome", "")
168
169
170func get_cache_stats() -> Dictionary:
171 return data_cache_manager.get_cache_stats()