Files
gtav-src/script/dev_ng/shared/include/public/wizard_arcade_main.sch
T
2025-09-29 00:52:08 +02:00

8060 lines
323 KiB
XML
Executable File

USING "wizard_arcade_using.sch"
USING "wizard_arcade_drawing.sch"
/// PURPOSE:
/// Updates the values used for animating sprite sequences
PROC TWS_UPDATE_ANIM_FRAMES()
//Slow anim update
sPlayerData.iSlowFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sPlayerData.iSlowUpdateFrames = FLOOR(sPlayerData.iSlowFrameTimeCounter / cfTWS_SLOW_ANIM_FRAME_TIME)
sPlayerData.iSlowFrameTimeCounter -= ROUND(cfTWS_SLOW_ANIM_FRAME_TIME * sPlayerData.iSlowUpdateFrames)
//Default anim update
sPlayerData.iDefaultFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sPlayerData.iDefaultUpdateFrames = FLOOR(sPlayerData.iDefaultFrameTimeCounter / cfTWS_FAST_ANIM_FRAME_TIME)
sPlayerData.iDefaultFrameTimeCounter -= ROUND(cfTWS_FAST_ANIM_FRAME_TIME * sPlayerData.iDefaultUpdateFrames)
INT i
FOR i = 0 TO ciTWS_MAX_ENEMIES -1
//Slow anim update
sEnemyData[i].iSlowFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sEnemyData[i].iSlowUpdateFrames = FLOOR(sEnemyData[i].iSlowFrameTimeCounter / cfTWS_SLOW_ANIM_FRAME_TIME)
sEnemyData[i].iSlowFrameTimeCounter -= ROUND(cfTWS_SLOW_ANIM_FRAME_TIME * sEnemyData[i].iSlowUpdateFrames)
//Default anim update
sEnemyData[i].iDefaultFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sEnemyData[i].iDefaultUpdateFrames = FLOOR(sEnemyData[i].iDefaultFrameTimeCounter / cfTWS_FAST_ANIM_FRAME_TIME)
sEnemyData[i].iDefaultFrameTimeCounter -= ROUND(cfTWS_FAST_ANIM_FRAME_TIME * sEnemyData[i].iDefaultUpdateFrames)
ENDFOR
FOR i = 0 TO ciTWS_MAX_ITEMS -1
//Slow anim update
sItemData[i].iSlowFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sItemData[i].iSlowUpdateFrames = FLOOR(sItemData[i].iSlowFrameTimeCounter / cfTWS_SLOW_ANIM_FRAME_TIME)
sItemData[i].iSlowFrameTimeCounter -= ROUND(cfTWS_SLOW_ANIM_FRAME_TIME * sItemData[i].iSlowUpdateFrames)
ENDFOR
FOR i = 0 TO ciTWS_MAX_FX -1
//Slow anim update
sFXData[i].iSlowFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sFXData[i].iSlowUpdateFrames = FLOOR(sFXData[i].iSlowFrameTimeCounter / cfTWS_FAST_ANIM_FRAME_TIME)
sFXData[i].iSlowFrameTimeCounter -= ROUND(cfTWS_FAST_ANIM_FRAME_TIME * sFXData[i].iSlowUpdateFrames)
ENDFOR
//Slow anim update
sHUDData[TWS_HUD_DIALOGUE_FRAME].iSlowFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sHUDData[TWS_HUD_DIALOGUE_FRAME].iSlowUpdateFrames = FLOOR(sHUDData[TWS_HUD_DIALOGUE_FRAME].iSlowFrameTimeCounter / cfTWS_SLOW_ANIM_FRAME_TIME)
sHUDData[TWS_HUD_DIALOGUE_FRAME].iSlowFrameTimeCounter -= ROUND(cfTWS_SLOW_ANIM_FRAME_TIME * sHUDData[TWS_HUD_DIALOGUE_FRAME].iSlowUpdateFrames)
//Default anim update
sTWSData.iGlobalDefaultFrameTimeCounter += ROUND(GET_FRAME_TIME() * 1000)
sTWSData.iGlobalDefaultUpdateFrames = FLOOR(sTWSData.iGlobalDefaultFrameTimeCounter / cfTWS_FAST_ANIM_FRAME_TIME)
sTWSData.iGlobalDefaultFrameTimeCounter -= ROUND(cfTWS_FAST_ANIM_FRAME_TIME * sTWSData.iGlobalDefaultUpdateFrames)
ENDPROC
PROC TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE eNewState)
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [JS] TWS_SET_CLIENT_STATE - State changed from ",
TWS_DEBUG_GET_TWS_ARCADE_CLIENT_STATE_AS_STRING(sTWSData.eClientState), " to ", TWS_DEBUG_GET_TWS_ARCADE_CLIENT_STATE_AS_STRING(eNewState))
sTWSData.eClientState = eNewState
ENDPROC
PROC TWS_INIT_TELEMETRY(BOOL bResetTime = FALSE)
CPRINTLN(DEBUG_MINIGAME, "TWS - Initialising data for telemetry. Reset time? ", bResetTime)
sTWSData.sTelemetry.challenges = 0
sTWSData.sTelemetry.gameType = HASH("ARCADE_CABINET_CH_WIZARDS_SLEVE")
sTWSData.sTelemetry.kills = 0
sTWSData.sTelemetry.level = 0
sTWSData.sTelemetry.matchId = -1
sTWSData.sTelemetry.numPlayers = 1
sTWSData.sTelemetry.powerUps = 0
sTWSData.sTelemetry.reward = 0
sTWSData.sTelemetry.score = 0
IF bResetTime
sTWSData.sTelemetry.timePlayed = GET_GAME_TIMER()
ENDIF
ENDPROC
PROC TWS_COLLECT_DATA_FOR_TELEMETRY_AFTER_LEVEL(BOOL bExitingGame = FALSE)
CPRINTLN(DEBUG_MINIGAME, "TWS - Collecting data for telemetry.")
sTWSData.sTelemetry.score = sPlayerData.iScore // NOT sPlayerData.iHighestScore as we want the score for the last play
sTWSData.sTelemetry.timePlayed = GET_GAME_TIMER() - sTWSData.sTelemetry.timePlayed
IF IS_BITMASK_ENUM_AS_ENUM_SET(sTWSData.eChallengeFlags,TWS_CHALLENGE_BIT_FEELIN_GROGGY)
AND IS_BITMASK_ENUM_AS_ENUM_SET(sTWSData.eChallengeFlags,TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)
AND IS_BITMASK_ENUM_AS_ENUM_SET(sTWSData.eChallengeFlags,TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)
sTWSData.sTelemetry.reward = ARCADE_GAME_GET_TROPHY_ID_FOR_TELEMETRY(ARCADE_GAME_TROPHY_WIZARDS_RUIN)
ENDIF
sTWSData.sTelemetry.challenges = sTWSData.iChallengesBitsetForTelemetry
sTWSData.sTelemetry.matchId = BOOL_TO_INT(bExitingGame)
ENDPROC
PROC TWS_SEND_TELEMETRY()
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] The Wizard's Sleeve Sending Telemetry")
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] challenges ",sTWSData.sTelemetry.challenges)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_FEELIN_GROGGY: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_FEELIN_GROGGY)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD_BRONZE: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_BRONZE)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD_SILVER: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_SILVER)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD_GOLD: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_GOLD)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE_BRONZE: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_BRONZE)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE_SILVER: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_SILVER)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE_GOLD: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_GOLD)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] gameType ",sTWSData.sTelemetry.gameType)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] kills ",sTWSData.sTelemetry.kills)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] level ",sTWSData.sTelemetry.level)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] matchId ",sTWSData.sTelemetry.matchId)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] numPlayers ",sTWSData.sTelemetry.numPlayers)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] powerUps ",sTWSData.sTelemetry.powerUps)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] reward ",sTWSData.sTelemetry.reward)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] score ",sTWSData.sTelemetry.score)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] timePlayed ",sTWSData.sTelemetry.timePlayed)
IF PLAYER_ID() != INVALID_PLAYER_INDEX()
SWITCH GET_SIMPLE_INTERIOR_TYPE_LOCAL_PLAYER_IS_IN()
CASE SIMPLE_INTERIOR_TYPE_AUTO_SHOP
sTWSData.sTelemetry.location = HASH("SIMPLE_INTERIOR_TYPE_AUTO_SHOP")
BREAK
CASE SIMPLE_INTERIOR_TYPE_ARCADE
sTWSData.sTelemetry.location = HASH("SIMPLE_INTERIOR_TYPE_ARCADE")
BREAK
#IF FEATURE_FIXER
CASE SIMPLE_INTERIOR_TYPE_FIXER_HQ
sTWSData.sTelemetry.location = HASH("SIMPLE_INTERIOR_TYPE_FIXER_HQ")
BREAK
#ENDIF
DEFAULT
CDEBUG1LN(DEBUG_MINIGAME, "[RUIN] [TWS_SEND_TELEMETRY not in valid property, setting sRoadArcadeTelemetry.location = 0")
sTWSData.sTelemetry.location = 0
BREAK
ENDSWITCH
ELSE
CDEBUG2LN(DEBUG_MINIGAME, "[RUIN] [TWS_SEND_TELEMETRY] Invalid Player ID, setting sTWSData.sTelemetry.location = 0")
sTWSData.sTelemetry.location = 0
ENDIF
PLAYSTATS_ARCADE_CABINET(sTWSData.sTelemetry)
ENDPROC
PROC TWS_SET_PLAYER_STATE(TWS_PLAYER_STATE eState)
CDEBUG2LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] Player changing from state ",sPlayerData.ePlayerState," to state ",eState)
sPlayerData.ePlayerState = eState
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,0.0)
sPlayerData.fShadowXOffset = 0.0
SWITCH sPlayerData.iLevel
CASE 1
SWITCH sPlayerData.ePlayerState
CASE TWS_IDLE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_IDLE_WIDTH, cfTWS_PLAYER_IDLE_HEIGHT)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_WALK
CASE TWS_INTRO
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_WALK_WIDTH, cfTWS_PLAYER_WALK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-10.0)
BREAK
CASE TWS_ATTACK
CASE TWS_ATTACK_DOUBLE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_ATTACK_WIDTH, cfTWS_PLAYER_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(76.0,0.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_ATTACK_LOW
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_ATTACK_LOW_WIDTH, cfTWS_PLAYER_ATTACK_LOW_HEIGHT)
BREAK
CASE TWS_CHARGE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_CHARGE_WIDTH, cfTWS_PLAYER_CHARGE_HEIGHT)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_SUPERATTACK
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_EVOLVING_WIDTH, cfTWS_PLAYER_EVOLVING_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-72.0)
BREAK
CASE TWS_FALL
CASE TWS_FALL_HIGH
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_FALL_1_WIDTH, cfTWS_PLAYER_HURT_FALL_1_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-60.0)
BREAK
CASE TWS_FALL_2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_FALL_2_WIDTH, cfTWS_PLAYER_HURT_FALL_2_HEIGHT)
BREAK
CASE TWS_FLAT
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_FLAT_WIDTH, cfTWS_PLAYER_HURT_FLAT_HEIGHT)
BREAK
CASE TWS_DEAD
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_FLAT_WIDTH, cfTWS_PLAYER_HURT_FLAT_HEIGHT)
BREAK
CASE TWS_GETTING_UP
CASE TWS_STUN
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_GETUP_1_WIDTH, cfTWS_PLAYER_HURT_GETUP_1_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(-60.0,0.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_START
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_WIDTH, cfTWS_PLAYER_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_ASCEND
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_CREST
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_WIDTH, cfTWS_PLAYER_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_DESCEND
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_WIDTH, cfTWS_PLAYER_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_END
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_WIDTH, cfTWS_PLAYER_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_ATTACK
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_ATTACK_WIDTH, cfTWS_PLAYER_JUMP_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-20.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_ATTACK_DESCEND
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_ATTACK_WIDTH, cfTWS_PLAYER_JUMP_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-20.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_EVOLVING
CASE TWS_EVOLVING_2
CASE TWS_EVOLVING_3
CASE TWS_EVOLVING_4
CASE TWS_EVOLVING_5
CASE TWS_EVOLVING_6
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_EVOLVING_WIDTH, cfTWS_PLAYER_EVOLVING_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-72.0)
BREAK
CASE TWS_FALL_INFINITE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_WIDTH, cfTWS_PLAYER_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
BREAK
CASE TWS_FALL_HOLE_1
CASE TWS_FALL_HOLE_2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_HOLE_WIDTH, cfTWS_PLAYER_JUMP_HOLE_HEIGHT)
BREAK
ENDSWITCH
BREAK
CASE 2
SWITCH sPlayerData.ePlayerState
CASE TWS_IDLE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_IDLE_WIDTH, cfTWS_PLAYER_2_IDLE_HEIGHT)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_WALK
CASE TWS_INTRO
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_WALK_WIDTH, cfTWS_PLAYER_2_WALK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(00.0,10.0)
BREAK
CASE TWS_ATTACK
CASE TWS_ATTACK_DOUBLE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_ATTACK_WIDTH, cfTWS_PLAYER_2_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(50.0,0.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_ATTACK_LOW
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_ATTACK_LOW_WIDTH, cfTWS_PLAYER_2_ATTACK_LOW_HEIGHT)
BREAK
CASE TWS_CHARGE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_CHARGE_WIDTH, cfTWS_PLAYER_2_CHARGE_HEIGHT)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_SUPERATTACK
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_EVOLVING_WIDTH, cfTWS_PLAYER_2_EVOLVING_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(8.0,-64.0)
BREAK
CASE TWS_FALL
CASE TWS_FALL_HIGH
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_FALL_1_WIDTH, cfTWS_PLAYER_2_HURT_FALL_1_HEIGHT)
BREAK
CASE TWS_FALL_2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_FALL_2_WIDTH, cfTWS_PLAYER_2_HURT_FALL_2_HEIGHT)
BREAK
CASE TWS_FLAT
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_FLAT_WIDTH, cfTWS_PLAYER_2_HURT_FLAT_HEIGHT)
BREAK
CASE TWS_DEAD
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_FLAT_WIDTH, cfTWS_PLAYER_2_HURT_FLAT_HEIGHT)
BREAK
CASE TWS_GETTING_UP
CASE TWS_STUN
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_GETUP_1_WIDTH, cfTWS_PLAYER_2_HURT_GETUP_1_HEIGHT)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_START
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_JUMP_WIDTH, cfTWS_PLAYER_2_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-32.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_ASCEND
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-32.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_CREST
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_JUMP_WIDTH, cfTWS_PLAYER_2_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-32.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_DESCEND
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_JUMP_WIDTH, cfTWS_PLAYER_2_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-32.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_END
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_JUMP_WIDTH, cfTWS_PLAYER_2_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-32.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_ATTACK
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_JUMP_ATTACK_WIDTH, cfTWS_PLAYER_2_JUMP_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-4.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_JUMP_ATTACK_DESCEND
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_JUMP_ATTACK_WIDTH, cfTWS_PLAYER_2_JUMP_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-4.0)
sPlayerData.fShadowXOffset = -20.0
BREAK
CASE TWS_EVOLVING
CASE TWS_EVOLVING_2
CASE TWS_EVOLVING_3
CASE TWS_EVOLVING_4
CASE TWS_EVOLVING_5
CASE TWS_EVOLVING_6
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_EVOLVING_WIDTH, cfTWS_PLAYER_2_EVOLVING_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(-8.0,-64.0)
BREAK
CASE TWS_FALL_INFINITE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_JUMP_WIDTH, cfTWS_PLAYER_2_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
BREAK
CASE TWS_FALL_HOLE_1
CASE TWS_FALL_HOLE_2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_HOLE_WIDTH, cfTWS_PLAYER_JUMP_HOLE_HEIGHT)
BREAK
ENDSWITCH
BREAK
CASE 3
SWITCH sPlayerData.ePlayerState
CASE TWS_IDLE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_IDLE_WIDTH, cfTWS_PLAYER_3_IDLE_HEIGHT)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_WALK
CASE TWS_INTRO
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_WALK_WIDTH, cfTWS_PLAYER_3_WALK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,5.0)
BREAK
CASE TWS_ATTACK
CASE TWS_ATTACK_DOUBLE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_ATTACK_WIDTH, cfTWS_PLAYER_3_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(48.0,-44.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_ATTACK_LOW
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_ATTACK_LOW_WIDTH, cfTWS_PLAYER_3_ATTACK_LOW_HEIGHT)
BREAK
CASE TWS_CHARGE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_CHARGE_WIDTH, cfTWS_PLAYER_3_CHARGE_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(56.0, 0.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_SUPERATTACK
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_EVOLVING_WIDTH, cfTWS_PLAYER_3_EVOLVING_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-96.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_FALL
CASE TWS_FALL_HIGH
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_FALL_1_WIDTH, cfTWS_PLAYER_3_HURT_FALL_1_HEIGHT)
BREAK
CASE TWS_FALL_2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_FALL_2_WIDTH, cfTWS_PLAYER_3_HURT_FALL_2_HEIGHT)
BREAK
CASE TWS_FLAT
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_FLAT_WIDTH, cfTWS_PLAYER_3_HURT_FLAT_HEIGHT)
BREAK
CASE TWS_DEAD
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_FLAT_WIDTH, cfTWS_PLAYER_3_HURT_FLAT_HEIGHT)
BREAK
CASE TWS_GETTING_UP
CASE TWS_STUN
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_GETUP_1_WIDTH, cfTWS_PLAYER_3_HURT_GETUP_1_HEIGHT)
BREAK
CASE TWS_JUMP_START
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_JUMP_WIDTH, cfTWS_PLAYER_3_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-24.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_JUMP_ASCEND
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-24.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_JUMP_CREST
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_JUMP_WIDTH, cfTWS_PLAYER_3_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-24.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_JUMP_DESCEND
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_JUMP_WIDTH, cfTWS_PLAYER_3_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-24.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_JUMP_END
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_JUMP_WIDTH, cfTWS_PLAYER_3_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-24.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_JUMP_ATTACK
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_JUMP_ATTACK_WIDTH, cfTWS_PLAYER_3_JUMP_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-60.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_JUMP_ATTACK_DESCEND
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_JUMP_ATTACK_WIDTH, cfTWS_PLAYER_3_JUMP_ATTACK_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-60.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_EVOLVING
CASE TWS_EVOLVING_2
CASE TWS_EVOLVING_3
CASE TWS_EVOLVING_4
CASE TWS_EVOLVING_5
CASE TWS_EVOLVING_6
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_EVOLVING_WIDTH, cfTWS_PLAYER_3_EVOLVING_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-96.0)
sPlayerData.fShadowXOffset = -30.0
BREAK
CASE TWS_FALL_INFINITE
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_JUMP_WIDTH, cfTWS_PLAYER_3_JUMP_HEIGHT)
sPlayerData.vSpriteOffset = INIT_VECTOR_2D(0.0,-40.0)
BREAK
CASE TWS_FALL_HOLE_1
CASE TWS_FALL_HOLE_2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_JUMP_HOLE_WIDTH, cfTWS_PLAYER_JUMP_HOLE_HEIGHT)
BREAK
ENDSWITCH
BREAK
ENDSWITCH
ENDPROC
FUNC BOOL TWS_CAN_BOSS_BE_HIT_AGAIN()
IF sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_IDLE
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_LANDING
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_FALL
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_FALL_OVER_1
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_FALL_OVER_2
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_STUN
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_GETTING_UP
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_TELEPORT_IN
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_TELEPORT_OUT
AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState != TWS_ENEMY_TELEPORTING
AND (
NOT sPlayerData.bIsAttacking
OR (sPlayerData.iLevel < 3 AND sPlayerData.bIsAttacking AND sPlayerData.iSpriteAnimFrame > ciTWS_ATTACK_ANIM_FRAMES)
OR (sPlayerData.iLevel >= 3 AND sPlayerData.bIsAttacking AND sPlayerData.iSpriteAnimFrame > ciTWS_ATTACK_EXTENDED_ANIM_FRAMES)
)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC TWS_CHECK_PLAYER_COLLIDING_WITH_ENEMY()
INT i
FLOAT fFactor = 1.0
FOR i = 0 TO ciTWS_MAX_ENEMIES -1
IF sEnemyData[i].bIsActive
IF i = sTWSData.iBossEnemyIndex
OR sEnemyData[i].eEnemyType = TWS_ENEMY_KNIGHT
IF sEnemyData[i].bIsHit AND TWS_CAN_BOSS_BE_HIT_AGAIN()
sEnemyData[i].bIsHit = FALSE
ENDIF
ENDIF
IF sPlayerData.vSpritePos.X < (sEnemyData[i].vSpritePos.x + sEnemyData[i].vSpriteSize.X + sEnemyData[i].vSpriteOffset.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteOffset.X + sPlayerData.vSpriteSize.X*fFactor) > sEnemyData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sEnemyData[i].vSpritePos.Y + sEnemyData[i].vSpriteSize.Y + sEnemyData[i].vSpriteOffset.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y + sPlayerData.vSpriteOffset.Y) > sEnemyData[i].vSpritePos.Y
AND ((NOT sPlayerData.bIsJumping AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sEnemyData[i].vSpritePos.Y + sEnemyData[i].vSpriteSize.Y + sEnemyData[i].vSpriteOffset.Y)) < TWS_GET_Z_WIDTH_FOR_ENEMY_TYPE(sEnemyData[i].eEnemyType))
OR (sPlayerData.bIsJumping AND ABSF((sPlayerData.vInitialJumpPos.Y + sPlayerData.vSpriteSize.Y) - (sEnemyData[i].vSpritePos.Y + sEnemyData[i].vSpriteSize.Y + sEnemyData[i].vSpriteOffset.Y)) < TWS_GET_Z_WIDTH_FOR_ENEMY_TYPE(sEnemyData[i].eEnemyType)))
IF sEnemyData[i].bIsHit = FALSE AND sPlayerData.bIsAttacking
AND NOT (sEnemyData[i].eEnemyState = TWS_ENEMY_ATTACK AND sEnemyData[i].iSpriteAnimFrame >= sEnemyData[i].iAttackFrame)
AND sEnemyData[i].eEnemyState != TWS_ENEMY_STUN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING
IF (sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x AND sPlayerData.bFacingLeft)
OR (sEnemyData[i].vSpritePos.x >= sPlayerData.vSpritePos.x AND NOT sPlayerData.bFacingLeft)
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : Player hit enemy! (", i,")")
sEnemyData[i].bIsHit = TRUE
sPlayerData.bIsHit = FALSE
IF sPlayerData.bIsCharging
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_DASH_HIT)
ELIF sPlayerData.bIsJumping
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_JUMP_KICK_HIT)
ELIF sPlayerData.bAttackIsLow
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_KICK_HIT)
ELIF sPlayerData.bAttackIsDouble
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_LONG_HIT)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_SHORT_HIT)
ENDIF
IF i = sTWSData.iBossEnemyIndex
IF sEnemyData[i].eEnemyState = TWS_ENEMY_IDLE
IF sEnemyData[i].eEnemyType = TWS_ENEMY_BOSS_SPIDER
sEnemyData[i].fHealth -= (0.015 * sPlayerData.iLevel + BOOL_TO_INT(sPlayerData.bIsJumping)*0.02)
ELSE
sEnemyData[i].fHealth -= (0.05 * sPlayerData.iLevel + BOOL_TO_INT(sPlayerData.bIsJumping)*0.02)
ENDIF
ELIF sEnemyData[i].eEnemyState = TWS_ENEMY_LANDING
IF sEnemyData[i].eEnemyType = TWS_ENEMY_BOSS_SPIDER
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.015 * sPlayerData.iLevel + BOOL_TO_INT(sPlayerData.bIsJumping)*0.02, 0.015, 1.0)
ELSE
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.05 * sPlayerData.iLevel + BOOL_TO_INT(sPlayerData.bIsJumping)*0.02, 0.015, 1.0)
ENDIF
ELIF sEnemyData[i].eEnemyState != TWS_ENEMY_STUN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_1
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_2
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_3
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_4
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_5
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_6
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_7
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_8
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DEAD
AND sEnemyData[i].eEnemyState != TWS_ENEMY_EXPLODING
AND sEnemyData[i].eEnemyState != TWS_ENEMY_FALL
AND sEnemyData[i].eEnemyState != TWS_ENEMY_FLAT
AND sEnemyData[i].eEnemyState != TWS_ENEMY_TELEPORT_IN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_TELEPORT_OUT
IF sEnemyData[i].eEnemyType = TWS_ENEMY_BOSS_AMAZON
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.015 * sPlayerData.iLevel, 0.015, 1.0)
ELSE
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.01 * sPlayerData.iLevel, 0.015, 1.0)
ENDIF
CPRINTLN(DEBUG_MINIGAME, "Boss hit (Minor damage: ",sEnemyData[i].fHealth, ")")
ENDIF
ELSE
SWITCH sEnemyData[i].iEnemySize
CASE 0
sEnemyData[i].fHealth -= (0.15 + BOOL_TO_INT(sPlayerData.bIsCharging)*0.05 + BOOL_TO_INT(sPlayerData.bIsJumping)*0.025) * sPlayerData.iLevel
BREAK
CASE 1
sEnemyData[i].fHealth -= (0.1 + BOOL_TO_INT(sPlayerData.bIsCharging)*0.05 + BOOL_TO_INT(sPlayerData.bIsJumping)*0.025) * sPlayerData.iLevel
BREAK
CASE 2
sEnemyData[i].fHealth -= (0.05 + BOOL_TO_INT(sPlayerData.bIsCharging)*0.05 + BOOL_TO_INT(sPlayerData.bIsJumping)*0.025) * sPlayerData.iLevel
BREAK
CASE 3
sEnemyData[i].fHealth -= (0.05 + BOOL_TO_INT(sPlayerData.bIsCharging)*0.05 + BOOL_TO_INT(sPlayerData.bIsJumping)*0.025) * sPlayerData.iLevel
BREAK
ENDSWITCH
ENDIF
IF sEnemyData[i].bIsAttacking
ARCADE_GAMES_SOUND_STOP(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType))
ENDIF
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].fHealth = 0.0
IF sTWSData.iBossEnemyIndex != i
IF sPlayerData.bFacingLeft
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x - cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), sEnemyData[i].eEnemyType)
ELSE
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x + cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), sEnemyData[i].eEnemyType)
ENDIF
ENDIF
TWS_ADD_SCORE_FOR_KILL(sEnemyData[i].eEnemyType)
ENDIF
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x - sEnemyData[i].vSpriteSize.x/2, sPlayerData.vSpritePos.Y), TWS_GET_FX_HIT(TRUE, i), sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y + 50.0)
ENDIF
ELIF NOT sPlayerData.bIsInvincible
AND NOT TWS_HAS_BOSS_BATTLE_FINISHED()
AND NOT TWS_ENEMY_ATTACKS_WITH_PROJECTILE(i)
AND sPlayerData.bIsInvincible = FALSE
AND sPlayerData.bIsHit = FALSE
AND sPlayerData.bIsEvolving = FALSE
AND sPlayerData.bIsUsingMagic = FALSE
AND sPlayerData.bIsCharging = FALSE
AND sPlayerData.bAttackIsDouble = FALSE
AND sPlayerData.bIsAttacking = FALSE
AND sEnemyData[i].eEnemyState != TWS_ENEMY_STUN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DEAD
AND ((sEnemyData[i].eEnemyState = TWS_ENEMY_ATTACK AND sEnemyData[i].iSpriteAnimFrame >= sEnemyData[i].iAttackFrame-1)
OR TWS_ENEMY_CAUSES_DAMAGE_ON_MOVEMENT(i)
OR sEnemyData[i].eEnemyType = TWS_ENEMY_BOSS_SPIDER AND sEnemyData[i].bIsAttacking AND NOT sPlayerData.bIsJumping
OR sEnemyData[i].eEnemyType = TWS_ENEMY_BOSS_AMAZON AND sEnemyData[i].bIsAttacking)
sPlayerData.bIsHit = TRUE
IF sEnemyData[i].eEnemyType = TWS_ENEMY_BRUTE OR sEnemyData[i].eEnemyType = TWS_ENEMY_BRUTE_AXE OR sEnemyData[i].eEnemyType = TWS_ENEMY_BOULDER
OR sEnemyData[i].eEnemyType = TWS_ENEMY_KNIGHT OR sTWSData.iBossEnemyIndex = i
sPlayerData.bIsFalling = TRUE
ENDIF
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.25 + (0.05*sPlayerData.iLevel), 0.0, 1.0)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : Player was jumping? (", sPlayerData.bIsJumping,")")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : Player was attacking? (", sPlayerData.bIsAttacking,")")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : Player was hit -20! (", i,")")
TWS_CREATE_FX(INIT_VECTOR_2D(sPlayerData.vSpritePos.x - sPlayerData.vSpriteSize.x/1.5, sEnemyData[i].vSpritePos.Y), TWS_GET_FX_HIT(FALSE, i), sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y + 50.0)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x AND NOT sPlayerData.bFacingLeft
sPlayerData.bFacingLeft = TRUE
ELIF sEnemyData[i].vSpritePos.x > sPlayerData.vSpritePos.x AND sPlayerData.bFacingLeft
sPlayerData.bFacingLeft = FALSE
ENDIF
ENDIF
ENDIF
ENDIF
ENDFOR
ENDPROC
PROC TWS_ACTIVATE_ITEM(INT iItemIndex)
TWS_CREATE_FX(sItemData[iItemIndex].vSpritePos, TWS_FX_PICKUP, -100)
SWITCH sItemData[iItemIndex].eItemType
CASE TWS_ITEM_HP_SMA
sTWSData.sTelemetry.powerUps ++
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth + 0.25, 0.0, 1.0)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_HP)
BREAK
CASE TWS_ITEM_HP_MED
sTWSData.sTelemetry.powerUps ++
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth + 0.5, 0.0, 1.0)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_HP)
BREAK
CASE TWS_ITEM_HP_LAR
sTWSData.sTelemetry.powerUps ++
IF sPlayerData.fHealth >= 1.0
sPlayerData.iLifes ++
ELSE
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth + 1.0, 0.0, 1.0)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_HP_BIG)
BREAK
CASE TWS_ITEM_MP_SMA
sTWSData.sTelemetry.powerUps ++
sPlayerData.fMagic = CLAMP(sPlayerData.fMagic + 0.25, 0.0, 1.0)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_MP)
IF sPlayerData.fMagic >= 1.0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_FULL)
ENDIF
BREAK
CASE TWS_ITEM_MP_MED
sTWSData.sTelemetry.powerUps ++
sPlayerData.fMagic = CLAMP(sPlayerData.fMagic + 0.5, 0.0, 1.0)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_MP)
IF sPlayerData.fMagic >= 1.0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_FULL)
ENDIF
BREAK
CASE TWS_ITEM_MP_LAR
sTWSData.sTelemetry.powerUps ++
sPlayerData.fMagic = CLAMP(sPlayerData.fMagic + 1.0, 0.0, 1.0)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_MP_BIG)
IF sPlayerData.fMagic >= 1.0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_FULL)
ENDIF
BREAK
CASE TWS_ITEM_1UP
sPlayerData.iLifes ++
sTWSData.sTelemetry.powerUps ++
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_EXTRA_LIFE)
BREAK
DEFAULT
sPlayerData.iScore += (TWS_GET_SCORE_BONUS_FOR_GOLD_TYPE(sItemData[iItemIndex].eItemType))
IF sPlayerData.iScore > sPlayerData.iHighestScore
sPlayerData.iHighestScore = sPlayerData.iScore
ENDIF
sPlayerData.iTreasures += (TWS_GET_SCORE_BONUS_FOR_GOLD_TYPE(sItemData[iItemIndex].eItemType))
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PICKUP_GOLD)
BREAK
ENDSWITCH
TWS_RESET_ITEM_VARIABLES(iItemIndex)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ITEM, iItemIndex)
ENDPROC
PROC TWS_CHECK_PLAYER_COLLIDING_WITH_ITEMS()
INT i
FOR i = 0 TO ciTWS_MAX_ITEMS -1
IF (sPlayerData.vSpritePos.X < (sItemData[i].vSpritePos.x + sItemData[i].vSpriteSize.x) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sItemData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y < (sItemData[i].vSpritePos.Y + sItemData[i].vSpriteSize.Y) AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sItemData[i].vSpritePos.Y)
IF sItemData[i].bIsHit = FALSE
sItemData[i].bIsHit = TRUE
TWS_ACTIVATE_ITEM(i)
ENDIF
ENDIF
ENDFOR
ENDPROC
PROC TWS_ACTIVATE_TRAP(INT iTrapIndex)
SWITCH sTrapsData[iTrapIndex].eType
CASE TWS_TRAP_FALL
IF sPlayerData.ePlayerState != TWS_FALL_INFINITE AND sPlayerData.ePlayerState != TWS_GETTING_UP AND sPlayerData.ePlayerState != TWS_DEAD
CDEBUG3LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : HIT TRAP")
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
TWS_SET_PLAYER_STATE(TWS_FALL_INFINITE)
sPlayerData.bIsJumping = TRUE
sPlayerData.fJumpAcceleration = 0.0
sPlayerData.vInitialJumpPos.y = cfBASE_SCREEN_HEIGHT*2
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
ENDIF
BREAK
CASE TWS_TRAP_HOLE
IF sPlayerData.ePlayerState != TWS_FALL_INFINITE AND sPlayerData.ePlayerState != TWS_GETTING_UP
CDEBUG3LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : HIT TRAP")
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_FALL_HOLE_1)
sPlayerData.vSpritePos = INIT_VECTOR_2D(sTrapsData[iTrapIndex].vSpritePos.x, sTrapsData[iTrapIndex].vSpritePos.y - 150.0)
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
ENDIF
BREAK
CASE TWS_TRAP_STALAGTITE
IF sTrapsData[iTrapIndex].bIsWorking
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STALACTITE_CRACK)
sTrapsData[iTrapIndex].bIsWorking = FALSE
ENDIF
IF sTrapsData[iTrapIndex].vSpritePos2.y < sTrapsData[iTrapIndex].vSpritePos.y - sTrapsData[iTrapIndex].vSpriteSize.y
sTrapsData[iTrapIndex].vSpritePos2.y = sTrapsData[iTrapIndex].vSpritePos2.y +@ cfTWS_VERTICAL_MOVEMENT_STALACTITES
IF sTrapsData[iTrapIndex].vSpritePos2.y >= sTrapsData[iTrapIndex].vSpritePos.y - sTrapsData[iTrapIndex].vSpriteSize.y
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STALACTITE_LAND)
ENDIF
IF VECTOR_2D_DIST(sPlayerData.vSpritePos, INIT_VECTOR_2D(sTrapsData[iTrapIndex].vSpritePos.x, sTrapsData[iTrapIndex].vSpritePos.y - sPlayerData.vSpriteSize.y)) < 75.0
AND (sPlayerData.vSpritePos.X < (sTrapsData[iTrapIndex].vSpritePos2.x + sTrapsData[iTrapIndex].vSpriteSize.x) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sTrapsData[iTrapIndex].vSpritePos2.x
AND sPlayerData.vSpritePos.Y < (sTrapsData[iTrapIndex].vSpritePos2.Y + sTrapsData[iTrapIndex].vSpriteSize.Y) AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sTrapsData[iTrapIndex].vSpritePos2.Y)
AND sPlayerData.ePlayerState != TWS_FALL_INFINITE AND sPlayerData.ePlayerState != TWS_GETTING_UP
AND TWS_CAN_PLAYER_BE_HURT(TRUE)
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : Player was hit by stalactite -10!")
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
PROC TWS_CHECK_PLAYER_COLLIDING_WITH_TRAPS()
INT i
FOR i = 0 TO ciTWS_MAX_TRAPS -1
IF sTrapsData[i].bIsActive
SWITCH sTrapsData[i].eType
CASE TWS_TRAP_FALL
IF (sPlayerData.vSpritePos.Y + sPlayerData.vSpriteOffset.Y) > sTrapsData[i].vSpritePos.Y
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteOffset.X) > (sTrapsData[i].vSpritePos.x - sTrapsData[i].vSpriteSize.x)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteOffset.X) < (sTrapsData[i].vSpritePos.x + sTrapsData[i].vSpriteSize.x)
TWS_ACTIVATE_TRAP(i)
ENDIF
BREAK
CASE TWS_TRAP_HOLE
IF (sPlayerData.vSpritePos.X - sPlayerData.vSpriteSize.y < (sTrapsData[i].vSpritePos.x + sTrapsData[i].vSpriteSize.x) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X * cfTWS_RESCALE_FACTOR) > sTrapsData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.y < (sTrapsData[i].vSpritePos.Y + sTrapsData[i].vSpriteSize.Y) AND (sPlayerData.vSpriteSize.Y * cfTWS_RESCALE_FACTOR + sPlayerData.vSpritePos.Y) > sTrapsData[i].vSpritePos.Y)
AND VECTOR_2D_DIST(sPlayerData.vSpritePos, INIT_VECTOR_2D(sTrapsData[i].vSpritePos.x, sTrapsData[i].vSpritePos.y - sPlayerData.vSpriteSize.y)) < 30.0
AND NOT sPlayerData.bIsJumping
TWS_ACTIVATE_TRAP(i)
ENDIF
BREAK
CASE TWS_TRAP_STALAGTITE
IF sTrapsData[i].bIsActive
IF NOT sTrapsData[i].bIsWorking OR VECTOR_2D_DIST(sPlayerData.vSpritePos, INIT_VECTOR_2D(sTrapsData[i].vSpritePos.x, sTrapsData[i].vSpritePos.y - sPlayerData.vSpriteSize.y)) < 50.0
TWS_ACTIVATE_TRAP(i)
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDFOR
ENDPROC
PROC TWS_TASK_PLAYER_TO_MOVE_TO_CENTER()
TWS_RESET_PLAYER_VARIABLES()
sPlayerData.bIsMovingToCenter = TRUE
ENDPROC
PROC TWS_TASK_PLAYER_TO_MOVE_OUT_OFF_SCREEN()
TWS_RESET_PLAYER_VARIABLES()
sPlayerData.bIsMovingOutOfScreen = TRUE
ENDPROC
PROC TWS_TASK_PLAYER_TO_MOVE_LEFT()
TWS_RESET_PLAYER_VARIABLES()
sPlayerData.bIsMovingLeft = TRUE
ENDPROC
PROC TWS_HANDLE_SCREEN_EFFECTS()
IF sTWSData.eCurrentLevel = TWS_CASTLE
IF NOT TWS_IS_CAMERA_SHAKE_ACTIVE() AND TWS_IS_ENEMY_OF_TYPE_ON_SCREEN(TWS_ENEMY_BOULDER)
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
ELIF TWS_IS_CAMERA_SHAKE_ACTIVE() AND NOT TWS_IS_ENEMY_OF_TYPE_ON_SCREEN(TWS_ENEMY_BOULDER)
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
ENDIF
ENDIF
ENDPROC
PROC TWS_HANDLE_PLAYER_MOVEMENT()
BOOL bLeft, bRight, bUp, bDown, bAttack, bJump, bSuperAttack, bEvolve, bCharge
IF IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_LB)
CPRINTLN(DEBUG_MINIGAME, "ENEMIES?: ", TWS_IS_ANY_ENEMY_ON_SCREEN(TRUE))
ENDIF
IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
IF sTWSData.eLevelStage <= TWS_LEVEL_BOSS_FIGHT
AND sTWSData.eLevelStage != TWS_LEVEL_DIALOGUE_PRE_FIGHT
bLeft = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_LEFT)// OR GET_DISABLED_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_X)
bRight = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_RIGHT)
bUp = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_UP)
bDown = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_DOWN)
bJump = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SKIP_CUTSCENE)
bAttack = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_LEFT)
bCharge = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_DOWN)
bSuperAttack = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_RIGHT)
bEvolve = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_UP)
IF (bLeft OR bRight OR bUp OR bDown)
IF NOT sTWSData.bShowedTextHelp[TWS_TH_MOVE]
sTWSData.bShowedTextHelp[TWS_TH_MOVE] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_MOVE)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ENDIF
ELSE
IF sPlayerData.bIsMovingToCenter
IF sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - 25
bRight = TRUE
ELIF sPlayerData.vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + 25
bLeft = TRUE
ENDIF
IF sPlayerData.vSpritePos.Y < cfBASE_SCREEN_HEIGHT/2 - 25
bDown = TRUE
ELIF sPlayerData.vSpritePos.Y > cfBASE_SCREEN_HEIGHT*0.6 + 25
bUp = TRUE
ENDIF
ELIF sPlayerData.bIsMovingLeft
IF sPlayerData.vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.2
bLeft = TRUE
ENDIF
IF sPlayerData.vSpritePos.Y < cfBASE_SCREEN_HEIGHT*0.6 - 25
bDown = TRUE
ELIF sPlayerData.vSpritePos.Y > cfBASE_SCREEN_HEIGHT*0.6 + 25
bUp = TRUE
ENDIF
IF sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.2
AND sPlayerData.vSpritePos.Y > cfBASE_SCREEN_HEIGHT*0.6 - 25
sPlayerData.bIsMovingLeft = FALSE
sPlayerData.bFacingLeft = FALSE
ENDIF
ELIF sPlayerData.bIsMovingOutOfScreen
IF sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH/2 // + sPlayerData.vSpriteSize.x
bRight = TRUE
ELSE
sPlayerData.bIsMovingOutOfScreen = FALSE
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
ENDIF
ENDIF
ELSE
IF sTWSData.eLevelStage <= TWS_LEVEL_BOSS_FIGHT
AND sTWSData.eLevelStage != TWS_LEVEL_DIALOGUE_PRE_FIGHT
FLOAT fAxisThresholdMod = 0.5
bLeft = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_LEFT)// OR GET_DISABLED_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_X)
bRight = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_RIGHT)
bUp = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_UP)
bDown = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_DOWN)
bAttack = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RRIGHT)
bJump = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RDOWN)
bSuperAttack = IS_CONTROL_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RUP)
bEvolve = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RB)
bCharge = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RLEFT)
// Joystick
FLOAT fRightStickX = GET_DISABLED_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_X)
FLOAT fRightStickY = GET_DISABLED_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_Y)
IF fRightStickX < -cfSTICK_THRESHOLD * fAxisThresholdMod
bLeft = TRUE
ELIF fRightStickX > cfSTICK_THRESHOLD * fAxisThresholdMod
bRight = TRUE
ENDIF
IF fRightStickY < -cfSTICK_THRESHOLD * fAxisThresholdMod
bUp = TRUE
ELIF fRightStickY > cfSTICK_THRESHOLD * fAxisThresholdMod
bDown = TRUE
ENDIF
IF (bLeft OR bRight OR bUp OR bDown)
IF NOT sTWSData.bShowedTextHelp[TWS_TH_MOVE]
sTWSData.bShowedTextHelp[TWS_TH_MOVE] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_MOVE)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ENDIF
ELSE
IF sPlayerData.bIsMovingToCenter
IF sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - 25
bRight = TRUE
ELIF sPlayerData.vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + 25
bLeft = TRUE
ENDIF
IF sPlayerData.vSpritePos.Y < cfBASE_SCREEN_HEIGHT/2 - 25
bDown = TRUE
ELIF sPlayerData.vSpritePos.Y > cfBASE_SCREEN_HEIGHT*0.6 + 25
bUp = TRUE
ENDIF
ELIF sPlayerData.bIsMovingLeft
IF sPlayerData.vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.2
bLeft = TRUE
ENDIF
IF sPlayerData.vSpritePos.Y < cfBASE_SCREEN_HEIGHT*0.6 - 25
bDown = TRUE
ELIF sPlayerData.vSpritePos.Y > cfBASE_SCREEN_HEIGHT*0.6 + 25
bUp = TRUE
ENDIF
IF sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.2
AND sPlayerData.vSpritePos.Y > cfBASE_SCREEN_HEIGHT*0.6 - 25
sPlayerData.bIsMovingLeft = FALSE
sPlayerData.bFacingLeft = FALSE
ENDIF
ELIF sPlayerData.bIsMovingOutOfScreen
IF sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH/2 // + sPlayerData.vSpriteSize.x
bRight = TRUE
ELSE
sPlayerData.bIsMovingOutOfScreen = FALSE
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
ENDIF
ENDIF
ENDIF
// Rotate player
IF sPlayerData.ePlayerState != TWS_INTRO AND sPlayerData.ePlayerState != TWS_FALL AND sPlayerData.ePlayerState != TWS_FALL_2 AND sPlayerData.ePlayerState != TWS_FLAT AND NOT sPlayerData.bIsEvolving
IF bLeft AND NOT sPlayerData.bIsAttacking AND NOT sPlayerData.bFacingLeft// AND GET_GAME_TIMER() - sPlayerData.iTimeSinceLastDirectionChange > ciTWS_ROTATE_PLAYER_DELAY
sPlayerData.bFacingLeft = TRUE
ELIF bRight AND NOT sPlayerData.bIsAttacking AND sPlayerData.bFacingLeft// AND GET_GAME_TIMER() - sPlayerData.iTimeSinceLastDirectionChange > ciTWS_ROTATE_PLAYER_DELAY
sPlayerData.bFacingLeft = FALSE
ENDIF
ENDIF
IF sPlayerData.ePlayerState = TWS_INTRO
sPlayerData.bIsMoving = TRUE
sPlayerData.vSpritePos.x = sPlayerData.vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER
EXIT
ENDIF
sPlayerData.bIsMoving = (bLeft OR bRight OR bUp OR bDown) AND NOT sPlayerData.bIsUsingMagic AND NOT sPlayerData.bIsEvolving
TWS_CHECK_PLAYER_COLLIDING_WITH_ENEMY()
TWS_CHECK_PLAYER_COLLIDING_WITH_ITEMS()
TWS_CHECK_PLAYER_COLLIDING_WITH_TRAPS()
// Charge
IF bCharge AND sPlayerData.fMagic >= 0.3 AND GET_GAME_TIMER() - sPlayerData.iLastCharge > 1000 AND NOT sPlayerData.bIsAttacking AND NOT sPlayerData.bIsUsingMagic AND NOT sPlayerData.bIsHit AND NOT sPlayerData.bIsCharging
sPlayerData.bIsCharging = TRUE
IF NOT sTWSData.bShowedTextHelp[TWS_TH_DASH]
sTWSData.bShowedTextHelp[TWS_TH_DASH] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_DASH)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ELIF bCharge AND sPlayerData.fMagic < 0.3
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_EMPTY)
ENDIF
// Superattack
IF bSuperAttack AND sPlayerData.fMagic >= 0.04 AND NOT sPlayerData.bIsAttacking AND NOT sPlayerData.bIsJumping AND NOT sPlayerData.bIsCharging AND NOT sPlayerData.bIsUsingMagic AND NOT sPlayerData.bIsHit
sPlayerData.bIsUsingMagic = TRUE
IF NOT sTWSData.bShowedTextHelp[TWS_TH_MAGIC]
sTWSData.bShowedTextHelp[TWS_TH_MAGIC] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_MAGIC)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ELIF bSuperAttack AND sPlayerData.fMagic < 0.04
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_EMPTY)
ENDIF
// Evolution
IF NOT sTWSData.bIsHardCoreMode AND bEvolve AND sPlayerData.iLevel < 3 AND sPlayerData.fMagic >= 1.0 AND NOT sPlayerData.bIsAttacking AND NOT sPlayerData.bIsCharging AND NOT sPlayerData.bIsUsingMagic AND NOT sPlayerData.bIsHit
sPlayerData.bIsEvolving = TRUE
sPlayerData.bIsUsingMagic = TRUE
IF NOT sTWSData.bShowedTextHelp[TWS_TH_EVOLUTION]
sTWSData.bShowedTextHelp[TWS_TH_EVOLUTION] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_EVOLUTION)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ELIF bEvolve AND sPlayerData.fMagic < 1.0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_EMPTY)
ENDIF
IF bAttack AND sPlayerData.bIsAttacking AND NOT sPlayerData.bAttackIsLow AND NOT sPlayerData.bAttackIsDouble AND NOT sPlayerData.bIsCharging AND NOT sPlayerData.bIsEvolving AND GET_GAME_TIMER() - sPlayerData.iTimeSinceLastAttack > 100
sPlayerData.bAttackIsDouble = TRUE
sPlayerData.iTimeSinceLastAttack = GET_GAME_TIMER()
ENDIF
//Attack
IF bAttack AND NOT sPlayerData.bIsAttacking AND NOT sPlayerData.bIsHit AND NOT sPlayerData.bIsEvolving
sPlayerData.bIsAttacking = TRUE
IF NOT sPlayerData.bIsJumping AND TWS_IS_ENEMY_SMALL(TWS_GET_CLOSEST_ENEMY())
sPlayerData.bAttackIsLow = TRUE
ELIF sPlayerData.bIsJumping
IF NOT sTWSData.bShowedTextHelp[TWS_TH_JUMP_ATTACK]
sTWSData.bShowedTextHelp[TWS_TH_JUMP_ATTACK] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_JUMP_ATTACK)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ENDIF
sPlayerData.iTimeSinceLastAttack = GET_GAME_TIMER()
IF NOT sTWSData.bShowedTextHelp[TWS_TH_ATTACK]
sTWSData.bShowedTextHelp[TWS_TH_ATTACK] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_ATTACK)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ELIF bJump AND NOT sPlayerData.bIsFalling AND NOT sPlayerData.bIsJumping AND NOT sPlayerData.bIsHit AND NOT sPlayerData.bIsCharging AND NOT sPlayerData.bIsEvolving AND NOT sPlayerData.bIsUsingMagic
CDEBUG2LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : Player started to jump")
sPlayerData.bIsJumping = TRUE
sPlayerData.vInitialJumpPos.Y = sPlayerData.vSpritePos.Y
sPlayerData.fJumpAcceleration = ciTWS_JUMP_ACCELERATION
sPlayerData.vSpritePos.y = sPlayerData.vSpritePos.y -@ sPlayerData.fJumpAcceleration
sPlayerData.fJumpAcceleration = sPlayerData.fJumpAcceleration +@ ciTWS_GRAVITY
IF NOT sTWSData.bShowedTextHelp[TWS_TH_JUMP]
sTWSData.bShowedTextHelp[TWS_TH_JUMP] = TRUE
ELIF ARCADE_GAMES_HELP_TEXT_IS_THIS_BEING_DISPLAYED(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_JUMP)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ENDIF
ENDIF
IF sPlayerData.bIsJumping AND sPlayerData.vSpritePos.y < sPlayerData.vInitialJumpPos.y
CDEBUG2LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : Player jumping, reducing acceleration")
sPlayerData.vSpritePos.y = sPlayerData.vSpritePos.y -@ sPlayerData.fJumpAcceleration
IF sPlayerData.vSpritePos.y > sPlayerData.vInitialJumpPos.y
sPlayerData.vSpritePos.y = sPlayerData.vInitialJumpPos.y
ENDIF
sPlayerData.fJumpAcceleration = sPlayerData.fJumpAcceleration +@ ciTWS_GRAVITY
ENDIF
IF NOT sPlayerData.bIsHit
AND NOT sPlayerData.bIsUsingMagic
AND NOT sPlayerData.bIsCharging
AND NOT sPlayerData.bIsEvolving
AND NOT (NOT sPlayerData.bIsJumping AND sPlayerData.bIsAttacking)
AND sPlayerData.ePlayerState != TWS_INTRO
AND sPlayerData.ePlayerState != TWS_FALL_INFINITE
AND sPlayerData.ePlayerState != TWS_FALL_HOLE_1
AND sPlayerData.ePlayerState != TWS_FALL_HOLE_2
AND sPlayerData.ePlayerState != TWS_FALL_HIGH
AND sPlayerData.ePlayerState != TWS_FALL
AND sPlayerData.ePlayerState != TWS_FALL_2
AND sPlayerData.ePlayerState != TWS_FLAT
AND sPlayerData.ePlayerState != TWS_GETTING_UP
AND sPlayerData.ePlayerState != TWS_DEAD
//Movement
IF bLeft
AND ((sPlayerData.vSpritePos.x > 400 AND sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND NOT sTWSData.bLockedScreen AND sTWSData.eCurrentLevel != TWS_CASTLE)
OR (sPlayerData.vSpritePos.Y > 605 AND sPlayerData.vSpritePos.x > 530 AND sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND NOT sTWSData.bLockedScreen AND sTWSData.eCurrentLevel = TWS_CASTLE)
OR (sPlayerData.vSpritePos.Y <= 605 AND sPlayerData.vSpritePos.x > 780 AND sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND NOT sTWSData.bLockedScreen AND sTWSData.eCurrentLevel = TWS_CASTLE)
OR (sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT AND sPlayerData.vSpritePos.x > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpriteWidth*0.45)
OR (sTWSData.bLockedScreen AND sPlayerData.vSpritePos.x > sTWSData.fLockedScreenPos - cfGAME_SCREEN_WIDTH*0.45))
sPlayerData.vSpritePos.x = sPlayerData.vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER
sPlayerData.vInitialJumpPos.x = sPlayerData.vInitialJumpPos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER
ELIF bRight AND (
(NOT sTWSData.bLockedScreen AND sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpriteWidth*0.45 OR sPlayerData.bIsMovingOutOfScreen)
OR (sTWSData.bLockedScreen AND sPlayerData.vSpritePos.x < sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.45)
)
sPlayerData.vSpritePos.x = sPlayerData.vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER
sPlayerData.vInitialJumpPos.x = sPlayerData.vInitialJumpPos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER
ENDIF
IF bUp
AND ((sPlayerData.vSpritePos.Y > 520 AND sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND sTWSData.eCurrentLevel != TWS_CASTLE)
OR (sPlayerData.vSpritePos.X > 760.0 AND sPlayerData.vSpritePos.Y > 500 AND sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND sTWSData.eCurrentLevel = TWS_CASTLE)
OR (sPlayerData.vSpritePos.X <= 760.0 AND sPlayerData.vSpritePos.Y > 605 AND sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND sTWSData.eCurrentLevel = TWS_CASTLE)
OR (sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT AND sTWSData.eCurrentLevel != TWS_CASTLE AND sPlayerData.vSpritePos.Y > 580)
OR (sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT AND sTWSData.eCurrentLevel = TWS_CASTLE AND sPlayerData.vSpritePos.Y > 400))
sPlayerData.vSpritePos.y = sPlayerData.vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_PLAYER
sPlayerData.vInitialJumpPos.y = sPlayerData.vInitialJumpPos.y -@ cfTWS_VERTICAL_MOVEMENT_PLAYER
ELIF bDown AND sPlayerData.vSpritePos.y < 850.0
sPlayerData.vSpritePos.y = sPlayerData.vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_PLAYER
sPlayerData.vInitialJumpPos.y = sPlayerData.vInitialJumpPos.y +@ cfTWS_VERTICAL_MOVEMENT_PLAYER
ENDIF
ENDIF
ENDPROC
PROC TWS_PERFORM_SUPERATTACK()
INT iDrawCallIndex, iRandom
VECTOR_2D vPos
IF NOT sFXData[0].bActive
sFXData[0].bActive = TRUE
sFXData[0].eType = TWS_FX_SWORD_LIGHTNING
sFXData[0].vSpritePos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 10, sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.Y*2 - 40)
iDrawCallIndex = TWS_GET_NEXT_EMPTY_SLOT_FOR_DRAW_CALL()
CPRINTLN(DEBUG_MINIGAME, "CREATE FX IN SLOT ",iDrawCallIndex)
sTWSData.sDrawCalls[iDrawCallIndex].eType = TWS_ENTITY_FX
sTWSData.sDrawCalls[iDrawCallIndex].iIndex = 0
sTWSData.sDrawCalls[iDrawCallIndex].fZIndex = sFXData[0].vSpritePos.Y + sFXData[0].vSpriteSize.y
ENDIF
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 20)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_MAGIC_NUKE_SMALL_BLAST)
SWITCH sPlayerData.iLevel
// Random explosions on screen
CASE 1
iRandom = GET_RANDOM_INT_IN_RANGE(0,9)
SWITCH iRandom
CASE 0
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 300.0, sPlayerData.vSpritePos.y - 100.0)
BREAK
CASE 1
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 300.0, sPlayerData.vSpritePos.y - 100.0)
BREAK
CASE 2
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 150.0, sPlayerData.vSpritePos.y)
BREAK
CASE 3
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 150.0, sPlayerData.vSpritePos.y)
BREAK
CASE 4
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 300.0, sPlayerData.vSpritePos.y + 100.0)
BREAK
CASE 5
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 300.0, sPlayerData.vSpritePos.y + 100.0)
BREAK
CASE 6
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 450.0, sPlayerData.vSpritePos.y)
BREAK
CASE 7
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 450.0, sPlayerData.vSpritePos.y)
BREAK
CASE 8
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 80.0, sPlayerData.vSpritePos.y + 100.0)
BREAK
CASE 9
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 80.0, sPlayerData.vSpritePos.y + 100.0)
BREAK
ENDSWITCH
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
BREAK
// Explosions with a defined pattern T
CASE 2
SWITCH sPlayerData.iSuperAttackStage
CASE 0
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 100.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x, sPlayerData.vSpritePos.y + 100.0)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 100.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage ++
BREAK
CASE 1
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 250.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x, sPlayerData.vSpritePos.y + 250.0)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 250.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage ++
BREAK
CASE 2
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 400.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x, sPlayerData.vSpritePos.y + 400.0)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 400.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage ++
BREAK
CASE 3
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 550.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x, sPlayerData.vSpritePos.y + 550.0)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 550.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage = 0
BREAK
ENDSWITCH
BREAK
// Explosions on the enemies on screen
CASE 3
SWITCH sPlayerData.iSuperAttackStage
CASE 0
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 200.0, sPlayerData.vSpritePos.y - 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 300.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 200.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 200.0, sPlayerData.vSpritePos.y - 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 300.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 200.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage ++
BREAK
CASE 1
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 330.0, sPlayerData.vSpritePos.y - 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 430.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 330.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 330.0, sPlayerData.vSpritePos.y - 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 430.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 330.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage ++
BREAK
CASE 2
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 480.0, sPlayerData.vSpritePos.y - 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 580.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 480.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 480.0, sPlayerData.vSpritePos.y - 150)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 580.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 480.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage ++
BREAK
CASE 3
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 580.0, sPlayerData.vSpritePos.y - 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 680.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x + 580.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 580.0, sPlayerData.vSpritePos.y - 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 680.0, sPlayerData.vSpritePos.y)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
vPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - 580.0, sPlayerData.vSpritePos.y + 150)
TWS_CREATE_FX(vPos, TWS_FX_SUPERATTACK_EXPLOSION)
sPlayerData.iSuperAttackStage = 0
BREAK
ENDSWITCH
BREAK
ENDSWITCH
INT i, j
FOR i = 0 TO ciTWS_MAX_ENEMIES -1
FOR j = 1 TO ciTWS_MAX_FX -1
IF sEnemyData[i].bIsActive AND sEnemyData[i].eEnemyState != TWS_ENEMY_INACTIVE AND sFXData[j].eType = TWS_FX_SUPERATTACK_EXPLOSION AND sFXData[j].bActive AND sEnemyData[i].fHealth > 0.0 AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sFXData[j].vSpritePos) < 300.0
sEnemyData[i].bIsHit = TRUE
IF sPlayerData.iLevel = 3
IF i = sTWSData.iBossEnemyIndex
IF sEnemyData[i].eEnemyState = TWS_ENEMY_IDLE
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.025, 0.015, 1.0)
ELIF sEnemyData[i].eEnemyState = TWS_ENEMY_LANDING
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.025, 0.015, 1.0)
ELIF sEnemyData[i].eEnemyState != TWS_ENEMY_STUN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_1
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_2
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_3
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_4
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_5
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_6
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_7
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_8
AND sEnemyData[i].eEnemyState != TWS_ENEMY_EXPLODING
AND sEnemyData[i].eEnemyState != TWS_ENEMY_FALL
AND sEnemyData[i].eEnemyState != TWS_ENEMY_FLAT
AND sEnemyData[i].eEnemyState != TWS_ENEMY_TELEPORT_IN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_TELEPORT_OUT
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.01, 0.015, 1.0)
CPRINTLN(DEBUG_MINIGAME, "Boss hit (Minor damage: ",sEnemyData[i].fHealth, ")")
ENDIF
ELSE
sEnemyData[i].fHealth -= 1.0
ENDIF
CPRINTLN(DEBUG_MINIGAME, "Player damaged enemy ",i," with magic. Enemy health: ", sEnemyData[i].fHealth)
IF sEnemyData[i].fHealth <= 0.0
IF sTWSData.iBossEnemyIndex != i
IF sPlayerData.bFacingLeft
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x - cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), sEnemyData[i].eEnemyType)
ELSE
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x + cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), sEnemyData[i].eEnemyType)
ENDIF
ENDIF
TWS_ADD_SCORE_FOR_KILL(sEnemyData[i].eEnemyType)
ENDIF
ELSE
IF i = sTWSData.iBossEnemyIndex
IF sEnemyData[i].eEnemyState = TWS_ENEMY_IDLE
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.025, 0.000, 1.0)
ELIF sEnemyData[i].eEnemyState = TWS_ENEMY_LANDING
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.025, 0.015, 1.0)
ELIF sEnemyData[i].eEnemyState != TWS_ENEMY_STUN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_1
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_2
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_3
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_4
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_5
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_6
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_7
AND sEnemyData[i].eEnemyState != TWS_ENEMY_DYING_8
AND sEnemyData[i].eEnemyState != TWS_ENEMY_EXPLODING
AND sEnemyData[i].eEnemyState != TWS_ENEMY_FALL
AND sEnemyData[i].eEnemyState != TWS_ENEMY_FLAT
AND sEnemyData[i].eEnemyState != TWS_ENEMY_TELEPORT_IN
AND sEnemyData[i].eEnemyState != TWS_ENEMY_TELEPORT_OUT
sEnemyData[i].fHealth = CLAMP(sEnemyData[i].fHealth - 0.01, 0.015, 1.0)
CPRINTLN(DEBUG_MINIGAME, "Boss hit (Minor damage: ",sEnemyData[i].fHealth, ")")
ENDIF
ELSE
sEnemyData[i].fHealth -= 0.2
ENDIF
CPRINTLN(DEBUG_MINIGAME, "Player damaged enemy ",i," with magic. Enemy health: ", sEnemyData[i].fHealth)
IF sEnemyData[i].fHealth <= 0.0
IF sTWSData.iBossEnemyIndex != i
IF sPlayerData.bFacingLeft
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x - cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), sEnemyData[i].eEnemyType)
ELSE
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x + cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), sEnemyData[i].eEnemyType)
ENDIF
ENDIF
TWS_ADD_SCORE_FOR_KILL(sEnemyData[i].eEnemyType)
ENDIF
ENDIF
ENDIF
ENDFOR
ENDFOR
ENDPROC
PROC TWS_INCREMENT_ANIM_FRAME_FOR_PLAYER()
SWITCH sPlayerData.ePlayerState
// 10 FPS
CASE TWS_IDLE
CASE TWS_EVOLVING
CASE TWS_EVOLVING_2
CASE TWS_EVOLVING_3
CASE TWS_EVOLVING_4
CASE TWS_EVOLVING_5
CASE TWS_EVOLVING_6
sPlayerData.iSpriteAnimFrame += sPlayerData.iSlowUpdateFrames
BREAK
// 15 FPS
CASE TWS_INTRO
CASE TWS_WALK
CASE TWS_SUPERATTACK
CASE TWS_ATTACK
CASE TWS_ATTACK_DOUBLE
CASE TWS_ATTACK_LOW
CASE TWS_CHARGE
CASE TWS_FALL_HOLE_1
CASE TWS_FALL_HOLE_2
CASE TWS_FALL
CASE TWS_FALL_HIGH
CASE TWS_FALL_2
CASE TWS_FLAT
CASE TWS_STUN
CASE TWS_DEAD
CASE TWS_GETTING_UP
CASE TWS_JUMP_ATTACK
CASE TWS_JUMP_ATTACK_DESCEND
CASE TWS_JUMP_START
CASE TWS_JUMP_ASCEND
CASE TWS_JUMP_CREST
CASE TWS_JUMP_DESCEND
CASE TWS_JUMP_END
CASE TWS_FALL_INFINITE
sPlayerData.iSpriteAnimFrame += sPlayerData.iDefaultUpdateFrames
BREAK
ENDSWITCH
ENDPROC
PROC TWS_RESET_PLAYER_AFTER_DYING(BOOL bFalling = FALSE)
IF sTWSData.eLevelStage != TWS_LEVEL_PLAYING
AND sTWSData.eLevelStage != TWS_LEVEL_BOSS_FIGHT
EXIT
ENDIF
// Lifes
sPlayerData.iLifes --
CPRINTLN(DEBUG_MINIGAME, "Wizard's Ruin - Player died and has now ", sPlayerData.iLifes, " lives left.")
IF sPlayerData.iLifes <= 0
DEGENATRON_GAMES_ANIMATION_SET_STATE(DEGENATRON_GAMES_ANIMATION_STATE_GAMEOVER)
sTWSData.eLevelStage = TWS_LEVEL_DEAD
sTWSData.iGameTimer = GET_GAME_TIMER()
sHUDData[TWS_HUD_GAMEOVER].bActive = TRUE
EXIT
ELSE
DEGENATRON_GAMES_ANIMATION_SET_STATE(DEGENATRON_GAMES_ANIMATION_STATE_DEAD)
ENDIF
// Health
sPlayerData.fHealth = 1.0
// Evolution
IF sPlayerData.iLevel > 1
sPlayerData.iLevel --
ENDIF
TWS_RESET_PLAYER_VARIABLES()
IF sTWSData.eLevelStage = TWS_LEVEL_PLAYING
// Move player to level start
IF bFalling
IF sTWSData.bLockedScreen
sPlayerData.vSpritePos = INIT_VECTOR_2D(sTWSData.fLockedScreenPos, -300)
sPlayerData.vInitialJumpPos = INIT_VECTOR_2D(sTWSData.fLockedScreenPos, cfBASE_SCREEN_HEIGHT*0.55)
ELSE
sPlayerData.vSpritePos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - cfBASE_SCREEN_WIDTH*0.25, -300)
sPlayerData.vInitialJumpPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x - cfBASE_SCREEN_WIDTH*0.25, cfBASE_SCREEN_HEIGHT*0.55)
ENDIF
sPlayerData.bIsJumping = TRUE
TWS_SET_PLAYER_STATE(TWS_FALL_HIGH)
ELSE
sPlayerData.vSpritePos = INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2, cfBASE_SCREEN_HEIGHT/2)
TWS_SET_PLAYER_STATE(TWS_GETTING_UP)
TWS_FADE_IN()
ENDIF
ELIF sTWSData.eLevelStage = TWS_LEVEL_BOSS_FIGHT
sPlayerData.bFacingLeft = FALSE
TWS_RESET_BOSS_FIGHT()
TWS_SET_PLAYER_STATE(TWS_INTRO)
sPlayerData.vSpritePos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.6, cfBASE_SCREEN_HEIGHT/3*2)
// TWS_FADE_IN()
ENDIF
// Frames
sPlayerData.iSpriteAnimFrame = 0
ENDPROC
PROC TWS_HANDLE_PLAYER_STATE()
TWS_INCREMENT_ANIM_FRAME_FOR_PLAYER()
IF sPlayerData.bIsInvincible AND GET_GAME_TIMER() - sPlayerData.iStunTime > ciTWS_INVINCIBLE_AFTER_HIT_TIME
sPlayerData.bIsInvincible = FALSE
sPlayerData.iStunTime = 0
ENDIF
SWITCH sPlayerData.ePlayerState
CASE TWS_IDLE
IF sPlayerData.iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sPlayerData.iSpriteAnimFrame = 0
ENDIF
IF sPlayerData.bIsAttacking
IF sPlayerData.bAttackIsLow
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_KICK_SWIPE, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_ATTACK_LOW)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_SHORT_SWIPE, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_ATTACK)
ENDIF
sPlayerData.iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MELEE, sPlayerData.iLevel)
sPlayerData.bIsInvincible = FALSE
ENDIF
IF sPlayerData.bIsCharging
TWS_SET_PLAYER_STATE(TWS_CHARGE)
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsAttacking = TRUE
sPlayerData.bIsInvincible = FALSE
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_DASH_SWIPE, sPlayerData.iLevel)
ENDIF
IF NOT sPlayerData.bIsInvincible AND sPlayerData.bIsHit
sPlayerData.iSpriteAnimFrame = 0
IF NOT sPlayerData.bIsJumping
sPlayerData.vInitialJumpPos = sPlayerData.vSpritePos
ENDIF
IF sPlayerData.bIsFalling OR sPlayerData.fHealth < 0.01
TWS_SET_PLAYER_STATE(TWS_FALL)
ELSE
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_SET_PLAYER_STATE(TWS_STUN)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_HIT_BY_ENEMY, sPlayerData.iLevel)
ENDIF
IF sPlayerData.bIsMoving
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_WALK)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
ENDIF
IF sPlayerData.bIsJumping
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_JUMP, sPlayerData.iLevel)
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_JUMP_START)
ENDIF
IF sPlayerData.bIsEvolving AND sPlayerData.iLevel < 3
IF sPlayerData.bIsUsingMagic
sPlayerData.fMagic = 0.0
sPlayerData.bIsUsingMagic = FALSE
ENDIF
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsInvincible = TRUE
ARCADE_GAMES_AUDIO_SCENE_START(TWR_AUDIO_SCENE_TRANSFORMATION)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_LEVEL_UP_SWORD, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_EVOLVING)
ELIF sPlayerData.bIsUsingMagic
sPlayerData.bIsInvincible = FALSE
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_MAGIC_NUKE_CAST, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_SUPERATTACK)
ENDIF
BREAK
CASE TWS_INTRO
IF sPlayerData.iSpriteAnimFrame >= ciTWS_WALK_ANIM_FRAMES
sPlayerData.iSpriteAnimFrame = 0
ENDIF
IF ARCADE_GAMES_SOUND_HAS_FINISHED(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
ENDIF
IF sTWSData.eLevelStage != TWS_LEVEL_BOSS_FIGHT AND sPlayerData.vSpritePos.x >= cfBASE_SCREEN_WIDTH/2
OR sTWSData.eLevelStage = TWS_LEVEL_BOSS_FIGHT AND sPlayerData.vSpritePos.x >= sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
sPlayerData.bIsMoving = FALSE
sPlayerData.bIsInvincible = FALSE
sPlayerData.iSpriteAnimFrame = 0
IF sTWSData.eCurrentLevel != TWS_FOREST_INTRO
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_LEVEL_BEGIN)
ENDIF
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
BREAK
CASE TWS_WALK
IF sPlayerData.iSpriteAnimFrame >= ciTWS_WALK_ANIM_FRAMES
sPlayerData.iSpriteAnimFrame = 0
ENDIF
IF sPlayerData.bIsAttacking
sPlayerData.iSpriteAnimFrame = 0
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MELEE, sPlayerData.iLevel)
IF sPlayerData.bAttackIsLow
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_KICK_SWIPE, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_ATTACK_LOW)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_SHORT_SWIPE, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_ATTACK)
ENDIF
ENDIF
IF sPlayerData.bIsCharging
TWS_SET_PLAYER_STATE(TWS_CHARGE)
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsAttacking = TRUE
sPlayerData.bIsInvincible = FALSE
sPlayerData.iStunTime = GET_GAME_TIMER()
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_DASH_SWIPE, sPlayerData.iLevel)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MELEE, sPlayerData.iLevel)
ENDIF
IF sPlayerData.bIsHit
sPlayerData.iSpriteAnimFrame = 0
IF NOT sPlayerData.bIsJumping OR sPlayerData.fHealth < 0.01
sPlayerData.vInitialJumpPos = sPlayerData.vSpritePos
ENDIF
IF sPlayerData.bIsFalling OR sPlayerData.fHealth < 0.01
TWS_SET_PLAYER_STATE(TWS_FALL)
ELSE
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_SET_PLAYER_STATE(TWS_STUN)
ENDIF
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_HIT_BY_ENEMY, sPlayerData.iLevel)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_HURT, sPlayerData.iLevel)
ENDIF
IF NOT sPlayerData.bIsMoving
sPlayerData.iSpriteAnimFrame = 0
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
IF sPlayerData.bIsJumping
sPlayerData.iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_JUMP, sPlayerData.iLevel)
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_PLAYER_WALK_LOOP)
TWS_SET_PLAYER_STATE(TWS_JUMP_START)
ENDIF
BREAK
CASE TWS_EVOLVING
IF sPlayerData.iSpriteAnimFrame >= ciTWS_EVOLVING_ANIM_FRAMES
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_SET_PLAYER_STATE(TWS_EVOLVING_2)
ENDIF
BREAK
// Brief pause with the sword up
CASE TWS_EVOLVING_2
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 750
sPlayerData.iSpriteAnimFrame = 0
IF sPlayerData.iLevel < 3
TWS_SET_PLAYER_STATE(TWS_EVOLVING_3)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_LEVEL_UP_SCREEN, sPlayerData.iLevel)
ELSE
sPlayerData.iLevel ++
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_SET_PLAYER_STATE(TWS_EVOLVING_4)
ENDIF
ENDIF
BREAK
// Chest anim
CASE TWS_EVOLVING_3
IF sPlayerData.iSpriteAnimFrame >= ciTWS_EVOLVING_CHEST_ANIM_FRAMES
sPlayerData.iSpriteAnimFrame = ciTWS_EVOLVING_ANIM_FRAMES
sPlayerData.iLevel ++
sPlayerData.iSuperAttackStage = sPlayerData.iLevel
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_LEVEL_UP_IG, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_EVOLVING_4)
ENDIF
BREAK
// After anim
CASE TWS_EVOLVING_4
IF SIN(GET_GAME_TIMER()/0.5) > 0.0
AND sPlayerData.iLevel < sPlayerData.iSuperAttackStage
sPlayerData.iLevel ++
TWS_SET_PLAYER_STATE(TWS_EVOLVING_4)
ELIF SIN(GET_GAME_TIMER()/0.5) < 0.0
AND sPlayerData.iLevel = sPlayerData.iSuperAttackStage
sPlayerData.iLevel --
TWS_SET_PLAYER_STATE(TWS_EVOLVING_4)
ENDIF
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 500
sPlayerData.iLevel = sPlayerData.iSuperAttackStage
TWS_SET_PLAYER_STATE(TWS_EVOLVING_4)
sPlayerData.iSuperAttackStage = 0
IF sPlayerData.iLevel < 3
TWS_CREATE_FX(INIT_VECTOR_2D(sPlayerData.vSpritePos.x, sPlayerData.vSpritePos.Y - 20), TWS_FX_CLOTHES, sPlayerData.vSpritePos.y + sPlayerData.vSpriteSize.y + 20.0)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_LEVEL_UP, sPlayerData.iLevel)
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_SET_PLAYER_STATE(TWS_EVOLVING_5)
ENDIF
BREAK
CASE TWS_EVOLVING_5
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 500
TWS_SET_PLAYER_STATE(TWS_EVOLVING_6)
sPlayerData.iSpriteAnimFrame = 3
ENDIF
BREAK
CASE TWS_EVOLVING_6
sPlayerData.iSpriteAnimFrame -= 2 * sPlayerData.iSlowUpdateFrames
IF sPlayerData.iSpriteAnimFrame <= 0
sPlayerData.bIsEvolving = FALSE
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsHit = FALSE
sPlayerData.bIsInvincible = FALSE
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_TRANSFORMATION)
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
BREAK
CASE TWS_SUPERATTACK
IF sPlayerData.iSpriteAnimFrame >= ciTWS_EVOLVING_ANIM_FRAMES -1
sPlayerData.iSpriteAnimFrame = ciTWS_EVOLVING_ANIM_FRAMES -1
ENDIF
IF sPlayerData.iSpriteAnimFrame >= ciTWS_EVOLVING_ANIM_FRAMES/2 AND GET_GAME_TIMER() - sPlayerData.iStunTime > (250 - (50 * sPlayerData.iLevel))
sPlayerData.iStunTime = GET_GAME_TIMER()
#IF IS_DEBUG_BUILD
IF NOT sTWSData.bInfiniteMagic
#ENDIF
sPlayerData.fMagic = CLAMP(sPlayerData.fMagic - 0.075 - (0.025*sPlayerData.iLevel), 0.0, 1.0)
IF sPlayerData.fMagic <= 0.0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_EMPTY)
ENDIF
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
TWS_PERFORM_SUPERATTACK()
ENDIF
IF NOT TWS_IS_PLAYER_USING_MAGIC() OR sPlayerData.fMagic < 0.05
sPlayerData.bIsUsingMagic = FALSE
sPlayerData.iSuperAttackStage = 0
sFXData[0].bActive = FALSE
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAGIC_SCREEN_NUKE, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
BREAK
CASE TWS_ATTACK
IF NOT sPlayerData.bAttackIsDouble AND sPlayerData.iSpriteAnimFrame >= ciTWS_ATTACK_SIMPLE_ANIM_FRAMES
sPlayerData.bIsAttacking = FALSE
sPlayerData.iSpriteAnimFrame = 0
ELSE
IF (sPlayerData.iLevel < 3 AND sPlayerData.bAttackIsDouble AND sPlayerData.iSpriteAnimFrame >= ciTWS_DOUBLE_ATTACK_START_FRAME)
OR (sPlayerData.iLevel >= 3 AND sPlayerData.bAttackIsDouble AND sPlayerData.iSpriteAnimFrame >= ciTWS_DOUBLE_ATTACK_EXTENDED_FRAME)
TWS_SET_PLAYER_STATE(TWS_ATTACK_DOUBLE)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_LONG_SWIPE, sPlayerData.iLevel)
ENDIF
ENDIF
IF !sPlayerData.bIsAttacking
sPlayerData.bAttackIsDouble = FALSE
sPlayerData.bAttackIsLow = FALSE
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
IF sPlayerData.bIsJumping
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsAttacking = FALSE
sPlayerData.bAttackIsDouble = FALSE
sPlayerData.bAttackIsLow = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_JUMP, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_JUMP_START)
ENDIF
BREAK
CASE TWS_ATTACK_DOUBLE
IF (sPlayerData.iLevel < 3 AND sPlayerData.bAttackIsDouble AND sPlayerData.iSpriteAnimFrame >= ciTWS_ATTACK_ANIM_FRAMES)
OR (sPlayerData.iLevel >= 3 AND sPlayerData.bAttackIsDouble AND sPlayerData.iSpriteAnimFrame >= ciTWS_ATTACK_EXTENDED_ANIM_FRAMES)
sPlayerData.bIsAttacking = FALSE
sPlayerData.iSpriteAnimFrame = 0
ENDIF
IF !sPlayerData.bIsAttacking
sPlayerData.bAttackIsDouble = FALSE
sPlayerData.bAttackIsLow = FALSE
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
IF sPlayerData.bIsJumping
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsAttacking = FALSE
sPlayerData.bAttackIsDouble = FALSE
sPlayerData.bAttackIsLow = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_JUMP, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_JUMP_START)
ENDIF
BREAK
CASE TWS_ATTACK_LOW
IF sPlayerData.iSpriteAnimFrame >= ciTWS_ATTACK_SIMPLE_ANIM_FRAMES
sPlayerData.bIsAttacking = FALSE
sPlayerData.bAttackIsLow = FALSE
sPlayerData.iSpriteAnimFrame = 0
ENDIF
IF !sPlayerData.bIsAttacking
sPlayerData.bAttackIsDouble = FALSE
sPlayerData.bAttackIsLow = FALSE
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
IF sPlayerData.bIsJumping
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_JUMP, sPlayerData.iLevel)
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsAttacking = FALSE
sPlayerData.bAttackIsDouble = FALSE
sPlayerData.bAttackIsLow = FALSE
TWS_SET_PLAYER_STATE(TWS_JUMP_START)
ENDIF
BREAK
CASE TWS_CHARGE
IF sPlayerData.iSpriteAnimFrame >= ciTWS_DASH_ANIM_FRAMES
sPlayerData.iSpriteAnimFrame = ciTWS_DASH_ANIM_FRAMES - 1
ENDIF
IF sPlayerData.iSpriteAnimFrame >= ciTWS_DASH_START_ANIM_FRAME
IF sPlayerData.bFacingLeft
sPlayerData.vSpritePos.x = sPlayerData.vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ELSE
sPlayerData.vSpritePos.x = sPlayerData.vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
ENDIF
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 500
sPlayerData.bIsCharging = FALSE
sPlayerData.bIsAttacking = FALSE
sPlayerData.bAttackIsDouble = FALSE
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.iLastCharge = GET_GAME_TIMER()
#IF IS_DEBUG_BUILD
IF NOT sTWSData.bInfiniteMagic
#ENDIF
sPlayerData.fMagic -= 0.30
IF sPlayerData.fMagic <= 0.0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MANA_EMPTY)
ENDIF
#IF IS_DEBUG_BUILD
ENDIF
#ENDIF
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
BREAK
CASE TWS_FALL_HOLE_1
IF sPlayerData.iSpriteAnimFrame >= ciTWS_FALL_HOLE_ANIM_FRAMES
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_FALL_TO_DEATH, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_FALL_HOLE_2)
ENDIF
BREAK
CASE TWS_FALL_HOLE_2
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 1000
sPlayerData.vSpritePos.y = 2000
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] Player fell in hole.")
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_PLAYER_STATE(TWS_DEAD)
IF sPlayerData.iLifes <= 1
TWS_FADE_OUT()
ENDIF
ENDIF
BREAK
CASE TWS_STUN
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 500
sPlayerData.bIsHit = FALSE
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_IDLE)
sPlayerData.iStunTime = GET_GAME_TIMER()
sPlayerData.bIsInvincible = TRUE
ENDIF
BREAK
CASE TWS_FALL
IF VECTOR_2D_DIST(sPlayerData.vInitialJumpPos, sPlayerData.vSpritePos) < 260.0
IF sPlayerData.bFacingLeft
sPlayerData.vSpritePos.x = sPlayerData.vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*1.25
ELSE
sPlayerData.vSpritePos.x = sPlayerData.vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*1.25
ENDIF
ELSE
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_FALL_2)
ENDIF
BREAK
CASE TWS_FALL_HIGH
IF sPlayerData.vSpritePos.y >= sPlayerData.vInitialJumpPos.y
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsJumping = FALSE
TWS_SET_PLAYER_STATE(TWS_FALL_2)
ENDIF
BREAK
CASE TWS_FALL_2
IF sPlayerData.iSpriteAnimFrame != 0
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_FLAT)
sPlayerData.iStunTime = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_BODYFALL, sPlayerData.iLevel)
IF sPlayerData.iLevel > 1
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
ENDIF
ENDIF
BREAK
CASE TWS_FLAT
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 250 AND TWS_IS_CAMERA_SHAKE_ACTIVE()
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
ENDIF
IF sPlayerData.fHealth <= 0.01
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] Player died.")
// TWS_FADE_OUT()
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_DEATH, sPlayerData.iLevel)
sPlayerData.bIsInvincible = TRUE
sPlayerData.bIsFalling = FALSE
TWS_SET_PLAYER_STATE(TWS_DEAD)
ELSE
IF GET_GAME_TIMER() - sPlayerData.iStunTime > 1000
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsFalling = FALSE
TWS_SET_PLAYER_STATE(TWS_GETTING_UP)
ENDIF
ENDIF
BREAK
CASE TWS_DEAD
IF TWS_IS_SCREEN_FADED_OUT()
TWS_RESET_PLAYER_AFTER_DYING()
ELIF NOT TWS_IS_SCREEN_FADING_OUT() AND GET_GAME_TIMER() - sPlayerData.iStunTime > 1000
TWS_RESET_PLAYER_AFTER_DYING(TRUE)
ENDIF
BREAK
CASE TWS_GETTING_UP
IF (sPlayerData.iLevel < 3 AND sPlayerData.iSpriteAnimFrame >= ciTWS_GETTING_UP_ANIM_FRAMES)
OR (sPlayerData.iLevel >= 3 AND sPlayerData.iSpriteAnimFrame >= ciTWS_GETTING_UP_EXTENDED_ANIM_FRAMES)
sPlayerData.bIsHit = FALSE
sPlayerData.iSpriteAnimFrame = 0
TWS_SET_PLAYER_STATE(TWS_IDLE)
sPlayerData.iStunTime = GET_GAME_TIMER()
sPlayerData.bIsInvincible = TRUE
ELSE
SWITCH sPlayerData.iLevel
CASE 1
SWITCH sPlayerData.iSpriteAnimFrame
CASE 0
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_GETUP_1_WIDTH, cfTWS_PLAYER_HURT_GETUP_1_HEIGHT)
BREAK
CASE 1
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_GETUP_2_WIDTH, cfTWS_PLAYER_HURT_GETUP_2_HEIGHT)
BREAK
CASE 2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_HURT_GETUP_3_WIDTH, cfTWS_PLAYER_HURT_GETUP_3_HEIGHT)
BREAK
ENDSWITCH
BREAK
CASE 2
SWITCH sPlayerData.iSpriteAnimFrame
CASE 0
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_GETUP_1_WIDTH, cfTWS_PLAYER_2_HURT_GETUP_1_HEIGHT)
BREAK
CASE 1
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_GETUP_2_WIDTH, cfTWS_PLAYER_2_HURT_GETUP_2_HEIGHT)
BREAK
CASE 2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_2_HURT_GETUP_3_WIDTH, cfTWS_PLAYER_2_HURT_GETUP_3_HEIGHT)
BREAK
ENDSWITCH
BREAK
CASE 3
SWITCH sPlayerData.iSpriteAnimFrame
CASE 0
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_GETUP_1_WIDTH, cfTWS_PLAYER_3_HURT_GETUP_1_HEIGHT)
BREAK
CASE 1
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_GETUP_2_WIDTH, cfTWS_PLAYER_3_HURT_GETUP_2_HEIGHT)
BREAK
CASE 2
sPlayerData.vSpriteSize = INIT_VECTOR_2D(cfTWS_PLAYER_3_HURT_GETUP_3_WIDTH, cfTWS_PLAYER_3_HURT_GETUP_3_HEIGHT)
BREAK
ENDSWITCH
BREAK
ENDSWITCH
ENDIF
BREAK
CASE TWS_JUMP_ATTACK
IF sPlayerData.iSpriteAnimFrame >= ciTWS_JUMP_KICK_ANIM_FRAMES
sPlayerData.iSpriteAnimFrame = ciTWS_JUMP_KICK_ANIM_FRAMES-1
ENDIF
IF sPlayerData.fJumpAcceleration <= 0
TWS_SET_PLAYER_STATE(TWS_JUMP_ATTACK_DESCEND)
sPlayerData.iSpriteAnimFrame = 2
ENDIF
BREAK
CASE TWS_JUMP_ATTACK_DESCEND
IF sPlayerData.vSpritePos.y >= sPlayerData.vInitialJumpPos.y
sPlayerData.iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_JUMP_LAND, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_JUMP_END)
ENDIF
BREAK
CASE TWS_JUMP_START
IF sPlayerData.iSpriteAnimFrame >= 1
TWS_SET_PLAYER_STATE(TWS_JUMP_ASCEND)
ENDIF
BREAK
CASE TWS_JUMP_ASCEND
IF sPlayerData.fJumpAcceleration <= 5
TWS_SET_PLAYER_STATE(TWS_JUMP_CREST)
ENDIF
IF sPlayerData.bIsAttacking
TWS_SET_PLAYER_STATE(TWS_JUMP_ATTACK)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_JUMP_KICK_SWIPE, sPlayerData.iLevel)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MELEE, sPlayerData.iLevel)
sPlayerData.iSpriteAnimFrame = 0
ENDIF
BREAK
CASE TWS_JUMP_CREST
IF sPlayerData.fJumpAcceleration <= 0
TWS_SET_PLAYER_STATE(TWS_JUMP_DESCEND)
ENDIF
IF sPlayerData.bIsAttacking
TWS_SET_PLAYER_STATE(TWS_JUMP_ATTACK)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_JUMP_KICK_SWIPE, sPlayerData.iLevel)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MELEE, sPlayerData.iLevel)
sPlayerData.iSpriteAnimFrame = 0
ENDIF
BREAK
CASE TWS_JUMP_DESCEND
IF sPlayerData.vSpritePos.y >= sPlayerData.vInitialJumpPos.y
IF sPlayerData.iLevel > 2
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_JUMP_LAND, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_JUMP_END)
ENDIF
IF sPlayerData.bIsAttacking
TWS_SET_PLAYER_STATE(TWS_JUMP_ATTACK)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_ATTACK_JUMP_KICK_SWIPE, sPlayerData.iLevel)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MELEE, sPlayerData.iLevel)
sPlayerData.iSpriteAnimFrame = 0
ENDIF
BREAK
CASE TWS_JUMP_END
IF (sPlayerData.bIsAttacking AND sPlayerData.iSpriteAnimFrame >= ciTWS_JUMP_END_ANIM_FRAMES) OR sPlayerData.iSpriteAnimFrame >= ciTWS_JUMP_ANIM_FRAMES
IF sPlayerData.iLevel > 2
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
ENDIF
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.bIsJumping = FALSE
sPlayerData.bIsAttacking = FALSE
TWS_SET_PLAYER_STATE(TWS_IDLE)
ENDIF
BREAK
CASE TWS_FALL_INFINITE
IF sPlayerData.vSpritePos.y >= cfBASE_SCREEN_HEIGHT*2
sPlayerData.bIsJumping = FALSE
sPlayerData.iSpriteAnimFrame = 0
sPlayerData.vSpritePos.y = 2000.0
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] Player fell in cliff.")
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_ARCADE_GAMES_SOUND_PLAY_FOR_PLAYER_LEVEL(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_FALL_TO_DEATH, sPlayerData.iLevel)
TWS_SET_PLAYER_STATE(TWS_DEAD)
IF sPlayerData.iLifes <= 1
TWS_FADE_OUT()
ENDIF
ENDIF
BREAK
ENDSWITCH
ENDPROC
FUNC BOOL TWS_IS_PLAYER_USING_FINAL_ATTACK()
IF sPlayerData.bIsAttacking AND sPlayerData.bAttackIsDouble AND sPlayerData.iSpriteAnimFrame >= ciTWS_FINAL_ATTACK_ANIM_FRAMES
CPRINTLN(DEBUG_MINIGAME, "Player is using Final Attack")
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
PROC TWS_INCREMENT_ANIM_FRAME_FOR_ENEMY(INT iIndex)
SWITCH sEnemyData[iIndex].eEnemyType
// 10 FPS
CASE TWS_ENEMY_BAT
CASE TWS_ENEMY_GRUNT
CASE TWS_ENEMY_GRUNT_SWORD
CASE TWS_ENEMY_GRUNT_SPEAR
CASE TWS_ENEMY_GRUNT_FIRESPEAR
CASE TWS_ENEMY_GRUNT_FIRESWORD
CASE TWS_ENEMY_GRUNT_CASTER
CASE TWS_ENEMY_GRUNT_CROSSBOW
CASE TWS_ENEMY_BRUTE
CASE TWS_ENEMY_BRUTE_AXE
CASE TWS_ENEMY_SPIDER
CASE TWS_ENEMY_SNAKE
CASE TWS_ENEMY_SLIME
CASE TWS_ENEMY_KNIGHT
CASE TWS_ENEMY_LEPRECHAUN
CASE TWS_ENEMY_BOSS_SPIDER
CASE TWS_ENEMY_BOSS_AMAZON
CASE TWS_ENEMY_BOSS_KNIGHT
CASE TWS_ENEMY_FAKE_WIZARD
CASE TWS_ENEMY_DIALOGUE_WIZARD
CASE TWS_ENEMY_BOSS_WIZARD
CASE TWS_ENEMY_BOULDER
sEnemyData[iIndex].iSpriteAnimFrame += sEnemyData[iIndex].iSlowUpdateFrames
BREAK
CASE TWS_ENEMY_FAIRY
sEnemyData[iIndex].iSpriteAnimFrame += sEnemyData[iIndex].iDefaultUpdateFrames
BREAK
ENDSWITCH
ENDPROC
PROC TWS_HANDLE_ENEMY_STATE()
INT i
FOR i = 0 TO ciTWS_MAX_ENEMIES - 1
IF sEnemyData[i].bIsActive
TWS_INCREMENT_ANIM_FRAME_FOR_ENEMY(i)
SWITCH sEnemyData[i].eEnemyType
CASE TWS_ENEMY_BOSS_WIZARD
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INACTIVE
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT
// Choose position
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos, cfBASE_SCREEN_HEIGHT/3)
sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_VOCAL_DIALOGUE, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORTING)
ENDIF
BREAK
CASE TWS_ENEMY_TELEPORT_OUT
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_TELEPORT_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].vSpritePos = INIT_VECTOR_2D(-5000.0,-5000.0)
CPRINTLN(DEBUG_MINIGAME, "Real Wizard warping!")
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORTING)
ENDIF
BREAK
CASE TWS_ENEMY_TELEPORTING
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vSpritePos = sEnemyData[i].vTargetPos
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_TELEPORT_IN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_IN)
ENDIF
BREAK
CASE TWS_ENEMY_TELEPORT_IN
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_TELEPORT_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].bIsHit = FALSE
CPRINTLN(DEBUG_MINIGAME, "Real Wizard warping in!")
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_VOCAL_DIALOGUE, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK
OR sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK_2
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_CAST_SPELL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
TWS_SET_ENEMY_STATE(i, sEnemyData[i].eNextState)
ENDIF
BREAK
CASE TWS_ENEMY_SPECIAL_ATTACK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ATTACK_EXTENDED_ANIM_FRAMES
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_CAST_SPELL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
IF sPlayerData.bIsJumping
TWS_CREATE_FX(INIT_VECTOR_2D(sPlayerData.vSpritePos.x,sPlayerData.vInitialJumpPos.y + sPlayerData.vSpriteSize.y - cfTWS_FX_WIZARD_PILLAR_HEIGHT), TWS_FX_MAGIC_COLUMN)
ELSE
TWS_CREATE_FX(INIT_VECTOR_2D(sPlayerData.vSpritePos.x,sPlayerData.vSpritePos.y + sPlayerData.vSpriteSize.y - cfTWS_FX_WIZARD_PILLAR_HEIGHT), TWS_FX_MAGIC_COLUMN)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_FLAME_PILLAR)
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget += 0.25
ENDIF
IF sEnemyData[i].fProgressToTarget >= 1.0
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH/2 + sEnemyData[i].vSpriteSize.x, sPlayerData.vSpritePos.y)
sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK_2
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_TELEPORT_OUT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_OUT)
ENDIF
BREAK
CASE TWS_ENEMY_SPECIAL_ATTACK_2
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ATTACK_EXTENDED_ANIM_FRAMES
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_CAST_SPELL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 100
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_FIRE_FLAMES)
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x + (sEnemyData[i].fProgressToTarget * 1000), sEnemyData[i].vSpritePos.Y + sEnemyData[i].vSpriteSize.y - cfTWS_FX_WIZARD_FIRE_HEIGHT), TWS_FX_MAGIC_FIRE)
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget += 0.1
ENDIF
IF sEnemyData[i].fProgressToTarget >= 1.0
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iSpriteAnimFrame = 0
// Spawn fakes
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(-cfGAME_SCREEN_WIDTH/3, cfGAME_SCREEN_WIDTH/3), cfBASE_SCREEN_HEIGHT/2 + GET_RANDOM_FLOAT_IN_RANGE(-cfGAME_SCREEN_HEIGHT/3, cfGAME_SCREEN_HEIGHT/3))
sEnemyData[i].eNextState = TWS_ENEMY_IDLE
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(-5000, 0), TWS_ENEMY_FAKE_WIZARD)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(-6000, 0), TWS_ENEMY_FAKE_WIZARD)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(-7000, 0), TWS_ENEMY_FAKE_WIZARD)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_TELEPORT_OUT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_OUT)
ENDIF
BREAK
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 5000
CPRINTLN(DEBUG_MINIGAME, "Real Wizard starting to invoque magic pillars!")
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos, cfBASE_SCREEN_HEIGHT/3)
sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_TELEPORT_OUT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_OUT)
ELIF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_VOCAL_HURT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
BREAK
CASE TWS_ENEMY_STUN
sEnemyData[i].vSpritePos.x += SIN(GET_GAME_TIMER()/0.4)
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].fProgressToTarget = 0.0
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_EXPLODING)
ELIF GET_GAME_TIMER() - sEnemyData[i].iTimer > 300
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos, cfBASE_SCREEN_HEIGHT/3)
sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_TELEPORT_OUT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_OUT)
ENDIF
BREAK
CASE TWS_ENEMY_EXPLODING
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x + SIN(GET_GAME_TIMER()/0.4)
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_DYING_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sEnemyData[i].fProgressToTarget >= 1.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_DEATH_FINAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ELIF GET_GAME_TIMER() - sEnemyData[i].iTimer > 200
sEnemyData[i].fProgressToTarget += 0.05
TWS_CREATE_FX(
INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x + GET_RANDOM_FLOAT_IN_RANGE(-sEnemyData[i].vSpriteSize.x, sEnemyData[i].vSpriteSize.x),
sEnemyData[i].vSpritePos.y + GET_RANDOM_FLOAT_IN_RANGE(-sEnemyData[i].vSpriteSize.y, sEnemyData[i].vSpriteSize.y)),
TWS_FX_SUPERATTACK_EXPLOSION)
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_DEATH_BLASTS)
sEnemyData[i].iTimer = GET_GAME_TIMER()
ENDIF
BREAK
CASE TWS_ENEMY_DYING
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_DEATH_FLASH_ANIM_FRAMES
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_2)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_2
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_DEATH_ANIM_FRAMES
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_VOCAL_KILLED, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = ciTWS_WIZARD_DEATH_FLASH_ANIM_FRAMES
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_3)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_3
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_DEATH_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DEAD)
ENDIF
BREAK
CASE TWS_ENEMY_DEAD
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_DIALOGUE_WIZARD
CASE TWS_ENEMY_FAKE_WIZARD
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INACTIVE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sEnemyData[i].eEnemyType = TWS_ENEMY_FAKE_WIZARD AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1500
OR sEnemyData[i].eEnemyType = TWS_ENEMY_DIALOGUE_WIZARD AND sTWSData.eGrogEncounterState >= TWS_GROG_LEAVES
// Choose position
IF sEnemyData[i].eEnemyType = TWS_ENEMY_FAKE_WIZARD
sEnemyData[i].vSpritePos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(-cfGAME_SCREEN_WIDTH/3, cfGAME_SCREEN_WIDTH/3), cfBASE_SCREEN_HEIGHT/2 + GET_RANDOM_FLOAT_IN_RANGE(-cfGAME_SCREEN_HEIGHT/3, cfGAME_SCREEN_HEIGHT/3))
ELSE
sEnemyData[i].vSpritePos = INIT_VECTOR_2D(sTWSData.fLockedScreenPos + 500, cfBASE_SCREEN_HEIGHT/2)
ENDIF
sEnemyData[i].eNextState = TWS_ENEMY_IDLE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_TELEPORT_IN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_IN)
ENDIF
BREAK
CASE TWS_ENEMY_TELEPORT_OUT
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_TELEPORT_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_INACTIVE)
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
CASE TWS_ENEMY_TELEPORT_IN
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_WIZARD_TELEPORT_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget = 0.0
TWS_SET_ENEMY_STATE(i, sEnemyData[i].eNextState)
ENDIF
BREAK
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sEnemyData[i].eEnemyType = TWS_ENEMY_FAKE_WIZARD AND (GET_GAME_TIMER() - sEnemyData[i].iTimer > 4000 OR sEnemyData[i].bIsHit OR sEnemyData[sTWSData.iBossEnemyIndex].fHealth <= 0.0)
OR sEnemyData[i].eEnemyType = TWS_ENEMY_DIALOGUE_WIZARD AND (sTWSData.eGrogEncounterState >= TWS_FIGHT_START)
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos, cfBASE_SCREEN_HEIGHT/3)
sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_WIZARD_TELEPORT_OUT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sEnemyData[i].eEnemyType = TWS_ENEMY_FAKE_WIZARD AND sEnemyData[i].bIsHit
IF sPlayerData.bFacingLeft
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x - cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), TWS_ENEMY_FAKE_WIZARD)
ELSE
TWS_SPAWN_FALLING_ITEMS(INIT_VECTOR_2D(sPlayerData.vSpritePos.x + cfGAME_SCREEN_WIDTH/4 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20, cfBASE_SCREEN_HEIGHT/4*3 + GET_RANDOM_FLOAT_IN_RANGE(-5.0, 5.0)*20), TWS_ENEMY_FAKE_WIZARD)
ENDIF
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_OUT)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_BOSS_KNIGHT
CASE TWS_ENEMY_KNIGHT
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INACTIVE
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT
OR ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < cfGAME_SCREEN_WIDTH*0.35
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_AGGRO, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GO_UP)
ENDIF
BREAK
CASE TWS_ENEMY_GO_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_KNIGHT_STAND_ANIM_FRAMES
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_DRAW_SWORD, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT AND sEnemyData[i].vSpritePos.X < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/3*2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT AND sEnemyData[i].vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/3*2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sEnemyData[i].vSpritePos.Y > cfGAME_SCREEN_HEIGHT/3*2
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, cfGAME_SCREEN_HEIGHT/3*2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELSE
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, cfGAME_SCREEN_HEIGHT/2)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_VOCAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLAM, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ENDIF
ELSE
IF sTWSData.bLockedScreen AND sEnemyData[i].vSpritePos.X < sTWSData.fLockedScreenPos - cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/3*2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sTWSData.bLockedScreen AND sEnemyData[i].vSpritePos.X > sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sTWSData.fLockedScreenPos - cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/3*2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sEnemyData[i].vSpritePos.Y > cfGAME_SCREEN_HEIGHT/3*2
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, cfGAME_SCREEN_HEIGHT/3*2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELSE
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, cfGAME_SCREEN_HEIGHT/2)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_VOCAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLAM, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ENDIF
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 50.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_VOCAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLAM, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ELSE
TWS_MOVE_ENEMY(i, 30.0)
ENDIF
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].iSpriteAnimFrame = 0
IF sEnemyData[i].fHealth <= 0.01
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
sEnemyData[i].fHealth = 0.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_DEATH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_1)
ELSE
CPRINTLN(DEBUG_MINIGAME, "HIT! ",sEnemyData[i].fHealth)
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_SPECIAL_ATTACK
IF sEnemyData[i].iSpriteAnimFrame >= 10
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget = 0.2
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.X, sPlayerData.vSpritePos.y + sPlayerData.vSpriteSize.y - cfTWS_FX_KNIGHT_SWORD_HEIGHT)
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK_2)
ENDIF
BREAK
CASE TWS_ENEMY_SPECIAL_ATTACK_2
IF sEnemyData[i].fProgressToTarget >= 1.2
sEnemyData[i].iSpriteAnimFrame = 10
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_STAND_UP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK_3)
ELIF GET_GAME_TIMER() - sEnemyData[i].iTimer > 100
TWS_CREATE_FX(LERP_VECTOR_2D(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.X, sEnemyData[i].vSpritePos.y + sEnemyData[i].vSpriteSize.y - cfTWS_FX_KNIGHT_SWORD_HEIGHT), sEnemyData[i].vTargetPos, sEnemyData[i].fProgressToTarget),
TWS_FX_SWORD)
sEnemyData[i].fProgressToTarget += 0.2
sEnemyData[i].iTimer = GET_GAME_TIMER()
ENDIF
BREAK
CASE TWS_ENEMY_SPECIAL_ATTACK_3
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_BOSS_KNIGHT_SLAM_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
IF sEnemyData[i].iNumberOfAttacksInARow > 1
sEnemyData[i].iNumberOfAttacksInARow = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ELSE
sEnemyData[i].iNumberOfAttacksInARow++
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].iSpriteAnimFrame = 0
IF sEnemyData[i].fHealth <= 0.01
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
sEnemyData[i].fHealth = 0.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_DEATH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_1)
ELSE
CPRINTLN(DEBUG_MINIGAME, "HIT! ",sEnemyData[i].fHealth)
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 250.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLASH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_VOCAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLAM, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ENDIF
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF (sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1500)
OR (sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 2000)
OR sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iNumberOfAttacksInARow = 0
sEnemyData[i].eNextState = TWS_ENEMY_IDLE
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT
IF sEnemyData[i].vSpritePos.X < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sEnemyData[i].vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sEnemyData[i].vSpritePos.Y > cfGAME_SCREEN_HEIGHT/3
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, cfGAME_SCREEN_HEIGHT/2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELSE
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 450.0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLASH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ELSE
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_VOCAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLAM, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ENDIF
ENDIF
ELSE
IF sTWSData.bLockedScreen AND sEnemyData[i].vSpritePos.X < sTWSData.fLockedScreenPos - cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sTWSData.bLockedScreen AND sEnemyData[i].vSpritePos.X > sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.1
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sTWSData.fLockedScreenPos - cfGAME_SCREEN_WIDTH*0.1, cfGAME_SCREEN_HEIGHT/2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sEnemyData[i].vSpritePos.Y > cfGAME_SCREEN_HEIGHT/3
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, cfGAME_SCREEN_HEIGHT/2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELSE
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 450.0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLASH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ELSE
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_VOCAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLAM, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ENDIF
ENDIF
ENDIF
ELIF sEnemyData[i].bIsHit OR sEnemyData[i].fHealth <= 0.0
sEnemyData[i].iSpriteAnimFrame = 0
IF sEnemyData[i].fHealth <= 0.01
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
sEnemyData[i].fHealth = 0.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_DEATH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_1)
ELSE
CPRINTLN(DEBUG_MINIGAME, "HIT! ",sEnemyData[i].fHealth)
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_ATTACK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
IF sEnemyData[i].iNumberOfAttacksInARow > 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_VOCAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_ATTACK_SLAM, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ELSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GO_UP)
ENDIF
ENDIF
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].iSpriteAnimFrame = 0
IF sEnemyData[i].fHealth <= 0.01
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
sEnemyData[i].fHealth = 0.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_DEATH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_1)
ELSE
CPRINTLN(DEBUG_MINIGAME, "HIT! ",sEnemyData[i].fHealth)
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_STUN
sEnemyData[i].vSpritePos.x += SIN(GET_GAME_TIMER()/0.4)
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 200
sEnemyData[i].iSpriteAnimFrame = 0
IF sEnemyData[i].iNumberOfAttacksInARow > 3
sEnemyData[i].iNumberOfAttacksInARow = 0
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_KNOCKBACK, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT
IF sEnemyData[i].fHealth > 0.55
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(-500.0, -300.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(-300.0, 0.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(0.0, 300.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(300.0, 500.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
ELIF sEnemyData[i].fHealth > 0.35
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH/2.0, GET_RANDOM_FLOAT_IN_RANGE(550.0, 750.0)), TWS_ENEMY_GRUNT_SPEAR, TRUE)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH/2.0, GET_RANDOM_FLOAT_IN_RANGE(550.0, 750.0)), TWS_ENEMY_GRUNT_SPEAR, TRUE)
ELSE
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(-500.0, -300.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(-300.0, 0.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(0.0, 300.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + GET_RANDOM_FLOAT_IN_RANGE(300.0, 500.0), GET_RANDOM_FLOAT_IN_RANGE(-50.0, -250.0)), TWS_ENEMY_FAIRY)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH/2.0, GET_RANDOM_FLOAT_IN_RANGE(550.0, 750.0)), TWS_ENEMY_GRUNT_SWORD, TRUE)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH/2.0, GET_RANDOM_FLOAT_IN_RANGE(550.0, 750.0)), TWS_ENEMY_GRUNT_SWORD, TRUE)
ENDIF
ENDIF
sEnemyData[i].eNextState = TWS_ENEMY_SPECIAL_ATTACK
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL_OVER_1)
ELSE
sEnemyData[i].iNumberOfAttacksInARow ++
sEnemyData[i].bIsHit = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_FALL_OVER_1
IF sEnemyData[i].iSpriteAnimFrame > 2
sEnemyData[i].iSpriteAnimFrame = 2
ENDIF
IF sTWSData.bLockedScreen
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vInitialPos.x) < (200.0 * sPlayerData.iLevel)
AND sEnemyData[i].vSpritePos.X > sTWSData.fLockedScreenPos - cfGAME_SCREEN_WIDTH*0.45
AND sEnemyData[i].vSpritePos.X < sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.45
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ENDIF
ELSE
sEnemyData[i].bIsFalling = FALSE
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GETTING_UP)
ENDIF
ELSE
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vInitialPos.x) < (200.0 * sPlayerData.iLevel)
AND sEnemyData[i].vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.45
AND sEnemyData[i].vSpritePos.X < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.45
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ENDIF
ELSE
sEnemyData[i].bIsFalling = FALSE
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GETTING_UP)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_GETTING_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_BOSS_KNIGHT_HURT_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsHit = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_1
IF sEnemyData[i].iSpriteAnimFrame >= 2
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x - sEnemyData[i].vSpriteSize.x, sEnemyData[i].vSpritePos.y + 50), TWS_FX_SWORD_DROP)
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x + sEnemyData[i].vSpriteSize.x, sEnemyData[i].vSpritePos.y + 50), TWS_FX_COD_DROP)
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_2)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_2
IF sEnemyData[i].iSpriteAnimFrame >= 3
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_3)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_3
IF sEnemyData[i].iSpriteAnimFrame >= 5
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_4)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_4
IF sEnemyData[i].iSpriteAnimFrame >= 6
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_5)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_5
IF sEnemyData[i].iSpriteAnimFrame >= 8
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_6)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_6
IF sEnemyData[i].iSpriteAnimFrame >= 9
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_DARKKNIGHT_BODYFALL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_7)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_7
IF sEnemyData[i].iSpriteAnimFrame >= 10
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING_8)
ENDIF
BREAK
CASE TWS_ENEMY_DYING_8
IF sEnemyData[i].iSpriteAnimFrame >= 11
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DEAD)
ENDIF
BREAK
CASE TWS_ENEMY_DEAD
IF sTWSData.eLevelStage < TWS_LEVEL_BOSS_FIGHT AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 2000
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_BOSS_AMAZON
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INACTIVE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget = 0.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_AGGRO, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sEnemyData[i].bIsHit
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sEnemyData[i].fHealth > 0.0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ELSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ENDIF
ELIF (sEnemyData[i].fProgressToTarget = 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000)
OR (sEnemyData[i].fProgressToTarget > 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 500)
OR sEnemyData[i].eNextState = TWS_ENEMY_ATTACK
IF sEnemyData[i].eNextState = TWS_ENEMY_ATTACK
sEnemyData[i].eNextState = TWS_ENEMY_IDLE
ENDIF
sEnemyData[i].iSpriteAnimFrame = 0
IF sEnemyData[i].vSpritePos.X < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.4
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.4, sPlayerData.vSpritePos.y)
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos.y = sPlayerData.vInitialJumpPos.y
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sEnemyData[i].vSpritePos.X > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.4
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.4, sPlayerData.vSpritePos.y)
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos.y = sPlayerData.vInitialJumpPos.y
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF sEnemyData[i].vSpritePos.Y > cfGAME_SCREEN_HEIGHT*0.75
OR ABSF(sEnemyData[i].vSpritePos.Y - sPlayerData.vSpritePos.y) > 100.0
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sPlayerData.vSpritePos.y)
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos.y = sPlayerData.vInitialJumpPos.y
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK_LOAD)
sEnemyData[i].fProgressToTarget += 0.35
ENDIF
ELIF sEnemyData[i].fProgressToTarget > 0.0
AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) <= 300.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_ATTACK_STAB, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK_2)
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 50.0
IF sPlayerData.ePlayerState != TWS_INTRO
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK_LOAD)
sEnemyData[i].fProgressToTarget += 0.35
ENDIF
ELSE
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.y < sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.Y > sEnemyData[i].vSpritePos.Y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.X < sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*0.75
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.X > sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*0.75
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK_LOAD
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_DASH_START_ANIM_FRAME - 1
sEnemyData[i].iSpriteAnimFrame = ciTWS_DASH_START_ANIM_FRAME - 1
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 500 AND sPlayerData.ePlayerState != TWS_INTRO
sEnemyData[i].bIsAttacking = TRUE
IF sPlayerData.vSpritePos.x < sEnemyData[i].vSpritePos.x
sEnemyData[i].bIsMoving = TRUE
ELSE
sEnemyData[i].bIsMoving = FALSE
ENDIF
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_ATTACK_THRUST, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK_HIT)
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK_HIT
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_DASH_START_ANIM_FRAME
IF sEnemyData[i].bIsMoving = TRUE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*4
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*4
ENDIF
sEnemyData[i].iSpriteAnimFrame = ciTWS_DASH_START_ANIM_FRAME
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 800
OR (NOT sEnemyData[i].bIsMoving AND sEnemyData[i].vSpritePos.x >= sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.3)
OR (sEnemyData[i].bIsMoving AND sEnemyData[i].vSpritePos.x <= sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.3)
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
IF sEnemyData[i].fProgressToTarget >= 1.0
sEnemyData[i].fProgressToTarget = ciTWS_JUMP_ACCELERATION*1.5
sEnemyData[i].vShadowOffset.y = sEnemyData[i].vSpritePos.y + TWS_GET_ENEMY_SHADOW_Y_POSITION(TWS_ENEMY_BOSS_AMAZON)
sEnemyData[i].vInitialPos.y = sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GO_UP)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_ATTACK_JUMP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ELSE
sEnemyData[i].fProgressToTarget += 0.35
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_GO_UP
IF sPlayerData.vSpritePos.y > sEnemyData[i].vInitialPos.y + 15.0
sEnemyData[i].vShadowOffset.y = sEnemyData[i].vShadowOffset.y +@ cfTWS_VERTICAL_MOVEMENT_PLAYER
sEnemyData[i].vInitialPos.y = sEnemyData[i].vInitialPos.y +@ cfTWS_VERTICAL_MOVEMENT_PLAYER
ELIF sPlayerData.vSpritePos.y < sEnemyData[i].vInitialPos.y - 15.0
sEnemyData[i].vShadowOffset.y = sEnemyData[i].vShadowOffset.y -@ cfTWS_VERTICAL_MOVEMENT_PLAYER
sEnemyData[i].vInitialPos.y = sEnemyData[i].vInitialPos.y -@ cfTWS_VERTICAL_MOVEMENT_PLAYER
ENDIF
IF sEnemyData[i].fProgressToTarget > 0.0
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
ELSE
sEnemyData[i].fProgressToTarget = 0.0
IF sPlayerData.vSpritePos.x < sEnemyData[i].vSpritePos.x
sEnemyData[i].bIsMoving = TRUE
ELSE
sEnemyData[i].bIsMoving = FALSE
ENDIF
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPECIAL_ATTACK)
ENDIF
BREAK
CASE TWS_ENEMY_SPECIAL_ATTACK
IF sEnemyData[i].vSpritePos.y < sEnemyData[i].vInitialPos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
IF sEnemyData[i].bIsMoving = TRUE
IF sEnemyData[i].vSpritePos.x > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.4
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
ELSE
IF sEnemyData[i].vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.4
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
ENDIF
ELSE
sEnemyData[i].vShadowOffset.y = 0.0
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsAttacking = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_JUMP_LAND, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_LANDING)
ENDIF
BREAK
CASE TWS_ENEMY_SPECIAL_ATTACK_2
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_ATTACK_ANIM_FRAMES-1
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].fProgressToTarget = ciTWS_JUMP_ACCELERATION*2.0
sEnemyData[i].vShadowOffset.y = sEnemyData[i].vSpritePos.y + TWS_GET_ENEMY_SHADOW_Y_POSITION(TWS_ENEMY_BOSS_AMAZON)
sEnemyData[i].vInitialPos.y = sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
IF sEnemyData[i].vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.4, sEnemyData[i].vSpritePos.y)
sEnemyData[i].bIsMoving = FALSE
ELSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.4, sEnemyData[i].vSpritePos.y)
sEnemyData[i].bIsMoving = TRUE
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_IN)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_ATTACK_JUMP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
BREAK
CASE TWS_ENEMY_TELEPORT_IN
IF sEnemyData[i].fProgressToTarget > 0.0
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vTargetPos.x) > 20.0
IF sEnemyData[i].bIsMoving = TRUE
IF sEnemyData[i].vSpritePos.x > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.4
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
ELSE
IF sEnemyData[i].vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.4
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
ENDIF
ENDIF
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_OUT)
ENDIF
BREAK
CASE TWS_ENEMY_TELEPORT_OUT
IF sEnemyData[i].vSpritePos.y < sEnemyData[i].vInitialPos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vTargetPos.x) > 20.0
IF sEnemyData[i].bIsMoving = TRUE
IF sEnemyData[i].vSpritePos.x > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfBASE_SCREEN_WIDTH*0.4
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
ELSE
IF sEnemyData[i].vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.4
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
ENDIF
ENDIF
ELSE
sEnemyData[i].vShadowOffset.y = 0.0
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_JUMP_LAND, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_LANDING)
ENDIF
BREAK
CASE TWS_ENEMY_LANDING
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 500
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsHit = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_STUN
sEnemyData[i].vSpritePos.x += SIN(GET_GAME_TIMER()/0.4)
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_ENEMIES_STUN_TIME
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].fProgressToTarget = ciTWS_JUMP_ACCELERATION*2.0
sEnemyData[i].vShadowOffset.y = sEnemyData[i].vSpritePos.y
sEnemyData[i].vInitialPos.y = sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
IF sEnemyData[i].vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.4, sEnemyData[i].vSpritePos.y)
sEnemyData[i].bIsMoving = FALSE
ELSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.4, sEnemyData[i].vSpritePos.y)
sEnemyData[i].bIsMoving = TRUE
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_IN)
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_ATTACK_JUMP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].eNextState = TWS_ENEMY_ATTACK
sEnemyData[i].bIsHit = FALSE
IF sEnemyData[i].fHealth > 0.5
FLOAT fPostionY
fPostionY = sPlayerData.vSpritePos.y
IF sPlayerData.bIsJumping
fPostionY = sPlayerData.vInitialJumpPos.y
ENDIF
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.5, fPostionY + 30), TWS_ENEMY_SNAKE, TRUE)
IF GET_RANDOM_BOOL()
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.6, CLAMP(fPostionY, 730, 900) + 50), TWS_ENEMY_SNAKE, TRUE)
ELSE
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.6, CLAMP(fPostionY, 730, 900) - 50), TWS_ENEMY_SNAKE, TRUE)
ENDIF
ELIF sEnemyData[i].fHealth > 0.3
IF sPlayerData.vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.25, -50), TWS_ENEMY_SLIME)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.35, -50), TWS_ENEMY_SLIME)
ELSE
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.35, -50), TWS_ENEMY_SLIME)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.25, -50), TWS_ENEMY_SLIME)
ENDIF
ELSE
FLOAT fPostionY
fPostionY = sPlayerData.vSpritePos.y
IF sPlayerData.bIsJumping
fPostionY = sPlayerData.vInitialJumpPos.y
ENDIF
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.5, fPostionY + 30), TWS_ENEMY_SNAKE, TRUE)
IF GET_RANDOM_BOOL()
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.6, CLAMP(fPostionY, 730, 900) + 80), TWS_ENEMY_SNAKE, TRUE)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.6, CLAMP(fPostionY, 730, 900) + 80), TWS_ENEMY_SNAKE, TRUE)
ELSE
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.6, CLAMP(fPostionY, 730, 900) - 80), TWS_ENEMY_SNAKE, TRUE)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfBASE_SCREEN_WIDTH*0.6, CLAMP(fPostionY, 730, 900) - 80), TWS_ENEMY_SNAKE, TRUE)
ENDIF
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_FALL
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < (350.0 * sPlayerData.iLevel)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
ELSE
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsFalling = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FLAT)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_BODYFALL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
BREAK
CASE TWS_ENEMY_FLAT
IF sEnemyData[i].fHealth > 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GETTING_UP)
ELIF sEnemyData[i].fHealth <= 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_AMAZON_DEATH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DEAD)
ENDIF
BREAK
CASE TWS_ENEMY_GETTING_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_GETTINGUP_ANIM_FRAMES
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].fProgressToTarget = ciTWS_JUMP_ACCELERATION*2.0
sEnemyData[i].vShadowOffset.y = sEnemyData[i].vSpritePos.y
sEnemyData[i].vInitialPos.y = sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ sEnemyData[i].fProgressToTarget
sEnemyData[i].fProgressToTarget = sEnemyData[i].fProgressToTarget +@ ciTWS_GRAVITY
IF sEnemyData[i].vSpritePos.x < sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.75, sEnemyData[i].vSpritePos.y)
sEnemyData[i].bIsMoving = FALSE
ELSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.75, sEnemyData[i].vSpritePos.y)
sEnemyData[i].bIsMoving = TRUE
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_TELEPORT_IN)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_BOSS_SPIDER
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INACTIVE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sTWSData.eLevelStage >= TWS_LEVEL_BOSS_FIGHT
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_AGGRO, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_LOOP)
sEnemyData[i].vShadowOffset.y = 660.0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GLIDE_DOWN)
ENDIF
BREAK
// Boss comes in
CASE TWS_ENEMY_GLIDE_DOWN
IF sEnemyData[i].vSpritePos.y <= 500.0
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELSE
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_LOOP)
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPIT_1)
ENDIF
BREAK
// Boss spits creating puddles of venom
CASE TWS_ENEMY_SPIT_1
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_BOSS_SPIDER_SPIT_ANIM_FRAMES/2
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x - 50.0, sEnemyData[i].vSpritePos.Y + 80.0), TWS_FX_BOSS_SPIDER_SPIT, sEnemyData[i].vSpritePos.Y + sEnemyData[i].vSpriteSize.Y + 50.0)
INT j
FOR j = 0 TO 2
TWS_CREATE_FX(INIT_VECTOR_2D(sPlayerData.vSpritePos.x + GET_RANDOM_FLOAT_IN_RANGE( -500.0, 500.0), CLAMP(sPlayerData.vSpritePos.Y + GET_RANDOM_FLOAT_IN_RANGE(-50.0, 300.0), 700, cfBASE_SCREEN_HEIGHT)), TWS_FX_VENOM_PUDDLE, 0)
ENDFOR
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_ATTACK_SPIT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPIT_2)
ENDIF
BREAK
CASE TWS_ENEMY_SPIT_2
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_BOSS_SPIDER_SPIT_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 2
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_BOSS_ATTACK_TIME
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos - cfGAME_SCREEN_WIDTH*0.4, -50), TWS_ENEMY_SPIDER)
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos + cfGAME_SCREEN_WIDTH*0.4, -50), TWS_ENEMY_SPIDER)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_SPIT_3)
ENDIF
BREAK
CASE TWS_ENEMY_SPIT_3
sEnemyData[i].iSpriteAnimFrame -= 2* sEnemyData[i].iSlowUpdateFrames
IF sEnemyData[i].iSpriteAnimFrame <= 0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
// Boss can be attacked for some seconds or certain damage
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sEnemyData[i].bIsHit
sEnemyData[i].fProgressToTarget += 0.34
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsHit = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ELIF sEnemyData[i].fProgressToTarget >= 1.0 OR GET_GAME_TIMER() - sEnemyData[i].iTimer > 3500
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].fHealth = 0.025
ENDIF
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK_LOAD)
ENDIF
BREAK
// Boss attacks
CASE TWS_ENEMY_ATTACK_LOAD
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_BOSS_SPIDER_ATTACK_LOAD_ANIM_FRAMES -1
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK_WAIT)
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK_WAIT
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = ciTWS_BOSS_SPIDER_ATTACK_LOAD_ANIM_FRAMES
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_ATTACK_HIT, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK_HIT)
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK_HIT
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_BOSS_SPIDER_ATTACK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_UP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_LOOP)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GO_UP)
ENDIF
BREAK
// Boss disappears
CASE TWS_ENEMY_GO_UP
IF sEnemyData[i].vSpritePos.y > -300.0
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x, sPlayerData.vSpritePos.Y - 900.0 )
sEnemyData[i].fProgressToTarget = 0.0
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_LOOP)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL_OVER_1)
ENDIF
BREAK
// Boss disappears
CASE TWS_ENEMY_FALL_OVER_1
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) > 5.0
sEnemyData[i].vSpritePos = LERP_VECTOR_2D(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos, sEnemyData[i].fProgressToTarget) //INIT_VECTOR_2D(LERP_FLOAT(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.x, sEnemyData[i].fProgressToTarget),sPlayerData.vSpritePos.y - sEnemyData[i].fShadowDistance)
IF sPlayerData.bIsJumping
sEnemyData[i].vShadowOffset.y = LERP_FLOAT(sEnemyData[i].vShadowOffset.y, sPlayerData.vInitialJumpPos.Y + sPlayerData.vSpriteSize.y, sEnemyData[i].fProgressToTarget)
ELSE
sEnemyData[i].vShadowOffset.y = LERP_FLOAT(sEnemyData[i].vShadowOffset.y, sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.y, sEnemyData[i].fProgressToTarget)
ENDIF
sEnemyData[i].fProgressToTarget += 0.0015
ELSE
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_ATTACK_DROP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL_OVER_2)
ENDIF
BREAK
CASE TWS_ENEMY_FALL_OVER_2
IF sEnemyData[i].vSpritePos.y < sPlayerData.vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY*4
ELSE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsAttacking = FALSE
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_ATTACK_DROP_LAND, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_LANDING)
ENDIF
BREAK
// Boss lands on player
CASE TWS_ENEMY_LANDING
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].fHealth = 0.025
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 1500
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos, -300)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_UP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_LOOP)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
BREAK
// Boss walks to default position
CASE TWS_ENEMY_WALK
IF sEnemyData[i].vSpritePos.y < 300.0
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) > 5.0
sEnemyData[i].vSpritePos = LERP_VECTOR_2D(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos, sEnemyData[i].fProgressToTarget) //INIT_VECTOR_2D(LERP_FLOAT(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.x, sEnemyData[i].fProgressToTarget),sEnemyData[i].vSpritePos.y)
sEnemyData[i].vShadowOffset.y = LERP_FLOAT(sEnemyData[i].vShadowOffset.y, 660.0 , sEnemyData[i].fProgressToTarget)
sEnemyData[i].fProgressToTarget += 0.0025
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_CLIMB_DOWN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GLIDE_DOWN)
ENDIF
ELSE
sEnemyData[i].vSpritePos.y -= 10.0
ENDIF
BREAK
CASE TWS_ENEMY_STUN
sEnemyData[i].vSpritePos.x += SIN(GET_GAME_TIMER()/0.4)
IF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_DEATH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_EXPLODING)
ELIF GET_GAME_TIMER() - sEnemyData[i].iTimer > 500
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vSpritePos = sEnemyData[i].vTargetPos
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_EXPLODING
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ SIN(GET_GAME_TIMER()/0.4)
IF sEnemyData[i].fProgressToTarget >= 1.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_BOSS_SPIDER_DEATH_FINAL, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ELIF GET_GAME_TIMER() - sEnemyData[i].iTimer > 200
sEnemyData[i].fProgressToTarget += 0.05
TWS_CREATE_FX(
INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x + GET_RANDOM_FLOAT_IN_RANGE(-sEnemyData[i].vSpriteSize.x, sEnemyData[i].vSpriteSize.x),
sEnemyData[i].vSpritePos.y + GET_RANDOM_FLOAT_IN_RANGE(-sEnemyData[i].vSpriteSize.y, sEnemyData[i].vSpriteSize.y)),
TWS_FX_VENOM_HIT)
sEnemyData[i].iTimer = GET_GAME_TIMER()
ENDIF
BREAK
CASE TWS_ENEMY_DYING
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_BOSS_SPIDER_DYING_ANIM_FRAMES
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DEAD)
ENDIF
BREAK
CASE TWS_ENEMY_DEAD
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_GRUNT
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < cfGAME_SCREEN_WIDTH/2
AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > 80.0
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
IF sPlayerData.bIsJumping
IF sPlayerData.ePlayerState != TWS_FALL_INFINITE
sEnemyData[i].vTargetPos = sPlayerData.vInitialJumpPos
ENDIF
ELSE
sEnemyData[i].vTargetPos = sPlayerData.vSpritePos
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vInitialPos) = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) <= 80.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_UNICORN_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 100.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ELIF NOT sEnemyData[i].bIsBattleEnemy AND ABSF(sEnemyData[i].vTargetPos.X - sPlayerData.vSpritePos.x) >= cfGAME_SCREEN_WIDTH*0.6
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ELIF sEnemyData[i].iSpriteAnimFrame >= 4
// IF distance to Y > 50 AND Y is higher
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.y < sEnemyData[i].vSpritePos.y
OR sTWSData.bLockedScreen AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 25.0 AND sEnemyData[i].vTargetPos.y < sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY
// IF distance to Y > 50 AND Y is lower
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.Y > sEnemyData[i].vSpritePos.Y
OR sTWSData.bLockedScreen AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 25.0 AND sEnemyData[i].vTargetPos.y > sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY
// IF distance to X > 50 AND X is on the left
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.X < sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
// IF distance to X > 50 AND X is on the right
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.X > sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ENDIF
ENDIF
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ELIF sEnemyData[i].iSpriteAnimFrame = 2 AND ARCADE_GAMES_SOUND_HAS_FINISHED(ARCADE_GAMES_SOUND_TWR_UNICORN_JUMP)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_UNICORN_JUMP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_UNICORN_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_ATTACK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_UNICORN_PAIN, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_FALL
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vInitialPos.x) < (350.0 * sPlayerData.iLevel)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsFalling = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_UNICORN_JUMP, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FLAT)
ENDIF
BREAK
CASE TWS_ENEMY_FLAT
IF sEnemyData[i].fHealth > 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GETTING_UP)
ELIF sEnemyData[i].fHealth <= 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_UNICORN_DEATH, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
CASE TWS_ENEMY_GETTING_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_GETTINGUP_ANIM_FRAMES
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_STUN
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_ENEMIES_STUN_TIME
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_GRUNT_SWORD
CASE TWS_ENEMY_GRUNT_SPEAR
CASE TWS_ENEMY_GRUNT_FIRESWORD
CASE TWS_ENEMY_GRUNT_FIRESPEAR
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < cfGAME_SCREEN_WIDTH/2 AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > 50.0
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos = sPlayerData.vInitialJumpPos
ELSE
sEnemyData[i].vTargetPos = sPlayerData.vSpritePos
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vInitialPos) = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) <= 50.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 100.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ELIF NOT sEnemyData[i].bIsBattleEnemy AND ABSF(sEnemyData[i].vTargetPos.X - sPlayerData.vSpritePos.x) >= cfGAME_SCREEN_WIDTH*0.6
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ELSE
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.y < sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.Y > sEnemyData[i].vSpritePos.Y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.X < sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 50.0 AND sEnemyData[i].vTargetPos.X > sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ENDIF
ENDIF
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK
IF (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_FIRESWORD AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_LONG_ATTACK_ANIM_FRAMES)
OR (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_FIRESPEAR AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_SHORT_ATTACK_ANIM_FRAMES)
OR (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_SWORD AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_LONG_ATTACK_ANIM_FRAMES)
OR (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_SPEAR AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_SHORT_ATTACK_ANIM_FRAMES)
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_FALL
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vInitialPos.x) < (350.0 * sPlayerData.iLevel)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsFalling = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_BODYFALL_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FLAT)
ENDIF
BREAK
CASE TWS_ENEMY_FLAT
IF sEnemyData[i].fHealth > 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GETTING_UP)
ELIF sEnemyData[i].fHealth <= 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
CASE TWS_ENEMY_GETTING_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_GETTINGUP_ANIM_FRAMES
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_STUN
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_ENEMIES_STUN_TIME
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_BRUTE
CASE TWS_ENEMY_BRUTE_AXE
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < cfGAME_SCREEN_WIDTH/2 AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > 50.0
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
IF sPlayerData.bIsJumping
IF sPlayerData.ePlayerState != TWS_FALL_INFINITE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sPlayerData.vInitialJumpPos.x, sPlayerData.vInitialJumpPos.y - sPlayerData.vSpriteSize.y/2)
ENDIF
ELSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.x, sPlayerData.vSpritePos.y - sPlayerData.vSpriteSize.y/2)
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vInitialPos) = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 400.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 200.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ELIF NOT sEnemyData[i].bIsBattleEnemy AND ABSF(sEnemyData[i].vTargetPos.X - sPlayerData.vSpritePos.x) >= cfGAME_SCREEN_WIDTH*0.6
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ELSE
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.y < sEnemyData[i].vSpritePos.y
OR sTWSData.bLockedScreen AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 15.0 AND sEnemyData[i].vTargetPos.y < sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.Y > sEnemyData[i].vSpritePos.Y
OR sTWSData.bLockedScreen AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 15.0 AND sEnemyData[i].vTargetPos.y > sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.X < sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*0.75
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.X > sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*0.75
ENDIF
ENDIF
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_ATTACK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.01 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_FALL
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vInitialPos.x) < (300.0 * sPlayerData.iLevel)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsFalling = FALSE
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_BODYFALL_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FLAT)
ENDIF
BREAK
CASE TWS_ENEMY_FLAT
IF TWS_IS_CAMERA_SHAKE_ACTIVE() AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 250
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
ENDIF
IF sEnemyData[i].fHealth > 0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GETTING_UP)
ELIF sEnemyData[i].fHealth <= 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
CASE TWS_ENEMY_GETTING_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_GETTINGUP_ANIM_FRAMES
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_STUN
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_ENEMIES_STUN_TIME
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_BAT
CASE TWS_ENEMY_FAIRY
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_FLY_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < 800.0
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GLIDE_DOWN)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
BREAK
CASE TWS_ENEMY_GLIDE_DOWN
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_FLY_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY*2
IF sEnemyData[i].vSpritePos.y > cfBASE_SCREEN_HEIGHT/3*2 - cfTWS_BAT_FLY_HEIGHT
sEnemyData[i].vShadowOffset.y = 0.0
sEnemyData[i].fProgressToTarget = 0.0
sEnemyData[i].iTimer = 0
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vInitialPos.X - 50, cfBASE_SCREEN_HEIGHT/3*2)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_FLY_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DEAD)
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) > 50.0
sEnemyData[i].vSpritePos = LERP_VECTOR_2D(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos, sEnemyData[i].fProgressToTarget)
sEnemyData[i].fProgressToTarget += 0.0025
ELSE
FLOAT fOffset
IF sEnemyData[i].vSpritePos.X < sPlayerData.vSpritePos.X
fOffset = 300 + GET_RANDOM_FLOAT_IN_RANGE(-50.0, 50.0)
ELSE
fOffset = -300 + GET_RANDOM_FLOAT_IN_RANGE(-50.0, 50.0)
ENDIF
sEnemyData[i].fProgressToTarget = 0.0
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > cfGAME_SCREEN_WIDTH/2 OR sPlayerData.ePlayerState = TWS_DEAD
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vTargetPos.X + GET_RANDOM_FLOAT_IN_RANGE(-100.0, 100.0), sEnemyData[i].vTargetPos.Y + GET_RANDOM_FLOAT_IN_RANGE(-20.0, 20.0))
ELSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sPlayerData.vSpritePos.X + fOffset, sPlayerData.vSpritePos.Y)
ENDIF
ENDIF
IF sEnemyData[i].vSpritePos.y < cfBASE_SCREEN_HEIGHT/3*2 - cfTWS_BAT_FLY_HEIGHT AND sEnemyData[i].vShadowOffset.y = 0.0
sEnemyData[i].vShadowOffset.y = cfBASE_SCREEN_HEIGHT/3*2
ELIF sEnemyData[i].vSpritePos.y > cfBASE_SCREEN_HEIGHT/3*2 - cfTWS_BAT_FLY_HEIGHT AND sEnemyData[i].vShadowOffset.y != 0.0
sEnemyData[i].vShadowOffset.y = 0.0
ENDIF
BREAK
CASE TWS_ENEMY_DEAD
IF sEnemyData[i].iTimer = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
ENDIF
IF sEnemyData[i].vSpritePos.X < sPlayerData.vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 500
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_SLIME
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INVISIBLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF (ABSF(sEnemyData[i].vSpritePos.x -sPlayerData.vSpritePos.x) < cfGAME_SCREEN_WIDTH AND sEnemyData[i].vSpritePos.y > 0)
OR (ABSF(sEnemyData[i].vSpritePos.x -sPlayerData.vSpritePos.x) < 400 AND sEnemyData[i].vSpritePos.y <= 0)
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vInitialPos) = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GLIDE_DOWN)
ENDIF
BREAK
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF sEnemyData[i].iSpriteAnimFrame >= 3 AND sEnemyData[i].iSpriteAnimFrame < 7 AND sEnemyData[i].vShadowOffset.y = -1.0
sEnemyData[i].vShadowOffset.y = 1.0
ELIF sEnemyData[i].iSpriteAnimFrame < 3 AND sEnemyData[i].iSpriteAnimFrame >= 7 AND sEnemyData[i].vShadowOffset.y = 1.0
sEnemyData[i].vShadowOffset.y = -1.0
ENDIF
IF (VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 600.0 OR sEnemyData[i].bIsBattleEnemy)
AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > 100.0
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].vTargetPos = sPlayerData.vSpritePos
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos = sPlayerData.vInitialJumpPos
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sEnemyData[i].fHealth <= 0.01
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_GLIDE_DOWN
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY*4
IF (NOT sPlayerData.bIsJumping AND sEnemyData[i].vSpritePos.y > sPlayerData.vSpritePos.y)
OR (sPlayerData.bIsJumping AND sEnemyData[i].vSpritePos.y > sPlayerData.vInitialJumpPos.y)
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].vTargetPos = sPlayerData.vSpritePos
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos = sPlayerData.vInitialJumpPos
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 100.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ELIF sEnemyData[i].iSpriteAnimFrame >= 3 AND sEnemyData[i].iSpriteAnimFrame < 7
TWS_MOVE_ENEMY(i, 30)
ENDIF
IF sEnemyData[i].iSpriteAnimFrame >= 3 AND sEnemyData[i].iSpriteAnimFrame < 7 AND sEnemyData[i].vShadowOffset.y = -1.0
sEnemyData[i].vShadowOffset.y = 1.0
ELIF sEnemyData[i].iSpriteAnimFrame < 3 AND sEnemyData[i].iSpriteAnimFrame >= 7 AND sEnemyData[i].vShadowOffset.y = 1.0
sEnemyData[i].vShadowOffset.y = -1.0
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sEnemyData[i].fHealth <= 0.01
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_STUN
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_ENEMIES_STUN_TIME
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_DYING
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_SLIME_DEATH_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DEAD)
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
CASE TWS_ENEMY_DEAD
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_GRUNT_CROSSBOW
CASE TWS_ENEMY_GRUNT_CASTER
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF NOT sEnemyData[i].bIsAttacking
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 400.0
sEnemyData[i].iSpriteAnimFrame = 0
IF sPlayerData.bIsJumping
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
IF sEnemyData[i].vSpritePos.x - 250 < sBackgroundTilesData[0].fSpritePos
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[1].fSpritePos, sPlayerData.vInitialJumpPos.y)
ELIF NOT sEnemyData[i].bIsBattleEnemy
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x - 250, sPlayerData.vInitialJumpPos.y)
ENDIF
ELSE
IF sEnemyData[i].vSpritePos.x + 250 > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-2].fSpritePos, sPlayerData.vInitialJumpPos.y)
ELIF NOT sEnemyData[i].bIsBattleEnemy
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x + 250, sPlayerData.vInitialJumpPos.y)
ENDIF
ENDIF
ELSE
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
IF sEnemyData[i].vSpritePos.x - 250 < sBackgroundTilesData[0].fSpritePos
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[1].fSpritePos, sPlayerData.vSpritePos.y)
ELIF NOT sEnemyData[i].bIsBattleEnemy
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x - 250, sPlayerData.vSpritePos.y)
ENDIF
ELSE
IF sEnemyData[i].vSpritePos.x + 250 > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-2].fSpritePos, sPlayerData.vSpritePos.y)
ELIF NOT sEnemyData[i].bIsBattleEnemy
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x + 250, sPlayerData.vSpritePos.y)
ENDIF
ENDIF
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vInitialPos) = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 800.0
OR ABSF(sEnemyData[i].vSpritePos.y - sPlayerData.vSpritePos.y) > 50
sEnemyData[i].iSpriteAnimFrame = 0
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sPlayerData.vInitialJumpPos.y)
ELSE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sPlayerData.vSpritePos.y)
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
ELIF (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CASTER AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000)
OR (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CROSSBOW AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1200)
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.0 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
IF sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CASTER
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ELSE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ENDIF
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 50.0
AND TWS_IS_ENEMY_ON_SCREEN(i)
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].fProgressToTarget = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ELSE
TWS_MOVE_ENEMY(i, 30)
ENDIF
IF (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CASTER AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES/2)
OR (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CROSSBOW AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES)
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.0 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
IF sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CASTER
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ELSE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ENDIF
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK
IF (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CASTER AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_LONG_ATTACK_ANIM_FRAMES-1)
OR (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CROSSBOW AND sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_LONG_ATTACK_ANIM_FRAMES)
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].fProgressToTarget = 0
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ELIF (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CASTER AND sEnemyData[i].iSpriteAnimFrame = 4 AND sEnemyData[i].fProgressToTarget <= 0)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vSpritePos.y - 60), TWS_FX_FIREBALL_RIGHT, sEnemyData[i].vSpritePos.y + sEnemyData[i].vSpriteSize.y)
ELSE
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vSpritePos.y - 60), TWS_FX_FIREBALL_LEFT, sEnemyData[i].vSpritePos.y + sEnemyData[i].vSpriteSize.y)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].fProgressToTarget ++
ELIF (sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CROSSBOW AND sEnemyData[i].iSpriteAnimFrame = 2 AND sEnemyData[i].fProgressToTarget <= 0)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vSpritePos.y - 75), TWS_FX_ARROW_RIGHT, sEnemyData[i].vSpritePos.y + sEnemyData[i].vSpriteSize.y)
ELSE
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vSpritePos.y - 75), TWS_FX_ARROW_LEFT, sEnemyData[i].vSpritePos.y + sEnemyData[i].vSpriteSize.y)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].fProgressToTarget ++
ENDIF
IF TWS_IS_ENEMY_HIT_OR_DEAD(i)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsFalling = TRUE
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.0 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
IF sEnemyData[i].eEnemyType = TWS_ENEMY_GRUNT_CASTER
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ELSE
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ENDIF
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_FALL
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vInitialPos.x) < (350.0 * sPlayerData.iLevel)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsFalling = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_BODYFALL_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FLAT)
ENDIF
BREAK
CASE TWS_ENEMY_FLAT
IF sEnemyData[i].fHealth > 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GETTING_UP)
ELIF sEnemyData[i].fHealth <= 0.0 AND GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
CASE TWS_ENEMY_GETTING_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_GETTINGUP_ANIM_FRAMES
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_STUN
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_ENEMIES_STUN_TIME
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_DYING
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_CASTER_DYING_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].bIsActive = FALSE
TWS_ACTIVATE_CAMERA_SHAKE(FALSE)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_INVISIBLE)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_LEPRECHAUN
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INVISIBLE
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 400.0 OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_LEPRECHAUN_JUMP_LAND, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GO_UP)
ENDIF
BREAK
CASE TWS_ENEMY_GO_UP
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_LEPRECHAUN_SPAWN_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
BREAK
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 600.0 AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > 50.0
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
IF sPlayerData.bIsJumping
sEnemyData[i].vTargetPos = sPlayerData.vInitialJumpPos
ELSE
sEnemyData[i].vTargetPos = sPlayerData.vSpritePos
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 400.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].fProgressToTarget = 0.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ENDIF
IF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
IF sPlayerData.bIsJumping OR sPlayerData.bIsCharging OR sEnemyData[i].fHealth <= 0.0 OR TWS_IS_PLAYER_USING_FINAL_ATTACK()
sEnemyData[i].bIsFalling = TRUE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ELSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sEnemyData[i].vTargetPos) < 600.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].fProgressToTarget = 0.0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_ATTACK)
ELIF sEnemyData[i].iSpriteAnimFrame >= 3
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.y < sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sEnemyData[i].vTargetPos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.Y > sEnemyData[i].vSpritePos.Y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.X < sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vTargetPos.x, sEnemyData[i].vSpritePos.Y)) > 30.0 AND sEnemyData[i].vTargetPos.X > sEnemyData[i].vSpritePos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ENDIF
ENDIF
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_LEPRECHAUN_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_LEPRECHAUN_JUMP_LAND, TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
ENDIF
IF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
sEnemyData[i].bIsFalling = TRUE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ENDIF
BREAK
CASE TWS_ENEMY_ATTACK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_EXTRA_LONG_ATTACK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].fProgressToTarget = 0.0
ELIF sEnemyData[i].iSpriteAnimFrame = ciTWS_ENEMY_LONG_ATTACK_ANIM_FRAMES AND sEnemyData[i].fProgressToTarget = 0.0
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x + cfTWS_LEPRECHAUN_COINS_WIDTH * cfTWS_RESCALE_FACTOR, sEnemyData[i].vSpritePos.y), TWS_FX_COINS_RIGHT)
ELSE
TWS_CREATE_FX(INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x - cfTWS_LEPRECHAUN_COINS_WIDTH * cfTWS_RESCALE_FACTOR, sEnemyData[i].vSpritePos.y), TWS_FX_COINS_LEFT)
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_ATTACK_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].fProgressToTarget ++
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > 600.0
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
IF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
sEnemyData[i].iTimer = GET_GAME_TIMER()
ENDIF
BREAK
CASE TWS_ENEMY_FALL
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < (300.0 * sPlayerData.iLevel)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsFalling = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ENDIF
BREAK
CASE TWS_ENEMY_DYING
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_LEPRECHAUN_DYING_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_SNAKE
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < cfBASE_SCREEN_WIDTH/2
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].fProgressToTarget = 0.0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_SNAKE_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
IF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].vTargetPos = sEnemyData[i].vSpritePos
sEnemyData[i].bIsFalling = TRUE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_FALL)
ENDIF
IF sEnemyData[i].vSpritePos.x < -cfBASE_SCREEN_WIDTH/2
sEnemyData[i].bIsActive = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_INVISIBLE)
ENDIF
BREAK
CASE TWS_ENEMY_FALL
IF ABSF(sEnemyData[i].vSpritePos.x - sEnemyData[i].vTargetPos.x) < (200.0 * sPlayerData.iLevel)
IF sEnemyData[i].vSpritePos.x < sPlayerData.vSpritePos.x
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ELSE
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*2
ENDIF
ELSE
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].iTimer = GET_GAME_TIMER()
sEnemyData[i].bIsFalling = FALSE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DYING)
ENDIF
BREAK
CASE TWS_ENEMY_DYING
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 1000
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = FALSE
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_BOULDER
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INVISIBLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < cfBASE_SCREEN_WIDTH/2
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].fProgressToTarget = 0.0
IF NOT TWS_IS_CAMERA_SHAKE_ACTIVE()
TWS_ACTIVATE_CAMERA_SHAKE(TRUE)
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_BOULDER_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_BOULDER_BOUNCE)
ENDIF
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY
ARCADE_GAMES_SOUND_SET_VARIABLE(ARCADE_GAMES_SOUND_TWR_BOULDER_BOUNCE, "Screen_Position", TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sEnemyData[i].vSpritePos.x < -cfBASE_SCREEN_WIDTH/2 OR (sEnemyData[i].bIsBattleEnemy AND sEnemyData[i].vSpritePos.x < sTWSData.fLockedScreenPos - cfBASE_SCREEN_WIDTH/2)
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_BOULDER_BOUNCE)
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_ENEMY_SPIDER
SWITCH sEnemyData[i].eEnemyState
CASE TWS_ENEMY_INACTIVE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF ABSF(sEnemyData[i].vSpritePos.x - sPlayerData.vSpritePos.x) < cfGAME_SCREEN_WIDTH/2.0
OR sEnemyData[i].bIsBattleEnemy
sEnemyData[i].iSpriteAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_AGGRO_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_GLIDE_DOWN)
ENDIF
BREAK
CASE TWS_ENEMY_IDLE
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_IDLE_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 600.0 AND VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) > 50.0
IF sEnemyData[i].vSpritePos.X <= sEnemyData[i].vTargetPos.X
sEnemyData[i].vTargetPos.X = sPlayerData.vSpritePos.X + 400
ELIF sEnemyData[i].vSpritePos.X >= sEnemyData[i].vTargetPos.X
sEnemyData[i].vTargetPos.X = sPlayerData.vSpritePos.X - 400
ENDIF
sEnemyData[i].iTimer = 0
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
IF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
BREAK
CASE TWS_ENEMY_GLIDE_DOWN
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY
IF sEnemyData[i].vSpritePos.y > cfBASE_SCREEN_HEIGHT/2
sEnemyData[i].vShadowOffset.y = 0.0
sEnemyData[i].iTimer = 0
sEnemyData[i].vInitialPos = sEnemyData[i].vSpritePos
sEnemyData[i].iSpriteAnimFrame = 0
sEnemyData[i].bIsAttacking = TRUE
sEnemyData[i].vTargetPos = INIT_VECTOR_2D(sEnemyData[i].vInitialPos.X, cfBASE_SCREEN_HEIGHT/2)
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_WALK)
ENDIF
BREAK
CASE TWS_ENEMY_WALK
IF sEnemyData[i].iSpriteAnimFrame >= ciTWS_ENEMY_WALK_ANIM_FRAMES
sEnemyData[i].iSpriteAnimFrame = 0
ENDIF
// CPRINTLN(DEBUG_MINIGAME, "sEnemyData[i].vTargetPos.X ",sEnemyData[i].vTargetPos.X)
// CPRINTLN(DEBUG_MINIGAME, "sEnemyData[i].vSpritePos.x ",sEnemyData[i].vSpritePos.x)
// CPRINTLN(DEBUG_MINIGAME, "sPlayerData.vSpritePos.x ",sPlayerData.vSpritePos.x)
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, sPlayerData.vSpritePos) < 700
OR sEnemyData[i].bIsBattleEnemy
IF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y/2)) > 30.0 AND sPlayerData.vSpritePos.y + sPlayerData.vSpriteSize.Y/2 < sEnemyData[i].vSpritePos.y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY/2
ELIF VECTOR_2D_DIST(sEnemyData[i].vSpritePos, INIT_VECTOR_2D(sEnemyData[i].vSpritePos.x, sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y/2)) > 30.0 AND sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y/2 > sEnemyData[i].vSpritePos.Y
sEnemyData[i].vSpritePos.y = sEnemyData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY/2
ELIF sEnemyData[i].vSpritePos.X >= sEnemyData[i].vTargetPos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY/2
IF sEnemyData[i].vSpritePos.X <= sEnemyData[i].vTargetPos.X
sEnemyData[i].vTargetPos.X = sPlayerData.vSpritePos.X + 400
ENDIF
ELIF sEnemyData[i].vSpritePos.X <= sEnemyData[i].vTargetPos.X
sEnemyData[i].vSpritePos.x = sEnemyData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY/2
IF sEnemyData[i].vSpritePos.X >= sEnemyData[i].vTargetPos.X
sEnemyData[i].vTargetPos.X = sPlayerData.vSpritePos.X - 400
ENDIF
ENDIF
ENDIF
IF sEnemyData[i].bIsHit
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_PAIN_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
sEnemyData[i].bIsAttacking = FALSE
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_STUN)
ENDIF
BREAK
CASE TWS_ENEMY_STUN
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > ciTWS_ENEMIES_STUN_TIME OR sEnemyData[i].fHealth <= 0
iF sEnemyData[i].fHealth <= 0.0
sEnemyData[i].iTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(TWS_GET_DEATH_SOUND_FOR_ENEMY(sEnemyData[i].eEnemyType), TWS_GET_SOUND_POSITION_FOR_ENEMY(i))
IF sTWSData.bLockedScreen AND sEnemyData[i].bIsBattleEnemy
sTWSData.iNumberOfEnemiesKilledInBattle ++
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_DEAD)
ELSE
sEnemyData[i].bIsHit = FALSE
sEnemyData[i].iSpriteAnimFrame = 0
TWS_SET_ENEMY_STATE(i, TWS_ENEMY_IDLE)
ENDIF
ENDIF
BREAK
CASE TWS_ENEMY_DEAD
IF GET_GAME_TIMER() - sEnemyData[i].iTimer > 3000
TWS_RESET_ENEMY_VARIABLES(i)
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_ENEMY, i)
ENDIF
BREAK
ENDSWITCH
BREAK
ENDSWITCH
ENDIF
ENDFOR
ENDPROC
PROC TWS_HANDLE_ITEM_STATE()
INT i
FOR i = 0 TO ciTWS_MAX_ITEMS - 1
IF sItemData[i].bIsActive AND sItemData[i].bIsHit
sItemData[i].iSpriteAnimFrame += sItemData[i].iSlowUpdateFrames
IF sItemData[i].iSpriteAnimFrame >= ciTWS_FX_ITEM_ANIM_FRAMES
sItemData[i].bIsActive = FALSE
ENDIF
ELIF sItemData[i].bIsActive AND sItemData[i].bFalling AND sItemData[i].vSpritePos.y < sItemData[i].vSpriteFallPos.y
sItemData[i].vSpritePos.y += 30.0
IF sItemData[i].vSpritePos.y >= sItemData[i].vSpriteFallPos.y
sItemData[i].bFalling = FALSE
ENDIF
ENDIF
ENDFOR
ENDPROC
PROC TWS_HANDLE_FX()
INT i
FOR i = 0 TO ciTWS_MAX_FX - 1
IF sFXData[i].bActive
sFXData[i].iSpriteBlastAnimFrame += sFXData[i].iSlowUpdateFrames
SWITCH sFXData[i].eType
CASE TWS_FX_SWORD_LIGHTNING
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_SWORD_LIGHTNING_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
ENDIF
IF NOT sPlayerData.bIsUsingMagic
sFXData[i].bActive = FALSE
ENDIF
BREAK
CASE TWS_FX_SUPERATTACK_EXPLOSION
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_SUPERATTACK_EXPLOSION_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ENDIF
BREAK
CASE TWS_FX_SMALL_HIT
CASE TWS_FX_LARGE_HIT
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_HIT_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ENDIF
BREAK
CASE TWS_FX_VENOM_HIT
CASE TWS_FX_BLOOD_HIT
CASE TWS_FX_PICKUP
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_HIT_VENOM_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ENDIF
BREAK
CASE TWS_FX_SWORD_DROP
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_KNIGHT_SWORD_DROP_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = ciTWS_FX_KNIGHT_SWORD_DROP_ANIM_FRAMES-1
ENDIF
BREAK
CASE TWS_FX_HELP
IF sTWSData.eLevelStage >= TWS_LEVEL_FINAL_DIALOGUE
sFXData[i].bActive = FALSE
ENDIF
BREAK
CASE TWS_FX_COD_DROP
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_KNIGHT_COD_DROP_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = ciTWS_FX_KNIGHT_COD_DROP_ANIM_FRAMES-1
ENDIF
BREAK
CASE TWS_FX_BOSS_SPIDER_SPIT
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_BOSS_SPIDER_SPIT_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
ENDIF
IF GET_GAME_TIMER() - sFXData[i].iTimer > ciTWS_BOSS_ATTACK_TIME
sFXData[i].bActive = FALSE
sFXData[i].iTimer = 0
ENDIF
BREAK
CASE TWS_FX_MAGIC_COLUMN
IF GET_GAME_TIMER() - sFXData[i].iTimer < ciTWS_MAGIC_COLUMN_INTRO_TIME
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_WIZARD_PILLAR_DAMAGE_ANIM_FRAMES -1
sFXData[i].iSpriteBlastAnimFrame = ciTWS_FX_WIZARD_PILLAR_DAMAGE_ANIM_FRAMES -2
ENDIF
ELSE
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_WIZARD_PILLAR_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF sPlayerData.bIsJumping
IF sFXData[i].iSpriteBlastAnimFrame > ciTWS_FX_WIZARD_PILLAR_DAMAGE_ANIM_FRAMES
ELIF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vInitialJumpPos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 50.0
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ELSE
IF sFXData[i].iSpriteBlastAnimFrame > ciTWS_FX_WIZARD_PILLAR_DAMAGE_ANIM_FRAMES
ELIF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 50.0
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ENDIF
ENDIF
BREAK
CASE TWS_FX_MAGIC_FIRE
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_WIZARD_FIRE_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF sPlayerData.bIsJumping
IF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vInitialJumpPos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 65.0
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ELSE
IF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 65.0
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ENDIF
BREAK
CASE TWS_FX_TRAP_SPEAR
IF sFXData[i].iTimer = 0 AND sFXData[i].iSpriteBlastAnimFrame >= ciTWS_TRAP_SPEAR_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = ciTWS_TRAP_SPEAR_ANIM_FRAMES-1
IF TWS_IS_FX_ON_SCREEN(i) AND ARCADE_GAMES_SOUND_HAS_FINISHED(ARCADE_GAMES_SOUND_TWR_SPIKE_DOWN)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_SPIKE_DOWN, TWS_GET_SOUND_POSITION_FOR_FX(i))
ENDIF
sFXData[i].iTimer = GET_GAME_TIMER()
ELIF sFXData[i].iTimer > 0
sFXData[i].iSpriteBlastAnimFrame -= (sFXData[i].iSlowUpdateFrames*2)
IF sFXData[i].iSpriteBlastAnimFrame <= 0
sFXData[i].iSpriteBlastAnimFrame = 0
ENDIF
IF GET_GAME_TIMER() - sFXData[i].iTimer > 1000
sFXData[i].iTimer = 0
IF TWS_IS_FX_ON_SCREEN(i) AND ARCADE_GAMES_SOUND_HAS_FINISHED(ARCADE_GAMES_SOUND_TWR_SPIKE_UP)
TWS_ARCADE_GAMES_SOUND_PLAY_AT_POSITION(ARCADE_GAMES_SOUND_TWR_SPIKE_UP, TWS_GET_SOUND_POSITION_FOR_FX(i))
ENDIF
ENDIF
ENDIF
IF sPlayerData.bIsJumping
IF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vInitialJumpPos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 20.0*sFXData[i].iSpriteBlastAnimFrame
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ELSE
IF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 20.0*sFXData[i].iSpriteBlastAnimFrame
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ENDIF
BREAK
CASE TWS_FX_SWORD
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_KNIGHT_SWORD_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF sPlayerData.bIsJumping
IF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vInitialJumpPos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 100.0
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ELSE
IF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 100.0
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ENDIF
BREAK
CASE TWS_FX_ARROW_LEFT
sFXData[i].vSpritePos.x = sFXData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*1.2
IF sFXData[i].vSpritePos.x < sPlayerData.vSpritePos.x - cfBASE_SCREEN_WIDTH
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF (sPlayerData.vSpritePos.X - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.x + cfTWS_GRUNT_CROSSBOW_ARROW_WIDTH) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.Y + cfTWS_GRUNT_CROSSBOW_ARROW_HEIGHT) AND (sPlayerData.vSpriteSize.Y/2 + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y)
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + cfTWS_FX_ARROW_HEIGHT_TO_GROUND)) < 75.0
sFXData[i].bActive = FALSE
TWS_CREATE_FX(sFXData[i].vSpritePos, TWS_FX_SMALL_HIT)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
IF TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_WEAPON_DEFLECT_ARROW)
ENDIF
ENDIF
BREAK
CASE TWS_FX_ARROW_RIGHT
sFXData[i].vSpritePos.x = sFXData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*1.2
IF sFXData[i].vSpritePos.x > sPlayerData.vSpritePos.x + cfBASE_SCREEN_WIDTH
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF (sPlayerData.vSpritePos.X - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.x + cfTWS_GRUNT_CROSSBOW_ARROW_WIDTH) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.Y + cfTWS_GRUNT_CROSSBOW_ARROW_HEIGHT) AND (sPlayerData.vSpriteSize.Y/2 + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y)
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + cfTWS_FX_ARROW_HEIGHT_TO_GROUND)) < 75.0
sFXData[i].bActive = FALSE
TWS_CREATE_FX(sFXData[i].vSpritePos, TWS_FX_SMALL_HIT)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
IF TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_WEAPON_DEFLECT_ARROW)
ENDIF
ENDIF
BREAK
CASE TWS_FX_CLOTHES
sFXData[i].vSpritePos.y += 1.0
IF sFXData[i].vSpritePos.y >= sPlayerData.vSpritePos.y
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ENDIF
BREAK
CASE TWS_FX_FIREBALL_LEFT
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_FIREBALL_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
ENDIF
sFXData[i].vSpritePos.x = sFXData[i].vSpritePos.x -@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*1.2
IF sFXData[i].vSpritePos.x < sPlayerData.vSpritePos.x - cfBASE_SCREEN_WIDTH
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF (sPlayerData.vSpritePos.X - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.x + cfTWS_GRUNT_CASTER_FIREBALL_WIDTH) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.Y + cfTWS_GRUNT_CASTER_FIREBALL_HEIGHT) AND (sPlayerData.vSpriteSize.Y/2 + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y)
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + cfTWS_FX_ARROW_HEIGHT_TO_GROUND)) < 75.0
sFXData[i].bActive = FALSE
TWS_CREATE_FX(sFXData[i].vSpritePos, TWS_FX_LARGE_HIT)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
IF TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.2, 0.0, 1.0)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_WEAPON_DEFLECT_FIREBALL)
ENDIF
ENDIF
BREAK
CASE TWS_FX_FIREBALL_RIGHT
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_FIREBALL_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
ENDIF
sFXData[i].vSpritePos.x = sFXData[i].vSpritePos.x +@ cfTWS_HORIZONTAL_MOVEMENT_ENEMY*1.2
IF sFXData[i].vSpritePos.x > sPlayerData.vSpritePos.x + cfBASE_SCREEN_WIDTH
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF (sPlayerData.vSpritePos.X - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.x + cfTWS_GRUNT_CASTER_FIREBALL_WIDTH) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.Y + cfTWS_GRUNT_CASTER_FIREBALL_HEIGHT) AND (sPlayerData.vSpriteSize.Y/2 + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y)
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + cfTWS_FX_ARROW_HEIGHT_TO_GROUND)) < 75.0
sFXData[i].bActive = FALSE
TWS_CREATE_FX(sFXData[i].vSpritePos, TWS_FX_LARGE_HIT)
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
IF TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.2, 0.0, 1.0)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_WEAPON_DEFLECT_FIREBALL)
ENDIF
ENDIF
BREAK
CASE TWS_FX_COINS_LEFT
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_COINS_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF (sPlayerData.vSpritePos.X - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.x + cfTWS_LEPRECHAUN_COINS_WIDTH) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X * cfTWS_RESCALE_FACTOR) > sFXData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.Y + cfTWS_LEPRECHAUN_COINS_HEIGHT) AND (sPlayerData.vSpriteSize.Y * cfTWS_RESCALE_FACTOR + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y)
AND TWS_CAN_PLAYER_BE_HURT()
AND sFXData[i].iSpriteBlastAnimFrame = 3
sFXData[i].bActive = FALSE
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
TWS_CREATE_FX(sFXData[i].vSpritePos, TWS_FX_SMALL_HIT)
ENDIF
BREAK
CASE TWS_FX_COINS_RIGHT
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_COINS_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
ELIF (sPlayerData.vSpritePos.X - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.x + cfTWS_LEPRECHAUN_COINS_WIDTH) AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X * cfTWS_RESCALE_FACTOR) > sFXData[i].vSpritePos.x
AND sPlayerData.vSpritePos.Y - sPlayerData.vSpriteSize.y < (sFXData[i].vSpritePos.Y + cfTWS_LEPRECHAUN_COINS_HEIGHT) AND (sPlayerData.vSpriteSize.Y * cfTWS_RESCALE_FACTOR + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y)
AND TWS_CAN_PLAYER_BE_HURT()
AND sFXData[i].iSpriteBlastAnimFrame = 3
sFXData[i].bActive = FALSE
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
TWS_CREATE_FX(sFXData[i].vSpritePos, TWS_FX_SMALL_HIT)
ENDIF
BREAK
CASE TWS_FX_VENOM_PUDDLE
IF GET_GAME_TIMER() - sFXData[i].iTimer < ciTWS_MAGIC_COLUMN_INTRO_TIME
IF sFXData[i].iSpriteBlastAnimFrame >= 2
sFXData[i].iSpriteBlastAnimFrame = 1
ENDIF
ELIF GET_GAME_TIMER() - sFXData[i].iTimer < ciTWS_BOSS_ATTACK_TIME
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_BOSS_SPIDER_VENOM_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = ciTWS_FX_BOSS_SPIDER_VENOM_ANIM_FRAMES - 1
ENDIF
IF sFXData[i].iSpriteBlastAnimFrame > ciTWS_FX_WIZARD_PILLAR_DAMAGE_ANIM_FRAMES
ELIF sPlayerData.vSpritePos.X < (sFXData[i].vSpritePos.x + sFXData[i].vSpriteSize.X)
AND (sPlayerData.vSpritePos.X + sPlayerData.vSpriteSize.X) > sFXData[i].vSpritePos.X
AND sPlayerData.vSpritePos.Y < (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)
AND (sPlayerData.vSpriteSize.Y + sPlayerData.vSpritePos.Y) > sFXData[i].vSpritePos.Y
AND ABSF((sPlayerData.vSpritePos.Y + sPlayerData.vSpriteSize.Y) - (sFXData[i].vSpritePos.Y + sFXData[i].vSpriteSize.Y)) < 50.0
AND TWS_CAN_PLAYER_BE_HURT()
sPlayerData.bIsHit = TRUE
SET_CONTROL_SHAKE(FRONTEND_CONTROL, 100, 10)
sPlayerData.fHealth = CLAMP(sPlayerData.fHealth - 0.1, 0.0, 1.0)
ENDIF
ELSE
sFXData[i].iSpriteBlastAnimFrame -= 2* sFXData[i].iSlowUpdateFrames
IF sFXData[i].iSpriteBlastAnimFrame < 0
sFXData[i].iSpriteBlastAnimFrame = 0
sFXData[i].bActive = FALSE
sFXData[i].iTimer = 0
ENDIF
ENDIF
BREAK
CASE TWS_FX_GROG_BUBBLE
IF sFXData[i].iSpriteBlastAnimFrame >= ciTWS_FX_HIT_VENOM_ANIM_FRAMES
sFXData[i].iSpriteBlastAnimFrame = 0
ENDIF
IF sTWSData.eGrogEncounterState < TWS_GROG_LEAVES AND sFXData[i].vSpritePos.y < cfBASE_SCREEN_HEIGHT*0.6
sFXData[i].vSpritePos.y = sFXData[i].vSpritePos.y +@ cfTWS_VERTICAL_MOVEMENT_ENEMY * 2
ELIF (sTWSData.eGrogEncounterState >= TWS_GROG_LEAVES AND sFXData[i].vSpritePos.y > -150)
sFXData[i].vSpritePos.y = sFXData[i].vSpritePos.y -@ cfTWS_VERTICAL_MOVEMENT_ENEMY * 2
ELIF sTWSData.eGrogEncounterState >= TWS_GROG_LEAVES AND sFXData[i].vSpritePos.y <= -150
sFXData[i].bActive = FALSE
ENDIF
BREAK
ENDSWITCH
IF sFXData[i].bActive = FALSE
TWS_REMOVE_DRAW_CALL(TWS_ENTITY_FX, i)
ENDIF
ENDIF
ENDFOR
ENDPROC
FUNC ARCADE_GAMES_SOUND TWS_GET_CHARACTER_SPEECH_BUBBLE_SOUND(INT iLine)
SWITCH iLine
CASE 1
CASE 5
CASE 7
CASE 9
CASE 12
CASE 16
CASE 18
CASE 21
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_THOG
CASE 17
CASE 19
CASE 20
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_WIZARD
CASE 0
CASE 2
CASE 3
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_MAN_01
CASE 13
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_MAN_02
CASE 4
CASE 6
CASE 8
CASE 10
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_WOMAN_01
CASE 11
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_WOMAN_02
CASE 14
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_WOMAN_03
CASE 15
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_WOMAN_04
DEFAULT
RETURN ARCADE_GAMES_SOUND_TWR_SPEECH_BUBBLE_GROG
ENDSWITCH
ENDFUNC
PROC TWS_START_DIALOGUE(INT iStartingLine, INT iFinalLine)
sHUDData[TWS_HUD_DIALOGUE_FRAME].bRendering = TRUE
sHUDData[TWS_HUD_DIALOGUE_FRAME].bActive = TRUE
sTWSData.iCurrentDialogue = iStartingLine
sTWSData.iLastDialogue = iFinalLine
TWS_ARCADE_GAMES_SOUND_PLAY(TWS_GET_CHARACTER_SPEECH_BUBBLE_SOUND(iStartingLine))
ENDPROC
PROC TWS_END_DIALOGUE()
sHUDData[TWS_HUD_DIALOGUE_FRAME].bActive = FALSE
ENDPROC
FUNC BOOL HAS_CURRENT_DIALOGUE_ENDED()
RETURN sTWSData.iCurrentDialogue > sTWSData.iLastDialogue
ENDFUNC
PROC TWS_HANDLE_DIALOGUE()
IF sTWSData.iCurrentDialogue < sTWSData.iLastDialogue AND TWS_IS_ANY_ACCEPT_BUTTON_PRESSED()
sTWSData.iCurrentDialogue ++
TWS_ARCADE_GAMES_SOUND_PLAY(TWS_GET_CHARACTER_SPEECH_BUBBLE_SOUND(sTWSData.iCurrentDialogue))
ELIF TWS_IS_ANY_ACCEPT_BUTTON_PRESSED()
sTWSData.iCurrentDialogue ++
TWS_END_DIALOGUE()
ENDIF
ENDPROC
PROC TWS_HANDLE_HUD()
IF sHUDData[TWS_HUD_START].bActive
IF sHUDData[TWS_HUD_START].vSpritePos.x > (cfBASE_SCREEN_WIDTH + 500)
sHUDData[TWS_HUD_START].bActive= FALSE
ELIF sHUDData[TWS_HUD_START].vSpritePos.x < (cfBASE_SCREEN_WIDTH/2 - 100) OR sHUDData[TWS_HUD_START].vSpritePos.x > (cfBASE_SCREEN_WIDTH/2 + 100)
IF sHUDData[TWS_HUD_START].vSpritePos.x <= - 100 AND sTWSData.eCurrentLevel != TWS_FOREST_INTRO
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_START_SHING)
ENDIF
sHUDData[TWS_HUD_START].vSpritePos.x += 30
IF NOT sHUDData[TWS_HUD_START].bPlayedSoundAttacked AND sHUDData[TWS_HUD_START].vSpritePos.x >= cfBASE_SCREEN_WIDTH/2 - 100 AND sTWSData.eCurrentLevel != TWS_FOREST_INTRO
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_START_HIT)
sHUDData[TWS_HUD_START].bPlayedSoundAttacked = TRUE
ENDIF
ELSE
sHUDData[TWS_HUD_START].vSpritePos.x += 4
ENDIF
ENDIF
IF sHUDData[TWS_HUD_GAMEOVER].bActive
IF sHUDData[TWS_HUD_GAMEOVER].vSpritePos.x > (cfBASE_SCREEN_WIDTH + 500)
sHUDData[TWS_HUD_GAMEOVER].bActive= FALSE
ELIF sHUDData[TWS_HUD_GAMEOVER].vSpritePos.x < (cfBASE_SCREEN_WIDTH/2 - 100) OR sHUDData[TWS_HUD_GAMEOVER].vSpritePos.x > (cfBASE_SCREEN_WIDTH/2 + 100)
IF sHUDData[TWS_HUD_GAMEOVER].vSpritePos.x <= - 100
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_START_SHING)
ENDIF
sHUDData[TWS_HUD_GAMEOVER].vSpritePos.x += 30
IF NOT sHUDData[TWS_HUD_GAMEOVER].bPlayedSoundAttacked AND sHUDData[TWS_HUD_GAMEOVER].vSpritePos.x >= cfBASE_SCREEN_WIDTH/2 - 100
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_START_HIT)
sHUDData[TWS_HUD_GAMEOVER].bPlayedSoundAttacked = TRUE
ENDIF
ELSE
sHUDData[TWS_HUD_GAMEOVER].vSpritePos.x += 4
ENDIF
ENDIF
IF sHUDData[TWS_HUD_END].bActive
IF sHUDData[TWS_HUD_END].vSpritePos.x < cfBASE_SCREEN_WIDTH/2
sHUDData[TWS_HUD_END].vSpritePos.x += 30
IF sHUDData[TWS_HUD_END].vSpritePos.x >= cfBASE_SCREEN_WIDTH/2
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_START_HIT)
ENDIF
IF NOT sHUDData[TWS_HUD_END].bPlayedSoundAttacked AND sHUDData[TWS_HUD_END].vSpritePos.x >= cfBASE_SCREEN_WIDTH/2
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_START_HIT)
sHUDData[TWS_HUD_END].bPlayedSoundAttacked = TRUE
ENDIF
ENDIF
ENDIF
IF sTWSData.eLevelStage = TWS_LEVEL_PLAYING
sHUDData[TWS_HUD_GO_ARROW].bActive = TRUE
IF sTWSData.bLockedScreen OR TWS_ARE_ENEMIES_IN_RANGE()
sHUDData[TWS_HUD_GO_ARROW].bActive = FALSE
sHUDData[TWS_HUD_GO_ARROW].iSlowUpdateFrames = 0
ENDIF
IF sHUDData[TWS_HUD_GO_ARROW].bActive AND sHUDData[TWS_HUD_START].bActive = FALSE
IF SIN(GET_GAME_TIMER()/2.0) > 0.0
IF sHUDData[TWS_HUD_GO_ARROW].bRendering = FALSE AND sHUDData[TWS_HUD_GO_ARROW].iSlowUpdateFrames < 3
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_GO)
sHUDData[TWS_HUD_GO_ARROW].iSlowUpdateFrames ++
ENDIF
sHUDData[TWS_HUD_GO_ARROW].bRendering = TRUE
ELSE
sHUDData[TWS_HUD_GO_ARROW].bRendering = FALSE
ENDIF
ENDIF
ELIF sHUDData[TWS_HUD_GO_ARROW].bActive
sHUDData[TWS_HUD_GO_ARROW].bActive = FALSE
ENDIF
IF sHUDData[TWS_HUD_DIALOGUE_FRAME].bActive
IF sHUDData[TWS_HUD_DIALOGUE_FRAME].iSpriteBlastAnimFrame < ciTWS_DIALOGUE_FRAME_ANIM_FRAMES -1
sHUDData[TWS_HUD_DIALOGUE_FRAME].iSpriteBlastAnimFrame += sHUDData[TWS_HUD_DIALOGUE_FRAME].iSlowUpdateFrames
ENDIF
ELIF NOT sHUDData[TWS_HUD_DIALOGUE_FRAME].bActive
IF sHUDData[TWS_HUD_DIALOGUE_FRAME].iSpriteBlastAnimFrame > 0
sHUDData[TWS_HUD_DIALOGUE_FRAME].iSpriteBlastAnimFrame -= sHUDData[TWS_HUD_DIALOGUE_FRAME].iSlowUpdateFrames
ELIF sHUDData[TWS_HUD_DIALOGUE_FRAME].iSpriteBlastAnimFrame = 0
sHUDData[TWS_HUD_DIALOGUE_FRAME].bRendering = FALSE
ENDIF
ENDIF
ENDPROC
FUNC BOOL TWS_HANDLE_FIB_WARNING()
SWITCH sTWSData.eFIBState
CASE TWS_FIB_FADEIN
TWS_FADE_IN(TRUE)
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.eFIBState = TWS_FIB_DISPLAY
BREAK
CASE TWS_FIB_DISPLAY
IF TWS_IS_SCREEN_FADED_IN() AND GET_GAME_TIMER() - sTWSData.iGameTimer > 4000
sTWSData.eFIBState = TWS_FIB_FADEOUT
TWS_FADE_OUT()
ENDIF
BREAK
CASE TWS_FIB_FADEOUT
IF TWS_IS_SCREEN_FADED_OUT()
sTWSData.eFIBState = TWS_FIB_FADEIN
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL TWS_HANDLE_PIXTRO_LOGO()
SWITCH sTWSData.ePixtroState
CASE TWS_PIXTRO_START
ARCADE_DRAW_PIXELSPACE_RECT(INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2, cfBASE_SCREEN_HEIGHT/2), INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH, cfBASE_SCREEN_HEIGHT), sTWSData.rgbaBlack)
TWS_START_MOVIE(sTWSData.bmIDPixtroIntro,"_Pixtro_Intro_80s_2")
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_PIXTRO_LOGO)
sTWSData.ePixtroState = TWS_PIXTRO_PLAYING
BREAK
CASE TWS_PIXTRO_PLAYING
ARCADE_DRAW_PIXELSPACE_RECT(INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH/2, cfBASE_SCREEN_HEIGHT/2), INIT_VECTOR_2D(cfBASE_SCREEN_WIDTH, cfBASE_SCREEN_HEIGHT), sTWSData.rgbaBlack)
IF TWS_DRAW_MOVIE(sTWSData.bmIDPixtroIntro, cfGAME_SCREEN_WIDTH/1264.0 ,1.0)
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_PIXTRO_LOGO)
sTWSData.ePixtroState = TWS_PIXTRO_START
RETURN TRUE
ENDIF
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_PIXTRO_LOGO)
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL TWS_HANDLE_TITLE_ANIM()
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame += sTWSData.iGlobalDefaultUpdateFrames
SWITCH sTWSData.sCutsceneData.eTitleCutsceneStage
CASE TWS_TITLE_ANIM_STRIKE_1
IF sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame >= ciTWS_TITLE_ANIM_STRIKE_FRAMES
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_INTRO_THUNDER)
TRIGGER_MUSIC_EVENT("ARCADE_WR_THEME_START")
sTWSData.sCutsceneData.eTitleCutsceneStage = TWS_TITLE_ANIM_STRIKE_1_PAUSE
ENDIF
BREAK
CASE TWS_TITLE_ANIM_STRIKE_1_PAUSE
IF sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame >= ciTWS_TITLE_ANIM_PAUSE_FRAMES
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_INTRO_THUNDER)
sTWSData.sCutsceneData.eTitleCutsceneStage = TWS_TITLE_ANIM_STRIKE_2
ENDIF
BREAK
CASE TWS_TITLE_ANIM_STRIKE_2
IF sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame >= ciTWS_TITLE_ANIM_STRIKE_FRAMES
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame = 0
sTWSData.sCutsceneData.eTitleCutsceneStage = TWS_TITLE_ANIM_STRIKE_2_PAUSE
ENDIF
BREAK
CASE TWS_TITLE_ANIM_STRIKE_2_PAUSE
IF sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame >= ciTWS_TITLE_ANIM_PAUSE_FRAMES
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame = 0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_INTRO_DOUBLE_THUNDER)
sTWSData.sCutsceneData.eTitleCutsceneStage = TWS_TITLE_ANIM_FINAL_STRIKE
ENDIF
BREAK
CASE TWS_TITLE_ANIM_FINAL_STRIKE
IF sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame >= ciTWS_TITLE_ANIM_FINAL_FRAMES
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame = 0
sTWSData.sCutsceneData.eTitleCutsceneStage = TWS_TITLE_ANIM_STRIKE_1
TWS_FADE_IN(TRUE)
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
IF TWS_IS_ANY_ACCEPT_BUTTON_PRESSED()
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame = 0
sTWSData.sCutsceneData.eTitleCutsceneStage = TWS_TITLE_ANIM_STRIKE_1
TWS_FADE_IN(TRUE)
RETURN TRUE
ENDIF
RETURN FALSE
ENDFUNC
FUNC BOOL TWS_HANDLE_TITLE_SCREEN()
BOOL bLeft, bRight
INT iCurrentOption
FLOAT fRightStickX = 0.0
FLOAT fAxisThresholdMod = 0.5
IF (sTWSData.eCurrentMenuOption = TWS_MENU_BEGIN_ADVENTURE AND sTWSData.iMenuOptionSpriteAnim != ciTWS_MENU_OPTIONS_BEGIN_FRAME)
OR (sTWSData.eCurrentMenuOption = TWS_MENU_LEADERBOARD AND sTWSData.iMenuOptionSpriteAnim != ciTWS_MENU_OPTIONS_LEADERBOARD_FRAME)
OR (sTWSData.eCurrentMenuOption = TWS_MENU_GROG_MODE AND sTWSData.iMenuOptionSpriteAnim != ciTWS_MENU_OPTIONS_GROG_FRAME)
IF sTWSData.bMenuOptionMovingToRight
sTWSData.iMenuOptionSpriteAnim += sTWSData.iGlobalDefaultUpdateFrames
ELSE
sTWSData.iMenuOptionSpriteAnim -= sTWSData.iGlobalDefaultUpdateFrames
ENDIF
IF sTWSData.iMenuOptionSpriteAnim < 0
sTWSData.iMenuOptionSpriteAnim = 14
ELIF sTWSData.iMenuOptionSpriteAnim >= 15
sTWSData.iMenuOptionSpriteAnim = 0
ENDIF
ENDIF
SWITCH sTWSData.eTitleStage
CASE TWS_TITLE_PRESS_START
IF TWS_IS_ANY_ACCEPT_BUTTON_PRESSED()
sTWSData.eTitleStage = TWS_TITLE_SELECT_OPTION
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MENU_SELECT)
ENDIF
BREAK
CASE TWS_TITLE_SELECT_OPTION
// Joystick
bLeft = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_LEFT) OR IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_LEFT)
bRight = IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_PAD_RIGHT) OR IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_FRONTEND_RIGHT)
fRightStickX = GET_DISABLED_CONTROL_NORMAL(FRONTEND_CONTROL, INPUT_SCRIPT_LEFT_AXIS_X)
IF fRightStickX < -cfSTICK_THRESHOLD * fAxisThresholdMod AND GET_GAME_TIMER() - sTWSData.iGameTimer > 150
bLeft = TRUE
sTWSData.iGameTimer = GET_GAME_TIMER()
ELIF fRightStickX > cfSTICK_THRESHOLD * fAxisThresholdMod AND GET_GAME_TIMER() - sTWSData.iGameTimer > 150
bRight = TRUE
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
IF bLeft
iCurrentOption = ENUM_TO_INT(sTWSData.eCurrentMenuOption) -1
IF iCurrentOption < 0
iCurrentOption = ENUM_TO_INT(TWS_MAX_MENU_OPTIONS) -1
ELSE
iCurrentOption = iCurrentOption % ENUM_TO_INT(TWS_MAX_MENU_OPTIONS)
ENDIF
sTWSData.eCurrentMenuOption = INT_TO_ENUM(TWS_MENU_OPTION, iCurrentOption)
sTWSData.bMenuOptionMovingToRight = FALSE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MENU_NAVIGATE)
ELIF bRight
iCurrentOption = (ENUM_TO_INT(sTWSData.eCurrentMenuOption) + 1) % ENUM_TO_INT(TWS_MAX_MENU_OPTIONS)
sTWSData.eCurrentMenuOption = INT_TO_ENUM(TWS_MENU_OPTION, iCurrentOption)
sTWSData.bMenuOptionMovingToRight = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MENU_NAVIGATE)
ELIF TWS_IS_ANY_ACCEPT_BUTTON_PRESSED()
IF sTWSData.eCurrentMenuOption = TWS_MENU_GROG_MODE AND NOT sTWSData.bNormalModeIsCompleted
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_WEAPON_DEFLECT_ARROW)
ELSE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_MENU_SELECT)
sTWSData.eTitleStage = TWS_TITLE_OPTION_BLINKING
sTWSData.iGameTimer = GET_GAME_TIMER()
ENDIF
ENDIF
BREAK
CASE TWS_TITLE_OPTION_BLINKING
IF GET_GAME_TIMER() - sTWSData.iGameTimer > 1000
sTWSData.eTitleStage = TWS_TITLE_FADE
TWS_FADE_OUT()
ENDIF
BREAK
CASE TWS_TITLE_FADE
IF TWS_IS_SCREEN_FADED_OUT()
sTWSData.eTitleStage = TWS_TITLE_PRESS_START
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
PROC TWS_INIT_MENU_VARIABLES()
sTWSData.fMenuBackgroundPosX[0] = cfTWS_MENU_BACKGROUND_TILE_WIDTH/2
sTWSData.fMenuBackgroundPosX[1] = sTWSData.fMenuBackgroundPosX[0] + cfTWS_MENU_BACKGROUND_TILE_WIDTH
sTWSData.rgbaFade.iA = 0
IF GET_PACKED_STAT_BOOL(PACKED_MP_BOOL_ARCADE_GROG_MODE_DEACTIVATED)
CPRINTLN(DEBUG_MINIGAME, "TWS - Grog mode is unlocked!")
sTWSData.bNormalModeIsCompleted = TRUE
ENDIF
ENDPROC
FUNC BOOL TWS_HANDLE_CUTSCENE_UPDATE()
IF NOT sTWSData.sCutsceneData.bShouldCutscenePlay
RETURN TRUE
ENDIF
IF TWS_IS_ANY_ACCEPT_BUTTON_PRESSED() AND (TWS_IS_SCREEN_FADED_IN() OR sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame > 0) AND sTWSData.eCurrentLevel != TWS_CASTLE_OUTRO
AND sTWSData.sCutsceneData.eGameplayCutsceneStage != TWS_CUTSCENE_FADE_OUT
sTWSData.sCutsceneData.iMaxCutsceneFrame = sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_FADE_OUT
TRIGGER_MUSIC_EVENT("ARCADE_WR_FADE")
ENDIF
SWITCH sTWSData.sCutsceneData.eGameplayCutsceneStage
CASE TWS_CUTSCENE_PAUSE
CDEBUG3LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] : TIMER: ",GET_GAME_TIMER() - sTWSData.iGameTimer, " FADE:", sTWSData.rgbaFade.iA)
IF GET_GAME_TIMER() - sTWSData.iGameTimer >= ciTWS_CUTSCENE_SHOT_TIME
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_FADE_IN
ENDIF
BREAK
CASE TWS_CUTSCENE_FADE_IN
IF TWS_IS_SCREEN_FADED_IN()
TEXT_LABEL_15 sSubtitles
IF sTWSData.eCurrentLevel = TWS_FOREST_INTRO
sSubtitles = "TWR_INTRO_S"
ELSE
sSubtitles = "TWR_OUTRO_S"
ENDIF
sSubtitles += (sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame)+1
PRINT_NOW(sSubtitles, 3000, 1)
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_PLAYING
ELIF NOT TWS_IS_SCREEN_FADING_IN()
IF sTWSData.eCurrentLevel = TWS_FOREST_INTRO
SWITCH sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame
CASE 0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_01)
BREAK
CASE 1
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_02)
BREAK
CASE 2
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_03)
BREAK
CASE 3
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_04)
BREAK
CASE 4
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_05)
BREAK
CASE 5
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_06)
BREAK
CASE 6
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_07)
BREAK
ENDSWITCH
ELSE
SWITCH sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame
CASE 0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_END_01)
BREAK
CASE 1
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_END_02)
BREAK
CASE 2
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_END_03)
BREAK
CASE 3
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SLIDESHOW_END_04)
BREAK
ENDSWITCH
ENDIF
TWS_FADE_IN()
ENDIF
BREAK
CASE TWS_CUTSCENE_PLAYING
IF GET_GAME_TIMER() - sTWSData.iGameTimer >= ciTWS_CUTSCENE_SHOT_TIME
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_FADE_OUT
ENDIF
BREAK
CASE TWS_CUTSCENE_FADE_OUT
IF TWS_IS_SCREEN_FADED_OUT()
IF sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame >= sTWSData.sCutsceneData.iMaxCutsceneFrame -1
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame = 0
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_PAUSE
TRIGGER_MUSIC_EVENT("ARCADE_WR_FADE")
RETURN TRUE
ELSE
sTWSData.sCutsceneData.iSpriteCutsceneAnimFrame ++
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_FADE_IN
ENDIF
ELIF NOT TWS_IS_SCREEN_FADING_OUT()
TWS_FADE_OUT()
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC BOOL TWS_HANDLE_MAP_SCREEN_UPDATE()
IF (NOT TWS_SHOULD_DISPLAY_MAP_IN_THIS_LEVEL()
OR IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RDOWN)
OR IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_SELECT)
OR IS_CONTROL_JUST_PRESSED(FRONTEND_CONTROL, INPUT_SCRIPT_RRIGHT))
AND sTWSData.sCutsceneData.eGameplayCutsceneStage != TWS_CUTSCENE_FADE_OUT
IF TWS_SHOULD_DISPLAY_MAP_IN_THIS_LEVEL() AND sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_PAUSE
SWITCH sTWSData.eCurrentLevel
CASE TWS_FOREST_INTRO
CASE TWS_FOREST
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_FOREST)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_FOREST)
TRIGGER_MUSIC_EVENT("ARCADE_WR_FOREST_START")
BREAK
CASE TWS_SWAMP
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_SWAMP)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_SWAMP)
TRIGGER_MUSIC_EVENT("ARCADE_WR_SWAMP_START")
BREAK
CASE TWS_CAVES
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_CAVE)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_CAVES)
TRIGGER_MUSIC_EVENT("ARCADE_WR_LABRYNTH_START")
BREAK
CASE TWS_CASTLE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_WIZARD_TOWER)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_CASTLE)
TRIGGER_MUSIC_EVENT("ARCADE_WR_CASTLE_START")
BREAK
ENDSWITCH
ENDIF
TWS_FADE_OUT()
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_FADE_OUT
ENDIF
CPRINTLN(DEBUG_MINIGAME, "Wizards Ruin - Updating map screen: ", sTWSData.sCutsceneData.eGameplayCutsceneStage, " | Is screen faded: ", TWS_IS_SCREEN_FADED_OUT())
SWITCH sTWSData.sCutsceneData.eGameplayCutsceneStage
CASE TWS_CUTSCENE_PAUSE
IF GET_GAME_TIMER() - sTWSData.iGameTimer > 2000
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_FADE_IN
SWITCH sTWSData.eCurrentLevel
CASE TWS_FOREST_INTRO
CASE TWS_FOREST
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_FOREST)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_FOREST)
TRIGGER_MUSIC_EVENT("ARCADE_WR_FOREST_START")
BREAK
CASE TWS_SWAMP
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_SWAMP)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_SWAMP)
TRIGGER_MUSIC_EVENT("ARCADE_WR_SWAMP_START")
BREAK
CASE TWS_CAVES
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_CAVE)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_CAVES)
TRIGGER_MUSIC_EVENT("ARCADE_WR_LABRYNTH_START")
BREAK
CASE TWS_CASTLE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_PLAYER_VOCAL_MAP_WIZARD_TOWER)
ARCADE_GAMES_SOUND_PLAY_LOOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_CASTLE)
TRIGGER_MUSIC_EVENT("ARCADE_WR_CASTLE_START")
BREAK
ENDSWITCH
ENDIF
BREAK
CASE TWS_CUTSCENE_FADE_IN
IF TWS_IS_SCREEN_FADED_IN()
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_PLAYING
sTWSData.iGameTimer = GET_GAME_TIMER()
ELIF NOT TWS_IS_SCREEN_FADING_IN()
TWS_FADE_IN()
ENDIF
BREAK
CASE TWS_CUTSCENE_PLAYING
IF GET_GAME_TIMER() - sTWSData.iGameTimer > 2000
TWS_FADE_OUT()
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_FADE_OUT
ENDIF
BREAK
CASE TWS_CUTSCENE_FADE_OUT
IF TWS_IS_SCREEN_FADED_OUT()
TWS_FADE_IN()
sTWSData.sCutsceneData.eGameplayCutsceneStage = TWS_CUTSCENE_PAUSE
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
FUNC TWS_ENEMY_TYPE TWS_GET_RANDOM_BATTLE_ENEMY(INT iSize)
SWITCH sTWSData.eCurrentLevel
CASE TWS_FOREST
INT iRandomEnemy
IF iSize = 0
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(0,2)
ELIF iSize = 1
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(2,5)
ELSE
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(0,4)
ENDIF
SWITCH iRandomEnemy
CASE 0
RETURN TWS_ENEMY_LEPRECHAUN
CASE 1
RETURN TWS_ENEMY_FAIRY
CASE 2
RETURN TWS_ENEMY_GRUNT_SPEAR
CASE 3
RETURN TWS_ENEMY_GRUNT_SWORD
CASE 4
RETURN TWS_ENEMY_GRUNT_CROSSBOW
ENDSWITCH
BREAK
CASE TWS_SWAMP
IF iSize = 0
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(0,1)
ELIF iSize = 1
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(1,3)
ELSE
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(1,5)
ENDIF
SWITCH iRandomEnemy
CASE 0
RETURN TWS_ENEMY_SLIME
CASE 1
RETURN TWS_ENEMY_GRUNT_SWORD
CASE 2
RETURN TWS_ENEMY_BRUTE_AXE
CASE 3
RETURN TWS_ENEMY_GRUNT_SPEAR
CASE 4
RETURN TWS_ENEMY_BRUTE_AXE
ENDSWITCH
BREAK
CASE TWS_CAVES
IF iSize = 0
IF GET_RANDOM_BOOL()
RETURN TWS_ENEMY_SPIDER
ELSE
RETURN TWS_ENEMY_SPIDER
ENDIF
ELSE
IF GET_RANDOM_BOOL()
RETURN TWS_ENEMY_GRUNT
ELSE
RETURN TWS_ENEMY_BRUTE
ENDIF
ENDIF
BREAK
CASE TWS_CASTLE
IF iSize = 0
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(0,1)
ELIF iSize = 1
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(0,3)
ELIF iSize = 2
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(3,5)
ELSE
iRandomEnemy = GET_RANDOM_INT_IN_RANGE(3,5)
ENDIF
SWITCH iRandomEnemy
CASE 0
RETURN TWS_ENEMY_BAT
CASE 1
CASE 2
RETURN TWS_ENEMY_BOULDER
CASE 3
RETURN TWS_ENEMY_GRUNT_FIRESPEAR
CASE 4
RETURN TWS_ENEMY_GRUNT_FIRESWORD
CASE 5
RETURN TWS_ENEMY_GRUNT_CASTER
ENDSWITCH
BREAK
ENDSWITCH
RETURN TWS_ENEMY_GRUNT
ENDFUNC
PROC TWS_HANDLE_BATTLE_POINTS()
IF sTWSData.bLockedScreen
IF sTWSData.bExitingLockedScreen
IF sPlayerData.vSpritePos.x > sTWSData.fLockedScreenPos
sTWSData.fLockedScreenPos = sTWSData.fLockedScreenPos +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ELSE
sTWSData.fLockedScreenPos = sTWSData.fLockedScreenPos -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
ENDIF
IF sPlayerData.vSpritePos.x > sTWSData.fLockedScreenPos -@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
AND sPlayerData.vSpritePos.x < sTWSData.fLockedScreenPos +@ cfTWS_HORIZONTAL_MOVEMENT_PLAYER*2
sTWSData.bExitingLockedScreen = FALSE
sTWSData.bLockedScreen = FALSE
sTWSData.iNumberOfEnemiesKilledInBattle = 0
sTWSData.iNumberOfEnemiesSpawnedInBattle = 0
ENDIF
ELIF sTWSData.iNumberOfEnemiesKilledInBattle >= sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies
sTWSData.bExitingLockedScreen = TRUE
sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].bActive = FALSE
ELIF sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].bSpawnEnemies
AND NOT TWS_IS_ANY_ENEMY_ON_SCREEN(TRUE)
AND GET_GAME_TIMER() - sTWSData.iGameTimer > ciTWS_BATTLE_SECURITY_TIME_LIMIT
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - WARNING! Something wrong happened in battle. Current battle: ", sTWSData.iNumberOfEnemiesSpawnedInBattle, " enemies spawned. ", sTWSData.iNumberOfEnemiesKilledInBattle, " enemies killed. ",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies, " is the objective.")
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Unlocking battle!")
sTWSData.iNumberOfEnemiesSpawnedInBattle = sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies
sTWSData.iNumberOfEnemiesKilledInBattle = sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies
ELIF sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].bSpawnEnemies AND GET_GAME_TIMER() - sTWSData.iBattleTimer > sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iSpawnTime AND sTWSData.iNumberOfEnemiesSpawnedInBattle < sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Current battle: ", sTWSData.iNumberOfEnemiesSpawnedInBattle, " enemies spawned. ", sTWSData.iNumberOfEnemiesKilledInBattle, " enemies killed. ",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies, " is the objective. Spawning one of size ", sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemySize)
TWS_ENEMY_TYPE enemyType
FLOAT spawnY
IF sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemySize = 0
enemyType = TWS_GET_RANDOM_BATTLE_ENEMY(sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemySize)
spawnY = GET_RANDOM_FLOAT_IN_RANGE(550.0,850.0)
IF enemyType = TWS_ENEMY_FAIRY
OR enemyType = TWS_ENEMY_SLIME
OR enemyType = TWS_ENEMY_BAT
spawnY = -50
ENDIF
IF TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sTWSData.fLockedScreenPos + GET_RANDOM_FLOAT_IN_RANGE(-600, 600), spawnY), enemyType, TRUE)
sTWSData.iNumberOfEnemiesSpawnedInBattle++
sTWSData.iBattleTimer = GET_GAME_TIMER()
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Spawned a ", TWS_ENEMY_TYPE_TO_STRING(enemyType), "(",sTWSData.iNumberOfEnemiesSpawnedInBattle,"/",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies,").")
ENDIF
ELSE
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Size: ",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemySize)
int iSide = 1
IF sTWSData.iNumberOfEnemiesSpawnedInBattle % 2 = 0
iSide = -1
ENDIF
enemyType = TWS_GET_RANDOM_BATTLE_ENEMY(sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemySize)
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Random enemy is a ", TWS_ENEMY_TYPE_TO_STRING(enemyType))
IF sTWSData.eCurrentLevel = TWS_CAVES
spawnY = cfBASE_SCREEN_HEIGHT*0.55
ELSE
spawnY = GET_RANDOM_FLOAT_IN_RANGE(550.0,850.0)
ENDIF
SWITCH enemyType
CASE TWS_ENEMY_FAIRY
CASE TWS_ENEMY_SLIME
CASE TWS_ENEMY_BAT
spawnY = -50
IF TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sTWSData.fLockedScreenPos + GET_RANDOM_FLOAT_IN_RANGE(-600, 600), spawnY), enemyType, TRUE)
sTWSData.iNumberOfEnemiesSpawnedInBattle++
sTWSData.iBattleTimer = GET_GAME_TIMER()
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Spawned a ", TWS_ENEMY_TYPE_TO_STRING(enemyType), "(",sTWSData.iNumberOfEnemiesSpawnedInBattle,"/",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies,").")
ENDIF
BREAK
CASE TWS_ENEMY_BRUTE
CASE TWS_ENEMY_BRUTE_AXE
IF sPlayerData.bIsJumping
spawnY = sPlayerData.vInitialJumpPos.y - 30.0
ELSE
spawnY = sPlayerData.vSpritePos.y - 30.0
ENDIF
IF TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.6*iSide, spawnY), enemyType, TRUE)
sTWSData.iNumberOfEnemiesSpawnedInBattle++
sTWSData.iBattleTimer = GET_GAME_TIMER()
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Spawned a ", TWS_ENEMY_TYPE_TO_STRING(enemyType), "(",sTWSData.iNumberOfEnemiesSpawnedInBattle,"/",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies,").")
ENDIF
BREAK
CASE TWS_ENEMY_GRUNT
CASE TWS_ENEMY_GRUNT_CROSSBOW
CASE TWS_ENEMY_GRUNT_FIRESPEAR
CASE TWS_ENEMY_GRUNT_SPEAR
CASE TWS_ENEMY_GRUNT_FIRESWORD
CASE TWS_ENEMY_GRUNT_SWORD
IF sPlayerData.bIsJumping
spawnY = sPlayerData.vInitialJumpPos.y - 30.0
ELSE
spawnY = sPlayerData.vSpritePos.y - 30.0
ENDIF
IF TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.6*iSide, spawnY), enemyType, TRUE)
sTWSData.iNumberOfEnemiesSpawnedInBattle++
sTWSData.iBattleTimer = GET_GAME_TIMER()
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Spawned a ", TWS_ENEMY_TYPE_TO_STRING(enemyType), "(",sTWSData.iNumberOfEnemiesSpawnedInBattle,"/",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies,").")
ENDIF
BREAK
CASE TWS_ENEMY_BOULDER
iSide = 1
IF TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.6*iSide, spawnY), enemyType, TRUE)
sTWSData.iNumberOfEnemiesSpawnedInBattle++
sTWSData.iBattleTimer = GET_GAME_TIMER()
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Spawned a ", TWS_ENEMY_TYPE_TO_STRING(enemyType), "(",sTWSData.iNumberOfEnemiesSpawnedInBattle,"/",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies,").")
ENDIF
BREAK
DEFAULT
IF TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sTWSData.fLockedScreenPos + cfGAME_SCREEN_WIDTH*0.6*iSide, spawnY), enemyType, TRUE)
sTWSData.iNumberOfEnemiesSpawnedInBattle++
sTWSData.iBattleTimer = GET_GAME_TIMER()
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Spawned a ", TWS_ENEMY_TYPE_TO_STRING(enemyType), "(",sTWSData.iNumberOfEnemiesSpawnedInBattle,"/",sTWSData.sLockedBattles[sTWSData.iCurrentLockedBattle].iEnemies,").")
ENDIF
BREAK
ENDSWITCH
ENDIF
ENDIF
ELSE
// Check if player arrived to one of the battle points to lock screen
INT i
FOR i = 0 TO ciTWS_MAX_LOCKED_BATTLES-1
IF sTWSData.sLockedBattles[i].bActive AND sTWSData.sLockedBattles[i].iTile != -1 AND sPlayerData.vSpritePos.x > sBackgroundTilesData[sTWSData.sLockedBattles[i].iTile].fSpritePos
CPRINTLN(DEBUG_MINIGAME, "TWS - LOCKED BATTLE - Init Battle. ID: ",i, " Number of enemies to spawn: ", sTWSData.sLockedBattles[i].iEnemies)
sTWSData.bLockedScreen = TRUE
sTWSData.bExitingLockedScreen = FALSE
sTWSData.iCurrentLockedBattle = i
sTWSData.iNumberOfEnemiesKilledInBattle = 0
sTWSData.iNumberOfEnemiesSpawnedInBattle = 0
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.fLockedScreenPos = sPlayerData.vSpritePos.x
BREAKLOOP
ENDIF
ENDFOR
ENDIF
ENDPROC
PROC TWS_INIT_HELP_TEXT_VARIABLES()
sTWSData.iHelpTextTimer = GET_GAME_TIMER()
ENDPROC
PROC TWS_HANDLE_HELP_TEXTS()
IF sTWSData.eCurrentLevel = TWS_FOREST
IF NOT sTWSData.bShowedTextHelp[TWS_TH_MOVE]
IF GET_GAME_TIMER() - sTWSData.iHelpTextTimer > 4000
ARCADE_GAMES_HELP_TEXT_PRINT(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_MOVE)
sTWSData.bShowedTextHelp[TWS_TH_MOVE] = TRUE
CPRINTLN(DEBUG_MINIGAME, "TWR - Help Text TWS_TH_MOVE activated")
ENDIF
ENDIF
IF NOT sTWSData.bShowedTextHelp[TWS_TH_ATTACK]
IF TWS_IS_ANY_ENEMY_ON_SCREEN() AND sTWSData.bShowedTextHelp[TWS_TH_MOVE]
ARCADE_GAMES_HELP_TEXT_PRINT(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_ATTACK)
sTWSData.bShowedTextHelp[TWS_TH_ATTACK] = TRUE
CPRINTLN(DEBUG_MINIGAME, "TWR - Help Text TWS_TH_ATTACK activated")
ENDIF
ENDIF
IF NOT sTWSData.bShowedTextHelp[TWS_TH_JUMP]
IF TWS_IS_ENEMY_OF_TYPE_ON_SCREEN(TWS_ENEMY_LEPRECHAUN) AND sTWSData.bShowedTextHelp[TWS_TH_ATTACK]
ARCADE_GAMES_HELP_TEXT_PRINT(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_JUMP)
sTWSData.bShowedTextHelp[TWS_TH_JUMP] = TRUE
CPRINTLN(DEBUG_MINIGAME, "TWR - Help Text TWS_TH_JUMP activated")
ENDIF
ENDIF
IF NOT sTWSData.bShowedTextHelp[TWS_TH_DASH]
IF sPlayerData.fMagic > 0.25 AND sTWSData.bShowedTextHelp[TWS_TH_JUMP]
ARCADE_GAMES_HELP_TEXT_PRINT(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_DASH)
sTWSData.bShowedTextHelp[TWS_TH_DASH] = TRUE
CPRINTLN(DEBUG_MINIGAME, "TWR - Help Text MoTWS_TH_DASHve activated")
ENDIF
ENDIF
IF NOT sTWSData.bShowedTextHelp[TWS_TH_JUMP_ATTACK]
IF TWS_IS_ENEMY_OF_TYPE_ON_SCREEN(TWS_ENEMY_FAIRY) AND sTWSData.bShowedTextHelp[TWS_TH_DASH]
ARCADE_GAMES_HELP_TEXT_PRINT(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_JUMP_ATTACK)
sTWSData.bShowedTextHelp[TWS_TH_JUMP_ATTACK] = TRUE
CPRINTLN(DEBUG_MINIGAME, "TWR - Help Text TWS_TH_JUMP_ATTACK activated")
ENDIF
ENDIF
IF NOT sTWSData.bShowedTextHelp[TWS_TH_MAGIC]
IF TWS_IS_ANY_ENEMY_ON_SCREEN() AND sPlayerData.fMagic > 0.50 AND sTWSData.bShowedTextHelp[TWS_TH_JUMP_ATTACK]
ARCADE_GAMES_HELP_TEXT_PRINT(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_MAGIC)
sTWSData.bShowedTextHelp[TWS_TH_MAGIC] = TRUE
CPRINTLN(DEBUG_MINIGAME, "TWR - Help Text TWS_TH_MAGIC activated")
ENDIF
ENDIF
IF NOT sTWSData.bShowedTextHelp[TWS_TH_EVOLUTION]
IF sPlayerData.fMagic >= 1.0 AND sTWSData.bShowedTextHelp[TWS_TH_MAGIC]
ARCADE_GAMES_HELP_TEXT_PRINT(ARCADE_GAMES_HELP_TEXT_ENUM_TWR_HELP_EVOLUTION, 10000)
sTWSData.bShowedTextHelp[TWS_TH_EVOLUTION] = TRUE
CPRINTLN(DEBUG_MINIGAME, "TWR - Help Text TWS_TH_EVOLUTION activated")
ENDIF
ENDIF
ENDIF
ENDPROC
PROC TWS_HANDLE_AWARDS()
TWS_SET_CHALLENGE_VALUE(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM, sPlayerData.iScore)
TWS_SET_CHALLENGE_VALUE(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM, sPlayerData.iTreasures)
ENDPROC
FUNC BOOL TWS_HANDLE_LEVEL_UPDATE()
#IF IS_DEBUG_BUILD
IF sTWSData.bShouldReloadLevel
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_FOREST)
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_SWAMP)
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_CAVES)
ARCADE_GAMES_SOUND_STOP(ARCADE_GAMES_SOUND_TWR_AMBIENCE_LOOP_CASTLE)
sTWSData.eCurrentLevel = INT_TO_ENUM(TWS_LEVEL, sTWSData.iReloadLevel)
sTWSData.bShouldReloadLevel = FALSE
RETURN TRUE
ENDIF
#ENDIF
SWITCH sTWSData.eLevelStage
CASE TWS_LEVEL_PLAYING
TWS_HANDLE_HELP_TEXTS()
IF TWS_IS_NPC_CUTSCENE_LEVEL() AND sPlayerData.ePlayerState != TWS_INTRO
sHUDData[TWS_HUD_END].bActive = FALSE
SWITCH sTWSData.eCurrentLevel
CASE TWS_FOREST_INTRO
TWS_START_DIALOGUE(0, 3)
BREAK
ENDSWITCH
sTWSData.eLevelStage = TWS_LEVEL_FINAL_DIALOGUE
ELIF sPlayerData.vSpritePos.x > sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
PREPARE_MUSIC_EVENT("ARCADE_WR_STAGE_END")
TRIGGER_MUSIC_EVENT("ARCADE_WR_BOSS_START")
IF sTWSData.eCurrentLevel = TWS_CASTLE AND NOT sTWSData.bIsHardCoreMode
TRIGGER_MUSIC_EVENT("ARCADE_WR_WIZARD_FIGHT_START")
sTWSData.eLevelStage = TWS_LEVEL_DIALOGUE_PRE_FIGHT
sTWSData.eGrogEncounterState = TWS_LOCK_SCREEN
ELIF sTWSData.eCurrentLevel = TWS_CASTLE AND sTWSData.bIsHardCoreMode
TRIGGER_MUSIC_EVENT("ARCADE_WR_WIZARD_FIGHT_START")
sTWSData.eLevelStage = TWS_LEVEL_BOSS_FIGHT
ELIF sTWSData.eCurrentLevel != TWS_CASTLE
sTWSData.eLevelStage = TWS_LEVEL_BOSS_FIGHT
ENDIF
TWS_KILL_ALL_ENEMIES()
ELSE
TWS_HANDLE_BATTLE_POINTS()
ENDIF
BREAK
CASE TWS_LEVEL_DIALOGUE_PRE_FIGHT
SWITCH sTWSData.eGrogEncounterState
CASE TWS_LOCK_SCREEN
sTWSData.bLockedScreen = TRUE
sTWSData.fLockedScreenPos = sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos
TWS_TASK_PLAYER_TO_MOVE_LEFT()
TWS_CREATE_FX(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos, -50), TWS_FX_GROG_BUBBLE, 600)
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.eGrogEncounterState = TWS_GROG_DESCENDS
BREAK
CASE TWS_GROG_DESCENDS
IF NOT sPlayerData.bIsMovingLeft AND GET_GAME_TIMER() - sTWSData.iGameTimer > 1000
TWS_START_DIALOGUE(21,21)
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.eGrogEncounterState = TWS_THOG_DIALOGUE_1
ENDIF
BREAK
CASE TWS_THOG_DIALOGUE_1
IF HAS_CURRENT_DIALOGUE_ENDED() AND GET_GAME_TIMER() - sTWSData.iGameTimer > 1000
TWS_ADD_ENEMY_TO_LIST(INIT_VECTOR_2D(sTWSData.fLockedScreenPos + 500, - 500), TWS_ENEMY_DIALOGUE_WIZARD)
TWS_START_DIALOGUE(17,18)
sTWSData.eGrogEncounterState = TWS_GROG_LEAVES
ENDIF
BREAK
CASE TWS_GROG_LEAVES
IF HAS_CURRENT_DIALOGUE_ENDED()
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.eGrogEncounterState = TWS_FIGHT_START
ENDIF
BREAK
CASE TWS_FIGHT_START
IF NOT TWS_IS_ANY_ENEMY_ON_SCREEN() AND GET_GAME_TIMER() - sTWSData.iGameTimer > 1000
sTWSData.eLevelStage = TWS_LEVEL_BOSS_FIGHT
sTWSData.bLockedScreen = FALSE
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_LEVEL_BOSS_FIGHT
IF sEnemyData[sTWSData.iBossEnemyIndex].fHealth <= 0.0 AND sEnemyData[sTWSData.iBossEnemyIndex].eEnemyState = TWS_ENEMY_DEAD
TWS_KILL_ALL_ENEMIES()
TWS_HANDLE_AWARDS()
TWS_TASK_PLAYER_TO_MOVE_TO_CENTER()
sTWSData.eLevelStage = TWS_LEVEL_LEADERBOARD
sTWSData.iHealthPoints = ROUND(sPlayerData.fHealth*10)*1000
sTWSData.iLivesPoints = sPlayerData.iLifes*1000
sTWSData.iBattleTimer = sPlayerData.iScore + (ROUND(sPlayerData.fHealth*10)*1000 +(sPlayerData.iLifes*1000))
sHUDData[TWS_HUD_END].bActive = TRUE
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_STAGE_START_SHING)
TRIGGER_MUSIC_EVENT("ARCADE_WR_STAGE_END")
DEGENATRON_GAMES_ANIMATION_SET_STATE(DEGENATRON_GAMES_ANIMATION_STATE_WIN)
ENDIF
BREAK
CASE TWS_LEVEL_LEADERBOARD
IF sTWSData.iHealthPoints > 0
OR sTWSData.iLivesPoints > 0
IF sTWSData.iHealthPoints >= 50
sTWSData.iHealthPoints -= 50
sPlayerData.iScore += 50
ELIF sTWSData.iHealthPoints > 0
sTWSData.iHealthPoints --
sPlayerData.iScore ++
ELIF sTWSData.iLivesPoints >= 50
sTWSData.iLivesPoints -= 50
sPlayerData.iScore += 50
ELIF sTWSData.iLivesPoints > 0
sTWSData.iLivesPoints --
sPlayerData.iScore ++
ENDIF
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SCORE_COUNT)
IF TWS_IS_ANY_ACCEPT_BUTTON_PRESSED()
IF sTWSData.iHealthPoints > 0
sPlayerData.iScore += sTWSData.iHealthPoints
sTWSData.iHealthPoints = 0
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SCORE_COMPLETE)
ELSE
sTWSData.iHealthPoints = 0
sTWSData.iLivesPoints = 0
sPlayerData.iScore = sTWSData.iBattleTimer
sTWSData.iGameTimer = GET_GAME_TIMER()
TWS_ARCADE_GAMES_SOUND_PLAY(ARCADE_GAMES_SOUND_TWR_SCORE_COMPLETE)
ENDIF
ENDIF
IF sPlayerData.iScore > sPlayerData.iHighestScore
sPlayerData.iHighestScore = sPlayerData.iScore
ENDIF
ELIF TWS_IS_ANY_ACCEPT_BUTTON_PRESSED() AND GET_GAME_TIMER() - sTWSData.iGameTimer > 1000
sHUDData[TWS_HUD_END].bActive = FALSE
sTWSData.iGameTimer = GET_GAME_TIMER()
TWS_FADE_IN()
IF NOT sTWSData.bIsHardCoreMode
SWITCH sTWSData.eCurrentLevel
CASE TWS_FOREST
TWS_START_DIALOGUE(4, 7)
BREAK
CASE TWS_SWAMP
TWS_START_DIALOGUE(8, 12)
BREAK
CASE TWS_CAVES
TWS_START_DIALOGUE(13, 16)
BREAK
CASE TWS_CASTLE
TWS_START_DIALOGUE(19, 20)
SET_PACKED_STAT_BOOL(PACKED_MP_BOOL_ARCADE_GROG_MODE_DEACTIVATED, TRUE)
BREAK
ENDSWITCH
sTWSData.eLevelStage = TWS_LEVEL_FINAL_DIALOGUE
ELSE
sTWSData.eLevelStage = TWS_LEVEL_FADING
TWS_FADE_OUT()
TWS_TASK_PLAYER_TO_MOVE_OUT_OFF_SCREEN()
ENDIF
ENDIF
BREAK
CASE TWS_LEVEL_FINAL_DIALOGUE
IF HAS_CURRENT_DIALOGUE_ENDED()
IF sTWSData.eCurrentLevel >= TWS_CASTLE
sTWSData.eGrogEncounterState = TWS_LOCK_SCREEN
sTWSData.eLevelStage = TWS_LEVEL_DIALOGUE_POST_FIGHT
ELSE
sTWSData.eLevelStage = TWS_LEVEL_FADING
TWS_FADE_OUT()
TWS_TASK_PLAYER_TO_MOVE_OUT_OFF_SCREEN()
ENDIF
ENDIF
BREAK
CASE TWS_LEVEL_DIALOGUE_POST_FIGHT
SWITCH sTWSData.eGrogEncounterState
CASE TWS_LOCK_SCREEN
TWS_TASK_PLAYER_TO_MOVE_LEFT()
TWS_CREATE_FX(INIT_VECTOR_2D(sBackgroundTilesData[iCurrentBackgroundTileToAdd-1].fSpritePos, -50), TWS_FX_GROG_BUBBLE, 600)
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.eGrogEncounterState = TWS_GROG_DESCENDS
BREAK
CASE TWS_GROG_DESCENDS
IF NOT sPlayerData.bIsMovingLeft AND GET_GAME_TIMER() - sTWSData.iGameTimer > 1000
TWS_START_DIALOGUE(21,21)
sTWSData.iGameTimer = GET_GAME_TIMER()
sTWSData.eGrogEncounterState = TWS_THOG_DIALOGUE_1
ENDIF
BREAK
CASE TWS_THOG_DIALOGUE_1
IF HAS_CURRENT_DIALOGUE_ENDED() AND GET_GAME_TIMER() - sTWSData.iGameTimer > 2000
TWS_FADE_OUT()
sTWSData.eLevelStage = TWS_LEVEL_FADING
ENDIF
BREAK
ENDSWITCH
BREAK
CASE TWS_LEVEL_DEAD
IF GET_GAME_TIMER() - sTWSData.iGameTimer > 3000
TWS_FADE_OUT()
sHUDData[TWS_HUD_GAMEOVER].bActive = FALSE
sTWSData.eLevelStage = TWS_LEVEL_FADING
TRIGGER_MUSIC_EVENT("ARCADE_WR_STOP")
ENDIF
BREAK
CASE TWS_LEVEL_FADING
IF TWS_IS_SCREEN_FADED_OUT()
sTWSData.eLevelStage = TWS_LEVEL_COMPLETE
TWS_STOP_ALL_SOUND_LOOPS()
ENDIF
BREAK
CASE TWS_LEVEL_COMPLETE
IF GET_GAME_TIMER() - sTWSData.iGameTimer > 1000
sTWSData.eCurrentLevel = INT_TO_ENUM(TWS_LEVEL, (ENUM_TO_INT(sTWSData.eCurrentLevel) + 1) % ENUM_TO_INT(TWS_MAX_LEVELS))
IF sTWSData.eCurrentLevel > TWS_CASTLE_OUTRO
sTWSData.eCurrentLevel = TWS_CASTLE_OUTRO
ENDIF
RETURN TRUE
ENDIF
BREAK
ENDSWITCH
RETURN FALSE
ENDFUNC
PROC TWS_PROCESS_CLIENT_STATE_INIT()
// Global flag indicating the player is engaged in arcade game
g_bIsPlayerPlayingWizardsRuin = TRUE
ARCADE_CABINET_COMMON_INITIALIZATION()
ARCADE_GAMES_POSTFX_INIT(CASINO_ARCADE_GAME_THE_WIZARDS_RUIN)
ARCADE_GAMES_SOUND_INIT(CASINO_ARCADE_GAME_THE_WIZARDS_RUIN)
TWS_INIT_COLOUR_STRUCTS()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_REQUESTING_ASSETS)
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS()
IF NOT ARCADE_GAMES_POSTFX_REQUESTING_ASSETS()
EXIT
ENDIF
IF NOT ARCADE_GAMES_SOUND_REQUESTING_AUDIO_BANK("DLC_HEIST3/H3_ArcMac_Wiz_01")
EXIT
ENDIF
IF NOT ARCADE_GAMES_SOUND_REQUESTING_AUDIO_BANK("DLC_HEIST3/H3_ArcMac_Wiz_02")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveBackgrounds12")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveBackgrounds12")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveBackgrounds12")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveBackgrounds34")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveBackgrounds34")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveBackgrounds34")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveCharacters")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveCharacters")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveCharacters")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveEnemies1a")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveEnemies1a")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveEnemies1a")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveEnemies1b")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveEnemies1b")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveEnemies1b")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveEnemies2")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveEnemies2")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveEnemies2")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveEnemies3a")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveEnemies3a")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveEnemies3a")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveEnemies3b")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveEnemies3b")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveEnemies3b")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveEnemies4a")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveEnemies4a")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveEnemies4a")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveEnemies4b")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveEnemies4b")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveEnemies4b")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveFacade")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveFacade")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveFacade")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveGrog")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveGrog")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveGrog")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveHUDAndScreen")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveHUDAndScreen")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveHUDAndScreen")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveHUDAndScreen2")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveHUDAndScreen2")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveHUDAndScreen")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveIntro")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveIntro")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveIntro")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveIntroMenu")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveIntroMenu")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveIntroMenu")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveItemsAndFX")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveItemsAndFX")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveItemsAndFX")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveThog12")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveThog12")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveThog12")
EXIT
ENDIF
REQUEST_STREAMED_TEXTURE_DICT("MPWizardsSleeveThog3NPC")
IF NOT HAS_STREAMED_TEXTURE_DICT_LOADED("MPWizardsSleeveThog3NPC")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [GD] TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS - Loading MPWizardsSleeveThog3NPC")
EXIT
ENDIF
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_FIB_WARNING)
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_FIB_WARNING()
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_FIB_WARNING)
IF TWS_HANDLE_FIB_WARNING()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_PIXTRO_LOGO)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_PIXTRO_LOGO()
IF TWS_HANDLE_PIXTRO_LOGO()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INIT_MENU)
TWS_INIT_TELEMETRY(TRUE)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_INIT_MENU()
TWS_INIT_MENU_VARIABLES()
ARCADE_GAMES_AUDIO_SCENE_START(TWR_AUDIO_SCENE_MENU)
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_GAMEPLAY)
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INIT_MENU)
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_TITLE_ANIM)
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_TITLE_ANIM()
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_TITLE_ANIM)
IF TWS_HANDLE_TITLE_ANIM()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_TITLE_SCREEN)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_TITLE_SCREEN()
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_TITLE_SCREEN)
IF TWS_HANDLE_TITLE_SCREEN()
SWITCH sTWSData.eCurrentMenuOption
CASE TWS_MENU_BEGIN_ADVENTURE
TWS_INIT_NORMAL_MODE()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INIT_LEVEL)
BREAK
CASE TWS_MENU_LEADERBOARD
TWS_FADE_IN()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_LEADERBOARD)
BREAK
CASE TWS_MENU_GROG_MODE
TWS_INIT_HARDCORE_MODE()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INIT_LEVEL)
BREAK
ENDSWITCH
ENDIF
ENDPROC
// Process INIT LEVEL
PROC TWS_PROCESS_CLIENT_STATE_INIT_LEVEL()
TWS_CLEANUP_VARIABLES()
TWS_INIT_PLAYERS()
TWS_INIT_FAR_BACKGROUND()
TWS_INIT_BACKGROUND()
TWS_INIT_FOREGROUND()
TWS_INIT_NPCS()
TWS_INIT_ENEMIES()
TWS_INIT_LOCKED_BATTLES()
TWS_INIT_TRAPS()
TWS_INIT_ITEMS()
TWS_INIT_HUD_ITEMS()
TWS_INIT_LEVEL_VARIABLES()
TWS_QUICK_SORT_ENTITIES(sTWSData.sDrawCalls, 0, ciTWS_MAX_DRAW_CALLS-1)
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INIT_LEVEL)
ARCADE_GAMES_HELP_TEXT_CLEAR()
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_MENU)
ARCADE_GAMES_AUDIO_SCENE_START(TWR_AUDIO_SCENE_GAMEPLAY)
IF sTWSData.bIsHardCoreMode
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_MAP_SCREEN)
ELSE
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INTRO_CUTSCENE)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_INTRO_CUTSCENE()
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INTRO_CUTSCENE)
IF TWS_HANDLE_CUTSCENE_UPDATE()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_MAP_SCREEN)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_OUTRO_CUTSCENE()
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_OUTRO_CUTSCENE)
IF TWS_HANDLE_CUTSCENE_UPDATE()
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_GAMEPLAY)
ARCADE_GAMES_AUDIO_SCENE_START(TWR_AUDIO_SCENE_MENU)
TWS_FADE_IN()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_LEADERBOARD)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_MAP_SCREEN()
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_MAP_SCREEN)
IF TWS_HANDLE_MAP_SCREEN_UPDATE()
TWS_INIT_HELP_TEXT_VARIABLES()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_PLAYING)
DEGENATRON_GAMES_ANIMATION_SET_STATE(DEGENATRON_GAMES_ANIMATION_STATE_PLAYING)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_LEADERBOARD()
ARCADE_GAMES_LEADERBOARD_PROCESS_ENTRY(sPlayerData.iScore)
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_LEADERBOARD)
IF NOT sAGLeaderboardData.bEditing AND TWS_IS_CANCEL_BUTTON_PRESSED()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INIT_MENU)
ENDIF
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_PLAYING()
TWS_HANDLE_PLAYER_MOVEMENT()
TWS_HANDLE_PLAYER_STATE()
TWS_HANDLE_ENEMY_STATE()
TWS_HANDLE_ITEM_STATE()
TWS_HANDLE_FX()
TWS_HANDLE_SCREEN_EFFECTS()
TWS_HANDLE_HUD()
TWS_HANDLE_DIALOGUE()
TWS_RELEASE_FINISHED_SOUNDS()
TWS_UPDATE_Z_INDEXES()
TWS_DRAW_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_PLAYING)
IF TWS_HANDLE_LEVEL_UPDATE()
IF sPlayerData.iLifes <= 0
sTWSData.eCurrentLevel = TWS_FOREST_INTRO
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_GAMEPLAY)
ARCADE_GAMES_AUDIO_SCENE_START(TWR_AUDIO_SCENE_MENU)
TRIGGER_MUSIC_EVENT("ARCADE_WR_THEME_START")
TWS_FADE_IN()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_LEADERBOARD)
DEGENATRON_GAMES_ANIMATION_SET_STATE(DEGENATRON_GAMES_ANIMATION_STATE_IDLE)
TWS_COLLECT_DATA_FOR_TELEMETRY_AFTER_LEVEL(TRUE)
TWS_SEND_TELEMETRY()
ELIF sTWSData.eCurrentLevel = TWS_CASTLE_OUTRO
IF sTWSData.bIsHardCoreMode
TWS_SET_CHALLENGE_VALUE(TWS_CHALLENGE_BIT_FEELIN_GROGGY, 1)
TWS_FADE_IN()
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_GAMEPLAY)
ARCADE_GAMES_AUDIO_SCENE_START(TWR_AUDIO_SCENE_MENU)
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_LEADERBOARD)
ELSE
sTWSData.bNormalModeIsCompleted = TRUE
sTWSData.sCutsceneData.bShouldCutscenePlay = TRUE
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_OUTRO_CUTSCENE)
ENDIF
TRIGGER_MUSIC_EVENT("ARCADE_WR_THEME_START")
DEGENATRON_GAMES_ANIMATION_SET_STATE(DEGENATRON_GAMES_ANIMATION_STATE_WIN_BIG)
TWS_COLLECT_DATA_FOR_TELEMETRY_AFTER_LEVEL(TRUE)
TWS_SEND_TELEMETRY()
ELSE
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_INIT_LEVEL)
DEGENATRON_GAMES_ANIMATION_SET_STATE(DEGENATRON_GAMES_ANIMATION_STATE_IDLE)
ENDIF
ENDIF
ENDPROC
PROC TWS_CLEANUP_AND_EXIT_CLIENT()
CDEBUG1LN(DEBUG_MINIGAME, "[Wizards Ruin] [JS] - EXAMPLE_CLEANUP_AND_EXIT_CLIENT - Cleaning up and terminating the script")
g_bIsPlayerPlayingWizardsRuin = FALSE
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_MENU)
ARCADE_GAMES_AUDIO_SCENE_STOP(TWR_AUDIO_SCENE_GAMEPLAY)
TWS_CLEAN_UP_MOVIE(sTWSData.bmIDPixtroIntro)
TRIGGER_MUSIC_EVENT("ARCADE_WR_STOP")
ARCADE_GAMES_HELP_TEXT_CLEAR()
sDGAnimationData.sArcadeCabinetAnimEvent.bLoopAnim = FALSE
PLAY_ARCADE_CABINET_ANIMATION(sDGAnimationData.sArcadeCabinetAnimEvent, ARCADE_CABINET_ANIM_CLIP_EXIT)
ARCADE_CABINET_COMMON_CLEANUP()
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveGrog")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveEnemies1a")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveEnemies1b")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveEnemies2")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveEnemies3a")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveEnemies3b")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveEnemies4a")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveEnemies4b")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveBackgrounds12")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveBackgrounds34")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveCharacters")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveHUDAndScreen")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveHUDAndScreen2")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveItemsAndFX")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveIntro")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveIntroMenu")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveFacade")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveThog12")
SET_STREAMED_TEXTURE_DICT_AS_NO_LONGER_NEEDED("MPWizardsSleeveThog3NPC")
ARCADE_GAMES_SOUND_RELEASE_AUDIO_BANK("DLC_HEIST3/H3_ArcMac_Wiz_01")
ARCADE_GAMES_SOUND_RELEASE_AUDIO_BANK("DLC_HEIST3/H3_ArcMac_Wiz_02")
TERMINATE_THIS_MULTIPLAYER_THREAD_NO_ARGS()
ENDPROC
PROC TWS_PROCESS_CLIENT_STATE_MACHINE()
SWITCH sTWSData.eClientState
CASE TWS_ARCADE_CLIENT_STATE_INIT
TWS_PROCESS_CLIENT_STATE_INIT()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_REQUESTING_ASSETS
TWS_PROCESS_CLIENT_STATE_REQUESTING_ASSETS()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_FIB_WARNING
TWS_PROCESS_CLIENT_STATE_FIB_WARNING()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_PIXTRO_LOGO
TWS_PROCESS_CLIENT_STATE_PIXTRO_LOGO()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_INIT_MENU
TWS_PROCESS_CLIENT_STATE_INIT_MENU()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_TITLE_ANIM
TWS_PROCESS_CLIENT_STATE_TITLE_ANIM()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_TITLE_SCREEN
TWS_PROCESS_CLIENT_STATE_TITLE_SCREEN()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_INIT_LEVEL
TWS_PROCESS_CLIENT_STATE_INIT_LEVEL()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_INTRO_CUTSCENE
TWS_PROCESS_CLIENT_STATE_INTRO_CUTSCENE()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_MAP_SCREEN
TWS_PROCESS_CLIENT_STATE_MAP_SCREEN()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_PLAYING
TWS_PROCESS_CLIENT_STATE_PLAYING()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_OUTRO_CUTSCENE
TWS_PROCESS_CLIENT_STATE_OUTRO_CUTSCENE()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_LEADERBOARD
TWS_PROCESS_CLIENT_STATE_LEADERBOARD()
BREAK
CASE TWS_ARCADE_CLIENT_STATE_CLEANUP
TWS_CLEANUP_AND_EXIT_CLIENT()
BREAK
ENDSWITCH
ENDPROC
#IF IS_DEBUG_BUILD
PROC TWS_DEBUG_SET_PARENT_WIDGET_GROUP(WIDGET_GROUP_ID parentWidgetGroup)
sTWSData.widgetGroup = parentWidgetGroup
ENDPROC
PROC TWS_DEBUG_CREATE_WIDGETS()
IF sTWSData.bDebugCreatedWidgets
EXIT
ENDIF
IF sTWSData.widgetGroup = NULL
EXIT
ENDIF
SET_CURRENT_WIDGET_GROUP(sTWSData.widgetGroup)
START_WIDGET_GROUP("TWS Arcade Widgets")
ADD_WIDGET_INT_READ_ONLY("iRectsDrawnThisFrame", iRectsDrawnThisFrame)
ADD_WIDGET_INT_READ_ONLY("iSpritesDrawnThisFrame", iSpritesDrawnThisFrame)
ADD_WIDGET_INT_READ_ONLY("iDebugLinesDrawnThisFrame", iDebugLinesDrawnThisFrame)
ADD_WIDGET_BOOL("Invincible player", sPlayerData.bIsInvincible)
ADD_WIDGET_BOOL("Infinite magic", sTWSData.bInfiniteMagic)
ADD_WIDGET_FLOAT_SLIDER("Magic Points", sPlayerData.fMagic, 0.0, 1.0, 0.05)
ADD_WIDGET_FLOAT_SLIDER("Health Points", sPlayerData.fHealth, 0.0, 1.0, 0.1)
ADD_WIDGET_INT_SLIDER("Player Lifes", sPlayerData.iLifes, 1, 10, 1)
ADD_WIDGET_INT_SLIDER("Player Level", sPlayerData.iLevel, 1, 8, 1)
ADD_WIDGET_INT_SLIDER("Player Score", sPlayerData.iScore, 0, 999999, 10)
ADD_WIDGET_INT_SLIDER("Player Treasures", sPlayerData.iTreasures, 0, 999999, 10)
ADD_WIDGET_FLOAT_READ_ONLY("Player Pos X", sPlayerData.vSpritePos.x)
ADD_WIDGET_FLOAT_READ_ONLY("Player Pos Y", sPlayerData.vSpritePos.Y)
ADD_WIDGET_FLOAT_SLIDER("Set Player Pos X", sPlayerData.vSpritePos.x, 0.0, 20000.0, 100.0)
ADD_WIDGET_INT_SLIDER("Current Enemies Killed in Locked Screen", sTWSData.iNumberOfEnemiesKilledInBattle, 0, 99, 1)
ADD_WIDGET_INT_SLIDER("Current Enemies Spawned in Locked Screen", sTWSData.iNumberOfEnemiesSpawnedInBattle, 0, 99, 1)
ADD_WIDGET_INT_SLIDER("Debug Go to Stage", sTWSData.iReloadLevel, 0, 4, 1)
ADD_WIDGET_BOOL("Reload selected stage",sTWSData.bShouldReloadLevel)
ADD_WIDGET_BOOL("Unlock Grog Mode",sTWSData.bNormalModeIsCompleted)
ADD_WIDGET_BOOL("Is Grog Mode",sTWSData.bIsHardCoreMode)
ADD_WIDGET_BOOL("Clear challenges",sTWSData.bChallengeCompleted[0])
ADD_WIDGET_BOOL("Challenge Feelin' Groggy",sTWSData.bChallengeCompleted[1])
ADD_WIDGET_BOOL("Challenge Platinum Sword",sTWSData.bChallengeCompleted[2])
ADD_WIDGET_BOOL("Challenge Coin Purse",sTWSData.bChallengeCompleted[3])
STOP_WIDGET_GROUP()
START_WIDGET_GROUP("Render")
ADD_WIDGET_BOOL("bBlockDrawing", g_bBlockArcadeCabinetDrawing)
ADD_WIDGET_BOOL("g_bMinimizeArcadeCabinetDrawing", g_bMinimizeArcadeCabinetDrawing)
ADD_WIDGET_INT_READ_ONLY("iRectsDrawnThisFrame", iRectsDrawnThisFrame)
ADD_WIDGET_INT_READ_ONLY("iSpritesDrawnThisFrame", iSpritesDrawnThisFrame)
ADD_WIDGET_INT_READ_ONLY("iDebugLinesDrawnThisFrame", iDebugLinesDrawnThisFrame)
STOP_WIDGET_GROUP()
ARCADE_GAMES_POSTFX_WIDGET_CREATE()
ARCADE_GAMES_SOUND_WIDGET_CREATE()
ARCADE_GAMES_LEADERBOARD_WIDGET_CREATE()
CLEAR_CURRENT_WIDGET_GROUP(sTWSData.widgetGroup)
sTWSData.bDebugCreatedWidgets = TRUE
ENDPROC
/// PURPOSE:
/// Dumps the current state of the game to the logs
/// Automatically called when a bug is entered
PROC TWS_DEBUG_DUMP_DATA_TO_LOGS()
ARCADE_CABINET_DUMP_DATA_TO_CONSOLE()
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [JS] TWS_DEBUG_DUMP_DATA_TO_LOGS - Dumping data...")
//General
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [JS] ----- GENERAL -----")
CDEBUG1LN(DEBUG_MINIGAME, "[TWS_ARCADE] [JS] eClientState = ", TWS_DEBUG_GET_TWS_ARCADE_CLIENT_STATE_AS_STRING(sTWSData.eClientState))
ENDPROC
PROC TWS_DEBUG_PROCESSING()
TWS_DEBUG_CREATE_WIDGETS()
IF sTWSData.bChallengeCompleted[0]
TWS_RESET_CHALLENGES()
sTWSData.bChallengeCompleted[0] = FALSE
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] challenges ",sTWSData.iChallengesBitsetForTelemetry)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_FEELIN_GROGGY: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_FEELIN_GROGGY)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)))
ENDIF
IF sTWSData.bChallengeCompleted[1]
TWS_SET_CHALLENGE_COMPLETED(TWS_CHALLENGE_BIT_FEELIN_GROGGY)
SET_BIT(sTWSData.iChallengesBitsetForTelemetry, ENUM_TO_INT(TWS_CHALLENGE_BIT_FEELIN_GROGGY))
sTWSData.bChallengeCompleted[1] = FALSE
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] challenges ",sTWSData.iChallengesBitsetForTelemetry)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_FEELIN_GROGGY: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_FEELIN_GROGGY)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)))
ENDIF
IF sTWSData.bChallengeCompleted[2]
TWS_SET_CHALLENGE_COMPLETED(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM)
SET_BIT(sTWSData.iChallengesBitsetForTelemetry, ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM))
sTWSData.bChallengeCompleted[2] = FALSE
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] challenges ",sTWSData.iChallengesBitsetForTelemetry)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_FEELIN_GROGGY: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_FEELIN_GROGGY)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)))
ENDIF
IF sTWSData.bChallengeCompleted[3]
TWS_SET_CHALLENGE_COMPLETED(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)
SET_BIT(sTWSData.iChallengesBitsetForTelemetry, ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM))
sTWSData.bChallengeCompleted[3] = FALSE
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] challenges ",sTWSData.iChallengesBitsetForTelemetry)
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_FEELIN_GROGGY: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_FEELIN_GROGGY)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_PLATINUM_SWORD: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_PLATINUM_SWORD_PLATINUM)))
CDEBUG1LN(DEBUG_MINIGAME, "[WIZARDS RUIN] - TWS_CHALLENGE_BIT_COIN_PURSE: ",IS_BIT_SET(sTWSData.iChallengesBitsetForTelemetry,ENUM_TO_INT(TWS_CHALLENGE_BIT_COIN_PURSE_PLATINUM)))
ENDIF
IF sTWSData.bDebugCreatedWidgets
ARCADE_GAMES_POSTFX_WIDGET_UPDATE()
ARCADE_GAMES_SOUND_WIDGET_UPDATE()
ARCADE_GAMES_LEADERBOARD_WIDGET_UPDATE()
//If a bug is entered dump all data to the console.
IF IS_KEYBOARD_KEY_PRESSED(KEY_SPACE)
OR IS_KEYBOARD_KEY_PRESSED(KEY_RBRACKET)
TWS_DEBUG_DUMP_DATA_TO_LOGS()
ENDIF
ENDIF
ENDPROC
#ENDIF
/// PURPOSE:
/// Returns true if the game should quit
/// Processes holding a button to quit
/// RETURNS:
///
FUNC BOOL TWS_SHOULD_QUIT_NOW()
IF g_bForceQuitPenthouseArcadeMachines
CDEBUG1LN(DEBUG_MINIGAME, "[TWS] TWS_SHOULD_QUIT_NOW - g_bForceQuitPenthouseArcadeMachines")
RETURN TRUE
ENDIF
IF IS_PLAYER_DOING_HELI_DOCK_CUTSCENE(GET_PLAYER_INDEX())
CDEBUG1LN(DEBUG_MINIGAME, "[TWS] TWS_SHOULD_QUIT_NOW - IS_PLAYER_DOING_HELI_DOCK_CUTSCENE")
RETURN TRUE
ENDIF
IF IS_LOCAL_PLAYER_WALKING_IN_OR_OUT_OF_SIMPLE_INTERIOR()
CDEBUG1LN(DEBUG_MINIGAME, "[TWS] TWS_SHOULD_QUIT_NOW - IS_LOCAL_PLAYER_WALKING_IN_OR_OUT_OF_SIMPLE_INTERIOR")
RETURN TRUE
ENDIF
IF SHOULD_KICK_PLAYER_FROM_ANY_ARCADE_GAME()
CDEBUG1LN(DEBUG_MINIGAME, "[TWS] TWS_SHOULD_QUIT_NOW - SHOULD_KICK_PLAYER_FROM_ANY_ARCADE_GAME")
RETURN TRUE
ENDIF
CONTROL_ACTION CA_Quit = INPUT_FRONTEND_CANCEL
IF IS_USING_KEYBOARD_AND_MOUSE(FRONTEND_CONTROL)
CA_Quit = INPUT_FRONTEND_DELETE
ENDIF
IF IS_CONTROL_PRESSED(FRONTEND_CONTROL, CA_Quit)
OR (IS_DISABLED_CONTROL_PRESSED(FRONTEND_CONTROL, CA_Quit))
DRAW_GENERIC_METER(ciTWS_HOLD_TO_QUIT_TIME - ABSI(NATIVE_TO_INT(GET_NETWORK_TIME()) - sTWSData.iQuitTime), ciTWS_HOLD_TO_QUIT_TIME, "DEG_GAME_QUIT")
ELSE
DRAW_GENERIC_METER(0, ciTWS_HOLD_TO_QUIT_TIME, "DEG_GAME_QUIT")
ENDIF
IF IS_DISABLED_CONTROL_PRESSED(FRONTEND_CONTROL, CA_Quit)
IF sTWSData.iQuitTime = -HIGHEST_INT
sTWSData.iQuitTime = NATIVE_TO_INT(GET_NETWORK_TIME()) + ciTWS_HOLD_TO_QUIT_TIME
ENDIF
//DRAW_GENERIC_METER(ciIAP_HOLD_TO_QUIT_TIME - (sIAPData.iQuitTime - NATIVE_TO_INT(GET_NETWORK_TIME())), ciIAP_HOLD_TO_QUIT_TIME, "IAP_EXIT", HUD_COLOUR_RED, -1, HUDORDER_TOP)
IF NATIVE_TO_INT(GET_NETWORK_TIME()) > sTWSData.iQuitTime
CDEBUG1LN(DEBUG_MINIGAME, "[TWS] TWS_SHOULD_QUIT_NOW - Button Held")
RETURN TRUE
ENDIF
ELIF sTWSData.iQuitTime != -HIGHEST_INT
sTWSData.iQuitTime = -HIGHEST_INT
ENDIF
RETURN FALSE
ENDFUNC
/// PURPOSE:
/// Run every frame before the client state machine is processed
PROC TWS_PRE_UPDATE()
IF sTWSData.eClientState >= TWS_ARCADE_CLIENT_STATE_CLEANUP
// Cleaning up, don't do anything
EXIT
ENDIF
IF NOT IS_SKYSWOOP_AT_GROUND()
OR TWS_SHOULD_QUIT_NOW()
TWS_SET_CLIENT_STATE(TWS_ARCADE_CLIENT_STATE_CLEANUP)
EXIT
ENDIF
TWS_UPDATE_ANIM_FRAMES()
ARCADE_GAMES_LEADERBOARD_PROCESS_EVENTS()
ARCADE_GAMES_LEADERBOARD_LOAD(CASINO_ARCADE_GAME_THE_WIZARDS_RUIN)
BOOL bIsPlaying = sTWSData.eClientState >= TWS_ARCADE_CLIENT_STATE_PLAYING
ARCADE_CABINET_COMMON_EVERY_FRAME_PROCESSING(bIsPlaying)
ENDPROC
/// PURPOSE:
/// Run every frame after the client state machine is processed
PROC TWS_POST_UPDATE()
//Hide help text every frame unless this minigame wants to show some
//See x:\gta5\script\dev_ng\shared\include\public\invade_persuade_main.sch IAP_SHOULD_ALLOW_HELP_TEXT_THIS_FRAME()
//Hide help text every frame unless this minigame wants to show some
IF NOT ARCADE_GAMES_HELP_TEXT_SHOULD_ALLOW_THIS_FRAME()
HIDE_HELP_TEXT_THIS_FRAME()
ENDIF
ENDPROC
/// PURPOSE:
/// Call every frame to run the minigame
PROC PROCESS_TWS_ARCADE()
TWS_PRE_UPDATE()
TWS_PROCESS_CLIENT_STATE_MACHINE()
DEGENATRON_GAMES_ANIMATION_UPDATE()
TWS_POST_UPDATE()
#IF IS_DEBUG_BUILD
TWS_DEBUG_PROCESSING()
#ENDIF
ENDPROC