Skip to content

Commit 62005e6

Browse files
committed
Add more documentation and fix errors with game still using old modlib.py
1 parent 9245cd5 commit 62005e6

File tree

2 files changed

+74
-36
lines changed

2 files changed

+74
-36
lines changed

modloader/modast.py

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -223,23 +223,30 @@ class emulates that at the base class.
223223
hook_func: A function that's called when the node is executed.
224224
If the function returns a non-None value, the next
225225
node will be skipped.
226-
fromOp: Unknown
227-
__oldNext: The original next node before hooking was done
226+
from_op: The original node before hooking
227+
old_next: The original next node before hooking was done
228228
"""
229-
def __init__(self, loc, hook_func=None, from_op=None):
230-
#TODO: Understand fromOp and __oldNext
229+
_serial = 1
230+
231+
def __init__(self, loc, hook_func_=None, from_op_=None):
231232
super(ASTHook, self).__init__(loc)
232233

233-
self.hook_func = hook_func
234-
self.from_op = from_op
234+
self.hook_func = hook_func_
235+
self.from_op = from_op_
235236
self.old_next = None
236237

238+
# Create a unique name
239+
self.name = "AWSWModOp_" + str(ASTHook._serial)
240+
ASTHook._serial += 1
241+
renpy.game.script.namemap[self.name] = self
242+
237243
def execute(self):
238244
"""Execute hook after node is called"""
239245
ast.statement_name("hook")
240246
ret = None
241247
if self.hook_func:
242248
ret = self.hook_func(self)
249+
243250
if not ret:
244251
self.exec_continue()
245252

@@ -270,26 +277,45 @@ def __init__(self, menu_, base_):
270277
# Copy the menu.items list, not a reference to it
271278
self.old_items = menu_.items[:]
272279

273-
def delete_item(self, item):
274-
"""Delete an item from the menu"""
275-
# TODO: Describe what the hell is happening here.
276-
self.get_items()[:] = [(lab, cond, block) for _, (lab, cond, block)
277-
in enumerate(self.get_items()) if lab != item]
278-
return None
280+
def delete_item(self, label):
281+
"""Delete a choice from the menu
282+
283+
Args:
284+
label (str): The label to search for
285+
"""
286+
# choice[0] is the choice's label
287+
self.get_items()[:] = [choice for choice in self.get_items() if choice[0] != label]
279288

280-
def get_item(self, item):
281-
"""Get an item from the menu"""
282-
for obj in self.get_items():
283-
if obj[0] == item:
284-
return obj
289+
def get_item(self, label):
290+
"""Get a choice from the menu
285291
286-
def get_option_code(self, item):
287-
"""Get an item's SL code from the menu"""
288-
obj = self.get_item(item)
289-
return obj[2]
292+
Args:
293+
label (str): The label to search for
294+
"""
295+
# obj[0] is the choice's label
296+
for choice in self.get_items():
297+
if choice[0] == label:
298+
return choice
299+
300+
def get_option_code(self, label):
301+
"""Get a choice's SL code from the menu
302+
303+
Args:
304+
choice (str): The choice to get
305+
"""
306+
# choice[2] is the choice's SL code
307+
choice = self.get_item(label)
308+
return choice[2]
290309

291310
def get_items(self):
292-
"""Get all the items in the menu"""
311+
"""Get all the items in the menu
312+
313+
Returns:
314+
A list of three-element tuples where the format is (label, condition, block), where
315+
label is the visible label given to the user,
316+
condition is a Python statement that determines whether or not to show the choice, and
317+
block is SL code
318+
"""
293319
return self.menu.items
294320

295321
def set_conditional(self, item, new_cond):
@@ -298,14 +324,14 @@ def set_conditional(self, item, new_cond):
298324
Returns:
299325
True if successful and False if not
300326
"""
301-
for i, (lab, _, block) in enumerate(self.get_items()):
302-
if lab == item:
303-
self.menu.items[i] = (lab, new_cond, block)
327+
for i, (label, _, block) in enumerate(self.get_items()):
328+
if label == item:
329+
self.menu.items[i] = (label, new_cond, block)
304330
return True
305331
return False
306332

307333
def add_item(self, label, hook, condition="True"):
308-
"""Add a new item to the menu
334+
"""Add a new choice to the menu
309335
310336
Args:
311337
label (str): The option's label
@@ -327,8 +353,6 @@ def add_item(self, label, hook, condition="True"):
327353
node = ASTHook(("AWSWMod", 1))
328354
node.from_op = self.menu
329355
node.hook_func = hook
330-
node.name = "AWSWModOp_" + str(self.base.name_serial)
331-
self.base.name_serial += 1
332356
self.get_items().append((label, condition, [node]))
333357
return node
334358

modloader/modgame.py

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ def get_ending_picker_menu(self):
9393

9494

9595
class AWSWHomeHook(object):
96-
"""Hook the menu found in the player's apartment."""
96+
"""Hook the menu found in the player's apartment.
97+
98+
Attributes:
99+
base (AWSWModBase):
100+
An instance of the mod base
101+
"""
97102

98103
def __init__(self, base_):
99104
"""Hook the hooks in the appropriate places.
@@ -104,12 +109,17 @@ def __init__(self, base_):
104109
self.base = base_
105110
self.hooks = []
106111

112+
# The alt menus are actually the character selection menus
113+
# The "a" and "b" versions are the first character selection and the second character
114+
# selection for the chapter, respectively.
107115
alt_menu_labels = ["chap2altmenua1", "chap2altmenub1", "chap3altmenua1",
108116
"chap3altmenub1", "chap4altmenua1", "chap4altmenub1"]
109-
self.alt_menus = [] # I'm not sure what I want to do about this yet.
117+
118+
self.alt_menus = []
110119
for lab in alt_menu_labels:
111120
self.alt_menus.append(modast.find_label(lab).next)
112121

122+
#TODO: Understand what chapter_menus_ does that alt_menus doesn't
113123
chapter_menus_ = modast.find_menu(["Meet with Bryce."]) # Choice was 100% unbiased thanks
114124
chapter_menus_[:] = [node for node in chapter_menus_ if node not in self.alt_menus]
115125
self.chapter_menus = chapter_menus_
@@ -284,17 +294,21 @@ def hook_opcode(self, node, func):
284294
Returns:
285295
An :class:`ASTHook` object
286296
"""
297+
#TODO: Determine if method should be a function
298+
# pylint: disable=no-self-use
299+
# Keep a copy of the node's original next node
287300
next_statement = node.next
288301

289-
hook = modast.ASTHook(("AWSWMod", 1)) # hooking hooks breaks
290-
hook.from_op = node
302+
# Make a new ASTHook and hook it to the node
303+
# The tuple is in the format (filename, filenumber)
304+
# This is used by the renpy stacktrace
305+
hook = modast.ASTHook(("AWSWMod", 1), func, node)
291306
node.next = hook
307+
308+
# Put the original next node to the hook node
309+
# Also keep a copy of the original next node in the hook node, allowing us to unhook it
292310
hook.chain(next_statement)
293311
hook.old_next = next_statement
294-
hook.hook_func = func
295-
hook.name = "AWSWModOp_" + str(self.name_serial)
296-
self.name_serial += 1
297-
renpy.game.script.namemap[hook.name] = hook
298312

299313
return hook
300314

0 commit comments

Comments
 (0)