-- Example mod to add effects to Tails' Khaos Kontraption.

-- NOTICE: You need to have Tails' Khaos Kontraption loaded before you add this, otherwise this will error out. --

--[[            -!- Documentation -!-
        Read here to learn more how to use this.

The basics here is that "TailsKK" is an exposed global variable, with the function "addEffect" that can let you add effects. Here's a go-over for all the options available for an effect's table:

-- MANDATORY --
name - Self-explanatory, it's what shows up in the HUD when the effect gets applied, the name given in the blacklist, and what shows up in "You Get The Bees" when it gives the player the effect.
chance - FRACUNIT divided by a number acts as the chance it will be to roll this number. For example, FRACUNIT/2 means 1/2th the time it gets rolled, it gets chosen as the effect.
duration - This is how long the effect will last, in seconds. If set to 0 or below, the timer will essentially be infinite.
etype - This is the type that the effect is, good, bad, or neutral. It changes it's border on the HUD, and other effects like "Lucky!" and "PANIC" can influence it's rolling odds.
func - This is where your main function that runs the effects goes. The values fed to the function are "player, selfid, value". The player is obvious, selfid is where in the index of player.khaoseffects this effect is currently located, and value contains all the table variables for the effect inside player.khaoseffects (basically, treat this as memory storage for the effect itself). Something to note is if you set "value.fxdone" to true, then the effect will immediately be removed in the next tic, and "endfunc" will be run if it exists.

-- OPTIONAL --
addition - In Amplify Mode only, this will add additional time to the duration. No fancy math here, just straight up addition.
amplifyname - Changes the name of the effect when Amplify Mode is enabled.
description - Gives a description of the effect when you use "tkk_What_Is" in the console. Write something helpful, but don't go overboard with what you detail!
drainrespawntimer - If set to true, this will have the timer still continue when the player is currently respawning. All effects have their timer not tick up during respawn otherwise.
endfunc - This is a function that uses the same values as func, but this runs right before the effect gets removed. Good for cleaning up anything done to the player that would otherwise be permanent.
forceend - Ditto but for removing effect.
forcestart - This forces the startsfx to play, regardless of if the HUD is enabled.
hudtextprefix - Adds a prefix to the text when it's added to a player's HUD. Basically, it just slaps some extra stuff behind the text. Useful when using the effects provided by l_fontlib.lua!
immune2remove - Can't be removed by "Remove Random Effect"
kartfunc - This is identical to "func", but it only runs if we're playing SRB2Kart. You're not required to make your mod compatible with SRB2Kart.
kartendfunc - Ditto but for "endfunc".
localsfx - This makes the starting and/or end sounds play only for the player, instead of broadcasting the sound from the player themself.
nohudtext - Doesn't show the text when it gets applied to the player. Useful if you want the name to be different when applied by using TailsKK.addHUDText(), or if you want the effect to be hidden from the player.
notimer - Don't show the timer text in the HUD.
range - With some Math, this will increase the range for how long effects actually last, depending on how big it is. It's a bit complicated to explain, so here's the code:
        local mintime = max(effect.duration - (effect.range/3), effect.duration/2 + 1) -- timer doesn't go below half the duration
        local maxtime = effect.duration + (effect.range + 2)
        duration = P_RandomRange(mintime, maxtime)
restartrespawn - If the player is currently respawning, the effects "value.started"... value, will be set to false.
sprite - This is the icon that will be shown on the HUD when the effect is in play. Despite the name, it actually uses Doom GFX, usually found in the "Graphics" folder in a PK3 file. It isn't recommended to use actual sprites or PNGs, due to some weird bugs that crop up from v.cachePatch, and maps with custom color palettes. If you need a placeholder icon, "KH_PLACEHOLDER" exists. !!IMPORTANT: Your icon will be pre-pended with "KH_" by the script! Use "noprepend" to change this!!
startsfx - This sets the sound that plays when the effect is applied, unless the HUD is disabled.
endsfx - Same as above, but for when an effect is removed.
kartstartsfx/kartendsfx - Ditto for both of the above, but only for SRB2Kart.

-- COMPATIBLE CHECKS --
- All except the first two are booleans that can be set to true, and if true, they'll require certain things to be true in order to get applied, or will be prevented from applying. -
incompatible - This is a table used to make sure this effect doesn't apply when an effect on this list is already applied to the player. Good for reining in the chaos just a smidge.
fxrequired - Requires that the player already has at least this many effects applied already. Note that the Roulette counts as an effect!
amplifyonly - Only applies if "Amplify Mode" is turned on. Good for seriously busted effects.
battleonly - Only applies in Battle/Egg Prisons mode.
dontrollme - This effect will not be rolled by the Roulette. Good for effects that get applied via other means than random chance.
grounded - Player needs to be on the ground.
nobattle - Won't apply in Battle/Egg Prisons mode.
nobees - Won't get rolled by the "You Get The Bees" universal effect.
noblacklist - Setting this will prevent this effect from being able to be added to a player's blacklist.
nobot - Doesn't apply if the player is a bot. Good for effects that are only visual, or ones that require cognisant player control.
nosrb2kart - Effect won't run if this is running under SRB2Kart. You're not required to make your mod compatible with SRB2Kart.
requirerings - Player needs 1 or more rings.
]]

