mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
1316 lines
35 KiB
Ruby
1316 lines
35 KiB
Ruby
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class PokemonGlobalMetadata
|
|
attr_writer :purifyChamber
|
|
attr_accessor :seenPurifyChamber
|
|
|
|
def purifyChamber
|
|
@purifyChamber = PurifyChamber.new() if !@purifyChamber
|
|
return @purifyChamber
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
# General purpose utilities
|
|
#===============================================================================
|
|
def pbDrawGauge(bitmap,rect,color,value,maxValue)
|
|
return if !bitmap
|
|
bitmap.fill_rect(rect.x,rect.y,rect.width,rect.height,Color.new(0,0,0))
|
|
width=(maxValue<=0) ? 0 : (rect.width-4)*value/maxValue
|
|
if rect.width>=4 && rect.height>=4
|
|
bitmap.fill_rect(rect.x+2,rect.y+2,rect.width-4,rect.height-4,Color.new(248,248,248))
|
|
bitmap.fill_rect(rect.x+2,rect.y+2,width,rect.height-4,color)
|
|
end
|
|
end
|
|
|
|
def calcPoint(x,y,distance,angle) # angle in degrees
|
|
angle -=(angle/360.0).floor*360 # normalize
|
|
angle = (angle/360.0)*(2*Math::PI) # convert to radians
|
|
angle = -angle % (2*Math::PI) # normalize radians
|
|
point = [(Math.cos(angle) * distance), (Math.sin(angle) * distance)]
|
|
point[0] += x
|
|
point[1] += y
|
|
return point
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class PurifyChamberSet
|
|
attr_reader :facing
|
|
attr_reader :shadow
|
|
|
|
def partialSum(x)
|
|
return (x*x+x)/2 # pattern: 1, 3, 6, 10, 15, 21, 28, ...
|
|
end
|
|
|
|
def length
|
|
return @list.length
|
|
end
|
|
|
|
def initialize
|
|
@list=[]
|
|
@facing=0
|
|
end
|
|
|
|
def facing=(value)
|
|
if value>=0 && value<@list.length
|
|
@facing=value
|
|
end
|
|
end
|
|
|
|
def shadow=(value)
|
|
if value==nil || value.shadowPokemon?
|
|
@shadow=value
|
|
end
|
|
end
|
|
|
|
# Main component is tempo
|
|
# Boosted if center has advantage over facing Pokemon
|
|
# Boosted based on number of best circles
|
|
def flow
|
|
ret=0
|
|
return 0 if !@shadow
|
|
for i in 0...@list.length
|
|
ret+=(PurifyChamberSet.isSuperEffective(@list[i],@list[(i+1)%@list.length])) ? 1 : 0
|
|
end
|
|
if @list[@facing]
|
|
ret+=PurifyChamberSet.isSuperEffective(@shadow,@list[@facing]) ? 1 : 0
|
|
end
|
|
return [ret+(@list.length/2),4].min
|
|
end
|
|
|
|
def shadowAffinity
|
|
return 0 if @facing<0 || @facing>=@list.length || !@shadow
|
|
return (PurifyChamberSet.isSuperEffective(@shadow,@list[@facing])) ? 2 : 1
|
|
end
|
|
|
|
def affinity(i)
|
|
return 0 if i<0 || i>=@list.length
|
|
return (PurifyChamberSet.isSuperEffective(@list[i],@list[(i+1)%@list.length])) ? 2 : 1
|
|
end
|
|
|
|
# Tempo refers to the type advantages of each Pokemon in a certain set in a
|
|
# clockwise direction. Tempo also depends on the number of Pokemon in the set
|
|
def tempo
|
|
ret=0
|
|
for i in 0...@list.length
|
|
ret+=(PurifyChamberSet.isSuperEffective(@list[i],@list[(i+1)%@list.length])) ? 1 : 0
|
|
end
|
|
return partialSum(@list.length)+ret
|
|
end
|
|
|
|
def list
|
|
return @list.clone
|
|
end
|
|
|
|
def [](index)
|
|
return @list[index]
|
|
end
|
|
|
|
def insertAfter(index,value)
|
|
return if self.length>=PurifyChamber::SETSIZE
|
|
return if index<0 || index>=PurifyChamber::SETSIZE
|
|
unless value && value.shadowPokemon?
|
|
@list.insert(index+1,value)
|
|
@list.compact!
|
|
@facing+=1 if @facing>index && value!=nil
|
|
@facing=[[@facing,@list.length-1].min,0].max
|
|
end
|
|
end
|
|
|
|
def insertAt(index,value)
|
|
return if index<0 || index>=PurifyChamber::SETSIZE
|
|
unless value && value.shadowPokemon?
|
|
@list[index]=value
|
|
@list.compact!
|
|
@facing=[[@facing,@list.length-1].min,0].max
|
|
end
|
|
end
|
|
|
|
# Purify Chamber treats Normal/Normal matchup as super effective
|
|
def self.typeAdvantage(p1,p2)
|
|
return true if p1 == :NORMAL && p2 == :NORMAL
|
|
return PBTypes.superEffective?(p1,p2)
|
|
end
|
|
|
|
def self.isSuperEffective(p1,p2)
|
|
return (typeAdvantage(p1.type1,p2.type1) || typeAdvantage(p1.type1,p2.type2))
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class PurifyChamber
|
|
NUMSETS=9
|
|
SETSIZE=4
|
|
attr_reader :currentSet # German: das Forum
|
|
|
|
def self.maximumTempo() # Calculates the maximum possible tempo
|
|
x=SETSIZE+1
|
|
return ((x*x+x)/2)-1
|
|
end
|
|
|
|
def initialize
|
|
@sets=[]
|
|
@currentSet=0
|
|
NUMSETS.times { |i| @sets[i]=PurifyChamberSet.new }
|
|
end
|
|
|
|
def currentSet=(value)
|
|
@currentSet=value if value>=0 && value<NUMSETS
|
|
end
|
|
|
|
# Number of regular Pokemon in a set
|
|
def setCount(set)
|
|
return @sets[set].length
|
|
end
|
|
|
|
def setList(set)
|
|
return [] if set<0 || set>=NUMSETS
|
|
return @sets[set].list
|
|
end
|
|
|
|
def chamberFlow(chamber) # for speeding up purification. German: Fluidum
|
|
return 0 if chamber<0 || chamber>=NUMSETS
|
|
return @sets[chamber].flow
|
|
end
|
|
|
|
def getShadow(chamber)
|
|
return nil if chamber<0 || chamber>=NUMSETS
|
|
return @sets[chamber].shadow
|
|
end
|
|
|
|
def setShadow(chamber,value)# allow only "shadow" Pokemon
|
|
return if chamber<0 || chamber>=NUMSETS
|
|
@sets[chamber].shadow=value
|
|
end
|
|
|
|
def switch(set1,set2)
|
|
return if set1<0 || set1>=NUMSETS
|
|
return if set2<0 || set2>=NUMSETS
|
|
s=@sets[set1]
|
|
@sets[set1]=@sets[set2]
|
|
@sets[set2]=s
|
|
end
|
|
|
|
def insertAfter(set,index,value)
|
|
return if set<0 || set>=NUMSETS
|
|
@sets[set].insertAfter(index,value)
|
|
end
|
|
|
|
def insertAt(set,index,value)
|
|
return if set<0 || set>=NUMSETS
|
|
@sets[set].insertAt(index,value)
|
|
end
|
|
|
|
def [](chamber,slot=nil)
|
|
if slot==nil
|
|
return @sets[chamber]
|
|
end
|
|
return nil if chamber<0 || chamber>=NUMSETS
|
|
return nil if slot<0 || slot>=SETSIZE
|
|
return @sets[chamber][slot]
|
|
end
|
|
|
|
def isPurifiableIgnoreRegular?(set)
|
|
shadow=getShadow(set)
|
|
return false if !shadow
|
|
return false if shadow.heart_gauge != 0
|
|
# Define an exception for Lugia
|
|
if shadow.isSpecies?(:LUGIA)
|
|
maxtempo=PurifyChamber.maximumTempo()
|
|
for i in 0...NUMSETS
|
|
return false if @sets[i].tempo!=maxtempo
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
def isPurifiable?(set)
|
|
isPurifiableIgnoreRegular?(set) && setCount(set)>0
|
|
end
|
|
|
|
def update # called each step
|
|
for set in 0...NUMSETS
|
|
# If a shadow Pokemon and a regular Pokemon are on the same set
|
|
if @sets[set].shadow
|
|
if @sets[set].shadow.heart_gauge > 0
|
|
flow=self.chamberFlow(set)
|
|
@sets[set].shadow.adjustHeart(-flow)
|
|
if isPurifiable?(set)
|
|
pbMessage(_INTL("Your {1} in the Purify Chamber is ready for purification!",@sets[set].shadow.name))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
def debugAddShadow(set,species)
|
|
pkmn=Pokemon.new(species,1)
|
|
pkmn.makeShadow
|
|
setShadow(set,pkmn)
|
|
end
|
|
|
|
def debugAddNormal(set,species)
|
|
pkmn=Pokemon.new(species,1)
|
|
insertAfter(set,setCount(set),pkmn)
|
|
end
|
|
|
|
def debugAdd(set,shadow,type1,type2=nil)
|
|
pkmn=PseudoPokemon.new(shadow,type1,type2||type1)
|
|
if pkmn.shadowPokemon?
|
|
self.setShadow(set,pkmn)
|
|
else
|
|
self.insertAfter(set,setCount(set),pkmn)
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
module PurifyChamberHelper
|
|
def self.pbGetPokemon2(chamber,set,position)
|
|
if position==0
|
|
return chamber.getShadow(set)
|
|
elsif position>0
|
|
position-=1
|
|
if position%2==0
|
|
return chamber[set,position/2]
|
|
else # In between two indices
|
|
return nil
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def self.pbGetPokemon(chamber,position)
|
|
if position==0
|
|
return chamber.getShadow(chamber.currentSet)
|
|
elsif position>0
|
|
position-=1
|
|
if position%2==0
|
|
return chamber[chamber.currentSet,position/2]
|
|
else # In between two indices
|
|
return nil
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def self.adjustOnInsert(position)
|
|
if position>0
|
|
position-=1
|
|
oldpos=position/2
|
|
if position%2==0
|
|
return position+1
|
|
else
|
|
return ((oldpos+1)*2)+1
|
|
end
|
|
end
|
|
return position
|
|
end
|
|
|
|
def self.pbSetPokemon(chamber,position,value)
|
|
if position==0
|
|
chamber.setShadow(chamber.currentSet,value)
|
|
elsif position>0
|
|
position-=1
|
|
if position%2==0
|
|
chamber.insertAt(chamber.currentSet,position/2,value)
|
|
else # In between two indices
|
|
chamber.insertAfter(chamber.currentSet,position/2,value)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class PurifyChamberScreen
|
|
def initialize(scene)
|
|
@scene=scene
|
|
@chamber=$PokemonGlobal.purifyChamber
|
|
# for j in 0...PurifyChamber::NUMSETS
|
|
# @chamber.debugAddShadow(j,rand(100)+1)
|
|
# @chamber[j].shadow.heart_gauge = 0
|
|
# for i in 0...PurifyChamber::SETSIZE
|
|
# @chamber.debugAddNormal(j,rand(100)+1)
|
|
# end
|
|
# end
|
|
end
|
|
|
|
def pbPlace(pkmn,position)
|
|
return false if !pkmn
|
|
if pkmn.egg?
|
|
@scene.pbDisplay(_INTL("Can't place an egg there."))
|
|
return false
|
|
end
|
|
if (position==0)
|
|
if pkmn.shadowPokemon?
|
|
# Remove from storage and place in set
|
|
oldpkmn=PurifyChamberHelper.pbGetPokemon(@chamber,position)
|
|
if oldpkmn
|
|
@scene.pbShift(position,pkmn)
|
|
else
|
|
@scene.pbPlace(position,pkmn)
|
|
end
|
|
PurifyChamberHelper.pbSetPokemon(@chamber,position,pkmn)
|
|
@scene.pbRefresh
|
|
else
|
|
@scene.pbDisplay(_INTL("Only a Shadow Pokémon can go there."))
|
|
return false
|
|
end
|
|
elsif (position>=1)
|
|
if pkmn.shadowPokemon?
|
|
@scene.pbDisplay(_INTL("Can't place a Shadow Pokémon there."))
|
|
return false
|
|
else
|
|
oldpkmn=PurifyChamberHelper.pbGetPokemon(@chamber,position)
|
|
if oldpkmn
|
|
@scene.pbShift(position,pkmn)
|
|
else
|
|
@scene.pbPlace(position,pkmn)
|
|
end
|
|
PurifyChamberHelper.pbSetPokemon(@chamber,position,pkmn)
|
|
@scene.pbRefresh
|
|
end
|
|
end
|
|
return true
|
|
end
|
|
|
|
def pbPlacePokemon(pos,position)
|
|
return false if !pos
|
|
pkmn=$PokemonStorage[pos[0],pos[1]]
|
|
if pbPlace(pkmn,position)
|
|
$PokemonStorage.pbDelete(pos[0],pos[1])
|
|
return true
|
|
end
|
|
return false
|
|
end
|
|
|
|
def pbOnPlace(pkmn)
|
|
set=@chamber.currentSet
|
|
if @chamber.setCount(set)==0 && @chamber.isPurifiableIgnoreRegular?(set)
|
|
pkmn=@chamber.getShadow(set)
|
|
@scene.pbDisplay(
|
|
_INTL("This {1} is ready to open its heart. However, there must be at least one regular Pokémon in the set to perform a purification ceremony.",pkmn.name))
|
|
end
|
|
end
|
|
|
|
def pbOpenSetDetail
|
|
chamber=@chamber
|
|
@scene.pbOpenSetDetail(chamber.currentSet)
|
|
heldpkmn=nil
|
|
loop do
|
|
# Commands
|
|
# array[0]==0 - a position was chosen
|
|
# array[0]==1 - a new set was chosen
|
|
# array[0]==2 - choose Pokemon command
|
|
cmd=@scene.pbSetScreen()
|
|
if cmd[0]==0
|
|
# Place Pokemon in the set
|
|
curpkmn=PurifyChamberHelper.pbGetPokemon(@chamber,cmd[1])
|
|
if curpkmn || heldpkmn
|
|
commands=[_INTL("MOVE"),_INTL("SUMMARY"),
|
|
_INTL("WITHDRAW")]
|
|
if curpkmn && heldpkmn
|
|
commands[0]=_INTL("EXCHANGE")
|
|
elsif heldpkmn
|
|
commands[0]=_INTL("PLACE")
|
|
end
|
|
cmdReplace=-1
|
|
cmdRotate=-1
|
|
if !heldpkmn && curpkmn && cmd[1]==0 &&
|
|
@chamber[@chamber.currentSet].length>0
|
|
commands[cmdRotate=commands.length]=_INTL("ROTATE")
|
|
end
|
|
if !heldpkmn && curpkmn
|
|
commands[cmdReplace=commands.length]=_INTL("REPLACE")
|
|
end
|
|
commands.push(_INTL("CANCEL"))
|
|
choice=@scene.pbShowCommands(
|
|
_INTL("What shall I do with this {1}?",
|
|
heldpkmn ? heldpkmn.name : curpkmn.name),commands)
|
|
if choice==0
|
|
if heldpkmn
|
|
if pbPlace(heldpkmn,cmd[1]) # calls place or shift as appropriate
|
|
if !curpkmn
|
|
pbOnPlace(heldpkmn)
|
|
@scene.pbPositionHint(PurifyChamberHelper.adjustOnInsert(cmd[1]))
|
|
heldpkmn=nil # Pokemon was placed
|
|
else
|
|
heldpkmn=curpkmn # Pokemon was shifted
|
|
end
|
|
end
|
|
else
|
|
@scene.pbMove(cmd[1])
|
|
PurifyChamberHelper.pbSetPokemon(@chamber,cmd[1],nil)
|
|
@scene.pbRefresh
|
|
heldpkmn=curpkmn
|
|
end
|
|
elsif choice==1
|
|
@scene.pbSummary(cmd[1],heldpkmn)
|
|
elsif choice==2
|
|
if pbBoxesFull?
|
|
@scene.pbDisplay("All boxes are full.")
|
|
elsif heldpkmn
|
|
@scene.pbWithdraw(cmd[1],heldpkmn)
|
|
$PokemonStorage.pbStoreCaught(heldpkmn)
|
|
heldpkmn=nil
|
|
@scene.pbRefresh
|
|
else
|
|
# Store and delete Pokemon.
|
|
@scene.pbWithdraw(cmd[1],heldpkmn)
|
|
$PokemonStorage.pbStoreCaught(curpkmn)
|
|
PurifyChamberHelper.pbSetPokemon(@chamber,cmd[1],nil)
|
|
@scene.pbRefresh
|
|
end
|
|
elsif cmdRotate>=0 && choice==cmdRotate
|
|
count=@chamber[@chamber.currentSet].length
|
|
nextPos=@chamber[@chamber.currentSet].facing
|
|
if count>0
|
|
@scene.pbRotate((nextPos+1)%count)
|
|
@chamber[@chamber.currentSet].facing=(nextPos+1)%count
|
|
@scene.pbRefresh
|
|
end
|
|
elsif cmdReplace>=0 && choice==cmdReplace
|
|
pos=@scene.pbChoosePokemon
|
|
if pos
|
|
newpkmn=$PokemonStorage[pos[0],pos[1]]
|
|
if newpkmn
|
|
if (newpkmn.shadowPokemon?)!=(curpkmn.shadowPokemon?)
|
|
@scene.pbDisplay(_INTL("That Pokémon can't be placed there."))
|
|
else
|
|
@scene.pbReplace(cmd,pos)
|
|
PurifyChamberHelper.pbSetPokemon(@chamber,cmd[1],newpkmn)
|
|
$PokemonStorage[pos[0],pos[1]]=curpkmn
|
|
@scene.pbRefresh
|
|
pbOnPlace(curpkmn)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
else # No current Pokemon
|
|
pos=@scene.pbChoosePokemon
|
|
if pbPlacePokemon(pos,cmd[1])
|
|
curpkmn=PurifyChamberHelper.pbGetPokemon(@chamber,cmd[1])
|
|
pbOnPlace(curpkmn)
|
|
@scene.pbPositionHint(PurifyChamberHelper.adjustOnInsert(cmd[1]))
|
|
end
|
|
end
|
|
elsif cmd[0]==1 # Change the active set
|
|
@scene.pbChangeSet(cmd[1])
|
|
chamber.currentSet=cmd[1]
|
|
elsif cmd[0]==2 # Choose a Pokemon
|
|
pos=@scene.pbChoosePokemon()
|
|
pkmn=pos ? $PokemonStorage[pos[0],pos[1]] : nil
|
|
heldpkmn=pkmn if pkmn
|
|
else # cancel
|
|
if heldpkmn
|
|
@scene.pbDisplay("You're holding a Pokémon!")
|
|
else
|
|
if !@scene.pbConfirm("Continue editing sets?")
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if pbCheckPurify()
|
|
@scene.pbDisplay(_INTL("There is a Pokémon that is ready to open its heart!\1"))
|
|
@scene.pbCloseSetDetail()
|
|
pbDoPurify()
|
|
return false
|
|
else
|
|
@scene.pbCloseSetDetail()
|
|
return true
|
|
end
|
|
end
|
|
|
|
def pbDisplay(msg)
|
|
@scene.pbDisplay(msg)
|
|
end
|
|
|
|
def pbConfirm(msg)
|
|
@scene.pbConfirm(msg)
|
|
end
|
|
|
|
def pbRefresh
|
|
@scene.pbRefresh
|
|
end
|
|
|
|
def pbCheckPurify
|
|
purifiables=[]
|
|
for set in 0...PurifyChamber::NUMSETS
|
|
if @chamber.isPurifiable?(set) # if ready for purification
|
|
purifiables.push(set)
|
|
end
|
|
return purifiables.length>0
|
|
end
|
|
end
|
|
|
|
def pbDoPurify
|
|
purifiables=[]
|
|
for set in 0...PurifyChamber::NUMSETS
|
|
if @chamber.isPurifiable?(set) # if ready for purification
|
|
purifiables.push(set)
|
|
end
|
|
end
|
|
for i in 0...purifiables.length
|
|
set=purifiables[i]
|
|
@chamber.currentSet=set
|
|
@scene.pbOpenSet(set)
|
|
@scene.pbPurify()
|
|
pbPurify(@chamber[set].shadow,self)
|
|
pbStorePokemon(@chamber[set].shadow)
|
|
@chamber.setShadow(set,nil) # Remove shadow Pokemon from set
|
|
if (i+1)!=purifiables.length
|
|
@scene.pbDisplay(_INTL("There is another Pokémon that is ready to open its heart!"))
|
|
if !@scene.pbConfirm("Would you like to switch sets?")
|
|
@scene.pbCloseSet()
|
|
break
|
|
end
|
|
end
|
|
@scene.pbCloseSet()
|
|
end
|
|
end
|
|
|
|
def pbStartPurify
|
|
chamber=@chamber
|
|
@scene.pbStart(chamber)
|
|
if pbCheckPurify()
|
|
pbDoPurify()
|
|
@scene.pbEnd()
|
|
return
|
|
end
|
|
@scene.pbOpenSet(chamber.currentSet)
|
|
loop do
|
|
set=@scene.pbChooseSet
|
|
if set<0
|
|
if !@scene.pbConfirm("Continue viewing holograms?")
|
|
break
|
|
end
|
|
else
|
|
chamber.currentSet=set
|
|
cmd=@scene.pbShowCommands(
|
|
_INTL("What do you want to do?"),[
|
|
_INTL("EDIT"),_INTL("SWITCH"),_INTL("CANCEL")])
|
|
if cmd==0 # edit
|
|
if !pbOpenSetDetail()
|
|
break
|
|
end
|
|
elsif cmd==1 # switch
|
|
chamber.currentSet=set
|
|
newSet=@scene.pbSwitch(set)
|
|
chamber.switch(set,newSet)
|
|
chamber.currentSet=newSet
|
|
@scene.pbRefresh()
|
|
end
|
|
end
|
|
end
|
|
@scene.pbCloseSet()
|
|
@scene.pbEnd()
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class Window_PurifyChamberSets < Window_DrawableCommand
|
|
attr_reader :switching
|
|
|
|
def initialize(chamber,x,y,width,height,viewport=nil)
|
|
@chamber=chamber
|
|
@switching=-1
|
|
super(x,y,width,height,viewport)
|
|
end
|
|
|
|
def itemCount
|
|
return PurifyChamber::NUMSETS
|
|
end
|
|
|
|
def switching=(value)
|
|
@switching = value
|
|
refresh
|
|
end
|
|
|
|
def drawItem(index,_count,rect)
|
|
textpos=[]
|
|
rect=drawCursor(index,rect)
|
|
if index==@switching
|
|
textpos.push([(index+1).to_s,rect.x,
|
|
rect.y,false,Color.new(248,0,0),self.shadowColor])
|
|
else
|
|
textpos.push([(index+1).to_s,rect.x,
|
|
rect.y,false,self.baseColor,self.shadowColor])
|
|
end
|
|
if @chamber.setCount(index)>0
|
|
pbDrawGauge(self.contents,Rect.new(rect.x+16,rect.y+6,48,8),
|
|
Color.new(0,0,256),@chamber[index].tempo,PurifyChamber.maximumTempo())
|
|
end
|
|
if @chamber.getShadow(index)
|
|
pbDrawGauge(self.contents, Rect.new(rect.x+16,rect.y+18,48,8),
|
|
Color.new(192,0,256), @chamber.getShadow(index).heart_gauge,
|
|
Pokemon::HEART_GAUGE_SIZE)
|
|
end
|
|
pbDrawTextPositions(self.contents,textpos)
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class DirectFlowDiagram
|
|
def initialize(viewport=nil)
|
|
@points=[]
|
|
@angles=[]
|
|
@viewport=viewport
|
|
@strength=0
|
|
@offset=0
|
|
@x=306
|
|
@y=138
|
|
@distance=96
|
|
end
|
|
|
|
# 0=none, 1=weak, 2=strong
|
|
def setFlowStrength(strength)
|
|
@strength=strength
|
|
end
|
|
|
|
def visible=(value)
|
|
for point in @points
|
|
point.visible=value
|
|
end
|
|
end
|
|
|
|
def dispose
|
|
for point in @points
|
|
point.dispose
|
|
end
|
|
end
|
|
|
|
def ensurePoint(j)
|
|
if !@points[j] || @points[j].disposed?
|
|
@points[j]=BitmapSprite.new(8,8,@viewport)
|
|
@points[j].bitmap.fill_rect(0,0,8,8,Color.new(0,0,0))
|
|
end
|
|
@points[j].tone=(@strength==2) ? Tone.new(232,232,248) :
|
|
Tone.new(16,16,232)
|
|
@points[j].visible=(@strength!=0)
|
|
end
|
|
|
|
def update
|
|
for point in @points
|
|
point.update
|
|
point.visible=false
|
|
end
|
|
j=0
|
|
i=0
|
|
while i<@distance
|
|
o=(i+@offset)%@distance
|
|
if o>=0 && o<@distance
|
|
ensurePoint(j)
|
|
pt=calcPoint(@x,@y,o,@angle)
|
|
@points[j].x=pt[0]
|
|
@points[j].y=pt[1]
|
|
j+=1
|
|
end
|
|
i+=(@strength==2) ? 16 : 32
|
|
end
|
|
@offset+=(@strength==2) ? 3 : 2
|
|
@offset%=@distance
|
|
end
|
|
|
|
def color=(value)
|
|
for point in @points
|
|
point.color=value
|
|
end
|
|
end
|
|
|
|
def setAngle(angle1)
|
|
@angle=angle1-(angle1/360).floor*360
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class FlowDiagram
|
|
def initialize(viewport=nil)
|
|
@points=[]
|
|
@angles=[]
|
|
@viewport=viewport
|
|
@strength=0
|
|
@offset=0
|
|
@x=306
|
|
@y=138
|
|
@distance=96
|
|
end
|
|
|
|
# 0=none, 1=weak, 2=strong
|
|
def setFlowStrength(strength)
|
|
@strength=strength
|
|
end
|
|
|
|
def visible=(value)
|
|
for point in @points
|
|
point.visible=value
|
|
end
|
|
end
|
|
|
|
def dispose
|
|
for point in @points
|
|
point.dispose
|
|
end
|
|
end
|
|
|
|
def ensurePoint(j)
|
|
if !@points[j] || @points[j].disposed?
|
|
@points[j]=BitmapSprite.new(8,8,@viewport)
|
|
@points[j].bitmap.fill_rect(0,0,8,8,Color.new(0,0,0))
|
|
end
|
|
@points[j].tone=(@strength==2) ? Tone.new(232,232,248) :
|
|
Tone.new(16,16,232)
|
|
@points[j].visible=(@strength!=0)
|
|
end
|
|
|
|
def withinRange(angle,startAngle,endAngle)
|
|
if startAngle>endAngle
|
|
return (angle>=startAngle || angle<=endAngle) &&
|
|
(angle>=0 && angle<=360)
|
|
else
|
|
return (angle>=startAngle && angle<=endAngle)
|
|
end
|
|
end
|
|
|
|
def update
|
|
for point in @points
|
|
point.update
|
|
point.visible=false
|
|
end
|
|
j=0
|
|
i=0
|
|
while i<360
|
|
angle=(i+@offset)%360
|
|
if withinRange(angle,@startAngle,@endAngle)
|
|
ensurePoint(j)
|
|
pt=calcPoint(@x,@y,@distance,angle)
|
|
@points[j].x=pt[0]
|
|
@points[j].y=pt[1]
|
|
j+=1
|
|
end
|
|
i+=(@strength==2) ? 10 : 20
|
|
end
|
|
@offset-=(@strength==2) ? 3 : 2
|
|
@offset%=(360*6)
|
|
end
|
|
|
|
def color=(value)
|
|
for point in @points
|
|
point.color=value
|
|
end
|
|
end
|
|
|
|
def setRange(angle1,angle2)
|
|
@startAngle=angle1-(angle1/360).floor*360
|
|
@endAngle=angle2-(angle2/360).floor*360
|
|
if @startAngle==@endAngle && angle1!=angle2
|
|
@startAngle=0
|
|
@endAngle=359.99
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class PurifyChamberSetView < SpriteWrapper
|
|
attr_reader :set
|
|
attr_reader :cursor
|
|
attr_reader :heldpkmn
|
|
|
|
def initialize(chamber,set,viewport=nil)
|
|
super(viewport)
|
|
@set=set
|
|
@heldpkmn=nil
|
|
@cursor=-1
|
|
@view=BitmapSprite.new(64,64,viewport)
|
|
@view.bitmap.fill_rect(8,8,48,48,Color.new(255,255,255))
|
|
@view.bitmap.fill_rect(10,10,44,44,Color.new(255,255,255,128))
|
|
@info=BitmapSprite.new(Graphics.width-112,48,viewport)
|
|
@flows=[]
|
|
@directflow=DirectFlowDiagram.new(viewport)
|
|
@directflow.setAngle(0)
|
|
@directflow.setFlowStrength(1)
|
|
@__sprites=[]
|
|
@__sprites[0]=PokemonIconSprite.new(nil,viewport)
|
|
for i in 0...PurifyChamber::SETSIZE*2
|
|
@__sprites[i+1]=PokemonIconSprite.new(nil,viewport)
|
|
end
|
|
@__sprites[1+PurifyChamber::SETSIZE*2]=PokemonIconSprite.new(nil,viewport)
|
|
@chamber=chamber
|
|
refresh
|
|
end
|
|
|
|
def refreshFlows()
|
|
for flow in @flows
|
|
flow.setFlowStrength(0)
|
|
end
|
|
setcount=@chamber.setCount(@set)
|
|
for i in 0...setcount
|
|
if !@flows[i]
|
|
@flows[i]=FlowDiagram.new(self.viewport)
|
|
end
|
|
angle=360-(i*360/setcount)
|
|
angle+=90 # start at 12 not 3 o'clock
|
|
endAngle=angle-(360/setcount)
|
|
@flows[i].setRange(endAngle,angle)
|
|
@flows[i].setFlowStrength(@chamber[@set].affinity(i))
|
|
end
|
|
end
|
|
|
|
def moveCursor(button)
|
|
points=[@chamber.setCount(@set)*2,1].max
|
|
oldcursor=@cursor
|
|
if @cursor==0 && points>0
|
|
@cursor=1 if button==Input::UP
|
|
@cursor=points*1/4+1 if button==Input::RIGHT
|
|
@cursor=points*2/4+1 if button==Input::DOWN
|
|
@cursor=points*3/4+1 if button==Input::LEFT
|
|
elsif @cursor>0
|
|
pos=@cursor-1
|
|
if @chamber.setCount(@set)==PurifyChamber::SETSIZE
|
|
points=[points/2,1].max
|
|
pos/=2
|
|
end
|
|
seg=pos*8/points
|
|
if seg==7 || seg==0
|
|
pos-=1 if button==Input::LEFT
|
|
pos+=1 if button==Input::RIGHT
|
|
pos=nil if button==Input::DOWN
|
|
elsif seg==1 || seg==2
|
|
pos-=1 if button==Input::UP
|
|
pos+=1 if button==Input::DOWN
|
|
pos=nil if button==Input::LEFT
|
|
elsif seg==3 || seg==4
|
|
pos-=1 if button==Input::RIGHT
|
|
pos+=1 if button==Input::LEFT
|
|
pos=nil if button==Input::UP
|
|
elsif seg==5 || seg==6
|
|
pos-=1 if button==Input::DOWN
|
|
pos+=1 if button==Input::UP
|
|
pos=nil if button==Input::RIGHT
|
|
end
|
|
if pos!=nil
|
|
pos-=(pos/points).floor*points # modulus
|
|
pos*=2 if @chamber.setCount(@set)==PurifyChamber::SETSIZE
|
|
@cursor=pos+1
|
|
else
|
|
@cursor=0
|
|
end
|
|
end
|
|
if @cursor!=oldcursor
|
|
refresh
|
|
end
|
|
end
|
|
|
|
def checkCursor(index)
|
|
if @cursor==index
|
|
@view.x=@__sprites[index].x-32
|
|
@view.y=@__sprites[index].y-40
|
|
@view.visible=true
|
|
end
|
|
end
|
|
|
|
def refresh
|
|
pkmn=@chamber.getShadow(@set)
|
|
@view.visible=false
|
|
@info.bitmap.fill_rect(0,0,@info.bitmap.width,@info.bitmap.height,Color.new(0,248,0))
|
|
pbSetSmallFont(@info.bitmap)
|
|
textpos=[]
|
|
if pkmn
|
|
if pkmn.type1==pkmn.type2
|
|
textpos.push([_INTL("{1} Lv.{2} {3}",pkmn.name,pkmn.level,GameData::Type.get(pkmn.type1).name),2,0,0,
|
|
Color.new(248,248,248),Color.new(128,128,128)])
|
|
else
|
|
textpos.push([_INTL("{1} Lv.{2} {3}/{4}",pkmn.name,pkmn.level,GameData::Type.get(pkmn.type1).name,
|
|
GameData::Type.get(pkmn.type2).name),2,0,0,
|
|
Color.new(248,248,248),Color.new(128,128,128)])
|
|
end
|
|
textpos.push([_INTL("FLOW"),2+@info.bitmap.width/2,24,0,
|
|
Color.new(248,248,248),Color.new(128,128,128)])
|
|
# draw heart gauge
|
|
pbDrawGauge(@info.bitmap, Rect.new(@info.bitmap.width*3/4,8,@info.bitmap.width*1/4,8),
|
|
Color.new(192,0,256), pkmn.heart_gauge, Pokemon::HEART_GAUGE_SIZE)
|
|
# draw flow gauge
|
|
pbDrawGauge(@info.bitmap,Rect.new(@info.bitmap.width*3/4,24+8,@info.bitmap.width*1/4,8),
|
|
Color.new(0,0,248),@chamber.chamberFlow(@set),6)
|
|
end
|
|
if @chamber.setCount(@set)>0
|
|
textpos.push([_INTL("TEMPO"),2,24,0,
|
|
Color.new(248,248,248),Color.new(128,128,128)])
|
|
# draw tempo gauge
|
|
pbDrawGauge(@info.bitmap,Rect.new(@info.bitmap.width*1/4,24+8,@info.bitmap.width*1/4,8),
|
|
Color.new(0,0,248),@chamber[@set].tempo,
|
|
PurifyChamber.maximumTempo())
|
|
end
|
|
pbDrawTextPositions(@info.bitmap,textpos)
|
|
@info.x=Graphics.width-@info.bitmap.width
|
|
@info.y=Graphics.height-@info.bitmap.height
|
|
@__sprites[0].pokemon=pkmn
|
|
@__sprites[0].x=312
|
|
@__sprites[0].y=136
|
|
@__sprites[0].z=2
|
|
@directflow.setAngle(angle)
|
|
@directflow.setFlowStrength(0)
|
|
checkCursor(0)
|
|
points=[@chamber.setCount(@set)*2,1].max
|
|
setList=@chamber.setList(@set)
|
|
refreshFlows()
|
|
for i in 0...PurifyChamber::SETSIZE*2
|
|
pkmn=(i%2==1 || i>=points) ? nil : setList[i/2]
|
|
angle=360-(i*360/points)
|
|
angle+=90 # start at 12 not 3 o'clock
|
|
if pkmn && @chamber[@set].facing==i/2
|
|
@directflow.setAngle(angle)
|
|
@directflow.setFlowStrength(@chamber[@set].shadowAffinity)
|
|
end
|
|
point=calcPoint(280,96,96,angle)
|
|
@__sprites[i+1].x=point[0]+32
|
|
@__sprites[i+1].y=point[1]+40
|
|
@__sprites[i+1].z=2
|
|
@__sprites[i+1].pokemon=pkmn
|
|
checkCursor(i+1)
|
|
end
|
|
@__sprites[1+PurifyChamber::SETSIZE*2].pokemon=@heldpkmn
|
|
@__sprites[1+PurifyChamber::SETSIZE*2].visible=@view.visible
|
|
@__sprites[1+PurifyChamber::SETSIZE*2].x=@view.x+32
|
|
@__sprites[1+PurifyChamber::SETSIZE*2].y=@view.y-6+40
|
|
@__sprites[1+PurifyChamber::SETSIZE*2].z=3
|
|
end
|
|
|
|
def getCurrent
|
|
return PurifyChamberHelper.pbGetPokemon(@chamber,@cursor)
|
|
end
|
|
|
|
def cursor=(value)
|
|
@cursor=value
|
|
refresh
|
|
end
|
|
|
|
def heldpkmn=(value)
|
|
@heldpkmn=value
|
|
refresh
|
|
end
|
|
|
|
def set=(value)
|
|
@set=value
|
|
refresh
|
|
end
|
|
|
|
def visible=(value)
|
|
super
|
|
for sprite in @__sprites
|
|
sprite.visible=value
|
|
end
|
|
for flow in @flows
|
|
flow.visible=value
|
|
end
|
|
@directflow.visible=value
|
|
@view.visible=value
|
|
@info.visible=value
|
|
end
|
|
|
|
def color=(value)
|
|
super
|
|
for sprite in @__sprites
|
|
sprite.color=pbSrcOver(sprite.color,value.clone)
|
|
end
|
|
for flow in @flows
|
|
flow.color=value.clone
|
|
end
|
|
@directflow.color=value.clone
|
|
@view.color=value.clone
|
|
@info.color=value.clone
|
|
end
|
|
|
|
def update
|
|
super
|
|
for sprite in @__sprites
|
|
sprite.update if sprite
|
|
end
|
|
for flow in @flows
|
|
flow.update
|
|
end
|
|
@directflow.update
|
|
@view.update
|
|
@info.update
|
|
end
|
|
|
|
def dispose
|
|
for sprite in @__sprites
|
|
sprite.dispose if sprite
|
|
end
|
|
for flow in @flows
|
|
flow.dispose
|
|
end
|
|
@directflow.dispose
|
|
@view.dispose
|
|
@info.dispose
|
|
@__sprites.clear
|
|
super
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class PurifyChamberScene
|
|
def pbUpdate()
|
|
pbUpdateSpriteHash(@sprites)
|
|
end
|
|
|
|
def pbRefresh()
|
|
if @sprites["setview"]
|
|
@sprites["setview"].refresh
|
|
@sprites["setwindow"].refresh
|
|
end
|
|
end
|
|
|
|
def pbStart(chamber)
|
|
@chamber=chamber
|
|
end
|
|
|
|
def pbEnd()
|
|
end
|
|
|
|
def pbOpenSet(set)
|
|
@sprites={}
|
|
@viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
|
|
@viewport.z=99999
|
|
@viewportmsg=Viewport.new(0,0,Graphics.width,Graphics.height)
|
|
@viewportmsg.z=99999
|
|
addBackgroundOrColoredPlane(@sprites,"bg","purifychamberbg",
|
|
Color.new(0,0,0),@viewport)
|
|
@sprites["setwindow"]=Window_PurifyChamberSets.new(
|
|
@chamber,0,0,112,Graphics.height,@viewport)
|
|
@sprites["setview"]=PurifyChamberSetView.new(@chamber,set,@viewport)
|
|
@sprites["msgwindow"]=Window_AdvancedTextPokemon.new("")
|
|
@sprites["msgwindow"].viewport=@viewportmsg
|
|
@sprites["msgwindow"].visible=false
|
|
@sprites["setwindow"].index=set
|
|
pbDeactivateWindows(@sprites)
|
|
pbFadeInAndShow(@sprites) { pbUpdate }
|
|
end
|
|
|
|
def pbCloseSet()
|
|
pbFadeOutAndHide(@sprites) { pbUpdate }
|
|
pbDisposeSpriteHash(@sprites)
|
|
@viewport.dispose
|
|
@viewportmsg.dispose
|
|
end
|
|
|
|
def pbOpenSetDetail(set)
|
|
@sprites["setwindow"].index=set
|
|
@sprites["setview"].set=set
|
|
@sprites["setview"].cursor=0
|
|
end
|
|
|
|
def pbCloseSetDetail()
|
|
end
|
|
|
|
def pbPurify()
|
|
pbRefresh
|
|
end
|
|
|
|
def pbMove(_pos)
|
|
@sprites["setview"].heldpkmn=@sprites["setview"].getCurrent()
|
|
pbRefresh
|
|
end
|
|
|
|
def pbShift(_pos,_heldpoke)
|
|
@sprites["setview"].heldpkmn=@sprites["setview"].getCurrent()
|
|
pbRefresh
|
|
end
|
|
|
|
def pbPlace(_pos,_heldpoke)
|
|
@sprites["setview"].heldpkmn=nil
|
|
pbRefresh
|
|
end
|
|
|
|
def pbReplace(_pos,_storagePos)
|
|
@sprites["setview"].heldpkmn=nil
|
|
pbRefresh
|
|
end
|
|
|
|
def pbRotate(facing); end
|
|
|
|
def pbWithdraw(_pos,_heldpoke)
|
|
@sprites["setview"].heldpkmn=nil
|
|
pbRefresh
|
|
end
|
|
|
|
def pbDisplay(msg)
|
|
UIHelper.pbDisplay(@sprites["msgwindow"],msg,false) { pbUpdate }
|
|
end
|
|
|
|
def pbConfirm(msg)
|
|
UIHelper.pbConfirm(@sprites["msgwindow"],msg) { pbUpdate }
|
|
end
|
|
|
|
def pbShowCommands(msg,commands)
|
|
UIHelper.pbShowCommands(@sprites["msgwindow"],msg,commands) { pbUpdate }
|
|
end
|
|
|
|
def pbSetScreen
|
|
pbDeactivateWindows(@sprites) {
|
|
loop do
|
|
Graphics.update; Input.update; pbUpdate
|
|
btn=0
|
|
btn=Input::DOWN if Input.repeat?(Input::DOWN)
|
|
btn=Input::UP if Input.repeat?(Input::UP)
|
|
btn=Input::RIGHT if Input.repeat?(Input::RIGHT)
|
|
btn=Input::LEFT if Input.repeat?(Input::LEFT)
|
|
if btn!=0
|
|
pbPlayCursorSE()
|
|
@sprites["setview"].moveCursor(btn)
|
|
end
|
|
if Input.repeat?(Input::L)
|
|
nextset=(@sprites["setview"].set==0) ? PurifyChamber::NUMSETS-1 : @sprites["setview"].set-1
|
|
pbPlayCursorSE()
|
|
return [1,nextset]
|
|
elsif Input.repeat?(Input::R)
|
|
nextset=(@sprites["setview"].set==PurifyChamber::NUMSETS-1) ? 0 : @sprites["setview"].set+1
|
|
pbPlayCursorSE()
|
|
return [1,nextset]
|
|
elsif Input.trigger?(Input::USE)
|
|
pbPlayDecisionSE()
|
|
return [0,@sprites["setview"].cursor]
|
|
elsif Input.trigger?(Input::BACK)
|
|
pbPlayCancelSE()
|
|
return [3,0]
|
|
end
|
|
end
|
|
}
|
|
end
|
|
|
|
def pbChooseSet()
|
|
pbActivateWindow(@sprites,"setwindow") {
|
|
oldindex=@sprites["setwindow"].index
|
|
loop do
|
|
if oldindex!=@sprites["setwindow"].index
|
|
oldindex=@sprites["setwindow"].index
|
|
@sprites["setview"].set=oldindex
|
|
end
|
|
Graphics.update; Input.update; pbUpdate
|
|
if Input.trigger?(Input::USE)
|
|
pbPlayDecisionSE()
|
|
return @sprites["setwindow"].index
|
|
end
|
|
if Input.trigger?(Input::BACK)
|
|
pbPlayCancelSE()
|
|
return -1
|
|
end
|
|
end
|
|
}
|
|
end
|
|
|
|
def pbSwitch(set)
|
|
@sprites["setwindow"].switching=set
|
|
ret=pbChooseSet()
|
|
@sprites["setwindow"].switching=-1
|
|
return ret<0 ? set : ret
|
|
end
|
|
|
|
def pbSummary(pos,heldpkmn)
|
|
if heldpkmn
|
|
oldsprites=pbFadeOutAndHide(@sprites)
|
|
scene=PokemonSummary_Scene.new
|
|
screen=PokemonSummaryScreen.new(scene)
|
|
screen.pbStartScreen([heldpkmn],0)
|
|
pbFadeInAndShow(@sprites,oldsprites)
|
|
return
|
|
end
|
|
party=[]
|
|
indexes=[]
|
|
startindex=0
|
|
set=@sprites["setview"].set
|
|
for i in 0...@chamber.setCount(set)*2
|
|
p=PurifyChamberHelper.pbGetPokemon2(@chamber,set,i)
|
|
if p
|
|
startindex=party.length if i==pos
|
|
party.push(p)
|
|
indexes.push(i)
|
|
end
|
|
end
|
|
return if party.length==0
|
|
oldsprites=pbFadeOutAndHide(@sprites)
|
|
scene=PokemonSummary_Scene.new
|
|
screen=PokemonSummaryScreen.new(scene)
|
|
selection=screen.pbStartScreen(party,startindex)
|
|
@sprites["setview"].cursor=indexes[selection]
|
|
pbFadeInAndShow(@sprites,oldsprites)
|
|
end
|
|
|
|
def pbPositionHint(pos)
|
|
@sprites["setview"].cursor=pos
|
|
pbRefresh
|
|
end
|
|
|
|
def pbChangeSet(set)
|
|
@sprites["setview"].set=set
|
|
@sprites["setwindow"].index=set
|
|
@sprites["setwindow"].refresh
|
|
pbRefresh
|
|
end
|
|
|
|
def pbChoosePokemon()
|
|
visible=pbFadeOutAndHide(@sprites)
|
|
scene=PokemonStorageScene.new()
|
|
screen=PokemonStorageScreen.new(scene,$PokemonStorage)
|
|
pos=screen.pbChoosePokemon()
|
|
pbRefresh
|
|
pbFadeInAndShow(@sprites,visible)
|
|
return pos
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
def pbPurifyChamber
|
|
$PokemonGlobal.seenPurifyChamber = true
|
|
pbFadeOutIn {
|
|
scene = PurifyChamberScene.new
|
|
screen = PurifyChamberScreen.new(scene)
|
|
screen.pbStartPurify
|
|
}
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class PurifyChamberPC
|
|
def shouldShow?
|
|
return $PokemonGlobal.seenPurifyChamber
|
|
end
|
|
|
|
def name
|
|
return _INTL("Purify Chamber")
|
|
end
|
|
|
|
def access
|
|
pbMessage(_INTL("\\se[PC access]Accessed the Purify Chamber."))
|
|
pbPurifyChamber()
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
PokemonPCList.registerPC(PurifyChamberPC.new)
|