essytas 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. data/LICENSE +19 -0
  2. data/README +3 -0
  3. data/Rakefile +44 -0
  4. data/bin/essytas +2 -0
  5. data/lib/animation.rb +74 -0
  6. data/lib/config.rb +63 -0
  7. data/lib/core.rb +242 -0
  8. data/lib/cursor.rb +43 -0
  9. data/lib/def/animations/explosion1.anim +103 -0
  10. data/lib/def/characters.def +132 -0
  11. data/lib/def/de/dialogues/test.dlg +4 -0
  12. data/lib/def/de/enemies.trans +6 -0
  13. data/lib/def/de/items.trans +84 -0
  14. data/lib/def/de/skills.trans +48 -0
  15. data/lib/def/de/spells.trans +31 -0
  16. data/lib/def/en/dialogues/test.dlg +4 -0
  17. data/lib/def/en/enemies.trans +6 -0
  18. data/lib/def/en/items.trans +78 -0
  19. data/lib/def/en/skills.trans +48 -0
  20. data/lib/def/en/spells.trans +31 -0
  21. data/lib/def/enemies.def +8 -0
  22. data/lib/def/enemies/wolf.bhv +11 -0
  23. data/lib/def/init.def +5 -0
  24. data/lib/def/items.def +153 -0
  25. data/lib/def/loot.def +2 -0
  26. data/lib/def/particles.def +66 -0
  27. data/lib/def/recipies.def +18 -0
  28. data/lib/def/skills.def +40 -0
  29. data/lib/def/spells.def +42 -0
  30. data/lib/def/spells.rb +16 -0
  31. data/lib/def/weapons.def +9 -0
  32. data/lib/ext/astar/AMap.rb +146 -0
  33. data/lib/ext/astar/node.rb +72 -0
  34. data/lib/ext/astar/priority_queue.rb +44 -0
  35. data/lib/ext/shader.rb +116 -0
  36. data/lib/game/alchemy/recipe.rb +26 -0
  37. data/lib/game/character.rb +102 -0
  38. data/lib/game/combat/bar.rb +119 -0
  39. data/lib/game/combat/battle.rb +345 -0
  40. data/lib/game/combat/control.rb +18 -0
  41. data/lib/game/combat/gui.rb +190 -0
  42. data/lib/game/combat/gui/select_item.rb +11 -0
  43. data/lib/game/combat/gui/select_spell.rb +38 -0
  44. data/lib/game/constitution.rb +48 -0
  45. data/lib/game/equipment.rb +34 -0
  46. data/lib/game/inventory.rb +37 -0
  47. data/lib/game/item.rb +54 -0
  48. data/lib/game/magic.rb +33 -0
  49. data/lib/game/map/events.rb +29 -0
  50. data/lib/game/map/fog.rb +41 -0
  51. data/lib/game/map/map.rb +247 -0
  52. data/lib/game/map/map_animation.rb +26 -0
  53. data/lib/game/map/map_loader.rb +177 -0
  54. data/lib/game/map/map_object.rb +208 -0
  55. data/lib/game/map/map_particle.rb +27 -0
  56. data/lib/game/map/player.rb +78 -0
  57. data/lib/game/map/tile.rb +35 -0
  58. data/lib/game/mind.rb +24 -0
  59. data/lib/game/npc/behaviour.rb +45 -0
  60. data/lib/game/npc/bubble.rb +28 -0
  61. data/lib/game/npc/goal.rb +93 -0
  62. data/lib/game/npc/npc.rb +95 -0
  63. data/lib/game/npc/task.rb +73 -0
  64. data/lib/game/osd/magic.rb +24 -0
  65. data/lib/game/party.rb +42 -0
  66. data/lib/game/skills.rb +64 -0
  67. data/lib/game/spell.rb +35 -0
  68. data/lib/game_window.rb +95 -0
  69. data/lib/glsl/contrast.frag +12 -0
  70. data/lib/glsl/fade.frag +11 -0
  71. data/lib/glsl/mezzotint.frag +20 -0
  72. data/lib/glsl/noise.frag +20 -0
  73. data/lib/glsl/pixelate.frag +42 -0
  74. data/lib/glsl/radialblur.frag +28 -0
  75. data/lib/glsl/sepia.frag +15 -0
  76. data/lib/glsl/shockwave.frag +24 -0
  77. data/lib/glsl/tv_screen.frag +17 -0
  78. data/lib/graphics/animations/credits.txt +1 -0
  79. data/lib/graphics/animations/explosion2.png +0 -0
  80. data/lib/graphics/backgrounds/white_ties_grass.png +0 -0
  81. data/lib/graphics/chars/ejera.png +0 -0
  82. data/lib/graphics/chars/salyjea.png +0 -0
  83. data/lib/graphics/chars/tharat.png +0 -0
  84. data/lib/graphics/combat/tharat.png +0 -0
  85. data/lib/graphics/cursors/normal.png +0 -0
  86. data/lib/graphics/fog/clouds1.png +0 -0
  87. data/lib/graphics/gui/bar_center.png +0 -0
  88. data/lib/graphics/gui/bar_left.png +0 -0
  89. data/lib/graphics/gui/bar_right.png +0 -0
  90. data/lib/graphics/gui/button_background.png +0 -0
  91. data/lib/graphics/gui/button_close.png +0 -0
  92. data/lib/graphics/gui/button_close_hi.png +0 -0
  93. data/lib/graphics/gui/button_highlight.png +0 -0
  94. data/lib/graphics/gui/charequip_background.png +0 -0
  95. data/lib/graphics/gui/charselect_background.png +0 -0
  96. data/lib/graphics/gui/container_background.png +0 -0
  97. data/lib/graphics/gui/drop_item.png +0 -0
  98. data/lib/graphics/gui/equip_Etarae.png +0 -0
  99. data/lib/graphics/gui/equip_Mensch.png +0 -0
  100. data/lib/graphics/gui/equipslot_background.png +0 -0
  101. data/lib/graphics/gui/iteminfo_background.png +0 -0
  102. data/lib/graphics/gui/msg_background.png +0 -0
  103. data/lib/graphics/gui/scrollbar_background.png +0 -0
  104. data/lib/graphics/gui/scroller.png +0 -0
  105. data/lib/graphics/gui/tile_32.png +0 -0
  106. data/lib/graphics/gui/tile_32_highlight.png +0 -0
  107. data/lib/graphics/icons/items/arrow.png +0 -0
  108. data/lib/graphics/icons/items/bandage.png +0 -0
  109. data/lib/graphics/icons/items/boots_leather.png +0 -0
  110. data/lib/graphics/icons/items/bow.png +0 -0
  111. data/lib/graphics/icons/items/credits.txt +8 -0
  112. data/lib/graphics/icons/items/harness_leather.png +0 -0
  113. data/lib/graphics/icons/items/knife.png +0 -0
  114. data/lib/graphics/icons/items/shirt_linen.png +0 -0
  115. data/lib/graphics/items/none.png +0 -0
  116. data/lib/graphics/menu/ingame_background.png +0 -0
  117. data/lib/graphics/menu/ingame_background.xcf +0 -0
  118. data/lib/graphics/menu/start_background.png +0 -0
  119. data/lib/graphics/missing.png +0 -0
  120. data/lib/graphics/osd/magic_bg.png +0 -0
  121. data/lib/graphics/particles/leaf.png +0 -0
  122. data/lib/graphics/particles/smoke.png +0 -0
  123. data/lib/graphics/pixel.png +0 -0
  124. data/lib/graphics/tiles/test.png +0 -0
  125. data/lib/gui/base.rb +278 -0
  126. data/lib/gui/button.rb +93 -0
  127. data/lib/gui/char_equip.rb +118 -0
  128. data/lib/gui/char_selector.rb +54 -0
  129. data/lib/gui/context_menu.rb +115 -0
  130. data/lib/gui/draggable.rb +18 -0
  131. data/lib/gui/grid.rb +118 -0
  132. data/lib/gui/image.rb +17 -0
  133. data/lib/gui/inventory.rb +42 -0
  134. data/lib/gui/item_info.rb +33 -0
  135. data/lib/gui/slider.rb +10 -0
  136. data/lib/gui/textfield.rb +57 -0
  137. data/lib/layer.rb +64 -0
  138. data/lib/load.rb +31 -0
  139. data/lib/main.rb +18 -0
  140. data/lib/maps/def/test.bhv +26 -0
  141. data/lib/maps/def/test.rb +14 -0
  142. data/lib/maps/test.tmx +133 -0
  143. data/lib/maps/test2.tmx +94 -0
  144. data/lib/maps/test3.tmx +29 -0
  145. data/lib/maps/test3_lower.tmx +25 -0
  146. data/lib/maps/test3_upper.tmx +25 -0
  147. data/lib/maps/test_left.tmx +25 -0
  148. data/lib/maps/test_upper.tmx +25 -0
  149. data/lib/music/Butterfly Tea - A New Hope 2K11.mp3 +0 -0
  150. data/lib/music/Greendjohn - Rebirth.mp3 +0 -0
  151. data/lib/music/credits.txt +8 -0
  152. data/lib/parse.rb +605 -0
  153. data/lib/parse_tmx.rb +114 -0
  154. data/lib/particles.rb +127 -0
  155. data/lib/sample.rb +29 -0
  156. data/lib/save.rb +44 -0
  157. data/lib/song.rb +41 -0
  158. data/lib/sounds/click1.wav +0 -0
  159. data/lib/sounds/credits.txt +2 -0
  160. data/lib/sounds/error1.wav +0 -0
  161. data/lib/sprite.rb +35 -0
  162. data/lib/states/menus.rb +17 -0
  163. data/lib/states/menus/alchemy.rb +53 -0
  164. data/lib/states/menus/equip.rb +79 -0
  165. data/lib/states/menus/ingame.rb +34 -0
  166. data/lib/states/menus/magic.rb +31 -0
  167. data/lib/states/menus/options.rb +54 -0
  168. data/lib/states/menus/start.rb +38 -0
  169. data/lib/states/states.rb +154 -0
  170. data/lib/tileset.rb +42 -0
  171. data/lib/tools/world.rb +103 -0
  172. data/lib/tools/worldmap_editor.rb +221 -0
  173. data/lib/translate.rb +368 -0
  174. metadata +255 -0
