Lua Help

Status
Not open for further replies.
Here you go:
Code:
freeslot(
"S_HANGON_2")

states[S_HANGON_2] = {SPR_HANG, 0, 1, A_CapeChase, FRACUNIT*0, FRACUNIT*0, S_HANGON_2}

addHook("MobjThinker", function(mobj)
	local player = mobj.player
		if not (player.pflags & PF_NIGHTSMODE) //No Nights Mode Hanger
			if (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING) //Gliders and carried players get a hanger
			if player.hang == nil
				player.hang = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BLACKEGGMAN_MISSILE)
				player.hang.target = player.mo
			if not (player.pflags & PF_CARRIED & PF_GLIDING)
			if not player.hang == nil
			P_RemoveObj(player.hang) //Removing the hanger if you aren't gliding/being carried
				player.hang = nil
				end
            end
        end
    end
end)
 
Here you go:
Code:
freeslot(
"S_HANGON_2")

states[S_HANGON_2] = {SPR_HANG, 0, 1, A_CapeChase, FRACUNIT*0, FRACUNIT*0, S_HANGON_2}

addHook("MobjThinker", function(mobj)
    local player = mobj.player
        if not (player.pflags & PF_NIGHTSMODE) //No Nights Mode Hanger
            if (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING) //Gliders and carried players get a hanger
            if player.hang == nil
                player.hang = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BLACKEGGMAN_MISSILE)
                player.hang.target = player.mo
            if not (player.pflags & PF_CARRIED & PF_GLIDING)
            if not player.hang == nil
            P_RemoveObj(player.hang) //Removing the hanger if you aren't gliding/being carried
                player.hang = nil
                end
            end
        end
    end
end)
Code:
            if not (player.pflags & PF_CARRIED & PF_GLIDING)
I thought we already talked about doing that thing. Derp. And I can count there not being enough "end"s, either. You need an "end" for every end of an "if", BLua doesn't check for more or less whitespace than the previous line. The reason the hanger doesn't work can be found in the console when you load the Wad; the hook gets removed (due to not having enough ends).

Also, I really thought I also went over you had to type in ", MT_PLAYER" between the last "end" and the ending bracket. "end, MT_PLAYER)". Not doing that will just make it run for every single object instead of players only.
 
The "Hang" sprite that tells you where the hanger is (will be invisible in the final version) appears now, which is definitely great news, but whenever the carried player gets off the carrier and gets on again, the hanger disappears. Could this be a problem with P_RemoveObj? Maybe this function is unneeded in this code and the system will already remove it if (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING) returns false?
 
...I just realized something while looking at your Lua again. "PF_GLIDING"? If I recall correctly, PF_THOKKED is the shared flag for every character ability. You might be able to change "or player.pflags & PF_GLIDING" to "or (player.charability == CA_GLIDEANDCLIMB and player.pflags & PF_THOKKED)"... But remember double-jumping with the Whirlwind Shield also sets PF_THOKKED to true, so you may want to change it to "or (player.charability == CA_GLIDEANDCLIMB and player.pflags & PF_THOKKED and (mobj.state == S_PLAY_ABL1 or mobj.state == S_PLAY_ABL2))" instead.

*Checks the Wiki to make sure I didn't misspell something* ...Wait, there IS a PF_GLIDING? But... if that doesn't work, then what is it for? Certainly not for the player ability, I guess?
 
What about this, because S_PLAY_ABL1 and S_PLAY_ABL2 might include gliding, and I want gliding players to be able to carry someone?
Code:
freeslot(
"S_HANGON_2")

states[S_HANGON_2] = {SPR_HANG, 0, 1, A_CapeChase, 0, -12, S_HANGON_2}

addHook("MobjThinker", function(mobj)
	local player = mobj.player
		if (player.pflags & PF_CARRIED or (player.charability == CA_GLIDEANDCLIMB and player.pflags & PF_THOKKED and not (mobj.state == S_PLAY_CLIMB1 or mobj.state == S_PLAY_CLIMB2 or mobj.state == S_PLAY_CLIMB3 or mobj.state == S_PLAY_CLIMB4 or mobj.state == S_PLAY_CLIMB5)) or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG) //Gliders and carried players get a hanger
		if player.hang == nil
			player.hang = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BLACKEGGMAN_MISSILE)
			player.hang.target = player.mo
		if not (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG)
		if not player.hang == nil
			P_RemoveMobj(MT_BLACKEGGMAN_MISSILE) //Removing the hanger if you aren't gliding/being carried
			player.hang = nil
			end
		end
	end
