game_machine 0.0.8

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 (273) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +72 -0
  4. data/Rakefile +38 -0
  5. data/bin/game_machine +79 -0
  6. data/config/cluster.conf +65 -0
  7. data/config/config.example.yml +93 -0
  8. data/config/game_messages.proto +45 -0
  9. data/config/messages.proto +339 -0
  10. data/config/regions.example.yml +9 -0
  11. data/config/standalone.conf +36 -0
  12. data/db/do_not_delete +0 -0
  13. data/game_machine.gemspec +38 -0
  14. data/games/example/boot.rb +6 -0
  15. data/games/example/data/game_data.yml +13 -0
  16. data/games/example/lib/aggressive_npc.rb +176 -0
  17. data/games/example/lib/authentication_handler.rb +69 -0
  18. data/games/example/lib/chatbot.rb +61 -0
  19. data/games/example/lib/combat_controller.rb +145 -0
  20. data/games/example/lib/example_controller.rb +21 -0
  21. data/games/example/lib/game.rb +85 -0
  22. data/games/example/lib/models/attack.rb +9 -0
  23. data/games/example/lib/models/combat_update.rb +11 -0
  24. data/games/example/lib/models/player_command.rb +7 -0
  25. data/games/example/lib/models/user.rb +11 -0
  26. data/games/example/lib/models/vitals.rb +17 -0
  27. data/games/example/lib/npc.rb +111 -0
  28. data/games/example/lib/npc_group.rb +42 -0
  29. data/games/example/lib/npc_movement.rb +116 -0
  30. data/games/example/lib/player_manager.rb +58 -0
  31. data/games/example/lib/player_register.rb +80 -0
  32. data/games/example/lib/tracking_handler.rb +17 -0
  33. data/games/example/lib/zone_manager.rb +57 -0
  34. data/games/preload.rb +8 -0
  35. data/integration_tests/basic_spec.rb +68 -0
  36. data/integration_tests/bot_spec.rb +18 -0
  37. data/integration_tests/chat_spec.rb +45 -0
  38. data/integration_tests/distributed_spec.rb +34 -0
  39. data/integration_tests/entity_tracking_spec.rb +48 -0
  40. data/integration_tests/mono_spec.rb +16 -0
  41. data/integration_tests/objectdb_spec.rb +55 -0
  42. data/integration_tests/tcp_client_spec.rb +71 -0
  43. data/integration_tests/udp_client_spec.rb +61 -0
  44. data/integration_tests/udp_spec.rb +20 -0
  45. data/integration_tests/udt_client_spec.rb +23 -0
  46. data/integration_tests/udt_spec.rb +31 -0
  47. data/java/.gitignore +1 -0
  48. data/java/build.gradle +93 -0
  49. data/java/component.erb +396 -0
  50. data/java/gradle.properties +6 -0
  51. data/java/gradle/wrapper/gradle-wrapper.jar +0 -0
  52. data/java/gradle/wrapper/gradle-wrapper.properties +6 -0
  53. data/java/gradlew +164 -0
  54. data/java/gradlew.bat +90 -0
  55. data/java/local_lib/protostuff-compiler-1.0.7-jarjar.jar +0 -0
  56. data/java/settings.gradle +2 -0
  57. data/java/src/main/java/com/game_machine/core/ActorFactory.java +25 -0
  58. data/java/src/main/java/com/game_machine/core/ActorUtil.java +39 -0
  59. data/java/src/main/java/com/game_machine/core/CommandProxy.java +9 -0
  60. data/java/src/main/java/com/game_machine/core/EntitySerializer.java +66 -0
  61. data/java/src/main/java/com/game_machine/core/EventStreamHandler.java +43 -0
  62. data/java/src/main/java/com/game_machine/core/GameMachineLoader.java +25 -0
  63. data/java/src/main/java/com/game_machine/core/Grid.java +195 -0
  64. data/java/src/main/java/com/game_machine/core/GridValue.java +30 -0
  65. data/java/src/main/java/com/game_machine/core/IActorFactory.java +7 -0
  66. data/java/src/main/java/com/game_machine/core/NetMessage.java +28 -0
  67. data/java/src/main/java/com/game_machine/core/UdpServer.java +97 -0
  68. data/java/src/main/java/com/game_machine/core/UdpServerHandler.java +90 -0
  69. data/java/src/main/resources/game_machine.java.stg +738 -0
  70. data/java/src/main/resources/logback.xml +14 -0
  71. data/java/src/main/resources/logging.properties +3 -0
  72. data/java/src/main/resources/protostuff.properties +7 -0
  73. data/lib/game_machine.rb +85 -0
  74. data/lib/game_machine/actor.rb +7 -0
  75. data/lib/game_machine/actor/base.rb +184 -0
  76. data/lib/game_machine/actor/builder.rb +108 -0
  77. data/lib/game_machine/actor/development.rb +31 -0
  78. data/lib/game_machine/actor/factory.rb +35 -0
  79. data/lib/game_machine/actor/mono_actor.rb +89 -0
  80. data/lib/game_machine/actor/ref.rb +81 -0
  81. data/lib/game_machine/actor/reloadable.rb +98 -0
  82. data/lib/game_machine/actor/system.rb +32 -0
  83. data/lib/game_machine/akka.rb +98 -0
  84. data/lib/game_machine/app_config.rb +49 -0
  85. data/lib/game_machine/application.rb +181 -0
  86. data/lib/game_machine/auth_handlers/base.rb +21 -0
  87. data/lib/game_machine/auth_handlers/public.rb +34 -0
  88. data/lib/game_machine/bot/chat.rb +66 -0
  89. data/lib/game_machine/bot/client.rb +54 -0
  90. data/lib/game_machine/client_manager.rb +204 -0
  91. data/lib/game_machine/clients.rb +4 -0
  92. data/lib/game_machine/clients/client.rb +45 -0
  93. data/lib/game_machine/clients/tcp_client.rb +25 -0
  94. data/lib/game_machine/clients/test_client.rb +151 -0
  95. data/lib/game_machine/clients/udp_client.rb +25 -0
  96. data/lib/game_machine/clients/udt_client.rb +34 -0
  97. data/lib/game_machine/cluster_monitor.rb +115 -0
  98. data/lib/game_machine/commands.rb +23 -0
  99. data/lib/game_machine/commands/base.rb +21 -0
  100. data/lib/game_machine/commands/chat_commands.rb +88 -0
  101. data/lib/game_machine/commands/datastore_commands.rb +60 -0
  102. data/lib/game_machine/commands/grid_commands.rb +35 -0
  103. data/lib/game_machine/commands/message_helper.rb +25 -0
  104. data/lib/game_machine/commands/misc_commands.rb +29 -0
  105. data/lib/game_machine/commands/navigation_commands.rb +24 -0
  106. data/lib/game_machine/commands/player_commands.rb +28 -0
  107. data/lib/game_machine/commands/proxy.rb +16 -0
  108. data/lib/game_machine/console.rb +3 -0
  109. data/lib/game_machine/console/build.rb +74 -0
  110. data/lib/game_machine/console/install.rb +92 -0
  111. data/lib/game_machine/console/server.rb +120 -0
  112. data/lib/game_machine/data_store.rb +52 -0
  113. data/lib/game_machine/data_stores/couchbase.rb +18 -0
  114. data/lib/game_machine/data_stores/mapdb.rb +49 -0
  115. data/lib/game_machine/data_stores/memory.rb +35 -0
  116. data/lib/game_machine/data_stores/redis.rb +46 -0
  117. data/lib/game_machine/endpoints.rb +6 -0
  118. data/lib/game_machine/endpoints/mono_gateway.rb +87 -0
  119. data/lib/game_machine/endpoints/tcp.rb +51 -0
  120. data/lib/game_machine/endpoints/tcp_handler.rb +75 -0
  121. data/lib/game_machine/endpoints/udp.rb +88 -0
  122. data/lib/game_machine/endpoints/udp_incoming.rb +113 -0
  123. data/lib/game_machine/endpoints/udp_outgoing.rb +46 -0
  124. data/lib/game_machine/game_loader.rb +46 -0
  125. data/lib/game_machine/game_systems.rb +14 -0
  126. data/lib/game_machine/game_systems/agents/controller.rb +118 -0
  127. data/lib/game_machine/game_systems/chat.rb +256 -0
  128. data/lib/game_machine/game_systems/chat_manager.rb +108 -0
  129. data/lib/game_machine/game_systems/chat_topic.rb +36 -0
  130. data/lib/game_machine/game_systems/devnull.rb +13 -0
  131. data/lib/game_machine/game_systems/entity_loader.rb +12 -0
  132. data/lib/game_machine/game_systems/entity_tracking.rb +133 -0
  133. data/lib/game_machine/game_systems/local_echo.rb +16 -0
  134. data/lib/game_machine/game_systems/objectdb_proxy.rb +61 -0
  135. data/lib/game_machine/game_systems/private_chat.rb +20 -0
  136. data/lib/game_machine/game_systems/region_manager.rb +91 -0
  137. data/lib/game_machine/game_systems/region_service.rb +94 -0
  138. data/lib/game_machine/game_systems/region_settings.rb +13 -0
  139. data/lib/game_machine/game_systems/remote_echo.rb +14 -0
  140. data/lib/game_machine/game_systems/stress_test.rb +21 -0
  141. data/lib/game_machine/grid.rb +60 -0
  142. data/lib/game_machine/grid_replicator.rb +31 -0
  143. data/lib/game_machine/handlers/authentication.rb +55 -0
  144. data/lib/game_machine/handlers/game.rb +63 -0
  145. data/lib/game_machine/handlers/request.rb +80 -0
  146. data/lib/game_machine/hashring.rb +48 -0
  147. data/lib/game_machine/helpers/game_message.rb +159 -0
  148. data/lib/game_machine/helpers/state_machine.rb +29 -0
  149. data/lib/game_machine/java_lib.rb +51 -0
  150. data/lib/game_machine/logger.rb +39 -0
  151. data/lib/game_machine/message_buffer.rb +58 -0
  152. data/lib/game_machine/message_queue.rb +63 -0
  153. data/lib/game_machine/model.rb +125 -0
  154. data/lib/game_machine/models.rb +3 -0
  155. data/lib/game_machine/models/player_status_update.rb +8 -0
  156. data/lib/game_machine/models/region.rb +9 -0
  157. data/lib/game_machine/mono_server.rb +20 -0
  158. data/lib/game_machine/navigation.rb +4 -0
  159. data/lib/game_machine/navigation/detour.rb +20 -0
  160. data/lib/game_machine/navigation/detour_navmesh.rb +53 -0
  161. data/lib/game_machine/navigation/detour_path.rb +53 -0
  162. data/lib/game_machine/navigation/path.rb +31 -0
  163. data/lib/game_machine/object_db.rb +67 -0
  164. data/lib/game_machine/protobuf.rb +6 -0
  165. data/lib/game_machine/protobuf/game_messages.rb +24 -0
  166. data/lib/game_machine/protobuf/generate.rb +113 -0
  167. data/lib/game_machine/protobuf_extensions/entity_helper.rb +11 -0
  168. data/lib/game_machine/reloadable_monitor.rb +26 -0
  169. data/lib/game_machine/restart_watcher.rb +17 -0
  170. data/lib/game_machine/ruby_extensions/nilclass.rb +10 -0
  171. data/lib/game_machine/ruby_extensions/string.rb +17 -0
  172. data/lib/game_machine/scheduler.rb +23 -0
  173. data/lib/game_machine/securerandom.rb +6 -0
  174. data/lib/game_machine/settings.rb +11 -0
  175. data/lib/game_machine/system_monitor.rb +19 -0
  176. data/lib/game_machine/system_stats.rb +24 -0
  177. data/lib/game_machine/uniqueid.rb +23 -0
  178. data/lib/game_machine/vector.rb +95 -0
  179. data/lib/game_machine/version.rb +3 -0
  180. data/lib/game_machine/write_behind_cache.rb +164 -0
  181. data/mono/bin/csharp/common.xslt +109 -0
  182. data/mono/bin/csharp/csharp.xslt +628 -0
  183. data/mono/bin/csharp/descriptor.proto +533 -0
  184. data/mono/bin/csharp/protobuf-net.dll +0 -0
  185. data/mono/bin/csharp/protobuf-net.pdb +0 -0
  186. data/mono/bin/csharp/protobuf-net.xml +2879 -0
  187. data/mono/bin/csharp/protogen.exe.config +3 -0
  188. data/mono/bin/csharp/protogen.pdb +0 -0
  189. data/mono/bin/csharp/protogen_csharp.exe +0 -0
  190. data/mono/bin/csharp/vb.xslt +745 -0
  191. data/mono/bin/csharp/xml.xslt +26 -0
  192. data/mono/server/Makefile +6 -0
  193. data/mono/server/NLog.config +12 -0
  194. data/mono/server/NLog.dll +0 -0
  195. data/mono/server/actor.cs +37 -0
  196. data/mono/server/build.bat +3 -0
  197. data/mono/server/cscompmgd.dll +0 -0
  198. data/mono/server/iactor.cs +11 -0
  199. data/mono/server/message_router.cs +67 -0
  200. data/mono/server/message_util.cs +29 -0
  201. data/mono/server/messages.cs +1888 -0
  202. data/mono/server/protobuf-net.dll +0 -0
  203. data/mono/server/proxy_client.cs +73 -0
  204. data/mono/server/proxy_server.cs +30 -0
  205. data/mono/server/test_actor.cs +33 -0
  206. data/pathfinding/bin/premake4 +0 -0
  207. data/pathfinding/include/mesh_loader.h +28 -0
  208. data/pathfinding/include/pathfind.h +167 -0
  209. data/pathfinding/main.cpp +39 -0
  210. data/pathfinding/mesh_loader.cpp +108 -0
  211. data/pathfinding/pathfind.cpp +174 -0
  212. data/pathfinding/pathfinder.cs +66 -0
  213. data/pathfinding/premake4.lua +109 -0
  214. data/script/server.sh +109 -0
  215. data/script/watch.sh +11 -0
  216. data/spec/actor/actor_spec.rb +73 -0
  217. data/spec/actor/builder_spec.rb +56 -0
  218. data/spec/actor/ref_spec.rb +83 -0
  219. data/spec/application_spec.rb +7 -0
  220. data/spec/client_manager_spec.rb +171 -0
  221. data/spec/commands/chat_commands_spec.rb +38 -0
  222. data/spec/commands/datastore_commands_spec.rb +91 -0
  223. data/spec/commands/grid_commands_spec.rb +37 -0
  224. data/spec/commands/navigation_commands_spec.rb +51 -0
  225. data/spec/commands/player_commands_spec.rb +48 -0
  226. data/spec/commands_spec.rb +38 -0
  227. data/spec/data_stores/mapdb_spec.rb +46 -0
  228. data/spec/data_stores/redis_spec.rb +44 -0
  229. data/spec/game_systems/agents/controller_spec.rb +84 -0
  230. data/spec/game_systems/agents/test_agent.rb +10 -0
  231. data/spec/game_systems/agents/test_agent_config.rb +29 -0
  232. data/spec/game_systems/chat_manager_spec.rb +66 -0
  233. data/spec/game_systems/chat_spec.rb +187 -0
  234. data/spec/game_systems/entity_tracking_spec.rb +64 -0
  235. data/spec/game_systems/region_manager_spec.rb +138 -0
  236. data/spec/grid_spec.rb +37 -0
  237. data/spec/handlers/authentication_spec.rb +36 -0
  238. data/spec/handlers/game_spec.rb +49 -0
  239. data/spec/handlers/request_spec.rb +65 -0
  240. data/spec/hashring_spec.rb +59 -0
  241. data/spec/integration_helper.rb +120 -0
  242. data/spec/java_grid_spec.rb +89 -0
  243. data/spec/message_buffer_spec.rb +67 -0
  244. data/spec/message_expectations.rb +47 -0
  245. data/spec/message_queue_spec.rb +23 -0
  246. data/spec/misc_spec.rb +71 -0
  247. data/spec/model_spec.rb +103 -0
  248. data/spec/mono_spec.rb +36 -0
  249. data/spec/mono_test.rb +18 -0
  250. data/spec/navigation/detour_navmesh_spec.rb +34 -0
  251. data/spec/navigation/detour_path_spec.rb +25 -0
  252. data/spec/spec_helper.rb +40 -0
  253. data/spec/udp_server_spec.rb +10 -0
  254. data/spec/write_behind_cache_spec.rb +109 -0
  255. data/web/app.rb +131 -0
  256. data/web/config/trinidad.yml +4 -0
  257. data/web/controllers/auth_controller.rb +19 -0
  258. data/web/controllers/base_controller.rb +16 -0
  259. data/web/controllers/index_controller.rb +7 -0
  260. data/web/controllers/log_controller.rb +47 -0
  261. data/web/controllers/messages_controller.rb +59 -0
  262. data/web/controllers/player_register_controller.rb +15 -0
  263. data/web/log/development.log +1339 -0
  264. data/web/tmp/restart.txt +0 -0
  265. data/web/views/game_messages.haml +45 -0
  266. data/web/views/index.haml +6 -0
  267. data/web/views/layout.haml +41 -0
  268. data/web/views/logs.haml +32 -0
  269. data/web/views/player_register.haml +22 -0
  270. data/web/views/player_registered.haml +2 -0
  271. data/web/views/register_layout.haml +22 -0
  272. data/web/views/restart.haml +35 -0
  273. metadata +576 -0
