Exult U7 Turn Based Combat – Designing stuff

Check previous post for context

I started digging through the code, got some guidance from Malignant_Manor over #exult at freenode IRC. Other than that it was good old code archeology 🙂

General Structure

The idea is to create a new module for turn based combat (turn_based_combat.cc), it will include all the methods that will be called from other modules.

All these changes apply only if combat mode is set to turn based.

turn_based_combat.cc methods

pauseGame()

  • gwin->get_tqueue()->pause(SDL_GetTicks());

resumeGame()

  • gwin->get_tqueue()->resume(SDL_GetTicks());

onCombatStarted()

  • Invoke freezeTurn()

onCombatEnded()

  • Hide the “pass turn” button in the UI
  • Resume the game if paused

runTurn()

  • Hide the “pass turn” button in the UI
  • Set playerActionsBlocked = true
  • Resume the game
  • Schedule “Freeze turn” in TURN_TIME_MS
  • TURN_TIME_MS = what it takes for a melee action. (Use 500ms initially)

freezeTurn()

  • If combat is over, onCombatEnded() and return
  • Show the “pass turn” button in the UI
  • Set playerActionsBlocked = false
  • pauseGame()
  • Set the player walk counter to 0

updateWalkCounter()

  • Increase player walk counter by 1
  • STEPS_LIMIT = how many steps can the player take over the TURN_TIME_MS
  • If walk counter > STEPS_LIMIT, runTurn()

Modifications in other game modules

Activate Turn Based Combat Mode

These places must invoke tbc.onCombatStarted.

  • Game_window::toggle_combat in gamewin.cc, when setting combat to true. This is triggered by either being attacked by a NPC, or attacking an NPC,  or manually changing combat mode

Deactivate Turn Based Combat Mode

These places must invoke tbc.onCombatEnded.

  • Game_window::toggle_combat in gamewin.cc, when setting combat to false. This is triggered when the player dies. Couldn’t find out if it’s called when battle ends.

Player character combat mode

If TBC is activated, the Avatar character should always behave as in combat mode Manual.

Check for player turn-ending actions

These player actions must invoke tbc.endTurn

  • Attack a monster

TBC mode will override the player combat mode so it’s always manual. That means attacking a monster will be done specifically by double clicking on it. This is handled in Game_window::double_clicked in gamewin.cc, specifically by main_actor->set_target(obj);

This should set the main actor’s schedule to Schedule::combat, which in due time will invoke Combat_schedule::attack_target (combat.cc).

Turn should end here regardless if attack hits.

This method seems to handle both melee and ranged attacks, as well as probably using items on enemies to attack them. It also seems to happen after the attack animation, which is great for our purposes.

  • Cast a spell

Over Spellbook_object::execute_spell (objs/spellbook.cc), this intercepts just before the spell is cast, however must also have in mind spells requiring a target, these use the click_on_item intrinsic too (see below)

  • Use an item

This one’s a bit complex: initially Game_object::activate (objs/objs.cc) may work, the problem is some items are not used immediately but require setting a target, and the target selection is handled by the UI_click_on_item usecode intrinsic, which is ultimately represented in usecode/intrinsics.cc (there’s a #define magic going on there, but basically the code over USECODE_INTRINSIC(click_on_item) becomes what the usecode calls)

Passing the Turn

This involves adding a new UI element to the game window. When it’s clicked it must invoke tbc.endTurn.

Blocking player actions

If tbc.isActive && tbc.playerBlocked (i.e. the player just acted, waiting for a new turn), player cannot do any of the following actions:

  • Attack a monster
  • Cast a spell
  • Use an Item

Limit walking while in combat

Every step the avatar takes should invoke tbc.updateWalkCounter

Pending research, may also need to find a way to interrupt the walk path.

Leave a comment