PDA

View Full Version : [Essentials script] Type Quiz


FL
August 4th, 2013, 11:10 AM
#===============================================================================
# * Type Quiz - by FL (Credits will be apreciated)
#===============================================================================
#
# This script is for Pokémon Essentials. It's a type quiz minigame where
# the player must know the multiplier of a certain type effectiveness in a
# certain type combination. You can use it by a normal message question or by
# a scene screen.
#
# The proportion of correct answers are made in way to every answer will have
# the same amount of being correct
#
#===============================================================================
#
# To this script works, put it above main.
#
# If you use the scene screen, put pictures of a background at
# "Graphics/Pictures/typequizbg" and a "VS" at "Graphics/Pictures/typequizvs".
#
# To use the quiz in standard text message, calls the script
# 'TypeQuiz::TypeQuestion.new.messageQuestion' in a conditional branch and
# handle when the player answers correctly and incorrectly, respectively.
#
# To use the scene screen, use the script command 'TypeQuiz.scene(X)'
# where X is the number of total questions. This method will return the number
# of question answered correctly.
#
#===============================================================================

module TypeQuiz
# If false the last two answers merge into one, resulting in five answers
SIXANSWERS = true
# In scene points the right answer if the player miss
SHOWRIGHTANSWER = true

class TypeQuestion
attr_reader :attackType
attr_reader :defense1Type
attr_reader :defense2Type
attr_reader :result

TYPEAVALIABLE = [:NORMAL,:FIGHTING,:FLYING,:POISON,:GROUND,
:ROCK,:BUG,:GHOST,:STEEL,:FIRE,:WATER,:GRASS,:ELECTRIC,:PSYCHIC,
:ICE,:DRAGON,:DARK]
ANSWERS = [
_INTL("4x"),_INTL("2x"),_INTL("Normal"),_INTL("1/2")
]
ANSWERS += SIXANSWERS ?
[_INTL("1/4"),_INTL("Immune")] : [_INTL("1/4 or immune")]
TYPERESULTS = [ANSWERS.size-1,4,3,nil,2,nil,nil,nil,1,
nil,nil,nil,nil,nil,nil,nil,0]

def initialize(answer=-1)
answer=rand(ANSWERS.size) if(answer==-1)
@result=-1
test=0
while(@result!=answer)
@attackType = getID(PBTypes,TYPEAVALIABLE[rand(TYPEAVALIABLE.size)])
@defense1Type = getID(PBTypes,TYPEAVALIABLE[rand(TYPEAVALIABLE.size)])
@defense2Type = getID(PBTypes,TYPEAVALIABLE[rand(TYPEAVALIABLE.size)])
@result = TYPERESULTS[PBTypes.getCombinedEffectiveness(
@attackType,@defense1Type,@defense2Type)]
end
end

def messageQuestion
attackTypeName = PBTypes.getName(@attackType)
defenseTypeName = PBTypes.getName(@defense1Type)
defenseTypeName += "/"+PBTypes.getName(@defense2Type) if(
@defense1Type!=@defense2Type)
question=_INTL("What is the damage of an {1} move versus a {2} pokémon?",
attackTypeName,defenseTypeName)
return Kernel.pbMessage(question,ANSWERS,0)==result
end
end

class TypeQuizScene
BGPATH = "Graphics/Pictures/typequizbg"
VSPATH = "Graphics/Pictures/typequizvs"
SCENEMUSIC = "evolv" # Put "" or nil to don't change the music.

WAITFRAMESQUANTITY=40*1
MARGIN=32

def update
pbUpdateSpriteHash(@sprites)
end