@@ -0,0 +1,21 @@
1
+ module Example
2
+ class ExampleController < GameMachine::Actor::Base
3
+ include GameMachine
4
+ include GameMachine::Commands
5
+ include GameMachine::Actor::Development
6
+
7
+ # This is our initializer method. It is called once on actor start.
8
+ #
9
+ def post_init(*args)
10
+ # Just because
11
+ GameMachine.logger.info "#{self.class.name} post_init called"
12
+ end
13
+
14
+ def on_receive(message)
15
+
16
+ # Send message back to player who sent it
17
+ commands.player.send_message(message.to_entity,message.player.id)
18
+ GameMachine.logger.info("message sent to #{message.player.id}")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,85 @@
1
+ require 'digest/md5'
2
+ require_relative 'models/vitals'
3
+ require_relative 'models/attack'
4
+ require_relative 'models/user'
5
+ require_relative 'models/combat_update'
6
+ require_relative 'models/player_command'
7
+ require_relative 'authentication_handler'
8
+ require_relative 'tracking_handler'
9
+ require_relative 'player_register'
10
+ require_relative 'example_controller'
11
+ require_relative 'chatbot'
12
+ require_relative 'combat_controller'
13
+ require_relative 'npc_movement'
14
+ require_relative 'npc'
15
+ require_relative 'aggressive_npc'
16
+ require_relative 'npc_group'
17
+ require_relative 'player_manager'
18
+ require_relative 'zone_manager'
19
+
20
+ module Example
21
+ class Game
22
+ include GameMachine::Commands
23
+
24
+ attr_reader :game_root, :game_data
25
+
26
+ def self.npcs
27
+ if @npcs
28
+ @npcs
29
+ else
30
+ @npcs = java.util.concurrent.ConcurrentHashMap.new
31
+ end
32
+ end
33
+
34
+ def initialize(game_root)
35
+ @game_root = game_root
36
+ @game_data = load_game_data
37
+ end
38
+
39
+ def start
40
+
41
+ # Start your custom actors here. In this example we show a simple method
42
+ # for loading some static data and passing it to the actor.
43
+
44
+ # Builder.new takes the classname of the actor,and any number of other arguments.
45
+ # These extra arguments will be sent to the actor's post_init method when
46
+ # it starts
47
+ GameMachine::Actor::Builder.new(ExampleController).start
48
+
49
+ # Creating the actor with a specific name. Useful if you want to start up
50
+ # multiple actors all using the same actor class.
51
+ # GameMachine::Actor::Builder.new(ExampleController).with_name('my_example_actor').start
52
+
53
+
54
+ # Using a router.
55
+ # This starts up 10 copies of the actor with router in front of them that
56
+ # distributes load using round robin
57
+ # GameMachine::Actor::Builder.new(ExampleController).
58
+ # with_router(JavaLib::RoundRobinRouter,10)start
59
+
60
+ # Using a distributed ring of actors.
61
+ # This creates a dstributed actor ring that will hash messages to actors
62
+ # using the id passed to ExampleActor.find_distributed(id).
63
+ # GameMachine::Actor::Builder.new(ExampleController).
64
+ # distributed(10).start
65
+
66
+ # Start our chatbot. No good reason for this, just shows off some more tech
67
+ GameMachine::Actor::Builder.new(Chatbot,'global').start
68
+
69
+ # Misc player management stuff is taken care of by the player manager.
70
+ # This is game specific.
71
+ GameMachine::Actor::Builder.new(PlayerManager).start
72
+
73
+ # This actor is responsible for starting up everything associated with a zone.
74
+ # It waits until the region manager tells it that it is responsible for a
75
+ # particular zone.
76
+ GameMachine::Actor::Builder.new(ZoneManager,game_data).start
77
+ end
78
+
79
+ def load_game_data
80
+ filename = File.join(game_root,'/data/game_data.yml')
81
+ YAML.load(File.read(filename))
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,9 @@
1
+ module Example
2
+ module Models
3
+ class Attack < GameMachine::Model
4
+ attribute :target, String
5
+ attribute :attacker, String
6
+ attribute :combat_ability, String
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ module Example
2
+ module Models
3
+ class CombatUpdate < GameMachine::Model
4
+ attribute :target, String
5
+ attribute :attacker, String
6
+ attribute :combat_ability, String
7
+ attribute :damage, Integer
8
+ attribute :target_health, Integer
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,7 @@
1
+ module Example
2
+ module Models
3
+ class PlayerCommand < GameMachine::Model
4
+ attribute :command, String
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module Example
2
+ module Models
3
+ class User < GameMachine::Model
4
+ attribute :id, String
5
+ attribute :password, String
6
+ attribute :authtoken, String
7
+
8
+ set_id_scope :user
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module Example
2
+ module Models
3
+ class Vitals < GameMachine::Model
4
+ attribute :max_health, Integer
5
+ attribute :health, Integer
6
+ attribute :id, String
7
+ attribute :defense_skill, Integer
8
+ attribute :offense_skill, Integer
9
+ attribute :entity_type, String
10
+ attribute :x, Integer
11
+ attribute :y, Integer
12
+ attribute :zone, String
13
+
14
+ set_id_scope :vitals
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,111 @@
1
+ module Example
2
+ class Npc
3
+ include GameMachine::Commands
4
+ include Models
5
+
6
+ attr_accessor :position, :id, :players, :movement, :player_index, :home, :vitals, :dead
7
+
8
+ def initialize(id)
9
+ @dead = false
10
+ @id = id
11
+ @position = GameMachine::Vector.new
12
+ @last_ai = Time.now.to_i
13
+ @player_check_counter = 0
14
+ @players = {}
15
+ set_spawn_point
16
+ @movement = NpcMovement.new(id,position)
17
+ movement.speed_scale = 2
18
+ @home = GameMachine::Vector.from(position)
19
+ @target = GameMachine::Vector.new
20
+ get_players
21
+ #GameMachine.logger.info "Npc #{id} created"
22
+ initialize_vitals
23
+ post_init
24
+ end
25
+
26
+ def initialize_vitals
27
+ if @vitals = Vitals.find(id,5000)
28
+
29
+ # Put dead npc's back to full health
30
+ if @vitals.health < @vitals.max_health
31
+ @vitals.health = @vitals.max_health
32
+ @vitals.save
33
+ end
34
+ else
35
+ @vitals = Vitals.new(
36
+ :id => id,
37
+ :max_health => 50,
38
+ :health => 50,
39
+ :entity_type => 'npc'
40
+ )
41
+ @vitals.save
42
+ end
43
+ end
44
+
45
+ def post_init
46
+ end
47
+
48
+ def update_combat(combat_update)
49
+ if combat_update.target == id && combat_update.target_health == 0
50
+ @dead = true
51
+ GameMachine.logger.info "Npc #{id} died!"
52
+ commands.grid.remove(id)
53
+ end
54
+ end
55
+
56
+ def set_spawn_point
57
+ position.x = rand(1000) + 1
58
+ position.y = rand(1000) + 1
59
+ end
60
+
61
+ def has_players?
62
+ players.size > 0
63
+ end
64
+
65
+ def sorted_players
66
+ players.values.sort do |a,b|
67
+ position.distance(a[:vector]) <=> position.distance(b[:vector])
68
+ end
69
+ end
70
+
71
+ def get_players
72
+ commands.grid.neighbors(position.x,position.y).each do |player|
73
+ if @players[player.id]
74
+ @players[player.id][:vector].x = player.x
75
+ @players[player.id][:vector].y = player.y
76
+ @players[player.id][:vector].z = 0
77
+ else
78
+ @players[player.id] = {:id => player.id, :vector => GameMachine::Vector.from(player)}
79
+ end
80
+ end
81
+ end
82
+
83
+ def check_players
84
+ get_players
85
+ end
86
+
87
+ def run_ai
88
+ pick_random_target
89
+ end
90
+
91
+ def pick_random_target
92
+ @target.x = position.x + rand(-30..30)
93
+ @target.y = position.y + rand(-30..30)
94
+ movement.set_target(@target)
95
+ end
96
+
97
+ def update
98
+ return if dead
99
+ if movement.has_target
100
+ if movement.reached_target
101
+ run_ai
102
+ end
103
+ else
104
+ run_ai
105
+ end
106
+
107
+ movement.update
108
+ end
109
+
110
+ end
111
+ end
@@ -0,0 +1,42 @@
1
+ module Example
2
+ class NpcGroup < GameMachine::Actor::Base
3
+ include GameMachine::Commands
4
+
5
+ attr :npcs
6
+ def post_init(*args)
7
+ @npcs = {}
8
+ group = args.first
9
+ klass = args.last
10
+ group.each do |npc_id|
11
+ npcs[npc_id] = klass.new(npc_id)
12
+ end
13
+
14
+ # schedule_once was not yet in the base actor, needs to be abstracted
15
+ # out to there
16
+ unit = java.util.concurrent.TimeUnit::MILLISECONDS
17
+ @duration = GameMachine::JavaLib::Duration.create(30, unit)
18
+ @scheduler = get_context.system.scheduler
19
+ @dispatcher = get_context.system.dispatcher
20
+ schedule_once('update')
21
+ end
22
+
23
+ def schedule_once(message)
24
+ @scheduler.schedule_once(@duration, get_self, message, @dispatcher, nil)
25
+ end
26
+
27
+ def on_receive(message)
28
+ if message == 'update'
29
+ npcs.each_value do |npc|
30
+ npc.update
31
+ end
32
+ schedule_once('update')
33
+ elsif message.is_a?(Models::CombatUpdate)
34
+ if npc = npcs.fetch(message.target,nil)
35
+ npc.update_combat(message)
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,116 @@
1
+ module Example
2
+ class NpcMovement
3
+ include GameMachine::Commands
4
+
5
+ attr_accessor :updates_between_move
6
+ attr_reader :current_target, :position, :updates_for_move,
7
+ :position_changed, :has_target, :last_move, :id,
8
+ :reached_target, :current_distance_to_target
9
+ attr_accessor :speed_scale
10
+ def initialize(id,position)
11
+ @id = id
12
+ @position = position
13
+ @last_move = Time.now.to_f
14
+ @position_changed = false
15
+ @has_target = false
16
+ @reached_target = false
17
+ @updates_for_move = 0
18
+ @updates_between_move = 15
19
+ @speed_scale = 4
20
+ @current_distance_to_target = 0
21
+ commands.grid.track(id,position.x,position.y,position.z)
22
+ end
23
+
24
+ def update
25
+ @position_changed = false
26
+
27
+ if has_target && !reached_target
28
+ if @updates_for_move >= updates_between_move
29
+ move
30
+ @updates_for_move = 0
31
+ end
32
+ else
33
+ return
34
+ end
35
+
36
+ # Only update position if we moved
37
+ if position_changed
38
+ commands.grid.track(id,position.x,position.y,0)
39
+ @position_changed = false
40
+ end
41
+
42
+ @updates_for_move += 1
43
+ end
44
+
45
+ def distance_to_target
46
+ current_distance_to_target
47
+ end
48
+
49
+ def set_target(target)
50
+ update_target(target)
51
+ @last_move = Time.now.to_f
52
+ @has_target = true
53
+ @reached_target = false
54
+ end
55
+
56
+ def update_target(target)
57
+ @current_distance_to_target = position.distance(target)
58
+ @current_target = target
59
+
60
+ if current_distance_to_target == 0
61
+ @reached_target = true
62
+ return
63
+ end
64
+
65
+ current_distance_to_target
66
+ end
67
+
68
+ def drop_target
69
+ @current_target = nil
70
+ @has_target = false
71
+ @reached_target = false
72
+ @current_distance_to_target = 0
73
+ end
74
+
75
+ def set_reached_target
76
+ position.x = current_target.x
77
+ position.y = current_target.y
78
+ @reached_target = true
79
+ end
80
+
81
+ def move
82
+ @current_distance_to_target = position.distance(current_target)
83
+ if current_distance_to_target == 0
84
+ set_reached_target
85
+ return
86
+ end
87
+
88
+ delta_time = Time.now.to_f - last_move.to_f
89
+
90
+ # Save object creation by not using methods that return new vector
91
+ x = current_target.x - position.x
92
+ y = current_target.y - position.y
93
+ dirx = GameMachine::Vector.norm(x)
94
+ diry = GameMachine::Vector.norm(y)
95
+ position.x += dirx * speed_scale * delta_time
96
+ position.y += diry * speed_scale * delta_time
97
+
98
+ #direction = (current_target - position).normalize
99
+ #position.x += direction.x * speed_scale * delta_time
100
+ #position.y += direction.y * speed_scale * delta_time
101
+
102
+ # Not really what we want
103
+ #position.interpolate(current_target, speed_scale * delta_time)
104
+
105
+ if position.distance(current_target) > current_distance_to_target
106
+ set_reached_target
107
+ end
108
+
109
+ #if id.match(/viking_499/) || id.match(/worm/)
110
+ # puts "#{id}: old_distance :#{current_distance_to_target} new_distance: #{position.distance(current_target)} time: #{delta_time}"
111
+ #end
112
+ @last_move = Time.now.to_f
113
+ @position_changed = true
114
+ end
115
+ end
116
+ end