@@ -0,0 +1,221 @@
1
+
2
+ # Note: This must be run from the lib directory.
3
+
4
+ require "rubygems"
5
+ require_relative "../core.rb"
6
+
7
+ module Core
8
+ module Tools
9
+
10
+ include Gosu
11
+
12
+ class AbstractMap
13
+ attr_accessor :lower, :upper, :right, :left
14
+ attr_reader :name, :file
15
+ def initialize(name, file)
16
+ @name = name
17
+ @file = file
18
+ @lower = @upper = @right = @left = nil
19
+ end
20
+ end
21
+
22
+ class WorldmapEditor < Window
23
+ include REXML
24
+
25
+ def initialize
26
+ super(1024, 768, false)
27
+ self.caption = "Essytas Worldmap Editor"
28
+ Core.window = self
29
+ @font = Core.font(Core::DEFAULT_FONT, 20)
30
+ @xoff = @yoff = 0
31
+ @unpress = []
32
+ @gui = {
33
+ :list => Core::GUI::Container.new(0, 0, 192, 768, 24)
34
+ }
35
+ @maps = []
36
+ start = Time.now.sec
37
+ Dir.new("maps/").each { |file|
38
+ next if File.directory?(file) or File.extname(file) != ".tmx"
39
+ map = Core::Parse.map(file.sub(".tmx", ""), true)
40
+ if !map.properties[:name] or map.properties[:name].empty?
41
+ map.properties[:name] = file.sub(".tmx", "")
42
+ end
43
+ map = AbstractMap.new(map.properties[:name], file.sub(".tmx", ""))
44
+ @maps.push(map)
45
+ @gui[:list].add(Core::GUI::Button.new(0, 0, 168, 24, map.name, lambda { clicked(map) }, true, :left))
46
+ }
47
+ puts("INFO: Loaded #{@maps.size} maps in #{Time.now.sec - start} seconds")
48
+ @world = load_world
49
+ end
50
+
51
+ def update
52
+ @gui.each_value { |el|
53
+ el.update
54
+ }
55
+ if @current and pressed?(Gosu::MsLeft) and mouse_x > 192
56
+ place_map(mouse_x - 192, mouse_y)
57
+ end
58
+ if pressed?(Gosu::MsRight) and mouse_x > 192
59
+ remove_map(mouse_x - 192, mouse_y)
60
+ end
61
+ unpress
62
+ end
63
+
64
+ def load_world
65
+ begin
66
+ file = File.open("tools/world.map", "r")
67
+ world = Marshal.load(file)
68
+ file.close
69
+ return world
70
+ rescue
71
+ return Array.new(@maps.size) { Array.new(@maps.size) }
72
+ end
73
+ end
74
+
75
+ def save_world
76
+ Marshal.dump(@world, File.open("tools/world.map", "w"))
77
+ y = 0
78
+ @world.size.times {
79
+ x = 0
80
+ @world[y].size.times {
81
+ if @world[y][x]
82
+ @world[y][x].left = @world[y][x - 1] if x > 0
83
+ @world[y][x].right = @world[y][x + 1] if x < @world[y].size
84
+ @world[y][x].upper = @world[y - 1][x] if y > 0
85
+ @world[y][x].lower = @world[y + 1][x] if y < @world.size
86
+ doc = Document.new(File.open("maps/#{@world[y][x].file}.tmx"))
87
+ doc.context[:attribute_quote] = :quote
88
+
89
+ if @world[y][x].upper
90
+ check_attribute(doc, "upper")
91
+ property_element(doc, "upper").add_attribute("value", @world[y][x].upper.file)
92
+ end
93
+ if @world[y][x].lower
94
+ check_attribute(doc, "lower")
95
+ property_element(doc, "lower").add_attribute("value", @world[y][x].lower.file)
96
+ end
97
+ if @world[y][x].left
98
+ check_attribute(doc, "left")
99
+ property_element(doc, "left").add_attribute("value", @world[y][x].left.file)
100
+ end
101
+ if @world[y][x].right
102
+ check_attribute(doc, "right")
103
+ property_element(doc, "right").add_attribute("value", @world[y][x].right.file)
104
+ end
105
+ doc.write(File.open("maps/#{@world[y][x].file}.tmx", "w"))
106
+ end
107
+ x += 1
108
+ }
109
+ y += 1
110
+ }
111
+ end
112
+
113
+ def property_element(doc, attribute)
114
+ return doc.root.elements['/map/properties/property[@name="'+attribute+'"]']
115
+ end
116
+
117
+ def check_attribute(doc, attribute)
118
+ if !doc.root.elements['/map/properties/property[@name="'+attribute+'"]']
119
+ props = doc.root.elements['/map/properties[1]']
120
+ if !props
121
+ props = Element.new('properties')
122
+ doc.root.elements['/map'] << props
123
+ props = doc.root.elements['/map/properties[1]']
124
+ end
125
+ prop = Element.new("property")
126
+ prop.add_attribute("name", "#{attribute}")
127
+ prop.add_attribute("value", "")
128
+ props << prop
129
+ doc.root.elements.add(props)
130
+ else
131
+ puts("found attribute #{attribute}")
132
+ end
133
+ end
134
+
135
+ def place_map(mx, my)
136
+ x = mx.to_i/32
137
+ y = my.to_i/24
138
+ if y >= @world.size or x >= @world.first.size
139
+ return
140
+ end
141
+ @world[y][x] = @current
142
+ end
143
+
144
+ def remove_map(mx, my)
145
+ x = mx.to_i/32
146
+ y = my.to_i/24
147
+ if y >= @world.size or x >= @world.first.size
148
+ return
149
+ end
150
+ @world[y][x] = nil
151
+ end
152
+
153
+ def draw
154
+ @gui.each_value { |el|
155
+ el.draw
156
+ }
157
+ y = 0
158
+ @world.size.times {
159
+ x = 0
160
+ @world.size.times {
161
+ if @world[y][x]
162
+ px = 192 + @xoff + (x * 32)
163
+ py = @yoff + (y * 24)
164
+ c = Gosu::Color::GRAY
165
+ draw_quad(px, py, c, px+32, py, c, px+32, py+24, c, px, py+24, c)
166
+ end
167
+ x += 1
168
+ }
169
+ y += 1
170
+ }
171
+ x = (mouse_x.to_i - 192) / 32
172
+ y = mouse_y.to_i / 24
173
+ if @world[y] and @world[y][x]
174
+ c = Gosu::Color::WHITE
175
+ @font.draw(@world[y][x].name, mouse_x + 12, mouse_y + 12, 200, 1, 1, Gosu::Color::BLACK)
176
+ w = @font.text_width(@world[y][x].name) + 8
177
+ x = mouse_x + 8
178
+ y = mouse_y + 8
179
+ draw_quad(x, y, c, x+w, y, c, x+w, y+24, c, x, y+24, c, 100)
180
+ end
181
+ end
182
+
183
+ def clicked(map)
184
+ @current = map
185
+ end
186
+
187
+ def pressed?(key)
188
+ p = button_down?(key)
189
+ if p
190
+ if @unpress.include?(key)
191
+ p = false
192
+ else
193
+ @unpress.push(key)
194
+ end
195
+ end
196
+ return p
197
+ end
198
+
199
+ def unpress
200
+ @unpress.each { |key|
201
+ if !button_down?(key)
202
+ @unpress.delete(key)
203
+ end
204
+ }
205
+ end
206
+
207
+ def needs_cursor?
208
+ return true
209
+ end
210
+
211
+ end
212
+
213
+ end
214
+ end
215
+
216
+ begin
217
+ editor = Core::Tools::WorldmapEditor.new
218
+ editor.show
219
+ ensure
220
+ editor.save_world if editor
221
+ end
@@ -0,0 +1,368 @@
1
+ # coding: utf-8
2
+
3
+ module Core
4
+ module Trans
5
+ # TODO auto-setup hashes, this is crap
6
+ # languages must be loaded from the available folders
7
+ @@items = {
8
+ "de" => {},
9
+ "en" => {},
10
+ }
11
+ @@skills = {
12
+ "de" => {},
13
+ "en" => {},
14
+ }
15
+ @@spells = {
16
+ "de" => {},
17
+ "en" => {},
18
+ }
19
+ @@dialogues = {
20
+ "de" => {},
21
+ "en" => {},
22
+ }
23
+ @@enemies = {
24
+ "de" => {},
25
+ "en" => {},
26
+ }
27
+ @@weapons = {
28
+ "de" => {},
29
+ "en" => {},
30
+ }
31
+
32
+ SUB = "[SUBSTITUTE]"
33
+
34
+ # menus are hardcoded anyway, so we dont parse anything
35
+ @@menu = {
36
+ "de" => {
37
+ :menu => "Menü",
38
+ :titlescreen_title => "Ewige Hoffnung",
39
+ :newgame => "Neues Spiel",
40
+ :loadgame => "Spiel laden",
41
+ :options => "Optionen",
42
+ :update => "Update",
43
+ :items => "Gegenstände",
44
+ :item => "Gegenstand",
45
+ :equipment => "Ausrüstung",
46
+ :skills => "Fertigkeiten",
47
+ :skill => "Fertigkeit",
48
+ :magic => "Magie",
49
+ :save => "Speichern",
50
+ :load => "Laden",
51
+ :language => "Sprache",
52
+ :options_details => "Details",
53
+ :volume => "Lautstärke",
54
+ :lang_english => "Englisch",
55
+ :lang_german => "Deutsch",
56
+ :restart_warning => "Das Spiel muss neugestartet werden, um alle Einstellungen zu übernehmen.",
57
+ :walk_here => "Hingehen",
58
+ :ground => "Boden",
59
+ :you => "Du",
60
+ :talk_to => "Ansprechen",
61
+ :attack => "Angreifen",
62
+ :abort => "Abbrechen",
63
+ :select_spell => "Zauber auswählen",
64
+ :botany => "Kräuterkunde",
65
+ :experience => "Erfahrung",
66
+ :xp_none => "Keine",
67
+ :xp_vlittle => "Sehr wenig",
68
+ :xp_little => "Wenig",
69
+ :xp_mediocre => "Mittelmäßig",
70
+ :xp_experienced => "Erfahren",
71
+ :xp_vexperienced => "Sehr erfahren",
72
+ :recipies => "Rezepte",
73
+ },
74
+ "en" => {
75
+ :menu => "Menu",
76
+ :titlescreen_title => "Ewige Hoffnung",
77
+ :newgame => "New Game",
78
+ :loadgame => "Load Game",
79
+ :options => "Options",
80
+ :update => "Update",
81
+ :items => "Items",
82
+ :item => "Item",
83
+ :equipment => "Equipment",
84
+ :skills => "Skills",
85
+ :skill => "Skill",
86
+ :magic => "Magic",
87
+ :save => "Save",
88
+ :load => "Load",
89
+ :language => "Language",
90
+ :options_details => "Details",
91
+ :volume => "Volume",
92
+ :lang_english => "English",
93
+ :lang_german => "German",
94
+ :restart_warning => "The game must be restarted to apply all settings.",
95
+ :walk_here => "Walk here",
96
+ :ground => "Ground",
97
+ :you => "You",
98
+ :talk_to => "Talk to",
99
+ :attack => "Attack",
100
+ :abort => "Abort",
101
+ :select_spell => "Select spell",
102
+ :botany => "Herbal lore",
103
+ :experience => "Experience",
104
+ :xp_none => "None",
105
+ :xp_vlittle => "Very little",
106
+ :xp_little => "Little",
107
+ :xp_mediocre => "Mediocre",
108
+ :xp_experienced => "Experienced",
109
+ :xp_vexperienced => "Very experienced",
110
+ :recipies => "Recipies",
111
+ },
112
+ }
113
+
114
+ def self.parse_items
115
+ begin
116
+ file = File.open("#{Core::LIBRARY_PATH}/def/#{Core.config[:language]}/items.trans", "r")
117
+ block = false
118
+ name = desc = ""
119
+ item = nil
120
+ file.each_line { |line|
121
+ line.gsub!("\n", "")
122
+ if line.start_with?("#") or line.length == 0
123
+ if line == "#EOF"
124
+ break
125
+ end
126
+ next
127
+ end
128
+ if line[0] == "{"
129
+ block = true
130
+ end
131
+ if line[0] == "}"
132
+ block = false
133
+ @@items[Core.config[:language]].store(item.name, name)
134
+ @@items[Core.config[:language]].store("#{item.name}_desc", desc)
135
+ next
136
+ end
137
+ if block
138
+ if line.start_with?("name")
139
+ line.gsub!(/name *= */, "")
140
+ name = line.gsub("\"", "")
141
+ elsif line.start_with?("desc")
142
+ line.gsub!(/desc *= */, "")
143
+ desc = line.gsub("\"", "")
144
+ end
145
+ else
146
+ item = Core::Game.find_item(line.to_sym)
147
+ end
148
+ }
149
+ file.close
150
+ rescue Errno::ENOENT
151
+ self.handle_failed("item")
152
+ end
153
+ end
154
+
155
+ def self.parse_spells
156
+ begin
157
+ file = File.open("#{Core::LIBRARY_PATH}/def/#{Core.config[:language]}/spells.trans", "r")
158
+ block = false
159
+ name = desc = ""
160
+ spell = nil
161
+ file.each_line { |line|
162
+ line.gsub!("\n", "")
163
+ if line.start_with?("#") or line.length == 0
164
+ if line == "#EOF"
165
+ break
166
+ end
167
+ next
168
+ end
169
+ if line[0] == "{"
170
+ block = true
171
+ end
172
+ if line[0] == "}"
173
+ block = false
174
+ @@spells[Core.config[:language]].store(spell.name, name)
175
+ @@spells[Core.config[:language]].store("#{spell.name}_desc".to_sym, desc)
176
+ next
177
+ end
178
+ if block
179
+ if line.start_with?("name")
180
+ line.gsub!(/name *= */, "")
181
+ name = line.gsub("\"", "")
182
+ elsif line.start_with?("desc")
183
+ line.gsub!(/desc *= */, "")
184
+ desc = line.gsub("\"", "")
185
+ end
186
+ else
187
+ spell = Core::Game.find_spell(line.to_sym)
188
+ end
189
+ }
190
+ file.close
191
+ rescue Errno::ENOENT
192
+ self.handle_failed("spell")
193
+ end
194
+ end
195
+
196
+ def self.parse_skills
197
+ begin
198
+ file = File.open("#{Core::LIBRARY_PATH}/def/#{Core.config[:language]}/skills.trans", "r")
199
+ block = false
200
+ name = desc = ""
201
+ skill = nil
202
+ file.each_line { |line|
203
+ line.gsub!("\n", "")
204
+ if line.start_with?("#") or line.length == 0
205
+ if line == "#EOF"
206
+ break
207
+ end
208
+ next
209
+ end
210
+ if line[0] == "{"
211
+ block = true
212
+ end
213
+ if line[0] == "}"
214
+ block = false
215
+ @@skills[Core.config[:language]].store(skill.name, name)
216
+ @@skills[Core.config[:language]].store("#{skill.name}_desc", desc)
217
+ next
218
+ end
219
+ if block
220
+ if line.start_with?("name")
221
+ line.gsub!(/name *= */, "")
222
+ name = line.gsub("\"", "")
223
+ elsif line.start_with?("desc")
224
+ line.gsub!(/desc *= */, "")
225
+ desc = line.gsub("\"", "")
226
+ end
227
+ else
228
+ skill = Core::Game.find_skill(line.to_sym)
229
+ end
230
+ }
231
+ file.close
232
+ rescue Errno::ENOENT
233
+ self.handle_failed("skill")
234
+ end
235
+ end
236
+
237
+ def self.parse_dialogues
238
+ Dir.new("#{Core::LIBRARY_PATH}/def/#{Core.config[:language]}/dialogues/").each { |f|
239
+ begin
240
+ if File.directory?("#{Core::LIBRARY_PATH}/#{f}") or File.extname("#{Core::LIBRARY_PATH}/#{f}") != ".dlg"
241
+ next
242
+ end
243
+ file = File.new("#{Core::LIBRARY_PATH}/def/#{Core.config[:language]}/dialogues/#{f}")
244
+ block = false
245
+ msg = ""
246
+ sym = nil
247
+ file.each_line { |line|
248
+ line.gsub!("\n", "")
249
+ if line.start_with?("#") or line.length == 0
250
+ if line == "#EOF"
251
+ break
252
+ end
253
+ next
254
+ end
255
+ line.lstrip!
256
+ if block
257
+ if line.include?("}")
258
+ block = false
259
+ @@dialogues[Core.config[:language]].store(sym, msg)
260
+ msg = ""
261
+ sym = nil
262
+ next
263
+ end
264
+ msg += "#{line}\n"
265
+ else
266
+ if line.include?("{")
267
+ block = true
268
+ sym = line.gsub(/\s?\{/, "").to_sym
269
+ end
270
+ end
271
+ }
272
+ file.close
273
+ rescue Errno::ENOENT
274
+ end
275
+ }
276
+ end
277
+
278
+ def self.parse_enemies
279
+ begin
280
+ file = File.open("#{Core::LIBRARY_PATH}/def/#{Core.config[:language]}/enemies.trans", "r")
281
+ block = false
282
+ name = desc = ""
283
+ enemy = nil
284
+ file.each_line { |line|
285
+ line.gsub!("\n", "")
286
+ if line.start_with?("#") or line.length == 0
287
+ if line == "#EOF"
288
+ break
289
+ end
290
+ next
291
+ end
292
+ if line[0] == "{"
293
+ block = true
294
+ end
295
+ if line[0] == "}"
296
+ block = false
297
+ @@enemies[Core.config[:language]].store(enemy.name, name)
298
+ @@enemies[Core.config[:language]].store("#{enemy.name}_desc", desc)
299
+ next
300
+ end
301
+ if block
302
+ if line.start_with?("name")
303
+ line.gsub!(/name *= */, "")
304
+ name = line.gsub("\"", "")
305
+ elsif line.start_with?("desc")
306
+ line.gsub!(/desc *= */, "")
307
+ desc = line.gsub("\"", "")
308
+ end
309
+ else
310
+ enemy = Core::Game.find_enemy(line.to_sym)
311
+ end
312
+ }
313
+ file.close
314
+ rescue Errno::ENOENT
315
+ self.handle_failed("skill")
316
+ end
317
+ end
318
+
319
+ def self.handle_failed(type)
320
+ puts("FATAL: No #{type} translations for selected language (#{Core.config[:language]}) found!")
321
+ if Core.config[:language] != "de"
322
+ Core.config[:language] = "de"
323
+ puts("INFO: Changed language to 'de' (German), try restarting")
324
+ Core.exit(1)
325
+ else
326
+ puts("INFO: Even the default language is not working, the install seems to be broken.\nTry redownloading the application.")
327
+ Core.exit(1)
328
+ end
329
+ end
330
+
331
+ def self.safe(hash, sym, replace=nil)
332
+ if !hash.has_key?(Core.config[:language])
333
+ warn("ERROR: Selected language (#{Core.config[:language]}) not available")
334
+ return ""
335
+ elsif !hash[Core.config[:language]].has_key?(sym)
336
+ warn("ERROR: Missing translation for #{sym} for language #{Core.config[:language]}")
337
+ return ""
338
+ end
339
+ if replace && !replace.empty?
340
+ return hash[Core.config[:language]][sym].gsub(SUB, replace)
341
+ else
342
+ return hash[Core.config[:language]][sym]
343
+ end
344
+ end
345
+
346
+ def self.item(sym)
347
+ return safe(@@items, sym)
348
+ end
349
+ def self.skill(sym)
350
+ return safe(@@skills, sym)
351
+ end
352
+ def self.spell(sym)
353
+ return safe(@@spells, sym)
354
+ end
355
+ def self.menu(sym, replace=nil)
356
+ return safe(@@menu, sym, replace)
357
+ end
358
+ def self.dialogue(sym, replace=nil)
359
+ return safe(@@dialogues, sym, replace)
360
+ end
361
+ def self.enemy(sym)
362
+ return safe(@@enemies, sym)
363
+ end
364
+ def self.weapon(sym)
365
+ return safe(@@weapons, sym)
366
+ end
367
+ end
368
+ end