def pbStartScene(questions)
@questionsTotal=questions
@questionsCount=0
@questionsRight=0
@index=0
pbBGMPlay(SCENEMUSIC) if SCENEMUSIC && SCENEMUSIC!=nil
@sprites={}
@viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
@viewport.z=99999
@typebitmap=AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
@sprites["background"]=IconSprite.new(0,0,@viewport)
@sprites["background"].setBitmap(BGPATH)
@sprites["background"].x=(
Graphics.width-@sprites["background"].bitmap.width)/2
@sprites["background"].y=(
Graphics.height-@sprites["background"].bitmap.height)/2
@sprites["vs"]=IconSprite.new(0,0,@viewport)
@sprites["vs"].setBitmap(VSPATH)
@sprites["vs"].x=Graphics.width*3/4-@sprites["vs"].bitmap.width/2-12
@sprites["vs"].y=Graphics.height*3/4-@sprites["vs"].bitmap.height/2-32
@sprites["arrow"]=IconSprite.new(MARGIN+8,0,@viewport)
@sprites["overlay"]=BitmapSprite.new(
Graphics.width,Graphics.height,@viewport)
pbSetSystemFont(@sprites["overlay"].bitmap)
nextQuestion
pbFadeInAndShow(@sprites) { update }
end

def nextQuestion
@questionsCount+=1
return if finished?
@typeQuestion=TypeQuestion.new
@answerLabel=""
@sprites["arrow"].setBitmap("Graphics/Pictures/selarrow")
refresh
@index=2 # Normal effective index
updateCursor
end

def refresh
leftText = ""
centerText = ""
rightText = ""
overlay=@sprites["overlay"].bitmap
overlay.clear
baseColor=Color.new(72,72,72)
shadowColor=Color.new(160,160,160)
leftText = @questionsRight.to_s # Remove to don't show player score
centerText = @answerLabel # Remove to don't show Correct/Wrong message
rightText += @questionsCount.to_s # Remove to don't show question count
rightText += "/" if rightText!=""
rightText += @questionsTotal.to_s # Remove to don't show question total
textPositions=[
[leftText,MARGIN,Graphics.height/2-80,false,
baseColor,shadowColor],
[centerText,Graphics.width/2,Graphics.height/2-80,2,
baseColor,shadowColor],
[rightText,Graphics.width-MARGIN,Graphics.height/2-80,true,
baseColor,shadowColor]
]
for i in 0...TypeQuestion::ANSWERS.size
textPositions.push([TypeQuestion::ANSWERS[i],
2*MARGIN,Graphics.height/2+i*40-40,false,baseColor,shadowColor])
end
pbDrawTextPositions(overlay,textPositions)
typeX = Graphics.width*3/4-40
typeDefY = Graphics.height*3/4+40
typeAtkRect=Rect.new(0,@typeQuestion.attackType*28,64,28)
typeDef1Rect=Rect.new(0,@typeQuestion.defense1Type*28,64,28)
typeDef2Rect=Rect.new(0,@typeQuestion.defense2Type*28,64,28)
overlay.blt(typeX,Graphics.height/2-36,@typebitmap.bitmap,typeAtkRect)
if @typeQuestion.defense1Type==@typeQuestion.defense2Type
overlay.blt(typeX,typeDefY,@typebitmap.bitmap,typeDef1Rect)
else
overlay.blt(typeX-34,typeDefY,@typebitmap.bitmap,typeDef1Rect)
overlay.blt(typeX+34,typeDefY,@typebitmap.bitmap,typeDef2Rect)
end
end

def updateCursor
@sprites["arrow"].y=Graphics.height/2+@index*40-40
end