end
end, MT_PLAYER)
Also, I found out that the thinker still runs after the Mobj is removed, so the problem isn't in the removing of it, the problem is respawning it.
 
Code:
freeslot(
"S_HANGON_2")

states[S_HANGON_2] = {SPR_HANG, 0, 1, A_CapeChase, 0, -12, S_HANGON_2}

addHook("MobjThinker", function(mobj)
    local player = mobj.player
        if (player.pflags & PF_CARRIED or (player.charability == CA_GLIDEANDCLIMB and player.pflags & PF_THOKKED and not (mobj.state == S_PLAY_CLIMB1 or mobj.state == S_PLAY_CLIMB2 or mobj.state == S_PLAY_CLIMB3 or mobj.state == S_PLAY_CLIMB4 or mobj.state == S_PLAY_CLIMB5)) or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG) //Gliders and carried players get a hanger
        if player.hang == nil
            player.hang = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BLACKEGGMAN_MISSILE)
            player.hang.target = player.mo
        if not (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG)
        if not player.hang == nil
            P_RemoveMobj(MT_BLACKEGGMAN_MISSILE) //Removing the hanger if you aren't gliding/being carried
            player.hang = nil
            end
        end
    end
end
end, MT_PLAYER)
Uhhmm... I thought I told you to
change it to "or (player.charability == CA_GLIDEANDCLIMB and player.pflags & PF_THOKKED and (mobj.state == S_PLAY_ABL1 or mobj.state == S_PLAY_ABL2))"
(BECAUSE the states include gliding)... and in both occurrences of it...? I don't even understand that Lua script any more...
 
Ah, I see what you mean. I thought that S_PLAY_ABL1 & S_PLAY_ABL2 were gliding AND climbing; I didn't realize that S_PLAY_CLIMB1 - 5 were seperate. I should've known that, because it wouldn't make sense if there were 2 totally different types of states. Also, I removed the Nights Mode thing, because it is unneeded. Still it doesn't show up for Knuckles (at all) or for carried people (only the first time they're picked up).
 
Still it doesn't show up for Knuckles (at all) or for carried people (only the first time they're picked up).
I got no clue about the Knuckles & Knuckles & Knuckles... err, about the Knuckles no-hanger-thing. But for the latter, maybe you can change "if player.hang == nil" to "if player.hang == nil or player.hang == -1", and change "if not player.hang == nil" to "if not (player.hang == nil or player.hang == -1", and then change the "player.hang = nil" after removing the object to "player.hang = -1". Maybe one can't set variables back to nil.
 
Last edited:
Still doesn't work, even after I did this:
Code:
freeslot(
"S_HANGON_2")

states[S_HANGON_2] = {SPR_HANG, 0, 1, A_CapeChase, 0, -12, S_HANGON_2}

addHook("MobjThinker", function(mobj)
    local player = mobj.player
        if (player.pflags & PF_CARRIED or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG) //Gliders and carried players get a hanger
        if player.hang == nil or player.hang == 0
            player.hang = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BLACKEGGMAN_MISSILE)
            player.hang.target = player.mo
			player.hang = 1
        if not (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG)
        if not player.hang == 0
            P_RemoveMobj(MT_BLACKEGGMAN_MISSILE) //Removing the hanger if you aren't gliding/being carried
            player.hang = 0
            end
        end
    end
end
end, MT_PLAYER)
Is it time for a new hook, like ThinkFrame again?
 
Still doesn't work, even after I did this: -Snip- Is it time for a new hook, like ThinkFrame again?
No, it is not time for a new hook, especially not ThinkFrame, it's time to clean up your code, giving each line the proper amount of whitespace in front of it, and adding "end"s at the proper spots.

Edit: Oh my yay, WHY would you set player.hang to 1 after spawning it? WHY would you remove the MT_BLACKEGGMAN_MISSILEnth object? I seriously thought I already went over that!

Edit 2: ...Oh my yay, you are checking for different things between "add a glider now" and "remove the glider"... I give up.
Code:
//Hero Carrying, made by Prisima the Fox, fixed by Zappy
freeslot("S_HANGON_2")
states[S_HANGON_2] = {SPR_HANG, 0, 1, A_CapeChase, 0, -12, S_HANGON_2}

addHook("MobjThinker", function(mobj)
    local player = mobj.player
    if (player.pflags & PF_CARRIED or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG or (player.charability == CA_GLIDEANDCLIMB and player.pflags & PF_THOKKED and (mobj.state == S_PLAY_ABL1 or mobj.state ==  S_PLAY_ABL2))) //Gliders and carried players get a hanger
    and (player.hang == nil or player.hang == 0)
        player.hang = P_SpawnMobj(mobj.x, mobj.y, mobj.z, MT_BLACKEGGMAN_MISSILE)
        player.hang.target = mobj
    else if not (player.hang == nil or player.hang == 0)
        P_RemoveMobj(player.hang) //Removing the hanger if you aren't gliding/being carried
        player.hang = 0
    end
end, MT_PLAYER)
 
