Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
I'm trying to create a player class that looks different at various stages of the game. I'd rather not use morphing.
The principle of what I have done is reasonably simple. Every state in the player has a check for an inventory item and jumps to the appropriate state based on whether the item is there or not. It works, up to a point, but I have come across a problem that I don't know how to fix.
ACTOR TestGuy : PlayerPawn
{
Speed 1
Health 100
Radius 16
Height 56
Mass 100
PainChance 255
Player.ColorRange 0, 0
Player.DisplayName "TestGuy"
Player.RunHealth 15
Player.ViewHeight 52
Player.AttackZOffset 24
Player.StartItem "Pistol"
Player.StartItem "Shotgun"
Player.StartItem "Clip" 50
Player.StartItem "Shell" 50
States
{
Spawn:
TNT1 A 0 A_JumpIfInventory ("QuestItem1", 1, "SpawnShotgunGuy")
//fallthrough
SpawnZombie:
POSS A 1
Goto Spawn
SpawnShotgunGuy:
SPOS A 1
Goto Spawn
See:
TNT1 A 0 A_JumpIfInventory ("QuestItem1", 1, "SeeShotGunGuy")
//fallthrough
SeeZombie:
POSS ABCD 4
Goto See
SeeShotgunGuy:
SPOS ABCD 4
Goto See
Missile:
TNT1 A 0 A_JumpIfInventory ("QuestItem1", 1, "MissileShotgunGuy")
//fallthrough
MissileZombie:
POSS E 3
POSS F 3
Goto Spawn
MissileShotgunGuy:
SPOS E 3
SPOS F 3
Goto Spawn
Melee:
TNT1 A 0 A_JumpIfInventory ("QuestItem1", 1, "MeleeShotgunGuy")
//fallthrough
MeleeZombie:
POSS EE 3
Goto Spawn
MeleeShotgunGuy:
SPOS EE 3
Goto Spawn
Pain:
TNT1 A 0 A_JumpIfInventory ("QuestItem1", 1, "PainShotgunGuy")
//fallthrough
PainZombie:
POSS G 4
POSS G 4 A_Pain
Goto Spawn
PainShotgunGuy:
SPOS G 4
SPOS G 4 A_Pain
Goto Spawn
Death:
TNT1 A 0 A_JumpIfInventory ("QuestItem1", 1, "DeathShotgunGuy")
//fallthrough
DeathZombie:
POSS H 4 A_PlayerScream
POSS I 3 A_NoBlocking
POSS JK 3
POSS L -1
Stop
DeathShotgunguy:
SPOS H 4 A_PlayerScream
SPOS I 3 A_NoBlocking
SPOS JK 3
SPOS L -1
Stop
}
}
That makes you look like a zombieman when you first appear on the map and if you type "give QuestItem1" at the console, your appearance changes to that of a Shotgunguy. So far so good but there is a problem with the shotgunguy animation. Instead of cycling through his walking animation, he just gets stuck on a single frame and glides around the map on one foot. I think he is getting stuck in his spawn state so the alternative that I have come up with is to make the spawn state animated. This looks fine when you are moving but, obviously, it looks like you are running on the spot when you stop.
Try the attached (just the above bundled into a zip). Load the zip and start a game. Switch on chasecam and you'll see that you look like a zombieman. Run around, shoot stuff, whatever, it all works. Now type "give QuestItem1" and you'll see your appearance change to that of a shotgun guy. Now run around and you'll see that your moving animation, well, isn't an animation. Everything else seems to work, it's just the running around stuff that's borked.
If you comment out the first A_JumpIfInventory (in Spawn), and set the end of the See states to "Goto Spawn", it works more or less, although you still look like a ZombieMan when not moving.
Player states are handled weirdly, unlike monsters which use code pointers to know when they can change state. (I.E. to attack.) Most of the stock states may be interrupted to change to another state, even mid-frame.
Seems like once it jumps, it loses track of the fact that you're in the Spawn state, and thus that movement should initiate the See state. Also, See appears to lose track as well - if you have it Goto See, you'll get stuck in an endless walking loop. Strangely, attacking overrides either.
This may be a bug... I hope so, as otherwise this is a nasty problem.
I've pissed about with playerclasses for a longer time than I had hoped to, but from what I see it should be working just fine. Can you try a different Jump method (i.e not inventory) and see if that fairs any better?
Nope, replacing the first jump with "TNT1 A 0 A_Jump (255, "SpawnShotgunGuy")" still leaves him stuck in the single frame spawn state.
I can kind of see why it's happening. Just following the logic through step by step it does make sense, kind of. I just wish that it worked as intended.
I know it's awkward but you could try not using different state labels and use numeric jumps, so it's all in the same state. I *think* what's happening is, ZDoom notices that you're not in the see state (or shooting/in pain/dying) and you're also moving so it thinks "Ok put him in the see state".
Overall though this is a horribly hacky way to do this and I would try some other method (granted I don't know what that method is yet).
Cutmanmike wrote:I know it's awkward but you could try not using different state labels and use numeric jumps, so it's all in the same state.
Technically, a state is a single "frame" (and a frame is what happens during a single tic). There is no way in ZDoom to know that you are in the "See" or whatever other state sequence. In other words, when you have this for the shotgun guy:
You do not define a See state. You define a See state (SPOS A 3 A_Chase) and seven other states that follow it. Let's say you're in the second B state, as far as the code is concerned, you're not in the See state. It's See+3, but it's also Spawn+5, or Missile-5...
I've actually ran across a problem like this myself. I tried to give my player class a simple 'idle' animation (a la Strife's rebels) when standing still, but I noticed that the only time the sprites would ever correctly jump to the walking animation when starting to move is if the class was not in the middle of the animation (i.e. at the very first, literal Spawn state). Otherwise, the player would 'slide' along the ground while moving (as Enjay described), with the 'idle' animation still playing out.
It seems that ZDoom is only checking to go into the walking animation when at the very first state, since (as Gez has stated) there is no way for the engine to know what state sequence it's in once it's past the first frame (though I admit I'm probably missing a bastardload of finer details about this). Though unfortunate, I still wonder if it would be possible somehow to implement an A_PlayerIdle action (in the vein of A_WeaponReady) that signals to the engine that the animation should immediately jump to See* once the player starts moving.
*Of course, if such an action is implemented, a state-to-jump-to parameter wouldn't hurt either. Optional, though.
Xaser wrote:Though unfortunate, I still wonder if it would be possible somehow to implement an A_PlayerIdle action (in the vein of A_WeaponReady) that signals to the engine that the animation should immediately jump to See* once the player starts moving.
*Of course, if such an action is implemented, a state-to-jump-to parameter wouldn't hurt either. Optional, though.
I thought about that too, but then you'd also need something to check the See state to make it stop looping. That was the other problem I found.
A second action wouldn't hurt for that, but honestly it shouldn't be necessary in this case since the switching from See back to Spawn already works fine (or seems to, in my experience).
Xaser wrote:A second action wouldn't hurt for that, but honestly it shouldn't be necessary in this case since the switching from See back to Spawn already works fine (or seems to, in my experience).
It didn't in this case. Instead of a sliding sergeant, I got a hyperactive one that continued to loop his "See" state, until I told it to go back to Spawn after each loop. Even then, I got an extra tic of the A frame in Spawn in each loop.
Another benefit of a matching command for See: By using the command in each frame, you could terminate and go immmediately back to Spawn instead of finishing the walking animation.
Even assuming these codepointers were possible, we'd probably also need a flag to disable the "vanilla" handling method, as it of course should still remain default.
Well, it seems from this discussion that what I kind of thought might be going on, probably is the situation (ie, what Gez described). Some way of over-riding this would be welcome though.
BTW, I had tried jumping by offset rather than state labels but that didn't work. (Which is, again, consistent with what Gez said).
I am sorry for bumping this- But I have the same issue and I am wondering If you have solved it. In my mod I have the player changing his walking/shooting frames to mirror what weapon he is holding. I ended up just doing this ONLY with the punching animations- because the player gets stuck in a looping walking state only interrupted when hitting the attack button. I don't mind this so much because he looks like he is bobbing and weaving for melee fight. However, I didn't wanna do the same things with other weapons because I don't want him doing the same thing while holding a gun. ( For the guns, I settled on seperate "blast" animations for the shooting states).
So, basically, its easy to alternate the shooting states, but the walking states will be stuck in a loop.
I am using "jumpinventory" on each seperate step the player is walking. That seems to be the best way to do it.
I tried "numeric jumps", it didn't seem to do the job.
Again, its easy to change the shooting states, but the walking states appear to be an issue. Anyone able to work around it?
Sorry, no, I didn't manage to get around it. The mod that I was actually trying to do this with was Paranoid and, if you use chasecam in that, you'll see that the scientist appearance at the start before you get the HEV suit exhibits this problem.
Hmmm.....Thanks for the reply. I am comfortable with how my player acts in game so far. I doubt I will find another solution, atleast before anyone else here does, but if i do i will post it.
Edit: This just popped in my head- I haven't thought it through....
What if one were to change the basic walking sprites to just a bottom half of the body- just the waist and legs....
And on each step, have the player spawn an upper torso...
Each torso would be holding a diff gun....
Hmm... I suppose that would be too "hacky", huh....meh, just brainstorming. lol.