def pbMain
waitFrames=0
loop do
Graphics.update
Input.update
self.update
if finished?
Kernel.pbMessage(_INTL("Game end! {1} correct answer(s)!",
@questionsRight))
return @questionsRight
elsif waitFrames>0 # Waiting
waitFrames-=1
elsif @answerLabel!=""
nextQuestion
else
if Input.trigger?(Input::C)
# Set frames to wait, after the result.
waitFrames = WAITFRAMESQUANTITY
if @typeQuestion.result==@index
@answerLabel=_INTL("Correct!")
pbSEPlay("itemlevel")
@questionsRight+=1
else
@answerLabel=_INTL("Wrong!")
pbSEPlay("buzzer")
if SHOWRIGHTANSWER
@index=@typeQuestion.result
@sprites["arrow"].setBitmap("Graphics/Pictures/selarrowwhite")
updateCursor
waitFrames*=2
end
end
refresh
end
if Input.trigger?(Input::B)
pbSEPlay($data_system.decision_se)
return -1
end
if Input.repeat?(Input::UP)
pbSEPlay($data_system.decision_se)
@index = (@index==0 ? TypeQuestion::ANSWERS.size : @index)-1
updateCursor
elsif Input.repeat?(Input::DOWN)
pbSEPlay($data_system.decision_se)
@index = @index==(TypeQuestion::ANSWERS.size-1) ? 0 : @index+1
updateCursor
end
end
end
end

def finished?
return @questionsCount>@questionsTotal
end

def pbEndScene
$game_map.autoplay if SCENEMUSIC && SCENEMUSIC!=nil
pbFadeOutAndHide(@sprites) { update }
pbDisposeSpriteHash(@sprites)
@typebitmap.dispose
@viewport.dispose
end
end

class TypeQuizScreen
def initialize(scene)
@scene=scene
end

def pbStartScreen(questions=10)
@scene.pbStartScene(questions)
ret=@scene.pbMain
@scene.pbEndScene
return ret
end
end

def self.scene(questions=10)
ret=nil
pbFadeOutIn(99999){
scene = TypeQuizScene.new
screen = TypeQuizScreen.new(scene)
ret = screen.pbStartScreen(questions)
}
return ret
end
end

lauerolus
August 5th, 2013, 06:39 AM
This is totally not going to go inside a Pokemon school and not going to give you something for doing well.

Thank you FL.

linkthehero
August 23rd, 2013, 08:25 AM
cool script =)
maybe i will use it

Amiasek
August 23rd, 2013, 10:56 AM
Nice script, not game-changing but still can be used in some ways. Might use it in some kind of contest or in Pokeschool. Ty. :D

Badhaas
September 4th, 2013, 04:36 AM
Nice script, it can be quite useful in teaching people the type effectiveness. I might use it in my game.

I made a small addition to your script which adds three different modes; single type only, double type only, and mixed. I can send the modified script to you, or post it here with your approval.

FL
September 7th, 2013, 02:38 PM
For some reason i liked alot this my script and played several times.

Nice script, it can be quite useful in teaching people the type effectiveness. I might use it in my game.

I made a small addition to your script which adds three different modes; single type only, double type only, and mixed. I can send the modified script to you, or post it here with your approval.Neat idea! Feel free to post here!

Badhaas
September 9th, 2013, 04:56 AM
Here's the entire script, with the code for the different 'difficulty levels' included.


#===============================================================================
# * Type Quiz - by FL modded by Badhaas (Credits will be apreciated)
#===============================================================================
#
# This script is for Pokémon Essentials. It's a type quiz minigame where
# the player must know the multiplier of a certain type effectiveness in a
# certain type combination. You can use it by a normal message question or by
# a scene screen.
#
# The proportion of correct answers are made in way to every answer will have
# the same amount of being correct
#
#===============================================================================
#
# To this script works, put it above main.
#
# If you use the scene screen, put pictures of a background at
# "Graphics/Pictures/typequizbg" and a "VS" at "Graphics/Pictures/typequizvs".
#
# To use the quiz in standard text message, calls the script
# 'TypeQuiz::TypeQuestion.new.messageQuestion' in a conditional branch and
# handle when the player answers correctly and incorrectly, respectively.
#
# To use the scene screen, use the script command 'TypeQuiz.scene(X)'
# where X is the number of total questions. This method will return the number
# of question answered correctly.
#
#===============================================================================
# Added difficulty levels by Badhaas;
# Use the script command 'TypeQuiz.scene(X,Y)' where X is the total number of
# questions, and Y is the difficulty (remove the ',Y' to use the defaulth);
# 0 = only single type questions
# 1 = mixed questions (defaulth)
# 2 = only double type questions
#===============================================================================


