• 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.

Gravity Shield

Status
Not open for further replies.

Goldenhog

Wandering Protagonist
Yup.

Mtikhun.png


The best way to learn something is to go all-out, in my opinion. Even though making this was easier than I anticipated(until the point where I am at now, at least), I learned many things about Lua, how it works and how to do stuff with it to use in SRB2. But I'm yet no Lua master and I need help. This wouldn't be in Editing otherwise, right?

HpzAfFo.gif


Enter the Gravity Shield. Press Spin while jumping to switch from regular gravity to reverse gravity and vice-versa. Following 2.1's steps, this shield has a unique look(compared to the other 2.1 shields anyway) and I made it so that the arrows that appear and the shield itself change color depending on the user's current gravity.

It behaves like the other shields do(for the most part) - it follows you around, it becomes invisible while you're invulnerable, it goes away if you pick up another shield or go super, it makes other shields go away when you pick it up, and you lose it when an enemy hits you.

However, if I intend to put it in Submissions, and I do, there are still some issues that need to be fixed, and I'm gonna need help since some stuff here won't work like I want it to no matter how hard I try:
  • I've been trying to use MF2_OBJECTFLIP instead of pw_gravityboots for the reverse gravity effect, but it refuses to work. I wouldn't mind so much if I didn't have to use that blue arrow icon on the top of the screen.
  • In order for it to fully act like a shield, it needs to take the hit for the player, like all the other shields do. I can't do it! D: - What I had in mind is using the hook ShouldDamage anytime the player hits anything, then checking if the object the player collided into has a flag that says it's harmful(MF_ENEMY, MF_PAIN, MF_BOSS, etc) and then using P_DoPlayerPain while taking the shield away and restoring gravity. But I don't think it's possible to have ShouldDamage run every time the player collides with something.
  • You switch to reverse gravity with Spin, and back to normal with Custom 1. I tried having both use Spin, but when I do then neither works!
  • Possibly related to the previous one, I want the player to only be able to change gravity once per jump. Right now you can just mash Spin and Custom 1 and stay in the same spot forever. I tried adding a variable that gets switched on if the player switches gravity(thus making him unable to change gravity anymore) and only switches off when the player touches the floor. Nope, that also makes neither gravity switch button work for some reason.
  • If the player dies while wielding the Gravity Shield, this message appears in the console: WARNING: luatest.lua:65: accessed mobj_t doesn't exist anymore, please check 'valid' before using mobj_t. I know what's causing it, I've bolded it below, but I have no idea how to fix it.
  • All of these now have been taken care of. Thanks to RedEnchilada for all the help given so far.
7/5/2014 Update: All the issues I wanted to fix are fixed! Yay! Now all it needs is some testing to make sure it doesn't break everything, then I have to make the test map and then it's on to the Submissions subforum. See ya!
 
Last edited:
Replace your ThinkFrame hook with this to fix the flipping issues: (changes have been bolded)

Code:
addHook("ThinkFrame", do
    for player in players.iterate
        if (player.cmd.buttons & BT_USE)
        and (player.pflags & PF_JUMPED)
        and (player.powers[pw_gravityboots] <= 1)
        and (player.gshield_power == 1)
        [B]and not player.gshield_used
            if player.powers[pw_gravityboots] <= 1
                player.powers[pw_gravityboots] = 1073741823
            else
                player.powers[pw_gravityboots] = 0
            end
            player.gshield_used = true
        end
        if P_IsObjectOnGround(player.mo) then
            player.gshield_used = false
        end[/B]
    end
end)
Add the bolded line between the lines around it to fix the script error:

Code:
    A_CAPECHASE(actor, 0, 0)
    [B]if not actor.valid then return end[/B]
    wielder.player.gshield_power = 1
For MF2_OBJECTFLIP not working, are you applying it to player.flags2 or player.mo.flags2? The latter is the right method.

