release: Cheat code module

BlitzMax Forums/BlitzMax Programming/release: Cheat code module

jondecker76(Posted 2010) [#1]
Here is another one of my modules that others may find a use for. This is a simple cheat code module which allows you to embed cheat codes into your games. Admittedly, it is on the simple side (doesn't support key combinations for example), but it is very functional and does what its supposed to.

This is one module where I wouldn't mind expanding on, so if you have any ideas for features, naming conventions and so on, please let me know!

The module can be downloaded at http://code.google.com/p/jmd-blitzmax-modules/downloads/list

To install, just unzip into your mod folder, and build modules (sorry, I don't run Windows and therefore don't compile any of the Windows binaries)

Here is a sample of usage from the documentation:
SuperStrict

Import jmd.cheat

'Create a familiar "up,up,down,down,left,right,left,right,B,A,Enter" cheat code
Local cheatAddLives:TCheat = TCheat.Create(500) 'Note: change the timeout value to be higher to allow for easier cheat code entering!
cheatAddLives.addStroke(KEY_STROKE,KEY_UP)
cheatAddLives.addStroke(KEY_STROKE,KEY_UP)
cheatAddLives.addStroke(KEY_STROKE,KEY_DOWN)
cheatAddLives.addStroke(KEY_STROKE,KEY_DOWN)
cheatAddLives.addStroke(KEY_STROKE,KEY_LEFT)
cheatAddLives.addStroke(KEY_STROKE,KEY_RIGHT)
cheatAddLives.addStroke(KEY_STROKE,KEY_LEFT)
cheatAddLives.addStroke(KEY_STROKE,KEY_RIGHT)
cheatAddLives.addStroke(KEY_STROKE,KEY_B)
cheatAddLives.addStroke(KEY_STROKE,KEY_A)
cheatAddLives.addStroke(KEY_STROKE,KEY_ENTER)

'We are starting with 3 lives
Local lives:Int = 3

'Lets use a fun sound effect for when we perform the cheat code properly!
Local sndCredit:TSound=LoadSound("credit.wav")

Graphics 640,480
While Not KeyDown(KEY_ESCAPE)
	Cls
	DrawText "Lives: " + lives, 10,10
	
	If cheatAddLives.Successful()
		PlaySound(sndCredit)
		lives:+ 30
	EndIf
	Flip
Wend

End



Htbaa(Posted 2010) [#2]
I think you should at least rename your module. Aside from cheats one could also, perhaps, use it to make key combinations for fighting games.


Czar Flavius(Posted 2010) [#3]
This looks like a nice idea! Out of curiosity, where do the key strokes get checked? In Successful? What if the user presses a key that is part of a sequence but he isn't trying to cheat, will the other parts of the program still be able to receive input?


jondecker76(Posted 2010) [#4]
Htbaa: Yes, I was also thinking that a rename is in order - but I'm still stuck on what to call it... I didn't even think about it being useful for fighting game key combinations - but I will keep that in mind now as I develop it further!

Czar Flavius: Yes, key strokes are checked in the Successful method. For this most part, this was a quick proof of concept I threw together last night. At the moment, it does block input from other areas of your code, so I see where that could be a problem - thanks for bringing that to my attention!

My ToDo list for this module is:
[ ] Find a better name for the module
[ ] Make it non-blocking so that it doesn't block input for other areas of code
[ ] Support for "macro" strokes (hitting Down + Left at the same time for one stroke, for example).
[ ] Add support for FryPad module buttons
[ ] Add internal tracking so you can quickly check if a code has been accepted, along with methods to reset the internal tracking


Again, looking improvement/naming suggestions as I do intend to develop on this further!


Czar Flavius(Posted 2010) [#5]
A way to prevent blocking will be to make some kind of generic interface handling system that checks all your key presses and stores whether they have been pressed or not in a bunch of variables. Eg in my games I tend to have globals for left_arrow, right_arrow etc and all the other keys I use. Each cycle, check for key hits and set the global to true or false. Then multiple parts of my program can process user input without blocking other parts.


jondecker76(Posted 2010) [#6]
I've already got a jump on it and I'm testing it right now. Internally, I'm now using KeyDown instead of KeyHit, as it will allow it to act non-blocking. I'm simply using an array to track the state of each key so it only triggers once if it is held. My test is working great, and I've already rewritten some of my internal functions to return arrays of keys/buttons so that I can now add in the Macro support. I figure that today I'll already have macro strokes supported, as well as have if fully non-blocking :)


jondecker76(Posted 2010) [#7]
ok, I've added support for almost everything in my todo list. Now I have a couple of opinion related questions:

-Does anyone see the need to be able to mix keyboard keys and joystick buttons in the same cheat sequence? (for example, keyboard KEY_DOWN,keyboard KEY_UP, keyboard KEY_LEFT, joystick button 0, joystick button 1)

-Would anyone find it useful if one "cheat" instance could have both the joystick and keyboard versions of the sequence? (assuming that we don't intermix the two, as explained above)

- Regarding "macro strokes" (a single stroke consisting of 2 or more buttons/keys) - regardless of the 2 questions above, I would think its fair to at bare minimum say that macro strokes must all be of the same type (keyboard or joystick)



My vote on this is:
-Each cheat sequence can be either Joystick sequences or keyboard sequences (can't intermix the two)
Thus, you declare the type at creation:
cheat:TCheat = CreateCheat(KEY_STROKES,500);stroke type, timeout  millisecs
'OR
cheat:TCheat = CreateCheat(JOY_STROKES,500);stroke type, timeout  millisecs


-I vote that any cheat can NOT hold both a joystick version of the sequence and a keyboard version. It will add un-necessary complexity for little benefit. Thus, if you want a joystick version, and a keyboard version, you will need to create 2 cheat instances!

- On the last issue with macro strokes, I also vote to keep them all the same (either all keyboard or all joystick). I highly doubt anyone would ever want one of their users to have to hold shift+space+joystick button 1 all at the same time to count as one stroke...




I'm going to hold off finishing this module until I get at least a little input, as I do want to make this flexible enough that anyone could get some use out of it.



Regarding a better naming strategy-
SequentialInput module?
MacroInput module?
strokes module?
InputStrokes module?
any other ideas?


thanks


jondecker76(Posted 2010) [#8]
ok, done coding for the night... Against my original thoughts, i went ahead and added a more complex (and flexible) featureset.



Here is where things are:
- Added mouse button support. Keyboard keys, mouse buttons and Joystick buttons are now supported

- Added Tracking to the cheat code sequence. You can now easily check how many times a cheat code sequence has been successfully entered (so that you don't need to use your own variables to track this! Example usage would be that you only want the user to be able use an "Add Ammo" cheat once per game.. )

- Everything is now non-blocking so keystrokes etc.. won't be robbed from your program

- Keyboard keys, mouse buttons and joystick buttons can be "inter-mingled" - meaning that any cheat code can consist of any and all of the 3!

- "Macro strokes" are now fully supported, and can intermingle keyboard keys, mouse buttons and joystick buttons as well! This means that any step of the cheat code sequence can consist of any number of Keyboard keys, mouse buttons or joystick buttons! For example, your cheat code can resemble something as complex as:
KEY_UP+KEY_Down, KEY_SPACE, KEY_Z+MOUSE_BUTTON_1, MOUSE_BUTTON_2+JOY_BUTTON3

- All of the above was accomplished without the need for extra methods or more complex usage! The same few simple methods/function handle everything!








I'm still lost on what to call the module (as it can be used for cheat codes, or sequences used for special moves in fighting games, for example). I'm still open to suggestions!

I'm also open to naming convention suggestions before I release this.. Currently, the interface consists of...
CreateCheat() 'creates a new cheat code
CheatAddStroke() 'adds a stroke or macro stroke to the cheat code sequence
CheatSuccessful() 'returns true for a single call when a cheat is entered successfully
CheatEntered() ' Returns the number of times a cheat has been successfully entered
CheatResetEntered() ' Resets the number of times a cheat has been successfully entered to 0
CheatClear() 'Clears all strokes/macro-strokes from the cheat (Example usage would be that the user changes control configuration - Clear the existing strokes with CheatClear() and add the new ones)

Overall I'm very excited about this module - It started yesterday as a simple proof-of-concept, and already today it is simple to use, feature-rich and pretty much complete! I'll release it as soon as I get some feedback on the naming issues!


Dabhand(Posted 2010) [#9]
Nice idea!

Dabz


jondecker76(Posted 2010) [#10]
The code is now finished. The module has been renamed to inputsequence, and a new thread has been started on it