module TypeQuiz
# If false the last two answers merge into one, resulting in five answers
SIXANSWERS = true
# In scene points the right answer if the player miss
SHOWRIGHTANSWER = true

class TypeQuestion
attr_reader :attackType
attr_reader :defense1Type
attr_reader :defense2Type
attr_reader :result

TYPEAVALIABLE = [:NORMAL,:FIGHTING,:FLYING,:POISON,:GROUND,
:ROCK,:BUG,:GHOST,:STEEL,:FIRE,:WATER,:GRASS,:ELECTRIC,:PSYCHIC,
:ICE,:DRAGON,:DARK]
ANSWERS = [
_INTL("4x"),_INTL("2x"),_INTL("Normal"),_INTL("1/2")
]
ANSWERS += SIXANSWERS ?
[_INTL("1/4"),_INTL("Immune")] : [_INTL("1/4 or immune")]
TYPERESULTS = [ANSWERS.size-1,4,3,nil,2,nil,nil,nil,1,
nil,nil,nil,nil,nil,nil,nil,0]

def initialize(difficulty=1,answer=-1)
@difficulty=difficulty
@result=-2
test=0
while(@result!=answer)
@attackType = getID(PBTypes,TYPEAVALIABLE[rand(TYPEAVALIABLE.size)])
@defense1Type = getID(PBTypes,TYPEAVALIABLE[rand(TYPEAVALIABLE.size)])
@defense2Type = getID(PBTypes,TYPEAVALIABLE[rand(TYPEAVALIABLE.size)])
if @difficulty==0
@defense2Type=@defense1Type
elsif @difficulty==2 && @defense2Type==@defense1Type
loop do
@defense2Type = getID(PBTypes,TYPEAVALIABLE[rand(TYPEAVALIABLE.size)])
if @defense2Type!=@defense1Type
break
end
end
end
@result = TYPERESULTS[PBTypes.getCombinedEffectiveness(
@attackType,@defense1Type,@defense2Type)]
answer=@result if(answer==-1)
end
end

def messageQuestion
attackTypeName = PBTypes.getName(@attackType)
defenseTypeName = PBTypes.getName(@defense1Type)
defenseTypeName += "/"+PBTypes.getName(@defense2Type) if(
@defense1Type!=@defense2Type)
question=_INTL("What is the damage of an {1} move versus a {2} pokémon?",
attackTypeName,defenseTypeName)
return Kernel.pbMessage(question,ANSWERS,0)==result
end
end

class TypeQuizScene
BGPATH = "Graphics/Pictures/typequizbg"
VSPATH = "Graphics/Pictures/typequizvs"
SCENEMUSIC = "evolv" # Put "" or nil to don't change the music.

WAITFRAMESQUANTITY=40*1
MARGIN=32

def update
pbUpdateSpriteHash(@sprites)
end

def pbStartScene(questions,difficulty)
@difficulty=difficulty
@questionsTotal=questions
@questionsCount=0
@questionsRight=0
@index=0
pbBGMPlay(SCENEMUSIC) if SCENEMUSIC && SCENEMUSIC!=nil
@sprites={}
@viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
@viewport.z=99999
@typebitmap=AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
@sprites["background"]=IconSprite.new(0,0,@viewport)
@sprites["background"].setBitmap(BGPATH)
@sprites["background"].x=(
Graphics.width-@sprites["background"].bitmap.width)/2
@sprites["background"].y=(
Graphics.height-@sprites["background"].bitmap.height)/2
@sprites["vs"]=IconSprite.new(0,0,@viewport)
@sprites["vs"].setBitmap(VSPATH)
@sprites["vs"].x=Graphics.width*3/4-@sprites["vs"].bitmap.width/2-12
@sprites["vs"].y=Graphics.height*3/4-@sprites["vs"].bitmap.height/2-32
@sprites["arrow"]=IconSprite.new(MARGIN+8,0,@viewport)
@sprites["overlay"]=BitmapSprite.new(
Graphics.width,Graphics.height,@viewport)
pbSetSystemFont(@sprites["overlay"].bitmap)
nextQuestion
pbFadeInAndShow(@sprites) { update }
end

