#==============================================================================
# 〓 转盘抽奖 (Lottery draw) 〓 Author: 芯☆淡茹水
#==============================================================================
# ■ 说明 ■
#--------------------------------------------------------------------------
# 1, 该转盘抽奖利用公共事件储存抽奖物品,分为 基本物品(设置项设置) 和
# 动态物品(脚本命令添加/删除)两种。
# 转盘上能够随机的物品为以上两种相加。
#--------------------------------------------------------------------------
# 2, 公共事件里编辑 增减物品,增减武器 或 增减防具 。当这个公共事件在物品
# 事件里时,里面的这些项目物品都将添加到转盘的随机物品中。
#--------------------------------------------------------------------------
# 3, 如果总共的随机物品当中有 珍贵物品 时,随机时至少有一件会是 珍贵物品 。
# 其它出现 珍贵物品 概率,依照设置项所设置的概率百分比。
#--------------------------------------------------------------------------
# 4, 进入抽奖场景,而未进行抽奖的,系统将储存当前转盘物品,防止进出抽奖场景
# 刷物品。
#--------------------------------------------------------------------------
# 5, 初始抽奖消耗为 金钱=>100 ,可用脚本命令适时更改。
#==============================================================================
# ■ 脚本命令 ■
#--------------------------------------------------------------------------
# 1,开始转盘抽奖 => XdRs_Ld.start_lottery_draw
#--------------------------------------------------------------------------
# 2,添加公共事件(设置有随机物品)里的所有物品到随机物品 =>
# XdRs_Ld.add_ld_event(event_id, type)
# 参数 event_id: 公共事件ID。
# type : 添加的类型(0:添加到普通物品; 1:添加到珍贵物品)
# 例:将 22 号公共事件里编辑的所有物品,添加到普通的随机物品中 =>
# XdRs_Ld.add_ld_event(22, 0)
# 将 15 号公共事件里编辑的所有物品,添加到珍贵的随机物品中 =>
# XdRs_Ld.add_ld_event(15, 1)
#--------------------------------------------------------------------------
# 3,将添加的公共事件里的所有物品从随机物品中删除 =>
# XdRs_Ld.del_ld_event(event_id, type)
# 参数同第 2 条。
#--------------------------------------------------------------------------
# 4,清空所有第 2 条添加的公共事件 => XdRs_Ld.clear_ld_events
#--------------------------------------------------------------------------
# 5,清除系统所记忆的转盘物品 => XdRs_Ld.clear_ld_data
#--------------------------------------------------------------------------
# 6,更改抽奖所需的消耗品 => XdRs_Ld.change_consume(type, num1, num2)
# 参数 type: 消耗类型(0:金钱;1:物品)
# num1: 数值1,消耗类型为 0(金钱)时,写所需的金钱数;
# 消耗类型为 1(物品)时,写物品ID。
# num2: 数值2,消耗类型为 0(金钱)时,省略不写;
# 消耗类型为 1(物品)时,写所需的数量。
# 例:设置抽奖消耗金钱 500 => XdRs_Ld.change_consume(0, 500)
# 设置抽奖消耗 10 号物品 3 个 => XdRs_Ld.change_consume(1, 10, 3)
#==============================================================================
#==============================================================================
module XdRs_Ld
#==============================================================================
# ■ 设置项 ■
#==============================================================================
#--------------------------------------------------------------------------
# 游戏分辨率宽。
Graphics_Width = 640
#--------------------------------------------------------------------------
# 游戏分辨率高。
Graphics_Height = 480
#--------------------------------------------------------------------------
# 基本普通抽奖物品的公共事件ID。
Base_Ordinary = 10
#--------------------------------------------------------------------------
# 基本珍贵抽奖物品的公共事件ID。
Base_Precious = 11
#--------------------------------------------------------------------------
# 转盘出现珍贵物品的概率百分比。
Precious_Rate = 10
#--------------------------------------------------------------------------
# 金钱图标名。
Gold_Icon = "035-Item04"
#--------------------------------------------------------------------------
# 得到奖品时播放的动画ID。
Award_Anm = 46
#--------------------------------------------------------------------------
# 指针转动时,播放的SE。
Needle_Se = "041-Knock02"
#--------------------------------------------------------------------------
end
#==============================================================================
# ■ 脚本正文 ■
#==============================================================================
module XdRs_Ld
#--------------------------------------------------------------------------
def self.ui_name
return "Ui_LotteryDraw" #UI图片名
end
#--------------------------------------------------------------------------
# 闪烁灯位置
#--------------------------------------------------------------------------
def self.lamp_place(index)
return [[201,21],[264,70],[289,156],[263,234],[196,283],[101,282],
[31,222],[11,144],[39,67],[103,18]][index]
end
#--------------------------------------------------------------------------
# 物品图标位置
#--------------------------------------------------------------------------
def self.item_place(index)
return [[182,52],[230,92],[250,150],[230,210],[182,248],[120,248],
[68,210],[46,150],[68,92],[120,52]][index]
end
#--------------------------------------------------------------------------
def self.has_ld_items
data = [[Base_Ordinary], [Base_Precious]]
data[0] += $game_system.ld_data[0]
data[1] += $game_system.ld_data[1]
return data.any?{|d| self.type_has_ld_items(d)}
end
#--------------------------------------------------------------------------
def self.type_has_ld_items(data)
return data.any?{|id| self.ld_list(id).size > 0}
end
#--------------------------------------------------------------------------
def self.ld_items
data = []
base = [[Base_Ordinary], [Base_Precious]]
data[0] = self.type_items(0, base) + self.type_items(0, $game_system.ld_data)
data[1] = self.type_items(1, base) + self.type_items(1, $game_system.ld_data)
return data
end
#--------------------------------------------------------------------------
def self.type_items(type, data)
items = []
data[type].size.times do |i|
list = self.ld_list(data[type][i])
list.each{|l| items << Ld_Item.new(self.item_obj(l))}
end
return items
end
#--------------------------------------------------------------------------
def self.ld_list(eventId)
event = $data_common_events[eventId]
return event.list.find_all{|l| [126,127,128].include?(l.code)}
end
#--------------------------------------------------------------------------
def self.item_obj(list)
case list.code
when 126; return $data_items[list.parameters[0]]
when 127; return $data_weapons[list.parameters[0]]
when 128; return $data_armors[list.parameters[0]]
end
end
#--------------------------------------------------------------------------
def self.lnitial_consumption
return ["gold", [100]] #初始抽奖消耗:金钱=>100
end
#--------------------------------------------------------------------------
def self.can_ld_start
cst = $game_system.consumption_data
return $game_party.gold >= cst[1][0] if cst[0] == "gold"
return $game_party.item_number(cst[1][0]) >= cst[1][1]
end
#--------------------------------------------------------------------------
def self.deductible
cst = $game_system.consumption_data
tp = cst[0]; d = cst[1][0]; n = cst[1][1]
tp == "gold" ? $game_party.lose_gold(d) : $game_party.gain_item(d, -n)
end
#--------------------------------------------------------------------------
def self.start_lottery_draw
unless self.has_ld_items
$game_temp.message_text = "没有抽奖物品,暂时无法抽奖!"
return
end
$scene = Lottery_Draw.new
end
#--------------------------------------------------------------------------
def self.add_ld_event(event_id, type=0)
return if type > 1
$game_system.set_ld_events(event_id, "add", type)
end
#--------------------------------------------------------------------------
def self.del_ld_event(event_id, type=0)
return if type > 1
$game_system.set_ld_events(event_id, "del", type)
end
#--------------------------------------------------------------------------
def self.clear_ld_data
$game_system.save_ld_items([])
end
#--------------------------------------------------------------------------
def self.clear_ld_events
$game_system.clear_all_ld_events
end
#--------------------------------------------------------------------------
def self.change_consume(type, num1, num2=0)
return if type == 0 && num1 <= 0
return if type == 1 && (!$data_items[num1] || num2 <= 0)
$game_system.set_consumption(type == 0 ? "gold" : "item", [num1,num2])
end
end
#==============================================================================
# 转换物品实例,减少数据容量
#==============================================================================
class Ld_Item
#--------------------------------------------------------------------------
def initialize(item)
@data_id = item.id
set_type(item)
end
#--------------------------------------------------------------------------
def set_type(item)
@item_type = case item
when RPG::Item ;"item"
when RPG::Weapon ;"weapon"
when RPG::Armor ;"armor"
end
end
#--------------------------------------------------------------------------
def obj
case @item_type
when "item"; return $data_items[@data_id]
when "weapon"; return $data_weapons[@data_id]
when "armor"; return $data_armors[@data_id]
end
end
end
#==============================================================================
# 添加抽奖所需的各种记录
#==============================================================================
class Game_System
#--------------------------------------------------------------------------
def ld_data; return @ld_data || [[],[]]; end
#--------------------------------------------------------------------------
def ld_items; return @ld_items || []; end
#--------------------------------------------------------------------------
def has_ld_item; return ld_items.size > 0; end
#--------------------------------------------------------------------------
def save_ld_items(items); @ld_items = items; end
#--------------------------------------------------------------------------
def set_ld_events(event_id, type, n)
@ld_data ||= [[],[]]
return if type == "add" && @ld_data[n].include?(event_id)
return if type == "del" && !@ld_data[n].include?(event_id)
type == "add" && @ld_data[n].push(event_id)
type == "del" && @ld_data[n].delete(event_id)
save_ld_items([])
end
#--------------------------------------------------------------------------
def consumption_data
return @consumption_data || XdRs_Ld.lnitial_consumption
end
#--------------------------------------------------------------------------
def set_consumption(type, data)
@consumption_data = [type, data]
end
#--------------------------------------------------------------------------
def clear_all_ld_events
@ld_data = nil
end
end
#==============================================================================
# 图片窗口
#==============================================================================
class XdRs_UiBase < RPG::Sprite
#--------------------------------------------------------------------------
def initialize(x, y, ui_name, rect, viewport=nil)
super(viewport)
@ui_name = ui_name
create_all(rect)
set_rect(rect)
move(x, y)
end
#--------------------------------------------------------------------------
def dispose
@drawing_board.bitmap.dispose
@drawing_board.dispose
self.bitmap.dispose
super
end
#--------------------------------------------------------------------------
def create_all(rect)
self.bitmap = @ui_name == "" ? Bitmap.new(rect.width, rect.height) :
RPG::Cache.picture(@ui_name)
@drawing_board = Sprite.new
end
#--------------------------------------------------------------------------
def set_rect(rect)
if @rect != rect
@rect = rect
refresh_rect
end
end
#--------------------------------------------------------------------------
def refresh_rect
self.src_rect.set(@rect.x, @rect.y, @rect.width, @rect.height)
@drawing_board.bitmap && @drawing_board.bitmap.dispose
@drawing_board.bitmap = Bitmap.new(@rect.width, @rect.height)
@drawing_board.bitmap.font.bold = true
end
#--------------------------------------------------------------------------
def move(x, y, z=nil)
self.x = @drawing_board.x = x
self.y = @drawing_board.y = y
return unless z
self.z = z; @drawing_board.z = z + 1
end
#--------------------------------------------------------------------------
def hide; self.visible = @drawing_board.visible = false; end
#--------------------------------------------------------------------------
def show; self.visible = @drawing_board.visible = true; end
#--------------------------------------------------------------------------
# 文字描边宽度
#--------------------------------------------------------------------------
def out_line_width; return 2; end
#--------------------------------------------------------------------------
# 图标尺寸(宽与高)
#--------------------------------------------------------------------------
def icon_size; return 24; end
#--------------------------------------------------------------------------
def clear; @drawing_board.bitmap.clear; end
#--------------------------------------------------------------------------
def set_font_size(n); @drawing_board.bitmap.font.size = n; end
#--------------------------------------------------------------------------
def set_font_color(c); @drawing_board.bitmap.font.color = c; end
#--------------------------------------------------------------------------
def draw_text(x, y, w, h, text, a=0)
last_color = @drawing_board.bitmap.font.color.clone
ow = out_line_width
set_font_color(Color.new(0,0,0,160))
@drawing_board.bitmap.draw_text(x+ow, y, w, h, text, a)
@drawing_board.bitmap.draw_text(x-ow, y, w, h, text, a)
@drawing_board.bitmap.draw_text(x, y+ow, w, h, text, a)
@drawing_board.bitmap.draw_text(x, y-ow, w, h, text, a)
set_font_color(last_color)
@drawing_board.bitmap.draw_text(x, y, w, h, text, a)
end
#--------------------------------------------------------------------------
def draw_icon(x, y, icon_name)
size = icon_size
blt_image(x, y, Rect.new(0, 0, size, size), RPG::Cache.icon(icon_name))
end
#--------------------------------------------------------------------------
def blt(x, y, rect, image_name=nil)
blt_image(x, y, rect, RPG::Cache.picture(image_name || @ui_name))
end
#--------------------------------------------------------------------------
def blt_image(x, y, rect, image)
@drawing_board.bitmap.blt(x, y, image, rect)
end
#--------------------------------------------------------------------------
def draw_item(x, y, item)
draw_icon(x, y, item.icon_name)
cw = @drawing_board.bitmap.text_size(item.name).width
ch = @drawing_board.bitmap.font.size
draw_text(x+icon_size+2, y, cw, ch, item.name)
end
#--------------------------------------------------------------------------
def play_se(se_name)
Audio.se_play("Audio/SE/" + se_name, 100, 100) if se_name != ""
end
#--------------------------------------------------------------------------
def play_anm(anm_id)
anm = $data_animations[anm_id]
anm && animation(anm, true)
end
end
#==============================================================================
# 图片按钮
#==============================================================================
class XdRs_Button < XdRs_UiBase
#--------------------------------------------------------------------------
def initialize(x, y, ui_name, rect, n_rect, viewport=nil)
super(x, y, ui_name, rect, viewport)
@c_rect = rect
@n_rect = n_rect
@is_current = true
@press_count = 0
end
#--------------------------------------------------------------------------
def refresh_rect
super
self.ox = @rect.width / 2
self.oy = @rect.height / 2
end
#--------------------------------------------------------------------------
def refresh_current(state)
if @is_current != state
@is_current = state
set_rect(@is_current ? @c_rect : @n_rect)
end
end
#--------------------------------------------------------------------------
def press
self.zoom_x = self.zoom_y = 0.9
@press_count = 3
end
#--------------------------------------------------------------------------
def reduction
self.zoom_x = self.zoom_y = 1
end
#--------------------------------------------------------------------------
def update
super
update_press
end
#--------------------------------------------------------------------------
def update_press
return if @press_count == 0
@press_count -= 1
@press_count == 0 && reduction
end
end
#==============================================================================
# 闪烁灯
#==============================================================================
class XdRs_LdLamp < XdRs_Button
#--------------------------------------------------------------------------
def initialize(index, x, y)
rect0 = Rect.new(300, 206, 16, 16)
rect1 = Rect.new(300, 222, 28, 28)
place = XdRs_Ld.lamp_place(index)
super(x+place[0], y+place[1], XdRs_Ld.ui_name, rect0, rect1)
@twinkle_type = index % 2
@count = 20
refresh_current(@twinkle_type == 0)
end
#--------------------------------------------------------------------------
def start_twinkle
@twinkle_type = (@twinkle_type+1)%2
refresh_current(@twinkle_type == 0)
@count = 20
end
#--------------------------------------------------------------------------
def update
super
update_twinkle
end
#--------------------------------------------------------------------------
def update_twinkle
return unless self.visible
@count > 0 ? @count -= 1 : start_twinkle
end
end
#==============================================================================
# 白色转幕
#==============================================================================
class XdRs_LdCurtain < XdRs_UiBase
#--------------------------------------------------------------------------
def initialize(x, y)
super(x, y, XdRs_Ld.ui_name, Rect.new(495,48,78,128))
self.ox = @rect.width / 2
self.oy = @rect.height
@index = rand 10
start_turn
end
#--------------------------------------------------------------------------
def start_turn
@count = 0
self.angle = 360 - (@index * 36 + 18)
@index = (@index+1) % 10
end
#--------------------------------------------------------------------------
def update
super
update_turn
end
#--------------------------------------------------------------------------
def update_turn
return unless self.visible
@count < 10 ? @count += 1 : start_turn
end
end
#==============================================================================
# 转针
#==============================================================================
class XdRs_LdNeedle < XdRs_UiBase
#--------------------------------------------------------------------------
def initialize(x, y)
super(x, y, XdRs_Ld.ui_name, Rect.new(381,48,114,150))
self.ox = @rect.width / 2
self.oy = 93
@index = rand 10
@count = @speed = 0
@is_start = false
self.angle = 360 - (@index * 36 + 18)
end
#--------------------------------------------------------------------------
def start
return if @is_start
add = rand 100
@count = (rand(2) == 0 ? add : -add) + 200
@is_start = true
end
#--------------------------------------------------------------------------
def index; return @index; end
#--------------------------------------------------------------------------
def in_rotation; return @is_start; end
#--------------------------------------------------------------------------
def refresh_angle
play_se(XdRs_Ld::Needle_Se)
@index = (@index+1) % 10
self.angle = 360 - (@index * 36 + 18)
@speed = [(300 - @count) / 50, 1].max
end
#--------------------------------------------------------------------------
def update
super
update_turn
end
#--------------------------------------------------------------------------
def update_turn
return if !self.visible || !@is_start
@count -= 1 if @count > 0
@speed -= 1 if @speed > 0
@speed == 0 && refresh_angle
@is_start = false if @count == 0
end
end
#==============================================================================
# 奖品显示
#==============================================================================
class XdRs_LdPrize < XdRs_UiBase
#--------------------------------------------------------------------------
def initialize
x = XdRs_Ld::Graphics_Width / 2
y = XdRs_Ld::Graphics_Height / 2
super(x, y, "", Rect.new(0,0,300,300))
self.ox = @drawing_board.ox = 150
self.oy = @drawing_board.oy = 150
show_prize
end
#--------------------------------------------------------------------------
def show_prize(prize=nil)
hide; clear
return if !prize
play_anm(XdRs_Ld::Award_Anm)
image = XdRs_Ld.ui_name
blt(50, 80, Rect.new(300, 255, 200, 45), image)
blt(125, 140, Rect.new(381, 198, 50, 50), image)
ix = (50 - icon_size) / 2
draw_icon(125+ix, 140+ix, prize.icon_name)
draw_text(0, 200, 300, 24, prize.name, 1)
show
end
end
#==============================================================================
# 抽奖场景
#==============================================================================
class Lottery_Draw
#--------------------------------------------------------------------------
def main
init_data
create_all
start
Graphics.transition
loop do
Graphics.update; Input.update; update
break if $scene != self
end
Graphics.freeze
dispose_all
end
#--------------------------------------------------------------------------
def init_data
@process = 0
@all_items = XdRs_Ld.ld_items
end
#--------------------------------------------------------------------------
def create_all
@lamps = []
x = (XdRs_Ld::Graphics_Width - 300) / 2
y = (XdRs_Ld::Graphics_Height - 300) / 2
cy = y + 304; hx = x + 150; hy = y + 150
rect1 = Rect.new(300,48,81,79); rect2 = Rect.new(300,127,81,79)
@map_bg = Spriteset_Map.new
@turntable = XdRs_UiBase.new(x, y, XdRs_Ld.ui_name,Rect.new(0,0,300,300))
@consume = XdRs_UiBase.new(x, cy, XdRs_Ld.ui_name,Rect.new(300,0,300,48))
@curtain = XdRs_LdCurtain.new(hx, hy)
@needle = XdRs_LdNeedle.new(hx, hy)
@button = XdRs_Button.new(hx, hy, XdRs_Ld.ui_name, rect1, rect2)
@prize_show = XdRs_LdPrize.new
10.times{|i| @lamps << XdRs_LdLamp.new(i, x, y)}
end
#--------------------------------------------------------------------------
def dispose_all
@map_bg.dispose
@button.dispose
@needle.dispose
@curtain.dispose
@consume.dispose
@turntable.dispose
@prize_show.dispose
@lamps.each{|l| l.dispose}
end
#--------------------------------------------------------------------------
def start
refresh_items
refresh_demand
refresh_button
end
#--------------------------------------------------------------------------
def refresh_items
@now_items = $game_system.has_ld_item ? $game_system.ld_items : create_new_items
draw_now_items
end
#--------------------------------------------------------------------------
def refresh_demand
@consume.clear
data = $game_system.consumption_data
x = 80; y = (48 - @consume.icon_size) / 2 + 2
@consume.set_font_color(Color.new(255,255,255))
if data[0] == "gold"
@consume.draw_icon(x, y, XdRs_Ld::Gold_Icon)
x += @consume.icon_size + 2
@consume.draw_text(x, y, 200, 24, $data_system.words.gold)
else
@consume.draw_item(x, y, $data_items[data[1][0]])
end
color = XdRs_Ld.can_ld_start ? Color.new(255,255,255) : Color.new(200,0,0)
@consume.set_font_color(color)
@consume.draw_text(0, y, 284, 24, num_text(data), 2)
end
#--------------------------------------------------------------------------
def refresh_button
@button.refresh_current(XdRs_Ld.can_ld_start)
end
#--------------------------------------------------------------------------
def create_new_items
data = []
p_index = @all_items[1].size > 0 ? rand(10) : nil
can_repeat = (@all_items[0] + @all_items[1]).size < 10
while data.size < 10
item = rand_item(is_precious(p_index, data) ? 1 : 0)
item && (can_repeat || !data.include?(item)) && data.push(item)
end
$game_system.save_ld_items(data)
return data
end
#--------------------------------------------------------------------------
def is_precious(index, data)
return rand(100) < XdRs_Ld::Precious_Rate || index && index == data.size
end
#--------------------------------------------------------------------------
def rand_item(type)
obj = @all_items[type]
return obj[rand(obj.size)]
end
#--------------------------------------------------------------------------
def draw_now_items
@turntable.clear
10.times do |i|
next unless @now_items[i]
place = XdRs_Ld.item_place(i)
x = place[0] - @turntable.icon_size / 2
y = place[1] - @turntable.icon_size / 2
@turntable.draw_icon(x,y,@now_items[i].obj.icon_name)
end
end
#--------------------------------------------------------------------------
def num_text(d)
num1 = d[0] == "gold" ? $game_party.gold : $game_party.item_number(d[1][0])
num2 = d[0] == "gold" ? d[1][0] : d[1][1]
return num2.to_s + "/" + num1.to_s
end
#--------------------------------------------------------------------------
def prize
return @now_items[@needle.index].obj
end
#--------------------------------------------------------------------------
def get_prize
case prize
when RPG::Item ;$game_party.gain_item(prize.id, 1)
when RPG::Weapon ;$game_party.gain_weapon(prize.id, 1)
when RPG::Armor ;$game_party.gain_armor(prize.id, 1)
end
end
#--------------------------------------------------------------------------
def update
update_windows
send("process"+@process.to_s)
end
#--------------------------------------------------------------------------
def update_windows
@button.update
@needle.update
@curtain.update
@prize_show.update
@lamps.each{|l| l.update}
end
#--------------------------------------------------------------------------
def process0
Input.trigger?(Input::C) && ready_start
Input.trigger?(Input::B) && return_to_map
end
#--------------------------------------------------------------------------
def process1
!@needle.in_rotation && end_rotation
end
#--------------------------------------------------------------------------
def process2
Input.trigger?(Input::C) && come_again
end
#--------------------------------------------------------------------------
def ready_start
@button.press
if !XdRs_Ld.can_ld_start
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.decision_se)
$game_system.save_ld_items([])
XdRs_Ld.deductible
refresh_demand
@needle.start
@curtain.hide
@lamps.each{|l| l.hide}
@process = 1
end
#--------------------------------------------------------------------------
def end_rotation
@prize_show.show_prize(prize)
get_prize
refresh_demand
refresh_button
@process = 2
end
#--------------------------------------------------------------------------
def come_again
$game_system.se_play($data_system.decision_se)
@prize_show.show_prize
@curtain.show
@lamps.each{|l| l.show}
refresh_items
@process = 0
end
#--------------------------------------------------------------------------
def return_to_map
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Map.new
end
end
#==============================================================================
# end
#==============================================================================