• Do not use Works in Progress as a way of avoiding the releases system! Works in Progress can be used for sharing early betas and for getting suggestions for improvement. Releases of finished content are not allowed in this forum! If you would like to submit a finished addon, click here for instructions on how to do so.

secret rings sonic for SRB2 Coder and spriter needed

Status
Not open for further replies.

KitKatiscool

A guy who trying to learn lua
Rule 14: Do not post about project plans without proof that you have started
download.jpg
so im making a sonic mod based off his moveset from secret rings i working on the sprites i just need a coder for the mod.
moveset: homing attack, time stop, and time boost.
 
Hmmm… well, homing attack is pretty easy, there's a few dedicated functions for it — P_Homing, for instance. Heck, there's a pre-coded homing attack (CA_HOMINGTHOK) that you can just slap into your S_SKIN. Time boost might also be as simple as P_Thrust or some other speed-increasing function or action. The time stop, however… I have a character who's intended to be capable of slowing and rewinding time, and I still haven't figured out how I'm going to do anything more than monkeying with the HUD timer.

So, yeah, I think I can help you out with at least some of the coding.
 
think of the time boost as a pre curser to the double boost from sonic forces i also want it to we're you need a certin amount of rings
 
think of the time boost as a pre curser to the double boost from sonic forces i also want it to we're you need a certin amount of rings
Yeah, I know what Speed Break and Time Break are, I played Sonic and the Secret Rings.

Incidentally, I recently started implementing Sonja's time slow as a for loop, so I think I might be able to handle Time Break after all. I'm currently at a bit of an impasse with my own mod, so I might as well make some code for this to help out while I wait to be let back into the Discord server.
 
Hey, @KitKatiscool, I'm starting on the code for your Sonic and the Secret Rings Sonic mod. I'm also setting up an outline/lesson plan of sorts so you can follow along with what the code is intended to do. As I said earlier, my own characters can already do the stuff that you want your character to do, so I can just take the code from there; I'll just need to tweak it a bit. It's gonna take me a while to get it all ready, though.
Post automatically merged:

All right, here's the outline/lesson plan of what your code could look like, based in part on the code for some of the similar things my custom characters can do. Bear in mind that I'm still working out some bugs and unintended side effects of this code myself, but I'll warn you when that comes up. Also, this is gonna be long, so I'll have to break it up into chunks and/or stuff it in a text file so you can actually read it.



First, let's add the Homing Attack. This can be as simple as making your ability in your S_SKIN CA_HOMINGTHOK, a variation of CA_THOK (Sonic's ability) that doesn't give quite as much speed for your character's actionspd value, but homes in on nearby enemies to attack them. Note that this has a 3-second time limit by default, based on the built-in player.homing variable. If that's not your style and you'd rather fine-tune it more, you could use P_HomingAttack, which behaves more or less identically, but doesn't have to be the air action (though for the purpose of the moveset you want, it would be), and you can use your own variables to set its timer by repeatedly calling it in a PlayerThink as long as some timer variable stays above 0. Speaking of which, here's how you'd set up a timer variable (put this code in a PlayerThink hook to run it on every tic):

How to make a timer:
if player.mo.timer == nil then
    player.mo.timer = 0
end

if player.mo.timer > 0 then
    if (leveltime%TICRATE) then
        player.mo.timer = $ - 1
    end
end

Then you'd set your timer to whatever number of tics you want it to last whenever you want it to be started, and set up some other thing to happen or not be able to happen as long as the timer variable is above 0 or not 0. Let's call the timer variable player.homingattack, since we're using it for that purpose. For instance:

A jump dash/homing attack combo:
addHook("JumpSpecial", function(player) --A JumpSpecial hook defines what happens when you press the Jump button in midair after having already jumped off the ground
    for player in players.iterate() do --tie the hook to the player
        if player.mo.skin ~= "satsr_sonic" then --check that the player is [U]Sonic and the Secret Rings[/U] Sonic
            continue --stop running the hook if the player isn't [U]Sonic and the Secret Rings[/U] Sonic
        end
 
        if not (player.pflags & PF_THOKKED) --if the player hasn't used an air action or shield action in the current jump
        and (player.pflags & PF_JUMPED) then --if the player jumped off the ground (note that this will [I]not[/I] allow the player to use an air action off of a spring, and you'd need to ask someone else how to set that up)
            player.target = P_LookForEnemies(player, true, true) --look for an enemy, monitor, or spring within 1024 fracunits of the player up to 30 degrees above or below them and select the nearest enemy, monitor, or spring as the player's target (yes, those distance and angle caveats are inherent to P_LookForEnemies, and no, I don't know how to help you with any other enemy-targeting functions or actions ([I]please[/I] put in a good word for me with the Discord server mods so I can come back sooner rather than later... I need expert advice on so many things...))
            if (player.target and player.target.valid) then --if a target was found
                player.homingattack = 5*TICRATE --start a 5-second timer for the homing attack (player.homing is the game's own homing variable used for CA_HOMINGTHOK)
                player.pflags = $1|PF_THOKKED --set the PF_THOKKED flag to prevent consecutive air actions (PF_THOKKED should automatically be removed when the player touches the ground or otherise has their PF_JUMPED flag removed to allow them to jump from the ground again)
            else
                P_InstaThrust(player.mo, player.mo.angle, player.actionspd*FRACUNIT) --launch the player in the direction they're facing at their actionspd as defined in their S_SKIN (with actionspd being multiplied by FRACUNIT in order to work properly)
                player.pflags = $1|PF_THOKKED --set the PF_THOKKED flag to prevent consecutive air actions (PF_THOKKED should automatically be removed when the player touches the ground or otherise has their PF_JUMPED flag removed to allow them to jump from the ground again)
            end
        end
    end
end)

addHook("PlayerThink", function(player)
    if player.mo and player.mo.valid then --check that the player object exists
        if player.mo.skin ~= "satsr_sonic" then --check which skin the player is using
            return --immediately end the hook if the player is not [U]Sonic and the Secret Rings[/U] Sonic
        end
 
        if (player.target and player.target.valid) and player.homingattack > 0 then
            P_HomingAttack(player.mo, player.target) --have the player lock on to the target and lunge towards them at a rate of movement equal to 2*player.actionspd/3; since this is in a PlayerThink hook, it will be called every tic if its conditions are met
            if P_HomingAttack(player.mo, player.target) == true then --if the homing attack connects
                player.pflags = $&~PF_THOKKED --remove the PF_THOKKED flag to enable another air action
            end
        end
    end
end)

These hooks, assuming that I got everything right, combine CA_THOK and CA_HOMINGTHOK to allow a full-speed thok in the absence of enemies while also having a homing attack when enemies are present, while also allowing the Homing Attack to be chained like in Sonic and the Secret Rings and other 3D Sonic games. satsr_sonic would be the value of your name parameter in your S_SKIN; you can set it to whatever you want, but I presume that's what you'd like to call it.

Also, any variable whose name is preceded by player.mo could alternatively be preceded by p, p.mo, or player. p is an alternative way to refer to player (but you have to stick with one or the other throughout your Lua script, otherwise you'll run into errors). p/player stores your variable within player_t (the player), while p.mo/player.mo stores your variable within the mobj_t tied to the MT_PLAYER object that the player controls. Sometimes it matters which userdata structure you put a variable in, but I've found that it doesn't matter for the majority of purposes. So while you can use either of them for custom variables throughout your script and interchange them (for pre-existing variables, you have to use what the game already puts them in; see the wiki's page on userdata structures), you have to be consistent with using p/player or p.mo/player.mo for a given custom variable once you've set it up to use one userdata structure or the other (call the wrong userdata structure, and you won't get your variable; however, you can use a p/player variable and a p.mo/player.mo variable with the same name if you really want to, given that they would actually be two separate variables, but I wouldn't recommend it, since that would get confusing in a hurry).
Post automatically merged:

I've dedicated the first Lua file to binding all of the buttons and other variables that will be used throughout the rest of the script:

Defining variables:
//Defining variables
addHook ("PlayerThink", function(player)
    if player.mo and player.mo.valid then
   
        if player.mo.skin ~= "satsr_sonic" then
            return
        end
       
        if player.custom1down == nil then --if the player does not have this variable yet
            player.custom1down = 0 --give it a starting number
        end
       
        if player.cmd.buttons & BT_CUSTOM1 > 0 then --if the player is pressing Custom 1
            player.custom1down = $1 + 1 --increment custom1 variable
        else
            player.custom1down = 0 --reset custom1 variable
        end
       
        if player.custom2down == nil then --if the player does not have this variable yet
            player.custom2down = 0 --give it a starting number
        end
       
        if player.cmd.buttons & BT_CUSTOM2 > 0 then --if the player is pressing Custom 2
            player.custom2down = $1 + 1 --increment custom2 variable
        else
            player.custom2down = 0 --reset custom2 variable
        end
       
        if player.custom3down == nil then --if the player does not have this variable yet
            player.custom3down = 0 --give it a starting number
        end
       
        if player.cmd.buttons & BT_CUSTOM3 > 0 then --if the player is pressing Custom 3
            player.custom3down = $1 + 1 --increment custom3 variable
        else
            player.custom3down = 0 --reset custom3 variable
        end
       
        if player.tossflagdown == nil then --if the player does not have this variable yet
            player.tossflagdown = 0 --give it a starting number
        end
       
        if player.cmd.buttons & BT_TOSSFLAG > 0 then --if the player is pressing Toss Flag
            player.tossflagdown = $1 + 1 --increment tossflag variable
        else
            player.tossflagdown = 0 --reset tossflag variable
        end
       
        if player.firenormaldown == nil then --if the player does not have this variable yet
            player.firenormaldown = 0 --give it a starting number
        end
       
        if player.cmd.buttons & BT_FIRENORMAL > 0 then --if the player is pressing Fire Normal
            player.firenormaldown = $1 + 1 --increment firenormal variable
        else
            player.firenormaldown = 0 --reset firenormal variable
        end
       
        if player.cmd.buttons & BT_ATTACK > 0 then --if the player is pressing Fire
            player.firedown = $1 + 1 --increment fire variable
        else
            player.firedown = 0 --reset fire variable
        end
       
        if player.homingattack == nil then
            player.homingattack = 0
        end
       
        if player.mo.soulgauge == nil then
            player.mo.soulgauge = 200
        end
       
        if player.slowedtime == nil then
            player.slowedtime = 0
        end
       
        if player.mo.timebreak == nil then
            player.mo.timebreak = 0
        end
       
        if player.mo.speedbreak == nil then
            player.mo.speedbreak = 0
        end
    end
end)

The only button variables I actually plan to use here are custom1down and custom2down, but it's probably good practice to bind them all. homingattack will serve as a timer for the Homing Attack. soulgauge will be the fuel for Time Break and Speed Break. slowedtime will reduce player.realtime based on how long Time Break has been in use. timebreak and speedbreak will tell the game when Time Break and Speed Break are in use, as well as measuring how long they've been in use if that is necessary for some reason.
 
Last edited:
Hey, @KitKatiscool, I'm starting on the code for your Sonic and the Secret Rings Sonic mod. I'm also setting up an outline/lesson plan of sorts so you can follow along with what the code is intended to do. As I said earlier, my own characters can already do the stuff that you want your character to do, so I can just take the code from there; I'll just need to tweak it a bit. It's gonna take me a while to get it all ready, though.
Post automatically merged:

All right, here's the outline/lesson plan of what your code could look like, based in part on the code for some of the similar things my custom characters can do. Bear in mind that I'm still working out some bugs and unintended side effects of this code myself, but I'll warn you when that comes up. Also, this is gonna be long, so I'll have to break it up into chunks and/or stuff it in a text file so you can actually read it.



First, let's add the Homing Attack. This can be as simple as making your ability in your S_SKIN CA_HOMINGTHOK, a variation of CA_THOK (Sonic's ability) that doesn't give quite as much speed for your character's actionspd value, but homes in on nearby enemies to attack them. Note that this has a 3-second time limit by default, based on the built-in player.homing variable. If that's not your style and you'd rather fine-tune it more, you could use P_HomingAttack, which behaves more or less identically, but doesn't have to be the air action (though for the purpose of the moveset you want, it would be), and you can use your own variables to set its timer by repeatedly calling it in a PlayerThink as long as some timer variable stays above 0. Speaking of which, here's how you'd set up a timer variable (put this code in a PlayerThink hook to run it on every tic):