def nextQuestion
@questionsCount+=1
return if finished?
@typeQuestion=TypeQuestion.new(@difficulty)
@answerLabel=""
@sprites["arrow"].setBitmap("Graphics/Pictures/selarrow")
refresh
@index=2 # Normal effective index
updateCursor
end

def refresh
leftText = ""
centerText = ""
rightText = ""
overlay=@sprites["overlay"].bitmap
overlay.clear
baseColor=Color.new(72,72,72)
shadowColor=Color.new(160,160,160)
leftText = @questionsRight.to_s # Remove to don't show player score
centerText = @answerLabel # Remove to don't show Correct/Wrong message
rightText += @questionsCount.to_s # Remove to don't show question count
rightText += "/" if rightText!=""
rightText += @questionsTotal.to_s # Remove to don't show question total
textPositions=[
[leftText,MARGIN,Graphics.height/2-80,false,
baseColor,shadowColor],
[centerText,Graphics.width/2,Graphics.height/2-80,2,
baseColor,shadowColor],
[rightText,Graphics.width-MARGIN,Graphics.height/2-80,true,
baseColor,shadowColor]
]
for i in 0...TypeQuestion::ANSWERS.size
textPositions.push([TypeQuestion::ANSWERS[i],
2*MARGIN,Graphics.height/2+i*40-40,false,baseColor,shadowColor])
end
pbDrawTextPositions(overlay,textPositions)
typeX = Graphics.width*3/4-40
typeDefY = Graphics.height*3/4+40
typeAtkRect=Rect.new(0,@typeQuestion.attackType*28,64,28)
typeDef1Rect=Rect.new(0,@typeQuestion.defense1Type*28,64,28)
typeDef2Rect=Rect.new(0,@typeQuestion.defense2Type*28,64,28)
overlay.blt(typeX,Graphics.height/2-36,@typebitmap.bitmap,typeAtkRect)
if @typeQuestion.defense1Type==@typeQuestion.defense2Type
overlay.blt(typeX,typeDefY,@typebitmap.bitmap,typeDef1Rect)
else
overlay.blt(typeX-34,typeDefY,@typebitmap.bitmap,typeDef1Rect)
overlay.blt(typeX+34,typeDefY,@typebitmap.bitmap,typeDef2Rect)
end
end

def updateCursor
@sprites["arrow"].y=Graphics.height/2+@index*40-40
end

def pbMain
waitFrames=0
loop do
Graphics.update
Input.update
self.update
if finished?
Kernel.pbMessage(_INTL("Game end! {1} correct answer(s)!",
@questionsRight))
return @questionsRight
elsif waitFrames>0 # Waiting
waitFrames-=1
elsif @answerLabel!=""
nextQuestion
else
if Input.trigger?(Input::C)
# Set frames to wait, after the result.
waitFrames = WAITFRAMESQUANTITY
if @typeQuestion.result==@index
@answerLabel=_INTL("Correct!")
pbSEPlay("itemlevel")
@questionsRight+=1
else
@answerLabel=_INTL("Wrong!")
pbSEPlay("buzzer")
if SHOWRIGHTANSWER
@index=@typeQuestion.result
@sprites["arrow"].setBitmap("Graphics/Pictures/selarrowwhite")
updateCursor
waitFrames*=2
end
end
refresh
end
if Input.trigger?(Input::B)
pbSEPlay($data_system.decision_se)
return -1
end
if Input.repeat?(Input::UP)
pbSEPlay($data_system.decision_se)
@index = (@index==0 ? TypeQuestion::ANSWERS.size : @index)-1
updateCursor
elsif Input.repeat?(Input::DOWN)
pbSEPlay($data_system.decision_se)
@index = @index==(TypeQuestion::ANSWERS.size-1) ? 0 : @index+1
updateCursor
end
end
end
end

