fabiangreffrath / crispy-doom

Crispy Doom is a limit-removing enhanced-resolution Doom source port based on Chocolate Doom.
https://fabiangreffrath.github.io/crispy-homepage
GNU General Public License v2.0
805 stars 132 forks source link

disable cheats during demo recording #218

Closed SoDOOManiac closed 7 years ago

SoDOOManiac commented 7 years ago

Yesterday a demo-related topic has arisen...I tried entering IDFA when recording a demo, fired the chaingun a bit and the result was striking: when I played back the demo, it played as if I just fired the pistol and didn't enter any cheat!

SoDOOManiac commented 7 years ago

p.s. started with just a pistol

fabiangreffrath commented 7 years ago

Yes, of course. Demos are supposed to desync in this case, cheater! ;)

SoDOOManiac commented 7 years ago

LOL) Why not disable cheats while recording demos then?)))

fabiangreffrath commented 7 years ago

Because (1) that's Vanilla behaviour and (2) there are also harmless but useful cheats, e.g. IDDT, IDBEHOLDL, IDMYPOS, SHOWFPS.

SoDOOManiac commented 7 years ago

OK, so maybe disable only gameplay-violating ones?

fabiangreffrath commented 7 years ago

Since the cheating system is shared among all four games, this would kill the three non-Doom ports. :(

fabiangreffrath commented 7 years ago

Since the cheating system is shared among all four games, this would kill the three non-Doom ports

Okay, so why is this?

I'd prefer to implement Boom's approach where each cheat gets a "tag" which determines in which situations the cheat is invalid. However, I would have to add support for this in the CHEAT definition in m_cheat.h and in cht_CheckCheat() in m_cheat.c.

The former, however, is also used by the three non-Doom games, so I would have to adjust them as well in order to keep them buildable, which I somehow would like to maintain. The latter doesn't know about gamestates such as netgame, deathmatch, demorecording, demoplayback and menuactive, for the same reason that it is meant to remain game-agnostic.

As an alternative, I could implement a similar check in st_stuff.c and manually add it to each cheat call in ST_Responder().

fabiangreffrath commented 7 years ago

How to proceed with Nightmare skill mode? Cheats are completely disabled in Vanilla, except for IDCLEV, but they are all allowed in Boom... :/

SoDOOManiac commented 7 years ago

In fact I can't decide between the ways you suggest to handle this request, so let it just hang for a while, I think.

fabiangreffrath commented 7 years ago

I have some code ready that I may commit to the "features" branch tomorrow. For now, I have decided to stay close to Vanilla and forbid all but the most harmless cheats in Nightmare difficulty.

fabiangreffrath commented 7 years ago

In Vanilla Doom we have three "categories" of cheats:

As a rule of thumb, I would like to remain as close as possible to the schema as possible, i.e. only add restrictions where necessary and remove restrictions only where strictly possible.

I am going to introduce something like the following "tags" for each cheat which determine which restrictions apply:

    cht_always = 0,
    cht_nonm   = 1,
    cht_nodm   = 2,
    cht_nocoop = 4,
    cht_nodemo = 8,
    cht_nomenu = 16,
    cht_nonet  = cht_nodm | cht_nocoop,
    cht_never  = cht_nonm | cht_nonet | cht_nodemo

I suggest applying the following tags to the present patches, please share your thoughts (this is more in line with Vanilla than Boom by intent);

cht_CheckCheatTag(&cheat_amap, ev->data2, cht_always))
cht_CheckCheatTag(&cheat_god, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_ammonokey, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_ammo, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_massacre, ev->data2, cht_never)
cht_CheckCheatTag(&cheat_massacre2, ev->data2, cht_never)
cht_CheckCheatTag(&cheat_massacre3, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_spechits, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_hom, ev->data2, cht_always))
cht_CheckCheatTag(&cheat_mus, ev->data2, cht_always))
cht_CheckCheatTag(&cheat_noclip, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_commercial_noclip,ev->data2, cht_never)))
cht_CheckCheatTag(&cheat_notarget, ev->data2, cht_never)
cht_CheckCheatTag(&cheat_notarget2, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_nomomentum, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_showfps, ev->data2, cht_always)
cht_CheckCheatTag(&cheat_showfps2, ev->data2, cht_always))
cht_CheckCheatTag(&cheat_goobers, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_powerup[i], ev->data2, i < 4 ? cht_never : cht_nodm))
cht_CheckCheatTag(&cheat_powerup[7], ev->data2, cht_never))
cht_CheckCheatTag(&cheat_powerup[6], ev->data2, cht_nodm))
cht_CheckCheatTag(&cheat_weapon, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_choppers, ev->data2, cht_never))
cht_CheckCheatTag(&cheat_mypos, ev->data2, cht_always))
cht_CheckCheatTag(&cheat_version, ev->data2, cht_always))
cht_CheckCheatTag(&cheat_clev, ev->data2, cht_nomenu | cht_nonet))