Page Menu
Home
Phabricator (Chris)
Search
Configure Global Search
Log In
Files
F132766
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
13 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/data/script/Backend.pl b/data/script/Backend.pl
index 5ad1f7a..ee3f7a8 100644
--- a/data/script/Backend.pl
+++ b/data/script/Backend.pl
@@ -1,601 +1,594 @@
#!/usr/bin/perl -w
# PERL backend for the game
=comment
This is the main perl backend for Mortal Szombat. It loads the other files,
compiles characters, creates shared variables.
1. FIGHTER ACTIONS
1.1. BASIC MOVEMENT 1.2. OFFENSIVE MOVES 1.3. HURT MOVES
Start KneelingPunch Falling
Stand KneelingKick Laying
Walk KneelingUppercut Getup
Back HighPunch HighPunched
Turn LowPunch LowPunched
Hurt HighKick GroinKicked
Block LowKick KneelingPunched
Kneeling Sweep KneelingKicked
Onknees GroinKick Thrown
Jump KneeKick Dead
JumpFW Elbow
JumpBW Grenade
Fun Uppercut
Threat Throw
[fighter-specific stuff]
=cut
=comment
MAIN CONSTANTS
=cut
$GAMEBITS = 3; # Number of oversampling bits in coordinates
$GAMEBITS2 = 1 << $GAMEBITS; # 2^(oversampling)
$SCRWIDTH = 640; # The physical horizontal screen resolution
$SCRHEIGHT = 480; # The physical vertical screen resolution
$SCRWIDTH2 = ($SCRWIDTH << $GAMEBITS); # The logical horizontal screen resolution
$SCRHEIGHT2 = ($SCRHEIGHT << $GAMEBITS); # The logical vertical screen resolution
$MOVEMARGIN2= 50 << $GAMEBITS; # The logical border for fighters.
$BGWIDTH2 = 1920 << $GAMEBITS; # The logical background width
$BGHEIGHT2 = 480 << $GAMEBITS; # The logical background height
$GROUND2 = 160 << $GAMEBITS; # The logical ground level.
$DELMULTIPLIER = 1; # DEL values in states are multiplied by this.
$MAXCOMBO = 5; # Maximum combo count.
$BgMax = $BGWIDTH2 - $SCRWIDTH2; # The logical maximum camera position
$BgSpeed = 0; # The current speed of the background movement
$BgPosition = $BgMax >> 1; # The logical camera position
$BgScrollEnabled = 1; # Can the background scroll?
$HitPointScale = 10; # Scale the hit points by this.
$NextDoodad = 0; # The next doodad to process
$Debug = 0;
require 'PlayerInput.pl';
require 'Fighter.pl';
require 'FighterStats.pl';
require 'Doodad.pl';
require 'Keys.pl';
require 'State.pl';
require 'Translate.pl';
=comment
MAIN OBJECTS
=cut
$Fighter1 = Fighter->new();
$Fighter2 = Fighter->new();
$Fighter1->{NUMBER} = 0;
$Fighter1->{OTHER} = $Fighter2;
$Fighter2->{NUMBER} = 1;
$Fighter2->{OTHER} = $Fighter1;
@Fighters = ( $Fighter1, $Fighter2 );
=comment
VARIABLES FOR DRAWING THE SCENE
=cut
$p1x = 10; # Player 1 X position
$p1y = 100; # Player 1 Y position
$p1f = 10; # Player 1 frame
$p1h = 100; # Player 1 HP
$p2x = 400; # Player 2 X position
$p2y = 100; # Player 2 Y position
$p2f = -40; # Player 2 frame. Negative means flipped.
$p2h = 100; # Player 2 HP
$bgx = 0; # Background X position
$bgy = 0; # Background Y position
-$time = 0; # Current game time
$over = 0; # Is the game over?
$ko = 0; # Is one fighter knocked down?
$doodad_x = -1; # Doodad X position
$doodad_y = -1; # Doodad Y position
$doodad_t = -1; # Doodad type
$doodad_f = -1; # Doodad frame number
$doodad_dir = 0; # The direction of the doodad; 1: normal; -1: flipped
$doodad_gfxowner = -1; # 0: first player; 1: second player; 2: Global doodad
$doodad_text = ''; # The text of type 0 doodads.
=comment
JUDGEMENT METHODS
=cut
sub JudgementStart
{
$bgx = 0;
$bgy = ( $SCRHEIGHT2 - $BGHEIGHT2 ) >> 1;
$BgSpeed = 0;
$BgPosition = 0;
$BgScrollEnabled = 0;
$OverTimer = 0;
$JudgementMode = 1;
$Debug = 0;
($JudgementWinner) = @_;
ResetEarthquake();
- $time = 0;
$over = 0;
$Fighter1->Reset();
$Fighter1->{X} = ($JudgementWinner ? 150 : 520 ) * $GAMEBITS2;
$Fighter1->{DIR} = ($JudgementWinner ? 1 : -1 );
$Fighter1->{NEXTST} = 'Stand';
$Fighter1->Update();
$Fighter2->Reset();
$Fighter2->{X} = ($JudgementWinner ? 520 : 150 ) * $GAMEBITS2;
$Fighter2->{DIR} = ($JudgementWinner ? -1 : 1 );
$Fighter2->{NEXTST} = 'Stand';
$Fighter2->Update();
$Input1->Reset();
$Input2->Reset();
}
=comment
PLAYER SELECTION METHODS
=cut
sub SelectStart
{
$bgx = 0;
$bgy = ( $SCRHEIGHT2 - $BGHEIGHT2 ) >> 1;
$BgSpeed = 0;
$BgPosition = 0;
$BgScrollEnabled = 0;
$OverTimer = 0;
$JudgementMode = 0;
$Debug = 0;
ResetEarthquake();
- $time = 0;
$over = 0;
if ( $Fighter1->{OK} )
{
$Fighter1->Reset();
$Fighter1->{X} = 80 * $GAMEBITS2;
$Fighter1->{NEXTST} = 'Stand';
$Fighter1->Update();
}
if ( $Fighter2->{OK} )
{
$Fighter2->Reset();
$Fighter2->{X} = 560 * $GAMEBITS2;
$Fighter2->{NEXTST} = 'Stand';
$Fighter2->Update();
}
$Input1->Reset();
$Input2->Reset();
}
sub SetPlayerNumber
{
my ($player, $fighterenum) = @_;
my ($f);
DeleteDoodadsOf( $player );
$f = $player ? $Fighter2 : $Fighter1;
$f->Reset($fighterenum);
$f->{NEXTST} = 'Stand';
$f->Update();
- $::PlayerName = $::FighterStats[$fighterenum]->{NAME};
+ GetFighterStats($fighterenum);
+ $::PlayerName = $::Name
}
sub PlayerSelected
{
my ($number) = @_;
my ($f) = $number ? $Fighter2 : $Fighter1;
$f->Event( 'Won' );
$f->Update();
}
=comment
EARTHQUAKE RELATED METHODS
=cut
@QUAKEOFFSET = ( 0, 6, 11, 15,
16, 15, 11, 6,
0, -6,-11,-15,
-16,-15,-11, -6, 0, 6 );
sub ResetEarthquake
{
$QuakeAmplitude = 0;
$QuakeOffset = 0;
$QuakeX = 0;
$QuakeY = 0;
}
sub AddEarthquake
{
my ($amplitude) = @_;
$QuakeAmplitude += $amplitude;
$QuakeAmplitude = 20 if ( $QuakeAmplitude > 20 );
}
sub AdvanceEarthquake
{
if ( $QuakeAmplitude <= 0.2 )
{
$QuakeAmplitude = $QuakeX = $QuakeY = 0;
return;
}
$QuakeAmplitude -= $QuakeAmplitude / 30 + 0.1;
$QuakeOffset = ( $QuakeOffset + 1 ) % 16;
$QuakeX = $QUAKEOFFSET[$QuakeOffset] * $QuakeAmplitude / 16;
$QuakeY = $QUAKEOFFSET[$QuakeOffset + 1] * $QuakeAmplitude / 16; # 1/1
$bgx -= $QuakeX;
$bgy -= $QuakeY;
$p1x += $QuakeX;
$p1y += $QuakeY;
$p2x += $QuakeX;
$p2y += $QuakeY;
# Do not quake doodads for now.
}
=comment
GAME BACKEND METHODS
=cut
sub GameStart
{
my ( $MaxHP, $debug ) = @_;
@Doodads = ();
@Sounds = ();
$bgx = ( $SCRWIDTH2 - $BGWIDTH2) >> 1;
$bgy = ( $SCRHEIGHT2 - $BGHEIGHT2 ) >> 1;
$BgSpeed = 0;
$BgPosition = $BgMax >> 1;
$BgScrollEnabled = 1;
$HitPointScale = 1000 / $MaxHP; # 1/1
$Debug = $debug;
ResetEarthquake();
- $time = 0;
$Fighter1->Reset();
$Fighter1->{HP} = $MaxHP;
$Input1->Reset();
$Fighter2->Reset();
$Fighter2->{HP} = $MaxHP;
$Input2->Reset();
$over = 0;
$ko = 0;
$OverTimer = 0;
$JudgementMode = 0;
$p1h = $p2h = 0;
}
sub GetFighterData
{
my ($fighter) = @_;
my ($x, $y, $fnum, $f, $hp);
$fnum = $fighter->{FR};
$f = $fighter->{FRAMES}->[$fnum];
$x = $fighter->{X} / $GAMEBITS2 + $f->{'x'};
$y = $fighter->{Y} / $GAMEBITS2 + $f->{'y'};
if ($fighter->{DIR}<0)
{
$fnum = -$fnum;
$x -= $f->{x}*2 + $f->{w};
}
return ($x, $y, $fnum);
}
sub GetNextDoodadData
{
if ( $NextDoodad >= scalar @Doodads )
{
$doodad_x = $doodad_y = $doodad_t = $doodad_f = $doodad_dir = $doodad_gfxowner = -1;
$doodad_text = '';
return;
}
my ($doodad) = $Doodads[$NextDoodad];
$doodad_x = $doodad->{POS}->[0] / $GAMEBITS2 - $bgx;
$doodad_y = $doodad->{POS}->[1] / $GAMEBITS2 - $bgy;
$doodad_t = $doodad->{T};
$doodad_f = $doodad->{F};
$doodad_dir = $doodad->{DIR};
$doodad_gfxowner = $doodad->{GFXOWNER};
$doodad_text = $doodad->{TEXT};
if ($doodad_gfxowner < 2 )
{
$doodad_x += $Fighters[$doodad_gfxowner]->{FRAMES}->[$doodad_f]->{'x'} * $doodad_dir;
$doodad_y += $Fighters[$doodad_gfxowner]->{FRAMES}->[$doodad_f]->{'y'};
}
++$NextDoodad;
}
sub UpdateDoodads
{
my ($i, $j, $doodad);
for ($i=0; $i<scalar @Doodads; ++$i)
{
$doodad = $Doodads[$i];
$j = Doodad::UpdateDoodad( $doodad );
if ( $j )
{
# Remove this Doodad
splice @Doodads, $i, 1;
--$i;
}
}
}
sub DeleteDoodadsOf($)
{
my ($owner) = @_;
my ($i, $doodad);
for ($i=0; $i<scalar @Doodads; ++$i)
{
$doodad = $Doodads[$i];
if ( $doodad->{OWNER} == $owner )
{
# Remove this Doodad
splice @Doodads, $i, 1;
--$i;
}
}
}
sub GetNextSoundData()
{
# print "GetSoundData: ", scalar @Sounds, join ' ,', @Sounds, "\n";
$sound = pop @Sounds;
$sound = '' unless defined $sound;
}
sub DoFighterEvents
{
my ($fighter, $hit) = @_;
if ( $JudgementMode )
{
if ( $fighter->{NUMBER} == $JudgementWinner )
{
$fighter->Event("Won");
}
else
{
$fighter->Event("Hurt");
}
return;
}
if ( $hit )
{
$fighter->HitEvent( $fighter->{OTHER}->GetCurrentState()->{HIT}, $hit );
return;
}
#if ( ($fighter->{X} - $fighter->{OTHER}->{X}) * ($fighter->{DIR}) > 0 )
if ( $fighter->IsBackTurned )
{
$fighter->Event("Turn");
}
if ( $fighter->{OTHER}->{ST} eq 'Dead' )
{
$fighter->Event("Won");
}
if ( ($fighter->{IDLE} > 150) and (rand(350) < 1) )
{
$fighter->Event("Fun");
}
if ( ($fighter->{IDLE} > 150) and (rand(350) < 1) )
{
$fighter->Event("Threat");
}
}
sub GameAdvance
{
- # $::adv += 1;
- # return if ( $::adv % 3 );
-
my ($hit1, $hit2);
- $time += 4/1000;
$NextDoodad = 0;
$NextSound = 0;
# 1. ADVANCE THE PLAYERS
$Input1->Advance();
$Input2->Advance();
$Fighter1->Advance( $Input1 ) if $Fighter1->{OK};
$Fighter2->Advance( $Input2 ) if $Fighter2->{OK};
$hit2 = $Fighter1->CheckHit() if $Fighter1->{OK};
$hit1 = $Fighter2->CheckHit() if $Fighter2->{OK};
# 2. Events come here
DoFighterEvents( $Fighter1, $hit1 ) if $Fighter1->{OK};
DoFighterEvents( $Fighter2, $hit2 ) if $Fighter2->{OK};
UpdateDoodads();
$Fighter1->Update() if $Fighter1->{OK};
$Fighter2->Update() if $Fighter2->{OK};
if ( $OverTimer == 0 and
($Fighter1->{ST} eq 'Dead' or $Fighter1->{ST} eq 'Won2') and
($Fighter2->{ST} eq 'Dead' or $Fighter2->{ST} eq 'Won2') )
{
$OverTimer = 1;
}
elsif ( $OverTimer > 0 )
{
$OverTimer++;
$over = 1 if ( $OverTimer > 200 )
}
# 3. DO THE BACKGROUND SCROLLING THING
if ( $BgScrollEnabled )
{
$BgOpt = ($Fighter1->{X} + $Fighter2->{X}) / 2; # 1/1 Stupid kdevelop syntax hightlight.
if ( ($BgOpt - $BgSpeed*50 - $BgPosition) > (320 << $GAMEBITS)) { $BgSpeed++; }
if ( ($BgOpt - $BgSpeed*50 - $BgPosition) < (320 << $GAMEBITS)) { $BgSpeed--; }
$BgPosition+=$BgSpeed;
if ($BgPosition<0) { $BgPosition = $BgSpeed = 0; }
if ($BgPosition>$BgMax) { $BgPosition = $BgMax; $BgSpeed = 0; }
# print "Pos:$BgPosition\tOpt:$BgOpt\tSpd:$BgSpeed\t";
}
# 4. SET GLOBAL VARIABLES FOR THE C++ DRAWING TO READ
($p1x, $p1y, $p1f) = GetFighterData( $Fighter1 );
($p2x, $p2y, $p2f) = GetFighterData( $Fighter2 );
$phTarget = $Fighter1->{HP}*$HitPointScale;
if ( $p1h < $phTarget ) { $p1h += 5; }
if ( $p1h > $phTarget ) { $p1h -= 3; }
$p1h = $phTarget if abs($p1h - $phTarget) < 3;
$p1h = 0 if $p1h < 0;
$phTarget = $Fighter2->{HP}*$HitPointScale;
if ( $p2h < $phTarget ) { $p2h += 5; }
if ( $p2h > $phTarget ) { $p2h -= 3; }
$p2h = $phTarget if abs($p2h - $phTarget) < 3;
$p2h = 0 if $p2h < 0;
$bgx = $BgPosition >> $GAMEBITS;
$p1x -= $bgx;
$p2x -= $bgx;
$bgy = 0;
AdvanceEarthquake();
# 5. DEBUG POLYGONS
return unless $Debug;
$fr1 = $Fighter1->{FRAMES}->[ $Fighter1->{FR} ];
@p1head = @{ $fr1->{head} };
MirrorPolygon( \@p1head ) if $Fighter1->{DIR} < 0;
OffsetPolygon( \@p1head, $Fighter1->{X} / $GAMEBITS2 - $bgx, $Fighter1->{Y} / $GAMEBITS2 - $bgy );
@p1body = @{ $fr1->{body} };
MirrorPolygon( \@p1body ) if $Fighter1->{DIR} < 0;
OffsetPolygon( \@p1body, $Fighter1->{X} / $GAMEBITS2 - $bgx, $Fighter1->{Y} / $GAMEBITS2 - $bgy );
@p1legs = @{ $fr1->{legs} };
MirrorPolygon( \@p1legs) if $Fighter1->{DIR} < 0;
OffsetPolygon( \@p1legs, $Fighter1->{X} / $GAMEBITS2 - $bgx, $Fighter1->{Y} / $GAMEBITS2 - $bgy );
if ( defined $fr1->{hit} )
{
@p1hit = @{ $fr1->{hit} };
MirrorPolygon( \@p1hit ) if $Fighter1->{DIR} < 0;
OffsetPolygon( \@p1hit, $Fighter1->{X} / $GAMEBITS2 - $bgx, $Fighter1->{Y} / $GAMEBITS2 - $bgy );
}
else
{
undef @p1hit;
}
$fr2 = $Fighter2->{FRAMES}->[ $Fighter2->{FR} ];
@p2head = @{ $fr2->{head} };
MirrorPolygon( \@p2head ) if $Fighter2->{DIR} < 0;
OffsetPolygon( \@p2head, $Fighter2->{X} / $GAMEBITS2 - $bgx, $Fighter2->{Y} / $GAMEBITS2 - $bgy );
@p2body = @{ $fr2->{body} };
MirrorPolygon( \@p2body ) if $Fighter2->{DIR} < 0;
OffsetPolygon( \@p2body, $Fighter2->{X} / $GAMEBITS2 - $bgx, $Fighter2->{Y} / $GAMEBITS2 - $bgy );
@p2legs = @{ $fr2->{legs} };
MirrorPolygon( \@p2legs) if $Fighter2->{DIR} < 0;
OffsetPolygon( \@p2legs, $Fighter2->{X} / $GAMEBITS2 - $bgx, $Fighter2->{Y} / $GAMEBITS2 - $bgy );
if ( defined $fr2->{hit} )
{
@p2hit = @{ $fr2->{hit} };
MirrorPolygon( \@p2hit ) if $Fighter2->{DIR} < 0;
OffsetPolygon( \@p2hit, $Fighter2->{X} / $GAMEBITS2 - $bgx, $Fighter2->{Y} / $GAMEBITS2 - $bgy );
}
else
{
undef @p2hit;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Jun 16, 1:00 AM (2 w, 1 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
70023
Default Alt Text
(13 KB)
Attached To
Mode
R76 OpenMortal
Attached
Detach File
Event Timeline