2011-07-04 19:52:53 +00:00
unit Unit10;
2011-10-25 20:44:03 +00:00
{Shared code tutorial}
2011-07-04 19:52:53 +00:00
{$MODE Delphi}
interface
uses
2020-08-21 16:15:09 +02:00
{$ifdef windows} windows, {$endif} LCLIntf, Messages, SysUtils, Classes, Graphics, Controls, Forms,
2021-03-26 00:10:44 +01:00
Dialogs, Unit8, StdCtrls, Buttons, LResources, ExtCtrls, math, betterControls;
2011-10-25 20:44:03 +00:00
type
TPlayer= class
private
public
health: Single ;
boguscrap: dword;
unrelatedrandomlychangingthing: integer ;
team: integer ;
name : string [ 6 3 ] ;
teammate: TPlayer;
healthlabel: TLabel;
wasteofspace: array [ 0 .. 9 9 1 2 3 ] of byte ;
procedure Hit( damage: integer ) ;
end ;
2011-07-04 19:52:53 +00:00
type
{ TForm10 }
TForm10 = class( TForm8)
2011-10-25 20:44:03 +00:00
Button3: TButton;
Button4: TButton;
Button5: TButton;
Button6: TButton;
Button7: TButton;
Button8: TButton;
Label10: TLabel;
2016-09-05 21:17:11 +02:00
Label2: TLabel;
2011-10-25 20:44:03 +00:00
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label8: TLabel;
Label9: TLabel;
2016-09-05 21:17:11 +02:00
Panel1: TPanel;
Panel2: TPanel;
Panel3: TPanel;
Panel4: TPanel;
Panel5: TPanel;
2011-07-04 19:52:53 +00:00
procedure Button2Click( Sender: TObject) ;
procedure Button1Click( Sender: TObject) ;
2011-10-25 20:44:03 +00:00
procedure Button3Click( Sender: TObject) ;
procedure Button4Click( Sender: TObject) ;
procedure Button5Click( Sender: TObject) ;
procedure Button6Click( Sender: TObject) ;
procedure Button7Click( Sender: TObject) ;
procedure Button8Click( Sender: TObject) ;
procedure FormCloseQuery( Sender: TObject; var CanClose: boolean ) ;
2011-07-04 19:52:53 +00:00
procedure FormCreate( Sender: TObject) ;
procedure SpeedButton1Click( Sender: TObject) ;
private
{ Private declarations }
2018-05-29 15:10:22 +02:00
p1, p2, p3, p4: TPlayer;
2020-08-21 16:15:09 +02:00
{$ifdef windows}
2018-05-29 15:10:22 +02:00
procedure LaunchGraphicalTut;
2020-08-21 16:15:09 +02:00
{$endif}
2011-07-04 19:52:53 +00:00
public
{ Public declarations }
end ;
var
Form10: TForm10;
implementation
2021-11-22 21:15:37 +01:00
uses Unit4, frmHelpUnit, cetranslator;
2011-07-04 19:52:53 +00:00
2012-01-04 10:31:22 +00:00
resourcestring
rsThisPlayerIsAlreadyDeadRestartTheGame = 'This player is already dead. Restart the game' ;
rsDEAD = 'DEAD' ;
rsHealth = 'Health: %s' ;
rsStop = 'Stop' ;
rsRestartGameAndAutoplay = 'Restart game and autoplay' ;
rsFailureYourTeamDied = 'Failure. Your team died' ;
rsTryAgain10 = 'Can' 't figure out how to do this? Don' 't worry. Try asking in the forum at cheatengine.org or perhaps someone already explained it better '
+ 'there. Are you sure you want to quit?' ;
rsStep9SharedCodePW = 'Step 9: Shared code: (PW=%s)' ;
rsTutorialStep9=
'This step will explain how to deal with code that is used for other object of the same type' + #13 #10 +
'' + #13 #10 +
2014-06-02 02:27:46 +00:00
'Often when you' 've found health of a unit or your own player, you will find that if you remove the code, it affects ' +
2012-01-04 10:31:22 +00:00
'enemies as well.' + #13 #10 +
'In these cases you must find out how to distinguish between your and the enemies objects.' + #13 #10 +
2014-06-02 02:27:46 +00:00
'Sometimes this is as easy as checking the first 4 bytes (Function pointer table) which often point to a unique location ' +
'for the player, and sometimes it' 's a team number, or a pointer to a pointer to a pointer to a pointer to a pointer to a ' +
2012-01-04 10:31:22 +00:00
'playername. It all depends on the complexity of the game, and your luck' + #13 #10 +
'' + #13 #10 +
2014-06-02 02:27:46 +00:00
'The easiest method is finding what addresses the code you found writes to and then use the dissect data feature to ' +
'compare against two structures. (Your unit(s)/player and the enemies) And then see if you can find out a way to ' +
2012-01-04 10:31:22 +00:00
'distinguish between them.' + #13 #10 +
2014-06-02 02:27:46 +00:00
'When you have found out how to distinguish between you and the computer you can inject an assembler script that ' +
2012-01-04 10:31:22 +00:00
'checks for the condition and then either do not execute the code or do something else. (One hit kills for example)' + #13 #10 +
2014-06-02 02:27:46 +00:00
'Alternatively, you can also use this to build a so called "Array of byte" string which you can use to search which will ' +
'result in a list of all your or the enemies players' +
2012-01-04 10:31:22 +00:00
'' + #13 #10 +
'In this tutorial I have implemented the most amazing game you will ever play.' + #13 #10 +
'It has 4 players. 2 Players belong to your team, and 2 Players belong to the computer. ' + #13 #10 +
'Your task is to find the code that writes the health and make it so you win the game WITHOUT freezing your health' + #13 #10 +
'To continue, press "Restart game and autoplay" to test that your code is correct' + #13 #10 +
'' + #13 #10 +
'' + #13 #10 +
'Tip: Health is a float' + #13 #10 +
'Tip2: There are multiple solutions' ;
2015-09-19 23:20:34 +02:00
rsU10ThisWasTheLastTutorial = 'This was the last tutorial and you skipped it. You lose' ;
2012-01-04 10:31:22 +00:00
2011-10-25 20:44:03 +00:00
procedure TPlayer. Hit( damage: integer ) ;
var x: single ;
begin
if health= 0 then
begin
2012-01-04 10:31:22 +00:00
showmessage( rsThisPlayerIsAlreadyDeadRestartTheGame) ;
2011-10-25 20:44:03 +00:00
exit;
end ;
x: = max( 0 , health- damage) ;
health: = x;
if health= 0 then
2012-01-04 10:31:22 +00:00
healthlabel. Caption: = rsDEAD
2011-10-25 20:44:03 +00:00
else
2012-01-04 10:31:22 +00:00
healthlabel. caption: = Format( rsHealth, [ FloatToStr( health) ] ) ;
2011-10-25 20:44:03 +00:00
unrelatedrandomlychangingthing: = random( 5 0 0 0 0 0 0 ) ;
end ;
2011-07-04 19:52:53 +00:00
2018-05-29 15:10:22 +02:00
2020-08-21 16:15:09 +02:00
{$ifdef windows}
2018-05-29 15:10:22 +02:00
procedure TForm10. LaunchGraphicalTut;
var nexttut: string ;
filename: string ;
begin
filename: = 'gtutorial-' + {$ifdef cpu32} 'i386' {$else} 'x86_64' {$endif} + '.exe' ;
nexttut: = ExtractFilePath( application. ExeName) + filename;
if fileexists( nexttut) then
begin
//launch the graphical tutorial
2020-08-21 16:15:09 +02:00
2018-05-29 15:10:22 +02:00
ShellExecute( 0 , PChar( 'open' ) , PChar( nexttut) , PChar( '' ) , PChar( extractfilepath( nexttut) ) , SW_SHOW) ;
ExitProcess( 0 ) ;
end ;
nexttut: = ExtractFileDir( application. ExeName) ;
if ExtractFileName( nexttut) = 'bin' then
begin
nexttut: = ExtractFilePath( nexttut) + 'tutorial\graphical\' + filename;
if fileexists( nexttut) then
begin
//launch the graphical tutorial
ShellExecute( 0 , PChar( 'open' ) , PChar( nexttut) , PChar( '' ) , PChar( extractfilepath( nexttut) ) , SW_SHOW) ;
ExitProcess( 0 ) ;
end ;
end ;
end ;
2020-08-21 16:15:09 +02:00
{$endif}
2018-05-29 15:10:22 +02:00
2011-07-04 19:52:53 +00:00
procedure TForm10. Button2Click( Sender: TObject) ;
begin
2020-08-21 16:15:09 +02:00
{$ifdef windows}
2018-05-29 15:10:22 +02:00
LaunchGraphicalTut;
2020-08-21 16:15:09 +02:00
{$endif}
2011-07-04 19:52:53 +00:00
hide;
form4: = tform4. create( self) ;
form4. show;
2019-07-19 11:27:16 +02:00
frmHelp. free;
frmHelp: = nil ;
2020-08-21 16:15:09 +02:00
2011-07-04 19:52:53 +00:00
end ;
procedure TForm10. Button1Click( Sender: TObject) ;
begin
2011-10-25 20:44:03 +00:00
end ;
procedure TForm10. Button3Click( Sender: TObject) ;
var z: pchar ;
begin
//memoryleak on purpose
p1: = TPlayer. Create;
p1. name : = 'Dave' ;
p1. health: = 1 0 0 ;
p1. boguscrap: = random( 1 0 0 0 0 ) ;
p1. team: = 1 ;
p1. healthlabel: = Label4;
2012-01-04 10:31:22 +00:00
p1. healthlabel. caption: = Format( rsHealth, [ FloatToStr( p1. health) ] ) ;
2011-10-25 20:44:03 +00:00
getmem( z, 1 + random( 9 0 0 0 0 ) ) ;
p2: = TPlayer. Create;
p2. name : = 'Eric' ;
p2. health: = 1 0 0 ;
p2. boguscrap: = random( 1 0 0 0 0 ) ;
p2. team: = 1 ;
p2. healthlabel: = Label6;
2012-01-04 10:31:22 +00:00
p2. healthlabel. caption: = Format( rsHealth, [ FloatToStr( p2. health) ] ) ;
2011-10-25 20:44:03 +00:00
p1. teammate: = p2;
p2. teammate: = p1;
getmem( z, 1 + random( 9 0 0 0 0 ) ) ;
p3: = TPlayer. Create;
p3. name : = 'HAL' ;
p3. health: = 5 0 0 ;
p3. boguscrap: = random( 1 0 0 0 0 ) ;
p3. team: = 2 ;
p3. healthlabel: = label8;
2012-01-04 10:31:22 +00:00
p3. healthlabel. caption: = Format( rsHealth, [ FloatToStr( p3. health) ] ) ;
2011-10-25 20:44:03 +00:00
getmem( z, 1 + random( 9 0 0 0 0 ) ) ;
p4: = TPlayer. Create;
p4. name : = 'KITT' ;
p4. health: = 5 0 0 ;
p4. boguscrap: = random( 1 0 0 0 0 ) ;
p4. team: = 2 ;
p4. healthlabel: = label10;
2012-01-04 10:31:22 +00:00
p4. healthlabel. caption: = Format( rsHealth, [ FloatToStr( p4. health) ] ) ;
2011-10-25 20:44:03 +00:00
p3. teammate: = p4;
p4. teammate: = p3;
end ;
procedure TForm10. Button4Click( Sender: TObject) ;
begin
p3. Hit( 1 + random( 1 ) ) ;
end ;
procedure TForm10. Button5Click( Sender: TObject) ;
begin
p4. Hit( 1 + random( 1 ) ) ;
end ;
procedure TForm10. Button6Click( Sender: TObject) ;
begin
2012-01-04 10:31:22 +00:00
if button6. Caption= rsStop then
2011-07-04 19:52:53 +00:00
begin
2012-01-04 10:31:22 +00:00
button6. Caption: = rsRestartGameAndAutoplay;
2011-10-25 20:44:03 +00:00
exit;
2011-07-04 19:52:53 +00:00
end ;
2011-10-25 20:44:03 +00:00
button3. Click;
2012-01-04 10:31:22 +00:00
button6. Caption: = rsStop;
2011-07-04 19:52:53 +00:00
2012-01-04 10:31:22 +00:00
while button6. Caption= rsStop do
2011-10-25 20:44:03 +00:00
begin
if p1. health> 0 then p1. Hit( 2 + random( 5 ) ) ;
if p2. health> 0 then p2. Hit( 2 + random( 5 ) ) ;
if p3. health> 0 then p3. Hit( 1 + random( 1 ) ) ;
if p4. health> 0 then p4. Hit( 1 + random( 1 ) ) ;
application. ProcessMessages;
if ( p1. health= 0 ) and ( p2. health= 0 ) then
begin
2012-01-04 10:31:22 +00:00
ShowMessage( rsFailureYourTeamDied) ;
button6. Caption: = rsRestartGameAndAutoplay;
2011-10-25 20:44:03 +00:00
break;
end ;
if ( p3. health= 0 ) and ( p4. health= 0 ) then
begin
button2. enabled: = true ;
2012-01-04 10:31:22 +00:00
button6. Caption: = rsRestartGameAndAutoplay;
2011-10-25 20:44:03 +00:00
break;
end ;
end ;
end ;
2011-07-04 19:52:53 +00:00
2011-10-25 20:44:03 +00:00
procedure TForm10. Button7Click( Sender: TObject) ;
begin
p2. Hit( 2 + random( 5 ) ) ;
end ;
2011-07-04 19:52:53 +00:00
2011-10-25 20:44:03 +00:00
procedure TForm10. Button8Click( Sender: TObject) ;
begin
p1. Hit( 2 + random( 5 ) ) ;
end ;
2011-07-04 19:52:53 +00:00
2011-10-25 20:44:03 +00:00
procedure TForm10. FormCloseQuery( Sender: TObject; var CanClose: boolean ) ;
begin
2012-01-04 10:31:22 +00:00
canclose: = MessageDlg( rsTryAgain10, mtconfirmation, [ mbyes, mbno] , 0 ) = mryes;
2011-07-04 19:52:53 +00:00
end ;
procedure TForm10. FormCreate( Sender: TObject) ;
begin
2016-09-05 21:17:11 +02:00
2011-10-25 20:44:03 +00:00
//31337157
2021-11-22 21:15:37 +01:00
caption: = altnamer( caption) ;
memo1. lines. text : = altnamer( rsTutorialStep9) ;
2012-01-04 10:31:22 +00:00
memo1. Lines. Insert( 0 , Format( rsStep9SharedCodePW, [ inttostr( 3 1 3 ) + inttostr( 3 7 1 5 7 ) ] ) ) ;
2011-10-25 20:44:03 +00:00
button3. Click;
2016-09-05 21:17:11 +02:00
font. size: = 1 2 ;
2019-07-19 11:27:16 +02:00
frmHelp. attach( self, '9' ) ;
2011-07-04 19:52:53 +00:00
end ;
procedure TForm10. SpeedButton1Click( Sender: TObject) ;
begin
2020-08-21 16:15:09 +02:00
{$ifdef windows}
2018-05-29 15:10:22 +02:00
LaunchGraphicalTut;
2020-08-21 16:15:09 +02:00
{$endif}
2015-09-19 23:20:34 +02:00
showmessage( rsU10ThisWasTheLastTutorial) ;
2011-07-04 19:52:53 +00:00
Application. Terminate;
end ;
initialization
{$i Unit10.lrs}
end .