Last edited:
Your code had some glitches in it, so I redid mostly everything. It looks promising, but the hook keeps getting removed because of some trivial thing that has to do with a ")". Here it is:
Code:
freeslot(
"S_HANGON_2",
"S_HANGON_5",
"S_HANGON_6")

states[S_HANGON_2] = {SPR_HANG, 0, 1, A_CapeChase, 0, -12, S_HANGON_2}
states[S_HANGON_5] = {SPR_HANG, 0, 1, A_CapeChase, 0, -12, S_HANGON_2}
states[S_HANGON_6] = {SPR_HANG, 0, 1, A_CapeChase, 0, -12, S_HANGON_2}

addHook("MobjThinker", function(mobj)
    local player = mobj.player
		player.hang = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BLACKEGGMAN_MISSILE)
		player.hang.target = player.mo
			if (player.pflags & PF_CARRIED or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG)
				P_SetMobjStateNF(MT_BLACKEGGMAN_MISSILE, S_HANGON_5)
				player.hang = 1
			if not (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG)
			if not player.hang == 0
				P_SetMobjStateNF(MT_BLACKEGGMAN_MISSILE, S_HANGON_6)
				player.hang = 0
				end
			end
		end
	end
end, MT_PLAYER)
The MAINCFG:
Code:
FREESLOT
S_HANGON_1
S_HANGON_2
S_HANGON_3
S_HANGON_4
S_HANGON_5
S_HANGON_6
SPR_HANG


Object MT_BLACKEGGMAN_MISSILE
MapThingNum = -1
SpawnState = S_HANGON_1
SpawnHealth = 1000
SeeState = 0
SeeSound = 0
ReactionTime = 1
AttackSound = 0
PainState = 0
PainChance = 1
PainSound = 0
MeleeState = 0
MissileState = 0
DeathState = 0
XDeathState = 0
DeathSound = 0
Speed = 50*FRACUNIT
Radius = 16*FRACUNIT
Height = 5*FRACUNIT
Mass = 100
Damage = 0
ActiveSound = 0
Flags = MF_RUNSPAWNFUNC|MF_SPECIAL|MF_NOGRAVITY
RaiseState = 0

State S_HANGON_1
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action None
Var1 = 0
Var2 = 0

State S_HANGON_2
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action A_CapeChase
Var1 = 0
Var2 = -12

State S_HANGON_3
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action A_SetObjectFlags
Var1 = MF_NOCLIP|MF_SPECIAL|MF_NOGRAVITY
Var2 = 0

State S_HANGON_4
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action A_SetObjectFlags
Var1 = MF_SPECIAL|MF_NOGRAVITY
Var2 = 0

State S_HANGON_5
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action A_SetObjectFlags
Var1 = S_HANGON_4
Var2 = S_HANGON_2

State S_HANGON_6
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action A_SetObjectFlags
Var1 = S_HANGON_3
Var2 = S_HANGON_2
 
Last edited:
Your code had some glitches in it, so I redid mostly everything. It looks promising, but the hook keeps getting removed because of some trivial thing that has to do with a ")". Here it is: -Snip-
Well, maybe if you... I don't know... didn't totally dis-acknowledge what I made, but actually either used what I made, or edited it, instead of screwing up on the same thing again*? Also why do you even need freeslots in the Lua code when you have freeslots in MainCfg? Oh, wait, you actually don't. Seriously, though, you have too many "end"s, and not enough "end"s. Even if there were the correct amount of "end"s at the correct spots, the hangers would never be removed.

* Okay, sorry, that's a bit of an overkill, you didn't screw up on the same thing again, you just didn't fix it.

One last time... Add proper whitespace so you can see where there should be "end"s and where there shouldn't. Take my fixed thing as example (and don't redo it, edit it, and only if necessary). It has proper whitespace, and as a result proper amounts of "end"s.


Edit: Looking at your code... I thought I already went over trying to do stuff to the MT_BLACKEGGMAN_MISSILEnth object... twice? It looks mostly like you're doing whatever you think is right, and don't really care that much about what I say here.
 
Last edited:
Also why do you even need freeslots in the Lua code when you have freeslots in MainCfg? Oh, wait, you actually don't.

Except you "actually" do.

