rawset(_G, "ANG3", FixedAngle(3*FRACUNIT)) local function CappyMoveObject(speed, mo) if abs(speed) < 256 then --kinda a bad hack to check for non fixed values but oh well speed = $*FRACUNIT end if mo.type == MT_SNAILER or mo.flags & MF_MONITOR speed = 0 end if mo.type == MT_BLUECRAWLA speed = $/2 end P_InstaThrust(mo, mo.angle, speed) mo.energy = max($-1, 0) end local function CappyPercentage(num, per) return (num*per)/100 end local function CappyAbandonMo(player) if not player.awayviewmobj then return end player.awayviewtics = 0 player.awayviewmobj.flags = $ & ~MF_NOCLIPTHING player.awayviewmobj.tics = 1 player.awayviewmobj.iscapped = nil player.awayviewmobj = nil player.cappytimer = 35 end local function FixedIntCheck(speed) if abs(speed) > 256 then speed = FixedInt($) end return speed end local function HeightCheck(h1, h2, hmax) local height = abs(h1-h2) if height <= hmax return true end return false end local redRingColors = { default = {SKINCOLOR_SALMON}, super = {SKINCOLOR_SUPERGOLD1, SKINCOLOR_SUPERGOLD2, SKINCOLOR_SUPERGOLD3, SKINCOLOR_SUPERGOLD4, SKINCOLOR_SUPERGOLD5, SKINCOLOR_SUPERGOLD4, SKINCOLOR_SUPERGOLD3, SKINCOLOR_SUPERGOLD2, SKINCOLOR_SUPERGOLD1}, hyper = {SKINCOLOR_SUPERSILVER1, SKINCOLOR_SUPERRED1, SKINCOLOR_SUPERORANGE1, SKINCOLOR_SUPERGOLD1, SKINCOLOR_SUPERPERIDOT1, SKINCOLOR_SUPERSKY1, SKINCOLOR_SUPERPURPLE1}, psychic = {SKINCOLOR_SUPERPURPLE1, SKINCOLOR_SUPERPURPLE2, SKINCOLOR_SUPERPURPLE3, SKINCOLOR_SUPERPURPLE4, SKINCOLOR_SUPERPURPLE5, SKINCOLOR_SUPERPURPLE4, SKINCOLOR_SUPERPURPLE3, SKINCOLOR_SUPERPURPLE2, SKINCOLOR_SUPERPURPLE1}, } local iscontrolring = nil local function controlRingSpawner(missile) if not (iscontrolring or iscontrolring[1] or iscontrolring[2]) then return end missile.iscontrol = iscontrolring[1].ringpointer missile.fuse = 105 if missile.type == MT_INFINITYRING P_DamageMobj(iscontrolring[2], missile, iscontrolring[1].mo, 1) end iscontrolring = nil end addHook("PlayerSpawn", function(player) if not player.ringpointer then player.ringpointer = 1 end player.controlrings = { {sprite = SPR_TRNG, name = "Red Ring", reloadtime = 9, cost = 1, type = MT_REDRING, color = redRingColors.default}, {sprite = SPR_RNGA, name = "Automatic Ring", reloadtime = 2, cost = 3, type = MT_THROWNAUTOMATIC, func = function(mo) local speed = FixedIntCheck(mo.speed) mo.speed = speed*(3*FRACUNIT/2) end}, {sprite = SPR_RNGB, name = "Bounce Ring", reloadtime = 8, cost = 7, type = MT_THROWNBOUNCE, func = function(mo) local speed = FixedIntCheck(mo.speed) mo.jumpforce = speed*2 end}, {sprite = SPR_RNGS, name = "Scatter Ring", reloadtime = 23, cost = 15, type = MT_THROWNSCATTER, func = function(mo) mo.energy = 1350 end}, {sprite = SPR_RNGG, name = "Grenade Ring", reloadtime = 11, cost = 20, type = MT_THROWNGRENADE, func = function(mo) mo.boomradius = FixedMul($, 3*FRACUNIT) end}, {sprite = SPR_RNGE, name = "Explosion Ring", reloadtime = 23, cost = 30, type = MT_THROWNEXPLOSION, func = function(mo) mo.boomradius = FixedMul($, 5*FRACUNIT) mo.speed = 0 mo.jumpforce = 0 end}, {sprite = SPR_RNGR, name = "Rail Ring", reloadtime = 52, cost = 50, type = MT_INFINITYRING} } player.cappytimer = player.controlrings[player.ringpointer].reloadtime player.hudtimer = 0 if not player.psychocounter then player.psychocounter = 0 end --[[if player.savedrings player.rings = player.savedrings if All7Emeralds(emeralds) player.rings = $+CappyPercentage($, 10) end end]] if mapheaderinfo[gamemap].bonustype == 1 and player.rings < 20 player.rings = 20 end end) addHook("PreThinkFrame", function() for player in players.iterate if not player.awayviewmobj then continue end player.awayviewmobj.momx = 0 player.awayviewmobj.momy = 0 if player.awayviewmobj.flags & MF_NOGRAVITY then player.awayviewmobj.momz = 0 end local speed = player.awayviewmobj.speed if player.cmd.forwardmove > 0 CappyMoveObject(speed, player.awayviewmobj) elseif player.cmd.forwardmove < 0 CappyMoveObject(-speed, player.awayviewmobj) end if player.cmd.sidemove > 0 player.awayviewmobj.angle = $-ANG3 elseif player.cmd.sidemove < 0 player.awayviewmobj.angle = $+ANG3 end if player.awayviewmobj.flags & MF_NOGRAVITY and not (player.awayviewmobj.flags & MF_BOSS) speed = FixedIntCheck($) if player.cmd.buttons & BT_JUMP player.awayviewmobj.momz = speed*FRACUNIT player.awayviewmobj.energy = max($-1, 0) elseif player.cmd.buttons & BT_SPIN player.awayviewmobj.momz = -speed*FRACUNIT player.awayviewmobj.energy = max($-1, 0) end end if player.cmd.buttons & BT_JUMP and not (player.awayviewmobj.flags & MF_NOGRAVITY) and player.awayviewmobj.jumpforce and P_IsObjectOnGround(player.awayviewmobj) A_BunnyHop(player.awayviewmobj, player.awayviewmobj.jumpforce, 0) player.awayviewmobj.energy = max($-5, 0) end if not player.awayviewmobj.energy CappyAbandonMo(player) end end end) addHook("PlayerThink", function(player) player.cappytimer = max($-1, 0) player.hudtimer = max($-1, 0) if player.psychocounter and player.controlrings[1].color == redRingColors.psychic --player.mo.color = redRingColors.psychic[(leveltime%#redRingColors.psychic)+1] if (leveltime%2) then player.psychocounter = max($-1, 0) end end if player.mo.health player.savedrings = player.rings end if player.powers[pw_super] and player.controlrings[1].color == redRingColors.default player.controlrings[1] = {sprite = SPR_TRNG, name = "Super Ring", reloadtime = 9, cost = 0, type = MT_REDRING, color = redRingColors.super, func = function(mo) local speed = FixedIntCheck(mo.speed) mo.speed = speed*(4*FRACUNIT/3) mo.jumpforce = speed mo.boomradius = FixedMul($, 2*FRACUNIT) end} player.mo.colorized = false elseif (not player.powers[pw_super] and player.controlrings[1].color == redRingColors.super) or (not player.psychocounter and player.controlrings[1].color == redRingColors.psychic) player.controlrings[1] = {sprite = SPR_TRNG, name = "Red Ring", reloadtime = 9, cost = 1, type = MT_REDRING, color = redRingColors.default} player.mo.color = player.skincolor player.mo.colorized = false end player.foundtarget = false local target = P_LookForEnemies(player, false, true) if target P_SpawnLockOn(player, target, S_LOCKON1) player.foundtarget = true end if player.awayviewmobj if player.awayviewmobj.flags & MF_NOCLIP player.awayviewmobj.flags = $ & ~MF_NOCLIP end player.awayviewmobj.tics = 2 player.awayviewtics = INT32_MAX player.powers[pw_nocontrol] = 1 local bradius = player.awayviewmobj.boomradius/2 searchBlockmap("objects", function(mo, foundmo) if mo == foundmo then return end if HeightCheck(mo.z, foundmo.z, bradius) and foundmo.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) P_SpawnLockOn(player, foundmo, S_LOCKON4) end end, player.awayviewmobj, player.awayviewmobj.x - bradius, player.awayviewmobj.x + bradius, player.awayviewmobj.y - bradius, player.awayviewmobj.y + bradius) if player.cmd.buttons & BT_CUSTOM2 player.awayviewmobj.flags = $ & ~MF_NOCLIPTHING player.awayviewtics = 0 P_NukeEnemies(player.awayviewmobj, player.mo, 0) searchBlockmap("objects", function(mo, foundmo) if mo == foundmo then return end if HeightCheck(mo.z, foundmo.z, bradius) and foundmo.flags & (MF_ENEMY|MF_BOSS|MF_MONITOR) P_DamageMobj(foundmo, player.awayviewmobj, player.mo, 1) --P_GivePlayerRings(player, player.awayviewmobj.iscapped) player.psychocounter = min($+10, 250) end end, player.awayviewmobj, player.awayviewmobj.x - bradius, player.awayviewmobj.x + bradius, player.awayviewmobj.y - bradius, player.awayviewmobj.y + bradius) player.awayviewmobj.iscapped = nil P_DamageMobj(player.awayviewmobj, player.awayviewmobj, player.mo, 1) player.awayviewmobj = nil player.cappytimer = 35 end if player.cmd.buttons & BT_CUSTOM3 and not (player.awayviewmobj.flags & MF_BOSS) local splayer = {x = player.mo.x, y = player.mo.y, z = player.mo.z} local senemy = {x = player.awayviewmobj.x, y = player.awayviewmobj.y, z = player.awayviewmobj.z} player.mo.flags = $|MF_NOCLIPTHING P_TeleportMove(player.mo, senemy.x, senemy.y, senemy.z) P_TeleportMove(player.awayviewmobj, splayer.x, splayer.y, splayer.z) player.mo.flags = $ & ~MF_NOCLIPTHING CappyAbandonMo(player) end end if player.cmd.buttons & BT_WEAPONMASK player.ringpointer = (player.cmd.buttons & BT_WEAPONMASK) player.hudtimer = 35 elseif player.cmd.buttons & BT_WEAPONNEXT player.ringpointer = min($+1, #player.controlrings) player.hudtimer = 35 elseif player.cmd.buttons & BT_WEAPONPREV player.ringpointer = max($-1, 1) player.hudtimer = 35 end if player.psychocounter and player.psychocounter == 250 and not player.powers[pw_super] and player.powers[pw_carry] ~= CR_NIGHTSMODE and player.cmd.buttons & BT_TOSSFLAG if player.controlrings[1].color == redRingColors.default player.controlrings[1] = {sprite = SPR_TRNG, name = "Psychic Ring", reloadtime = 15, cost = 2, type = MT_REDRING, color = redRingColors.psychic, func = function(mo) local speed = FixedIntCheck(mo.speed) mo.speed = speed*(3*FRACUNIT/2) mo.jumpforce = speed*2 mo.boomradius = FixedMul($, 3*FRACUNIT) mo.energy = 1350 end} player.mo.color = SKINCOLOR_PURPLE player.mo.colorized = true end end if player.cappytimer then return end if player.cmd.buttons & BT_CUSTOM1 if player.awayviewmobj CappyAbandonMo(player) elseif target and player.rings >= player.controlrings[player.ringpointer].cost iscontrolring = {player, target} P_SpawnMissile(player.mo, target, player.controlrings[player.ringpointer].type) player.rings = $-player.controlrings[player.ringpointer].cost player.cappytimer = player.controlrings[player.ringpointer].reloadtime end end end) addHook("MobjSpawn", controlRingSpawner, MT_REDRING) addHook("MobjSpawn", controlRingSpawner, MT_THROWNAUTOMATIC) addHook("MobjSpawn", controlRingSpawner, MT_THROWNBOUNCE) addHook("MobjSpawn", controlRingSpawner, MT_THROWNSCATTER) addHook("MobjSpawn", controlRingSpawner, MT_THROWNGRENADE) addHook("MobjSpawn", controlRingSpawner, MT_THROWNEXPLOSION) addHook("MobjSpawn", controlRingSpawner, MT_INFINITYRING) addHook("MobjThinker", function(mo) if mo and mo.iscontrol and mo.target.player local colors = mo.target.player.controlrings[1].color mo.color = colors[(leveltime%#colors)+1] end end, MT_REDRING) addHook("ShouldDamage", function(target, inflictor, source, damage, damagetype) if damagetype == DMG_INSTAKILL and target.player and target.player.savedrings if target.player.psychocounter then target.player.psychocounter = max($-50, 0) end target.player.savedrings = $-CappyPercentage($, 35) return true end if damagetype == DMG_INSTAKILL then return true end if inflictor and not inflictor.player and source and source.player and inflictor.iscontrol and not target.player local player = source.player if player.awayviewmobj and player.awayviewmobj == target P_RemoveMobj(inflictor) return false end player.awayviewmobj = target player.awayviewmobj.momx = 0 player.awayviewmobj.momy = 0 player.awayviewmobj.momz = 0 player.awayviewmobj.iscapped = 2 player.awayviewmobj.flags = $|MF_NOCLIPTHING player.awayviewtics = INT32_MAX player.cappytimer = 20 player.awayviewmobj.speed = mobjinfo[player.awayviewmobj.type].speed if player.awayviewmobj.type == MT_DETON or player.awayviewmobj.type == MT_METALSONIC_BATTLE then player.awayviewmobj.speed = 15*FRACUNIT end player.awayviewmobj.jumpforce = 0 player.awayviewmobj.boomradius = 150*FRACUNIT player.awayviewmobj.energy = 1000 if player.controlrings[inflictor.iscontrol].func then player.controlrings[inflictor.iscontrol].func(player.awayviewmobj) end inflictor.iscontrol = nil if inflictor.type == MT_THROWNBOUNCE or inflictor.type == MT_THROWNEXPLOSION or inflictor.type == MT_THROWNGRENADE P_RemoveMobj(inflictor) end return false elseif inflictor and inflictor.player and not inflictor.player.bot and target.type ~= MT_CANARIVORE_GAS and target.type ~= MT_PROXIMITYTNT and target.type ~= MT_TNTBARREL and target.type ~= MT_BLASTEXECUTOR and inflictor.player ~= target.player and inflictor.player.powers[pw_carry] ~= CR_NIGHTSMODE if inflictor.player.psychocounter and inflictor.player.controlrings[1].color == redRingColors.psychic inflictor.player.psychocounter = max($-3, 0) return false end P_DamageMobj(inflictor, nil, nil, 1, DMG_INSTAKILL) return false elseif target.player and not target.player.bot and target.player.powers[pw_carry] ~= CR_NIGHTSMODE if target.player.psychocounter and target.player.controlrings[1].color == redRingColors.psychic target.player.psychocounter = max($-3, 0) return false end P_DamageMobj(target, nil, nil, 1, DMG_INSTAKILL) return false end end) --local intToTrans = {V_10TRANS, V_20TRANS, V_30TRANS, V_40TRANS, V_50TRANS, V_60TRANS, V_70TRANS, V_80TRANS, V_90TRANS} CV_RegisterVar({ name = "overrideringstips", defaultvalue = "On", flags = CV_SAVE|CV_SHOWMODIF, PossibleValue = CV_OnOff, func = nil }) hud.add(function(v, player) v.drawFill(16, 57, player.cappytimer*3, 5, 17|V_SNAPTOLEFT|v.userTransFlag()) --[[local trans = 0 print(player.hudtimer) if player.hudtimer < 10 and player.hudtimer > 0 local trans = intToTrans[player.hudtimer] print("yes") end]] local ring = player.controlrings if player.hudtimer for i = 1,#ring local flipcheck = false local patchicon = v.getSpritePatch(ring[i].sprite, leveltime%35, 0) if i == 1 then patchicon, flipcheck = v.getSpritePatch(ring[i].sprite, leveltime%24, 0) end local red = nil if i == 1 local color = ring[1].color[(leveltime%#ring[1].color)+1] red = v.getColormap(TC_DEFAULT, color) end local flipped = 0 if flipcheck then flipped = V_FLIP end v.drawScaled(20*FRACUNIT, (58+(16*i))*FRACUNIT, FRACUNIT/3, patchicon, V_SNAPTOLEFT|v.userTransFlag()|flipped, red) local flags = V_SNAPTOLEFT|v.userTransFlag() if i == player.ringpointer then flags = V_YELLOWMAP|V_SNAPTOLEFT|v.userTransFlag() end if ring[i].cost > player.rings and leveltime%35 >= 13 then flags = V_REDMAP|V_SNAPTOLEFT|v.userTransFlag() end v.drawString(33, 64+16*(i-1), ring[i].name, flags, "small") v.drawString(33, 71+16*(i-1), "Cost : "..ring[i].cost, flags, "small") end end local playercolor = 0 if player.skincolor then playercolor = skincolors[player.skincolor].chatcolor end local var = CV_FindVar("overrideringstips").value if var local tiptexts = { "WEAPON NUM 1-7: CHANGE RING", "WEAPON NEXT: NEXT RING", "WEAPON PREV: PREVIOUS RING" } if not player.awayviewmobj and player.foundtarget then table.insert(tiptexts, "C1: FIRE") elseif player.awayviewmobj then table.insert(tiptexts, "C1: DISMISS") table.insert(tiptexts, "C2: EXPLODE") table.insert(tiptexts, "C3: SWAP") end if player.psychocounter and player.psychocounter == 250 and not player.powers[pw_super] then table.insert(tiptexts, "TOSSFLAG: PSYCHIC BOOST") end if player.cappytimer then table.remove(tiptexts, 4) end local tipy = 20 if player.awayviewmobj and player.awayviewmobj.energy then tipy = 40 end for i = 1,#tiptexts v.drawString(305, tipy+6*(i-1), tiptexts[i], playercolor|V_SNAPTOTOP|V_SNAPTORIGHT|V_TRANSLUCENT|v.userTransFlag(), "small-right") end end if player.psychocounter local psicolor = 163 if player.psychocounter == 250 then psicolor = 169-(leveltime%10) end v.drawFill(80, 185, player.psychocounter/3, 5, psicolor|V_SNAPTOBOTTOM|v.userTransFlag()) local psitext = "Psychic Energy: "..(player.psychocounter/10).."/25" v.drawString(80, 185, psitext, V_INVERTMAP|V_SNAPTOBOTTOM|V_TRANSLUCENT|v.userTransFlag(), "small") end if not player.awayviewmobj then return end local isdangerclose = "" searchBlockmap("objects", function(mo, foundmo) if mo.player.awayviewmobj == foundmo then return end if not HeightCheck(mo.z, foundmo.z, 75*FRACUNIT) then return end if foundmo.flags & MF_ENEMY isdangerclose = "enemy" return true elseif foundmo.flags & MF_BOSS isdangerclose = "boss" return true elseif foundmo.flags & MF_MISSILE isdangerclose = "missile" return true elseif foundmo.flags & MF_PAIN isdangerclose = "threat" return true end end, player.mo, player.mo.x - 150*FRACUNIT, player.mo.x + 150*FRACUNIT, player.mo.y - 150*FRACUNIT, player.mo.y + 150*FRACUNIT) if isdangerclose ~= "" then v.drawString(130, 10, isdangerclose.." NEAR PLAYER!", V_REDMAP|V_SNAPTOTOP|v.userTransFlag()) end local color = 195 local energy = player.awayviewmobj.energy if not energy then return end if energy < 250 color = 35 elseif energy >= 250 and energy < 500 color = 54 elseif energy >= 500 and energy < 750 color = 73 elseif energy >= 750 and energy <= 1000 color = 114 end v.drawFill(260, 30, player.awayviewmobj.energy/25, 5, color|V_SNAPTOTOP|V_SNAPTORIGHT|v.userTransFlag()) v.drawString(260, 20, "ENERGY:", V_YELLOWMAP|V_SNAPTOTOP|V_SNAPTORIGHT|v.userTransFlag()) v.drawString(260, 30, player.awayviewmobj.energy, V_INVERTMAP|V_SNAPTOTOP|V_SNAPTORIGHT|V_TRANSLUCENT|v.userTransFlag(), "small") end)