Surgo
goes to eleven
I don't want to keep clogging chaos's discussion thread so I'm going to post these in a separate thread.
6/12/07 so far:
I finished implementing the first Hook_Object and its corresponding Hooks. The Hook_Object class is entitled Common_Hooks::has_run_reset and a global object has been defined for it that all Hooks should reference, entitled Common_Hooks::has_run_reset_hook. The Common_Hooks namespace, as its name sounds like, is a collection of "example" Hook_Objects that are also used in various places by the engine.
This Hook_Object iterates through every hook in the list that contains the referring Hook that called it, and sets the has_run variable of every Hook in said list to false. It's the first Hook of many that has been created so far. At the very beginning of a battle, the engine calls BattleState->setup_hooks, which creates a Hook in every Hook list that references this Hook_Object. Said Hook_Object has priority 999, ensuring it is always the last hook that is run when the list is iterated through.
In other news I pushed the hook priority variable back to the Hook_Object class where it really belongs, instead of the Hook class.
The difference between Hook and Hook_Object can be a little confusing. A Hook is what attacks and the engine places in various lists. It's something of a shell, not much more than a reference. It gets assigned a Hook_Object when it is created, and keeps track of a few things like which list it belongs to, which battle it belongs to, the internal state of the Hook, and whether or not it has been run yet. The Hook_Object is where the meat of what the Hook does is coded -- it takes various arguments and acts on them. The move Reflect, for example, extends the Hook_Object class. When someone uses the move Reflect in GSC onward, the code for the move creates two hooks, both referring to the Reflect Hook_Object. One of these goes in the damage-dealt hook list and gets called whenever damage is dealt -- it checks whether the damage was physical or special, takes the damage as an argument, and halves it. The second goes in the end-of-turn hook list and, when called, checks an internal state that starts at 5 and decrements it each time it's called. When it reaches 0, it removes itself and the other Hook from the hook lists. (It keeps track of what its "family" hooks are by a unique identifier.)
I probably won't do any more tonight because I have to finish some math stuff for work tomorrow and it's really hard.
TODO #1: Make the BattleState::add_hook function take a variable-length argument list, turn it into an argument map, and pass it to the Hook constructor, which should then pass it to a new function in Hook_Object to generate an internal state from that list. This is much, much better than making a state before making a Hook and then assigning the state to the Hook.
TODO #2: Make a function to give per-battle unique identifiers. Not difficult.
TODO #3: Something I thought of while I was typing this up. Instead of having the BattleState::add_hook() function create new Hooks, this functionality should be moved to the Hook_Object class, turning each Hook_Object into a "Hook factory". That way the Hook_Object can create all the necessary Hooks that the object needs for an instance, synchronize their unique identifiers, their states, etc., and add them to the necessary lists.
TODO #4: Implement a BattleState::desetup_hooks function, which deletes any remaining hooks at the end of the battle so we don't have a memory leak.
edit: Anyone can feel free to post here. I like keeping this updated with my progress because it forces me to work.
6/12/07 so far:
I finished implementing the first Hook_Object and its corresponding Hooks. The Hook_Object class is entitled Common_Hooks::has_run_reset and a global object has been defined for it that all Hooks should reference, entitled Common_Hooks::has_run_reset_hook. The Common_Hooks namespace, as its name sounds like, is a collection of "example" Hook_Objects that are also used in various places by the engine.
This Hook_Object iterates through every hook in the list that contains the referring Hook that called it, and sets the has_run variable of every Hook in said list to false. It's the first Hook of many that has been created so far. At the very beginning of a battle, the engine calls BattleState->setup_hooks, which creates a Hook in every Hook list that references this Hook_Object. Said Hook_Object has priority 999, ensuring it is always the last hook that is run when the list is iterated through.
In other news I pushed the hook priority variable back to the Hook_Object class where it really belongs, instead of the Hook class.
The difference between Hook and Hook_Object can be a little confusing. A Hook is what attacks and the engine places in various lists. It's something of a shell, not much more than a reference. It gets assigned a Hook_Object when it is created, and keeps track of a few things like which list it belongs to, which battle it belongs to, the internal state of the Hook, and whether or not it has been run yet. The Hook_Object is where the meat of what the Hook does is coded -- it takes various arguments and acts on them. The move Reflect, for example, extends the Hook_Object class. When someone uses the move Reflect in GSC onward, the code for the move creates two hooks, both referring to the Reflect Hook_Object. One of these goes in the damage-dealt hook list and gets called whenever damage is dealt -- it checks whether the damage was physical or special, takes the damage as an argument, and halves it. The second goes in the end-of-turn hook list and, when called, checks an internal state that starts at 5 and decrements it each time it's called. When it reaches 0, it removes itself and the other Hook from the hook lists. (It keeps track of what its "family" hooks are by a unique identifier.)
I probably won't do any more tonight because I have to finish some math stuff for work tomorrow and it's really hard.
TODO #1: Make the BattleState::add_hook function take a variable-length argument list, turn it into an argument map, and pass it to the Hook constructor, which should then pass it to a new function in Hook_Object to generate an internal state from that list. This is much, much better than making a state before making a Hook and then assigning the state to the Hook.
TODO #2: Make a function to give per-battle unique identifiers. Not difficult.
TODO #3: Something I thought of while I was typing this up. Instead of having the BattleState::add_hook() function create new Hooks, this functionality should be moved to the Hook_Object class, turning each Hook_Object into a "Hook factory". That way the Hook_Object can create all the necessary Hooks that the object needs for an instance, synchronize their unique identifiers, their states, etc., and add them to the necessary lists.
TODO #4: Implement a BattleState::desetup_hooks function, which deletes any remaining hooks at the end of the battle so we don't have a memory leak.
edit: Anyone can feel free to post here. I like keeping this updated with my progress because it forces me to work.