Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package world.mechanics.combat
- import world.activity.Activity
- import world.activity.process.action.Action
- import world.activity.process.action.Action.State.*
- import world.mechanics.combat.supervision.DamageSupervisor
- import world.activity.result.Result
- import world.activity.process.causality.effects.Animation
- import world.activity.process.causality.effects.Graphic
- import world.activity.process.causality.effects.CombatProjectile
- import world.activity.force.Force
- import world.mechanics.Mechanic
- import world.mechanics.combat.supervision.behavior.CombatTactic
- import world.mechanics.combat.supervision.behavior.CombatTurn
- import java.util.*
- /**
- * This class represents the mechanics of a combat session between two [CombatAgent] entities.
- *
- * @param agent subject of this [CombatSession]
- * @param target potential adversary of [agent]
- * @param tactic behavioural instructions for this [CombatSession]
- *
- * Created by Stan van der Bend for Empyrean at 08/06/2018.
- *
- * @author https://www.rune-server.ee/members/icebrick/
- */
- abstract class CombatSession(val agent: CombatAgent, val target: CombatAgent, private val tactic: CombatTactic) : Mechanic<CombatAgent>, Action() {
- lateinit var turn: CombatTurn
- /**
- * Supervises the damage applied to this [agent] by incoming strikes.
- */
- private val damageSupervisor : DamageSupervisor = DamageSupervisor(agent)
- /**
- * This function is called if either [turn] is not initialized or is [Action.State.TERMINATED].
- *
- * @return determine the next turn of [CombatSession.agent]
- * @see CombatTurn.state
- */
- abstract fun createNextTurn(): CombatTurn
- /**
- * While this sessions is alive, this will be called every game cycle.
- *
- * @see util.TimeUtil.GAME_CYCLES the execution interval
- * @see Action.State the potential state of any [Action]
- * @see CombatTactic the tactic instructing this [CombatSession]
- * @see CombatTurn the turn in which [agent] is subject
- */
- override fun sequence() {
- // Determine whether current turn is either not initialized, or the former one is terminated.
- // If either is true, create next turn and continue.
- if(!this::turn.isInitialized || turn.state == TERMINATED)
- turn = createNextTurn()
- turn.pulse()
- // Determine whether turn has successfully started and initiate behaviour as instructed by the active tactic.
- if(turn.state == STARTED){
- tactic.pulse()
- // Determine whether visual effects should be negated in this sequence.
- if(!tactic.skipVisualEffects(agent, target)) {
- initGraphic().ifPresent(agent::performGraphic)
- initAnimation().ifPresent(agent::performAnimation)
- initProjectile().ifPresent{run{ it.lockOn(target).send() }}
- finalGraphic().ifPresent(target::performGraphic)
- }
- // Create an optional outgoing strike and apply it to the target.
- turn.strike(agent, target).ifPresent { strike ->
- // Drain target's life by final strike damage
- run { strike.collide().apply(target) }
- }
- turn.state = PULSING
- }
- }
- /**
- * Handles outgoing forces.
- *
- * @param opponentSession the [CombatSession] with [target] as its subject
- */
- fun pulse(opponentSession: CombatSession){
- if(!tactic.skipNextPulse(agent, target)) {
- pulse()
- turn.strike(agent, target)
- .flatMap(opponentSession::apply)
- .ifPresent {
- action : Result<CombatAgent> -> run { action.apply(target) }
- }
- }
- }
- /**
- * Adhere to resulting processes, inherited from [Mechanic].
- *
- * @param activity the incoming activity to be dealt with
- *
- * @return if the incoming activity is a force then it will be dealt with accordingly,
- * in every other case the method returns [Optional.empty]
- */
- override fun apply(activity: Activity): Optional<Result<CombatAgent>> {
- // We currently only deal with forces (strikes in specific)
- if(activity is Force) {
- if(!tactic.negateNextHostileDamage(agent, target))
- damageSupervisor.resolve(activity)
- if(tactic.negateNextHostileForces(agent, target))
- return Optional.empty()
- return Optional.of(activity.collide())
- }
- return Optional.empty()
- }
- /**
- * @return an optional animation performed at the start of the current [turn] by the [agent].
- * @see Animation
- */
- open fun initAnimation(): Optional<Animation> { return Optional.empty() }
- /**
- * @return an optional projectile executed at the start of the current [turn].
- * @see CombatProjectile
- */
- open fun initProjectile(): Optional<CombatProjectile> { return Optional.empty() }
- /**
- * @return an optional graphic executed at the start of the current [turn].
- * @see Graphic
- */
- open fun initGraphic(): Optional<Graphic> { return Optional.empty() }
- /**
- * @return an optional graphic executed at the end of the current [turn].
- * @see Graphic
- */
- open fun finalGraphic(): Optional<Graphic> { return Optional.empty() }
- }
Add Comment
Please, Sign In to add comment