How to make a timer:
if player.mo.timer == nil then
    player.mo.timer = 0
end

if player.mo.timer > 0 then
    if (leveltime%TICRATE) then
        player.mo.timer = $ - 1
    end
end

Then you'd set your timer to whatever number of tics you want it to last whenever you want it to be started, and set up some other thing to happen or not be able to happen as long as the timer variable is above 0 or not 0. Let's call the timer variable player.homingattack, since we're using it for that purpose. For instance:

A jump dash/homing attack combo:
addHook("JumpSpecial", function(player) --A JumpSpecial hook defines what happens when you press the Jump button in midair after having already jumped off the ground
    for player in players.iterate() do --tie the hook to the player
        if player.mo.skin ~= "satsr_sonic" then --check that the player is [U]Sonic and the Secret Rings[/U] Sonic
            continue --stop running the hook if the player isn't [U]Sonic and the Secret Rings[/U] Sonic
        end
 
        if not (player.pflags & PF_THOKKED) --if the player hasn't used an air action or shield action in the current jump
        and (player.pflags & PF_JUMPED) then --if the player jumped off the ground (note that this will [I]not[/I] allow the player to use an air action off of a spring, and you'd need to ask someone else how to set that up)
            player.target = P_LookForEnemies(player, true, true) --look for an enemy, monitor, or spring within 1024 fracunits of the player up to 30 degrees above or below them and select the nearest enemy, monitor, or spring as the player's target (yes, those distance and angle caveats are inherent to P_LookForEnemies, and no, I don't know how to help you with any other enemy-targeting functions or actions ([I]please[/I] put in a good word for me with the Discord server mods so I can come back sooner rather than later... I need expert advice on so many things...))
            if (player.target and player.target.valid) then --if a target was found
                player.homingattack = 5*TICRATE --start a 5-second timer for the homing attack (player.homing is the game's own homing variable used for CA_HOMINGTHOK)
                player.pflags = $1|PF_THOKKED --set the PF_THOKKED flag to prevent consecutive air actions (PF_THOKKED should automatically be removed when the player touches the ground or otherise has their PF_JUMPED flag removed to allow them to jump from the ground again)
            else
                P_InstaThrust(player.mo, player.mo.angle, player.actionspd*FRACUNIT) --launch the player in the direction they're facing at their actionspd as defined in their S_SKIN (with actionspd being multiplied by FRACUNIT in order to work properly)
                player.pflags = $1|PF_THOKKED --set the PF_THOKKED flag to prevent consecutive air actions (PF_THOKKED should automatically be removed when the player touches the ground or otherise has their PF_JUMPED flag removed to allow them to jump from the ground again)
            end
        end
    end
end)

addHook("PlayerThink", function(player)
    if player.mo and player.mo.valid then --check that the player object exists
        if player.mo.skin ~= "satsr_sonic" then --check which skin the player is using
            return --immediately end the hook if the player is not [U]Sonic and the Secret Rings[/U] Sonic
        end
 
        if (player.target and player.target.valid) and player.homingattack > 0 then
            P_HomingAttack(player.mo, player.target) --have the player lock on to the target and lunge towards them at a rate of movement equal to 2*player.actionspd/3; since this is in a PlayerThink hook, it will be called every tic if its conditions are met
            if P_HomingAttack(player.mo, player.target) == true then --if the homing attack connects
                player.pflags = $&~PF_THOKKED --remove the PF_THOKKED flag to enable another air action
            end
        end
    end
end)

These hooks, assuming that I got everything right, combine CA_THOK and CA_HOMINGTHOK to allow a full-speed thok in the absence of enemies while also having a homing attack when enemies are present, while also allowing the Homing Attack to be chained like in Sonic and the Secret Rings and other 3D Sonic games. satsr_sonic would be the value of your name parameter in your S_SKIN; you can set it to whatever you want, but I presume that's what you'd like to call it.

Also, any variable whose name is preceded by player.mo could alternatively be preceded by p, p.mo, or player. p is an alternative way to refer to player (but you have to stick with one or the other throughout your Lua script, otherwise you'll run into errors). p/player stores your variable within player_t (the player), while p.mo/player.mo stores your variable within the mobj_t tied to the MT_PLAYER object that the player controls. Sometimes it matters which userdata structure you put a variable in, but I've found that it doesn't matter for the majority of purposes. So while you can use either of them for custom variables throughout your script and interchange them (for pre-existing variables, you have to use what the game already puts them in; see the wiki's page on userdata structures), you have to be consistent with using p/player or p.mo/player.mo for a given custom variable once you've set it up to use one userdata structure or the other (call the wrong userdata structure, and you won't get your variable; however, you can use a p/player variable and a p.mo/player.mo variable with the same name if you really want to, given that they would actually be two separate variables, but I wouldn't recommend it, since that would get confusing in a hurry).
Post automatically merged:

I've dedicated the first Lua file to binding all of the buttons and other variables that will be used throughout the rest of the script:

Defining variables:
//Defining variables
addHook ("PlayerThink", function(player)
    if player.mo and player.mo.valid then
  
        if player.mo.skin ~= "satsr_sonic" then
            return
        end
      
        if player.custom1down == nil then --if the player does not have this variable yet
            player.custom1down = 0 --give it a starting number
        end
      
        if player.cmd.buttons & BT_CUSTOM1 > 0 then --if the player is pressing Custom 1
            player.custom1down = $1 + 1 --increment custom1 variable
        else
            player.custom1down = 0 --reset custom1 variable
        end
      
        if player.custom2down == nil then --if the player does not have this variable yet
            player.custom2down = 0 --give it a starting number
        end
      
        if player.cmd.buttons & BT_CUSTOM2 > 0 then --if the player is pressing Custom 2
            player.custom2down = $1 + 1 --increment custom2 variable
        else
            player.custom2down = 0 --reset custom2 variable
        end
      
        if player.custom3down == nil then --if the player does not have this variable yet
            player.custom3down = 0 --give it a starting number
        end
      
        if player.cmd.buttons & BT_CUSTOM3 > 0 then --if the player is pressing Custom 3
            player.custom3down = $1 + 1 --increment custom3 variable
        else
            player.custom3down = 0 --reset custom3 variable
        end
      
        if player.tossflagdown == nil then --if the player does not have this variable yet
            player.tossflagdown = 0 --give it a starting number
        end
      
        if player.cmd.buttons & BT_TOSSFLAG > 0 then --if the player is pressing Toss Flag
            player.tossflagdown = $1 + 1 --increment tossflag variable
        else
            player.tossflagdown = 0 --reset tossflag variable
        end
      
        if player.firenormaldown == nil then --if the player does not have this variable yet
            player.firenormaldown = 0 --give it a starting number
        end
      
        if player.cmd.buttons & BT_FIRENORMAL > 0 then --if the player is pressing Fire Normal
            player.firenormaldown = $1 + 1 --increment firenormal variable
        else
            player.firenormaldown = 0 --reset firenormal variable
        end
      
        if player.cmd.buttons & BT_ATTACK > 0 then --if the player is pressing Fire
            player.firedown = $1 + 1 --increment fire variable
        else
            player.firedown = 0 --reset fire variable
        end
      
        if player.homingattack == nil then
            player.homingattack = 0
        end
      
        if player.mo.soulgauge == nil then
            player.mo.soulgauge = 200
        end
      
        if player.slowedtime == nil then
            player.slowedtime = 0
        end
      
        if player.mo.timebreak == nil then
            player.mo.timebreak = 0
        end
      
        if player.mo.speedbreak == nil then
            player.mo.speedbreak = 0
        end
    end
end)

The only button variables I actually plan to use here are custom1down and custom2down, but it's probably good practice to bind them all. homingattack will serve as a timer for the Homing Attack. soulgauge will be the fuel for Time Break and Speed Break. slowedtime will reduce player.realtime based on how long Time Break has been in use. timebreak and speedbreak will tell the game when Time Break and Speed Break are in use, as well as measuring how long they've been in use if that is necessary for some reason.
we can talk about this more on my discord catsarecool#1419
 
Rule 14: Do not post about project plans without proof that you have started. Feel free to nake a new thread once you have something to show off.
 
Status
Not open for further replies.

Who is viewing this thread (Total: 1, Members: 0, Guests: 1)

Back
Top