--[[
         -!- Functions and Variables -!-
    This is a list of functions and variables
          found in the TailsKK varaible.

TailsKK.addEffect(table) - This adds your effect that you want, using all the information provided above. It's recommended to do "TailsKK.addEffect{name = "Silly, chance = FRACUNIT/2, incompatible = {"Bread", "Where's The Caveman?"}}", etc.
TailsKK.addUniversalEffect(table) - This lets you add your own Universal Effect to the game! This works in a similar way to addEffect, refer to how my code adds effects to see everything you need to do. Recommended voices are "Better S.A.M.", and Microsoft Sam from a real Windows XP (virtual) machine.
TailsKK.addHUDText(player, string, override, extend) - This adds text to the player's HUD. Override makes it so if the player's HUD is disabled, it will display anyways. And extend makes it so the text lasts longer on screen by this many seconds.
TailsKK.GlobalNonConflict(effectid) - Provided an effectID (index in the KhaosEffectsTable), this makes sure an effect is compatible with basic global parameters, such as gametype being compatible.
TailsKK.CheckNonConflict(player, effectid, ignoreotherincompats) - Provided with an ID, it will make sure this isn't incompatible with various things according to the compatibility checks. "ignoreotherincompats" is a number that's used to gradually ignore more and more incompatibilites, til the only thing it checks is if the effect is already applied.
TailsKK.ApplyEffect(player, effect, extravalues) - When provided an effectID or name of an effect, this will apply said effect to the player! "extravalues" is used to add extra values to the effect inside the player's khaos effects table.

TailsKK.version - Current version of Tails' Khaos Kontraption.
    TailsKK.versiontable - Table containing numbers for the version. i.e. version "1.2.3" would become {1, 2, 3}, first one is the major version, second one is the minor version, third is the sub-version.
TailsKK.attributions - Credits to all contributors/sources for this mod!
TailsKK.TextBoxTable - This is a table that contains the textboxes used for the "Hey! Listen!" effect. You can add your own ones here, if you want. An individual table holds pages of text, in which those pages are tables. The pages need to have 4 strings of text, if it doesn't, then this doesn't work. You can just set them to be blank if you're done with that page. There's also no word wrap, you need to do that yourself.

]]

-- If there's anything missing here that you feel like should be exposed here, feel free to reach out to me, and I'll consider adding it in whatever next version comes out.

-- A good idea is to do a quick test run on a map and save a replay with this effect in use (set the chance to FRACUNIT to guarantee it gets rolled), just to make sure this works. If it doesn't, chances are this won't work in net games, and something is getting desynchronized.

  TailsKK.addEffect{name = "Timebomb", chance = FRACUNIT/38, duration = 3, addition = -1, sprite = "BOMBZ", etype = "bad",
startsfx = sfx_s3k5c,
func = function(player, selfid, value)
    if not value.started then
        value.repeatsound = 1
        value.subtracttime = 8
        value.sublimetime = 3
        value.defaulttimer = value.duration*TICRATE - value.timer
        value.started = true
    end

    local function SpawnSplode(x, y, z)
        local theobj = MT_SONIC3KBOSSEXPLODE
        if P_RandomChance(FRACUNIT/5) then
            theobj = MT_BOSSEXPLODE
        end
        local Sperk = P_SpawnMobj(player.mo.x + x*2, player.mo.y + y*3, player.mo.z + z/4, theobj)
        Sperk.scale = player.mo.scale
        Sperk.momx = x * 2
        Sperk.momy = y * 2
        Sperk.momz = z * 5
    end

    local function Blinker()
        if not value.back then
            player.mo.colorized = true
            value.prevcolor = player.mo.color
            player.mo.color = SKINCOLOR_RED
            value.back = true
        else
            player.mo.colorized = false
            player.mo.color = value.prevcolor
            value.back = false
        end
    end

    SpawnSplode(P_RandomFixed()*2, P_RandomFixed()*3, P_RandomFixed()*2)

    if value.defaulttimer > (value.duration*TICRATE - value.timer) - value.repeatsound then -- beeping
        value.repeatsound = $ - value.subtracttime
        value.sublimetime = $ - 1
        if value.sublimetime <= 0 then
            value.sublimetime = 3
            value.subtracttime = $ - 1
        end
        S_StartSound(player.mo, sfx_deton)
        Blinker()
    end

    if value.duration*TICRATE - value.timer == TICRATE/2 + TICRATE/3 then
        S_StartSound(player.mo, sfx_s3k86)
    end
end,
endfunc = function(player,selfid, value)
    local JankSplosion = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_SSMINE)
    P_KillMobj(JankSplosion)
    --K_SpawnKartExplosion(player.mo.x, player.mo.y, player.mo.z, 92*FRACUNIT)
    --K_SpawnMineExplosion(player.mo)
    S_StartSound(player.mo, sfx_s3k4e)
    player.mo.color = value.prevcolor
end}
