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
+ # FIXME policy = :recalc doesnt work
3
+
4
+ module Core::Game
5
+
6
+ class Goal
7
+ def initialize
8
+ @state = :before
9
+ end
10
+ def setup
11
+ @state = :progress
12
+ end
13
+ def state
14
+ return @state
15
+ end
16
+ def restart
17
+ @state = :before
18
+ end
19
+ def recalc
20
+ restart
21
+ end
22
+ end
23
+
24
+ class MotionGoal < Goal
25
+ attr_reader :dx, :dy, :x, :y
26
+ attr_accessor :state
27
+ def initialize(dx, dy, x, y)
28
+ super()
29
+ @dx, @dy = dx, dy
30
+ @x, @y = x, y
31
+ end
32
+ def recalc
33
+ @state = :recalc
34
+ end
35
+ end
36
+
37
+ class CompositeGoal < Array
38
+ attr_reader :state
39
+ def initialize(policy=:abort)
40
+ super()
41
+ @current = 0
42
+ @policy = policy
43
+ @state = :progress
44
+ end
45
+ def reset
46
+ self.clear
47
+ @current = 0
48
+ @state = :reset
49
+ end
50
+ def start
51
+ @state = :progress
52
+ end
53
+ def current
54
+ return self[@current]
55
+ end
56
+ def update
57
+ if @state == :progress
58
+ awesome_print(self) if !current
59
+ case current.state
60
+ when :before
61
+ if current.class != MotionGoal
62
+ current.setup
63
+ end
64
+ when :progress
65
+ return
66
+ when :failed
67
+ handle_failed
68
+ when :finished
69
+ advance
70
+ end
71
+ end
72
+ end
73
+ def advance
74
+ @current += 1
75
+ if @current == self.size
76
+ @state = :finished
77
+ @current = 0
78
+ end
79
+ end
80
+ private
81
+ def handle_failed
82
+ case @policy
83
+ when :abort
84
+ @state = :failed
85
+ when :retry
86
+ current.restart
87
+ when :recalc
88
+ current.recalc
89
+ end
90
+ end
91
+ end
92
+
93
+ end
@@ -0,0 +1,95 @@
1
+
2
+ require_relative "goal.rb"
3
+ require_relative "bubble.rb"
4
+
5
+ # TODO move goal logic to mapobject
6
+
7
+ module Core::Game
8
+ # Interactive map object
9
+ class MapNPC < MapObject
10
+ attr_accessor :behaviour
11
+ attr_reader :goal, :gamename, :children
12
+ def initialize(x, y, props)
13
+ super(x, y, props)
14
+ @x, @y = x, y
15
+ @behaviour = nil
16
+ @goal = CompositeGoal.new(:retry)
17
+ @speed = 2
18
+ @name = "npc-#{props[:file].downcase}-#{rand(1000)}"
19
+ @gamename = props[:name] ? props[:name] : @name
20
+ @children = []
21
+ @bubble = nil
22
+ end
23
+
24
+ def setup
25
+ super
26
+ @behaviour.on_init if @behaviour
27
+ end
28
+
29
+ # Generates a path from the current position to the given screen coordinates by using A*
30
+ def find_path_to(x, y)
31
+ #puts("from #{@x/32}|#{@y/32} to #{x}|#{y}")
32
+ curr = Core.window.state.map.current.astar(AStar::Node.new(@x/32, @y/32), AStar::Node.new(x, y))
33
+ @goal.reset
34
+ while curr and curr.parent
35
+ @goal.push(MotionGoal.new((curr.x - curr.parent.x) * 32, (curr.y - curr.parent.y) * 32, x, y))
36
+ curr = curr.parent
37
+ end
38
+ @goal.reverse!
39
+ @goal.start
40
+ return @goal
41
+ end
42
+
43
+ def update
44
+ @children.each { |child|
45
+ if child.follow
46
+ child.x = @x + child.xoff
47
+ child.y = @y + child.yoff
48
+ end
49
+ child.update
50
+ }
51
+ @behaviour.on_update if @behaviour
52
+ moved = update_move(Core.window.state.map.current)
53
+ @goal.update if @goal.size > 0
54
+ if @goal.current.class == MotionGoal
55
+ if @goal.current.state == :recalc
56
+ @dx = @dy = 0
57
+ find_path_to(@goal.last.x, @goal.last.y)
58
+ @goal.update
59
+ end
60
+ if @dx == 0 and @dy == 0
61
+ if @goal.current.state == :before
62
+ @dx, @dy = @goal.current.dx, @goal.current.dy
63
+ @goal.current.state = :progress
64
+ elsif @goal.current.state == :progress
65
+ if moved
66
+ @goal.advance
67
+ else
68
+ @goal.current.state = :failed
69
+ end
70
+ end
71
+ end
72
+ end
73
+ if @bubble
74
+ @bubble.update
75
+ @bubble = nil if @bubble.remove?
76
+ end
77
+ end
78
+
79
+ def draw(x, y)
80
+ super
81
+ @bubble.draw(@x+x, @y+y) if @bubble
82
+ @children.each { |child| child.draw(x, y) }
83
+ end
84
+
85
+ # Displays a speech bubble with the given text
86
+ def talk(text)
87
+ @bubble = Bubble.new(text)
88
+ end
89
+
90
+ def destroy_goal
91
+ @goal.reset
92
+ end
93
+
94
+ end
95
+ end
@@ -0,0 +1,73 @@
1
+
2
+ module Core::Game::NPC
3
+
4
+ class Task
5
+ # action: proc to execute
6
+ # wait: stall later tasks until this one finished
7
+ # remove_after: delete task when finished
8
+ def initialize(parameters)
9
+ @array = parameters
10
+ @finished = false
11
+ @current = 0
12
+ end
13
+
14
+ def execute(npc, other=nil)
15
+ if !@array.empty? and !@finished
16
+ send(@array[@current].first, @array[@current], npc, other)
17
+ end
18
+ end
19
+
20
+ def empty?
21
+ return @array.empty?
22
+ end
23
+
24
+ def finished?
25
+ return @finished
26
+ end
27
+
28
+ def reset
29
+ @finished = false
30
+ end
31
+
32
+ def next_subtask(npc, other)
33
+ if @array[@current].include?(:remove)
34
+ @array.delete_at(@current)
35
+ else
36
+ @current += 1
37
+ end
38
+ if @current >= @array.size
39
+ @current = 0
40
+ return
41
+ end
42
+ if !@array[@current-1].include?(:wait)
43
+ execute(npc, other)
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ def particles(parms, npc, other)
50
+ npc.children.push(Core::Game::MapParticle.new(parms[1].x, parms[1].y, parms[2]))
51
+ npc.children.last.xoff = npc.children.last.yoff = 16
52
+ if parms.include?(:follow)
53
+ npc.children.last.follow = true
54
+ end
55
+ next_subtask(npc, other)
56
+ end
57
+
58
+ def path_to(parms, npc, other)
59
+ if npc.goal.state != :progress
60
+ next_subtask(npc, other)
61
+ npc.find_path_to(parms[1].x, parms[1].y)
62
+ npc.goal.start
63
+ end
64
+ end
65
+
66
+ def msg(parms, npc, other)
67
+ Core.window.state.map.message(parms[1])
68
+ next_subtask(npc, other)
69
+ end
70
+
71
+ end
72
+
73
+ end
@@ -0,0 +1,24 @@
1
+
2
+ module Core::Game
3
+ module OSD
4
+
5
+ class Magic < Core::GUI::Window
6
+ def initialize(x, y, caster=Core::Game.party.player, target=nil)
7
+ if x + 640 > 1024
8
+ x = 386
9
+ elsif x < 0
10
+ x = 0
11
+ end
12
+ if y + 480 > 768
13
+ y = 264
14
+ elsif y < 0
15
+ y = 0
16
+ end
17
+ super(x, y, 640, 480, Core::Trans.menu(:magic), true, "osd/magic_bg", true)
18
+ @caster, @target = caster, target
19
+ add(:char, Core::GUI::CharSelector.new(16, 16, @state.party))
20
+ end
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,42 @@
1
+
2
+ require_relative "character.rb"
3
+
4
+ module Core::Game
5
+
6
+ # TODO < Array
7
+ class Party
8
+ attr_accessor :location, :player_index
9
+ def initialize
10
+ @members = []
11
+ @members += Core::Game.characters
12
+ @player_index = 0
13
+ @location = ""
14
+ (Core::Game.items.size * 5).times { @members[0].inventory.add(Core::Game.items.sample) }
15
+ @members[0].equipment.equip(Core::Game.items[1], :rarm, @members[0].inventory)
16
+ end
17
+ def add(char)
18
+ @members.push(char)
19
+ end
20
+ def remove(char)
21
+ @members.delete(char)
22
+ end
23
+ def members
24
+ return @members
25
+ end
26
+ def update
27
+ @members.each { |m|
28
+ m.update
29
+ }
30
+ end
31
+ def player
32
+ return @members[@player_index]
33
+ end
34
+ end
35
+
36
+ # Character states
37
+ NORMAL = 0
38
+ ASLEEP = 1
39
+ DEAD = 2
40
+ UNCONSCIOUS = 3
41
+
42
+ end
@@ -0,0 +1,64 @@
1
+
2
+ module Core::Game
3
+ @skills = []
4
+
5
+ def self.skills
6
+ return @skills
7
+ end
8
+
9
+ def self.skills=(ary)
10
+ @skills = ary
11
+ end
12
+
13
+ def self.find_skill(name)
14
+ @skills.each { |skill|
15
+ if skill.name == name
16
+ return skill
17
+ end
18
+ }
19
+ end
20
+
21
+ class Skill
22
+ attr_reader :name, :desc, :img
23
+ end
24
+
25
+ # skills and their respective levels, instanced once for every character
26
+ class Skills
27
+ def initialize
28
+ @skills = {}
29
+ Core::Game.skills.each { |skill|
30
+ @skills.store(skill, 0)
31
+ }
32
+ end
33
+
34
+ def list
35
+ return @skills
36
+ end
37
+
38
+ def advance(skill)
39
+ @skills.each { |s|
40
+ if skill.class == s.class
41
+ @skills[s] += 1
42
+ end
43
+ }
44
+ end
45
+
46
+ def level_to_s(skill)
47
+ lvl = @skills[skill]
48
+ case lvl
49
+ when 0
50
+ return Core::Trans.menu(:xp_none)
51
+ when 1
52
+ return Core::Trans.menu(:xp_vlittle)
53
+ when 2
54
+ return Core::Trans.menu(:xp_little)
55
+ when 3
56
+ return Core::Trans.menu(:xp_mediocre)
57
+ when 4
58
+ return Core::Trans.menu(:xp_experienced)
59
+ when 5
60
+ return Core::Trans.menu(:xp_vexperienced)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,35 @@
1
+
2
+ require_relative "../def/spells.rb"
3
+
4
+ module Core::Game
5
+
6
+ def self.spells
7
+ return @spells
8
+ end
9
+
10
+ def self.spells=(ary)
11
+ @spells = ary
12
+ end
13
+
14
+ def self.find_spell(name)
15
+ @spells.each { |spell|
16
+ if spell.name == name
17
+ return spell
18
+ end
19
+ }
20
+ return nil
21
+ end
22
+
23
+ class Spell
24
+ attr_reader :name, :icon, :type, :cost
25
+ def cast(caster, target=nil)
26
+ puts("#{caster} casts #{self.name} on #{target}")
27
+ if Core::Game::Spells.respond_to?(self.name)
28
+ Core::Game::Spells.send(self.name)
29
+ else
30
+ puts("ERROR: No ruby definition for spell #{self.name} found")
31
+ end
32
+ end
33
+ end
34
+
35
+ end
@@ -0,0 +1,95 @@
1
+
2
+ #--
3
+ # Main state logic - obviously
4
+
5
+ if Core.config[:opengl]
6
+ require_relative "ext/shader.rb"
7
+ end
8
+
9
+ require_relative "particles.rb"
10
+ require_relative "animation.rb"
11
+
12
+ module Core
13
+
14
+ class GameWindow < Gosu::Window
15
+
16
+ attr_accessor :state, :saved
17
+
18
+ include States
19
+
20
+ def initialize
21
+ super(1024, 768, false)
22
+ self.caption = "Essytas - v#{Core::VERSION}"
23
+ Core.window = self
24
+ Core.particles = Core::Parse.particles
25
+ Core.animations = Core::Parse.animations
26
+ @state = StartMenu.new(self)
27
+ @unpress = []
28
+ @font = Core.font(Core::DEFAULT_FONT, 20)
29
+ @bg = Core.sprite("pixel", true)
30
+ if (Core.config[:contrast] != 1.0 and Core.config[:opengl])
31
+ @contrast = Shader.new(self, "glsl/contrast")
32
+ @contrast["contrast"] = Core.config[:contrast]
33
+ else
34
+ @contrast = nil
35
+ end
36
+ end
37
+
38
+ def update
39
+ @state.update
40
+ unpress
41
+ self.caption = "Essytas - v#{Core::VERSION} - #{Gosu.fps} FPS"
42
+ end
43
+
44
+ def draw
45
+ @state.draw
46
+ if $DEBUG
47
+ @bg.draw(16, 16, 999999, 160, 48, 0x99000000)
48
+ @font.draw("Mouse: #{mouse_x.to_i}|#{mouse_y.to_i}", 32, 32, 999999)
49
+ end
50
+ if @contrast
51
+ @contrast.apply
52
+ end
53
+ end
54
+
55
+ # Advance to the next state
56
+ #
57
+ # Requires an EH::States::State instance
58
+ def advance(state)
59
+ @state.finish
60
+ @state = state
61
+ end
62
+
63
+ # Save current state so we can go back to it later
64
+ #
65
+ # The GameState is saved when switching to a MenuState
66
+ def save
67
+ @saved = @state
68
+ end
69
+
70
+ def load
71
+ @state = @saved
72
+ end
73
+ # Checks if a specific key is pressed
74
+ #
75
+ # Only returns true again if the key was held loose
76
+ def pressed?(key)
77
+ p = button_down?(key)
78
+ if p
79
+ if @unpress.include?(key)
80
+ p = false
81
+ else
82
+ @unpress.push(key)
83
+ end
84
+ end
85
+ return p
86
+ end
87
+ def unpress
88
+ @unpress.each { |key|
89
+ if !button_down?(key)
90
+ @unpress.delete(key)
91
+ end
92
+ }
93
+ end
94
+ end
95
+ end