As long as one thing in the SOC is also used in Lua, you need a freeslot for Lua as well. Plain and simple.

Meanwhile try this:

Code:
local function hangThink(mobj)
	local player = mobj.player
	if (player.pflags & PF_ROPEHANG or player.pflags & PF_CARRIED or player.pflags & PF_ITEMHANG or player.pflags & PF_GLIDING)
	and not player.hanging
		local missile = P_SpawnMobj(player.mo.x, player.mo.y, player.mo.z, MT_BLACKEGGMAN_MISSILE)
		missile.angle = player.mo.angle
		//print("oh goodness")
		missile.target = player.mo
		player.hanging = true
	end	
	if not (player.pflags & PF_CARRIED or player.pflags & PF_GLIDING or player.pflags & PF_ITEMHANG or player.pflags & PF_ROPEHANG)
	and player.hanging == true
		//print("oh snap")
		player.hanging = false
	end
end	
addHook("MobjThinker",hangThink, MT_PLAYER) 

function A_HangChase(actor,var1,var2)
	if not (actor.target.player.pflags & PF_ROPEHANG or actor.target.player.pflags & PF_ITEMHANG or actor.target.player.pflags & PF_CARRIED or actor.target.player.pflags & PF_GLIDING)
		P_RemoveMobj(actor)
	else
		A_CapeChase(actor,var1,var2)
	end
end

FREESLOT
S_HANGON_1
S_HANGON_2
SPR_HANG

Object MT_BLACKEGGMAN_MISSILE
MapThingNum = -1
SpawnState = S_HANGON_1
SpawnHealth = 1000
SeeState = 0
SeeSound = 0
ReactionTime = 1
AttackSound = 0
PainState = 0
PainChance = 1
PainSound = 0
MeleeState = 0
MissileState = 0
DeathState = 0
XDeathState = 0
DeathSound = 0
Speed = 50*FRACUNIT
Radius = 16*FRACUNIT
Height = 5*FRACUNIT
Mass = 100
Damage = 0
ActiveSound = 0
Flags = MF_RUNSPAWNFUNC|MF_NOGRAVITY
RaiseState = 0

State S_HANGON_1
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action None
Var1 = 0
Var2 = 0

State S_HANGON_2
SpriteName = HANG
SpriteFrame = A
Duration = 1
Next = S_HANGON_2
Action A_HangChase
Var1 = 0
Var2 = -12

I just created a custom action that checks if the target has any of those flags, capechases the target if it does, and removes itself if it doesn't. Then I just made a simple check for the player that decides if it has those flags so it can SPAWN the object.

I playtested this, it SHOULD work. And before ZZZ jumps on me for not putting a freeslot on the Lua code, this time it wasn't necessary, as MT_BLACKEGGMAN_MISSILE is an existing object, and I didn't use any states from SOC in Lua.
 
Last edited:
Except you "actually" do.

As long as one thing in the SOC is also used in Lua, you need a freeslot for Lua as well. Plain and simple.
-Snip-
And before ZZZ jumps on me for not putting a freeslot on the Lua code, this time it wasn't necessary, as MT_BLACKEGGMAN_MISSILE is an existing object, and I didn't use any states from SOC in Lua.
Well, I did know freeslots are not required for vanilla things being used... Hm. I just seem to remember custom states I freeslotted in an ObjectCfg once could be applied to a player without freeslotting them in the Lua code.
 
Actually, it's rather a bad idea to have freeslots created in both Lua and SOC simultaneously. Because then you're in fact creating two freeslots for the same thing. This may cause problems, particularly with sprite freeslots as it happens.

If you need to use the names in Lua, you create it only in Lua. After all, order is everything - the freeslots technically won't exist yet in the Lua script if you don't put it there, as Lua always runs before SOC. If you don't put the freeslots there, the Lua script won't recognise the names in the script and will error out if you try to use them like you want them to.

SOC can quite happily use the same names from the Lua freeslots without creating a freeslot block of its own.
 
Last edited:
Thanks Monster Iestyn, fixed. I also noticed that when I did what you told me to, it allocated all the stuff that was in the Freeslot, so I guess that's a good thing. Also, I tried the code Zappy told me to use, but it glitches out with this code and the hanger doesn't appear anymore:
Code:
WARNING: herocarry.wad|LUA_BODY:14: accessed mobj_t doesn't exist anymore, please check 'valid' before using mobj_t.
Hook removed.
EDIT: Wow Zipper, your code actually works! Thanks! I'll just change the offset for it and make it MF2_DONTDRAW, then I'll send it in to releases. Thanks everyone for your help!
 
Last edited:
Status
Not open for further replies.

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

Back
Top