Finally, this hook should do the damage handling bit (fair warning: I haven't tested this)

Code:
addHook("MobjDamage", function(mo, src, inf)
    if mo.player.gshield_power then
        mo.player.gshield_power = false
        P_DoPlayerPain(mo.player, src, inf)
        return false
    end
end, MT_PLAYER)

Hope that helps you. The concept looks incredibly interesting and I'm looking forward to it, especially if it gets used well in a custom level of some sort.
 
Last edited:
Oh wow. This does look incredibly cool. I can't wait for you to release this! One problem I noticed in the .gif though was that Sonic was constantly flickering between being in front of the shield and being in it.
 
Replace your ThinkFrame hook with this to fix the flipping issues: (changes have been bolded)

Code:
addHook("ThinkFrame", do
    for player in players.iterate
        if (player.cmd.buttons & BT_USE)
        and (player.pflags & PF_JUMPED)
        and (player.powers[pw_gravityboots] <= 1)
        and (player.gshield_power == 1)
        [B]and not player.gshield_used
            if player.powers[pw_gravityboots] <= 1
                player.powers[pw_gravityboots] = 1073741823
            else
                player.powers[pw_gravityboots] = 0
            end
            player.gshield_used = true
        end
        if P_IsObjectOnGround(player.mo) then
            player.gshield_used = false
        end[/B]
    end
end)

The "no gravity boots" check is there twice, making it not work. Fixed that easily though. Now I can easily switch the gravity! Thanks a lot!

Add the bolded line between the lines around it to fix the script error:

Code:
    A_CAPECHASE(actor, 0, 0)
    [B]if not actor.valid then return end[/B]
    wielder.player.gshield_power = 1

Yup, working like a charm. Thanks again!

For MF2_OBJECTFLIP not working, are you applying it to player.flags2 or player.mo.flags2? The latter is the right method.

Trying this out now. I got it working, but it's causing problems with the shield's animation that I'm trying to sort out.

Finally, this hook should do the damage handling bit (fair warning: I haven't tested this)

Code:
addHook("MobjDamage", function(mo, src, inf)
    if mo.player.gshield_power then
        mo.player.gshield_power = false
        P_DoPlayerPain(mo.player, src, inf)
        return false
    end
end, MT_PLAYER)

Welp, I should have read Monster Iestyn's thread more throughly. I had no idea that such a hook existed. It doesn't work, by the way, but it'll prove useful for further experimenting.

Hope that helps you. The concept looks incredibly interesting and I'm looking forward to it, especially if it gets used well in a custom level of some sort.

Thanks! While I am working on a level that uses the Gravity Shield as its main gimmick, it's still a long way from being completed. I'll release the shield standalone once all the stuff I listed in the first post is fixed(maybe with a test map or something, I still have to ask how do releasing something like this would work).

Oh wow. This does look incredibly cool. I can't wait for you to release this! One problem I noticed in the .gif though was that Sonic was constantly flickering between being in front of the shield and being in it.

And I'm looking forward to releasing this as well! As for that problem, I am aware of it, but it's not important enough right now.
 
Well, I got nothing, but either way I wanted to pop in and say this looks pretty kickass. Good luck.
 
Wow this is really interesting... It would make some space levels fun and all using this gimmick...
 
The "no gravity boots" check is there twice, making it not work. Fixed that easily though. Now I can easily switch the gravity! Thanks a lot!
Whoops!~

Trying this out now. I got it working, but it's causing problems with the shield's animation that I'm trying to sort out.
What kind of animation problems?

Welp, I should have read Monster Iestyn's thread more throughly. I had no idea that such a hook existed. It doesn't work, by the way, but it'll prove useful for further experimenting.
My apologies, I rushed out the reply without thinking and that hook should return true where it's currently returning false, to suppress normal damage actions. (It should also just return if the damage value is equal to 10000, too, but I hadn't thought about that in writing the script. That should be a simple fix, though.)


Thanks! While I am working on a level that uses the Gravity Shield as its main gimmick, it's still a long way from being completed. I'll release the shield standalone once all the stuff I listed in the first post is fixed(maybe with a test map or something, I still have to ask how do releasing something like this would work).
Releasing it with a test map is absolutely fine.

Also, I believe the player flickering in front of/behind the shield can be fixed by setting the mobjinfo's dispoffset value in your SOC, but I could be wrong since I haven't actually worked with it.
 
What kind of animation problems?
It's the whole "turn blue when rightside up and orange when upside down" thing. I changed the pw_gravityboots lines so that they add/remove MF2_OBJECTFLIP. It works! No more stupid HUD arrow! I don't see why it didn't work before, but that's not important. So, with that done, I had to change this part of the A_GShieldThink's code...
Code:
    if (wielder.player.powers[pw_gravityboots] <= 1)
    and (actor.state > actor.info.meleestate)
    and (actor.state < actor.info.missilestate)
        actor.state = actor.info.spawnstate
    end
    if (wielder.player.powers[pw_gravityboots] > 1)
    and (actor.state > actor.info.spawnstate)
    and (actor.state < actor.info.seestate)
        actor.state = actor.info.meleestate
    end
...so that instead of changing the shield's states according to the player's pw_gravityboots, it did it according to the presence or lack thereof of the MF2_OBJECTFLIP flag2(first one should be "normal gravity = blue orb states", while the second should be "flipped gravity = orange orb states").
Code:
    if not wielder.mo.flags2 & MF2_OBJECTFLIP
    and (actor.state > actor.info.meleestate)
    and (actor.state < actor.info.missilestate)
        actor.state = actor.info.spawnstate
    end
    if wielder.mo.flags2 & MF2_OBJECTFLIP
    and (actor.state > actor.info.spawnstate)
    and (actor.state < actor.info.seestate)
        actor.state = actor.info.meleestate
    end
Not so lucky this time :(. It just spams the console with
Code:
WARNING: luatest.lua:66: attempt to index field 'mo' (a nil value)
Right now, I'm trying to figure out how to fix it.
My apologies, I rushed out the reply without thinking and that hook should return true where it's currently returning false, to suppress normal damage actions. (It should also just return if the damage value is equal to 10000, too, but I hadn't thought about that in writing the script. That should be a simple fix, though.)

OK, changed "return false" to "return true"(if I understood you right), and it works! It doesn't play the hit sound, but I can take care of that myself.

Releasing it with a test map is absolutely fine.

Also, I believe the player flickering in front of/behind the shield can be fixed by setting the mobjinfo's dispoffset value in your SOC, but I could be wrong since I haven't actually worked with it.

Good to know. Should the test map be MAP01 or something like MAPG0?

As for the latter thing, I don't know what dispoffset is, but I'll look into it once everything else is done.
 
MAPG0, but change SPStart in MAINCFG to just start a game on it.

Dispoffset determines if the sprite goes in front of or behind the player if they overlap.
 
This looks pretty cool, and if used right, could lead to some fun custom maps with gravity switching!
 
It's the whole "turn blue when rightside up and orange when upside down" thing. I changed the pw_gravityboots lines so that they add/remove MF2_OBJECTFLIP. It works! No more stupid HUD arrow! I don't see why it didn't work before, but that's not important. So, with that done, I had to change this part of the A_GShieldThink's code...
Code:
    if (wielder.player.powers[pw_gravityboots] <= 1)
    and (actor.state > actor.info.meleestate)
    and (actor.state < actor.info.missilestate)
        actor.state = actor.info.spawnstate
    end
    if (wielder.player.powers[pw_gravityboots] > 1)
    and (actor.state > actor.info.spawnstate)
    and (actor.state < actor.info.seestate)
        actor.state = actor.info.meleestate
    end
...so that instead of changing the shield's states according to the player's pw_gravityboots, it did it according to the presence or lack thereof of the MF2_OBJECTFLIP flag2(first one should be "normal gravity = blue orb states", while the second should be "flipped gravity = orange orb states").
Code:
    if not wielder.mo.flags2 & MF2_OBJECTFLIP
    and (actor.state > actor.info.meleestate)
    and (actor.state < actor.info.missilestate)
        actor.state = actor.info.spawnstate
    end
    if wielder.mo.flags2 & MF2_OBJECTFLIP
    and (actor.state > actor.info.spawnstate)
    and (actor.state < actor.info.seestate)
        actor.state = actor.info.meleestate
    end
Not so lucky this time :(. It just spams the console with
Code:
WARNING: luatest.lua:66: attempt to index field 'mo' (a nil value)
Right now, I'm trying to figure out how to fix it.
.
wielder is already set to the player's mo. (As evidenced by the fact that you're using wielder.player to get their player_t userdata.) Just use wielder.flags2 and it'll work.
 
Oh man, this looks great. I'd actually love to use this for a space station level I've been meaning to make for some time now.
 
This definitely looks like something really useful, yeah. Being able to switch gravity at will would be a really cool gimmick for some puzzles.

I look forward to screwing around with this once you're finished with it. :>
 
MAPG0, but change SPStart in MAINCFG to just start a game on it.

Dispoffset determines if the sprite goes in front of or behind the player if they overlap.

Thanks and thanks. Wow, SRB2 has a truckload of stuff nobody uses.

wielder is already set to the player's mo. (As evidenced by the fact that you're using wielder.player to get their player_t userdata.) Just use wielder.flags2 and it'll work.