def finished?
return @questionsCount>@questionsTotal
end

def pbEndScene
$game_map.autoplay if SCENEMUSIC && SCENEMUSIC!=nil
pbFadeOutAndHide(@sprites) { update }
pbDisposeSpriteHash(@sprites)
@typebitmap.dispose
@viewport.dispose
end
end

class TypeQuizScreen
def initialize(scene)
@scene=scene
end

def pbStartScreen(questions=10,difficulty=1)
@scene.pbStartScene(questions,difficulty)
ret=@scene.pbMain
@scene.pbEndScene
return ret
end
end

def self.scene(questions=10,difficulty=1)
ret=nil
pbFadeOutIn(99999){
scene = TypeQuizScene.new
screen = TypeQuizScreen.new(scene)
ret = screen.pbStartScreen(questions,difficulty)
}
return ret
end
end


As described in the comments at the start;
use the script command 'TypeQuiz.scene(X,Y)' then replace X with the total number of questions and Y with the desired difficulty (or remove ',Y' to use the defaulth). For the difficulties:
0 = only single type questions
1 = mixed questions (defaulth, as in the original script)
2 = only double type questions

dydd90
January 20th, 2014, 11:22 AM
I will use it thank you FL :)

joeyhugg
February 14th, 2014, 05:34 AM
If I added another type in types.txt, how do I make it show up in the quiz? And is there a way to make it so that the quiz is based off of one type? For instance, a researcher has just discovered the Fairy type and quizzes you on your knowledge on it.

FL
February 19th, 2014, 02:58 PM
Change
TYPEAVALIABLE = [:NORMAL,:FIGHTING,:FLYING,:POISON,:GROUND,
:ROCK,:BUG,:GHOST,:STEEL,:FIRE,:WATER,:GRASS,:ELECTRIC,:PSYCHIC,
:ICE,:DRAGON,:DARK]
to
TYPEAVALIABLE = [:NORMAL,:FIGHTING,:FLYING,:POISON,:GROUND,
:ROCK,:BUG,:GHOST,:STEEL,:FIRE,:WATER,:GRASS,:ELECTRIC,:PSYCHIC,
:ICE,:DRAGON,:DARK,:FAIRY]

Change Graphics/Pictures/types image too.

To force for some type always appears while Switch 85 is on, change line 'while(@result!=answer)' to:

typeAlways = getID(PBTypes,:FAIRY)
while(@result!=answer || ($game_switches[85] && typeAlways!=@attackType && typeAlways!=@defense1Type && typeAlways!=@defense2Type))

joeyhugg
February 19th, 2014, 08:05 PM
Change
TYPEAVALIABLE = [:NORMAL,:FIGHTING,:FLYING,:POISON,:GROUND,
:ROCK,:BUG,:GHOST,:STEEL,:FIRE,:WATER,:GRASS,:ELECTRIC,:PSYCHIC,
:ICE,:DRAGON,:DARK]
to
TYPEAVALIABLE = [:NORMAL,:FIGHTING,:FLYING,:POISON,:GROUND,
:ROCK,:BUG,:GHOST,:STEEL,:FIRE,:WATER,:GRASS,:ELECTRIC,:PSYCHIC,
:ICE,:DRAGON,:DARK,:FAIRY]

Change Graphics/Pictures/types image too.

To force for some type always appears while Switch 85 is on, change line 'while(@result!=answer)' to:

typeAlways = getID(PBTypes,:FAIRY)
while(@result!=answer || ($game_switches[85] && typeAlways!=@attackType && typeAlways!=@defense1Type && typeAlways!=@defense2Type))

This is most useful. Thanks a ton, FL!