mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
405 lines
13 KiB
Ruby
405 lines
13 KiB
Ruby
################################################################################
|
|
# "Slot Machine" mini-game
|
|
# By Maruno
|
|
#-------------------------------------------------------------------------------
|
|
# Run with: pbSlotMachine(1)
|
|
# - The number is either 0 (easy), 1 (default) or 2 (hard).
|
|
################################################################################
|
|
class SlotMachineReel < BitmapSprite
|
|
attr_accessor :reel
|
|
attr_accessor :toppos
|
|
attr_accessor :spinning
|
|
attr_accessor :stopping
|
|
attr_accessor :slipping
|
|
SCROLLSPEED = 16 # Must be a divisor of 48
|
|
ICONSPOOL = [[0,0,0,0,1,1,2,2,3,3,3,4,4,4,5,5,6,6,7], # 0 - Easy
|
|
[0,0,0,0,1,1,1,2,2,2,3,3,4,4,5,6,7], # 1 - Medium (default)
|
|
[0,0,1,1,1,2,2,2,3,3,4,4,5,6,7] # 2 - Hard
|
|
]
|
|
SLIPPING = [0,0,0,0,0,0,1,1,1,2,2,3]
|
|
|
|
def initialize(x,y,difficulty=1)
|
|
@viewport=Viewport.new(x,y,64,144)
|
|
@viewport.z=99999
|
|
super(64,144,@viewport)
|
|
@reel=[]
|
|
for i in 0...ICONSPOOL[difficulty].length
|
|
@reel.push(ICONSPOOL[difficulty][i])
|
|
end
|
|
@reel.shuffle!
|
|
@toppos=0
|
|
@spinning=false
|
|
@stopping=false
|
|
@slipping=0
|
|
@index=rand(@reel.length)
|
|
@images=AnimatedBitmap.new(_INTL("Graphics/Pictures/Slot Machine/images"))
|
|
@shading=AnimatedBitmap.new(_INTL("Graphics/Pictures/Slot Machine/ReelOverlay"))
|
|
update
|
|
end
|
|
|
|
def startSpinning
|
|
@spinning=true
|
|
end
|
|
|
|
def stopSpinning(noslipping=false)
|
|
@stopping=true
|
|
@slipping=SLIPPING[rand(SLIPPING.length)]
|
|
@slipping=0 if noslipping
|
|
end
|
|
|
|
def showing
|
|
array=[]
|
|
for i in 0...3
|
|
num=@index-i
|
|
num+=@reel.length if num<0
|
|
array.push(@reel[num])
|
|
end
|
|
return array # [0] = top, [1] = middle, [2] = bottom
|
|
end
|
|
|
|
def update
|
|
self.bitmap.clear
|
|
if @toppos==0 && @stopping && @slipping==0
|
|
@spinning=@stopping=false
|
|
end
|
|
if @spinning
|
|
@toppos+=SCROLLSPEED
|
|
if @toppos>0
|
|
@toppos-=48
|
|
@index=(@index+1)%@reel.length
|
|
@slipping-=1 if @slipping>0
|
|
end
|
|
end
|
|
for i in 0...4
|
|
num=@index-i
|
|
num+=@reel.length if num<0
|
|
self.bitmap.blt(0,@toppos+i*48,@images.bitmap,Rect.new(@reel[num]*64,0,64,48))
|
|
end
|
|
self.bitmap.blt(0,0,@shading.bitmap,Rect.new(0,0,64,144))
|
|
end
|
|
end
|
|
|
|
|
|
|
|
class SlotMachineScore < BitmapSprite
|
|
attr_reader :score
|
|
|
|
def initialize(x,y,score=0)
|
|
@viewport=Viewport.new(x,y,70,22)
|
|
@viewport.z=99999
|
|
super(70,22,@viewport)
|
|
@numbers=AnimatedBitmap.new(_INTL("Graphics/Pictures/Slot Machine/numbers"))
|
|
self.score=score
|
|
end
|
|
|
|
def score=(value)
|
|
@score = value
|
|
@score = Settings::MAX_COINS if @score > Settings::MAX_COINS
|
|
refresh
|
|
end
|
|
|
|
def refresh
|
|
self.bitmap.clear
|
|
for i in 0...5
|
|
digit=(@score/(10**i))%10 # Least significant digit first
|
|
self.bitmap.blt(14*(4-i),0,@numbers.bitmap,Rect.new(digit*14,0,14,22))
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
class SlotMachineScene
|
|
attr_accessor :gameRunning
|
|
attr_accessor :gameEnd
|
|
attr_accessor :wager
|
|
attr_accessor :replay
|
|
|
|
def update
|
|
pbUpdateSpriteHash(@sprites)
|
|
end
|
|
|
|
def pbPayout
|
|
@replay=false
|
|
payout=0
|
|
bonus=0
|
|
wonRow=[]
|
|
# Get reel pictures
|
|
reel1=@sprites["reel1"].showing
|
|
reel2=@sprites["reel2"].showing
|
|
reel3=@sprites["reel3"].showing
|
|
combinations=[[reel1[1],reel2[1],reel3[1]], # Centre row
|
|
[reel1[0],reel2[0],reel3[0]], # Top row
|
|
[reel1[2],reel2[2],reel3[2]], # Bottom row
|
|
[reel1[0],reel2[1],reel3[2]], # Diagonal top left -> bottom right
|
|
[reel1[2],reel2[1],reel3[0]], # Diagonal bottom left -> top right
|
|
]
|
|
for i in 0...combinations.length
|
|
break if i>=1 && @wager<=1 # One coin = centre row only
|
|
break if i>=3 && @wager<=2 # Two coins = three rows only
|
|
wonRow[i]=true
|
|
case combinations[i]
|
|
when [1,1,1] # Three Magnemites
|
|
payout += 8
|
|
when [2,2,2] # Three Shellders
|
|
payout += 8
|
|
when [3,3,3] # Three Pikachus
|
|
payout += 15
|
|
when [4,4,4] # Three Psyducks
|
|
payout += 15
|
|
when [5,5,6], [5,6,5], [6,5,5], [6,6,5], [6,5,6], [5,6,6] # 777 multi-colored
|
|
payout += 90
|
|
bonus = 1 if bonus<1
|
|
when [5,5,5], [6,6,6] # Red 777, blue 777
|
|
payout += 300
|
|
bonus = 2 if bonus<2
|
|
when [7,7,7] # Three replays
|
|
@replay = true
|
|
else
|
|
if combinations[i][0]==0 # Left cherry
|
|
if combinations[i][1]==0 # Centre cherry as well
|
|
payout+=4
|
|
else
|
|
payout+=2
|
|
end
|
|
else
|
|
wonRow[i]=false
|
|
end
|
|
end
|
|
end
|
|
@sprites["payout"].score=payout
|
|
frame=0
|
|
if payout>0 || @replay
|
|
if bonus>0
|
|
pbMEPlay("Slots big win")
|
|
else
|
|
pbMEPlay("Slots win")
|
|
end
|
|
# Show winning animation
|
|
timePerFrame = Graphics.frame_rate/8
|
|
until frame==Graphics.frame_rate*3
|
|
Graphics.update
|
|
Input.update
|
|
update
|
|
@sprites["window2"].bitmap.clear if @sprites["window2"].bitmap
|
|
@sprites["window1"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/win"))
|
|
@sprites["window1"].src_rect.set(152*((frame/timePerFrame)%4),0,152,208)
|
|
if bonus>0
|
|
@sprites["window2"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/bonus"))
|
|
@sprites["window2"].src_rect.set(152*(bonus-1),0,152,208)
|
|
end
|
|
@sprites["light1"].visible=true
|
|
@sprites["light1"].src_rect.set(0,26*((frame/timePerFrame)%4),96,26)
|
|
@sprites["light2"].visible=true
|
|
@sprites["light2"].src_rect.set(0,26*((frame/timePerFrame)%4),96,26)
|
|
for i in 1..5
|
|
if wonRow[i-1]
|
|
@sprites["row#{i}"].visible = ((frame/timePerFrame)%2)==0
|
|
else
|
|
@sprites["row#{i}"].visible = false
|
|
end
|
|
end
|
|
frame += 1
|
|
end
|
|
@sprites["light1"].visible=false
|
|
@sprites["light2"].visible=false
|
|
@sprites["window1"].src_rect.set(0,0,152,208)
|
|
# Pay out
|
|
loop do
|
|
break if @sprites["payout"].score<=0
|
|
Graphics.update
|
|
Input.update
|
|
update
|
|
@sprites["payout"].score -= 1
|
|
@sprites["credit"].score += 1
|
|
if Input.trigger?(Input::USE) || @sprites["credit"].score == Settings::MAX_COINS
|
|
@sprites["credit"].score += @sprites["payout"].score
|
|
@sprites["payout"].score = 0
|
|
end
|
|
end
|
|
(Graphics.frame_rate/2).times do
|
|
Graphics.update
|
|
Input.update
|
|
update
|
|
end
|
|
else
|
|
# Show losing animation
|
|
timePerFrame = Graphics.frame_rate/4
|
|
until frame==Graphics.frame_rate*2
|
|
Graphics.update
|
|
Input.update
|
|
update
|
|
@sprites["window2"].bitmap.clear if @sprites["window2"].bitmap
|
|
@sprites["window1"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/lose"))
|
|
@sprites["window1"].src_rect.set(152*((frame/timePerFrame)%2),0,152,208)
|
|
frame += 1
|
|
end
|
|
end
|
|
@wager = 0
|
|
end
|
|
|
|
def pbStartScene(difficulty)
|
|
@sprites={}
|
|
@viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
|
|
@viewport.z=99999
|
|
addBackgroundPlane(@sprites,"bg","Slot Machine/bg",@viewport)
|
|
@sprites["reel1"]=SlotMachineReel.new(64,112,difficulty)
|
|
@sprites["reel2"]=SlotMachineReel.new(144,112,difficulty)
|
|
@sprites["reel3"]=SlotMachineReel.new(224,112,difficulty)
|
|
for i in 1..3
|
|
@sprites["button#{i}"]=IconSprite.new(68+80*(i-1),260,@viewport)
|
|
@sprites["button#{i}"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/button"))
|
|
@sprites["button#{i}"].visible=false
|
|
end
|
|
for i in 1..5
|
|
y=[170,122,218,82,82][i-1]
|
|
@sprites["row#{i}"]=IconSprite.new(2,y,@viewport)
|
|
@sprites["row#{i}"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/line%1d%s",
|
|
1+i/2,(i>=4) ? ((i==4) ? "a" : "b") : ""))
|
|
@sprites["row#{i}"].visible=false
|
|
end
|
|
@sprites["light1"]=IconSprite.new(16,32,@viewport)
|
|
@sprites["light1"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/lights"))
|
|
@sprites["light1"].visible=false
|
|
@sprites["light2"]=IconSprite.new(240,32,@viewport)
|
|
@sprites["light2"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/lights"))
|
|
@sprites["light2"].mirror=true
|
|
@sprites["light2"].visible=false
|
|
@sprites["window1"]=IconSprite.new(358,96,@viewport)
|
|
@sprites["window1"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/insert"))
|
|
@sprites["window1"].src_rect.set(0,0,152,208)
|
|
@sprites["window2"]=IconSprite.new(358,96,@viewport)
|
|
@sprites["credit"]=SlotMachineScore.new(360,66,$Trainer.coins)
|
|
@sprites["payout"]=SlotMachineScore.new(438,66,0)
|
|
@wager=0
|
|
update
|
|
pbFadeInAndShow(@sprites)
|
|
end
|
|
|
|
def pbMain
|
|
frame=0
|
|
spinFrameTime = Graphics.frame_rate/4
|
|
insertFrameTime = Graphics.frame_rate*4/10
|
|
loop do
|
|
Graphics.update
|
|
Input.update
|
|
update
|
|
@sprites["window1"].bitmap.clear if @sprites["window1"].bitmap
|
|
@sprites["window2"].bitmap.clear if @sprites["window2"].bitmap
|
|
if @sprites["credit"].score == Settings::MAX_COINS
|
|
pbMessage(_INTL("You've got {1} Coins.", Settings::MAX_COINS.to_s_formatted))
|
|
break
|
|
elsif $Trainer.coins==0
|
|
pbMessage(_INTL("You've run out of Coins.\nGame over!"))
|
|
break
|
|
elsif @gameRunning # Reels are spinning
|
|
@sprites["window1"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/stop"))
|
|
@sprites["window1"].src_rect.set(152*((frame/spinFrameTime)%4),0,152,208)
|
|
if Input.trigger?(Input::USE)
|
|
pbSEPlay("Slots stop")
|
|
if @sprites["reel1"].spinning
|
|
@sprites["reel1"].stopSpinning(@replay)
|
|
@sprites["button1"].visible=true
|
|
elsif @sprites["reel2"].spinning
|
|
@sprites["reel2"].stopSpinning(@replay)
|
|
@sprites["button2"].visible=true
|
|
elsif @sprites["reel3"].spinning
|
|
@sprites["reel3"].stopSpinning(@replay)
|
|
@sprites["button3"].visible=true
|
|
end
|
|
end
|
|
if !@sprites["reel3"].spinning
|
|
@gameEnd=true
|
|
@gameRunning=false
|
|
end
|
|
elsif @gameEnd # Reels have been stopped
|
|
pbPayout
|
|
# Reset graphics
|
|
@sprites["button1"].visible=false
|
|
@sprites["button2"].visible=false
|
|
@sprites["button3"].visible=false
|
|
for i in 1..5
|
|
@sprites["row#{i}"].visible=false
|
|
end
|
|
@gameEnd=false
|
|
else # Awaiting coins for the next spin
|
|
@sprites["window1"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/insert"))
|
|
@sprites["window1"].src_rect.set(152*((frame/insertFrameTime)%2),0,152,208)
|
|
if @wager>0
|
|
@sprites["window2"].setBitmap(sprintf("Graphics/Pictures/Slot Machine/press"))
|
|
@sprites["window2"].src_rect.set(152*((frame/insertFrameTime)%2),0,152,208)
|
|
end
|
|
if Input.trigger?(Input::DOWN) && @wager<3 && @sprites["credit"].score>0
|
|
pbSEPlay("Slots coin")
|
|
@wager+=1
|
|
@sprites["credit"].score-=1
|
|
if @wager>=3
|
|
@sprites["row5"].visible=true
|
|
@sprites["row4"].visible=true
|
|
elsif @wager>=2
|
|
@sprites["row3"].visible=true
|
|
@sprites["row2"].visible=true
|
|
elsif @wager>=1
|
|
@sprites["row1"].visible=true
|
|
end
|
|
elsif @wager>=3 || (@wager>0 && @sprites["credit"].score==0) ||
|
|
(Input.trigger?(Input::USE) && @wager>0) || @replay
|
|
if @replay
|
|
@wager=3
|
|
for i in 1..5
|
|
@sprites["row#{i}"].visible=true
|
|
end
|
|
end
|
|
@sprites["reel1"].startSpinning
|
|
@sprites["reel2"].startSpinning
|
|
@sprites["reel3"].startSpinning
|
|
frame=0
|
|
@gameRunning=true
|
|
elsif Input.trigger?(Input::BACK) && @wager==0
|
|
break
|
|
end
|
|
end
|
|
frame = (frame+1)%(Graphics.frame_rate*4)
|
|
end
|
|
$Trainer.coins = @sprites["credit"].score
|
|
end
|
|
|
|
def pbEndScene
|
|
pbFadeOutAndHide(@sprites)
|
|
pbDisposeSpriteHash(@sprites)
|
|
@viewport.dispose
|
|
end
|
|
end
|
|
|
|
|
|
|
|
class SlotMachine
|
|
def initialize(scene)
|
|
@scene=scene
|
|
end
|
|
|
|
def pbStartScreen(difficulty)
|
|
@scene.pbStartScene(difficulty)
|
|
@scene.pbMain
|
|
@scene.pbEndScene
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def pbSlotMachine(difficulty=1)
|
|
if GameData::Item.exists?(:COINCASE) && !$PokemonBag.pbHasItem?(:COINCASE)
|
|
pbMessage(_INTL("It's a Slot Machine."))
|
|
elsif $Trainer.coins == 0
|
|
pbMessage(_INTL("You don't have any Coins to play!"))
|
|
elsif $Trainer.coins == Settings::MAX_COINS
|
|
pbMessage(_INTL("Your Coin Case is full!"))
|
|
else
|
|
pbFadeOutIn {
|
|
scene = SlotMachineScene.new
|
|
screen = SlotMachine.new(scene)
|
|
screen.pbStartScreen(difficulty)
|
|
}
|
|
end
|
|
end
|