Code:
WARNING: luatest.lua:66: attempt to perform arithmetic on a boolean value
Code:
    [B]if not wielder.flags2 & MF2_OBJECTFLIP[/B]
    and (actor.state > actor.info.meleestate)
    and (actor.state < actor.info.missilestate)
        actor.state = actor.info.spawnstate
    end
    if wielder.flags2 & MF2_OBJECTFLIP
    and (actor.state > actor.info.spawnstate)
    and (actor.state < actor.info.seestate)
        actor.state = actor.info.meleestate
Still no dice :(

EDIT: OK, if I change the &s for ==s, then the error stops, and the shield turns orange like it should. But it doesn't change back when the player is in normal gravity, which I'm looking into right now.
'nother edit: Nevermind any of that, I was able to fix it. No more stupid HUD arrow now.

Oh man, this looks great. I'd actually love to use this for a space station level I've been meaning to make for some time now.

This definitely looks like something really useful, yeah. Being able to switch gravity at will would be a really cool gimmick for some puzzles.

I look forward to screwing around with this once you're finished with it. :>

As long as credit is given, you are free to use it(once I release it of course). I too look forward to see it being used by others in the future and what kind of puzzles and platforming challenges you guys can come up with!

Updated main post. But for the lazy, there are no glaring issues remaining and all that needs to be done from this point on is to test it and to make that test map. I'm so close to a release!
 
Last edited:
A really cool idea you got there.

It would be a good idea to mix this shield with some kind of puzzle map, just saying. I wanna see this in releases soon. =P
 
Status
Not open for further replies.

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

Back
Top