Class: Alchemist::World

Inherits:
Object show all
Includes:
Record
Defined in:
lib/alchemist-server/world.rb

Constant Summary collapse

LOOK_RANGE =
10
LOCKED_MESSAGE =
"New basic elements can no longer be created. Try creating a compound instead"

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Record

#attr_names, hamsterize, included, #initialize, #read, #update

Class Method Details

.genesisObject



198
199
200
201
202
203
# File 'lib/alchemist-server/world.rb', line 198

def self.genesis
  World.new avatars: [],
            formulas: Hamster.hash,
            geography: Geography.new,
            elements: Hamster.hash
end

Instance Method Details

#at(avatar_name) ⇒ Object



104
105
106
107
# File 'lib/alchemist-server/world.rb', line 104

def at(avatar_name)
  a = avatar(avatar_name)
  geography.at a.x, a.y
end

#avatar(name) ⇒ Object



99
100
101
102
# File 'lib/alchemist-server/world.rb', line 99

def avatar(name)
  avatars.detect { |a| a.name == name } ||
  raise("#{name} isn't in the world")
end

#basic_elementsObject



186
187
188
# File 'lib/alchemist-server/world.rb', line 186

def basic_elements
  elements.values.select(&:basic?)
end

#compound_elementsObject



190
191
192
# File 'lib/alchemist-server/world.rb', line 190

def compound_elements
  elements.values.reject(&:basic?)
end

#create(avatar_name, c) ⇒ Object



139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/alchemist-server/world.rb', line 139

def create(avatar_name, c)
  a = avatar(avatar_name)
  new_a = a.add_to_inventory c

  element = elements[c]

  if element.nil?
    raise "Unknown element: #{c}."
  elsif !element.basic
    raise "#{c} is not a basic element."
  end

  update avatars: avatars - [a] + [new_a]
end

#dimensionsObject



182
183
184
# File 'lib/alchemist-server/world.rb', line 182

def dimensions
  geography.dimensions
end

#element(symbol) ⇒ Object



194
195
196
# File 'lib/alchemist-server/world.rb', line 194

def element(symbol)
  elements[symbol]
end

#forge(avatar_name, elem_1, elem_2, result) ⇒ Object



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/alchemist-server/world.rb', line 80

def forge(avatar_name, elem_1, elem_2, result)
  a = avatar avatar_name

  if !a.has?(elem_1, elem_2)
    raise "#{avatar_name} doesn't have the required elements"
  end

  f = Formula.new elem_1, elem_2, result

  if formulas[result] == f
    a_temp = a.remove_from_inventory elem_1, elem_2
    a_prime = a_temp.add_to_inventory result

    update avatars: avatars - [a] + [a_prime]
  else
    raise "Incorrect formula for #{result}"
  end
end

#formulate(avatar_name, elem_1, elem_2, novel_elem, name) ⇒ Object



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/alchemist-server/world.rb', line 58

def formulate(avatar_name, elem_1, elem_2, novel_elem, name)
  validate_element_symbol! novel_elem

  if formulas[novel_elem]
    raise "There is already a formula for #{novel_elem}"

  elsif elements[novel_elem]
    raise "#{novel_elem} is a basic element!"

  else
    f = Formula.new elem_1, elem_2, novel_elem
    e = Element.new symbol: novel_elem,
                    name: name,
                    basic: false

    w = update formulas: formulas.put(novel_elem, f),
               elements: elements.put(novel_elem, e)

    w.forge(avatar_name, elem_1, elem_2, novel_elem)
  end
end

#location(avatar_name) ⇒ Object



177
178
179
180
# File 'lib/alchemist-server/world.rb', line 177

def location(avatar_name)
  a = avatar avatar_name
  [a.x, a.y]
end

#lockObject



37
38
39
40
# File 'lib/alchemist-server/world.rb', line 37

def lock
  raise "The world is already locked" if locked
  update locked: true
end

#look(avatar_name) ⇒ Object



109
110
111
112
# File 'lib/alchemist-server/world.rb', line 109

def look(avatar_name)
  a = avatar(avatar_name)
  geography.string_around a.x, a.y, LOOK_RANGE
end

#messages_for(avatar_name) ⇒ Object



168
169
170
171
172
173
174
175
# File 'lib/alchemist-server/world.rb', line 168

def messages_for(avatar_name)
  a = avatar(avatar_name)
  messengers = nearby_avatars a

  messengers.sort_by(&:name).map do |m|
    { m.name => m.message_list }
  end.reduce({}, :merge)
end

#move(avatar_name, direction) ⇒ Object



154
155
156
157
158
159
# File 'lib/alchemist-server/world.rb', line 154

def move(avatar_name, direction)
  a = avatar(avatar_name)
  a_prime = a.move direction

  update avatars: avatars - [a] + [a_prime]
end

#nearby_avatar_names(name) ⇒ Object



27
28
29
# File 'lib/alchemist-server/world.rb', line 27

def nearby_avatar_names(name)
  nearby_avatars(avatar(name)).map &:name
end

#nearby_avatars(a) ⇒ Object



31
32
33
34
35
# File 'lib/alchemist-server/world.rb', line 31

def nearby_avatars(a)
  avatars.select do |avatar|
    avatar.near? a.location, LOOK_RANGE
  end
end

#new_avatar(name) ⇒ Object



15
16
17
18
19
20
21
22
23
24
25
# File 'lib/alchemist-server/world.rb', line 15

def new_avatar(name)
  a = Avatar.new name: name,
                 x: 0,
                 y: 0,
                 inventory: "",
                 messages: Hamster.hash

  if !avatars.include? a
    update avatars: avatars | [a]
  end
end

#new_element(char, name) ⇒ Object

Raises:



49
50
51
52
53
54
55
56
# File 'lib/alchemist-server/world.rb', line 49

def new_element(char, name)
  raise LOCKED_MESSAGE if locked
  validate_element_symbol! char

  e = Element.new symbol: char, name: name, basic: true

  update elements: elements.put(char, e)
end

#put(avatar_name, c) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/alchemist-server/world.rb', line 125

def put(avatar_name, c)
  a = avatar(avatar_name)

  if a.has? c
    new_g = geography.put a.x, a.y, c
    new_a = a.remove_from_inventory c

    update avatars: avatars - [a] + [new_a],
           geography: new_g
  else
    raise "#{avatar_name} doesn't have #{c}"
  end
end

#put_message(avatar_name, key, message) ⇒ Object



161
162
163
164
165
166
# File 'lib/alchemist-server/world.rb', line 161

def put_message(avatar_name, key, message)
  a = avatar(avatar_name)
  a_prime = a.put_message key, message

  update avatars: avatars - [a] + [a_prime]
end

#take(avatar_name) ⇒ Object



114
115
116
117
118
119
120
121
122
123
# File 'lib/alchemist-server/world.rb', line 114

def take(avatar_name)
  a = avatar(avatar_name)

  resource = geography.at a.x, a.y
  new_a = a.add_to_inventory resource
  new_g = geography.take a.x, a.y

  update avatars: avatars - [a] + [new_a],
         geography: new_g
end

#to_sObject



11
12
13
# File 'lib/alchemist-server/world.rb', line 11

def to_s
  (avatars.to_a.map(&:to_s) + [geography]).join("\n")
end

#validate_element_symbol!(symbol) ⇒ Object



42
43
44
45
46
# File 'lib/alchemist-server/world.rb', line 42

def validate_element_symbol!(symbol)
  if !Glyphs.strings.include? symbol
    raise "#{symbol} is not a valid element symbol"
  end
end