Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'rubygems'
- require 'digest/sha1'
- require 'rgl/adjacency'
- require 'rgl/dot'
- class Dialog
- attr_accessor :block, :steps, :first_step, :session
- def initialize(&block)
- self.steps = {}
- instance_eval(&block)
- end
- def step(name, &block)
- st = Step.new({:name => name, :dialog => self}, &block)
- self.steps[st.hash_id] = st
- self.first_step = st unless self.first_step
- end
- def process(session, hash_id = nil)
- self.session = session
- step = hash_id && self.steps[hash_id] ? self.steps[hash_id] : self.first_step
- step.process
- end
- def self.secret_phrase
- 'hello baby'
- end
- def self.step_hash(name)
- Digest::SHA1.hexdigest(Dialog.secret_phrase + name.to_s)
- end
- def to_graph
- dg = RGL::DirectedAdjacencyGraph.new
- self.steps.each do |key, step|
- step.run_type = :only_text
- parts = step.process
- dg.add_vertex(step.vertex_name)
- end
- self.steps.each do |key, step|
- step.parts.select{|v| v[0] == 'answer'}.each{|v| dg.add_edge(self.steps[key].vertex_name, self.steps[v[2]].vertex_name)}
- end
- dg.write_to_graphic_file('jpg')
- end
- end
- class Step
- attr_accessor :block, :hash_id, :dialog, :name, :parts, :redirect_step, :run_type
- def initialize(options = {}, &block)
- self.block = block
- self.name = options[:name]
- self.dialog = options[:dialog]
- self.parts = []
- self.hash_id = Dialog.step_hash(options[:name])
- end
- def part_def(type = :text, &block)
- if self.redirect_step || (self.run_type == :only_text && type != :text)
- nil
- else
- instance_eval(&block)
- end
- end
- def process
- res = instance_eval(&self.block)
- if res.is_a?(Symbol)
- next_button res
- end
- self.redirect_step ? self.redirect_step.process : self.parts
- end
- def message(text)
- part_def do
- self.parts << ['text', text]
- end
- end
- def answer(hash)
- part_def do
- text, step = hash.to_a.flatten
- self.parts << ['answer', text, Dialog.step_hash(step)]
- end
- end
- def has(name)
- part_def :action do
- !self.dialog.session[name].nil?
- end
- end
- def set(name, value)
- part_def :action do
- self.dialog.session[name] = value
- end
- end
- def next_button(name)
- part_def do
- self.parts << ['answer', '[Next]', Dialog.step_hash(name)]
- end
- end
- def exit
- part_def do
- self.parts << ['exit']
- end
- end
- def go_to(name)
- part_def :action do
- self.redirect_step = self.dialog.steps[Dialog.step_hash(name)]
- end
- end
- def give_quest
- part_def :action do
- puts 'Дали квест!'
- end
- end
- def player
- {:charm => 10}
- end
- def vertex_name
- self.name.to_s + ": " + self.parts.select{|v| v[0] == 'text' }.map{|v| v[1]}.join("\n")
- end
- end
- di = Dialog.new do
- step :greeting do
- message "Hello"
- answer "Let me buy something" => :shop
- answer "What's going on recently?" => :whats_new
- answer "No, nevermind" => :exit
- end
- step :whats_new do
- go_to :whats_new_good_mood if has :bought_something
- message "No, not gonna tell you anything. Maybe you only if you'd buy something..."
- answer "Okay man, show me the stuff" => :shop
- answer "Oh really? How about me using persuation" => :persuation
- answer "Oh really? Fuck you man, not gonna waste time" => :exit
- end
- step :persuation do
- if player[:charm] > 5
- set :persuation_success, true
- go_to :whats_new_good_mood
- else
- go_to :persuation_failed
- end
- end
- step :persuation_failed do
- message "Fuck you, man"
- :whats_new
- end
- step :whats_new_good_mood do
- message "You good man" if has :persuation_success
- message "Ok. Mr Sally yesterday win $400 in a lottery"
- :greeting
- end
- step :whats_new_bought do
- message "Stange things happen around"
- answer "Ok, I'll fix it for ya" => :quest_taken
- answer "No, I'd better buy something" => :shop
- answer "Nevermind" => :exit
- end
- step :quest_taken do
- message "Hurry up!"
- give_quest :title => "asdad"
- give_quest_part, :fight_win => 5
- :exit
- end
- step :shop do
- message "I got this sword"
- answer "Ok, I take it [buy sword]" => :buy
- answer "Fuck you!" => :greeting
- end
- step :buy do
- message "Okay, here's the sword"
- # player -= 50.gold
- set :bought_something, true
- :greeting
- end
- step :exit do
- message "Good bye then"
- exit
- end
- end
Add Comment
Please, Sign In to add comment