by srid on Thu Jul 19, 2018 5:05 pm
So, the game works with an Event Queue.
An event can be literraly anything that happen in the game and that can trigger other event.
Most events aren't even noticeable for the player.
Example of events are LevelUpEvent, PlayerPoisonedEvent.
Let's say that the current event queue contains 4 events A, B, C, D.
The first event of the queue, A is taken by the game and passed to a set of Handlers.
A Handler is a piece of logic code that will have effects when certain types of events are passed to it.
Depending on the situation of the game, some handlers can be added or removed.
For instance, each god has its own handler that will manage its interaction (piety gain and loss etc.)
Each dungeon has its own handler (sometimes several), and some items have handlers too that are attached
to the game when you equip or use them, etc.
Each handler has a priority level to determine in which order an even is passed to Handlers.
Anyway, so event A is passed to a bunch of handlers, and some of them will manage various effects,
and they can also add new events to the queue. They are two ways to add events.
The most common one is to add events at the beginning of the queue.
Example: if, when handling event A, the events E, F, G are added to the queue (in that order),
then the new state of the queue will be A, E, F, G, B, C, D (and not G, F, E, B, C, D),
and after A has been fully handled the next event to be handled will be E.
In some cases, a handler may add events at the end of the queue.
Example: if, when handling event A, the events E, F, G are added to the end of the queue (in that order),
the new state of the queue will be A, B, C, D, E, F, G and the next event to be handled will be B.
To mix the two possible state, if you start with a queue A, B, C, D and while handling A you add E and F
at the beginning and G at the end, you will get A, E, F, B, C, D, G.
So now, let's detail the interaction between KnockBack, Death and Burning.
Let us consider the case of your double kill:
First, your attack start a PlayerDealMeleeDamageEvent to the queue.
- This event is first passed to an EnemyDamageHandler:
-- The Indomitable takes damage and loses a DP.
-- An EnemyKnockbackEvent(The Indomitable) is added to the queue because the player has knockback
-- It also adds an EnemyAttemptMeleeDamageEvent(The Indomitable) at the end of the queue
- The PlayerDealMeleeDamageEvent is then passed to a BurningHandler:
-- The Burning Stack Pop and adds a PlayerDealSpellDamageEvent(Count BlahBlah) to the queue
The PlayerDealMeleeDamageEvent is now fully handled and discarded, the queue now is
[EnemyKnockbackEvent(The Indomitable), PlayerDealSpellDamageEvent(Count BlahBlah), EnemyAttemptMeleeDamageEvent(The Indomitable)]
So the EnemyKnockbackEvent(The Indomitable) is now passed to the handlers, and
- The event is passed to a KnockbackHandler:
-- The Indomitable takes knockback damage and dies. This adds an EnemyDeathEvent(The Indomitable) to the queue
the EnemyKnockbackEvent(The Indomitable) is now fully handled and discarded, the queue now is:
[EnemyDeathEvent(The Indomitable), PlayerDealSpellDamageEvent(Count BlahBlah), EnemyAttemptMeleeDamageEvent(The Indomitable)]
(I'm going a bit faster now)
The EnemyDeathEvent(The Indomitable) is handled by a ExperienceHandler that adds an ExperienceEvent(The Indomitable) to the queue.
The queue now is:
[ExperienceEvent(The Indomitable), PlayerDealSpellDamageEvent(Count BlahBlah), EnemyAttemptMeleeDamageEvent(The Indomitable)]
The ExperienceEvent(The Indomitable) is handled by the same ExperienceHandler and a LevelUpEvent is added at the end of the queue.
The queue now is:
[PlayerDealSpellDamageEvent(Count BlahBlah), EnemyAttemptMeleeDamageEvent(The Indomitable), LevelUpEvent]
The PlayerDealSpellDamageEvent(Count BlahBlah) is handled and Count BlahBlah dies, a EnemyDeathEvent is added to the queue
The queue now is:
[EnemyDeathEvent(Count BlahBlah), EnemyAttemptMeleeDamageEvent(The Indomitable), LevelUpEvent]
the EnemyDeathEvent(Count BlahBlah) is handled and adds an ExperienceEvent(Count BlahBlah) to the queue)
The queue now is:
[ExperienceEvent(Count BlahBlah), EnemyAttemptMeleeDamageEvent(The Indomitable), LevelUpEvent]
The ExperienceEvent(Count BlahBlah) adds experience (at this point, your technically still level 1 and get the full XP bonus)
but do not add a second LevelUpEvent because the ExperienceHandler remembers that an one is already pending
(this is a specific case, in general you can have several events of the same type pending).
The queue now is:
[EnemyAttemptMeleeDamageEvent(The Indomitable), LevelUpEvent]
The EnemyAttemptMeleeDamageEvent(The Indomitable) is handled and the Indomitable retaliates (even if he is already dead!)
So technically, the pisorf damage happens before the retaliation, but after the retaliation has been queued.
The queue now is:
[LevelUpEvent]
The LevelUpEvent and you finally level up.
Of course, I focused only on the events we are interested in, but many other things happened outside from that
(for instance, the EnemyDeathEvent(Count BlahBlah) triggered a DungeonWinEvent that spawned the exit, the light, etc.)
So to resume, the events are handled in this order (even if they are added to the queue in a different order)
> PlayerDealMeleeDamageEvent
> The Indomitable takes damage and loses his DP
> EnemyKnockbackEvent(The Indomitable)
> EnemyDeathEvent(The Indomitable)
> ExperienceEvent(The Indomitable)
> Burning Stack Pop: PlayerDealSpellDamageEvent(Count BlahBlah)
> EnemyDeathEvent(Count BlahBlah)
> ExperienceEvent(Count BlahBlah)
> EnemyAttemptMeleeDamageEvent (end of queue)
> LevelUpEvent (end of queue)
I hope I made it clear enough.
When I have more time, I'll explain the First Strike + Curse + Burning Stack kill interaction too.
We made an expansion and it is awesome. Really, you should check it out, especially if you're looking for some extra challenge.
Download over at ddmod.weebly.com!