classless_mud 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +24 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +32 -0
  6. data/Rakefile +5 -0
  7. data/bin/classless_mud +11 -0
  8. data/classless_mud.gemspec +29 -0
  9. data/conf/settings.yml +4 -0
  10. data/lib/classless_mud.rb +72 -0
  11. data/lib/classless_mud/account_builder.rb +81 -0
  12. data/lib/classless_mud/character.rb +39 -0
  13. data/lib/classless_mud/character_sheet.rb +26 -0
  14. data/lib/classless_mud/character_sheet_builder.rb +72 -0
  15. data/lib/classless_mud/client.rb +47 -0
  16. data/lib/classless_mud/colorizer.rb +33 -0
  17. data/lib/classless_mud/commands.rb +32 -0
  18. data/lib/classless_mud/commands/admin/kick.rb +15 -0
  19. data/lib/classless_mud/commands/bad_command.rb +81 -0
  20. data/lib/classless_mud/commands/character.rb +9 -0
  21. data/lib/classless_mud/commands/chat.rb +14 -0
  22. data/lib/classless_mud/commands/commands.rb +31 -0
  23. data/lib/classless_mud/commands/dance.rb +20 -0
  24. data/lib/classless_mud/commands/eat.rb +26 -0
  25. data/lib/classless_mud/commands/get.rb +20 -0
  26. data/lib/classless_mud/commands/inventory.rb +12 -0
  27. data/lib/classless_mud/commands/look.rb +43 -0
  28. data/lib/classless_mud/commands/move.rb +16 -0
  29. data/lib/classless_mud/commands/quit.rb +16 -0
  30. data/lib/classless_mud/commands/say.rb +10 -0
  31. data/lib/classless_mud/commands/score.rb +12 -0
  32. data/lib/classless_mud/commands/whisper.rb +17 -0
  33. data/lib/classless_mud/commands/who.rb +9 -0
  34. data/lib/classless_mud/effect.rb +14 -0
  35. data/lib/classless_mud/exit.rb +15 -0
  36. data/lib/classless_mud/game.rb +40 -0
  37. data/lib/classless_mud/game_master.rb +12 -0
  38. data/lib/classless_mud/input_parser.rb +7 -0
  39. data/lib/classless_mud/item.rb +21 -0
  40. data/lib/classless_mud/npc.rb +12 -0
  41. data/lib/classless_mud/player.rb +57 -0
  42. data/lib/classless_mud/room.rb +60 -0
  43. data/lib/classless_mud/server.rb +18 -0
  44. data/lib/classless_mud/version.rb +3 -0
  45. data/lib/classless_mud/world.rb +26 -0
  46. data/tasks/db.rake +10 -0
  47. metadata +202 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0874ae6052ac4e355731e3e4d05953365deb28e4
