#!/usr/bin/env ruby # $Revision: 1.33 $ # $Date: 2003/12/06 18:12:08 $ # $Author: jefus, mikeman2 $ class Mobile < Base attr_accessor :connection # ability stuff attr_accessor :str, :dex, :con, :int, :wil, :per attr_accessor :skills def initialize(cfile) @config = cfile @connection = nil begin @str = Ability.new(@config['@str']) @dex = Ability.new(@config['@dex']) @con = Ability.new(@config['@con']) @int = Ability.new(@config['@int']) @wil = Ability.new(@config['@wil']) @per = Ability.new(@config['@per']) if @config['@access'] != nil @access = @config['@access'].to_i else @access = 0 end rescue Logger.log("Mobile#initialize: #{$!}") end #p @str @skills = {} super(@config) end def write(string) if @connection @connection.write(string) end end def puts(line) if @connection @connection.puts(line.gsub(/\n/, "\n\r")) end end def gets if @connection return @connection.gets end end def save self.instance_attributes.each{|key, value| if value.instance_of?(Ability) #Logger.log("saving ability #{key}") @config[key] = value.to_s end } @config['@access'] = @access super end def checkSkill(name, modifier = 0) # average situation modifier by default if skill = Skill[name] ordinary = getSkillScore(skill, Skill.Ordinary) good = getSkillScore(skill, Skill.Good) amazing = getSkillScore(skill, Skill.Amazing) if ordinary and good and amazing # make sure nothing is nil control = Dice.control situation = Dice.situation(modifier) result = control + situation puts("Rolling for #{skill.name}...") puts("Control: #{control}\tSituation: #{situation}\tResult: #{result}") if result <= amazing puts("&GAmazing success!&*") return Skill.Amazing elsif result <= good puts("&gGood success!&*") return Skill.Good elsif result <= ordinary puts("Ordinary success.&*") return Skill.Ordinary elsif control == 20 puts("&RCritical failure!&*") return Skill.CriticalFailure else if control == 1 # a 1 turns a failure into an ordinary success puts("Ordinary success. (automatic success)") return Skill.Ordinary else puts("&rFailure!&*") return Skill.Failure end end else Logger.log("No such skill '#{name}'.") # these no such skill messages # should be Logger.errors or etc. end end end def move(where) @location.puts("#{@name} leaves the room.", self) if @location super(where) @location.puts("#{@name} enters the room.", self) end def gainSkill(name, rank = 1) # improve by 1 rank by default if skill = Skill[name] if skill.broad? # broad skills don't have ranks if @skills.include?(skill) # already have it... can't do anything. Logger.log("gainSkill: #{self} already has skill '#{name}'.") else @skills[skill] = 0 puts("You learn the broad skill '#{name}'.") end else # but specialty skills do if @skills.include?(skill) # already have it... improve by rank @skills[skill] = @skills[skill] + rank puts("You improve in '#{name}' to rank #{@skills[skill]}.") else # learn from scratch @skills[skill] = rank puts("You learn the specialty skill '#{name}' at rank #{rank}.") end end else Logger.log("No such skill '#{name}'.") end end # returns an ordinary, good, or amazing score for a specified skill def getSkillScore(name, rating = Skill.Ordinary) # sanity check? if rating < Skill.Ordinary or rating > Skill.Amazing Logger.log("getSkillScore: invalid rating") return nil end # name can actually be either a skill name or a skill object if name.is_a?(String) skill = Skill[name] else # it should already be a skill object, then skill = name end if skill ability = eval("@#{skill.ability}") # "str" -> @str if @skills.include?(skill) # first of all, do we know the skill? rank = @skills[skill] if skill.broad? # broad skills have no rank, and score == ability case rating when Skill.Ordinary return ability.to_i when Skill.Good return ability / 2 when Skill.Amazing return ability / 4 end else # specialty skill scores == rank + ability case rating when Skill.Ordinary return ability + rank when Skill.Good return (ability + rank) / 2 when Skill.Amazing return (ability + rank) / 4 end end else # we don't have the skill if skill.broad? # if it's a broad skill, we use its untrained ability case rating when Skill.Ordinary return ability.untrained when Skill.Good return ability.untrained / 2 when Skill.Amazing return ability.untrained / 4 end else # first check to see if the specialty skill can be used untrained if skill.untrained? # untrained specialty skill checks use the broad skill score # i feel like i'm repeating code here, but oh well. case rating when Skill.Ordinary return ability.to_i when Skill.Good return ability / 2 when Skill.Amazing return ability / 4 end else return nil # skill can't be used untrained end end end end end def enterGame(new = false) move(@location) if new # special case for new players @str = Ability.new(10) @dex = Ability.new(10) @con = Ability.new(10) @int = Ability.new(10) @wil = Ability.new(10) @per = Ability.new(10) end end end Logger.log("Mobile code initialized.")