mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2026-07-21 23:27:00 +00:00
408 lines
13 KiB
Ruby
408 lines
13 KiB
Ruby
class FusionQuiz
|
|
attr_accessor :silhouette_color
|
|
attr_accessor :windowed
|
|
attr_accessor :picture_offset_x
|
|
attr_accessor :picture_offset_y
|
|
|
|
#
|
|
# Possible difficulties:
|
|
#
|
|
# :REGULAR -> 4 options choice
|
|
#
|
|
# :ADVANCED -> List of all pokemon
|
|
#
|
|
def initialize(difficulty = :REGULAR)
|
|
@sprites = {}
|
|
|
|
|
|
@previewwindow = nil
|
|
@difficulty = difficulty
|
|
@customs_list = getCustomSpeciesList(true, false)
|
|
@selected_pokemon = nil
|
|
@head_id = nil
|
|
@body_id = nil
|
|
@body_choices = []
|
|
@head_choices = []
|
|
@abandonned = false
|
|
@score = 0
|
|
@current_streak = 0
|
|
@streak_multiplier = 0.15
|
|
|
|
@silhouette_color = Color.new(255, 255, 255, 200)
|
|
@windowed=true
|
|
@picture_offset_x = 0
|
|
@picture_offset_y = 0
|
|
|
|
@score_viewport = nil
|
|
@score_sprite = nil
|
|
@streak_viewport = nil
|
|
@streak_sprite = nil
|
|
end
|
|
|
|
|
|
def start_quiz(nb_rounds = 3)
|
|
create_score_display
|
|
nb_games_played= pbGet(VAR_STAT_FUSION_QUIZ_NB_TIMES)
|
|
pbSet(VAR_STAT_FUSION_QUIZ_NB_TIMES,nb_games_played+1)
|
|
|
|
round_multiplier = 1
|
|
round_multiplier_increase = 0.1
|
|
|
|
for i in 1..nb_rounds
|
|
if i == nb_rounds
|
|
pbMessage(_INTL("Get ready! Here comes the final round!\\wtnp[10]"))
|
|
elsif i == 1
|
|
pbMessage(_INTL("Get ready! Here comes the first round!\\wtnp[10]"))
|
|
else
|
|
pbMessage(_INTL("Get ready! Here comes round {1}!\\wtnp[10]", i))
|
|
end
|
|
start_quiz_new_round(round_multiplier)
|
|
|
|
rounds_left = nb_rounds - i
|
|
if rounds_left > 0
|
|
pbMessage(_INTL("That's it for round {1}. You've cumulated {2} points so far.\\wtnp[20]", i, @score))
|
|
prompt_next_round = pbMessage(_INTL("Are you ready to move on to the next round?", i), [_INTL("Yes"), _INTL("No")])
|
|
if prompt_next_round != 0
|
|
prompt_quit = pbMessage(_INTL("You still have {1} rounds to go. You'll only keep your points if you finish all {2} rounds. Do you really want to quit now?", rounds_left, nb_rounds), [_INTL("Yes"), _INTL("No")])
|
|
if prompt_quit
|
|
@abandonned = true
|
|
break
|
|
end
|
|
end
|
|
round_multiplier += round_multiplier_increase
|
|
else
|
|
pbMessage(_INTL("This concludes our quiz! You've cumulated {1} points in total.", @score))
|
|
pbMessage(_INTL("Thanks for playing!\\wtnp[20]"))
|
|
end
|
|
end
|
|
end_quiz()
|
|
end
|
|
|
|
def create_score_display
|
|
@score_viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
|
@score_viewport.z = 99999
|
|
@score_sprite = BitmapSprite.new(200, 32, @score_viewport)
|
|
@score_sprite.x = Graphics.width - 230
|
|
@score_sprite.y = 10
|
|
refresh_score_display
|
|
|
|
@streak_viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
|
@streak_viewport.z = 99999
|
|
@streak_sprite = BitmapSprite.new(200, 32, @streak_viewport)
|
|
@streak_sprite.x = Graphics.width - 230
|
|
@streak_sprite.y = 42
|
|
refresh_streak_ui
|
|
end
|
|
|
|
def refresh_score_display
|
|
return unless @score_sprite
|
|
@score_sprite.bitmap.clear
|
|
pbSetSystemFont(@score_sprite.bitmap)
|
|
text = _INTL("{1}", @score)
|
|
@score_sprite.bitmap.font.color = Color.new(160, 160, 160)
|
|
@score_sprite.bitmap.draw_text(1, 1, 200, 32, text, 2)
|
|
@score_sprite.bitmap.font.color = Color.new(255, 255, 255)
|
|
@score_sprite.bitmap.draw_text(0, 0, 200, 32, text, 2)
|
|
end
|
|
|
|
def dispose_score_display
|
|
@score_sprite&.dispose
|
|
@score_viewport&.dispose
|
|
@score_sprite = nil
|
|
@score_viewport = nil
|
|
@streak_sprite&.dispose
|
|
@streak_viewport&.dispose
|
|
@streak_sprite = nil
|
|
@streak_viewport = nil
|
|
end
|
|
|
|
def end_quiz()
|
|
dispose_score_display
|
|
hide_fusion_picture
|
|
Kernel.pbClearText()
|
|
previous_highest = pbGet(VAR_STAT_FUSION_QUIZ_HIGHEST_SCORE)
|
|
pbSet(VAR_STAT_FUSION_QUIZ_HIGHEST_SCORE,@score) if @score > previous_highest
|
|
|
|
previous_total = pbGet(VAR_STAT_FUSION_QUIZ_TOTAL_PTS)
|
|
pbSet(VAR_STAT_FUSION_QUIZ_TOTAL_PTS,previous_total+@score)
|
|
dispose
|
|
end
|
|
|
|
def start_quiz_new_round(round_multiplier = 1)
|
|
if @difficulty == :ADVANCED
|
|
base_points_q1 = 500
|
|
base_points_q1_redemption = 200
|
|
base_points_q2 = 600
|
|
base_points_q2_redemption = 200
|
|
perfect_round_points = 100
|
|
else
|
|
base_points_q1 = 300
|
|
base_points_q1_redemption = 100
|
|
base_points_q2 = 400
|
|
base_points_q2_redemption = 100
|
|
perfect_round_points = 50
|
|
end
|
|
|
|
pick_random_pokemon()
|
|
sprite_loader = BattleSpriteLoader.new
|
|
@pif_sprite = sprite_loader.select_new_pif_fusion_sprite(@head_id,@body_id)
|
|
show_fusion_picture(true)
|
|
correct_answers = []
|
|
|
|
#OBSCURED
|
|
correct_answers << new_question(calculate_points_awarded(base_points_q1, round_multiplier), _INTL("Which Pokémon is this fusion's body?"), @body_id, nil, true, :BODY)
|
|
pbMessage(_INTL("Next question!\\wtnp[10]"))
|
|
correct_answers << new_question(calculate_points_awarded(base_points_q2, round_multiplier), _INTL("Which Pokémon is this fusion's head?"), @head_id, nil, true, :HEAD)
|
|
|
|
#NON-OBSCURED
|
|
if !correct_answers[0] || !correct_answers[1]
|
|
show_fusion_picture(false)
|
|
pbMessage(_INTL("Okay, now's your chance to make up for the points you missed!\\wtnp[15]"))
|
|
if !correct_answers[0] #1st question redemption
|
|
new_question(calculate_points_awarded(base_points_q1_redemption, round_multiplier), _INTL("Which Pokémon is this fusion's body?"), @body_id, @body_choices, false, :BODY)
|
|
if !correct_answers[1]
|
|
pbMessage(_INTL("Next question!\\wtnp[10]"))
|
|
end
|
|
end
|
|
|
|
if !correct_answers[1] #2nd question redemption
|
|
new_question(calculate_points_awarded(base_points_q2_redemption, round_multiplier), _INTL("Which Pokémon is this fusion's head?"), @head_id, @head_choices, false, :HEAD)
|
|
end
|
|
else
|
|
pbSEPlay("Applause", 80)
|
|
pbMessage(_INTL("Wow! A perfect round! You get {1} more points!\\wtnp[15]", perfect_round_points))
|
|
pbMessage(_INTL("Let's see what this Pokémon looked like...\\wtnp[20]"))
|
|
show_fusion_picture(false)
|
|
fusion_name= GameData::Species.get(fusionOf(@head_id,@body_id)).name
|
|
pbMessage(_INTL("It's... \\C[1]{1}\\C[0]!",fusion_name))
|
|
|
|
end
|
|
current_streak_dialog()
|
|
hide_fusion_picture()
|
|
|
|
end
|
|
|
|
def calculate_points_awarded(base_points, round_multiplier)
|
|
points = base_points * round_multiplier
|
|
if @current_streak > 0
|
|
current_streak_multiplier = (@current_streak * @streak_multiplier) - @streak_multiplier
|
|
points += points * current_streak_multiplier
|
|
#p (base_points * round_multiplier)
|
|
#p (points * current_streak_multiplier)
|
|
end
|
|
return points
|
|
end
|
|
|
|
def new_question(points_value, question, answer_id, choices, other_chance_later,question_type)
|
|
points_value = points_value.to_i
|
|
answer_name = getPokemon(answer_id).name
|
|
answered_correctly = give_answer(question, answer_id, choices,question_type)
|
|
award_points(points_value) if answered_correctly
|
|
question_answer_followup_dialog(answered_correctly, answer_name, points_value, other_chance_later)
|
|
return answered_correctly
|
|
end
|
|
|
|
def increase_streak
|
|
@current_streak += 1
|
|
refresh_streak_ui()
|
|
end
|
|
|
|
def break_streak
|
|
@current_streak = 0
|
|
refresh_streak_ui()
|
|
end
|
|
|
|
|
|
def refresh_streak_ui
|
|
base_color_low_streak = Color.new(72, 72, 72)
|
|
base_color_medium_streak = Color.new(213, 254, 205)
|
|
base_color_high_streak = Color.new(100, 232, 96)
|
|
|
|
streak_color = base_color_low_streak
|
|
streak_color = base_color_medium_streak if @current_streak >= 2
|
|
streak_color = base_color_high_streak if @current_streak >= 4
|
|
|
|
# Update persistent sprite
|
|
if @streak_sprite
|
|
@streak_sprite.bitmap.clear
|
|
pbSetSystemFont(@streak_sprite.bitmap)
|
|
text = _INTL("Streak: {1}", @current_streak)
|
|
@streak_sprite.bitmap.font.color = Color.new(0, 0, 0)
|
|
@streak_sprite.bitmap.draw_text(1, 1, 200, 32, text, 2)
|
|
@streak_sprite.bitmap.font.color = streak_color
|
|
@streak_sprite.bitmap.draw_text(0, 0, 200, 32, text, 2)
|
|
end
|
|
end
|
|
|
|
|
|
|
|
def award_points(nb_points)
|
|
@score += nb_points
|
|
refresh_score_display
|
|
end
|
|
|
|
def question_answer_followup_dialog(answered_correctly, correct_answer, points_awarded_if_win, other_chance_later = false)
|
|
if !other_chance_later
|
|
pbMessage(_INTL("And the correct answer was...\\wtnp[10]"))
|
|
pbMessage(_INTL("...\\wtnp[10]"))
|
|
pbMessage(_INTL("{1}!", correct_answer))
|
|
end
|
|
|
|
if answered_correctly
|
|
pbSEPlay("itemlevel", 80)
|
|
increase_streak
|
|
pbMessage(_INTL("That's a correct answer!\\wtnp[10]"))
|
|
pbMessage(_INTL("You're awarded {1} points for your answer. Your current score is {2}.\\wtnp[20]", points_awarded_if_win, @score.to_s))
|
|
else
|
|
pbSEPlay("buzzer", 80)
|
|
break_streak
|
|
pbMessage(_INTL("Unfortunately, that was a wrong answer.\\wtnp[10]"))
|
|
pbMessage(_INTL("But you'll get another chance at it!\\wtnp[15]")) if other_chance_later
|
|
end
|
|
end
|
|
|
|
def current_streak_dialog()
|
|
return if @current_streak ==0
|
|
streak_base_worth= @difficulty == :REGULAR ? 25 : 100
|
|
if @current_streak % 4 == 0
|
|
extra_points = (@current_streak/4)*streak_base_worth
|
|
if @current_streak >= 8
|
|
pbMessage(_INTL("That's {1} correct answers in a row. You're on a roll!\\wtnp[20]", @current_streak))
|
|
else
|
|
pbMessage(_INTL("That's {1} correct answers in a row. You're doing great!\\wtnp[20]", @current_streak))
|
|
end
|
|
pbMessage(_INTL("Here's {1} extra points for maintaining a streak!\\wtnp[15]",extra_points))
|
|
award_points(extra_points)
|
|
end
|
|
end
|
|
|
|
def show_fusion_picture(obscured = false, x = nil, y = nil)
|
|
hide_fusion_picture()
|
|
spriteLoader = BattleSpriteLoader.new
|
|
bitmap = spriteLoader.load_pif_sprite_directly(@pif_sprite)
|
|
bitmap.scale_bitmap(Settings::FRONTSPRITE_SCALE)
|
|
@previewwindow = PictureWindow.new(bitmap)
|
|
@previewwindow.opacity = 0 unless @windowed
|
|
@previewwindow.y = y ? y : 30
|
|
@previewwindow.y += @picture_offset_y
|
|
@previewwindow.x = x ? x : (@difficulty == :ADVANCED ? 275 : 100)
|
|
@previewwindow.x += @picture_offset_x
|
|
@previewwindow.z = 100000
|
|
if obscured
|
|
@previewwindow.picture.pbSetColorValue(@silhouette_color)
|
|
end
|
|
end
|
|
|
|
def hide_fusion_picture()
|
|
@previewwindow.dispose if @previewwindow
|
|
end
|
|
|
|
def pick_random_pokemon(save_in_variable = 1)
|
|
random_pokemon = getRandomCustomFusion(true, @customs_list)
|
|
@head_id = random_pokemon[0]
|
|
@body_id = random_pokemon[1]
|
|
@selected_pokemon = getSpeciesIdForFusion(@head_id, @body_id)
|
|
pbSet(save_in_variable, @selected_pokemon)
|
|
end
|
|
|
|
def give_answer(prompt_message, answer_id, choices,question_type=:BODY)
|
|
question_answered = false
|
|
answer_pokemon_name = getPokemon(answer_id).name
|
|
choices = generate_new_choices(answer_id,question_type) unless choices
|
|
while !question_answered
|
|
if @difficulty == :ADVANCED
|
|
player_answer = prompt_pick_answer_advanced(prompt_message, answer_id)
|
|
else
|
|
player_answer = prompt_pick_answer_regular(prompt_message, answer_id, choices,question_type)
|
|
end
|
|
confirmed = pbMessage(_INTL("Is this your final answer?"), [_INTL("Yes"), _INTL("No")])
|
|
if confirmed == 0
|
|
question_answered = true
|
|
end
|
|
end
|
|
return player_answer == answer_pokemon_name
|
|
end
|
|
|
|
def get_random_pokemon_from_same_egg_group(pokemon, amount_required)
|
|
pokemon = ::GameData::Species.get(pokemon)
|
|
egg_groups = getPokemonEggGroups(pokemon)
|
|
|
|
# Get a list all pokemon in the same egg group
|
|
matching_egg_group = []
|
|
for num in 1..NB_POKEMON-4
|
|
next if pokemon.id_number == num
|
|
next if matching_egg_group.include?(num)
|
|
new_pokemon = ::GameData::Species.get(num)
|
|
new_pokemon_egg_groups = getPokemonEggGroups(new_pokemon)
|
|
matching_egg_group << num if (egg_groups & new_pokemon_egg_groups).any?
|
|
end
|
|
|
|
# Select random pokemon from the list
|
|
matching_egg_group.shuffle!
|
|
choices = []
|
|
for index in 1..amount_required
|
|
if matching_egg_group[index].nil?
|
|
# If there's not enough pokemon in the list (e.g. for Ditto), get anything
|
|
new_pokemon = rand(1..NB_POKEMON-4) until !choices.include?(new_pokemon) && new_pokemon != pokemon.id_number
|
|
choices << new_pokemon
|
|
else
|
|
choices << matching_egg_group[index]
|
|
end
|
|
end
|
|
|
|
return choices
|
|
end
|
|
|
|
def prompt_pick_answer_regular(prompt_message, real_answer, choices, question_type=:BODY)
|
|
echoln choices
|
|
if choices && choices.is_a?(Array)
|
|
commands = choices.shuffle
|
|
else
|
|
commands = generate_new_choices(real_answer,question_type)
|
|
end
|
|
chosen = pbMessage(prompt_message, commands)
|
|
return commands[chosen]
|
|
end
|
|
|
|
def generate_new_choices(real_answer,question_type=:BODY)
|
|
choices = []
|
|
choices << real_answer
|
|
choices.push(*get_random_pokemon_from_same_egg_group(real_answer, 3))
|
|
|
|
commands = []
|
|
choices.each do |dex_num, i|
|
|
species = getPokemon(dex_num)
|
|
commands.push(species.name)
|
|
end
|
|
if question_type == :BODY
|
|
@body_choices = commands
|
|
else
|
|
@head_choices = commands
|
|
end
|
|
return commands.shuffle
|
|
end
|
|
|
|
def prompt_pick_answer_advanced(prompt_message, answer)
|
|
commands = []
|
|
for dex_num in 1..NB_POKEMON-4
|
|
species = getPokemon(dex_num)
|
|
commands.push([dex_num - 1, species.name, species.name])
|
|
end
|
|
pbMessage(prompt_message)
|
|
return pbChooseListWithFilter(commands, 0, nil, 1,0,42,_INTL("Type with your keyboard"))
|
|
end
|
|
|
|
def get_score
|
|
return @score
|
|
end
|
|
|
|
def player_abandonned
|
|
return @abandonned
|
|
end
|
|
|
|
def dispose
|
|
@previewwindow.dispose
|
|
end
|
|
|
|
end
|