4
+ data.tar.gz: a0d5fc8961762100d4bb09251a8f18f19fe7232a
5
+ SHA512:
6
+ metadata.gz: 1f64d2ea4656f81a0444623ef4fa279154affadf1f5abac0b5e7d512c68574fc8fe127e34bada0d07cddfc06df156ed8735a6596892c2ad7a86a708bdcd9d336
7
+ data.tar.gz: 03d3229787bca05bafced0ccc11ae2bed2762979a67b40952c30d0a375ef062bd19c91f7b79242ac382c92da566ec4f9a08093dbd9feea0563a31be9a2e699dd
data/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ tags
24
+ *.sqlite
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in classless_mud.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Patrick McFadden
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,32 @@
1
+ basic_mud
2
+ =========
3
+ =======
4
+ # ClasslessMud
5
+
6
+ TODO: Write a gem description
7
+
8
+ ## Installation
9
+
10
+ Add this line to your application's Gemfile:
11
+
12
+ gem 'classless_mud'
13
+
14
+ And then execute:
15
+
16
+ $ bundle
17
+
18
+ Or install it yourself as:
19
+
20
+ $ gem install classless_mud
21
+
22
+ ## Usage
23
+
24
+ TODO: Write usage instructions here
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it ( https://github.com/[my-github-username]/classless_mud/fork )
29
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
30
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
31
+ 4. Push to the branch (`git push origin my-new-feature`)
32
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rake/testtask'
3
+ require 'minitest/pride'
4
+
5
+ FileList['tasks/**/*.rake'].each { |task| import task }
data/bin/classless_mud ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ git_path = File.join(File.expand_path('../..', __FILE__), '.git')
4
+
5
+ if File.exists?(git_path)
6
+ lib_path = File.expand_path('../../lib', __FILE__)
7
+ $:.unshift(lib_path)
8
+ end
9
+
10
+ require 'classless_mud'
11
+ ClasslessMud.start!
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'classless_mud/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "classless_mud"
8
+ spec.version = ClasslessMud::VERSION
9
+ spec.authors = ["Patrick McFadden"]
10
+ spec.email = ["pemcfadden@gmail.com"]
11
+ spec.summary = %q{Simple Mud Server}
12
+ spec.description = %q{Run your own server}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "pry"
24
+ spec.add_dependency "activesupport"
25
+ spec.add_dependency "eventmachine"
26
+ spec.add_dependency "datamapper"
27
+ spec.add_dependency "dm-sqlite-adapter"
28
+ spec.add_dependency "dm-postgres-adapter"
29
+ end
data/conf/settings.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+
3
+ db:
4
+ name: classless.sqlite
@@ -0,0 +1,72 @@
1
+ require 'socket'
2
+ require 'data_mapper'
3
+ require 'eventmachine'
4
+ require 'active_support'
5
+ require 'active_support/core_ext'
6
+
7
+ require_relative "classless_mud/version"
8
+ require_relative "classless_mud/server"
9
+ require_relative "classless_mud/client"
10
+ require_relative "classless_mud/colorizer"
11
+ require_relative "classless_mud/character_sheet"
12
+ require_relative "classless_mud/item"
13
+ require_relative "classless_mud/character"
14
+ require_relative "classless_mud/player"
15
+ require_relative "classless_mud/npc"
16
+ require_relative "classless_mud/world"
17
+ require_relative "classless_mud/game"
18
+ require_relative "classless_mud/room"
19
+ require_relative "classless_mud/exit"
20
+ require_relative "classless_mud/account_builder"
21
+ require_relative "classless_mud/character_sheet_builder"
22
+ require_relative "classless_mud/game_master"
23
+ require_relative "classless_mud/effect"
24
+ Dir[File.dirname(__FILE__) + '/classless_mud/commands/*.rb'].each { |f| require f }
25
+ Dir[File.dirname(__FILE__) + '/classless_mud/commands/admin/*.rb'].each { |f| require f }
26
+ require_relative "classless_mud/commands"
27
+
28
+ module ClasslessMud
29
+ def self.settings
30
+ @settings ||= YAML.load_file('conf/settings.yml')
31
+ end
32
+
33
+ def self.setup_db!
34
+ DataMapper::Logger.new($stdout, :debug)
35
+ db_name = settings['db']['name']
36
+ if ENV.has_key? 'SNAP_DB_PG_URL_ALT' # snapci
37
+ DataMapper.setup :default, ENV['SNAP_DB_PG_URL_ALT']
38
+ elsif ENV.has_key? 'DATABASE_URL'
39
+ DataMapper.setup :default, ENV['DATABASE_URL']
40
+ else
41
+ puts "Using DB:#{db_name}"
42
+ DataMapper.setup :default, "sqlite3://#{Dir.pwd}/#{db_name}"
43
+ end
44
+ DataMapper.finalize
45
+ end
46
+
47
+ def self.start!
48
+ setup_db!
49
+
50
+ plus_20 = Effect.new description: 'You munch on the bar of chocolate and feel refreshed.', health_modification: 20
51
+ minus_20 = Effect.new description: 'Despite better judgment, you bite into the open bar of chocolate. It is filled with razor blades.', health_modification: -20
52
+ chocolate = Item.new name: "Good Chocolate", short_description: "a pristine bar of chocolate", keywords: "pristine bar chocolate", edible: true
53
+ chocolate.effects << plus_20
54
+ bad_chocolate = Item.new name: "Bad Chocolate", short_description: "a sketchy bar of chocolate", keywords: "sketchy bar chocolate", edible: true
55
+ bad_chocolate.effects << minus_20
56
+ room1 = Room.create! description: "There's a set of glass double doors to the west and an intersection of hallways to the east."
57
+ room2 = Room.create! description: "You are at an intersection of hallways. Glass double doors lay to the north and south. An extension of the hallway lays to the west."
58
+ room1.items << bad_chocolate
59
+ room2.items << chocolate
60
+ room1.exits.create! direction: 'east', target: room2
61
+ room2.exits.create! direction: 'west', target: room1
62
+ goblin = Npc.new name: 'Goblin', health: 90, level: 2
63
+ room1.npcs << goblin
64
+ world = World.new [room1, room2]
65
+ game = Game.new world, settings
66
+
67
+ EventMachine::run {
68
+ puts "Starting server on port 2000"
69
+ ::ClasslessMud::Server.new(2000, game).start
70
+ }
71
+ end
72
+ end
@@ -0,0 +1,81 @@
1
+ module ClasslessMud
2
+ class AccountBuilder
3
+ attr_reader :client, :game, :player
4
+
5
+ def self.create client, game, &on_complete
6
+ builder = self.new(client, game, on_complete)
7
+ builder.login_or_create
8
+ end
9
+
10
+ def initialize client, game, on_complete
11
+ @client = client
12
+ @game = game
13
+ @on_complete = on_complete
14
+ end
15
+
16
+ def login! player
17
+ @player = player
18
+ player.client = client
19
+ player.game = game
20
+ player.puts "Logged in as #{player.name}"
21
+ game.add_player player
22
+ player.save!
23
+ @on_complete.call(player)
24
+ end
25
+
26
+ def login_or_create
27
+ client.puts 'Enter account name: '
28
+ client.on do |account_name|
29
+ player = Player.first(name: account_name)
30
+ if player
31
+ login player
32
+ else
33
+ create account_name
34
+ end
35
+ end
36
+ end
37
+
38
+ def login player
39
+ client.puts "Password:"
40
+ client.on do |password|
41
+ if player.password == password
42
+ login! player
43
+ else
44
+ login_or_create
45
+ end
46
+ end
47
+ end
48
+
49
+ def create account_name
50
+ client.puts "No account by the name #{account_name} exists. Create this account now? [y/N]"
51
+ client.on do |confirm_create|
52
+ if confirm_create == 'y' || confirm_create == 'Y'
53
+ create_password account_name
54
+ else
55
+ login_or_create
56
+ end
57
+ end
58
+ end
59
+
60
+ def create_password account_name
61
+ client.puts "Ok, #{account_name}. What is your password?"
62
+ client.on do |password|
63
+ client.puts "Confirm password:"
64
+ client.on do |confirm_password|
65
+ if password == confirm_password
66
+ player = Player.new(name: account_name, password: password)
67
+ player.client = client
68
+ player.game = game
69
+ ::ClasslessMud::CharacterSheetBuilder.create(player) {
70
+ GameMaster.setup_player player
71
+ login! player
72
+ }
73
+ else
74
+ client.puts "Retrying.."
75
+ create_password account_name
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,39 @@
1
+ module ClasslessMud
2
+ # This module is included in both player
3
+ # and NPC
4
+ module Character
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ property :id, DataMapper::Property::Serial
9
+ property :name, DataMapper::Property::String
10
+ property :health, DataMapper::Property::Integer
11
+ property :level, DataMapper::Property::Integer, default: 1
12
+
13
+ has n, :items
14
+ has 1, :character_sheet, default: CharacterSheet.new
15
+
16
+ belongs_to :room
17
+ end
18
+
19
+ def game= game
20
+ @game = game
21
+ end
22
+
23
+ def affect_health amount
24
+ self.health += amount
25
+ if amount > 0
26
+ self.puts "You are healed for #{amount} health."
27
+ self.puts "You have #{health} health"
28
+ else
29
+ self.puts "You take #{amount.abs} damage."
30
+ self.puts "You have #{health} health"
31
+ die if dead?
32
+ end
33
+ end
34
+
35
+ def dead?
36
+ health <= 0
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,26 @@
1
+ module ClasslessMud
2
+ class CharacterSheet
3
+ include ClasslessMud::Colorizer
4
+ include DataMapper::Resource
5
+
6
+ property :id, Serial
7
+ property :strength, Integer, default: 10
8
+ property :agility, Integer, default: 10
9
+ property :intelligence, Integer, default: 10
10
+ property :race, String, default: 'human'
11
+
12
+ belongs_to :player
13
+
14
+ def display
15
+ player.puts <<EOS
16
+ #{green(player.name)} - #{red(race)}
17
+
18
+ #{green('Strength')}: #{red(strength)}
19
+ #{green('Agility')}: #{red(agility)}
20
+ #{green('Intelligence')}: #{red(intelligence)}
21
+
22
+ #{green('Superpowers')}: #{red('none')}
23
+ EOS
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,72 @@
1
+ module ClasslessMud
2
+ RACES = ['human', 'elven']
3
+ class CharacterSheetBuilder
4
+ attr_reader :player, :character_sheet, :on_complete
5
+
6
+ def self.create player, &on_complete
7
+ builder = self.new player, on_complete
8
+ builder.build
9
+ player.character_sheet
10
+ end
11
+
12
+ def initialize player, on_complete
13
+ @player = player
14
+ @character_sheet = CharacterSheet.new
15
+ @on_complete = on_complete
16
+ end
17
+
18
+ def build
19
+ player.puts <<EOS
20
+ We are going to roll your character. This means that your character
21
+ will be going through a process to determine its stats. Blah blah blah
22
+ instructions instructions.
23
+
24
+ First, you will need to select a race. The races available are:
25
+ #{RACES.join(' ')}
26
+
27
+ Which race are you?
28
+ EOS
29
+ player.on do |race|
30
+ if RACES.include? race
31
+ player.puts "Your character is now #{race}."
32
+ character_sheet.race = race
33
+ roll_stats
34
+ else
35
+ player.puts 'Invalid race.'
36
+ build
37
+ end
38
+ end
39
+ end
40
+
41
+ def roll_stats
42
+ strength_roll = two_d_six_die
43
+ agility_roll = two_d_six_die
44
+ intelligence_roll = two_d_six_die
45
+ player.puts <<EOS
46
+ You rolled
47
+ Strength : #{strength_roll}
48
+ Agility : #{agility_roll}
49
+ Intelligence: #{intelligence_roll}
50
+
51
+ Keep these? [y/N]
52
+ EOS
53
+
54
+ player.on do |confirm_roll|
55
+ if confirm_roll == 'Y' or confirm_roll == 'y'
56
+ character_sheet.strength = strength_roll
57
+ character_sheet.agility = agility_roll
58
+ character_sheet.intelligence = intelligence_roll
59
+ player.character_sheet = character_sheet
60
+ player.save!
61
+ @on_complete.call
62
+ else
63
+ roll_stats
64
+ end
65
+ end
66
+ end
67
+
68
+ def two_d_six_die
69
+ (1..6).to_a.sample + (1..6).to_a.sample
70
+ end
71
+ end
72
+ end