-- 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, 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.
effect - 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 --
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.
startsfx - This sets the sound that plays when the effect is applied, unless the HUD is disabled.
description - Gives a description of the effect when you use "tkkWhatIs" in the console. Write something helpful, but don't go overboard with what you detail!
endsfx - Same as above, but for when an effect is removed.
forcestart - This forces the startsfx to play, regardless of if the HUD is enabled.
forceend - Ditto but for removing effect.
localsfx - This makes the starting and/or end sounds play only for the player, instead of broadcasting the sound from the player themself.
notimer - Don't show the timer text in the HUD.
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.
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)
addition - In Amplify Mode only, this will add additional time to the duration. No fancy math here, just straight up addition.
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.

-- 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, the spinning roulette counts as an effect!
dontrollme - This effect will not be rolled by the Roulette. Good for effects that get applied via other means than random chance.
nobattle - Won't apply in battle/egg prisons mode.
nobees - Won't get rolled by the "You Get The Bees" universal effect.
battleonly - Inverse of the above!
amplifyonly - Only applies if "Amplify Mode" is turned on. Good for seriously busted effects.
nobot - Doesn't apply if the player is a bot. Good for effects that are only visual, or ones that require cognisant player control.
requirerings - Player needs 1 or more rings.
grounded - Player needs to be on the ground.
]]

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

TailsKK.addEffect() - 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}", etc.
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.



]]

-- 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 = "CEICB0", effect = "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}
