essytas 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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,93 @@
1
+
2
+ module Core::GUI
3
+ # Button to be used in menus.
4
+ # Executes the given lambda when clicked
5
+ class Button < Element
6
+ attr_accessor :background, :proc
7
+ @@sound = Core::Sample.new("click1")
8
+ @@error = Core::Sample.new("error1")
9
+ def initialize(x, y, w, h, text, proc, bg=true, align=:center, text_height=h)
10
+ super(x, y, w, h)
11
+ if bg
12
+ @bg = Core.sprite("gui/button_background")
13
+ end
14
+ @hi = Core.sprite("gui/button_highlight", true)
15
+ @font = Core.font(Core::DEFAULT_FONT, text_height)
16
+ @text = text
17
+ @proc = proc
18
+ @selected = false
19
+ @background = bg
20
+ @align = align
21
+ @enabled = true
22
+ @fw = @font.text_width(@text)
23
+ end
24
+ def hovered?
25
+ return @selected
26
+ end
27
+ def toggle
28
+ @enabled = !@enabled
29
+ end
30
+ def disable
31
+ @enabled = false
32
+ end
33
+ def enable
34
+ @enabled = true
35
+ end
36
+ def update
37
+ @selected = Core.inside?(Core.window.mouse_x, Core.window.mouse_y, @x+@xoff, @y+@yoff, @x+@w+@xoff, @y+@h+@yoff)
38
+ if @selected and Core.window.pressed?(Gosu::MsLeft)
39
+ if @enabled
40
+ @@sound.play(0.25)
41
+ @proc.call
42
+ else
43
+ @@error.play
44
+ end
45
+ end
46
+ end
47
+ def draw
48
+ case @align
49
+ when :center
50
+ @font.draw(@text, @x + @xoff + (@w/2) - (@fw/2), @y + @yoff + (@h/9), Core::GUI_Z + 10 + @zoff, 1, 1, Gosu::Color::BLACK)
51
+ when :left
52
+ @font.draw(@text, @x + @xoff + 4, @y + @yoff + (@h/9), Core::GUI_Z + 10 + @zoff, 1, 1, Gosu::Color::BLACK)
53
+ when :right
54
+ @font.draw(@text, @x + @xoff + (@w-@fw), @y + @yoff + (@h/9), Core::GUI_Z + 10 + @zoff, 1, 1, Gosu::Color::BLACK)
55
+ end
56
+ if @background
57
+ color = Gosu::Color.new(255, 255, 255, 255)
58
+ if !@enabled
59
+ color.saturation = 125
60
+ end
61
+ @bg.draw(@x + @xoff, @y + @yoff, Core::GUI_Z + 9 + @zoff, @w/@bg.width.to_f, @h/@bg.height.to_f, color)
62
+ end
63
+ if @selected and @enabled
64
+ @hi.draw(@x + @xoff, @y + @yoff, Core::GUI_Z + 11 + @zoff, @w/@hi.width.to_f, @h/@hi.height.to_f, 0xff999999, :additive)
65
+ end
66
+ end
67
+ end
68
+
69
+ # Same as Button, but draws an image instead of text
70
+ class ImageButton < Button
71
+ attr_reader :bg
72
+ def initialize(x, y, file, proc, w=-1, h=-1)
73
+ @bg = Core.sprite(file.to_s)
74
+ if w < 0
75
+ @w = w = @bg.width
76
+ end
77
+ if h < 0
78
+ @h = h = @bg.height
79
+ end
80
+ super(x, y, w, h, "", proc, false)
81
+ end
82
+ def draw
83
+ color = Gosu::Color.new(255, 255, 255, 255)
84
+ if !@enabled
85
+ color.saturation = 125
86
+ end
87
+ @bg.draw(@x+@xoff, @y+@yoff, Core::GUI_Z + 10 + @zoff, @w/@bg.width.to_f, @h/@bg.height.to_f, color)
88
+ if @selected and @enabled
89
+ @hi.draw(@x+@xoff, @y+@yoff, Core::GUI_Z + 11 + @zoff, @w/@hi.width.to_f, @h/@hi.height.to_f, 0xff999999, :additive)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,118 @@
1
+
2
+ module Core::GUI
3
+
4
+ class CharEquip < Element
5
+ attr_reader :slot
6
+ @@positions = {
7
+ :head => [144, 72],
8
+ :torso => [144, 160],
9
+ :rarm => [80, 256],
10
+ :larm => [208, 256],
11
+ :legs => [144, 320],
12
+ :feet => [144, 416],
13
+ :back => [208, 96],
14
+ }
15
+ def initialize(x, y, c)
16
+ super(x, y, 320, 512)
17
+ @bg = Core.sprite("gui/charequip_background")
18
+ @body = Core.sprite("gui/equip_#{c.race}")
19
+ @font = Core.font(Core::DEFAULT_FONT, 24)
20
+ @equipped = {}
21
+ reset_slots
22
+ @char = c
23
+ @equip = false
24
+ @changed = false
25
+ setup_equipment
26
+ end
27
+ def char=(c)
28
+ @char = c
29
+ @body = Core.sprite("gui/equip_#{c.race}")
30
+ setup_equipment
31
+ end
32
+ def reset_slots
33
+ @slots = {}
34
+ @colors = {}
35
+ @@positions.each { |loc, pos|
36
+ @slots.store(loc, ImageButton.new(@x+pos[0], @y+pos[1], "gui/equipslot_background", lambda {}))
37
+ }
38
+ @slots.each { |k, v|
39
+ @colors.store(v, Gosu::Color.new(255, 255, 255, 255))
40
+ }
41
+ end
42
+ def highlight_slots(ary)
43
+ @colors = {}
44
+ red = @slots
45
+ green = {}
46
+ ary.each { |loc|
47
+ green.store(loc, red[loc])
48
+ green[loc].proc = lambda { equip(loc) }
49
+ red.delete(loc)
50
+ }
51
+ red.each_value { |img|
52
+ color = Gosu::Color.new(255, 255, 0, 0)
53
+ @colors.store(img, color)
54
+ }
55
+ green.each_value { |img|
56
+ color = Gosu::Color.new(255, 0, 255, 0)
57
+ @colors.store(img, color)
58
+ }
59
+ @slots = red.merge(green)
60
+ end
61
+ def setup_equipment
62
+ equip = @char.equipment
63
+ @equipped = {}
64
+ equip.each { |loc, item|
65
+ if item
66
+ @equipped.store(loc, ImageButton.new(@x+@@positions[loc][0], @y+@@positions[loc][1], "#{item.icon_file}", lambda { unequip(loc) }, 32, 32))
67
+ end
68
+ }
69
+ end
70
+ def equip(location)
71
+ @equip = true
72
+ @slot = location
73
+ end
74
+ def equip?
75
+ if @equip
76
+ @equip = false
77
+ return true
78
+ else
79
+ return false
80
+ end
81
+ end
82
+ def unequip(location)
83
+ # TODO weight/capacity check
84
+ @char.inventory.add(@char.equipment.remove_at(location))
85
+ setup_equipment
86
+ @changed = true
87
+ end
88
+ def update
89
+ super
90
+ @equipped.each_value { |el|
91
+ el.update
92
+ }
93
+ @slots.each_value { |but|
94
+ but.update
95
+ }
96
+ end
97
+ def draw
98
+ super
99
+ @bg.draw(@x, @y, Core::GUI_Z + 5, @w/@bg.width.to_f, @h/@bg.height.to_f)
100
+ @body.draw(@x+32, @y+32, Core::GUI_Z + 6, (@w-64)/@body.width.to_f, (@h-64)/@body.height.to_f)
101
+ @slots.each_value { |but|
102
+ but.bg.draw(but.x, but.y, Core::GUI_Z + 10, 1, 1, @colors[but])
103
+ }
104
+ @equipped.each_value { |el|
105
+ el.draw
106
+ }
107
+ end
108
+ def changed?
109
+ if @changed
110
+ @changed = false
111
+ return true
112
+ else
113
+ return false
114
+ end
115
+ end
116
+ end
117
+
118
+ end
@@ -0,0 +1,54 @@
1
+
2
+ require_relative "base.rb"
3
+
4
+ module Core::GUI
5
+
6
+ class CharSelector < Element
7
+ attr_reader :index
8
+ def initialize(x, y, party, w=256, h=32)
9
+ super(x, y, w, h)
10
+ @index = 0
11
+ @changed = false
12
+ @party = party
13
+ @background = Core.sprite("gui/charselect_background")
14
+ @font = Core.font(Core::DEFAULT_FONT, 24)
15
+ @left = Button.new(x, y, 32, 32, "<", lambda {left}, false)
16
+ @right = Button.new(x+w-32, y, 32, 32, ">", lambda {right}, false)
17
+ end
18
+ def update
19
+ @left.xoff = @right.xoff = @xoff
20
+ @left.yoff = @right.yoff = @yoff
21
+ @left.update
22
+ @right.update
23
+ end
24
+ def left
25
+ @index -= 1
26
+ if @index < 0
27
+ @index = @party.members.size-1
28
+ end
29
+ @changed = true
30
+ end
31
+ def right
32
+ @index += 1
33
+ if @index >= @party.members.size
34
+ @index = 0
35
+ end
36
+ @changed = true
37
+ end
38
+ def changed?
39
+ if @changed
40
+ @changed = false
41
+ return true
42
+ else
43
+ return false
44
+ end
45
+ end
46
+ def draw
47
+ @background.draw(@x+@xoff, @y+@yoff, Core::GUI_Z + 9, @w/@background.width, @h/@background.height)
48
+ @font.draw(@party.members[@index].name, @x+@xoff+(@w/2)-(@font.text_width(@party.members[@index].name)/2), @y+@yoff+(@h/6), Core::GUI_Z + 10, 1, 1, Gosu::Color::BLACK)
49
+ @left.draw
50
+ @right.draw
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,115 @@
1
+
2
+ module Core::GUI
3
+
4
+ # Small menu available by rightclicking on the map
5
+ class ContextMenu < Element
6
+ def initialize(x, y, obj=nil)
7
+ super(x, y, 128, items(obj) * 24)
8
+ @zoff = 10000
9
+ if @x + @w > 1024
10
+ @x = 1024 - @w
11
+ end
12
+ @buttons = {}
13
+ setup_defaults(obj)
14
+ @buttons.each_value { |but|
15
+ but.zoff = @zoff
16
+ }
17
+ end
18
+ def update
19
+ super
20
+ @buttons.each_value { |but|
21
+ but.update
22
+ }
23
+ end
24
+ def draw
25
+ @buttons.each_value { |but|
26
+ but.draw
27
+ }
28
+ end
29
+
30
+ private
31
+
32
+ def items(obj)
33
+ if obj
34
+ return 3
35
+ else
36
+ return 2
37
+ end
38
+ end
39
+
40
+ def in_window?
41
+ Core.window.state.osd.each_value { |w|
42
+ if Core.inside?(@x, @y, w.x, w.y, w.x+w.w, w.y+w.h)
43
+ return true
44
+ end
45
+ }
46
+ return false
47
+ end
48
+
49
+ def magic_window(p)
50
+ Core.window.state.osd.store(:magic, Core::Game::OSD::Magic.new(@x-320, @y-240, p, p));
51
+ end
52
+
53
+ def setup_defaults(obj)
54
+ if in_window?
55
+ return
56
+ end
57
+ npc = player = false
58
+ if obj
59
+ if obj.class == Core::Game::MapNPC
60
+ label = obj.gamename
61
+ npc = true
62
+ elsif obj.class == Core::Game::Player
63
+ player = true
64
+ label = Core::Trans.menu(:you)
65
+ else
66
+ label = obj.name
67
+ end
68
+ else
69
+ label = Core::Trans.menu(:ground)
70
+ end
71
+
72
+ p = Core.window.state.player
73
+
74
+ @buttons.store(:label, Textfield.new(@x, @y, @w, 24, label, 24))
75
+
76
+ x = @x - Core.window.state.map.xoff
77
+ y = @y - Core.window.state.map.yoff
78
+
79
+ if !player
80
+ if npc
81
+ @buttons.store(:talk_to,
82
+ Button.new(@x, @y+(@buttons.size*24), @w, 24, Core::Trans.menu(:talk_to),
83
+ lambda { puts("STUB: talk_to"); p.find_path_to(x.to_i/32, (y.to_i/32) - (p.y < obj.y ? 1 : -1)); @remove = true }, true, :left))
84
+ else
85
+ @buttons.store(:move,
86
+ Button.new(@x, @y+(@buttons.size*24), @w, 24, Core::Trans.menu(:walk_here),
87
+ lambda { p.find_path_to(x.to_i/32, y.to_i/32); @remove = true }, true, :left))
88
+ if !Core.window.state.map.current.passable?(x, y) or (obj and !obj.through)
89
+ # TODO left/right
90
+ if !obj
91
+ obj = [x, y] # i <3 ruby
92
+ end
93
+ # a* cant find a path to a blocked tile, so shift the position away a bit
94
+ @buttons[:move].proc = lambda { p.find_path_to(x.to_i/32, (y.to_i/32) - (p.y < obj.y ? 1 : -1)); @remove = true }
95
+ # TODO check again if it works, the player *must* move
96
+ end
97
+ end
98
+ end
99
+ if !Core.window.state.osd.has_key?(:magic)
100
+ @buttons.store(:magic,
101
+ Button.new(@x, @y+(@buttons.size*24), @w, 24, Core::Trans.menu(:magic),
102
+ lambda { magic_window(p); @remove = true}, true, :left))
103
+ if npc
104
+ @buttons[:magic].proc = lambda { puts("STUB: othermagic"); @remove = true }
105
+ end
106
+ end
107
+ if $DEBUG and obj
108
+ @buttons.store(:debug_inspect,
109
+ Button.new(@x, @y+(@buttons.size*24), @w, 24, "inspect", lambda { awesome_print(obj); @remove = true }, true, :left))
110
+ end
111
+ end
112
+
113
+ end
114
+
115
+ end
@@ -0,0 +1,18 @@
1
+
2
+ module Core::GUI
3
+
4
+ class Draggable < Element
5
+ def initialize(x, y, w, h, type, sprite)
6
+ super(x, y, w, h)
7
+ @type = type
8
+ @sprite = sprite
9
+ end
10
+ def update(window)
11
+ super
12
+ end
13
+ def draw
14
+ @sprite.img.draw(@x, @y, Core::GUI_Z + 20, @w/@sprite.width, @h/@sprite.height)
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,118 @@
1
+
2
+ module Core::GUI
3
+
4
+ # Allows EH::GUI::Elements to be placed into a 32x32 px grid.
5
+ # Elements can be selected and dragged
6
+ class Grid < Element
7
+
8
+ attr_reader :selected
9
+
10
+ def initialize(x, y, tx, ty, in_classes=[])
11
+ super(x, y, tx*32, ty*32)
12
+ @classes = in_classes
13
+ @grid = Array.new(tx) { Array.new(ty) }
14
+ @bg = Core.sprite("gui/container_background")
15
+ @tile = Core.sprite("gui/tile_32")
16
+ @hl = Core.sprite("gui/tile_32_highlight")
17
+ @selected = nil
18
+ @highlight = nil
19
+ @hovered = nil
20
+ end
21
+
22
+ def update
23
+ if Core.mouse_inside?(@x+@xoff, @y+@yoff, @x+@xoff+@w, @y+@yoff+@h)
24
+ if Core.window.pressed?(Gosu::MsLeft)
25
+ @highlight = mouse_to_tile(Core.window.mouse_x, Core.window.mouse_y)
26
+ @selected = get_at(@highlight.x, @highlight.y)
27
+ else
28
+ @hovered = mouse_to_tile(Core.window.mouse_x, Core.window.mouse_y)
29
+ end
30
+ else
31
+ @hovered = nil
32
+ if Core.window.button_down?(Gosu::MsLeft)
33
+ @selected = nil
34
+ @highlight = nil
35
+ end
36
+ end
37
+ end
38
+
39
+ def draw
40
+ x = @x + @xoff
41
+ y = @y + @yoff
42
+ @bg.draw(x, y, Core::GUI_Z + @zoff, @w/@bg.width.to_f, @h/@bg.height.to_f)
43
+ @grid.each { |col|
44
+ col.each { |tile|
45
+ tile.icon.draw(x, y, Core::GUI_Z + @zoff + 1) if tile
46
+ @tile.draw(x, y, Core::GUI_Z + @zoff + 1)
47
+ y += 32
48
+ }
49
+ x += 32
50
+ y = @y + @yoff
51
+ }
52
+ if @selected and @highlight
53
+ @hl.draw(@x+@xoff+@highlight.x*32, @y+@yoff+@highlight.y*32, Core::GUI_Z + @zoff + 2)
54
+ end
55
+ if @hovered and (!@highlight or !(@hovered.x == @highlight.x and @hovered.y == @highlight.y))
56
+ @hl.draw(@x+@xoff+@hovered.x*32, @y+@yoff+@hovered.y*32, Core::GUI_Z + @zoff + 2)
57
+ end
58
+ end
59
+
60
+ # Adds obj to the grid at the next free position
61
+ # Returns the position where obj was inserted
62
+ def add(obj)
63
+ if @classes.include?(obj.class)
64
+ x = 0
65
+ @grid.each { |col|
66
+ y = 0
67
+ col.each { |tile|
68
+ if tile == nil
69
+ @grid[x][y] = obj
70
+ return [x, y]
71
+ end
72
+ y += 1
73
+ }
74
+ x += 1
75
+ }
76
+ end
77
+ return [0, 0]
78
+ end
79
+
80
+ # Adds obj at the given position, overwriting any other value
81
+ # Calls add() if the given position is invalid
82
+ def add_at(obj, tx, ty)
83
+ if @classes.include?(obj.class)
84
+ @grid[tx][ty] = obj
85
+ end
86
+ rescue NoMethodError
87
+ warn("WARNING: Tried to insert element at invalid index (#{obj}, #{tx}|#{ty})")
88
+ add(obj)
89
+ end
90
+
91
+ def get_at(tx, ty)
92
+ return @grid[tx][ty]
93
+ rescue NoMethodError
94
+ return nil
95
+ end
96
+
97
+ def mouse_to_tile(mx, my)
98
+ x = (mx - @x - @xoff).to_i / 32
99
+ y = (my - @y - @yoff).to_i / 32
100
+ return [x, y]
101
+ end
102
+
103
+ def empty?
104
+ @grid.each { |col|
105
+ col.each { |tile|
106
+ return false if tile
107
+ }
108
+ }
109
+ return true
110
+ end
111
+
112
+ def clear
113
+ @grid = Array.new(@w/32) { Array.new(@h/32) }
114
+ end
115
+
116
+ end
117
+
118
+ end