diff --git a/.gitignore b/.gitignore index 2efefbd5a9a369f2438949bd60ea5684d4d87ce1..730fd6c006bb2408a727401b9abf5a45f228dfca 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.#* logs storage objects/reactions @@ -7,3 +8,5 @@ results.html .idea/ nbproject/ lib/aethyr/extensions/reactions/ +.bundle/ +vendor/ diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000000000000000000000000000000000000..06f0a5753d560ea999b0ed9304ebc17a7f64bb90 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,22 @@ +FROM archlinux/base + +RUN pacman -Sy --noconfirm +RUN pacman -S --noconfirm ruby git +RUN gem install --no-user-install bundler + +# throw errors if Gemfile has been modified since Gemfile.lock +RUN bundle config --global frozen 1 + +WORKDIR /usr/src/app + +COPY . . +RUN rm -rf storage && rm -rf lib/aethyr/extensions/reactions + +RUN bundle install +#RUN bundle update --bundler + +#cleanup +RUN rm -rf .git + +EXPOSE 8888 +CMD ["bundle", "exec", "./bin/aethyr", "run"] diff --git a/Gemfile.lock b/Gemfile.lock index dafce496b2e7d4c1660fb44d27ff9bf342dc7938..eb65157c8cf59d13b93e5ad75a84c6b46cc95e0d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -12,18 +12,18 @@ PATH GEM remote: https://rubygems.org/ specs: - aruba (0.14.6) - childprocess (>= 0.6.3, < 0.10.0) + aruba (0.14.14) + childprocess (>= 0.6.3, < 4.0.0) contracts (~> 0.9) cucumber (>= 1.3.19) - ffi (~> 1.9.10) + ffi (~> 1.9) rspec-expectations (>= 2.99) - thor (~> 0.19) - backports (3.11.4) - builder (3.2.3) - childprocess (0.9.0) - ffi (~> 1.0, >= 1.0.11) - concurrent-ruby (1.0.5) + thor (>= 0.19, < 2.0) + ast (2.4.0) + backports (3.17.1) + builder (3.2.4) + childprocess (3.0.0) + concurrent-ruby (1.1.6) contracts (0.16.0) cucumber (3.1.2) builder (>= 2.1.2) @@ -34,32 +34,48 @@ GEM gherkin (~> 5.1.0) multi_json (>= 1.7.5, < 2.0) multi_test (>= 0.1.2) - cucumber-core (3.2.0) + cucumber-core (3.2.1) backports (>= 3.8.0) cucumber-tag_expressions (~> 1.1.0) - gherkin (>= 5.0.0) + gherkin (~> 5.0) cucumber-expressions (6.0.1) cucumber-tag_expressions (1.1.1) cucumber-wire (0.0.1) diff-lcs (1.3) eventmachine (1.2.7) - ffi (1.9.25) + ffi (1.12.2) gherkin (5.1.0) + jaro_winkler (1.5.4) json (1.8.6) methadone (1.9.5) bundler - multi_json (1.13.1) + multi_json (1.14.1) multi_test (0.1.2) ncursesw (1.4.10) + parallel (1.19.1) + parser (2.7.1.1) + ast (~> 2.4.0) + rainbow (3.0.0) rake (11.3.0) rdoc (4.3.0) require_all (2.0.0) - rspec-expectations (3.8.1) + rexml (3.2.4) + rspec-expectations (3.9.1) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.8.0) - rspec-support (3.8.0) - thor (0.20.0) - wisper (2.0.0) + rspec-support (~> 3.9.0) + rspec-support (3.9.2) + rubocop (0.82.0) + jaro_winkler (~> 1.5.1) + parallel (~> 1.10) + parser (>= 2.7.0.1) + rainbow (>= 2.2.2, < 4.0) + rexml + ruby-progressbar (~> 1.7) + unicode-display_width (>= 1.4.0, < 2.0) + ruby-progressbar (1.10.1) + thor (1.0.1) + unicode-display_width (1.7.0) + wisper (2.0.1) PLATFORMS ruby @@ -67,10 +83,11 @@ PLATFORMS DEPENDENCIES aethyr! aruba (~> 0.14) - bundler (~> 1.7) + bundler (~> 2.0) json (~> 1.8) rake (~> 11.3) rdoc (~> 4.2) + rubocop (~> 0.82) BUNDLED WITH - 1.16.1 + 2.1.4 diff --git a/README.rdoc b/README.rdoc index ecdba1827e34afdd9c95baae6d4c26501d7061fa..5575c37760b0e4e734108a6c3cba14e43171910f 100644 --- a/README.rdoc +++ b/README.rdoc @@ -26,7 +26,18 @@ Just run the application with the following command. == From source - bundle install + bundle install --path vendor/bundle bundle exec rake bundle exec ./bin/aethyr_setup - bundle exec ./bin/aethyr run \ No newline at end of file + bundle exec ./bin/aethyr run + +== Using Docker + + docker run --rm -i -v "$PWD/storage:/usr/src/app/storage" -v "$PWD/conf:/usr/src/app/conf" -v "$PWD/lib/aethyr/extensions/reactions:/usr/src/app/lib/aethyr/extensions/reactions" -t syncleus/aethyr:git bundle exec ./bin/aethyr_setup + docker run -p 8888:8888 -v "$PWD/storage:/usr/src/app/storage" -v "$PWD/conf:/usr/src/app/conf" -v "$PWD/lib/aethyr/extensions/reactions:/usr/src/app/lib/aethyr/extensions/reactions" --rm syncleus/aethyr:git + +== Building image + + docker build -t syncleus/aethyr:git . + docker login # if not logged in + docker push syncleus/aethyr:git diff --git a/aethyr.gemspec b/aethyr.gemspec index e57988d9dc368fbc594e24ada1c4a079458b8a7b..7dcbf938e94edb111acc90199bfe47a21aa509b6 100644 --- a/aethyr.gemspec +++ b/aethyr.gemspec @@ -33,11 +33,12 @@ Gem::Specification.new do |spec| spec.add_dependency 'methadone', '~> 1.9' spec.add_dependency 'eventmachine', '~> 1.2' spec.add_dependency 'require_all', '~> 2.0' - spec.add_dependency 'concurrent-ruby', '~> 1.0' - spec.add_dependency 'ncursesw', '~> 1.4' - spec.add_development_dependency 'bundler', '~> 1.7' + spec.add_dependency 'concurrent-ruby', '~> 1.0' + spec.add_dependency 'ncursesw', '~> 1.4' + spec.add_development_dependency 'bundler', '~> 2.0' spec.add_development_dependency 'json', '~> 1.8' spec.add_development_dependency 'rake', '~> 11.3' spec.add_development_dependency 'rdoc', '~> 4.2' spec.add_development_dependency 'aruba', '~> 0.14' + spec.add_development_dependency 'rubocop', '~> 0.82' end diff --git a/bin/aethyr_setup b/bin/aethyr_setup index 45871a74b30f80fe7169d89bfd3d9fd9898a7a4b..f01417041d3522211cf508565230f3cd5aaaa1ec 100755 --- a/bin/aethyr_setup +++ b/bin/aethyr_setup @@ -87,8 +87,8 @@ def reset_storage end puts "Erasing storage..." - FileUtils.rm_rf "storage/", :secure => true - FileUtils.mkdir "storage" + FileUtils.mkdir "storage" if not File.exist? "storage/" + FileUtils.rm_rf Dir.glob("storage/*"), :secure => true FileUtils.mkdir "storage/boards" FileUtils.mkdir "storage/admin" FileUtils.mkdir "logs" if not File.exist? "logs/" @@ -131,7 +131,7 @@ def reset_storage puts "Adding helper reactions..." - FileUtils.mkdir "lib/aethyr/extensions/reactions" if not File.exist? "lib/aethyr/objects/reactions/" + FileUtils.mkdir "lib/aethyr/extensions/reactions" if not File.exist? "lib/aethyr/extensions/reactions/" File.open "lib/aethyr/extensions/reactions/helper.rx", "w" do |f| f.write helper_reactions diff --git a/conf/config.yaml b/conf/config.yaml index 82a58bb7721eff875619863efff2ed7e08125e2d..af129658ac2bfb40d3b0178a154c0fe8ddd875b8 100644 --- a/conf/config.yaml +++ b/conf/config.yaml @@ -9,7 +9,7 @@ :restart_delay: 10 :address: 0.0.0.0 :intro_file: intro.txt -:start_room: fcaa64fd-0271-5d23-50d1-62e3bab8aa00 +:start_room: 46cf2781-1e5e-d6e4-18e6-ea72ea437aa9 :restart_limit: 15 :mccp: false :mssp: false diff --git a/intro.txt b/intro.txt index df9372306f4625003534a07a5e8339e3c7e4ef92..6ce6b13ff7e9a025e866722300e0ca25ef6b934c 100644 --- a/intro.txt +++ b/intro.txt @@ -1,44 +1,59 @@ - /\ - || - || - || - || ~-----~ - || /===-- -- - || ;' /==~- -- - - || (/ (' /=---- ~~_ - || ' / ;' /=---- \ - ' ~==_=~ '(' ~-~~ ~~~~ ~~~- - \\ (c_\_ .i. /~-- ~~~-- -~ ( - `\ (}| / / : \ / ~~------~ ~~\ ( - \ ' ||/ \ |===| /~/ ~~~ \ \( - ``~\ ~~\ )~.~_ >._.< _~-~ |`_ ~~-~ )\ - '-~ { / ) \___/ ( \ |` ` _ ~~ ' - \ -~\ -<__/ - - L~ -; \\ \ _ _/ - `` ~~=\ { : }\ ,\ || _ :( - \ ~~=\__ \ _/ \_ / ) } _// ( `|' - `` , ~\--~=\ \ / / _/ / ' ( ' - \` } ~ ~~ -~=\ _~_ / \ / \ )^ ( // :_ / ' - | , _~-' '~~__-_ / - |/ \ ( - \ ,_--_ _/ \_'---', -~ . \ - )/ /\ / /\ ,~, \__ _} \_ "~_ - , { ( _ )'} ~ - \_ ~\ (-:-) "\ ~ - /'' '' )~ \~_ ~\ )-> \ :| _, " - (\ _/)''} | \~_ ~ /~( | :) / } - <`` >;,,/ )= \~__ {{{ ' \ =( , , ; - {o_o }_/ |v '~__ _ )-v| " : ," - {/"\_) {_/' \~__ ~\_ \\_} ' { /~\ - ,/! '_/ '~__ _-~ \_' : ' ," ~ - (''` /,'~___~ | / ," \ ~' - '/, ) (-) '~____~"; ," , } - /,') / \ / ,~-" '~' - ( ''/ / ( ' / / '~' - ~ ~ ,, /) , (/( \) ( -) /~' - ( ~~ )` ~} ' \)' _/ / ~' - { |) /`,--.( }' ' ( / /~' -(` ~ ( c|~~| `} ) '/:\ ,' - ~ )/``) )) '|), (/ | \) -sjm - (` (-~(( `~`' ) ' (/ ' - `~' )'`') ' - ` `` - - Welcome to the Aethyr \ No newline at end of file + <earthhigh>/\</earthhigh> + <earthhigh>||</earthhigh> + <earthhigh>||</earthhigh> + <earthhigh>||</earthhigh> + <earthhigh>||</earthhigh> <water>~---~</water> + <earthhigh>||</earthhigh> <water>/===- -</water> + <earthhigh>||</earthhigh> <identifier>;'</identifier> <water>/==~- - -</water> + <earthhigh>||</earthhigh> <identifier>(/ ('</identifier> <water>/=---- ~_</water> + <earthhigh>||</earthhigh> <identifier>' / ;'</identifier> <water>/=---- \</water> + <water>' <airlow>~==_=~</airlow> <identifier>'('</identifier> ~-~~ ~~~~ ~~-</water> + <water>\\ <regular>(c<airlow>_</airlow>\_ .i.</regular> /~-- ~~~-- -~ (</water> + <water>`\ <regular>(}<airlow>|</airlow> / / : \</regular> / ~~------~ ~~\ (</water> + <water>\ ' <regular><airlow>||</airlow>/ \ |<mob>===</mob>|</regular> /~/ ~~~ \ \(</water> + <water>``~\ <regular><airlow>~~</airlow>\ )~.~_ \._./ _~-~</regular> |`_ ~~-~ )\</water> + <water>'-~ <regular>{ / ) \___/ ( \</regular> |` ` _ ~~ '</water> + <water>\ -~\ <regular>-<__/ - - L~ -;</regular> \\ \ _ _/</water> + <water>`` ~~=\ <regular>{ : }\ ,\</regular> || _ :(</water> + <water>\ ~~=\__ <regular>\ _/ \_ / ) }</regular> _// ( `|'</water> + <water>`` , ~\--~=\ <regular>\ / / _/</regular> / ' ( '</water> + <water>\` } ~ ~~ -~=\ _~_ <regular>/ \ / \ )^ (</regular> // :_ / '</water> + <water>| , _~-' '~~__<regular>-_ / - |</regular>/ \ (</water> + <water>\ ,_--_ _/ <regular>\_'---',</regular> -~ . \</water> + <water>)/ /\ / /\ ,~, <regular>\__ _}</regular> \_ "~_</water> + <water>, { ( _ )'} ~ - \_ ~\ <regular>(-:-)</regular> "\ ~</water> + <water>/'' '' )~ \~_ ~\ )-> <regular>\ :|</regular> _, "</water> + <water><roomtitle>(\</roomtitle> _<roomtitle>/)</roomtitle>''} | \~_ ~ /~( <regular>| :)</regular> / }</water> + <water>/`` /;,,/ )= \~__ {{{ ' <regular>\ =(</regular> , , ;</water> + <water>{<roomtitle>o</roomtitle>_<roomtitle>o</roomtitle> }_/ |v '~__ _ <regular>)-v|</regular> " : ,"</water> + <water>{/"\_) {_/' \~__ ~\_ <regular>\\_}</regular> ' { /~\</water> + <important>,/!</important> <water>'_/ '~__ _-~ <regular>\_'</regular> : ' ," ~</water> + <important>(''`</important> <water>/,'~___~ | / ," \ ~'</water> + <important>'/, )</important> <water>(-) '~____~"; ," , }</water> + <important>/,')</important> <water>/ \ / ,~-" '~'</water> + <important>( ''/</important> <water>/ ( ' / / '~'</water> + <important>~ ~ ,, /) ,</important> <water>(/( \) ( -) /~'</water> + <important>( ~~ )` ~}</important> <news>'</news> <water>\)</water><news>'</news> <water>_/ / ~'</water> + <important>{ |) /`,--.( }'</important> <news>'</news> <water>( / /~'</water> +<important>(` ~ ( c|~~| `} )</important> <water>'/:\</water> <news>,</news><water>'</water> + <important>~ )/``) )) '|),</important> <water>(/ | \)</water> + <important>(` (-~(( `~`' )</important> <news>'</news> <water>(/</water> <news>'</news> + <important>`~' )'`')</important> <news>'</news> + <important>` ``</important> + + <earthhigh>Welcome to the</earthhigh> +<earth> .. s</earth> +<earth> :**888H: `: .xH"" :8 .uef^" ..</earth> +<earth> X `8888k XX888 .88 :d88E @L .u .</earth> +<earth>'8hx 48888 ?8888 .u :888ooo `888E 9888i .dL .d88B :@8c</earth> +<earth>'8888 '8888 `8888 ud8888. -*8888888 888E .z8k `Y888k:*888. ="8888f888r</earth> +<earth> %888>'8888 8888 :888'8888. 8888 888E~?888L 888E 888I 4888>'88"</earth> +<earth> "8 '888" 8888 d888 '88%" 8888 888E 888E 888E 888I 4888> '</earth> +<earth> .-` X*" 8888 8888.+" 8888 888E 888E 888E 888I 4888></earth> +<earth> .xhx. 8888 8888L .8888Lu= 888E 888E 888E 888I .d888L .+</earth> +<earth> .H88888h.~`8888.. '8888c. .+ ^%888* 888E 888E x888N>-888' ^"8888*"</earth> +<earth> .~ `%88!` '888*~ "88888% 'Y" m888N= 888` "88" 888 "Y"</earth> +<earth> `" "" "YP' `Y" 888 88F</earth> +<earth> J88" 98"</earth> +<earth> @% ./"</earth> +<earth> :" ~`</earth> diff --git a/lib/aethyr/core/actions/action.rb b/lib/aethyr/core/actions/action.rb new file mode 100644 index 0000000000000000000000000000000000000000..7dd7874662d945a1f4e298a3888def293c9f7cd4 --- /dev/null +++ b/lib/aethyr/core/actions/action.rb @@ -0,0 +1,19 @@ +module Aethyr + module Extend + module Action + def concurrency + :single + end + + def action; end + end + + class Event + include Aethyr::Extend::Action + + def initialize(**data) + @data = data.freeze + end + end + end +end diff --git a/lib/aethyr/core/actions/action_groups.rb b/lib/aethyr/core/actions/action_groups.rb new file mode 100644 index 0000000000000000000000000000000000000000..a957597605e8f94b6db24bd114b54711099970bc --- /dev/null +++ b/lib/aethyr/core/actions/action_groups.rb @@ -0,0 +1,23 @@ +module Aethyr + module Extend + class ActionGroup + attr_reader :concurrency + + def initialize(concurrency, *actions) + @actions = *actions + @concurrency = concurrency + + if @concurrency != :parallel && @concurrency != :sequenial + raise 'Invalid concurrency type' + end + if @actions.nil? || @actions.length < 2 + raise 'actions needs to have at least two values' + end + end + + def each + @actions.each { |e| yield e } + end + end + end +end diff --git a/lib/aethyr/core/actions/command_action.rb b/lib/aethyr/core/actions/command_action.rb new file mode 100644 index 0000000000000000000000000000000000000000..c037006fc8b327163ba975a08ab96de957c2cb9a --- /dev/null +++ b/lib/aethyr/core/actions/command_action.rb @@ -0,0 +1,12 @@ +require "aethyr/core/actions/action" + +module Aethyr + module Extend + class CommandAction < Event + def initialize(actor, **data) + super(**data) + @player = actor + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/acarea.rb b/lib/aethyr/core/actions/commands/acarea.rb new file mode 100644 index 0000000000000000000000000000000000000000..4f70fc3f0709fc29851e8a55812394ddeaf37357 --- /dev/null +++ b/lib/aethyr/core/actions/commands/acarea.rb @@ -0,0 +1,25 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Acarea + class AcareaCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + area = $manager.create_object(Area, nil, nil, nil, {:@name => event[:name]}) + player.output "Created: #{area}" + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/acdoor.rb b/lib/aethyr/core/actions/commands/acdoor.rb new file mode 100644 index 0000000000000000000000000000000000000000..cf592c24133225c40030f995ff4f1c6930d25ec1 --- /dev/null +++ b/lib/aethyr/core/actions/commands/acdoor.rb @@ -0,0 +1,60 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Acdoor + class AcdoorCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + player = @player + exit_room = nil + if event[:exit_room].nil? + out = find_object event[:direction], event + if out and out.is_a? Exit + exit_room = $manager.find out.exit_room + other_side = $manager.find opposite_dir(event[:direction]), out.exit_room + + if other_side + $manager.delete_object other_side + player.output "Removed opposite exit (#{other_side})." + else + player.output "Could not find opposite exit" + end + + $manager.delete_object out + player.output "Removed exit (#{out})." + end + else + exit_room = $manager.get_object event[:exit_room] + end + + if exit_room.nil? + player.output "Cannot find #{event[:exit_room]} to connect to." + return + end + + door_here = $manager.create_object Door, room, nil, exit_room.goid, :@alt_names => [event[:direction]], :@name => "a door to the #{event[:direction]}" + door_there = $manager.create_object Door, exit_room, nil, room.goid, :@alt_names => [opposite_dir(event[:direction])], :@name => "a door to the #{opposite_dir event[:direction]}" + door_here.connect_to door_there + + player.output "Created: #{door_here}" + player.output "Created: #{door_there}" + + if room + event[:to_player] = "Frowning in concentration, you make vague motions with your hands. There is a small flash of light as #{door_here.name} to #{exit_room.name} appears." + event[:to_other] = "Frowning in concentration, #{player.name} makes vague motions with #{player.pronoun(:possessive)} hands. There is a small flash of light as #{door_here.name} to #{exit_room.name} appears." + room.out_event event + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/acomment.rb b/lib/aethyr/core/actions/commands/acomment.rb new file mode 100644 index 0000000000000000000000000000000000000000..12907e79a6af9c35a11aa0ef7207f73552f36637 --- /dev/null +++ b/lib/aethyr/core/actions/commands/acomment.rb @@ -0,0 +1,31 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Acomment + class AcommentCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = find_object(event[:target], event) + if object.nil? + player.output "Cannot find:#{event[:target]}" + return + end + + object.comment = event[:comment] + player.output "Added comment: '#{event[:comment]}'\nto#{object}" + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/aconfig.rb b/lib/aethyr/core/actions/commands/aconfig.rb new file mode 100644 index 0000000000000000000000000000000000000000..717f53f5753f0588b3adde724148397bd842b151 --- /dev/null +++ b/lib/aethyr/core/actions/commands/aconfig.rb @@ -0,0 +1,48 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Aconfig + class AconfigCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + if event[:setting].nil? + player.output "Current configuration:\n#{ServerConfig}" + return + end + + setting = event[:setting].downcase.to_sym + + if setting == :reload + ServerConfig.reload + player.output "Reloaded configuration:\n#{ServerConfig}" + return + elsif not ServerConfig.has_setting? setting + player.output "No such setting." + return + end + + value = event[:value] + if value =~ /^\d+$/ + value = value.to_i + end + + ServerConfig[setting] = value + + player.output "New configuration:\n#{ServerConfig}" + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/acportal.rb b/lib/aethyr/core/actions/commands/acportal.rb new file mode 100644 index 0000000000000000000000000000000000000000..e669eaff9879add3991f8216c3badef049d3bf05 --- /dev/null +++ b/lib/aethyr/core/actions/commands/acportal.rb @@ -0,0 +1,27 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Acportal + class AcportalCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = Admin.acreate(event, player, room) + if event[:portal_action] and event[:portal_action].downcase != "enter" + object.info.portal_action = event[:portal_action].downcase.to_sym + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/acreate.rb b/lib/aethyr/core/actions/commands/acreate.rb new file mode 100644 index 0000000000000000000000000000000000000000..bf8f660e4ed4cdbc980995642b081664603110ac --- /dev/null +++ b/lib/aethyr/core/actions/commands/acreate.rb @@ -0,0 +1,55 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Acreate + class AcreateCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + class_name = event[:object] + + class_name[0,1] = class_name[0,1].capitalize + + if Object.const_defined? class_name + klass = Object.const_get(class_name) + else + player.output "No such thing. Sorry." + return + end + + if not klass <= GameObject or klass == Player + player.output "You cannot create a #{klass.class}." + return + end + + vars = {} + vars[:@name] = event[:name] if event[:name] + vars[:@alt_names] = event[:alt_names] if event[:alt_names] + vars[:@generic] = event[:generic] if event[:generic] + args = event[:args] + + object = $manager.create_object(klass, room, nil, args, vars) + + if room + event[:to_player] = "Frowning in concentration, you make vague motions with your hands. There is a small flash of light as #{object.name} appears." + event[:to_other] = "Frowning in concentration, #{player.name} makes vague motions with #{player.pronoun(:possessive)} hands. There is a small flash of light as #{object.name} appears." + room.out_event event + end + + player.output "Created: #{object}" + object + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/acroom.rb b/lib/aethyr/core/actions/commands/acroom.rb new file mode 100644 index 0000000000000000000000000000000000000000..345c0376f02f179c081127523346d3f26e766d79 --- /dev/null +++ b/lib/aethyr/core/actions/commands/acroom.rb @@ -0,0 +1,107 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Acroom + class AcroomCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + area = nil + if room.container + area = $manager.get_object(room.container) + end + + unless area.nil? or area.map_type.eql? :none + current_pos = area.position(room) + new_pos = current_pos.dup + case event[:out_dir].downcase.strip + when "north" + new_pos[1] += 1 + when "south" + new_pos[1] -= 1 + when "west" + new_pos[0] -= 1 + when "east" + new_pos[0] += 1 + when "northeast" + player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" + return + when "northwest" + player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" + return + when "southeast" + player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" + return + when "southwest" + player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" + return + else + new_pos = nil + end + new_pos_text = new_pos.map{ |e| e.to_s}.join('x') unless new_pos.nil? + end + + unless new_pos.nil? or area.find_by_position(new_pos).nil? + player.output "There is already a room at the coordinates (#{new_pos_text}) that would be occupied by the new room, aborting" + return + end + + new_room = $manager.create_object(Room, area, new_pos, nil, :@name => event[:name]) + out_exit = $manager.create_object(Exit, room, nil, new_room.goid, :@alt_names => [event[:out_dir]]) + in_exit = $manager.create_object(Exit, new_room, nil, room.goid, :@alt_names => [event[:in_dir]]) + + player.output "Created: #{new_room}#{new_pos.nil? ? '' : ' @ ' + new_pos_text}" + player.output "Created: #{out_exit}" + player.output "Created: #{in_exit}" + + if !area.nil? and area.map_type.eql? :world + west = area.find_by_position([new_pos[0] - 1, new_pos[1]]) + east = area.find_by_position([new_pos[0] + 1, new_pos[1]]) + north = area.find_by_position([new_pos[0], new_pos[1] + 1]) + south = area.find_by_position([new_pos[0], new_pos[1] - 1]) + if !west.nil? and !west.eql? room + out_exit = $manager.create_object(Exit, new_room, nil, west.goid, :@alt_names => ["west"]) + in_exit = $manager.create_object(Exit, west, nil, new_room.goid, :@alt_names => ["east"]) + player.output "Created: #{out_exit}" + player.output "Created: #{in_exit}" + west.output "There is a small flash of light as a new room appears to the east." + elsif !east.nil? and !east.eql? room + out_exit = $manager.create_object(Exit, new_room, nil, east.goid, :@alt_names => ["east"]) + in_exit = $manager.create_object(Exit, east, nil, new_room.goid, :@alt_names => ["west"]) + player.output "Created: #{out_exit}" + player.output "Created: #{in_exit}" + east.output "There is a small flash of light as a new room appears to the west." + elsif !north.nil? and !north.eql? room + out_exit = $manager.create_object(Exit, new_room, nil, north.goid, :@alt_names => ["north"]) + in_exit = $manager.create_object(Exit, north, nil, new_room.goid, :@alt_names => ["south"]) + player.output "Created: #{out_exit}" + player.output "Created: #{in_exit}" + north.output "There is a small flash of light as a new room appears to the south." + elsif !south.nil? and !south.eql? room + out_exit = $manager.create_object(Exit, new_room, nil, south.goid, :@alt_names => ["south"]) + in_exit = $manager.create_object(Exit, south, nil, new_room.goid, :@alt_names => ["north"]) + player.output "Created: #{out_exit}" + player.output "Created: #{in_exit}" + south.output "There is a small flash of light as a new room appears to the north." + end + end + + if room + room.output "There is a small flash of light as a new room appears to the #{event[:out_dir]}." + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/adelete.rb b/lib/aethyr/core/actions/commands/adelete.rb new file mode 100644 index 0000000000000000000000000000000000000000..f740862a1dc61413ec6bb0948aaef39cc2a69be7 --- /dev/null +++ b/lib/aethyr/core/actions/commands/adelete.rb @@ -0,0 +1,69 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Adelete + class AdeleteCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:object] and event[:object].split.first.downcase == "all" + log event[:object].split + klass = event[:object].split[1] + klass.capitalize! unless klass[0,1] == klass[0,1].upcase + begin + klass = Module.const_get klass.to_sym + rescue NameError + player.output "No such object type." + return + end + + objects = $manager.find_all("class", klass) + + objects.each do |obj| + e = event.dup + e[:object] = obj.goid + + Admin.adelete(e, player, room) + end + + return + end + + object = find_object(event[:object], event) + + if object.nil? + player.output "Cannot find #{event[:object]} to delete." + return + elsif object.is_a? Player + player.output "Use DELETEPLAYER to delete players." + return + end + + object_container = object.container + + $manager.delete_object(object) + + if room and room.goid == object.container + event[:to_player] = "You casually wave your hand and #{object.name} disappears." + event[:to_other] = "With a casual wave of #{player.pronoun(:possessive)} hand, #{player.name} makes #{object.name} disappear." + room.out_event event + else + player.output "You casually wave your hand and #{object.name} disappears." + end + + player.output "#{object} deleted." + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/adesc.rb b/lib/aethyr/core/actions/commands/adesc.rb new file mode 100644 index 0000000000000000000000000000000000000000..fe23f9a244581fd49df84da7c2a1293553d0886f --- /dev/null +++ b/lib/aethyr/core/actions/commands/adesc.rb @@ -0,0 +1,47 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Adesc + class AdescCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = nil + if event[:object].downcase == "here" + object = room + else + object = find_object(event[:object], event) + end + + if object.nil? + player.output "Cannot find #{event[:object]}." + return + end + + if event[:inroom] + if event[:desc].nil? or event[:desc].downcase == "false" + object.show_in_look = false + player.output "#{object.name} will not be shown in the room description." + else + object.show_in_look= event[:desc] + player.output "The room will show #{object.show_in_look}" + end + else + object.instance_variable_set(:@short_desc, event[:desc]) + player.output "#{object.name} now looks like:\n#{object.short_desc}" + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/aforce.rb b/lib/aethyr/core/actions/commands/aforce.rb new file mode 100644 index 0000000000000000000000000000000000000000..6359f70585c60378cf632494d3f37160c3d5a487 --- /dev/null +++ b/lib/aethyr/core/actions/commands/aforce.rb @@ -0,0 +1,33 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Aforce + class AforceCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = find_object(event[:target], event) + if object.nil? + player.output "Force who?" + return + elsif object.is_a? Player + object.handle_input(event[:command]) + else + player.output "You can only force other players to execute a command." + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/ahelp.rb b/lib/aethyr/core/actions/commands/ahelp.rb new file mode 100644 index 0000000000000000000000000000000000000000..0d060e62bdc4d0a0dcc2e9f34e85f608f6fe98a1 --- /dev/null +++ b/lib/aethyr/core/actions/commands/ahelp.rb @@ -0,0 +1,24 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Ahelp + class AhelpCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + Generic.help(event, player, room) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/ahide.rb b/lib/aethyr/core/actions/commands/ahide.rb new file mode 100644 index 0000000000000000000000000000000000000000..51f9bb99ebdf890e3197e61767382c4bbbde99d9 --- /dev/null +++ b/lib/aethyr/core/actions/commands/ahide.rb @@ -0,0 +1,39 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Ahide + class AhideCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = find_object(event[:object], event) + + if object.nil? + player.output "Cannot find #{event[:object]}." + return + end + + if event[:hide] + object.show_in_look = "" + player.output "#{object.name} is now hidden." + elsif object.show_in_look == "" + object.show_in_look = false + player.output "#{object.name} is no longer hidden." + else + player.output "This object is not hidden." + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/ainfo.rb b/lib/aethyr/core/actions/commands/ainfo.rb new file mode 100644 index 0000000000000000000000000000000000000000..0cd564ba3ac10be954dd85aee51067029eb401b6 --- /dev/null +++ b/lib/aethyr/core/actions/commands/ainfo.rb @@ -0,0 +1,88 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Ainfo + class AinfoCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:object].downcase == "here" + event[:object] = player.container + elsif event[:object].downcase == "me" + event[:object] = player + elsif event[:object] and event[:object].split.first.downcase == "all" + log event[:object].split + klass = event[:object].split[1] + klass.capitalize! unless klass[0,1] == klass[0,1].upcase + begin + klass = Module.const_get klass.to_sym + rescue NameError + player.output "No such object type." + return + end + + objects = $manager.find_all("class", klass) + + objects.each do |obj| + e = event.dup + e[:object] = obj.goid + + Admin.ainfo(e, player, room) + end + + return + end + + object = find_object(event[:object], event) + + if object.nil? + player.output "What object? #{event[:object]}" + return + end + + case event[:command] + when "set" + value = event[:value] #for ease + if value.split.length == 1 + if value == "true" + value = true + elsif value == "false" + value = false + elsif value[0,1] == ":" + value = value[1..-1].to_sym + elsif value == "nil" + value = nil + elsif value.match(/^[0-9]+$/) + value = value.to_i + elsif value.downcase == "!nothing" + value = "" + end + end + object.info.set(event[:attrib], value) + player.output "Set #{event[:attrib]} to #{object.info.get(event[:attrib])}" + when "delete" + object.info.delete(event[:attrib]) + player.output "Deleted #{event[:attrib]} from #{object}" + when "show" + player.output object.info.inspect + when "clear" + object.info = Info.new + player.output "Completely cleared info for #{object}." + else + player.output "Huh? What?" + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/alearn.rb b/lib/aethyr/core/actions/commands/alearn.rb new file mode 100644 index 0000000000000000000000000000000000000000..58a8a987ee1b3b6a1086b48eea31526a0b113e27 --- /dev/null +++ b/lib/aethyr/core/actions/commands/alearn.rb @@ -0,0 +1,23 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Alearn + class AlearnCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/alist.rb b/lib/aethyr/core/actions/commands/alist.rb new file mode 100644 index 0000000000000000000000000000000000000000..925610e3c6dd07424a51161e743b8ab6ff63d27e --- /dev/null +++ b/lib/aethyr/core/actions/commands/alist.rb @@ -0,0 +1,42 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Alist + class AlistCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + objects = nil + if event[:match].nil? + objects = $manager.find_all("class", :GameObject) + else + objects = $manager.find_all(event[:match], event[:attrib]) + end + + if objects.empty? + player.output "Nothing like that to list!" + else + output = [] + objects.each do |o| + output << "\t" + o.to_s + end + + output = output.join("\n") + + player.output(output) + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/all.rb b/lib/aethyr/core/actions/commands/all.rb new file mode 100644 index 0000000000000000000000000000000000000000..83d00058d24dd576278ad53ca6c709a360aca600 --- /dev/null +++ b/lib/aethyr/core/actions/commands/all.rb @@ -0,0 +1,33 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module All + class AllCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + board = find_board(event, room) + + if board.nil? + player.output "There do not seem to be any postings here." + return + end + + wordwrap = player.word_wrap || 100 + + player.output board.list_latest(wordwrap, 0, nil) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/alog.rb b/lib/aethyr/core/actions/commands/alog.rb new file mode 100644 index 0000000000000000000000000000000000000000..6c67e352303ace1f83624a6e742df1bbc70c72e9 --- /dev/null +++ b/lib/aethyr/core/actions/commands/alog.rb @@ -0,0 +1,79 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Alog + class AlogCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:command].nil? + player.output "What do you want to do with the log?" + return + else + command = event[:command].downcase + end + + case command + when /^players?$/ + if event[:value] + lines = event[:value].to_i + else + lines = 10 + end + + player.output tail('logs/player.log', lines) + when 'server' + if event[:value] + lines = event[:value].to_i + else + lines = 10 + end + + player.output tail('logs/server.log', lines) + when 'system' + if event[:value] + lines = event[:value].to_i + else + lines = 10 + end + + $LOG.dump + + player.output tail('logs/system.log', lines) + when 'flush' + log('Flushing log') + $LOG.dump + player.output 'Flushed log to disk.' + when 'ultimate' + ServerConfig[:log_level] = 3 + player.output "Log level now set to ULTIMATE." + when 'high' + ServerConfig[:log_level] = 2 + player.output "Log level now set to high." + when 'low', 'normal' + ServerConfig[:log_level] = 1 + player.output "Log level now set to normal." + when 'off' + ServerConfig[:log_level] = 0 + player.output "Logging mostly turned off. You may also want to turn off debugging." + when 'debug' + ServerConfig[:debug] = !$DEBUG + player.output "Debug info is now: #{$DEBUG ? 'on' : 'off'}" + else + player.output 'Possible settings: Off, Debug, Normal, High, or Ultimate' + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/alook.rb b/lib/aethyr/core/actions/commands/alook.rb new file mode 100644 index 0000000000000000000000000000000000000000..144ab35ef070435f159571d727d32136a5254eab --- /dev/null +++ b/lib/aethyr/core/actions/commands/alook.rb @@ -0,0 +1,69 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Alook + class AlookCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:at].nil? + object = room + elsif event[:at].downcase == "here" + object = $manager.find player.container + else + object = find_object(event[:at], event) + end + + if object.nil? + player.output "Cannot find #{event[:at]} to inspect." + return + end + + output = "Object: #{object}\n" + output << "Attributes:\n" + + object.instance_variables.sort.each do |var| + val = object.instance_variable_get(var) + if var == :@observer_peers + val = val.keys.map {|k| k.to_s } + elsif var == :@local_registrations + val = val.map { |e| e.instance_variable_get(:@listener).to_s.tr('#<>', '') } + end + output << "\t#{var} = #{val}\n" + end + + output << "\r\nInventory:\r\n" + + if object.respond_to? :inventory + object.inventory.each do |o| + output << "\t#{o.name} # #{o.goid} #{object.inventory.position(o) == nil ? "" : object.inventory.position(o).map(&:to_s).join('x')}\n" + end + else + output << "\tNo Inventory" + end + + if object.respond_to? :equipment + output << "\r\nEquipment:\r\n" + object.equipment.inventory.each do |o| + output << "\t#{o.name} # #{o.goid}\n" + end + output << "\t#{object.equipment.equipment.inspect}\n" + end + + puts output + player.output(output) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/aput.rb b/lib/aethyr/core/actions/commands/aput.rb new file mode 100644 index 0000000000000000000000000000000000000000..c58e543de8dde07c056020c5880bd96e8e3873e3 --- /dev/null +++ b/lib/aethyr/core/actions/commands/aput.rb @@ -0,0 +1,71 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Aput + class AputCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:object].is_a? GameObject + object = event[:object] + else + event[:object] = player.container if event[:object].downcase == "here" + object = find_object(event[:object], event) + end + + container = find_object(event[:in], event) + + if object.nil? + player.output "Cannot find #{event[:object]} to move." + return + elsif event[:in] == "!world" + container = $manager.find object.container + container.inventory.remove(object) unless container.nil? + object.container = nil + player.output "Removed #{object} from any containers." + return + elsif event[:in].downcase == "here" + container = $manager.find player.container + if container.nil? + player.output "Cannot find #{event[:in]} " + return + end + elsif container.nil? + player.output "Cannot find #{event[:in]} " + return + end + + if not object.container.nil? + current_container = $manager.find object.container + current_container.inventory.remove(object) if current_container + end + + unless event[:at] == nil + position = event[:at].split('x').map{ |e| e.to_i} + end + + if container.is_a? Inventory + container.add(object, position) + elsif container.is_a? Container + container.add(object) + else + container.inventory.add(object, position) + object.container = container.goid + end + + player.output "Moved #{object} into #{container}#{event[:at] == nil ? '' : ' at ' + event[:at]}" + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/areaction.rb b/lib/aethyr/core/actions/commands/areaction.rb new file mode 100644 index 0000000000000000000000000000000000000000..09a3908d30eb850e6118d4c1d11e583e9ae0890b --- /dev/null +++ b/lib/aethyr/core/actions/commands/areaction.rb @@ -0,0 +1,111 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Areaction + class AreactionCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + if event[:command] == "reload" and event[:object] and event[:object].downcase == "all" + objects = $manager.find_all("class", Reacts) + + objects.each do |o| + o.reload_reactions + end + + player.output "Updated reactions for #{objects.length} objects." + elsif event[:object] and event[:object].split.first.downcase == "all" + klass = event[:object].split[1] + klass.capitalize! unless klass[0,1] == klass[0,1].upcase + begin + klass = Module.const_get klass.to_sym + rescue NameError + player.output "No such object type." + return + end + + objects = $manager.find_all("class", klass) + + objects.each do |obj| + e = event.dup + e[:object] = obj.goid + + player.output "(Doing #{obj})" + Admin.areaction(e, player, room) + end + else + if event[:object] == "here" + object = room + else + object = find_object(event[:object], event) + end + + if object.nil? + player.output "Cannot find:#{event[:object]}" + return + elsif not object.is_a? Reacts and (event[:command] == "load" or event[:command] == "reload") + player.output "Object cannot react, adding react ability." + object.extend(Reacts) + end + + case event[:command] + when "add" + if object.actions.add? event[:action_name] + player.output "Added #{event[:action_name]}" + else + player.output "Already had a reaction by that name." + end + when "delete" + if object.actions.delete? event[:action_name] + player.output "Removed #{event[:action_name]}" + else + player.output "That verb was not associated with this object." + end + when "load" + unless File.exist? "objects/reactions/#{event[:file]}.rx" + player.output "No such reaction file - #{event[:file]}" + return + end + + object.load_reactions event[:file] + player.output "Probably loaded reactions." + when "reload" + object.reload_reactions if object.can? :reload_reactions + player.output "Probably reloaded reactions." + when "clear" + object.unload_reactions if object.can? :unload_reactions + player.output "Probably cleared out reactions." + when "show" + if object.actions and not object.actions.empty? + player.output "Custom actions: #{object.actions.to_a.sort.join(' ')}", true + end + + if object.can? :show_reactions + player.output object.show_reactions + else + player.output "Object does not react." + end + else + player.output("Options:", true) + player.output("areaction load <object> <file>", true) + player.output("areaction reload <object> <file>", true) + player.output("areaction [add|delete] <object> <action>", true) + player.output("areaction [clear|show] <object>") + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/areas.rb b/lib/aethyr/core/actions/commands/areas.rb new file mode 100644 index 0000000000000000000000000000000000000000..11378e696af24fbb1244282d79ca496526e91e2e --- /dev/null +++ b/lib/aethyr/core/actions/commands/areas.rb @@ -0,0 +1,31 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Areas + class AreasCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + areas = $manager.find_all('class', Area) + + if areas.empty? + player.output "There are no areas." + return + end + + player.output areas.map {|a| "#{a.name} - #{a.inventory.find_all('class', Room).length} rooms (#{a.info.terrain.area_type})" } + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/areload.rb b/lib/aethyr/core/actions/commands/areload.rb new file mode 100644 index 0000000000000000000000000000000000000000..6148f1bbe8c3507a1fd179bb451b3808fe0295d3 --- /dev/null +++ b/lib/aethyr/core/actions/commands/areload.rb @@ -0,0 +1,29 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Areload + class AreloadCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + begin + result = load "#{event[:object]}.rb" + player.output "Reloaded #{event[:object]}: #{result}" + rescue LoadError + player.output "Unable to load #{event[:object]}" + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/asave.rb b/lib/aethyr/core/actions/commands/asave.rb new file mode 100644 index 0000000000000000000000000000000000000000..b197ebeedc6e02100d5c919f7a8f43189050434c --- /dev/null +++ b/lib/aethyr/core/actions/commands/asave.rb @@ -0,0 +1,26 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Asave + class AsaveCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + log "#{player.name} initiated manual save." + $manager.save_all + player.output "Save complete. Check log for details." + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/aset.rb b/lib/aethyr/core/actions/commands/aset.rb new file mode 100644 index 0000000000000000000000000000000000000000..1324a862d916eecfb9d57d68499a955a14fe5303 --- /dev/null +++ b/lib/aethyr/core/actions/commands/aset.rb @@ -0,0 +1,145 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Aset + class AsetCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:object].downcase == "here" + event[:object] = player.container + elsif event[:object] and event[:object].split.first.downcase == "all" + log event[:object].split + klass = event[:object].split[1] + klass.capitalize! unless klass[0,1] == klass[0,1].upcase + begin + klass = Module.const_get klass.to_sym + rescue NameError + player.output "No such object type." + return + end + + objects = $manager.find_all("class", klass) + + objects.each do |obj| + e = event.dup + e[:object] = obj.goid + + Admin.aset(e, player, room) + end + + return + end + + object = find_object(event[:object], event) + + if object.nil? + player.output "Cannot find #{event[:object]} to edit." + return + end + + attrib = event[:attribute] + + if attrib[0,1] != "@" + value = event[:value] + if value.downcase == "!nothing" or value.downcase == "nil" + value = nil + end + + if value and value[-1,1] !~ /[!.?"']/ + value << "." + end + + case attrib.downcase + when "smell" + if value.nil? + object.info.delete :smell + player.output "#{object.name} will no longer smell." + else + object.info.smell = value + player.output "#{object.name} will now smell like: #{object.info.smell}" + end + return + when "feel", "texture" + if value.nil? + object.info.delete :texture + player.output "#{object.name} will no longer have a particular texture." + else + object.info.texture = value + player.output "#{object.name} will now feel like: #{object.info.texture}" + end + return + when "taste" + if value.nil? + object.info.delete :taste + player.output "#{object.name} will no longer have a particular taste." + else + object.info.taste = value + player.output "#{object.name} will now taste like: #{object.info.taste}" + end + return + when "sound", "listen" + if value.nil? + object.info.delete :sound + player.output "#{object.name} will no longer make sounds." + else + object.info.sound = value + player.output "#{object.name} will now sound like: #{object.info.sound}" + end + return + else + player.output "What are you trying to set?" + return + end + end + + if not object.instance_variables.include? attrib and not object.instance_variables.include? attrib.to_sym and not event[:force] + player.output "#{object}:No such setting/variable/attribute: #{attrib}" + return + else + current_value = object.instance_variable_get(attrib) + if current_value.is_a? Array + object.instance_variable_set(attrib, event[:value].split(/s*"(.*?)"\s*|\s+/)) + player.output "Set #{object} attribute #{attrib} to #{event[:value].inspect}" + else + value = event[:value] #for ease + if value.split.length == 1 + case value.downcase + when "true" + value = true + when "false" + value = false + when /^:/ + value = value[1..-1].to_sym + when "nil" + value = nil + when /^[0-9]+$/ + value = value.to_i unless current_value.is_a? String + when "!nothing" + value = "" + when "!delete" + object.instance_eval { remove_instance_variable(attrib) } + player.output "Removed attribute #{attrib} from #{object}" + return + end + end + + object.instance_variable_set(attrib, value) + player.output "Set #{object} attribute #{attrib} to #{value}" + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/astatus.rb b/lib/aethyr/core/actions/commands/astatus.rb new file mode 100644 index 0000000000000000000000000000000000000000..2ce5dc3472f577d8e0c1b48b786afbd50f5a640e --- /dev/null +++ b/lib/aethyr/core/actions/commands/astatus.rb @@ -0,0 +1,30 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Astatus + class AstatusCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + awho(event, player, room) + total_objects = $manager.game_objects_count + player.output("Object Counts:" , true) + $manager.type_count.each do |obj, count| + player.output("#{obj}: #{count}", true) + end + player.output("Total Objects: #{total_objects}") + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/ateach.rb b/lib/aethyr/core/actions/commands/ateach.rb new file mode 100644 index 0000000000000000000000000000000000000000..5acae607ed6872500d3391247369ced3d2cf5457 --- /dev/null +++ b/lib/aethyr/core/actions/commands/ateach.rb @@ -0,0 +1,30 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Ateach + class AteachCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = find_object(event[:target], event) + if object.nil? + player.output "Teach who what where?" + return + end + + alearn(event, object, room) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/awatch.rb b/lib/aethyr/core/actions/commands/awatch.rb new file mode 100644 index 0000000000000000000000000000000000000000..66ecf3473ede39f9bf675aeabaf6ebffcb42ecb5 --- /dev/null +++ b/lib/aethyr/core/actions/commands/awatch.rb @@ -0,0 +1,58 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Awatch + class AwatchCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = find_object(event[:target], event) + if object.nil? + player.output "What mobile do you want to watch?" + return + elsif not object.is_a? Mobile + player.output "You can only use this to watch mobiles." + return + end + + case event[:command] + when "start" + if object.info.redirect_output_to == player.goid + player.output "You are already watching #{object.name}." + else + object.info.redirect_output_to = player.goid + player.output "Watching #{object.name}." + object.output "#{player.name} is watching you." + end + when "stop" + if object.info.redirect_output_to != player.goid + player.output "You are not watching #{object.name}." + else + object.info.redirect_output_to = nil + player.output "No longer watching #{object.name}." + end + else + if object.info.redirect_output_to != player.goid + object.info.redirect_output_to = player.goid + player.output "Watching #{object.name}." + object.output "#{player.name} is watching you." + else + object.info.redirect_output_to = nil + player.output "No longer watching #{object.name}." + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/awho.rb b/lib/aethyr/core/actions/commands/awho.rb new file mode 100644 index 0000000000000000000000000000000000000000..1632f9e39dbc3df380ea2cb7f99febe16ba8b935 --- /dev/null +++ b/lib/aethyr/core/actions/commands/awho.rb @@ -0,0 +1,32 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Awho + class AwhoCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + players = $manager.find_all('class', Player) + + names = [] + players.each do |playa| + names << playa.name + end + + player.output('Players currently online:', true) + player.output(names.join(', ')) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/close.rb b/lib/aethyr/core/actions/commands/close.rb new file mode 100644 index 0000000000000000000000000000000000000000..ec14e2f750cc52ff6e92400110380e06aa6e71f3 --- /dev/null +++ b/lib/aethyr/core/actions/commands/close.rb @@ -0,0 +1,30 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Close + class CloseCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action() + event = @data + room = $manager.get_object(@player.container) + object = expand_direction(event[:object]) + object = @player.search_inv(object) || $manager.find(object, room) + + if object.nil? + @player.output("Close what?") + elsif not object.can? :open + @player.output("You cannot close #{object.name}.") + else + object.close(event) + end + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/date.rb b/lib/aethyr/core/actions/commands/date.rb new file mode 100644 index 0000000000000000000000000000000000000000..477be8c52bc59235f4ff30cd44e3aac0c32c9731 --- /dev/null +++ b/lib/aethyr/core/actions/commands/date.rb @@ -0,0 +1,21 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Date + class DateCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + @player.output $manager.date + end + #Show who is in the game. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/delete_player.rb b/lib/aethyr/core/actions/commands/delete_player.rb new file mode 100644 index 0000000000000000000000000000000000000000..4a4882b12411f53a6df4481d3417b0d0d4a582bd --- /dev/null +++ b/lib/aethyr/core/actions/commands/delete_player.rb @@ -0,0 +1,42 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module DeletePlayer + class DeletePlayerCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + name = event.object + if not $manager.player_exist? name + player.output "No such player found: #{name}" + return + elsif $manager.find name + player.output "Player is currently logged in. Deletion aborted." + return + elsif name == player.name.downcase + player.output "You cannot delete yourself this way. Use DELETE ME PLEASE instead." + return + end + + $manager.delete_player name + + if $manager.find name or $manager.player_exist? name + player.output "Something went wrong. Player still exists." + else + player.output "#{name} deleted." + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/delete_post.rb b/lib/aethyr/core/actions/commands/delete_post.rb new file mode 100644 index 0000000000000000000000000000000000000000..f2b8b40d38e056e57c3b6130548656cc5013a08d --- /dev/null +++ b/lib/aethyr/core/actions/commands/delete_post.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module DeletePost + class DeletePostCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + + + + board = find_board(event, room) + + if board.nil? + player.output "What newsboard are you talking about?" + return + end + + post = board.get_post event[:post_id] + + if post.nil? + player.output "No such post." + elsif post[:author] != player.name + player.output "You can only delete your own posts." + else + board.delete_post event[:post_id] + player.output "Deleted post ##{event[:post_id]}" + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/deleteme.rb b/lib/aethyr/core/actions/commands/deleteme.rb new file mode 100644 index 0000000000000000000000000000000000000000..9388dff6af3b5f982371328563fe7313492d1c86 --- /dev/null +++ b/lib/aethyr/core/actions/commands/deleteme.rb @@ -0,0 +1,37 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Deleteme + class DeletemeCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + if event[:password] + if $manager.check_password(@player.name, event[:password]) + @player.output "This character #{@player.name} will no longer exist." + @player.quit + $manager.delete_player(@player.name) + else + @player.output "That password is incorrect. You are allowed to continue existing." + end + else + @player.output "To confirm your deletion, please enter your password:" + @player.io.echo_off + @player.expect do |password| + @player.io.echo_on + event[:password] = password + Generic.deleteme(event) + end + end + end + #Write something. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/drop.rb b/lib/aethyr/core/actions/commands/drop.rb new file mode 100644 index 0000000000000000000000000000000000000000..92e3f7166131c8ff6e071d6bb7bec72a68120182 --- /dev/null +++ b/lib/aethyr/core/actions/commands/drop.rb @@ -0,0 +1,41 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Drop + class DropCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = @player.inventory.find(event[:object]) + + if object.nil? + if response = @player.equipment.worn_or_wielded?(event[:object]) + @player.output response + else + @player.output "You have no #{event[:object]} to drop." + end + + return + end + + @player.inventory.remove(object) + + object.container = room.goid + room.add(object) + + event[:to_player] = "You drop #{object.name}." + event[:to_other] = "#{@player.name} drops #{object.name}." + event[:to_blind_other] = "You hear something hit the ground." + room.out_event(event) + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/agree.rb b/lib/aethyr/core/actions/commands/emotes/agree.rb new file mode 100644 index 0000000000000000000000000000000000000000..b0ba07405247d71595c96c048d348c7f7573c490 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/agree.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Agree + class AgreeCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You nod your head in agreement." + to_other "#{player.name} nods #{player.pronoun(:possessive)} head in agreement." + to_deaf_other event[:to_other] + end + + self_target do + to_player "You are in complete agreement with yourself." + to_other "#{player.name} nods at #{player.pronoun(:reflexive)}, apparently in complete agreement." + to_deaf_other event[:to_other] + end + + target do + to_player "You nod your head in agreement with #{event.target.name}." + to_target "#{player.name} nods #{player.pronoun(:possessive)} head in agreement with you." + to_other "#{player.name} nods #{player.pronoun(:possessive)} head in agreement with #{event.target.name}." + to_deaf_other event[:to_other] + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/back.rb b/lib/aethyr/core/actions/commands/emotes/back.rb new file mode 100644 index 0000000000000000000000000000000000000000..44288f084bb4ae4e2fab9ac1466fa6c3063d04af --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/back.rb @@ -0,0 +1,43 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Back + class BackCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "\"I'm back!\" you happily announce." + to_other "\"I'm back!\" #{player.name} happily announces to those nearby." + to_blind_other "Someone announces, \"I'm back!\"" + end + + self_target do + player.output "Hm? How do you do that?" + end + + target do + to_player "You happily announce your return to #{event.target.name}." + to_target "#{player.name} happily announces #{player.pronoun(:possessive)} return to you." + to_other "#{player.name} announces #{player.pronoun(:possessive)} return to #{event.target.name}." + to_blind_other "Someone says, \"I shall return shortly!\"" + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/blush.rb b/lib/aethyr/core/actions/commands/emotes/blush.rb new file mode 100644 index 0000000000000000000000000000000000000000..f0533fc01ac2c00a5262c0aa44bda5d6d457ffe1 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/blush.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Blush + class BlushCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You feel the blood rush to your cheeks and you look down, blushing." + to_other "#{player.name}'s face turns bright red as #{player.pronoun} looks down, blushing." + to_deaf_other event[:to_other] + end + + self_target do + to_player "You blush at your foolishness." + to_other "#{player.name} blushes at #{event.target.pronoun(:possessive)} foolishness." + to_deaf_other event[:to_other] + end + + target do + to_player "Your face turns red and you blush at #{event.target.name} uncomfortably." + to_target "#{player.name} blushes in your direction." + to_deaf_target event[:to_target] + to_other "#{player.name} blushes at #{event.target.name}, clearly uncomfortable." + to_deaf_other event[:to_other] + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/bow.rb b/lib/aethyr/core/actions/commands/emotes/bow.rb new file mode 100644 index 0000000000000000000000000000000000000000..d6dc5ee1bb7fd805b906f594b94332ac7eb651d4 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/bow.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Bow + class BowCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You bow deeply and respectfully." + to_other "#{player.name} bows deeply and respectfully." + to_deaf_other event[:to_other] + end + + self_target do + player.output "Huh?" + end + + target do + to_player "You bow respectfully towards #{event.target.name}." + to_target "#{player.name} bows respectfully before you." + to_other "#{player.name} bows respectfully towards #{event.target.name}." + to_deaf_other event[:to_other] + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/brb.rb b/lib/aethyr/core/actions/commands/emotes/brb.rb new file mode 100644 index 0000000000000000000000000000000000000000..0a2da882d94633dd307897c36b8c7d1ee29b0660 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/brb.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Brb + class BrbCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "\"I shall return shortly!\" you say to no one in particular." + to_other "#{player.name} says, \"I shall return shortly!\" to no one in particular." + to_blind_other "Someone says, \"I shall return shortly!\"" + end + + self_target do + player.output "Hm? How do you do that?" + end + + target do + to_player "You let #{event.target.name} know you will return shortly." + to_target "#{player.name} lets you know #{player.pronoun} will return shortly." + to_other "#{player.name} tells #{event.target.name} that #{player.pronoun} will return shortly." + to_blind_other "Someone says, \"I shall return shortly!\"" + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/bye.rb b/lib/aethyr/core/actions/commands/emotes/bye.rb new file mode 100644 index 0000000000000000000000000000000000000000..4f7b8652c9d8604eb807352edf90ff587b042a0a --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/bye.rb @@ -0,0 +1,42 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Bye + class ByeCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You say a hearty \"Goodbye!\" to those around you." + to_other "#{player.name} says a hearty \"Goodbye!\"" + end + + self_target do + player.output "Goodbye." + end + + target do + to_player "You say \"Goodbye!\" to #{event.target.name}." + to_target "#{player.name} says \"Goodbye!\" to you." + to_other "#{player.name} says \"Goodbye!\" to #{event.target.name}" + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/cheer.rb b/lib/aethyr/core/actions/commands/emotes/cheer.rb new file mode 100644 index 0000000000000000000000000000000000000000..9f89ad0e8add44c75092ed968386231c03b46ae2 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/cheer.rb @@ -0,0 +1,43 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Cheer + class CheerCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You throw your hands in the air and cheer wildly!" + to_other "#{player.name} throws #{player.pronoun(:possessive)} hands in the air as #{player.pronoun} cheers wildy!" + to_blind_other "You hear someone cheering." + end + + self_target do + player.output "Hm? How do you do that?" + end + + target do + to_player "Beaming at #{event.target.name}, you throw your hands up and cheer for #{event.target.pronoun(:objective)}." + to_target "Beaming at you, #{player.name} throws #{player.pronoun(:possessive)} hands up and cheers for you." + to_other "#{player.name} throws #{player.pronoun(:possessive)} hands up and cheers for #{event.target.name}." + to_blind_other "You hear someone cheering." + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/cry.rb b/lib/aethyr/core/actions/commands/emotes/cry.rb new file mode 100644 index 0000000000000000000000000000000000000000..1513198834db0437f1e04f06c6940eeb2bf0bf35 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/cry.rb @@ -0,0 +1,31 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Cry + class CryCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + default do + to_player "Tears run down your face as you cry pitifully." + to_other "Tears run down #{player.name}'s face as #{player.pronoun} cries pitifully." + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/curtsey.rb b/lib/aethyr/core/actions/commands/emotes/curtsey.rb new file mode 100644 index 0000000000000000000000000000000000000000..59662232d834bceac9c7c60c5041917a91b0f8ec --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/curtsey.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Curtsey + class CurtseyCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You perform a very graceful curtsey." + to_other "#{player.name} curtseys quite gracefully." + to_deaf_other event[:to_other] + end + + self_target do + player.output "Hm? How do you do that?" + end + + target do + to_player "You curtsey gracefully and respectfully towards #{event.target.name}." + to_target "#{player.name} curtseys gracefully and respectfully in your direction." + to_other "#{player.name} curtseys gracefully and respectfully towards #{event.target.name}." + to_deaf_other event[:to_other] + end + + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/eh.rb b/lib/aethyr/core/actions/commands/emotes/eh.rb new file mode 100644 index 0000000000000000000000000000000000000000..28d1dee869ae1d4773db636e435c018360c3c701 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/eh.rb @@ -0,0 +1,35 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Eh + class EhCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + make_emote event, player, room do + target do + to_player "After giving #{event.target.name} a cursory glance, you emit an unimpressed, 'Eh.'" + to_other "#{player.name} gives #{event.target.name} a cursory glance and then emits an unimpressed, 'Eh.'" + to_target "#{player.name} gives you a cursory glance and then emits an unimpressed, 'Eh.'" + end + + no_target do + to_player "After a brief consideration, you give an unimpressed, 'Eh.'" + to_other "#{player.name} appears to consider for a moment before giving an unimpressed, 'Eh.'" + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/emote.rb b/lib/aethyr/core/actions/commands/emotes/emote.rb new file mode 100644 index 0000000000000000000000000000000000000000..2a4921897ae2ab9b359f5f53c95c38aeeb01bfe3 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/emote.rb @@ -0,0 +1,58 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Emote + class EmoteCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + action = event[:show].strip + + unless ['!', '.', '?', '"'].include? action[-1..-1] + action << '.' + end + + if action =~ /\$me[^a-zA-Z]/i + action.gsub!(/\$me/i, player.name) + action[0,1] = action[0,1].capitalize + show = action + elsif action.include? '$' + people = [] + action.gsub!(/\$(\w+)/) do |name| + target = room.find($1) + people << target unless target.nil? + target ? target.name : 'no one' + end + + people.each do |person| + out = action.gsub(person.name, 'you') + person.output("#{player.name} #{out}", message_type = :chat) unless person.can? :blind and person.blind? + end + + room.output("#{player.name} #{action}", player, *people) + player.output("You emote: #{player.name} #{action}") + else + show = "#{player.name} #{action}" + end + + if show + event[:message_type] = :chat + event[:to_player] = "You emote: #{show}" + event[:to_other] = show + room.out_event event + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/emote_action.rb b/lib/aethyr/core/actions/commands/emotes/emote_action.rb new file mode 100644 index 0000000000000000000000000000000000000000..eeb19e6a76b8c0e941b2e1ff48d61d678f6fa0bb --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/emote_action.rb @@ -0,0 +1,149 @@ +require 'aethyr/core/actions/command_action' + +module Aethyr + module Extend + class EmoteAction < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + protected + + #Run an emote. + def make_emote event, player, room, &block + g = GenericEmote.new(event, player, room) + g.instance_eval(&block) + if g.return_event && (g.return_event.respond_to? :has_key?) + g.set_post #add postfix + log "Doing event" , Logger::Ultimate + room.out_event g.return_event + end + end + + + #Provides little DSL to easily create emotes. + class GenericEmote + + attr_reader :return_event + + def initialize(event, player, room) + @event = event.dup + @event[:message_type] = :chat + @event[:player] = player + @player = player + @room = room + @post = event[:post] + @object = nil + @return_event = nil + find_target + end + + #If there is no target, return the given block. + def no_target + return if @return_event + + if @object.nil? + @return_event = yield + end + end + + #If the target is the player, return the given block. + def self_target + return if @return_event + + if @object == @player + @return_event = yield + end + end + + #If there is a target, return the given block. + def target + return if @return_event + + unless @object.nil? + @return_event = yield + end + end + + #If nothing else matches, return the given block. + def default + @return_event = yield + end + + #Provide output to show player. + def to_player output + @event[:to_player] = output + @event + end + + #Provide output to show others. + def to_other output + @event[:to_other] = output + @event + end + + #Provide output to show target. + def to_target output + @event[:to_target] = output + @event + end + + #Provide output to show blind others. + def to_blind_other output + @event[:to_blind_other] = output + @event + end + + #Provide output to show deaf others. + def to_deaf_other output + @event[:to_deaf_other] = output + @event + end + + #Provide output to show blind target. + def to_blind_target output + @event[:to_blind_target] = output + @event + end + + #Provide output to show deaf target. + def to_deaf_target output + @event[:to_deaf_target] = output + @event + end + + #Appends suffix to emote. + def set_post + return if not @post + [:to_player, :to_other, :to_target, :to_blind_other, :to_blind_target, :to_deaf_other, :to_deaf_target].each do |t| + if @return_event[t] + if @return_event[t][-1,1] == "." + @return_event[t][-1] = "" + end + + if @post[0,1] == "," + @return_event[t] << @post + else + @return_event[t] << " " << @post + end + + unless ["!", "?", ".", "\"", "'"].include? @post[-1,1] + @return_event[t] << "." + end + end + end + end + + private + + #Find target for emote. + def find_target + if @object.nil? and @event[:object] + @object = @room.find(@event[:object]) || @player.search_inv(@event[:object]) + @event[:target] = @object + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/er.rb b/lib/aethyr/core/actions/commands/emotes/er.rb new file mode 100644 index 0000000000000000000000000000000000000000..8c095a6deac26fe745c7248074bd8264e617daaa --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/er.rb @@ -0,0 +1,35 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Er + class ErCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + make_emote event, player, room do + no_target do + to_player "With a look of uncertainty, you say, \"Er...\"" + to_other "With a look of uncertainty, #{player.name} says, \"Er...\"" + end + + target do + to_player "Looking at #{target.name} uncertainly, you say, \"Er...\"" + to_other "Looking at #{target.name} uncertainly, #{player.name} says, \"Er...\"" + to_target "Looking at you uncertainly, #{player.name} says, \"Er...\"" + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/ew.rb b/lib/aethyr/core/actions/commands/emotes/ew.rb new file mode 100644 index 0000000000000000000000000000000000000000..a0659611da2d936103fdfc8c87524a541845d028 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/ew.rb @@ -0,0 +1,45 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Ew + class EwCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "\"Ewww!\" you exclaim, looking disgusted." + to_other "#{player.name} exclaims, \"Eww!!\" and looks disgusted." + to_deaf_other "#{player.name} looks disgusted." + to_blind_other "Somone exclaims, \"Eww!!\"" + end + + self_target do + player.output "You think you are digusting?" + end + + target do + to_player "You glance at #{event.target.name} and say \"Ewww!\"" + to_target "#{player.name} glances in your direction and says, \"Ewww!\"" + to_deaf_other "#{player.name} gives #{event.target.name} a disgusted look." + to_blind_other "Somone exclaims, \"Eww!!\"" + to_other "#{player.name} glances at #{event.target.name}, saying \"Ewww!\"" + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/frown.rb b/lib/aethyr/core/actions/commands/emotes/frown.rb new file mode 100644 index 0000000000000000000000000000000000000000..fe36d16572a8ad77825b43901986b063a28e1621 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/frown.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Frown + class FrownCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + no_target do + to_player "The edges of your mouth turn down as you frown." + to_other "The edges of #{player.name}'s mouth turn down as #{player.pronoun} frowns." + to_deaf_other event[:to_other] + end + + self_target do + to_player "You frown sadly at yourself." + to_other "#{player.name} frowns sadly at #{event.target.pronoun(:reflexive)}." + to_deaf_other event[:to_other] + end + + target do + to_player "You frown at #{event.target.name} unhappily." + to_target "#{player.name} frowns at you unhappily." + to_deaf_target event[:to_target] + to_other "#{player.name} frowns at #{event.target.name} unhappily." + to_deaf_other event[:to_other] + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/grin.rb b/lib/aethyr/core/actions/commands/emotes/grin.rb new file mode 100644 index 0000000000000000000000000000000000000000..ae688e5ba3d1ef2bb0c55996f32453d29b0381ba --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/grin.rb @@ -0,0 +1,47 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Grin + class GrinCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player 'You grin widely, flashing all your teeth.' + to_other "#{player.name} grins widely, flashing all #{player.pronoun(:possessive)} teeth." + to_deaf_other event[:to_other] + end + + self_target do + to_player "You grin madly at yourself." + to_other "#{player.name} grins madly at #{event.target.pronoun(:reflexive)}." + to_deaf_other event[:to_other] + end + + target do + to_player "You give #{event.target.name} a wide grin." + to_target "#{player.name} gives you a wide grin." + to_deaf_target event[:to_target] + to_other "#{player.name} gives #{event.target.name} a wide grin." + to_deaf_other event[:to_other] + end + + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/hi.rb b/lib/aethyr/core/actions/commands/emotes/hi.rb new file mode 100644 index 0000000000000000000000000000000000000000..56364f4d6bedee88cfb87bbf3d301ff1843b481c --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/hi.rb @@ -0,0 +1,42 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Hi + class HiCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "\"Hi!\" you greet those around you." + to_other "#{player.name} greets those around with a \"Hi!\"" + end + + self_target do + player.output "Hi." + end + + target do + to_player "You say \"Hi!\" in greeting to #{event.target.name}." + to_target "#{player.name} greets you with a \"Hi!\"" + to_other "#{player.name} greets #{event.target.name} with a hearty \"Hi!\"" + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/hm.rb b/lib/aethyr/core/actions/commands/emotes/hm.rb new file mode 100644 index 0000000000000000000000000000000000000000..f363f746388ffa6f2aefdcc520f1eb009de57700 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/hm.rb @@ -0,0 +1,43 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Hm + class HmCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_other "#{player.name} purses #{player.pronoun(:possessive)} lips thoughtfully and says, \"Hmmm...\"" + to_player "You purse your lips thoughtfully and say, \"Hmmm...\"" + end + + self_target do + to_other "#{player.name} looks down at #{player.pronoun(:reflexive)} and says, \"Hmmm...\"" + to_player "You look down at yourself and say, \"Hmmm...\"" + end + + target do + to_other "#{player.name} purses #{player.pronoun(:possessive)} lips as #{player.pronoun} looks thoughtfully at #{event.target.name} and says, \"Hmmm...\"" + to_player "You purse your lips as you look thoughtfully at #{event.target.name} and say, \"Hmmm...\"" + to_target "#{player.name} purses #{player.pronoun(:possessive)} lips as #{player.pronoun} looks thoughtfully at you and says, \"Hmmm...\"" + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/hug.rb b/lib/aethyr/core/actions/commands/emotes/hug.rb new file mode 100644 index 0000000000000000000000000000000000000000..65c86a4625137e0f9afb875ca6048a7ef608543f --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/hug.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Hug + class HugCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + player.output "Who are you trying to hug?" + end + + self_target do + to_player 'You wrap your arms around yourself and give a tight squeeze.' + to_other "#{player.name} gives #{player.pronoun(:reflexive)} a tight squeeze." + to_deaf_other event[:to_other] + end + + target do + to_player "You give #{event.target.name} a great big hug." + to_target "#{player.name} gives you a great big hug." + to_other "#{player.name} gives #{event.target.name} a great big hug." + to_blind_target "Someone gives you a great big hug." + to_deaf_other event[:to_other] + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/huh.rb b/lib/aethyr/core/actions/commands/emotes/huh.rb new file mode 100644 index 0000000000000000000000000000000000000000..c70eac40737baa864e7e42aa5d66bbb58a8b317b --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/huh.rb @@ -0,0 +1,41 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Huh + class HuhCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + make_emote event, player, room do + + no_target do + to_player "\"Huh?\" you ask, confused." + to_other "#{player.name} ask, \"Huh?\" and looks confused." + end + + self_target do + player.output "Well, huh!" + end + + target do + to_player "\"Huh?\" you ask #{event.target.name}." + to_target "#{player.name} asks, \"Huh?\"" + to_other "#{player.name} asks #{event.target.name}, \"Huh?\"" + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/laugh.rb b/lib/aethyr/core/actions/commands/emotes/laugh.rb new file mode 100644 index 0000000000000000000000000000000000000000..7917322ce13ec0c4c88cd9a815749f6143a117ad --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/laugh.rb @@ -0,0 +1,48 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Laugh + class LaughCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + self_target do + to_player "You laugh heartily at yourself." + to_other "#{player.name} laughs heartily at #{player.pronoun(:reflexive)}." + to_blind_other "Someone laughs heartily." + end + + target do + to_player "You laugh at #{event.target.name}." + to_target "#{player.name} laughs at you." + to_other "#{player.name} laughs at #{event.target.name}" + to_blind_target "Someone laughs in your direction." + to_blind_other "You hear someone laughing." + end + + no_target do + to_player "You laugh." + to_other "#{player.name} laughs." + to_blind_other "You hear someone laughing." + to_deaf_other "You see #{player.name} laugh." + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/no.rb b/lib/aethyr/core/actions/commands/emotes/no.rb new file mode 100644 index 0000000000000000000000000000000000000000..5fa862c692962c7f8415d6d5814312b87bf46e03 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/no.rb @@ -0,0 +1,41 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module No + class NoCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + make_emote event, player, room do + no_target do + to_player "\"No,\" you say, shaking your head." + to_other "#{player.name} says, \"No\" and shakes #{player.pronoun(:possessive)} head." + end + self_target do + to_player "You shake your head negatively in your direction. You are kind of strange." + to_other "#{player.name} shakes #{player.pronoun(:possessive)} head at #{player.pronoun(:reflexive)}." + to_deaf_other event[:to_other] + end + target do + to_player "You shake your head, disagreeing with #{event.target.name}." + to_target "#{player.name} shakes #{player.pronoun(:possessive)} head in your direction, disagreeing." + to_other "#{player.name} shakes #{player.pronoun(:possessive)} head in disagreement with #{event.target.name}." + to_deaf_other event[:to_other] + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/nod.rb b/lib/aethyr/core/actions/commands/emotes/nod.rb new file mode 100644 index 0000000000000000000000000000000000000000..63c5c31b71ceb5c04471d5587cfd0840061762ff --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/nod.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Nod + class NodCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You nod your head." + to_other "#{player.name} nods #{player.pronoun(:possessive)} head." + to_deaf_other event[:to_other] + end + + self_target do + to_player 'You nod to yourself thoughtfully.' + to_other "#{player.name} nods to #{player.pronoun(:reflexive)} thoughtfully." + to_deaf_other event[:to_other] + end + + target do + + to_player "You nod your head towards #{event.target.name}." + to_target "#{player.name} nods #{player.pronoun(:possessive)} head towards you." + to_other "#{player.name} nods #{player.pronoun(:possessive)} head towards #{event.target.name}." + to_deaf_other event[:to_other] + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/pet.rb b/lib/aethyr/core/actions/commands/emotes/pet.rb new file mode 100644 index 0000000000000000000000000000000000000000..0759df19107ec784bd3e2db37bec593ac1e69704 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/pet.rb @@ -0,0 +1,45 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Pet + class PetCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + player.output "Who are you trying to pet?" + end + + self_target do + to_player 'You pet yourself on the head in a calming manner.' + to_other "#{player.name} pets #{player.pronoun(:reflexive)} on the head in a calming manner." + to_deaf_other "#{player.name} pets #{player.pronoun(:reflexive)} on the head in a calming manner." + end + + target do + to_player "You pet #{event.target.name} affectionately." + to_target "#{player.name} pets you affectionately." + to_deaf_target event[:to_target] + to_blind_target "Someone pets you affectionately." + to_other "#{player.name} pets #{event.target.name} affectionately." + to_deaf_other event[:to_other] + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/poke.rb b/lib/aethyr/core/actions/commands/emotes/poke.rb new file mode 100644 index 0000000000000000000000000000000000000000..c42b94a6828bd9c21b5e3f90fc59c6a69f870225 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/poke.rb @@ -0,0 +1,45 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Poke + class PokeCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + player.output "Who are you trying to poke?" + end + + self_target do + to_player "You poke yourself in the eye. 'Ow!'" + to_other "#{player.name} pokes #{player.pronoun(:reflexive)} in the eye." + to_deaf_other event[:to_other] + end + + target do + to_player "You poke #{event.target.name} playfully." + to_target "#{player.name} pokes you playfully." + to_blind_target "Someone pokes you playfully." + to_deaf_target event[:to_target] + to_other "#{player.name} pokes #{event.target.name} playfully." + to_deaf_other event[:to_other] + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/ponder.rb b/lib/aethyr/core/actions/commands/emotes/ponder.rb new file mode 100644 index 0000000000000000000000000000000000000000..b01c1f829ee5fe97b1b56ccc207cefc36f6c207b --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/ponder.rb @@ -0,0 +1,45 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Ponder + class PonderCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You ponder that idea for a moment." + to_other "#{player.name} looks thoughtful as #{player.pronoun} ponders a thought." + to_deaf_other event[:to_other] + end + + self_target do + to_player "You look down in deep thought at your navel." + to_other "#{player.name} looks down thoughtfully at #{player.pronoun(:possessive)} navel." + to_deaf_other event[:to_other] + end + + target do + to_player "You give #{event.target.name} a thoughtful look as you reflect and ponder." + to_target "#{player.name} gives you a thoughtful look and seems to be reflecting upon something." + to_other "#{player.name} gives #{event.target.name} a thoughtful look and appears to be absorbed in reflection." + to_deaf_other event[:to_other] + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/shrug.rb b/lib/aethyr/core/actions/commands/emotes/shrug.rb new file mode 100644 index 0000000000000000000000000000000000000000..1d4ab619b5888c968318f742ad279f04352d41cb --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/shrug.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Shrug + class ShrugCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You shrug your shoulders." + to_other "#{player.name} shrugs #{player.pronoun(:possessive)} shoulders." + to_deaf_other event[:to_other] + end + + self_target do + player.output "Don't just shrug yourself off like that!" + + end + + target do + to_player "You give #{event.target.name} a brief shrug." + to_target "#{player.name} gives you a brief shrug." + to_other "#{player.name} gives #{event.target.name} a brief shrug." + to_deaf_other event[:to_other] + to_deaf_target event[:to_target] + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/sigh.rb b/lib/aethyr/core/actions/commands/emotes/sigh.rb new file mode 100644 index 0000000000000000000000000000000000000000..fcf3e9bd61a53d5368ab69bed699c57ced2c83f0 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/sigh.rb @@ -0,0 +1,43 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Sigh + class SighCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You exhale, sighing deeply." + to_other "#{player.name} breathes out a deep sigh." + end + + self_target do + to_player "You sigh at your misfortunes." + to_other "#{player.name} sighs at #{player.pronoun(:possessive)} own misfortunes." + end + + target do + to_player "You sigh in #{event.target.name}'s general direction." + to_target "#{player.name} heaves a sigh in your direction." + to_other "#{player.name} sighs heavily in #{event.target.name}'s direction." + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/skip.rb b/lib/aethyr/core/actions/commands/emotes/skip.rb new file mode 100644 index 0000000000000000000000000000000000000000..d80f5f399b1dcd7442aea332d6dc03ca5f4484b8 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/skip.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Skip + class SkipCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You skip around cheerfully." + to_other "#{player.name} skips around cheerfully." + to_deaf_other "#{player.name} skips around cheerfully." + end + + self_target do + player.output 'How?' + end + + target do + to_player "You skip around #{event.target.name} cheerfully." + to_target "#{player.name} skips around you cheerfully." + to_other "#{player.name} skips around #{event.target.name} cheerfully." + to_deaf_other "#{player.name} skips around #{event.target.name} cheerfully." + end + + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/smile.rb b/lib/aethyr/core/actions/commands/emotes/smile.rb new file mode 100644 index 0000000000000000000000000000000000000000..7c0cca965e33226e349c060a994fc70b0adf0be8 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/smile.rb @@ -0,0 +1,42 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Smile + class SmileCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + self_target do + to_player "You smile happily at yourself." + to_other "#{player.name} smiles at #{player.pronoun(:reflexive)} sillily." + end + + target do + to_player "You smile at #{event.target.name} kindly." + to_target "#{player.name} smiles at you kindly." + to_other "#{player.name} smiles at #{event.target.name} kindly." + end + + no_target do + to_player "You smile happily." + to_other "#{player.name} smiles happily." + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/snicker.rb b/lib/aethyr/core/actions/commands/emotes/snicker.rb new file mode 100644 index 0000000000000000000000000000000000000000..463daf548993c1b524dffbb0db16b086288b87bb --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/snicker.rb @@ -0,0 +1,43 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Snicker + class SnickerCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You snicker softly to yourself." + to_other "You hear #{player.name} snicker softly." + to_blind_other "You hear someone snicker softly." + end + + self_target do + player.output "What are you snickering about?" + end + + target do + to_player "You snicker at #{event.target.name} under your breath." + to_target "#{player.name} snickers at you under #{player.pronoun(:possessive)} breath." + to_other "#{player.name} snickers at #{event.target.name} under #{player.pronoun(:possessive)} breath." + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/uh.rb b/lib/aethyr/core/actions/commands/emotes/uh.rb new file mode 100644 index 0000000000000000000000000000000000000000..1c6af37f60c3169313ab699d36f824832844220b --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/uh.rb @@ -0,0 +1,35 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Uh + class UhCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + make_emote event, player, room do + no_target do + to_player "\"Uh...\" you say, staring blankly." + to_other "With a blank stare, #{player.name} says, \"Uh...\"" + end + + target do + to_player "With a blank stare at #{target.name}, you say, \"Uh...\"" + to_other "With a blank stare at #{target.name}, #{player.name} says, \"Uh...\"" + to_target "Staring blankly at you, #{player.name} says, \"Uh...\"" + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/wave.rb b/lib/aethyr/core/actions/commands/emotes/wave.rb new file mode 100644 index 0000000000000000000000000000000000000000..fd0fa274755175875191e30242c4661db73d35d0 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/wave.rb @@ -0,0 +1,41 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Wave + class WaveCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You wave goodbye to everyone." + to_other "#{player.name} waves goodbye to everyone." + end + + self_target do + player.output "Waving at someone?" + end + + target do + to_player "You wave farewell to #{event.target.name}." + to_target "#{player.name} waves farewell to you." + to_other "#{player.name} waves farewell to #{event.target.name}." + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/yawn.rb b/lib/aethyr/core/actions/commands/emotes/yawn.rb new file mode 100644 index 0000000000000000000000000000000000000000..6a9f5d2f41aaf34ae434ddc1bc50a61b2b980eff --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/yawn.rb @@ -0,0 +1,45 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Yawn + class YawnCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + make_emote event, player, room do + + no_target do + to_player "You open your mouth in a wide yawn, then exhale loudly." + to_other "#{player.name} opens #{player.pronoun(:possessive)} mouth in a wide yawn, then exhales loudly." + end + + self_target do + to_player "You yawn at how boring you are." + to_other "#{player.name} yawns at #{player.pronoun(:reflexive)}." + to_deaf_other event[:to_other] + end + + target do + to_player "You yawn at #{event.target.name}, bored out of your mind." + to_target "#{player.name} yawns at you, finding you boring." + to_other "#{player.name} yawns at how boring #{event.target.name} is." + to_deaf_other event[:to_other] + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/emotes/yes.rb b/lib/aethyr/core/actions/commands/emotes/yes.rb new file mode 100644 index 0000000000000000000000000000000000000000..46a9689bbd25839ca6197b07076091a7f09b3d57 --- /dev/null +++ b/lib/aethyr/core/actions/commands/emotes/yes.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/commands/emotes/emote_action" + +module Aethyr + module Core + module Actions + module Yes + class YesCommand < Aethyr::Extend::EmoteAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + make_emote event, player, room do + + no_target do + to_player "\"Yes,\" you say, nodding." + to_other "#{player.name} says, \"Yes\" and nods." + end + + self_target do + to_player "You nod in agreement with yourself." + to_other "#{player.name} nods at #{player.pronoun(:reflexive)} strangely." + to_deaf_other event[:to_other] + end + + target do + to_player "You nod in agreement with #{event.target.name}." + to_target "#{player.name} nods in your direction, agreeing." + to_other "#{player.name} nods in agreement with #{event.target.name}." + to_deaf_other event[:to_other] + end + end + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/feel.rb b/lib/aethyr/core/actions/commands/feel.rb new file mode 100644 index 0000000000000000000000000000000000000000..7efcb739242e26ace1ba59313440fefd37e8cada --- /dev/null +++ b/lib/aethyr/core/actions/commands/feel.rb @@ -0,0 +1,40 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Feel + class FeelCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = @player.search_inv(event[:target]) || room.find(event[:target]) + + if object == @player or event[:target] == "me" + @player.output "You feel fine." + return + elsif object.nil? + @player.output "What would you like to feel?" + return + end + + event[:target] = object + event[:to_player] = "You reach out your hand and gingerly feel #{object.name}. " + if object.info.texture.nil? or object.info.texture == "" + event[:to_player] << "#{object.pronoun(:possessive).capitalize} texture is what you would expect." + else + event[:to_player] << object.info.texture + end + event[:to_target] = "#{@player.name} reaches out a hand and gingerly touches you." + event[:to_other] = "#{@player.name} reaches out #{@player.pronoun(:possessive)} hand and touches #{object.name}." + room.out_event event + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/fill.rb b/lib/aethyr/core/actions/commands/fill.rb new file mode 100644 index 0000000000000000000000000000000000000000..a7301995600979682fb5750bc8a7e9d91180ae31 --- /dev/null +++ b/lib/aethyr/core/actions/commands/fill.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Fill + class FillCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = @player.search_inv(event[:object]) || room.find(event[:object]) + from = @player.search_inv(event[:from]) || room.find(event[:from]) + + if object.nil? + @player.output("What would you like to fill?") + return + elsif not object.is_a? LiquidContainer + @player.output("You cannot fill #{object.name} with liquids.") + return + elsif from.nil? + @player.output "There isn't any #{event[:from]} around here." + return + elsif not from.is_a? LiquidContainer + @player.output "You cannot fill #{object.name} from #{from.name}." + return + elsif from.empty? + @player.output "That #{object.generic} is empty." + return + elsif object.full? + @player.output("That #{object.generic} is full.") + return + elsif object == from + @player.output "Quickly flipping #{object.name} upside-down then upright again, you manage to fill it from itself." + return + end + end + #Display time. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/gait.rb b/lib/aethyr/core/actions/commands/gait.rb new file mode 100644 index 0000000000000000000000000000000000000000..4b97d7c8a84dc0bdaffa7398569585f3f7f04071 --- /dev/null +++ b/lib/aethyr/core/actions/commands/gait.rb @@ -0,0 +1,41 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Gait + class GaitCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:phrase].nil? + if player.info.entrance_message + player.output "When you move, it looks something like:", true + player.output player.exit_message("north") + else + player.output "You are walking normally." + end + elsif event[:phrase].downcase == "none" + player.info.entrance_message = nil + player.info.exit_message = nil + player.output "You will now walk normally." + else + player.info.entrance_message = "#{event[:phrase]}, !name comes in from !direction." + player.info.exit_message = "#{event[:phrase]}, !name leaves to !direction." + + player.output "When you move, it will now look something like:", true + player.output player.exit_message("north") + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/commands/get.rb b/lib/aethyr/core/actions/commands/get.rb similarity index 64% rename from lib/aethyr/core/commands/get.rb rename to lib/aethyr/core/actions/commands/get.rb index dcf6b58e1e0708f6666f5fdf3dadd63f9d6de7cf..9788ebe898006c7c0646dede6bdb10b2f538b468 100644 --- a/lib/aethyr/core/commands/get.rb +++ b/lib/aethyr/core/actions/commands/get.rb @@ -1,51 +1,16 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" +require "aethyr/core/actions/command_action" module Aethyr module Core - module Commands + module Actions module Get - class GetHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["get", "grab", "take"]) + class GetCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(GetHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^(get|grab|take)\s+((\w+|\s)*)(\s+from\s+(\w+))/i - action({ :object => $2.strip, :from => $5 }) - when /^(get|grab|take)\s+(.*)$/i - action({ :object => $2.strip }) - when /^help (get|grab|take)$/i - action_help({}) - end - end - - private - def action_help(event) - @player.output <<'EOF' -Command: Get -Command: Grab -Command: Take -Syntax: GET [object] -Syntax: GRAB [object' -Syntax: TAKE [object] -Pick up an object and put it in your inventory. - -See also: GIVE - -EOF - end - - #Gets (or takes) an object and puts it in the player's inventory. - def action(event) + def action + event = @data room = $manager.get_object(@player.container) if event[:from].nil? object = $manager.find(event[:object], room) @@ -106,9 +71,7 @@ EOF end end end - - Aethyr::Extend::HandlerRegistry.register_handler(GetHandler) end end end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/commands/give.rb b/lib/aethyr/core/actions/commands/give.rb similarity index 51% rename from lib/aethyr/core/commands/give.rb rename to lib/aethyr/core/actions/commands/give.rb index e6264467906036e29371dc029e77d48ce04f09e5..b4ed399f640a06ed157ee316f2fa7fe87f8b729e 100644 --- a/lib/aethyr/core/commands/give.rb +++ b/lib/aethyr/core/actions/commands/give.rb @@ -1,47 +1,16 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" +require "aethyr/core/actions/command_action" module Aethyr module Core - module Commands + module Actions module Give - class GiveHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["give"]) + class GiveCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(GiveHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^give\s+((\w+\s*)*)\s+to\s+(\w+)/i - action({ :item => $2.strip, :to => $3 }) - when /^help give$/i - action_help({}) - end - end - - private - def action_help(event) - @player.output <<'EOF' -Command: Give -Syntax: GIVE [object] TO [person] - -Give an object to someone else. Beware, though, they may not want to give it back. -At the moment, the object must be in your inventory. - -See also: GET - -EOF - end - - #Gives an item to someone else. - def action(event) + def action + event = @data room = $manager.get_object(@player.container) item = player.inventory.find(event[:item]) @@ -76,9 +45,7 @@ EOF room.out_event(event) end end - - Aethyr::Extend::HandlerRegistry.register_handler(GiveHandler) end end end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/actions/commands/health.rb b/lib/aethyr/core/actions/commands/health.rb new file mode 100644 index 0000000000000000000000000000000000000000..d29ef0d36993175fd6f1a5bdd499aca434ba6a2a --- /dev/null +++ b/lib/aethyr/core/actions/commands/health.rb @@ -0,0 +1,21 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Health + class HealthCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + @player.output "You are #{@player.health}." + end + #Display hunger. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/inventory.rb b/lib/aethyr/core/actions/commands/inventory.rb new file mode 100644 index 0000000000000000000000000000000000000000..b3b639bf61f4872d412cb283cb42d3f168faacff --- /dev/null +++ b/lib/aethyr/core/actions/commands/inventory.rb @@ -0,0 +1,20 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Inventory + class InventoryCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + player.output(player.show_inventory) + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/issue.rb b/lib/aethyr/core/actions/commands/issue.rb new file mode 100644 index 0000000000000000000000000000000000000000..a0396785f3d87d046c08c7801fd9979dd3d5f19a --- /dev/null +++ b/lib/aethyr/core/actions/commands/issue.rb @@ -0,0 +1,77 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Issue + class IssueCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + case event[:option] + when "new" + issue = Issues.add_issue event[:itype], player.name, event[:value] + player.output "Thank you for submitting #{event[:itype]} ##{issue[:id]}." + when "add" + if not event[:issue_id] + player.output "Please specify a #{event[:itype]} number." + else + denied = Issues.check_access event[:itype], event[:issue_id], player + if denied + player.output denied + else + player.output Issues.append_issue(event[:itype], event[:issue_id], player.name, event[:value]) + end + end + when "del" + if not event[:issue_id] + player.output "Please specify a #{event[:itype]} number." + else + denied = Issues.check_access event[:itype], event[:issue_id], player + if denied + player.output denied + else + player.output Issues.delete_issue(event[:itype], event[:issue_id]) + end + end + when "list" + if player.admin + list = Issues.list_issues event[:itype] + else + list = Issues.list_issues event[:itype], player.name + end + if list.empty? + player.output "No #{event[:itype]}s to list." + else + player.output list + end + when "show" + if not event[:issue_id] + player.output "Please specify a #{event[:itype]} number." + else + denied = Issues.check_access event[:itype], event[:issue_id], player + if denied + player.output denied + else + player.output Issues.show_issue(event[:itype], event[:issue_id]) + end + end + when "status" + if not player.admin + player.output "Only administrators may change a #{event[:itype]}'s status." + elsif not event[:issue_id] + player.output "Please specify a #{event[:itype]} number." + else + player.output Issues.set_status(event[:itype], event[:issue_id], player.name, event[:value]) + end + + end + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/kick.rb b/lib/aethyr/core/actions/commands/kick.rb new file mode 100644 index 0000000000000000000000000000000000000000..3f1c1a55e4cd4308d103ed4a74ca1f70c670c073 --- /dev/null +++ b/lib/aethyr/core/actions/commands/kick.rb @@ -0,0 +1,56 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Kick + class KickCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + return if not Combat.ready? player + + target = (event.target && room.find(event.target)) || room.find(player.last_target) + + if target.nil? + player.output "Who are you trying to attack?" + return + else + return unless Combat.valid_target? player, target + end + + player.last_target = target.goid + + event.target = target + + event[:to_other] = "#{player.name} kicks #{player.pronoun(:possessive)} foot out at #{target.name}." + event[:to_target] = "#{player.name} kicks #{player.pronoun(:possessive)} foot at you." + event[:to_player] = "You balance carefully and kick your foot out towards #{target.name}." + event[:blockable] = true + + player.balance = false + player.info.in_combat = true + target.info.in_combat = true + + room.out_event event + + event[:action] = :martial_hit + event[:combat_action] = :kick + event[:to_other] = "#{player.name} kicks #{target.name} with considerable violence." + event[:to_target] = "#{player.name} kicks you rather violently." + event[:to_player] = "Your kick makes good contact with #{target.name}." + + Combat.future_event event + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/latest_news.rb b/lib/aethyr/core/actions/commands/latest_news.rb new file mode 100644 index 0000000000000000000000000000000000000000..04fc83254a3e06c9a2fb77757921b6b0dd432099 --- /dev/null +++ b/lib/aethyr/core/actions/commands/latest_news.rb @@ -0,0 +1,39 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module LatestNews + class LatestNewsCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + board = find_board(event, room) + + if board.nil? + player.output "There do not seem to be any postings here." + return + end + + if not board.is_a? Newsboard + log board.class + end + + offset = event[:offset] || 0 + wordwrap = player.word_wrap || 100 + limit = event[:limit] || player.page_height + + player.output board.list_latest(wordwrap, offset, limit) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/list_unread.rb b/lib/aethyr/core/actions/commands/list_unread.rb new file mode 100644 index 0000000000000000000000000000000000000000..13078688d303592f2d581a15ef5f5c7234a5d127 --- /dev/null +++ b/lib/aethyr/core/actions/commands/list_unread.rb @@ -0,0 +1,35 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module ListUnread + class ListUnreadCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + board = find_board(event, room) + + if board.nil? + player.output "There do not seem to be any postings here." + return + end + + if player.info.boards.nil? + player.info.boards = {} + end + + player.output board.list_since(player.info.boards[board.goid], player.word_wrap) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/listen.rb b/lib/aethyr/core/actions/commands/listen.rb new file mode 100644 index 0000000000000000000000000000000000000000..7d7fd25525774e422192cedd8b2a819c64f50f09 --- /dev/null +++ b/lib/aethyr/core/actions/commands/listen.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Listen + class ListenCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + if event[:target].nil? + event[:target] = room + if room.info.sound + event[:to_player] = "You listen carefully. #{room.info.sound}." + else + event[:to_player] = "You listen carefully but hear nothing unusual." + end + event[:to_other] = "A look of concentration forms on #{@player.name}'s face as #{@player.pronoun} listens intently." + room.out_event event + return + end + + object = @player.search_inv(event[:target]) || room.find(event[:target]) + + if object == @player or event[:target] == "me" + @player.output "Listening quietly, you can faintly hear your pulse." + return + elsif object.nil? + @player.output "What would you like to listen to?" + return + end + + event[:target] = object + event[:to_player] = "You bend your head towards #{object.name}. " + if object.info.sound.nil? or object.info.sound == "" + event[:to_player] << "#{object.pronoun.capitalize} emits no unusual sounds." + else + event[:to_player] << object.info.sound + end + event[:to_target] = "#{@player.name} listens to you carefully." + event[:to_other] = "#{@player.name} bends #{@player.pronoun(:possessive)} head towards #{object.name} and listens." + room.out_event event + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/lock.rb b/lib/aethyr/core/actions/commands/lock.rb new file mode 100644 index 0000000000000000000000000000000000000000..a0d564f8d4221e788d367c72503fdd5b43fbc52e --- /dev/null +++ b/lib/aethyr/core/actions/commands/lock.rb @@ -0,0 +1,66 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Lock + class LockCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = @player.search_inv(event[:object]) || room.find(event[:object]) + + if object.nil? + @player.output('Lock what?') + return + elsif not object.can? :lock or not object.lockable? + @player.output('That object cannot be locked.') + return + elsif object.locked? + @player.output("#{object.name} is already locked.") + return + end + + has_key = false + object.keys.each do |key| + if @player.inventory.include? key + has_key = key + break + end + end + + if has_key or @player.admin + status = object.lock(has_key, @player.admin) + if status + event[:to_player] = "You lock #{object.name}." + event[:to_other] = "#{@player.name} locks #{object.name}." + event[:to_blind_other] = "You hear the click of a lock." + + room.out_event(event) + + if object.is_a? Door and object.connected? + other_side = $manager.find object.connected_to + other_side.lock(has_key) + other_room = $manager.find other_side.container + o_event = event.dup + event[:to_other] = "#{other_side.name} locks from the other side." + event[:to_blind_other] = "You hear the click of a lock." + other_room.out_event(event) + end + else + @player.output("You are unable to lock that #{object.name}.") + end + else + @player.output("You do not have the key to that #{object.name}.") + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/commands/look.rb b/lib/aethyr/core/actions/commands/look.rb similarity index 69% rename from lib/aethyr/core/commands/look.rb rename to lib/aethyr/core/actions/commands/look.rb index 5b3acaf27437dc2434699781be331618a72885e5..c3b17950349447d74c0db04daf88be814af4996e 100644 --- a/lib/aethyr/core/commands/look.rb +++ b/lib/aethyr/core/actions/commands/look.rb @@ -1,53 +1,16 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" +require "aethyr/core/actions/command_action" module Aethyr module Core - module Commands + module Actions module Look - class LookHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["l", "look"]) + class LookCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) end - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(LookHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^(l|look)$/i - action({}) - when /^(l|look)\s+(in|inside)\s+(.*)$/i - action({ :in => $3 }) - when /^(l|look)\s+(.*)$/i - action({ :at => $2 }) - when /^help (l|look)$/i - action_help({}) - end - end - - private - def action_help(event) - @player.output <<'EOF' -Command: Look -Syntax: LOOK -Syntax: LOOK [object] -Syntax: LOOK IN [object] - -Look by itself will show you your surroundings. - -Look followed by an object will look at that object. - -Look IN will look inside of a container (if it is open). - -'l' is a shortcut for look. -EOF - end - - def action(event) + def action + event = @data room = $manager.get_object(@player.container) if @player.blind? @player.output "You cannot see while you are blind." @@ -96,7 +59,7 @@ EOF else if not room.nil? look_text = room.look(@player) - @player.output(look_text, message_type: :look) + @player.output(look_text) else @player.output "Nothing to look at." end @@ -104,6 +67,7 @@ EOF end end + private def describe_area(object) if object.is_a? Room result = object.terrain_type.room_text unless object.terrain_type.nil? @@ -114,10 +78,9 @@ EOF end result end + end - - Aethyr::Extend::HandlerRegistry.register_handler(LookHandler) end end end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/actions/commands/map.rb b/lib/aethyr/core/actions/commands/map.rb new file mode 100644 index 0000000000000000000000000000000000000000..12c89b1b185def32bdcac41fad901ab1527b0f7f --- /dev/null +++ b/lib/aethyr/core/actions/commands/map.rb @@ -0,0 +1,21 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Map + class MapCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + @player.output(room.area.render_map(@player, room.area.position(room))) + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/more.rb b/lib/aethyr/core/actions/commands/more.rb new file mode 100644 index 0000000000000000000000000000000000000000..8b6703303625daba0da031ffe5f63c8ca02bc260 --- /dev/null +++ b/lib/aethyr/core/actions/commands/more.rb @@ -0,0 +1,20 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module More + class MoreCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + player.more + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/move.rb b/lib/aethyr/core/actions/commands/move.rb new file mode 100644 index 0000000000000000000000000000000000000000..f4fa764b75693bdfffe6961b06869ea433af729b --- /dev/null +++ b/lib/aethyr/core/actions/commands/move.rb @@ -0,0 +1,48 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Move + class MoveCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data.dup + room = $manager.get_object(@player.container) + exit = room.exit(event[:direction]) + + if exit.nil? + @player.output("You cannot go #{event[:direction]}.") + return + elsif exit.can? :open and not exit.open? + @player.output("That exit is closed. Perhaps you should open it?") + return + end + + new_room = $manager.find(exit.exit_room) + + if new_room.nil? + @player.output("That exit #{exit.name} leads into the void.") + return + end + + room.remove(@player) + new_room.add(@player) + @player.container = new_room.game_object_id + event[:to_player] = "You move #{event[:direction]}." + event[:to_other] = "#{@player.name} leaves #{event[:direction]}." + event[:to_blind_other] = "You hear someone leave." + + room.out_event(event) + look_text = new_room.look(@player) + out_text = Window.split_message(look_text, 79).join("\n") + @player.output(out_text, message_type: :look, internal_clear: true) + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/open.rb b/lib/aethyr/core/actions/commands/open.rb new file mode 100644 index 0000000000000000000000000000000000000000..f71b7e9cd295c0af62fdc75b27d93d1287744966 --- /dev/null +++ b/lib/aethyr/core/actions/commands/open.rb @@ -0,0 +1,30 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Open + class OpenCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = expand_direction(event[:object]) + object = player.search_inv(object) || $manager.find(object, room) + + if object.nil? + player.output("Open what?") + elsif not object.can? :open + player.output("You cannot open #{object.name}.") + else + object.open(event) + end + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/portal.rb b/lib/aethyr/core/actions/commands/portal.rb new file mode 100644 index 0000000000000000000000000000000000000000..5a19d143b7503f0c74f073645e8e402edbc7af17 --- /dev/null +++ b/lib/aethyr/core/actions/commands/portal.rb @@ -0,0 +1,79 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Portal + class PortalCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = find_object(event[:object], event) + if object.nil? + player.output "Cannot find #{event[:object]}" + return + elsif not object.is_a? Portal + player.output "That is not a portal." + return + end + + value = event[:value] + + case event[:setting] + when "action" + value.downcase! + if value == "enter" + object.info.delete :portal_action + player.output "Set portal action to enter" + elsif ["jump", "climb", "crawl"].include? value + object.info.portal_action = value.downcase.to_sym + player.output "Set portal action to #{value}" + else + player.output "#{value} is not a valid portal action." + end + when "exit" + if value.downcase == "!nothing" or value.downcase == "nil" + object.info.delete :exit_message + else + if value[-1,1] !~ /[!.?"']/ + value << "." + end + object.info.exit_message = value + end + player.output "#{object.name} exit message set to: #{object.info.exit_message}" + when "entrance" + if value.downcase == "!nothing" or value.downcase == "nil" + object.info.delete :entrance_message + else + if value[-1,1] !~ /[!.?"']/ + value << "." + end + object.info.entrance_message = value + end + player.output "#{object.name} entrance message set to: #{object.info.entrance_message}" + when "portal" + if value.downcase == "!nothing" or value.downcase == "nil" + object.info.delete :portal_message + else + if value[-1,1] !~ /[!.?"']/ + value << "." + end + object.info.portal_message = value + end + player.output "#{object.name} portal message set to: #{object.info.portal_message}" + else + player.output "Valid options: action, exit, entrance, or portal." + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/pose.rb b/lib/aethyr/core/actions/commands/pose.rb new file mode 100644 index 0000000000000000000000000000000000000000..09c383187bbb7556bd098d394258c15a94e1a707 --- /dev/null +++ b/lib/aethyr/core/actions/commands/pose.rb @@ -0,0 +1,30 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Pose + class PoseCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:pose].downcase == "none" + player.pose = nil + player.output "You are no longer posing." + else + player.pose = event[:pose] + player.output "Your pose is now: #{event[:pose]}." + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/punch.rb b/lib/aethyr/core/actions/commands/punch.rb new file mode 100644 index 0000000000000000000000000000000000000000..555cca5b717196036c774c9a72b96a29123815ee --- /dev/null +++ b/lib/aethyr/core/actions/commands/punch.rb @@ -0,0 +1,56 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Punch + class PunchCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + return unless Combat.ready? player + + target = (event.target && room.find(event.target)) || room.find(player.last_target) + + if target.nil? + player.output "Who are you trying to attack?" + return + else + return unless Combat.valid_target? player, target + end + + player.last_target = target.goid + + event.target = target + + event[:to_other] = "#{player.name} swings #{player.pronoun(:possessive)} clenched fist at #{target.name}." + event[:to_target] = "#{player.name} swings #{player.pronoun(:possessive)} fist straight towards your face." + event[:to_player] = "You clench your hand into a fist and swing it at #{target.name}." + event[:blockable] = true + + player.balance = false + player.info.in_combat = true + target.info.in_combat = true + + room.out_event event + + event[:action] = :martial_hit + event[:combat_action] = :punch + event[:to_other] = "#{player.name} punches #{target.name} directly in the face." + event[:to_target] = "You stagger slightly as #{player.name} punches you in the face." + event[:to_player] = "Your fist lands squarely in #{target.name}'s face." + + Combat.future_event event + end + + end + end + end + end +end diff --git a/lib/aethyr/core/commands/put.rb b/lib/aethyr/core/actions/commands/put.rb similarity index 54% rename from lib/aethyr/core/commands/put.rb rename to lib/aethyr/core/actions/commands/put.rb index b4e7af21a8e0ecda1f0622c899e115dafcba4ffe..21a2a0cb35c1ac83894026f06b4e044814fcf527 100644 --- a/lib/aethyr/core/commands/put.rb +++ b/lib/aethyr/core/actions/commands/put.rb @@ -1,46 +1,16 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" +require "aethyr/core/actions/command_action" module Aethyr module Core - module Commands + module Actions module Put - class PutHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["put"]) + class PutCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) end - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(PutHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^put((\s+(\d+)\s+)|\s+)(\w+)\s+in\s+(\w+)$/i - action({ :item => $4, - :count => $3.to_i, - :container => $5 }) - when /^help put$/i - action_help({}) - end - end - - private - def action_help(event) - @player.output <<'EOF' -Command: Put -Syntax: PUT [object] IN [container] - -Puts an object in a container. The container must be open to do so. - -See also: LOOK TAKE OPEN - -EOF - end - - def action(event) + def action + event = @data room = $manager.get_object(@player.container) item = @player.inventory.find(event[:item]) @@ -76,9 +46,7 @@ EOF room.out_event(event) end end - - Aethyr::Extend::HandlerRegistry.register_handler(PutHandler) end end end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/actions/commands/quit.rb b/lib/aethyr/core/actions/commands/quit.rb new file mode 100644 index 0000000000000000000000000000000000000000..ea4fea557bc1a0bc47af7e1272552cb46eb2330a --- /dev/null +++ b/lib/aethyr/core/actions/commands/quit.rb @@ -0,0 +1,20 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Quit + class QuitCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + $manager.drop_player @player + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/read_post.rb b/lib/aethyr/core/actions/commands/read_post.rb new file mode 100644 index 0000000000000000000000000000000000000000..879f534b68f1c6779258aa7623b8798dcfdd13bb --- /dev/null +++ b/lib/aethyr/core/actions/commands/read_post.rb @@ -0,0 +1,43 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module ReadPost + class ReadPostCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + board = find_board(event, room) + + if board.nil? + player.output "There do not seem to be any postings here." + return + end + + post = board.get_post event[:post_id] + if post.nil? + player.output "No such posting here." + return + end + + if player.info.boards.nil? + player.info.boards = {} + end + + player.info.boards[board.goid] = event[:post_id].to_i + + player.output board.show_post(post, player.word_wrap || 80) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/remove.rb b/lib/aethyr/core/actions/commands/remove.rb new file mode 100644 index 0000000000000000000000000000000000000000..2abe0197cc6b81cf37240e85cb53ed9982fd05d4 --- /dev/null +++ b/lib/aethyr/core/actions/commands/remove.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Remove + class RemoveCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + object = player.equipment.find(event[:object]) + + if object.nil? + player.output("What #{event[:object]} are you trying to remove?") + return + end + + if player.inventory.full? + player.output("There is no room in your inventory.") + return + end + + if object.is_a? Weapon + player.output("You must unwield weapons.") + return + end + + response = player.remove(object, event[:position]) + + if response + event[:to_player] = "You remove #{object.name}." + event[:to_other] = "#{player.name} removes #{object.name}." + room.out_event(event) + else + player.output "Could not remove #{object.name} for some reason." + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/reply.rb b/lib/aethyr/core/actions/commands/reply.rb new file mode 100644 index 0000000000000000000000000000000000000000..fd3058b1c2fc6c943a935988b7f69722878f2cea --- /dev/null +++ b/lib/aethyr/core/actions/commands/reply.rb @@ -0,0 +1,27 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Reply + class ReplyCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + unless @player.reply_to + @player.output "There is no one to reply to." + return + end + + event[:target] = @player.reply_to + + action_tell(event) + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/restart.rb b/lib/aethyr/core/actions/commands/restart.rb new file mode 100644 index 0000000000000000000000000000000000000000..4d949650145f88994e858c8c7e021fdb6e13994a --- /dev/null +++ b/lib/aethyr/core/actions/commands/restart.rb @@ -0,0 +1,24 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Restart + class RestartCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + $manager.restart + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/satiety.rb b/lib/aethyr/core/actions/commands/satiety.rb new file mode 100644 index 0000000000000000000000000000000000000000..0800665546fd608629694e701c7eeca3b5c7122b --- /dev/null +++ b/lib/aethyr/core/actions/commands/satiety.rb @@ -0,0 +1,21 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Satiety + class SatietyCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + @player.output "You are #{@player.satiety}." + end + #Display status. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/say.rb b/lib/aethyr/core/actions/commands/say.rb new file mode 100644 index 0000000000000000000000000000000000000000..cbd7f9a03da64ae478132e2453bfb51302a2387c --- /dev/null +++ b/lib/aethyr/core/actions/commands/say.rb @@ -0,0 +1,113 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Say + class SayCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data.dup + room = $manager.get_object(@player.container) + + phrase = event[:phrase] + target = event[:target] && room.find(event[:target]) + prefix = event[:pre] + + if prefix + prefix << ", " + else + prefix = "" + end + + if phrase.nil? + @player.output("Huh?") + return + elsif event[:target] and target.nil? + @player.output("Say what to whom?") + return + elsif target and target == @player + @player.output "Talking to yourself again?" + return + elsif target + to_clause = " to #{target.name}" + ask_clause = " #{target.name}" + else + to_clause = "" + ask_clause = "" + end + + phrase[0,1] = phrase[0,1].capitalize + phrase.gsub!(/(\s|^|\W)(i)(\s|$|\W)/) { |match| match.sub('i', 'I') } + + case phrase + when /:\)$/ + rvoice = "smiles and " + pvoice = "smile and " + when /:\($/ + rvoice = "frowns and " + pvoice = "frown and " + when /:D$/ + rvoice = "laughs as #{@player.pronoun} " + pvoice = "laugh as you " + else + rvoice = "" + pvoice = "" + end + + phrase = phrase.gsub(/\s*(:\)|:\()|:D/, '').strip.gsub(/\s{2,}/, ' ') + + case phrase[-1..-1] + when "!" + pvoice += "exclaim" + rvoice += "exclaims" + when "?" + pvoice += "ask" + rvoice += "asks" + when "." + pvoice += "say" + rvoice += "says" + else + pvoice += "say" + rvoice += "says" + ender = "." + end + + phrase = "<say>\"#{phrase}#{ender}\"</say>" + + event[:message_type] = :chat + event[:target] = target + if target and pvoice == "ask" + event[:to_target] = prefix + "#{@player.name} #{rvoice} you, #{phrase}" + event[:to_player] = prefix + "you #{pvoice} #{target.name}, #{phrase}" + event[:to_other] = prefix + "#{@player.name} #{rvoice} #{target.name}, #{phrase}" + event[:to_blind_target] = "Someone asks, #{phrase}" + event[:to_blind_other] = "Someone asks, #{phrase}" + event[:to_deaf_target] = "#{@player.name} seems to be asking you something." + event[:to_deaf_other] = "#{@player.name} seems to be asking #{target.name} something." + elsif target + event[:to_target] = prefix + "#{@player.name} #{rvoice} to you, #{phrase}" + event[:to_player] = prefix + "you #{pvoice} to #{target.name}, #{phrase}" + event[:to_other] = prefix + "#{@player.name} #{rvoice} to #{target.name}, #{phrase}" + event[:to_blind_target] = "Someone #{rvoice}, #{phrase}" + event[:to_blind_other] = "Someone #{rvoice}, #{phrase}" + event[:to_deaf_target] = "You see #{@player.name} say something to you." + event[:to_deaf_other] = "You see #{@player.name} say something to #{target.name}." + else + event[:to_player] = prefix + "you #{pvoice}, #{phrase}" + event[:to_other] = prefix + "#{@player.name} #{rvoice}, #{phrase}" + event[:to_blind_other] = "Someone #{rvoice}, #{phrase}" + event[:to_deaf_target] = "You see #{@player.name} say something." + event[:to_deaf_other] = "You see #{@player.name} say something." + end + + room.out_event(event) + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/set.rb b/lib/aethyr/core/actions/commands/set.rb new file mode 100644 index 0000000000000000000000000000000000000000..d528d6ba3a412d7efe0754cce723d3d20bd8d4b3 --- /dev/null +++ b/lib/aethyr/core/actions/commands/set.rb @@ -0,0 +1,101 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Set + class SetCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + event[:setting].downcase! + case event[:setting] + when 'wordwrap' + value = event[:value] + if player.word_wrap.nil? + player.output("Word wrap is currently off.", true) + else + player.output("Word wrap currently set to #{player.word_wrap}.", true) + end + + if value.nil? + player.output "Please specify 'off' or a value between 10 - 200." + return + elsif value.downcase == 'off' + player.word_wrap = nil + player.output "Word wrap is now disabled." + return + else + value = value.to_i + if value > 200 or value < 10 + player.output "Please use a value between 10 - 200." + return + else + player.word_wrap = value + player.output "Word wrap is now set to: #{value} characters." + return + end + end + when 'pagelength', "page_length" + value = event[:value] + if player.page_height.nil? + player.output("Pagination is currently off.", true) + else + player.output("Page length is currently set to #{player.page_height}.", true) + end + + if value.nil? + player.output "Please specify 'off' or a value between 1 - 200." + return + elsif value.downcase == 'off' + player.page_height = nil + player.output "Output will no longer be paginated." + return + else + value = value.to_i + if value > 200 or value < 1 + player.output "Please use a value between 1 - 200." + return + else + player.page_height = value + player.output "Page length is now set to: #{value} lines." + return + end + + end + when "desc", "description" + player.editor(player.instance_variable_get(:@long_desc) || [], 10) do |data| + unless data.nil? + player.long_desc = data.strip + end + player.output("Set description to:\r\n#{player.long_desc}") + end + when "layout" + case event[:value].downcase + when "basic" + player.layout = :basic + when "partial" + player.layout = :partial + when "full" + player.layout = :full + when "wide" + player.layout = :wide + else + player.output "#{value} is not a valid layout please set one of the following: basic, partial, full, wide." + end + else + player.output "No such setting: #{event[:setting]}" + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/setcolor.rb b/lib/aethyr/core/actions/commands/setcolor.rb new file mode 100644 index 0000000000000000000000000000000000000000..4d5410e189fd5e120d7c5bb6bee7a85a05e45f1b --- /dev/null +++ b/lib/aethyr/core/actions/commands/setcolor.rb @@ -0,0 +1,35 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Setcolor + class SetcolorCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:option] == "off" + player.io.use_color = false + player.output "Colors disabled." + elsif event[:option] == "on" + player.io.use_color = true + player.output "Colors enabled." + elsif event[:option] == "default" + player.io.to_default + player.output "Colors set to defaults." + else + player.output player.io.set_color(event[:option], event[:color]) + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/setpassword.rb b/lib/aethyr/core/actions/commands/setpassword.rb new file mode 100644 index 0000000000000000000000000000000000000000..ef58d3384b07d978744eeecfb257fa20b7069998 --- /dev/null +++ b/lib/aethyr/core/actions/commands/setpassword.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Setpassword + class SetpasswordCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:new_password] + if event[:new_password] !~ /^\w{6,20}$/ + player.output "Please only use letters and numbers. Password should be between 6 and 20 characters long." + return + else + $manager.set_password(player, event[:new_password]) + player.output "Your password has been changed." + end + else + player.output "Please enter your current password:", true + player.io.echo_off + player.expect do |password| + if $manager.check_password(player.name, password) + player.output "Please enter your new password:", true + player.io.echo_off + player.expect do |password| + player.io.echo_on + event[:new_password] = password + Settings.setpassword(event, player, room) + end + else + player.output "Sorry, that password is invalid." + player.io.echo_on + end + + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/showcolors.rb b/lib/aethyr/core/actions/commands/showcolors.rb new file mode 100644 index 0000000000000000000000000000000000000000..45c146aedbb92a84cce47bcc3955daecd8ee9a33 --- /dev/null +++ b/lib/aethyr/core/actions/commands/showcolors.rb @@ -0,0 +1,24 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Showcolors + class ShowcolorsCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + player.output player.io.display.show_color_config + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/simple_block.rb b/lib/aethyr/core/actions/commands/simple_block.rb new file mode 100644 index 0000000000000000000000000000000000000000..22479a134f959aa251ada12ec88b6e62802084c0 --- /dev/null +++ b/lib/aethyr/core/actions/commands/simple_block.rb @@ -0,0 +1,70 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module SimpleBlock + class SimpleBlockCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + return if not Combat.ready? player + + weapon = get_weapon(player, :block) + if weapon.nil? + player.output "You are not wielding a weapon you can block with." + return + end + + target = (event.target && room.find(event.target)) || room.find(player.last_target) + + if target == player + player.output "You cannot block yourself." + return + elsif target + events = Combat.find_events(:player => target, :target => player, :blockable => true) + else + events = Combat.find_events(:target => player, :blockable => true) + end + + if events.empty? + player.output "What are you trying to block?" + return + end + + if target.nil? + target = events[0].player + end + + player.last_target = target.goid + + b_event = events[0] + if rand > 0.5 + b_event[:action] = :weapon_block + b_event[:type] = :WeaponCombat + b_event[:to_other] = "#{player.name} deftly blocks #{target.name}'s attack with #{weapon.name}." + b_event[:to_player] = "#{player.name} deftly blocks your attack with #{weapon.name}." + b_event[:to_target] = "You deftly block #{target.name}'s attack with #{weapon.name}." + end + + event[:target] = target + event[:to_other] = "#{player.name} raises #{player.pronoun(:possessive)} #{weapon.generic} to block #{target.name}'s attack." + event[:to_target] = "#{player.name} raises #{player.pronoun(:possessive)} #{weapon.generic} to block your attack." + event[:to_player] = "You raise your #{weapon.generic} to block #{target.name}'s attack." + + player.balance = false + room.out_event event + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/simple_dodge.rb b/lib/aethyr/core/actions/commands/simple_dodge.rb new file mode 100644 index 0000000000000000000000000000000000000000..9fe19d0482109748d5dcd38d47b305d5368c2cf0 --- /dev/null +++ b/lib/aethyr/core/actions/commands/simple_dodge.rb @@ -0,0 +1,63 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module SimpleDodge + class SimpleDodgeCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + return unless Combat.ready? player + + target = (event.target && room.find(event.target)) || room.find(player.last_target) + + if target == player + player.output "You cannot block yourself." + return + elsif target + events = Combat.find_events(:player => target, :target => player, :blockable => true) + else + events = Combat.find_events(:target => player, :blockable => true) + end + + if events.empty? + player.output "What are you trying to dodge?" + return + end + + if target.nil? + target = events[0].player + end + + player.last_target = target.goid + + b_event = events[0] + if rand > 0.5 + b_event[:action] = :martial_miss + b_event[:type] = :MartialCombat + b_event[:to_other] = "#{player.name} twists away from #{target.name}'s attack." + b_event[:to_player] = "#{player.name} twists away from your attack." + b_event[:to_target] = "You manage to twist your body away from #{target.name}'s attack." + end + + event[:target] = target + event[:to_other] = "#{player.name} attempts to dodge #{target.name}'s attack." + event[:to_target] = "#{player.name} attempts to dodge your attack." + event[:to_player] = "You attempt to dodge #{target.name}'s attack." + + player.balance = false + room.out_event event + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/sit.rb b/lib/aethyr/core/actions/commands/sit.rb new file mode 100644 index 0000000000000000000000000000000000000000..b8aa009b96fb444540705f0a550f2a99d3a956a6 --- /dev/null +++ b/lib/aethyr/core/actions/commands/sit.rb @@ -0,0 +1,63 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Sit + class SitCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if not player.balance + player.output "You cannot sit properly while unbalanced." + return + elsif event[:object].nil? + if player.sitting? + player.output('You are already sitting down.') + elsif player.prone? and player.sit + event[:to_player] = 'You stand up then sit on the ground.' + event[:to_other] = "#{player.name} stands up then sits down on the ground." + event[:to_deaf_other] = event[:to_other] + room.output(event) + elsif player.sit + event[:to_player] = 'You sit down on the ground.' + event[:to_other] = "#{player.name} sits down on the ground." + event[:to_deaf_other] = event[:to_other] + room.out_event(event) + else + player.output('You are unable to sit down.') + end + else + object = $manager.find(event[:object], player.room) + + if object.nil? + player.output('What do you want to sit on?') + elsif not object.can? :sittable? + player.output("You cannot sit on #{object.name}.") + elsif object.occupied_by? player + player.output("You are already sitting there!") + elsif not object.has_room? + player.output("The #{object.generic} #{object.plural? ? "are" : "is"} already occupied.") + elsif player.sit(object) + object.sat_on_by(player) + event[:to_player] = "You sit down on #{object.name}." + event[:to_other] = "#{player.name} sits down on #{object.name}." + event[:to_deaf_other] = event[:to_other] + room.out_event(event) + else + player.output('You are unable to sit down.') + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/commands/skills.rb b/lib/aethyr/core/actions/commands/skills.rb similarity index 76% rename from lib/aethyr/core/commands/skills.rb rename to lib/aethyr/core/actions/commands/skills.rb index 9a711e6fdf90d48cbc18e505a5e67a887e356b52..5f076032a862e6b5fd3063449e80340de9d66a9d 100644 --- a/lib/aethyr/core/commands/skills.rb +++ b/lib/aethyr/core/actions/commands/skills.rb @@ -1,34 +1,17 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" -require 'aethyr/core/render/text_util' -include TextUtil +# coding: utf-8 +require "aethyr/core/actions/command_action" module Aethyr module Core - module Commands + module Actions module Skills - class SkillsHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["skills"]) + class SkillsCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) end - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(SkillsHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^skills$/i - action({}) - when /^help (skills)$/i - action_help({}) - end - end - - private - def action(event) + def action + event = @data box_width = 25 box_work_width = box_width - 2 width = @player.word_wrap @@ -58,7 +41,7 @@ module Aethyr output += "│#{text_format_right % ''}│\n" - output += "│#{SkillsHandler::generate_progress(box_work_width, skill.level_percentage)}│\n" + output += "│#{SkillsCommand::generate_progress(box_work_width, skill.level_percentage)}│\n" xp_left = "#{skill.xp_to_go} xp to next" output += "│#{text_format_right % xp_left}│\n" @@ -74,15 +57,7 @@ module Aethyr @player.output(output) end - def action_help(event) - player.output <<'EOF' -Command: Skills -Syntax: SKILLS - -List all your currently known skills, their level, and level up info. -EOF - end - + private def self.generate_progress(width, percentage, style = :vertical_smooth) if (style.eql? :horizontal_smooth) or (style.eql? :vertical_smooth) working_space = width - 7 @@ -116,10 +91,8 @@ EOF return "[<raw fg:white>#{bar_format % bar}</raw fg:white>] #{percent_format % percent_text}" end end - - Aethyr::Extend::HandlerRegistry.register_handler(SkillsHandler) end end end end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/actions/commands/slash.rb b/lib/aethyr/core/actions/commands/slash.rb new file mode 100644 index 0000000000000000000000000000000000000000..c00a3445470c83d1ea242d4d6954cceeb2829649 --- /dev/null +++ b/lib/aethyr/core/actions/commands/slash.rb @@ -0,0 +1,65 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Slash + class SlashCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + return if not Combat.ready? player + + weapon = get_weapon(player, :slash) + if weapon.nil? + player.output "You are not wielding a weapon you can slash with." + return + end + + target = (event.target && room.find(event.target)) || room.find(player.last_target) + + if target.nil? + player.output "Who are you trying to attack?" + return + else + return unless Combat.valid_target? player, target + end + + player.last_target = target.goid + + event.target = target + + event[:to_other] = "#{weapon.name} flashes as #{player.name} swings it at #{target.name}." + event[:to_target] = "#{weapon.name} flashes as #{player.name} swings it towards you." + event[:to_player] = "#{weapon.name} flashes as you swing it towards #{target.name}." + event[:attack_weapon] = weapon + event[:blockable] = true + + player.balance = false + player.info.in_combat = true + target.info.in_combat = true + + room.out_event event + + event[:action] = :weapon_hit + event[:combat_action] = :slash + event[:to_other] = "#{player.name} slashes across #{target.name}'s torso with #{weapon.name}." + event[:to_target] = "#{player.name} slashes across your torso with #{weapon.name}." + event[:to_player] = "You slash across #{target.name}'s torso with #{weapon.name}." + + Combat.future_event event + + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/smell.rb b/lib/aethyr/core/actions/commands/smell.rb new file mode 100644 index 0000000000000000000000000000000000000000..72b0be03e4814e35971c2b580d1cbce76782441e --- /dev/null +++ b/lib/aethyr/core/actions/commands/smell.rb @@ -0,0 +1,60 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Smell + class SmellCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + if event[:target].nil? + if room.info.smell + event[:to_player] = "You sniff the air. #{room.info.smell}." + else + event[:to_player] = "You sniff the air, but detect no unusual aromas." + end + event[:to_other] = "#{@player.name} sniffs the air." + room.out_event event + return + end + + object = @player.search_inv(event[:target]) || room.find(event[:target]) + + if object == @player or event[:target] == "me" + event[:target] = @player + event[:to_player] = "You cautiously sniff your armpits. " + if rand > 0.6 + event[:to_player] << "Your head snaps back from the revolting stench coming from beneath your arms." + event[:to_other] = "#{@player.name} sniffs #{@player.pronoun(:possessive)} armpits, then recoils in horror." + else + event[:to_player] << "Meh, not too bad." + event[:to_other] = "#{@player.name} sniffs #{@player.pronoun(:possessive)} armpits, then shrugs, apparently unconcerned with #{@player.pronoun(:possessive)} current smell." + end + room.out_event event + return + elsif object.nil? + @player.output "What are you trying to smell?" + return + end + + event[:target] = object + event[:to_player] = "Leaning in slightly, you sniff #{object.name}. " + if object.info.smell.nil? or object.info.smell == "" + event[:to_player] << "#{object.pronoun.capitalize} has no particular aroma." + else + event[:to_player] << object.info.smell + end + event[:to_target] = "#{@player.name} sniffs you curiously." + event[:to_other] = "#{@player.name} thrusts #{@player.pronoun(:possessive)} nose at #{object.name} and sniffs." + room.out_event event + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/stand.rb b/lib/aethyr/core/actions/commands/stand.rb new file mode 100644 index 0000000000000000000000000000000000000000..f97890a7094a6fbd4a7a17ada8b5bab57e4a8028 --- /dev/null +++ b/lib/aethyr/core/actions/commands/stand.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Stand + class StandCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if not player.prone? + player.output('You are already on your feet.') + return + elsif not player.balance + player.output "You cannot stand while unbalanced." + return + end + + if player.sitting? + object = $manager.find(player.sitting_on, room) + else + object = $manager.find(player.lying_on, room) + end + + if player.stand + event[:to_player] = 'You rise to your feet.' + event[:to_other] = "#{player.name} stands up." + event[:to_deaf_other] = event[:to_other] + room.out_event(event) + object.evacuated_by(player) unless object.nil? + else + player.output('You are unable to stand up.') + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/status.rb b/lib/aethyr/core/actions/commands/status.rb new file mode 100644 index 0000000000000000000000000000000000000000..aac5e8c951fecde6d8b7930702718933976ec0af --- /dev/null +++ b/lib/aethyr/core/actions/commands/status.rb @@ -0,0 +1,23 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Status + class StatusCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + @player.output("You are #{@player.health}.") + @player.output("You are feeling #{@player.satiety}.") + @player.output "You are currently #{@player.pose || 'standing up'}." + end + #Fill something. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/taste.rb b/lib/aethyr/core/actions/commands/taste.rb new file mode 100644 index 0000000000000000000000000000000000000000..ead897f980f89b877ea6e933f07fab6771423fbf --- /dev/null +++ b/lib/aethyr/core/actions/commands/taste.rb @@ -0,0 +1,40 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Taste + class TasteCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = @player.search_inv(event[:target]) || room.find(event[:target]) + + if object == @player or event[:target] == "me" + @player.output "You covertly lick yourself.\nHmm, not bad." + return + elsif object.nil? + @player.output "What would you like to taste?" + return + end + + event[:target] = object + event[:to_player] = "Sticking your tongue out hesitantly, you taste #{object.name}. " + if object.info.taste.nil? or object.info.taste == "" + event[:to_player] << "#{object.pronoun.capitalize} does not taste that great, but has no particular flavor." + else + event[:to_player] << object.info.taste + end + event[:to_target] = "#{@player.name} licks you, apparently in an attempt to find out your flavor." + event[:to_other] = "#{@player.name} hesitantly sticks out #{@player.pronoun(:possessive)} tongue and licks #{object.name}." + room.out_event event + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/tell.rb b/lib/aethyr/core/actions/commands/tell.rb new file mode 100644 index 0000000000000000000000000000000000000000..efa0147e64299525831f39e68db85bdfaadca3f7 --- /dev/null +++ b/lib/aethyr/core/actions/commands/tell.rb @@ -0,0 +1,46 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Tell + class TellCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + target = $manager.find event[:target] + unless target and target.is_a? Player + @player.output "That person is not available." + return + end + + if target == @player + @player.output "Talking to yourself?" + return + end + + phrase = event[:message] + + last_char = phrase[-1..-1] + + unless ["!", "?", "."].include? last_char + phrase << "." + end + + phrase[0,1] = phrase[0,1].upcase + phrase = phrase.strip.gsub(/\s{2,}/, ' ') + + @player.output "You tell #{target.name}, <tell>\"#{phrase}\"</tell>" + target.output "#{@player.name} tells you, <tell>\"#{phrase}\"</tell>" + target.reply_to = @player.name + end + + #Reply to a tell. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/terrain.rb b/lib/aethyr/core/actions/commands/terrain.rb new file mode 100644 index 0000000000000000000000000000000000000000..72f70365512ab93d9d673ff3b09381b104a19000 --- /dev/null +++ b/lib/aethyr/core/actions/commands/terrain.rb @@ -0,0 +1,73 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Terrain + class TerrainCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + if event[:target] == "area" + if room.area.nil? + player.output "This room is not in an area." + return + end + + room.area.info.terrain.area_type = event[:value].downcase.to_sym + + player.output "Set #{room.area.name} terrain type to #{room.area.info.terrain.area_type}" + + return + end + + case event[:setting].downcase + when "type" + room.info.terrain.room_type = event[:value].downcase.to_sym + player.output "Set #{room.name} terrain type to #{room.info.terrain.room_type}" + when "indoors" + if event[:value] =~ /yes|true/i + room.info.terrain.indoors = true + player.output "Room is now indoors." + elsif event[:value] =~ /no|false/i + room.info.terrain.indoors = false + player.output "Room is now outdoors." + else + player.output "Indoors: yes or no?" + end + when "water" + if event[:value] =~ /yes|true/i + room.info.terrain.water = true + player.output "Room is now water." + elsif event[:value] =~ /no|false/i + room.info.terrain.water = false + player.output "Room is now dry." + else + player.output "Water: yes or no?" + end + when "underwater" + if event[:value] =~ /yes|true/i + room.info.terrain.underwater = true + player.output "Room is now underwater." + elsif event[:value] =~ /no|false/i + room.info.terrain.underwater = false + player.output "Room is now above water." + else + player.output "Underwater: yes or no?" + end + else + player.output "What are you trying to set?" + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/time.rb b/lib/aethyr/core/actions/commands/time.rb new file mode 100644 index 0000000000000000000000000000000000000000..b1109c335386f6c7dfd24cac4eb409d02e600da1 --- /dev/null +++ b/lib/aethyr/core/actions/commands/time.rb @@ -0,0 +1,22 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Time + class TimeCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + @player.output $manager.time + end + + #Display date. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/unlock.rb b/lib/aethyr/core/actions/commands/unlock.rb new file mode 100644 index 0000000000000000000000000000000000000000..0b43aa259f18996a81d867dd3c216258e1fcb1d8 --- /dev/null +++ b/lib/aethyr/core/actions/commands/unlock.rb @@ -0,0 +1,69 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Unlock + class UnlockCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = @player.search_inv(event[:object]) || room.find(event[:object]) + + if object.nil? + @player.output("Unlock what? #{event[:object]}?") + return + elsif not object.can? :unlock or not object.lockable? + @player.output('That object cannot be unlocked.') + return + elsif not object.locked? + @player.output("#{object.name} is already unlocked.") + return + end + + has_key = false + object.keys.each do |key| + if @player.inventory.include? key + has_key = key + break + end + end + + if has_key or @player.admin + status = object.unlock(has_key, @player.admin) + if status + event[:to_player] = "You unlock #{object.name}." + event[:to_other] = "#{@player.name} unlocks #{object.name}." + event[:to_blind_other] = "You hear the clunk of a lock." + + room.out_event(event) + + if object.is_a? Door and object.connected? + other_side = $manager.find object.connected_to + other_side.unlock(has_key) + other_room = $manager.find other_side.container + o_event = event.dup + event[:to_other] = "#{other_side.name} unlocks from the other side." + event[:to_blind_other] = "You hear the click of a lock." + other_room.out_event(event) + end + + return + else + @player.output("You are unable to unlock #{object.name}.") + return + end + else + @player.output("You do not have the key to #{object.name}.") + return + end + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/unwield.rb b/lib/aethyr/core/actions/commands/unwield.rb new file mode 100644 index 0000000000000000000000000000000000000000..5b6d0765b93593a8c91f9882124d1030bbf51339 --- /dev/null +++ b/lib/aethyr/core/actions/commands/unwield.rb @@ -0,0 +1,60 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Unwield + class UnwieldCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + if event[:weapon] == "right" || event[:weapon] == "left" + weapon = player.equipment.get_wielded(event[:weapon]) + + if weapon.nil? + player.output "You are not wielding anything in your #{event[:weapon]} hand." + return + end + elsif event[:weapon].nil? + weapon = player.equipment.get_wielded + if weapon.nil? + player.output "You are not wielding anything." + return + end + else + weapon = player.equipment.find(event[:weapon]) + + if weapon.nil? + player.output "What are you trying to unwield?" + return + end + + if not [:left_wield, :right_wield, :dual_wield].include? player.equipment.position_of(weapon) + player.output "You are not wielding #{weapon.name}." + return + end + + end + + if player.equipment.remove(weapon) + player.inventory << weapon + event[:to_player] = "You unwield #{weapon.name}." + event[:to_other] = "#{player.name} unwields #{weapon.name}." + room.out_event(event) + else + player.output "Could not unwield #{weapon.name}." + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/wear.rb b/lib/aethyr/core/actions/commands/wear.rb new file mode 100644 index 0000000000000000000000000000000000000000..8f705a3481be690089288738afb40f105f56cb73 --- /dev/null +++ b/lib/aethyr/core/actions/commands/wear.rb @@ -0,0 +1,39 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Wear + class WearCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + + object = player.inventory.find(event[:object]) + + if object.nil? + player.output("What #{event[:object]} are you trying to wear?") + return + elsif object.is_a? Weapon + player.output "You must wield #{object.name}." + return + end + + if player.wear object + event[:to_player] = "You put on #{object.name}." + event[:to_other] = "#{player.name} puts on #{object.name}." + room.out_event(event) + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/whereis.rb b/lib/aethyr/core/actions/commands/whereis.rb new file mode 100644 index 0000000000000000000000000000000000000000..6d7ca0b7ee867d7d117278f15c3d8da3b1812c0a --- /dev/null +++ b/lib/aethyr/core/actions/commands/whereis.rb @@ -0,0 +1,47 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Whereis + class WhereisCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + object = find_object(event[:object], event) + + if object.nil? + player.output "Could not find #{event[:object]}." + return + end + + if object.container.nil? + if object.can? :area and not object.area.nil? and object.area != object + area = $manager.get_object object.area || "nothing" + player.output "#{object} is in #{area}." + else + player.output "#{object} is not in anything." + end + else + container = $manager.get_object object.container + if container.nil? + player.output "Container for #{object} not found." + else + player.output "#{object} is in #{container}." + event[:object] = container.goid + whereis(event, player, room) + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/whisper.rb b/lib/aethyr/core/actions/commands/whisper.rb new file mode 100644 index 0000000000000000000000000000000000000000..af16e79e52da874b88b0620ac431572c81a25baa --- /dev/null +++ b/lib/aethyr/core/actions/commands/whisper.rb @@ -0,0 +1,65 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Whisper + class WhisperCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + room = $manager.get_object(@player.container) + object = room.find(event[:to], Player) + + if object.nil? + @player.output("To whom are you trying to whisper?") + return + elsif object == @player + @player.output("Whispering to yourself again?") + event[:to_other] = "#{@player.name} whispers to #{@player.pronoun(:reflexive)}." + room.out_event(event, @player) + return + end + + phrase = event[:phrase] + + if phrase.nil? + @player.ouput "What are you trying to whisper?" + return + end + + prefix = event[:pre] + + if prefix + prefix << ", " + else + prefix = "" + end + + phrase[0,1] = phrase[0,1].capitalize + + last_char = phrase[-1..-1] + + unless ["!", "?", "."].include? last_char + ender = "." + end + + phrase = ", <say>\"#{phrase}#{ender}\"</say>" + + event[:target] = object + event[:to_player] = prefix + "you whisper to #{object.name}#{phrase}" + event[:to_target] = prefix + "#{@player.name} whispers to you#{phrase}" + event[:to_other] = prefix + "#{@player.name} whispers quietly into #{object.name}'s ear." + event[:to_other_blind] = "#{@player.name} whispers." + event[:to_target_blind] = "Someone whispers to you#{phrase}" + + room.out_event(event) + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/who.rb b/lib/aethyr/core/actions/commands/who.rb new file mode 100644 index 0000000000000000000000000000000000000000..3db7c9e29f3b685847858facd22954cbd2d3bed3 --- /dev/null +++ b/lib/aethyr/core/actions/commands/who.rb @@ -0,0 +1,28 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Who + class WhoCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + players = $manager.find_all("class", Player) + output = ["The following people are visiting Aethyr:"] + players.sort_by {|p| p.name}.each do |playa| + room = $manager.find playa.container + output << "#{playa.name} - #{room.name if room}" + end + + @player.output output + end + #Delete your player. + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/wield.rb b/lib/aethyr/core/actions/commands/wield.rb new file mode 100644 index 0000000000000000000000000000000000000000..82476261f0736e2b188574ab378e8982d3a49492 --- /dev/null +++ b/lib/aethyr/core/actions/commands/wield.rb @@ -0,0 +1,78 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Wield + class WieldCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + weapon = player.inventory.find(event[:weapon]) + if weapon.nil? + weapon = player.equipment.find(event[:weapon]) + if weapon and player.equipment.get_all_wielded.include? weapon + player.output "You are already wielding that." + else + player.output "What are you trying to wield?" + end + return + end + + if not weapon.is_a? Weapon + player.output "#{weapon.name} is not wieldable." + return + end + + if event[:side] + side = event[:side] + if side != "right" and side != "left" + player.output "Which hand?" + return + end + + result = player.equipment.check_wield(weapon, "#{side} wield") + if result + player.output result + return + end + + result = player.equipment.wear(weapon, "#{side} wield") + if result.nil? + player.output "You are unable to wield that." + return + end + event[:to_player] = "You grip #{weapon.name} firmly in your #{side} hand." + else + result = player.equipment.check_wield(weapon) + + if result + player.output result + return + end + + result = player.equipment.wear(weapon) + if result.nil? + player.output "You are unable to wield that weapon." + return + end + + event[:to_player] = "You firmly grip #{weapon.name} and begin to wield it." + end + + player.inventory.remove weapon + event[:to_other] = "#{player.name} wields #{weapon.name}." + room.out_event(event) + end + + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/write.rb b/lib/aethyr/core/actions/commands/write.rb new file mode 100644 index 0000000000000000000000000000000000000000..ea29d146b91f8876ffe2defe0fd314f87ed50418 --- /dev/null +++ b/lib/aethyr/core/actions/commands/write.rb @@ -0,0 +1,39 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module Write + class WriteCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + object = @player.search_inv(event[:target]) + + if object.nil? + @player.output "What do you wish to write on?" + return + end + + if not object.info.writable + @player.output "You cannot write on #{object.name}." + return + end + + @player.output "You begin to write on #{object.name}." + + @player.editor(object.readable_text || [], 100) do |data| + unless data.nil? + object.readable_text = data + end + @player.output "You finish your writing." + end + end + end + end + end + end +end diff --git a/lib/aethyr/core/actions/commands/write_post.rb b/lib/aethyr/core/actions/commands/write_post.rb new file mode 100644 index 0000000000000000000000000000000000000000..e0a1fa70442aac3b0e91f4acc1ad97565ff349a4 --- /dev/null +++ b/lib/aethyr/core/actions/commands/write_post.rb @@ -0,0 +1,44 @@ +require "aethyr/core/actions/command_action" + +module Aethyr + module Core + module Actions + module WritePost + class WritePostCommand < Aethyr::Extend::CommandAction + def initialize(actor, **data) + super(actor, **data) + end + + def action + event = @data + + room = $manager.get_object(@player.container) + player = @player + board = find_board(event, room) + + if board.nil? + player.output "There do not seem to be any postings here." + return + end + + player.output("What is the subject of this post?", true) + + player.expect do |subj| + player.editor do |message| + unless message.nil? + post_id = board.save_post(player, subj, event[:reply_to], message) + player.output "You have written post ##{post_id}." + if board.announce_new + area = $manager.get_object(board.container).area + area.output board.announce_new + end + end + end + end + end + + end + end + end + end +end diff --git a/lib/aethyr/core/cache_gary.rb b/lib/aethyr/core/cache_gary.rb index 928320245ac7ec648c96c496d878e36ab1d6cc02..2cf41d394b87c170752f353a7ae5961a87e114ee 100644 --- a/lib/aethyr/core/cache_gary.rb +++ b/lib/aethyr/core/cache_gary.rb @@ -67,7 +67,6 @@ class CacheGary < Gary log "Loading #{goid} from storage" , Logger::Ultimate begin obj = @storage.load_object(goid, self) - obj.add_observer(@manager) rescue MUDError::NoSuchGOID log "Tried to load #{goid}, but it must have been deleted." return nil @@ -78,12 +77,11 @@ class CacheGary < Gary end end - #Add object to CacheGary, also adds the Manager as an observer. + #Add object to CacheGary. def << game_object @mutex.synchronize do @ghash[game_object.goid] = game_object @all_goids << game_object.goid - game_object.add_observer(@manager) end end diff --git a/lib/aethyr/core/commands/admin.rb b/lib/aethyr/core/commands/admin.rb deleted file mode 100644 index e91021355d88fb29e0f528dc4809368fa90155c6..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/admin.rb +++ /dev/null @@ -1,1143 +0,0 @@ -#This module contains all the commands for administering the game. -# -#Note: need to add documentation of syntax, that would help -module Admin - class << self - - #Moves an object into a specified container. - # - # APUT [OBJECT] IN [CONTAINER] AT [x]x[y] - def aput(event, player, room) - if event[:object].is_a? GameObject - object = event[:object] - else - event[:object] = player.container if event[:object].downcase == "here" - object = find_object(event[:object], event) - end - - container = find_object(event[:in], event) - - if object.nil? - player.output "Cannot find #{event[:object]} to move." - return - elsif event[:in] == "!world" - container = $manager.find object.container - container.inventory.remove(object) unless container.nil? - object.container = nil - player.output "Removed #{object} from any containers." - return - elsif event[:in].downcase == "here" - container = $manager.find player.container - if container.nil? - player.output "Cannot find #{event[:in]} " - return - end - elsif container.nil? - player.output "Cannot find #{event[:in]} " - return - end - - if not object.container.nil? - current_container = $manager.find object.container - current_container.inventory.remove(object) if current_container - end - - unless event[:at] == nil - position = event[:at].split('x').map{ |e| e.to_i} - end - - if container.is_a? Inventory - container.add(object, position) - elsif container.is_a? Container - container.add(object) - else - container.inventory.add(object, position) - object.container = container.goid - end - - player.output "Moved #{object} into #{container}#{event[:at] == nil ? '' : ' at ' + event[:at]}" - end - - #Loads/Reloads a .rb file. Do not provide the extension. - # - # ARELOAD [FILENAME] - def areload(event, player, room) - begin - result = load "#{event[:object]}.rb" - player.output "Reloaded #{event[:object]}: #{result}" - rescue LoadError - player.output "Unable to load #{event[:object]}" - end - end - - #Creates a new object. - # - # ACREATE <OBJECT_TYPE> <NAME> - def acreate(event, player, room) - class_name = event[:object] - - class_name[0,1] = class_name[0,1].capitalize - - if Object.const_defined? class_name - klass = Object.const_get(class_name) - else - player.output "No such thing. Sorry." - return - end - - if not klass <= GameObject or klass == Player - player.output "You cannot create a #{klass.class}." - return - end - - vars = {} - vars[:@name] = event[:name] if event[:name] - vars[:@alt_names] = event[:alt_names] if event[:alt_names] - vars[:@generic] = event[:generic] if event[:generic] - args = event[:args] - - object = $manager.create_object(klass, room, nil, args, vars) - - if room - event[:to_player] = "Frowning in concentration, you make vague motions with your hands. There is a small flash of light as #{object.name} appears." - event[:to_other] = "Frowning in concentration, #{player.name} makes vague motions with #{player.pronoun(:possessive)} hands. There is a small flash of light as #{object.name} appears." - room.out_event event - end - - player.output "Created: #{object}" - object - end - - def acdoor event, player, room - - exit_room = nil - if event[:exit_room].nil? - out = find_object event[:direction], event - if out and out.is_a? Exit - exit_room = $manager.find out.exit_room - other_side = $manager.find opposite_dir(event[:direction]), out.exit_room - - if other_side - $manager.delete_object other_side - player.output "Removed opposite exit (#{other_side})." - else - player.output "Could not find opposite exit" - end - - $manager.delete_object out - player.output "Removed exit (#{out})." - end - else - exit_room = $manager.get_object event[:exit_room] - end - - if exit_room.nil? - player.output "Cannot find #{event[:exit_room]} to connect to." - return - end - - door_here = $manager.create_object Door, room, nil, exit_room.goid, :@alt_names => [event[:direction]], :@name => "a door to the #{event[:direction]}" - door_there = $manager.create_object Door, exit_room, nil, room.goid, :@alt_names => [opposite_dir(event[:direction])], :@name => "a door to the #{opposite_dir event[:direction]}" - door_here.connect_to door_there - - player.output "Created: #{door_here}" - player.output "Created: #{door_there}" - - if room - event[:to_player] = "Frowning in concentration, you make vague motions with your hands. There is a small flash of light as #{door_here.name} to #{exit_room.name} appears." - event[:to_other] = "Frowning in concentration, #{player.name} makes vague motions with #{player.pronoun(:possessive)} hands. There is a small flash of light as #{door_here.name} to #{exit_room.name} appears." - room.out_event event - end - end - - #Creates a portal. - def acportal(event, player, room) - object = Admin.acreate(event, player, room) - if event[:portal_action] and event[:portal_action].downcase != "enter" - object.info.portal_action = event[:portal_action].downcase.to_sym - end - end - - #Command for editing portals. - def portal(event, player, room) - object = find_object(event[:object], event) - if object.nil? - player.output "Cannot find #{event[:object]}" - return - elsif not object.is_a? Portal - player.output "That is not a portal." - return - end - - value = event[:value] - - case event[:setting] - when "action" - value.downcase! - if value == "enter" - object.info.delete :portal_action - player.output "Set portal action to enter" - elsif ["jump", "climb", "crawl"].include? value - object.info.portal_action = value.downcase.to_sym - player.output "Set portal action to #{value}" - else - player.output "#{value} is not a valid portal action." - end - when "exit" - if value.downcase == "!nothing" or value.downcase == "nil" - object.info.delete :exit_message - else - if value[-1,1] !~ /[!.?"']/ - value << "." - end - object.info.exit_message = value - end - player.output "#{object.name} exit message set to: #{object.info.exit_message}" - when "entrance" - if value.downcase == "!nothing" or value.downcase == "nil" - object.info.delete :entrance_message - else - if value[-1,1] !~ /[!.?"']/ - value << "." - end - object.info.entrance_message = value - end - player.output "#{object.name} entrance message set to: #{object.info.entrance_message}" - when "portal" - if value.downcase == "!nothing" or value.downcase == "nil" - object.info.delete :portal_message - else - if value[-1,1] !~ /[!.?"']/ - value << "." - end - object.info.portal_message = value - end - player.output "#{object.name} portal message set to: #{object.info.portal_message}" - else - player.output "Valid options: action, exit, entrance, or portal." - end - end - - #Create a new area. - def acarea(event, player, room) - area = $manager.create_object(Area, nil, nil, nil, {:@name => event[:name]}) - player.output "Created: #{area}" - end - - #Create room, with an exit to the new room and back to the current room. - def acroom(event, player, room) - area = nil - if room.container - area = $manager.get_object(room.container) - end - - unless area.nil? or area.map_type.eql? :none - current_pos = area.position(room) - new_pos = current_pos.dup - case event[:out_dir].downcase.strip - when "north" - new_pos[1] += 1 - when "south" - new_pos[1] -= 1 - when "west" - new_pos[0] -= 1 - when "east" - new_pos[0] += 1 - when "northeast" - player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" - return - when "northwest" - player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" - return - when "southeast" - player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" - return - when "southwest" - player.output "Can not create a #{event[:out_dir]} exit in a mappable area at this time" - return - else - new_pos = nil - end - new_pos_text = new_pos.map{ |e| e.to_s}.join('x') unless new_pos.nil? - end - - unless new_pos.nil? or area.find_by_position(new_pos).nil? - player.output "There is already a room at the coordinates (#{new_pos_text}) that would be occupied by the new room, aborting" - return - end - - new_room = $manager.create_object(Room, area, new_pos, nil, :@name => event[:name]) - out_exit = $manager.create_object(Exit, room, nil, new_room.goid, :@alt_names => [event[:out_dir]]) - in_exit = $manager.create_object(Exit, new_room, nil, room.goid, :@alt_names => [event[:in_dir]]) - - player.output "Created: #{new_room}#{new_pos.nil? ? '' : ' @ ' + new_pos_text}" - player.output "Created: #{out_exit}" - player.output "Created: #{in_exit}" - - if !area.nil? and area.map_type.eql? :world - west = area.find_by_position([new_pos[0] - 1, new_pos[1]]) - east = area.find_by_position([new_pos[0] + 1, new_pos[1]]) - north = area.find_by_position([new_pos[0], new_pos[1] + 1]) - south = area.find_by_position([new_pos[0], new_pos[1] - 1]) - if !west.nil? and !west.eql? room - out_exit = $manager.create_object(Exit, new_room, nil, west.goid, :@alt_names => ["west"]) - in_exit = $manager.create_object(Exit, west, nil, new_room.goid, :@alt_names => ["east"]) - player.output "Created: #{out_exit}" - player.output "Created: #{in_exit}" - west.output "There is a small flash of light as a new room appears to the east." - elsif !east.nil? and !east.eql? room - out_exit = $manager.create_object(Exit, new_room, nil, east.goid, :@alt_names => ["east"]) - in_exit = $manager.create_object(Exit, east, nil, new_room.goid, :@alt_names => ["west"]) - player.output "Created: #{out_exit}" - player.output "Created: #{in_exit}" - east.output "There is a small flash of light as a new room appears to the west." - elsif !north.nil? and !north.eql? room - out_exit = $manager.create_object(Exit, new_room, nil, north.goid, :@alt_names => ["north"]) - in_exit = $manager.create_object(Exit, north, nil, new_room.goid, :@alt_names => ["south"]) - player.output "Created: #{out_exit}" - player.output "Created: #{in_exit}" - north.output "There is a small flash of light as a new room appears to the south." - elsif !south.nil? and !south.eql? room - out_exit = $manager.create_object(Exit, new_room, nil, south.goid, :@alt_names => ["south"]) - in_exit = $manager.create_object(Exit, south, nil, new_room.goid, :@alt_names => ["north"]) - player.output "Created: #{out_exit}" - player.output "Created: #{in_exit}" - south.output "There is a small flash of light as a new room appears to the north." - end - end - - if room - room.output "There is a small flash of light as a new room appears to the #{event[:out_dir]}." - end - - end - - #Sets a server configuration option. - def aconfig(event, player, room) - - if event[:setting].nil? - player.output "Current configuration:\n#{ServerConfig}" - return - end - - setting = event[:setting].downcase.to_sym - - if setting == :reload - ServerConfig.reload - player.output "Reloaded configuration:\n#{ServerConfig}" - return - elsif not ServerConfig.has_setting? setting - player.output "No such setting." - return - end - - value = event[:value] - if value =~ /^\d+$/ - value = value.to_i - end - - ServerConfig[setting] = value - - player.output "New configuration:\n#{ServerConfig}" - end - - #Deletes an object. - def adelete(event, player, room) - if event[:object] and event[:object].split.first.downcase == "all" - log event[:object].split - klass = event[:object].split[1] - klass.capitalize! unless klass[0,1] == klass[0,1].upcase - begin - klass = Module.const_get klass.to_sym - rescue NameError - player.output "No such object type." - return - end - - objects = $manager.find_all("class", klass) - - objects.each do |obj| - e = event.dup - e[:object] = obj.goid - - Admin.adelete(e, player, room) - end - - return - end - - object = find_object(event[:object], event) - - if object.nil? - player.output "Cannot find #{event[:object]} to delete." - return - elsif object.is_a? Player - player.output "Use DELETEPLAYER to delete players." - return - end - - object_container = object.container - - $manager.delete_object(object) - - if room and room.goid == object.container - event[:to_player] = "You casually wave your hand and #{object.name} disappears." - event[:to_other] = "With a casual wave of #{player.pronoun(:possessive)} hand, #{player.name} makes #{object.name} disappear." - room.out_event event - else - player.output "You casually wave your hand and #{object.name} disappears." - end - - player.output "#{object} deleted." - end - - #Describe an object. - def adesc(event, player, room) - object = nil - if event[:object].downcase == "here" - object = room - else - object = find_object(event[:object], event) - end - - if object.nil? - player.output "Cannot find #{event[:object]}." - return - end - - if event[:inroom] - if event[:desc].nil? or event[:desc].downcase == "false" - object.show_in_look = false - player.output "#{object.name} will not be shown in the room description." - else - object.show_in_look= event[:desc] - player.output "The room will show #{object.show_in_look}" - end - else - object.instance_variable_set(:@short_desc, event[:desc]) - player.output "#{object.name} now looks like:\n#{object.short_desc}" - end - end - - #ASHOW and AHIDE. Either hides an object by setting its show_in_look to "" or shows it by setting - #show_in_look to false. - def ahide(event, player, room) - object = find_object(event[:object], event) - - if object.nil? - player.output "Cannot find #{event[:object]}." - return - end - - if event[:hide] - object.show_in_look = "" - player.output "#{object.name} is now hidden." - elsif object.show_in_look == "" - object.show_in_look = false - player.output "#{object.name} is no longer hidden." - else - player.output "This object is not hidden." - end - end - - #Looks at an object. - def alook(event, player, room) - if event[:at].nil? - object = room - elsif event[:at].downcase == "here" - object = $manager.find player.container - else - object = find_object(event[:at], event) - end - - if object.nil? - player.output "Cannot find #{event[:at]} to inspect." - return - end - - output = "Object: #{object}\n" - output << "Attributes:\n" - - object.instance_variables.sort.each do |var| - val = object.instance_variable_get(var) - if var == :@observer_peers - val = val.keys.map {|k| k.to_s } - end - output << "\t#{var} = #{val}\n" - end - - output << "\r\nInventory:\r\n" - - if object.respond_to? :inventory - object.inventory.each do |o| - output << "\t#{o.name} # #{o.goid} #{object.inventory.position(o) == nil ? "" : object.inventory.position(o).map(&:to_s).join('x')}\n" - end - else - output << "\tNo Inventory" - end - - if object.respond_to? :equipment - output << "\r\nEquipment:\r\n" - object.equipment.inventory.each do |o| - output << "\t#{o.name} # #{o.goid}\n" - end - output << "\t#{object.equipment.equipment.inspect}\n" - end - - player.output(output) - end - - #Lists objects in the world - def alist(event, player, room) - objects = nil - if event[:match].nil? - objects = $manager.find_all("class", :GameObject) - else - objects = $manager.find_all(event[:match], event[:attrib]) - end - - if objects.empty? - player.output "Nothing like that to list!" - else - output = [] - objects.each do |o| - output << "\t" + o.to_s - end - - output = output.join("\n") - - player.output(output) - end - end - - #Shows an object's containers. - def whereis(event, player, room) - object = find_object(event[:object], event) - - if object.nil? - player.output "Could not find #{event[:object]}." - return - end - - if object.container.nil? - if object.can? :area and not object.area.nil? and object.area != object - area = $manager.get_object object.area || "nothing" - player.output "#{object} is in #{area}." - else - player.output "#{object} is not in anything." - end - else - container = $manager.get_object object.container - if container.nil? - player.output "Container for #{object} not found." - else - player.output "#{object} is in #{container}." - event[:object] = container.goid - whereis(event, player, room) - end - end - end - - #Sets object variables. - def aset(event, player, room) - if event[:object].downcase == "here" - event[:object] = player.container - elsif event[:object] and event[:object].split.first.downcase == "all" - log event[:object].split - klass = event[:object].split[1] - klass.capitalize! unless klass[0,1] == klass[0,1].upcase - begin - klass = Module.const_get klass.to_sym - rescue NameError - player.output "No such object type." - return - end - - objects = $manager.find_all("class", klass) - - objects.each do |obj| - e = event.dup - e[:object] = obj.goid - - Admin.aset(e, player, room) - end - - return - end - - object = find_object(event[:object], event) - - if object.nil? - player.output "Cannot find #{event[:object]} to edit." - return - end - - attrib = event[:attribute] - - if attrib[0,1] != "@" - value = event[:value] - if value.downcase == "!nothing" or value.downcase == "nil" - value = nil - end - - if value and value[-1,1] !~ /[!.?"']/ - value << "." - end - - case attrib.downcase - when "smell" - if value.nil? - object.info.delete :smell - player.output "#{object.name} will no longer smell." - else - object.info.smell = value - player.output "#{object.name} will now smell like: #{object.info.smell}" - end - return - when "feel", "texture" - if value.nil? - object.info.delete :texture - player.output "#{object.name} will no longer have a particular texture." - else - object.info.texture = value - player.output "#{object.name} will now feel like: #{object.info.texture}" - end - return - when "taste" - if value.nil? - object.info.delete :taste - player.output "#{object.name} will no longer have a particular taste." - else - object.info.taste = value - player.output "#{object.name} will now taste like: #{object.info.taste}" - end - return - when "sound", "listen" - if value.nil? - object.info.delete :sound - player.output "#{object.name} will no longer make sounds." - else - object.info.sound = value - player.output "#{object.name} will now sound like: #{object.info.sound}" - end - return - else - player.output "What are you trying to set?" - return - end - end - - if not object.instance_variables.include? attrib and not object.instance_variables.include? attrib.to_sym and not event[:force] - player.output "#{object}:No such setting/variable/attribute: #{attrib}" - return - else - current_value = object.instance_variable_get(attrib) - if current_value.is_a? Array - object.instance_variable_set(attrib, event[:value].split(/s*"(.*?)"\s*|\s+/)) - player.output "Set #{object} attribute #{attrib} to #{event[:value].inspect}" - else - value = event[:value] #for ease - if value.split.length == 1 - case value.downcase - when "true" - value = true - when "false" - value = false - when /^:/ - value = value[1..-1].to_sym - when "nil" - value = nil - when /^[0-9]+$/ - value = value.to_i unless current_value.is_a? String - when "!nothing" - value = "" - when "!delete" - object.instance_eval { remove_instance_variable(attrib) } - player.output "Removed attribute #{attrib} from #{object}" - return - end - end - - object.instance_variable_set(attrib, value) - player.output "Set #{object} attribute #{attrib} to #{value}" - end - end - end - - #Display and edit the Info object for a GameObject. - def ainfo(event, player, room) - if event[:object].downcase == "here" - event[:object] = player.container - elsif event[:object].downcase == "me" - event[:object] = player - elsif event[:object] and event[:object].split.first.downcase == "all" - log event[:object].split - klass = event[:object].split[1] - klass.capitalize! unless klass[0,1] == klass[0,1].upcase - begin - klass = Module.const_get klass.to_sym - rescue NameError - player.output "No such object type." - return - end - - objects = $manager.find_all("class", klass) - - objects.each do |obj| - e = event.dup - e[:object] = obj.goid - - Admin.ainfo(e, player, room) - end - - return - end - - object = find_object(event[:object], event) - - if object.nil? - player.output "What object? #{event[:object]}" - return - end - - case event[:command] - when "set" - value = event[:value] #for ease - if value.split.length == 1 - if value == "true" - value = true - elsif value == "false" - value = false - elsif value[0,1] == ":" - value = value[1..-1].to_sym - elsif value == "nil" - value = nil - elsif value.match(/^[0-9]+$/) - value = value.to_i - elsif value.downcase == "!nothing" - value = "" - end - end - object.info.set(event[:attrib], value) - player.output "Set #{event[:attrib]} to #{object.info.get(event[:attrib])}" - when "delete" - object.info.delete(event[:attrib]) - player.output "Deleted #{event[:attrib]} from #{object}" - when "show" - player.output object.info.inspect - when "clear" - object.info = Info.new - player.output "Completely cleared info for #{object}." - else - player.output "Huh? What?" - end - end - - #Lists all players currently online - def awho(event, player, room) - players = $manager.find_all('class', Player) - - names = [] - players.each do |playa| - names << playa.name - end - - player.output('Players currently online:', true) - player.output(names.join(', ')) - end - - #Lists players online and how many of what objects are in memory - def astatus(event, player, room) - awho(event, player, room) - total_objects = $manager.game_objects_count - player.output("Object Counts:" , true) - $manager.type_count.each do |obj, count| - player.output("#{obj}: #{count}", true) - end - player.output("Total Objects: #{total_objects}") - end - - #Change log settings, view logs. - def alog(event, player, room) - if event[:command].nil? - player.output "What do you want to do with the log?" - return - else - command = event[:command].downcase - end - - case command - when /^players?$/ - if event[:value] - lines = event[:value].to_i - else - lines = 10 - end - - player.output tail('logs/player.log', lines) - when 'server' - if event[:value] - lines = event[:value].to_i - else - lines = 10 - end - - player.output tail('logs/server.log', lines) - when 'system' - if event[:value] - lines = event[:value].to_i - else - lines = 10 - end - - $LOG.dump - - player.output tail('logs/system.log', lines) - when 'flush' - log('Flushing log') - $LOG.dump - player.output 'Flushed log to disk.' - when 'ultimate' - ServerConfig[:log_level] = 3 - player.output "Log level now set to ULTIMATE." - when 'high' - ServerConfig[:log_level] = 2 - player.output "Log level now set to high." - when 'low', 'normal' - ServerConfig[:log_level] = 1 - player.output "Log level now set to normal." - when 'off' - ServerConfig[:log_level] = 0 - player.output "Logging mostly turned off. You may also want to turn off debugging." - when 'debug' - ServerConfig[:debug] = !$DEBUG - player.output "Debug info is now: #{$DEBUG ? 'on' : 'off'}" - else - player.output 'Possible settings: Off, Debug, Normal, High, or Ultimate' - end - end - - #Copies an object (but with new goid) -=begin - def acopy(event, player, room) - object = find_object(event[:object], event) - if object.nil? - player.output "Cannot find #{event[:object]} to copy." - end - - new_object = object.dup - new_object.instance_variable_set(:@game_object_id, Guid.new.to_s) - $manager.add_object(new_object) - room.add(new_object) - player.output "Created #{new_object}" - end -=end - - #Teach yourself a skill. - # - #Does nothing righ now. - def alearn(event, player, room) - end - - #Teach someone else a skill. - # - #Does nothing right now. - def ateach(event, player, room) - object = find_object(event[:target], event) - if object.nil? - player.output "Teach who what where?" - return - end - - alearn(event, object, room) - end - - #SAVE POINT - def asave(event, player, room) - log "#{player.name} initiated manual save." - $manager.save_all - player.output "Save complete. Check log for details." - end - - #Force something or someone to perform an action. - def aforce(event, player, room) - object = find_object(event[:target], event) - if object.nil? - player.output "Force who?" - return - elsif object.is_a? Mobile - unless object.info.redirect_output_to == player.goid - object.info.redirect_output_to = player.goid - - after 10 do - object.info.redirect_output_to = nil - end - end - end - - player.add_event(CommandParser.parse(object, event[:command])) - end - - #View what a GameObject sees. - def awatch(event, player, room) - object = find_object(event[:target], event) - if object.nil? - player.output "What mobile do you want to watch?" - return - elsif not object.is_a? Mobile - player.output "You can only use this to watch mobiles." - return - end - - case event[:command] - when "start" - if object.info.redirect_output_to == player.goid - player.output "You are already watching #{object.name}." - else - object.info.redirect_output_to = player.goid - player.output "Watching #{object.name}." - object.output "#{player.name} is watching you." - end - when "stop" - if object.info.redirect_output_to != player.goid - player.output "You are not watching #{object.name}." - else - object.info.redirect_output_to = nil - player.output "No longer watching #{object.name}." - end - else - if object.info.redirect_output_to != player.goid - object.info.redirect_output_to = player.goid - player.output "Watching #{object.name}." - object.output "#{player.name} is watching you." - else - object.info.redirect_output_to = nil - player.output "No longer watching #{object.name}." - end - end - end - - #Set a comment on an object. - def acomment(event, player, room) - object = find_object(event[:target], event) - if object.nil? - player.output "Cannot find:#{event[:target]}" - return - end - - object.comment = event[:comment] - player.output "Added comment: '#{event[:comment]}'\nto#{object}" - end - - #Manage reactions for an object. - def areaction(event, player, room) - - if event[:command] == "reload" and event[:object] and event[:object].downcase == "all" - objects = $manager.find_all("class", Reacts) - - objects.each do |o| - o.reload_reactions - end - - player.output "Updated reactions for #{objects.length} objects." - elsif event[:object] and event[:object].split.first.downcase == "all" - klass = event[:object].split[1] - klass.capitalize! unless klass[0,1] == klass[0,1].upcase - begin - klass = Module.const_get klass.to_sym - rescue NameError - player.output "No such object type." - return - end - - objects = $manager.find_all("class", klass) - - objects.each do |obj| - e = event.dup - e[:object] = obj.goid - - player.output "(Doing #{obj})" - Admin.areaction(e, player, room) - end - else - if event[:object] == "here" - object = room - else - object = find_object(event[:object], event) - end - - if object.nil? - player.output "Cannot find:#{event[:object]}" - return - elsif not object.is_a? Reacts and (event[:command] == "load" or event[:command] == "reload") - player.output "Object cannot react, adding react ability." - object.extend(Reacts) - end - - case event[:command] - when "add" - if object.actions.add? event[:action_name] - player.output "Added #{event[:action_name]}" - else - player.output "Already had a reaction by that name." - end - when "delete" - if object.actions.delete? event[:action_name] - player.output "Removed #{event[:action_name]}" - else - player.output "That verb was not associated with this object." - end - when "load" - unless File.exist? "objects/reactions/#{event[:file]}.rx" - player.output "No such reaction file - #{event[:file]}" - return - end - - object.load_reactions event[:file] - player.output "Probably loaded reactions." - when "reload" - object.reload_reactions if object.can? :reload_reactions - player.output "Probably reloaded reactions." - when "clear" - object.unload_reactions if object.can? :unload_reactions - player.output "Probably cleared out reactions." - when "show" - if object.actions and not object.actions.empty? - player.output "Custom actions: #{object.actions.to_a.sort.join(' ')}", true - end - - if object.can? :show_reactions - player.output object.show_reactions - else - player.output "Object does not react." - end - else - player.output("Options:", true) - player.output("areaction load <object> <file>", true) - player.output("areaction reload <object> <file>", true) - player.output("areaction [add|delete] <object> <action>", true) - player.output("areaction [clear|show] <object>") - end - end - end - - #Lists existing areas - def areas(event, player, room) - areas = $manager.find_all('class', Area) - - if areas.empty? - player.output "There are no areas." - return - end - - player.output areas.map {|a| "#{a.name} - #{a.inventory.find_all('class', Room).length} rooms (#{a.info.terrain.area_type})" } - end - - #Settings for the area or room terrain - def terrain(event, player, room) - if event[:target] == "area" - if room.area.nil? - player.output "This room is not in an area." - return - end - - room.area.info.terrain.area_type = event[:value].downcase.to_sym - - player.output "Set #{room.area.name} terrain type to #{room.area.info.terrain.area_type}" - - return - end - - case event[:setting].downcase - when "type" - room.info.terrain.room_type = event[:value].downcase.to_sym - player.output "Set #{room.name} terrain type to #{room.info.terrain.room_type}" - when "indoors" - if event[:value] =~ /yes|true/i - room.info.terrain.indoors = true - player.output "Room is now indoors." - elsif event[:value] =~ /no|false/i - room.info.terrain.indoors = false - player.output "Room is now outdoors." - else - player.output "Indoors: yes or no?" - end - when "water" - if event[:value] =~ /yes|true/i - room.info.terrain.water = true - player.output "Room is now water." - elsif event[:value] =~ /no|false/i - room.info.terrain.water = false - player.output "Room is now dry." - else - player.output "Water: yes or no?" - end - when "underwater" - if event[:value] =~ /yes|true/i - room.info.terrain.underwater = true - player.output "Room is now underwater." - elsif event[:value] =~ /no|false/i - room.info.terrain.underwater = false - player.output "Room is now above water." - else - player.output "Underwater: yes or no?" - end - else - player.output "What are you trying to set?" - end - end - - #Restarts the server. - def restart(event, player, room) - $manager.restart - end - - #Show admin help files. - def ahelp(event, player, room) - Generic.help(event, player, room) - end - - #Delete a player/character. - def delete_player(event, player, room) - name = event.object - if not $manager.player_exist? name - player.output "No such player found: #{name}" - return - elsif $manager.find name - player.output "Player is currently logged in. Deletion aborted." - return - elsif name == player.name.downcase - player.output "You cannot delete yourself this way. Use DELETE ME PLEASE instead." - return - end - - $manager.delete_player name - - if $manager.find name or $manager.player_exist? name - player.output "Something went wrong. Player still exists." - else - player.output "#{name} deleted." - end - end - - private - - #Tail a file - def tail file, lines = 10 - require 'util/tail' - - output = [] - File::Tail::Logfile.tail(file, :backward => lines, :return_if_eof => true) do |line| - output << line.strip - end - - output << "(#{output.length} lines shown.)" - end - - #Looks in player's inventory and room for name. - #Then checks at global level for GOID. - def find_object(name, event) - $manager.find(name, event[:player]) || $manager.find(name, event[:player].container) || $manager.get_object(name) - end - end -end diff --git a/lib/aethyr/core/commands/close.rb b/lib/aethyr/core/commands/close.rb deleted file mode 100644 index 22524d682cc081559fe724db2dbfef0f60271bdb..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/close.rb +++ /dev/null @@ -1,66 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Close - class CloseHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["close"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(CloseHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^(close|shut)\s+(\w+)$/i - action({ :object => $2 }) - when /^help (close|shut)$/i - action_help({}) - end - end - - private - def action(event) - room = $manager.get_object(@player.container) - object = expand_direction(event[:object]) - object = @player.search_inv(object) || $manager.find(object, room) - - if object.nil? - @player.output("Close what?") - elsif not object.can? :open - @player.output("You cannot close #{object.name}.") - else - object.close(event) - end - end - - def action_help(event) - @player.output <<'EOF' -Command: Close -Syntax: CLOSE [object or direction] - -Closes the object. For doors and such, it is more accurate to use the direction in which the object lies. - -For example: - -CLOSE north - -CLOSE door - - -See also: LOCK, UNLOCK, OPEN -EOF - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(CloseHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/clothing.rb b/lib/aethyr/core/commands/clothing.rb deleted file mode 100644 index e32f626cf13326d17bb52742985d86cd6eb31b2d..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/clothing.rb +++ /dev/null @@ -1,55 +0,0 @@ -module Clothing - class << self - - #Wear some clothing. - def wear(event, player, room) - - object = player.inventory.find(event[:object]) - - if object.nil? - player.output("What #{event[:object]} are you trying to wear?") - return - elsif object.is_a? Weapon - player.output "You must wield #{object.name}." - return - end - - if player.wear object - event[:to_player] = "You put on #{object.name}." - event[:to_other] = "#{player.name} puts on #{object.name}." - room.out_event(event) - end - end - - #Remove some clothing. - def remove(event, player, room) - - object = player.equipment.find(event[:object]) - - if object.nil? - player.output("What #{event[:object]} are you trying to remove?") - return - end - - if player.inventory.full? - player.output("There is no room in your inventory.") - return - end - - if object.is_a? Weapon - player.output("You must unwield weapons.") - return - end - - response = player.remove(object, event[:position]) - - if response - event[:to_player] = "You remove #{object.name}." - event[:to_other] = "#{player.name} removes #{object.name}." - room.out_event(event) - else - player.output "Could not remove #{object.name} for some reason." - end - end - end -end diff --git a/lib/aethyr/core/commands/combat.rb b/lib/aethyr/core/commands/combat.rb deleted file mode 100644 index 4fec27b35cc1234a84948ce080fbec652ac18401..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/combat.rb +++ /dev/null @@ -1,262 +0,0 @@ -require 'yaml' - -#This is likely to get overhauled one day. -module Combat - - #Keeps track of 'in-flight' combat commands. - class CombatEventTracker - - def initialize - @events = [] - end - - #Add an event to the list. - def add event - @events << event - end - - #Find an event with the given attributes. - # - # find(:action => :slash) - # find(:player => someone) - def find args - @events.find do |e| - match = true - args.each do |k,v| - if e[k] != v - match = false - break - end - end - match - end - end - - #Same as CombatEventTracker#find, except returns an array of all matches. - def find_all args - @events.find_all do |e| - match = true - args.each do |k,v| - if e[k] != v - match = false - break - end - end - match - end - end - - #Remove event from list. - def delete event - @events.delete event - end - - #Display the commands currently in the list nicely. - def inspect - @events.map do |e| - e.to_s - end.join(", ") - end - end - - Events = CombatEventTracker.new - - class << self - - #Attempts to run away during combat. - def flee(event, player, room) - dir_exit = room.exit(event[:direction]) - - if dir_exit.nil? - player.output("You cannot go #{event[:direction]}.") - return - elsif dir_exit.is_a? Portal - player.output "You cannot simply go that way." - return - elsif dir_exit.can? :open and not dir_exit.open? - player.output("That exit is closed. Perhaps you should open it?") - return - elsif player.prone? - player.output('You must stand up first.') - return - end - - events = Combat.find_events(:target => player) - - if events.empty? - player.output "What are you trying to flee from?" - player.info.in_combat = false - return - end - - if rand > 0.5 - dir = expand_direction event.direction - events.each do |e| - e.action = :flee - e.type = :Movement - e.direction = dir - end - player.info.fleeing = true - end - - player.balance = false - event.to_player = "Heart beating wildly, you attempt to flee from combat." - event.to_other = "#{player.name} looks about wildly for a way to escape." - room.out_event event - end - - #I guess damage calculations should go here. - # - #Calls take_damage on the target, outputs the event to the - #room, then calls the death sequence if necessary. - def inflict_damage(event, player, room, base) - target = event.target - - if target.can? :take_damage - target.take_damage base - end - - room.out_event event - - if target.info.stats.health and target.info.stats.health <= 0 - death target - end - end - - #Goes through death sequence for give player/mobile. - def death player - room = $manager.get_object player.container - player.alive = false - - unless room.nil? - room.remove player - room.output player.death_message - end - - case player - when Player - player.output "You vision fills with darkness as you breathe your last breath." - after 5 do - defroom = $manager.get_object ServerConfig.start_room - player.info.stats.health = player.info.stats.max_health - player.output "Streams of golden light pour down on you as you are restored to life." - defroom.add player - player.alive = true - end - when Respawns - corpse = $manager.create_object(Corpse, nil, nil) - corpse.corpse_of player - room.add corpse - player.info.respawn_time = (Time.now.to_i + player.info.respawn_rate) - else - log "Don't know how to handle dead #{player}" - end - end - - #Check if the player is balanced. - #Gives message to player if not balanced. - def balanced? player - if player.balance - true - else - player.output "You do not have the balance to do that." - false - end - end - - #Checks if the target is valid (alive, etc.) - #Gives message to player if invalid. - def valid_target? player, target - if not target.is_a? GameObject - player.output "What are you trying to attack?" - false - elsif not target.is_a? LivingObject - player.output "You cannot attack #{target.name}." - false - elsif target == player - player.output "You cannot attack yourself." - false - else - true - end - end - - #Checks if player is balanced, not blind, and not prone. - #Prints message if any of these are not true. - def ready? player - if not Combat.balanced? player - false - elsif player.blind? - player.output "You cannot see who you are trying to attack!" - false - elsif player.prone? - player.output "You must stand up first." - false - else - true - end - end - - #Finds a target for the given event. Unless suppress_output is true, - #method will alert player if the target cannot be found. - def get_target(event, suppress_output = false) - player = event[:player] - room = $manager.find player.room - if event[:target].nil? - if player.last_target.nil? - target = nil - else - target = room.find(player.last_target) - end - else - target = room.find(event[:target]) - end - - if target.nil? - player.output "Who are you fighting?" unless suppress_output - return nil - elsif not target.can? :alive - player.output "You cannot do that to #{target.name}." unless suppress_output - return nil - elsif not target.alive - player.output "#{target.name} is no longer living." unless suppress_output - return nil - end - - return target - end - - #Add event to list. - def add_event event - Events.add event - end - - #Remove event from list, - def delete_event event - Events.delete event - end - - #Find commands matching the given args. - def find_events args - Events.find_all args - end - - #Add an event for the future. Does Combat#add_event as well. - # - #If there are already commands which target this player, - #the event will be attached to those commands so it ends - #at the same time. - # - #Otherwise, the event will occur after the given delay. - def future_event event, delay = 2.5, unit = :sec - events = Events.find_all(:target => event.player) - if events.empty? - after delay, unit, event - else - log "Attaching event to #{events[0].object_id}" - events[0].attach_event event - end - Events.add event - end - end -end diff --git a/lib/aethyr/core/commands/command_handler.rb b/lib/aethyr/core/commands/command_handler.rb deleted file mode 100644 index 53a5b5629dc0ee81ab098ec78240d2055d1fc240..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/command_handler.rb +++ /dev/null @@ -1,27 +0,0 @@ -require 'aethyr/core/commands/help_handler' - -module Aethyr - module Extend - - class InputHandler - attr_reader :player - - def initialize(player, *args) - super(*args) - @player = player - end - - def player_input(data) - false - end - end - - class CommandHandler < InputHandler - include Aethyr::Extend::HandleHelp - - def initialize(player, commands, *args) - super(player, commands, *args) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/command_parser.rb b/lib/aethyr/core/commands/command_parser.rb deleted file mode 100644 index 3d4a54b8b0919e475c86cae08a7ef5bef3959395..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/command_parser.rb +++ /dev/null @@ -1,600 +0,0 @@ -require 'set' -require 'aethyr/core/event' -require 'aethyr/core/commands/look' -require 'aethyr/core/util/direction' -include Aethyr::Direction - -#CommandParser parses commands into commands for the event handler. -module CommandParser - - @communication = Set.new([ - 'say', - 'sayto', - 'whisper', - 'tell', - 'reply' - ]) - - @movement = Set.new([ - 'sit', - 'stand', - 'pose', - 'enter', - 'climb', - 'jump', - 'crawl', - 'gait' - ]) - - @emotes = Set.new([ 'smile', - 'cheer', - 'back', - 'laugh', - 'cry', - 'emote', - 'eh', - 'er', - 'eh?', - 'uh', - 'pet', - 'hug', - 'blush', - 'ew', - 'frown', - 'grin', - 'hm', - 'snicker', - 'wave', - 'poke', - 'yes', - 'no', - 'huh', - 'hi', - 'bye', - 'yawn', - 'bow', - 'curtsey', - 'brb', - 'agree', - 'sigh', - 'ponder', - 'shrug', - 'skip', - 'nod' - ]) - - @news = Set.new(['news']) - - @weapon_combat = Set.new(['wield', 'unwield', 'slash', 'block']) - - @martial_combat = Set.new(['punch', 'kick', 'dodge']) - - @magic = Set.new - - @equipment = Set.new(['wear', 'remove']) - - @admin = Set.new(['acreate', - 'alook', - 'adesc', - 'acarea', - 'acopy', - 'acomment', - 'acomm', - 'aconfig', - 'acportal', - 'ahelp', - 'portal', - 'aset', - 'aset!', - 'adelete', - 'aforce', - 'ahide', - 'ashow', - 'ainfo', - 'aput', - 'alist', - 'alearn', - 'areas', - 'ateach', - 'areload', - 'areact', - 'awho', - 'alog', - 'astatus', - 'acroom', - 'acexit', - 'acdoor', - 'acprop', - 'asave', - 'awatch', - 'deleteplayer', - 'restart', - 'terrain', - 'whereis' - ]) - - @settings = Set.new(['set']) - - @mobile = Set.new(['teach']) - - #etc... - - class <<self - - #Creates an event to occur in the future. The event can be an event generated with CommandParser.parse or a block to be executed - #when the time elapses. - # - #If a block is given, the event parameter is ignored. - def future_event(player, seconds_delay, f_event = nil, &block) - event = Event.new(:Future, :player => player, :time => seconds_delay) - - if block_given? - event.action = :call - event.event = block - else - event.action = :event - event.event = f_event - end - - event - end - - #Parses input into a hash that can be passed to the EventHandler. - #Returns nil if the input cannot be parsed into a meaningful command. - def parse(player, input) - if input.nil? - return nil - end - - input = input.strip - - if input == "" or input.nil? - return nil - end - - command = input.split - - if command.empty? - return nil - else - command = command[0].downcase - end - - event = if @emotes.include? command - parse_emote input - elsif @movement.include? command - parse_movement input - elsif @equipment.include? command - parse_equipment input - elsif @settings.include? command - parse_settings input - elsif @admin.include? command and player.admin - parse_admin input - elsif @weapon_combat.include? command - parse_weapon_combat input - elsif @martial_combat.include? command - parse_martial_combat input - elsif @communication.include? command - parse_communication input - elsif @news.include? command - parse_news input - elsif @mobile.include? command and player.is_a? Mobile - parse_mobile command ### implement me - elsif input =~ /^alarm\s+([0-9]+)$/i - after $1.to_i do - player.output "***ALARM***" - end - elsif input =~ /^(\w+)\s+(.*)$/ - parse_custom input - end - - unless event.nil? - event.player = player - end - - event - end - - alias :create_event :parse - - private - - def parse_communication(input) - e = case input - when /^say\s+(\((.*?)\)\s*)?(.*)$/i - { :action => :say, :phrase => $3, :pre => $2 } - when /^sayto\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i - { :action => :say, :target => $1, :phrase => $4, :pre => $3 } - when /^whisper\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i - { :action => :whisper, :to => $1, :phrase => $4, :pre => $3 } - when /^tell\s+(\w+)\s+(.*)$/i - { :action => :tell, :target => $1, :message => $2 } - when /^reply\s+(.*)$/i - { :action => :reply, :message => $1 } - else - nil - end - - Event.new(:Communication, e) if e - end - - def parse_emote(input) - event = Event.new(:Emote) - - case input - when /^emote\s+(.*)/i - event[:action] = :emote - event[:show] = $1 - when /^(uh|er|eh\?|eh|shrug|sigh|ponder|agree|cry|hug|pet|smile|laugh|ew|blush|grin|frown|snicker|wave|poke|yes|no|huh|hi|bye|yawn|bow|curtsey|brb|skip|nod|back|cheer|hm)(\s+([^()]*))?(\s+\((.*)\))?$/i - event[:action] = $1.downcase.to_sym - event[:object] = $3 - event[:post] = $5 - else - return nil - end - - event - end - - def parse_movement(input) - event = Event.new(:Movement, :action => :move) - - case input - when /^gait(\s+(.*))?$/i - event[:action] = :gait - event[:phrase] = $2 if $2 - when /^(jump|climb|crawl|enter)\s+(.*)$/i - event[:action] = :enter - event[:portal_action] = $1.downcase - event[:object] = $2 - when /^sit\s+on\s+(.*)$/i, /^sit\s+(.*)$/i, /^sit$/i - event[:action] = :sit - event[:object] = $1.strip if $1 - when /^pose\s+(.*)$/i - event[:action] = :pose - event[:pose] = $1.strip - when /^stand$/i - event[:action] = :stand - when /^(jump|crawl|climb|enter)$/i - input.downcase! - return nil ### TODO: handle portal movement - else - return nil - end - - event - end - - def parse_equipment(input) - event = Event.new(:Clothing) - - case input - when /^wear\s+(\w+)(\s+on\s+(.*))?$/i - event[:action] = :wear - event[:object] = $1 - event[:position] = $3 - when /^remove\s+(\w+)(\s+from\s+(.*))?$/i - event[:action] = :remove - event[:object] = $1 - event[:position] = $3 - else - return nil - end - - event - end - - def parse_admin(input) - event = Event.new(:Admin) - - case input - when /^astatus/i - event[:action] = :astatus - when /^ahelp(.*)$/i - event[:action] = :ahelp - event[:object] = $1 - when /^awho/i - event[:action] = :awho - when /^(ac|acreate)\s+(\w+)\s*(.*)$/i - event[:action] = :acreate - event[:object] = $2 - event[:name] = $3.strip - when /^acarea\s+(.*)$/i - event[:action] = :acarea - event[:name] = $1.strip - when /^acroom\s+(\w+)\s+(.*)$/i - event[:action] = :acroom - event[:out_dir] = $1 - event[:in_dir] = opposite_dir($1) - event[:name] = $2 - when /^acexit\s+(\w+)\s+(.*)$/i - event[:action] = :acreate - event[:object] = "exit" - event[:alt_names] = [$1.strip] - event[:args] = [$2.strip] - when /^acdoor\s+(\w+)$/i - event[:action] = :acdoor - event[:direction] = $1 - when /^acdoor\s+(\w+)\s+(.*)$/i - event[:action] = :acdoor - event[:direction] = $1.strip - event[:exit_room] = $2.strip - when /^aconfig(\s+reload)?$/i - event[:action] = :aconfig - event[:setting] = "reload" if $1 - when /^aconfig\s+(\w+)\s+(.*)$/i - event[:action] = :aconfig - event[:setting] = $1 - event[:value] = $2 - when /^acportal(\s+(jump|climb|crawl|enter))?(\s+(.*))?$/i - event[:action] = :acportal - event[:object] = "portal" - event[:alt_names] = [] - event[:portal_action] = $2 - event[:args] = [$4] - when /^portal\s+(.*?)\s+(action|exit|entrance|portal)\s+(.*)$/i - event[:action] = :portal - event[:object] = $1 - event[:setting] = $2.downcase - event[:value] = $3.strip - when /^acprop\s+(.*)$/i - event[:action] = :acreate - event[:object] = "prop" - event[:generic] = $1 - when /^adelete\s+(.*)$/i - event[:action] = :adelete - event[:object] = $1 - when /^deleteplayer\s+(\w+)$/i - event[:action] = :delete_player - event[:object] = $1.downcase - when /^adesc\s+inroom\s+(.*?)\s+(.*)$/i - event[:action] = :adesc - event[:object] = $1 - event[:inroom] = true - event[:desc] = $2 - when /^adesc\s+(.*?)\s+(.*)$/i - event[:action] = :adesc - event[:object] = $1 - event[:desc] = $2 - when /^ahide\s+(.*)$/i - event[:action] = :ahide - event[:object] = $1 - event[:hide] = true - when /^ashow\s+(.*)$/i - event[:action] = :ahide - event[:object] = $1 - event[:hide] = false - when /^ainfo\s+set\s+(.+)\s+@((\w|\.|\_)+)\s+(.*?)$/i - event[:action] = :ainfo - event[:command] = "set" - event[:object] = $1 - event[:attrib] = $2 - event[:value] = $4 - when /^ainfo\s+(del|delete)\s+(.+)\s+@((\w|\.|\_)+)$/i - event[:action] = :ainfo - event[:command] = "delete" - event[:object] = $2 - event[:attrib] = $3 - when /^ainfo\s+(show|clear)\s+(.*)$/i - event[:action] = :ainfo - event[:object] = $2 - event[:command] = $1 - when /^alook$/i - event[:action] = :alook - when /^alook\s+(.*)$/i - event[:action] = :alook - event[:at] = $1 - when /^alist$/i - event[:action] = :alist - when /^alist\s+(@\w+|class)\s+(.*)/i - event[:action] = :alist - event[:attrib] = $2 - event[:match] = $1 - when /^aset\s+(.+?)\s+(@\w+|smell|feel|texture|taste|sound|listen)\s+(.*)$/i - event[:action] = :aset - event[:object] = $1 - event[:attribute] = $2 - event[:value] = $3 - when /^aset!\s+(.+?)\s+(@\w+|smell|feel|texture|taste|sound|listen)\s+(.*)$/i - event[:action] = :aset - event[:object] = $1 - event[:attribute] = $2 - event[:value] = $3 - event[:force] = true - when /^aput\s+(.*?)\s+in\s+(.*?)\s+at\s+(.*?)$/i - event[:action] = :aput - event[:object] = $1 - event[:in] = $2 - event[:at] = $3 - when /^aput\s+(.*?)\s+in\s+(.*?)$/i - event[:action] = :aput - event[:object] = $1 - event[:in] = $2 - when /^areas$/i - event[:action] = :areas - when /^areload\s+(.*)$/i - event[:action] = :areload - event[:object] = $1 - when /^areact\s+load\s+(.*?)\s+(\w+)$/i - event[:action] = :areaction - event[:object] = $1 - event[:command] = "load" - event[:file] = $2 - when /^areact\s+(add|delete)\s+(.*?)\s+(\w+)$/i - event[:action] = :areaction - event[:object] = $2 - event[:command] = $1 - event[:action_name] = $3 - when /^areact\s+(reload|clear|show)\s+(.*?)$/i - event[:action] = :areaction - event[:object] = $2 - event[:command] = $1 - when /^alog\s+(\w+)(\s+(\d+))?$/i - event[:action] = :alog - event[:command] = $1 - event[:value] = $3.downcase if $3 - when /^acopy\s+(.*)$/i - event[:action] = :acopy - event[:object] = $1 - when /^alearn\s+(\w+)$/i - event[:action] = :alearn - event[:skill] = $1 - when /^ateach\s+(\w+)\s+(\w+)$/i - event[:action] = :ateach - event[:target] = $1 - event[:skill] = $2 - when /^aforce\s+(.*?)\s+(.*)$/i - event[:action] = :aforce - event[:target] = $1 - event[:command] = $2 - when /^(acomm|acomment)\s+(.*?)\s+(.*)$/i - event[:action] = :acomment - event[:target] = $2 - event[:comment] = $3 - when /^awatch\s+((start|stop)\s+)?(.*)$/i - event[:action] = :awatch - event[:target] = $3.downcase if $3 - event[:command] = $2.downcase if $2 - when /^asave$/i - event[:action] = :asave - when /^restart$/i - event[:action] = :restart - when /^terrain\s+area\s+(.*)$/i - event[:action] = :terrain - event[:target] = "area" - event[:value] = $1 - when /^terrain\s+(room|here)\s+(type|indoors|underwater|water)\s+(.*)$/ - event[:action] = :terrain - event[:target] = "room" - event[:setting] = $2.downcase - event[:value] = $3 - when /^whereis\s(.*)$/ - event[:action] = :whereis - event[:object] = $1 - else - return nil - end - - event - end - - def parse_settings(input) - event = Event.new(:Settings) - - case input - when /^set\s+colors?\s+(on|off|default)$/i - event[:action] = :setcolor - event[:option] = $1 - when /^set\s+colors?\s+(\w+)\s+(.+)$/i - event[:action] = :setcolor - event[:option] = $1 - event[:color] = $2 - when /^set\s+colors?.*/i - event[:action] = :showcolors - when /^set\s+password$/i - event[:action] = :setpassword - when /^set\s+(\w+)\s*(.*)$/i - event[:action] = :set - event[:setting] = $1.strip - event[:value] = $2.strip if $2 - else - return nil - end - - event - end - - def parse_weapon_combat(input) - event = Event.new(:WeaponCombat) - - case input - when /^wield\s+(.*?)(\s+(\w+))?$/i - event[:action] = :wield - event[:weapon] = $1 - event[:side] = $3 - when /^unwield(\s+(.*))?$/i - event[:action] = :unwield - event[:weapon] = $2 - when /^slash$/i - event[:action] = :slash - when /^slash\s+(.*)$/i - event[:action] = :slash - event[:target] = $1 - when /^block(\s+(.*))?$/i - event[:action] = :simple_block - event[:target] = $2 - else - return nil - end - - event - end - - def parse_custom(input) - if input =~ /^(\w+)\s+(.*)$/ - event = Event.new(:Custom) - event[:action] = :custom - event[:custom_action] = $1 - event[:target] = $2 - event - else - nil - end - end - - def parse_news(input) - event = Event.new(:News) - - case input.downcase - when "news" - event.action = :latest_news - when /^news\s+last\s+(\d+)/i - event.action = :latest_news - event.limit = $1.to_i - when /^news\s+(read\s+)?(\d+)$/i - event.action = :read_post - event.post_id = $2 - when /^news\s+write$/i - event.action = :write_post - when /^news\s+reply(\s+to\s+)?\s+(\d+)$/i - event.action = :write_post - event.reply_to = $2 - when /^news\s+delete\s+(\d+)/i - event.action = :delete_post - event.post_id = $1 - when /^news\s+unread/i - event.action = :list_unread - when /^news\s+all/i - event.action = :all - else - return nil - end - - event - end - - def parse_martial_combat(input) - event = Event.new(:MartialCombat) - - case input - when /^punch$/i - event.action = :punch - when /^punch\s+(.*)$/i - event.action = :punch - event.target = $1 - when /^kick$/i - event.action = :kick - when /^kick\s+(.*)$/i - event.action = :kick - event.target = $1 - when /^dodge(\s+(.*))?$/i - event.action = :simple_dodge - event.target = $2 if $2 - else - return nil - end - - event - end - end -end diff --git a/lib/aethyr/core/commands/communication.rb b/lib/aethyr/core/commands/communication.rb deleted file mode 100644 index 98dd7dd4fcd282da043fa01dc66e10f0a80490f7..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/communication.rb +++ /dev/null @@ -1,190 +0,0 @@ -#Communication commands. -module Communication - class << self - #Says something to the room or to a specific player. - def say(event, player, room) - phrase = event[:phrase] - target = event[:target] && room.find(event[:target]) - prefix = event[:pre] - - if prefix - prefix << ", " - else - prefix = "" - end - - if phrase.nil? - player.output("Huh?") - return - elsif event[:target] and target.nil? - player.output("Say what to whom?") - return - elsif target and target == player - player.output "Talking to yourself again?" - return - elsif target - to_clause = " to #{target.name}" - ask_clause = " #{target.name}" - else - to_clause = "" - ask_clause = "" - end - - phrase[0,1] = phrase[0,1].capitalize - phrase.gsub!(/(\s|^|\W)(i)(\s|$|\W)/) { |match| match.sub('i', 'I') } - - case phrase - when /:\)$/ - rvoice = "smiles and " - pvoice = "smile and " - when /:\($/ - rvoice = "frowns and " - pvoice = "frown and " - when /:D$/ - rvoice = "laughs as #{player.pronoun} " - pvoice = "laugh as you " - else - rvoice = "" - pvoice = "" - end - - phrase = phrase.gsub(/\s*(:\)|:\()|:D/, '').strip.gsub(/\s{2,}/, ' ') - - case phrase[-1..-1] - when "!" - pvoice += "exclaim" - rvoice += "exclaims" - when "?" - pvoice += "ask" - rvoice += "asks" - when "." - pvoice += "say" - rvoice += "says" - else - pvoice += "say" - rvoice += "says" - ender = "." - end - - phrase = "<say>\"#{phrase}#{ender}\"</say>" - - event[:target] = target - if target and pvoice == "ask" - event[:to_target] = prefix + "#{player.name} #{rvoice} you, #{phrase}" - event[:to_player] = prefix + "you #{pvoice} #{target.name}, #{phrase}" - event[:to_other] = prefix + "#{player.name} #{rvoice} #{target.name}, #{phrase}" - event[:to_blind_target] = "Someone asks, #{phrase}" - event[:to_blind_other] = "Someone asks, #{phrase}" - event[:to_deaf_target] = "#{player.name} seems to be asking you something." - event[:to_deaf_other] = "#{player.name} seems to be asking #{target.name} something." - elsif target - event[:to_target] = prefix + "#{player.name} #{rvoice} to you, #{phrase}" - event[:to_player] = prefix + "you #{pvoice} to #{target.name}, #{phrase}" - event[:to_other] = prefix + "#{player.name} #{rvoice} to #{target.name}, #{phrase}" - event[:to_blind_target] = "Someone #{rvoice}, #{phrase}" - event[:to_blind_other] = "Someone #{rvoice}, #{phrase}" - event[:to_deaf_target] = "You see #{player.name} say something to you." - event[:to_deaf_other] = "You see #{player.name} say something to #{target.name}." - else - event[:to_player] = prefix + "you #{pvoice}, #{phrase}" - event[:to_other] = prefix + "#{player.name} #{rvoice}, #{phrase}" - event[:to_blind_other] = "Someone #{rvoice}, #{phrase}" - event[:to_deaf_target] = "You see #{player.name} say something." - event[:to_deaf_other] = "You see #{player.name} say something." - end - - room.out_event(event) - end - - #Whispers to another thing. - def whisper(event, player, room) - object = room.find(event[:to], Player) - - if object.nil? - player.output("To whom are you trying to whisper?") - return - elsif object == player - player.output("Whispering to yourself again?") - event[:to_other] = "#{player.name} whispers to #{player.pronoun(:reflexive)}." - room.out_event(event, player) - return - end - - phrase = event[:phrase] - - if phrase.nil? - player.ouput "What are you trying to whisper?" - return - end - - prefix = event[:pre] - - if prefix - prefix << ", " - else - prefix = "" - end - - phrase[0,1] = phrase[0,1].capitalize - - last_char = phrase[-1..-1] - - unless ["!", "?", "."].include? last_char - ender = "." - end - - phrase = ", <say>\"#{phrase}#{ender}\"</say>" - - event[:target] = object - event[:to_player] = prefix + "you whisper to #{object.name}#{phrase}" - event[:to_target] = prefix + "#{player.name} whispers to you#{phrase}" - event[:to_other] = prefix + "#{player.name} whispers quietly into #{object.name}'s ear." - event[:to_other_blind] = "#{player.name} whispers." - event[:to_target_blind] = "Someone whispers to you#{phrase}" - - room.out_event(event) - end - - #Tells someone something. - def tell(event, player, room) - target = $manager.find event[:target] - unless target and target.is_a? Player - player.output "That person is not available." - return - end - - if target == player - player.output "Talking to yourself?" - return - end - - phrase = event[:message] - - last_char = phrase[-1..-1] - - unless ["!", "?", "."].include? last_char - phrase << "." - end - - phrase[0,1] = phrase[0,1].upcase - phrase = phrase.strip.gsub(/\s{2,}/, ' ') - - player.output "You tell #{target.name}, <tell>\"#{phrase}\"</tell>" - target.output "#{player.name} tells you, <tell>\"#{phrase}\"</tell>" - target.reply_to = player.name - end - - #Reply to a tell. - def reply(event, player, room) - unless player.reply_to - player.output "There is no one to reply to." - return - end - - event[:target] = player.reply_to - - tell(event, player, room) - end - end -end - diff --git a/lib/aethyr/core/commands/custom.rb b/lib/aethyr/core/commands/custom.rb deleted file mode 100644 index 34cc95e0083071844f2574f779f3708138b19164..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/custom.rb +++ /dev/null @@ -1,25 +0,0 @@ -#Handles custom actions for objects -module Custom - class << self - - #Check for and handle custom commands. - def custom(event, player, room) - object = player.search_inv(event[:target]) || room.find(event[:target]) - if object.nil? - player.output "Not sure what you are talking about." - return - elsif not object.actions.include? event[:custom_action] - player.output "You cannot do that to #{object.name}." - return - elsif object.can? event[:custom_action].to_sym - object.send(event[:custom_action].to_sym, event, player, room) - elsif object.is_a? Reacts - event.action = event[:custom_action].to_sym - object.alert(event) - else - player.output "Nothing happens." - end - end - - end -end diff --git a/lib/aethyr/core/commands/drop.rb b/lib/aethyr/core/commands/drop.rb deleted file mode 100644 index 676b1a20fb0eb88d46bb3a183a5a9b960b58d396..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/drop.rb +++ /dev/null @@ -1,72 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Drop - class DropHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["drop"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(DropHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^drop\s+((\w+\s*)*)$/i - action({ :object => $1.strip }) - when /^help drop$/i - action_help({}) - end - end - - private - #Drops an item from the player's inventory into the room. - def action(event) - room = $manager.get_object(@player.container) - object = @player.inventory.find(event[:object]) - - if object.nil? - if response = @player.equipment.worn_or_wielded?(event[:object]) - @player.output response - else - @player.output "You have no #{event[:object]} to drop." - end - - return - end - - @player.inventory.remove(object) - - object.container = room.goid - room.add(object) - - event[:to_player] = "You drop #{object.name}." - event[:to_other] = "#{@player.name} drops #{object.name}." - event[:to_blind_other] = "You hear something hit the ground." - room.out_event(event) - end - - def action_help(event) - @player.output <<'EOF' -Command: Drop -Syntax: DROP [object] - -Removes an object from your inventory and places it gently on the ground. - -See also: GET, TAKE, GRAB - -EOF - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(DropHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/emote.rb b/lib/aethyr/core/commands/emote.rb deleted file mode 100644 index 7c0de15828e8264e0e8a32d371a695042e145fc8..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/emote.rb +++ /dev/null @@ -1,950 +0,0 @@ -#Contains all the emote actions -module Emote - class << self - #Do an emote - def emote(event, player, room) - action = event[:show].strip - - unless ['!', '.', '?', '"'].include? action[-1..-1] - action << '.' - end - - if action =~ /\$me[^a-zA-Z]/i - action.gsub!(/\$me/i, player.name) - action[0,1] = action[0,1].capitalize - show = action - elsif action.include? '$' - people = [] - action.gsub!(/\$(\w+)/) do |name| - target = room.find($1) - people << target unless target.nil? - target ? target.name : 'no one' - end - - people.each do |person| - out = action.gsub(person.name, 'you') - person.output("#{player.name} #{out}") unless person.can? :blind and person.blind? - end - - room.output("#{player.name} #{action}", player, *people) - player.output("You emote: #{player.name} #{action}") - else - show = "#{player.name} #{action}" - end - - if show - event.to_player = "You emote: #{show}" - event.to_other = show - room.out_event event - end - end - - #Smile - def smile(event, player, room) - - make_emote event, player, room do - - self_target do - to_player "You smile happily at yourself." - to_other "#{player.name} smiles at #{player.pronoun(:reflexive)} sillily." - end - - target do - to_player "You smile at #{event.target.name} kindly." - to_target "#{player.name} smiles at you kindly." - to_other "#{player.name} smiles at #{event.target.name} kindly." - end - - no_target do - to_player "You smile happily." - to_other "#{player.name} smiles happily." - end - end - end - - def eh(event, player, room) - make_emote event, player, room do - target do - to_player "After giving #{event.target.name} a cursory glance, you emit an unimpressed, 'Eh.'" - to_other "#{player.name} gives #{event.target.name} a cursory glance and then emits an unimpressed, 'Eh.'" - to_target "#{player.name} gives you a cursory glance and then emits an unimpressed, 'Eh.'" - end - - no_target do - to_player "After a brief consideration, you give an unimpressed, 'Eh.'" - to_other "#{player.name} appears to consider for a moment before giving an unimpressed, 'Eh.'" - end - end - end - - def eh?(event, player, room) - - make_emote event, player, room do - no_target do - to_player "Thoughtfully, you murmur, \"Eh?\"" - to_other "#{player.name} murmurs, \"Eh?\" with a thoughtful appearance." - end - - target do - to_player "Looking perplexed, you ask #{target.name}, \"Eh?\"" - to_other "\"Eh?\" #{player.name} asks #{target.name}, looking perplexed." - to_target "\"Eh?\" #{player.name} asks you, with a perplexed expression." - end - end - end - - def er(event, player, room) - make_emote event, player, room do - no_target do - to_player "With a look of uncertainty, you say, \"Er...\"" - to_other "With a look of uncertainty, #{player.name} says, \"Er...\"" - end - - target do - to_player "Looking at #{target.name} uncertainly, you say, \"Er...\"" - to_other "Looking at #{target.name} uncertainly, #{player.name} says, \"Er...\"" - to_target "Looking at you uncertainly, #{player.name} says, \"Er...\"" - end - end - end - - def uh(event, player, room) - make_emote event, player, room do - no_target do - to_player "\"Uh...\" you say, staring blankly." - to_other "With a blank stare, #{player.name} says, \"Uh...\"" - end - - target do - to_player "With a blank stare at #{target.name}, you say, \"Uh...\"" - to_other "With a blank stare at #{target.name}, #{player.name} says, \"Uh...\"" - to_target "Staring blankly at you, #{player.name} says, \"Uh...\"" - end - end - end - - #Laugh laugh laugh - def laugh(event, player, room) - - make_emote event, player, room do - - self_target do - to_player "You laugh heartily at yourself." - to_other "#{player.name} laughs heartily at #{player.pronoun(:reflexive)}." - to_blind_other "Someone laughs heartily." - end - - target do - to_player "You laugh at #{event.target.name}." - to_target "#{player.name} laughs at you." - to_other "#{player.name} laughs at #{event.target.name}" - to_blind_target "Someone laughs in your direction." - to_blind_other "You hear someone laughing." - end - - no_target do - to_player "You laugh." - to_other "#{player.name} laughs." - to_blind_other "You hear someone laughing." - to_deaf_other "You see #{player.name} laugh." - end - end - - end - - #Weepiness - def cry(event, player, room) - - make_emote event, player, room do - - default do - to_player "Tears run down your face as you cry pitifully." - to_other "Tears run down #{player.name}'s face as #{player.pronoun} cries pitifully." - end - end - end - - def skip(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You skip around cheerfully." - to_other "#{player.name} skips around cheerfully." - to_deaf_other "#{player.name} skips around cheerfully." - end - - self_target do - player.output 'How?' - end - - target do - to_player "You skip around #{event.target.name} cheerfully." - to_target "#{player.name} skips around you cheerfully." - to_other "#{player.name} skips around #{event.target.name} cheerfully." - to_deaf_other "#{player.name} skips around #{event.target.name} cheerfully." - end - - end - end - - def pet(event, player, room) - - make_emote event, player, room do - - no_target do - player.output "Who are you trying to pet?" - end - - self_target do - to_player 'You pet yourself on the head in a calming manner.' - to_other "#{player.name} pets #{player.pronoun(:reflexive)} on the head in a calming manner." - to_deaf_other "#{player.name} pets #{player.pronoun(:reflexive)} on the head in a calming manner." - end - - target do - to_player "You pet #{event.target.name} affectionately." - to_target "#{player.name} pets you affectionately." - to_deaf_target event[:to_target] - to_blind_target "Someone pets you affectionately." - to_other "#{player.name} pets #{event.target.name} affectionately." - to_deaf_other event[:to_other] - end - end - end - - def nod(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You nod your head." - to_other "#{player.name} nods #{player.pronoun(:possessive)} head." - to_deaf_other event[:to_other] - end - - self_target do - to_player 'You nod to yourself thoughtfully.' - to_other "#{player.name} nods to #{player.pronoun(:reflexive)} thoughtfully." - to_deaf_other event[:to_other] - end - - target do - - to_player "You nod your head towards #{event.target.name}." - to_target "#{player.name} nods #{player.pronoun(:possessive)} head towards you." - to_other "#{player.name} nods #{player.pronoun(:possessive)} head towards #{event.target.name}." - to_deaf_other event[:to_other] - end - end - end - - def hug(event, player, room) - - make_emote event, player, room do - - no_target do - player.output "Who are you trying to hug?" - end - - self_target do - to_player 'You wrap your arms around yourself and give a tight squeeze.' - to_other "#{player.name} gives #{player.pronoun(:reflexive)} a tight squeeze." - to_deaf_other event[:to_other] - end - - target do - to_player "You give #{event.target.name} a great big hug." - to_target "#{player.name} gives you a great big hug." - to_other "#{player.name} gives #{event.target.name} a great big hug." - to_blind_target "Someone gives you a great big hug." - to_deaf_other event[:to_other] - end - end - end - - def grin(event, player, room) - - make_emote event, player, room do - - no_target do - to_player 'You grin widely, flashing all your teeth.' - to_other "#{player.name} grins widely, flashing all #{player.pronoun(:possessive)} teeth." - to_deaf_other event[:to_other] - end - - self_target do - to_player "You grin madly at yourself." - to_other "#{player.name} grins madly at #{event.target.pronoun(:reflexive)}." - to_deaf_other event[:to_other] - end - - target do - to_player "You give #{event.target.name} a wide grin." - to_target "#{player.name} gives you a wide grin." - to_deaf_target event[:to_target] - to_other "#{player.name} gives #{event.target.name} a wide grin." - to_deaf_other event[:to_other] - end - - end - end - - def frown(event, player, room) - - make_emote event, player, room do - no_target do - to_player "The edges of your mouth turn down as you frown." - to_other "The edges of #{player.name}'s mouth turn down as #{player.pronoun} frowns." - to_deaf_other event[:to_other] - end - - self_target do - to_player "You frown sadly at yourself." - to_other "#{player.name} frowns sadly at #{event.target.pronoun(:reflexive)}." - to_deaf_other event[:to_other] - end - - target do - to_player "You frown at #{event.target.name} unhappily." - to_target "#{player.name} frowns at you unhappily." - to_deaf_target event[:to_target] - to_other "#{player.name} frowns at #{event.target.name} unhappily." - to_deaf_other event[:to_other] - end - end - - end - - def blush(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You feel the blood rush to your cheeks and you look down, blushing." - to_other "#{player.name}'s face turns bright red as #{player.pronoun} looks down, blushing." - to_deaf_other event[:to_other] - end - - self_target do - to_player "You blush at your foolishness." - to_other "#{player.name} blushes at #{event.target.pronoun(:possessive)} foolishness." - to_deaf_other event[:to_other] - end - - target do - to_player "Your face turns red and you blush at #{event.target.name} uncomfortably." - to_target "#{player.name} blushes in your direction." - to_deaf_target event[:to_target] - to_other "#{player.name} blushes at #{event.target.name}, clearly uncomfortable." - to_deaf_other event[:to_other] - end - end - end - - def ew(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "\"Ewww!\" you exclaim, looking disgusted." - to_other "#{player.name} exclaims, \"Eww!!\" and looks disgusted." - to_deaf_other "#{player.name} looks disgusted." - to_blind_other "Somone exclaims, \"Eww!!\"" - end - - self_target do - player.output "You think you are digusting?" - end - - target do - to_player "You glance at #{event.target.name} and say \"Ewww!\"" - to_target "#{player.name} glances in your direction and says, \"Ewww!\"" - to_deaf_other "#{player.name} gives #{event.target.name} a disgusted look." - to_blind_other "Somone exclaims, \"Eww!!\"" - to_other "#{player.name} glances at #{event.target.name}, saying \"Ewww!\"" - end - end - end - - def snicker(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You snicker softly to yourself." - to_other "You hear #{player.name} snicker softly." - to_blind_other "You hear someone snicker softly." - end - - self_target do - player.output "What are you snickering about?" - end - - target do - to_player "You snicker at #{event.target.name} under your breath." - to_target "#{player.name} snickers at you under #{player.pronoun(:possessive)} breath." - to_other "#{player.name} snickers at #{event.target.name} under #{player.pronoun(:possessive)} breath." - end - end - - end - - def wave(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You wave goodbye to everyone." - to_other "#{player.name} waves goodbye to everyone." - end - - self_target do - player.output "Waving at someone?" - end - - target do - to_player "You wave farewell to #{event.target.name}." - to_target "#{player.name} waves farewell to you." - to_other "#{player.name} waves farewell to #{event.target.name}." - end - end - end - - def poke(event, player, room) - - make_emote event, player, room do - - no_target do - player.output "Who are you trying to poke?" - end - - self_target do - to_player "You poke yourself in the eye. 'Ow!'" - to_other "#{player.name} pokes #{player.pronoun(:reflexive)} in the eye." - to_deaf_other event[:to_other] - end - - target do - to_player "You poke #{event.target.name} playfully." - to_target "#{player.name} pokes you playfully." - to_blind_target "Someone pokes you playfully." - to_deaf_target event[:to_target] - to_other "#{player.name} pokes #{event.target.name} playfully." - to_deaf_other event[:to_other] - end - end - end - - def yes(event, player, room) - make_emote event, player, room do - - no_target do - to_player "\"Yes,\" you say, nodding." - to_other "#{player.name} says, \"Yes\" and nods." - end - - self_target do - to_player "You nod in agreement with yourself." - to_other "#{player.name} nods at #{player.pronoun(:reflexive)} strangely." - to_deaf_other event[:to_other] - end - - target do - to_player "You nod in agreement with #{event.target.name}." - to_target "#{player.name} nods in your direction, agreeing." - to_other "#{player.name} nods in agreement with #{event.target.name}." - to_deaf_other event[:to_other] - end - end - - end - - def no(event, player, room) - make_emote event, player, room do - no_target do - to_player "\"No,\" you say, shaking your head." - to_other "#{player.name} says, \"No\" and shakes #{player.pronoun(:possessive)} head." - end - self_target do - to_player "You shake your head negatively in your direction. You are kind of strange." - to_other "#{player.name} shakes #{player.pronoun(:possessive)} head at #{player.pronoun(:reflexive)}." - to_deaf_other event[:to_other] - end - target do - to_player "You shake your head, disagreeing with #{event.target.name}." - to_target "#{player.name} shakes #{player.pronoun(:possessive)} head in your direction, disagreeing." - to_other "#{player.name} shakes #{player.pronoun(:possessive)} head in disagreement with #{event.target.name}." - to_deaf_other event[:to_other] - end - end - - end - - def huh(event, player, room) - make_emote event, player, room do - - no_target do - to_player "\"Huh?\" you ask, confused." - to_other "#{player.name} ask, \"Huh?\" and looks confused." - end - - self_target do - player.output "Well, huh!" - end - - target do - to_player "\"Huh?\" you ask #{event.target.name}." - to_target "#{player.name} asks, \"Huh?\"" - to_other "#{player.name} asks #{event.target.name}, \"Huh?\"" - end - end - - end - - def hi(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "\"Hi!\" you greet those around you." - to_other "#{player.name} greets those around with a \"Hi!\"" - end - - self_target do - player.output "Hi." - end - - target do - to_player "You say \"Hi!\" in greeting to #{event.target.name}." - to_target "#{player.name} greets you with a \"Hi!\"" - to_other "#{player.name} greets #{event.target.name} with a hearty \"Hi!\"" - end - end - - end - - def bye(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You say a hearty \"Goodbye!\" to those around you." - to_other "#{player.name} says a hearty \"Goodbye!\"" - end - - self_target do - player.output "Goodbye." - end - - target do - to_player "You say \"Goodbye!\" to #{event.target.name}." - to_target "#{player.name} says \"Goodbye!\" to you." - to_other "#{player.name} says \"Goodbye!\" to #{event.target.name}" - end - end - - end - - def yawn(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You open your mouth in a wide yawn, then exhale loudly." - to_other "#{player.name} opens #{player.pronoun(:possessive)} mouth in a wide yawn, then exhales loudly." - end - - self_target do - to_player "You yawn at how boring you are." - to_other "#{player.name} yawns at #{player.pronoun(:reflexive)}." - to_deaf_other event[:to_other] - end - - target do - to_player "You yawn at #{event.target.name}, bored out of your mind." - to_target "#{player.name} yawns at you, finding you boring." - to_other "#{player.name} yawns at how boring #{event.target.name} is." - to_deaf_other event[:to_other] - end - end - - end - - def bow(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You bow deeply and respectfully." - to_other "#{player.name} bows deeply and respectfully." - to_deaf_other event[:to_other] - end - - self_target do - player.output "Huh?" - end - - target do - to_player "You bow respectfully towards #{event.target.name}." - to_target "#{player.name} bows respectfully before you." - to_other "#{player.name} bows respectfully towards #{event.target.name}." - to_deaf_other event[:to_other] - end - end - - end - - def curtsey(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You perform a very graceful curtsey." - to_other "#{player.name} curtseys quite gracefully." - to_deaf_other event[:to_other] - end - - self_target do - player.output "Hm? How do you do that?" - end - - target do - to_player "You curtsey gracefully and respectfully towards #{event.target.name}." - to_target "#{player.name} curtseys gracefully and respectfully in your direction." - to_other "#{player.name} curtseys gracefully and respectfully towards #{event.target.name}." - to_deaf_other event[:to_other] - end - - end - end - - def ponder(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You ponder that idea for a moment." - to_other "#{player.name} looks thoughtful as #{player.pronoun} ponders a thought." - to_deaf_other event[:to_other] - end - - self_target do - to_player "You look down in deep thought at your navel." - to_other "#{player.name} looks down thoughtfully at #{player.pronoun(:possessive)} navel." - to_deaf_other event[:to_other] - end - - target do - to_player "You give #{event.target.name} a thoughtful look as you reflect and ponder." - to_target "#{player.name} gives you a thoughtful look and seems to be reflecting upon something." - to_other "#{player.name} gives #{event.target.name} a thoughtful look and appears to be absorbed in reflection." - to_deaf_other event[:to_other] - end - end - end - - def sigh(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You exhale, sighing deeply." - to_other "#{player.name} breathes out a deep sigh." - end - - self_target do - to_player "You sigh at your misfortunes." - to_other "#{player.name} sighs at #{player.pronoun(:possessive)} own misfortunes." - end - - target do - to_player "You sigh in #{event.target.name}'s general direction." - to_target "#{player.name} heaves a sigh in your direction." - to_other "#{player.name} sighs heavily in #{event.target.name}'s direction." - end - end - - end - - def agree(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You nod your head in agreement." - to_other "#{player.name} nods #{player.pronoun(:possessive)} head in agreement." - to_deaf_other event[:to_other] - end - - self_target do - to_player "You are in complete agreement with yourself." - to_other "#{player.name} nods at #{player.pronoun(:reflexive)}, apparently in complete agreement." - to_deaf_other event[:to_other] - end - - target do - to_player "You nod your head in agreement with #{event.target.name}." - to_target "#{player.name} nods #{player.pronoun(:possessive)} head in agreement with you." - to_other "#{player.name} nods #{player.pronoun(:possessive)} head in agreement with #{event.target.name}." - to_deaf_other event[:to_other] - end - end - - end - - def shrug(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You shrug your shoulders." - to_other "#{player.name} shrugs #{player.pronoun(:possessive)} shoulders." - to_deaf_other event[:to_other] - end - - self_target do - player.output "Don't just shrug yourself off like that!" - - end - - target do - to_player "You give #{event.target.name} a brief shrug." - to_target "#{player.name} gives you a brief shrug." - to_other "#{player.name} gives #{event.target.name} a brief shrug." - to_deaf_other event[:to_other] - to_deaf_target event[:to_target] - end - end - - end - - def brb(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "\"I shall return shortly!\" you say to no one in particular." - to_other "#{player.name} says, \"I shall return shortly!\" to no one in particular." - to_blind_other "Someone says, \"I shall return shortly!\"" - end - - self_target do - player.output "Hm? How do you do that?" - end - - target do - to_player "You let #{event.target.name} know you will return shortly." - to_target "#{player.name} lets you know #{player.pronoun} will return shortly." - to_other "#{player.name} tells #{event.target.name} that #{player.pronoun} will return shortly." - to_blind_other "Someone says, \"I shall return shortly!\"" - end - end - - end - - def back(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "\"I'm back!\" you happily announce." - to_other "\"I'm back!\" #{player.name} happily announces to those nearby." - to_blind_other "Someone announces, \"I'm back!\"" - end - - self_target do - player.output "Hm? How do you do that?" - end - - target do - to_player "You happily announce your return to #{event.target.name}." - to_target "#{player.name} happily announces #{player.pronoun(:possessive)} return to you." - to_other "#{player.name} announces #{player.pronoun(:possessive)} return to #{event.target.name}." - to_blind_other "Someone says, \"I shall return shortly!\"" - end - end - end - - def cheer(event, player, room) - - make_emote event, player, room do - - no_target do - to_player "You throw your hands in the air and cheer wildly!" - to_other "#{player.name} throws #{player.pronoun(:possessive)} hands in the air as #{player.pronoun} cheers wildy!" - to_blind_other "You hear someone cheering." - end - - self_target do - player.output "Hm? How do you do that?" - end - - target do - to_player "Beaming at #{event.target.name}, you throw your hands up and cheer for #{event.target.pronoun(:objective)}." - to_target "Beaming at you, #{player.name} throws #{player.pronoun(:possessive)} hands up and cheers for you." - to_other "#{player.name} throws #{player.pronoun(:possessive)} hands up and cheers for #{event.target.name}." - to_blind_other "You hear someone cheering." - end - end - end - - def hm(event, player, room) - - make_emote event, player, room do - - no_target do - to_other "#{player.name} purses #{player.pronoun(:possessive)} lips thoughtfully and says, \"Hmmm...\"" - to_player "You purse your lips thoughtfully and say, \"Hmmm...\"" - end - - self_target do - to_other "#{player.name} looks down at #{player.pronoun(:reflexive)} and says, \"Hmmm...\"" - to_player "You look down at yourself and say, \"Hmmm...\"" - end - - target do - to_other "#{player.name} purses #{player.pronoun(:possessive)} lips as #{player.pronoun} looks thoughtfully at #{event.target.name} and says, \"Hmmm...\"" - to_player "You purse your lips as you look thoughtfully at #{event.target.name} and say, \"Hmmm...\"" - to_target "#{player.name} purses #{player.pronoun(:possessive)} lips as #{player.pronoun} looks thoughtfully at you and says, \"Hmmm...\"" - end - end - - end - - private - - #Run an emote. - def make_emote event, player, room, &block - g = GenericEmote.new(event, player, room) - g.instance_eval(&block) - if g.return_event and g.return_event.is_a? Event - g.set_post #add postfix - log "Doing event" , Logger::Ultimate - room.out_event g.return_event - end - end - end - - #Provides little DSL to easily create emotes. - class GenericEmote - - attr_reader :return_event - - def initialize(event, player, room) - @event = event - @player = player - @room = room - @post = event[:post] - @object = nil - @return_event = nil - find_target - end - - #If there is no target, return the given block. - def no_target - return if @return_event - - if @object.nil? - @return_event = yield - end - end - - #If the target is the player, return the given block. - def self_target - return if @return_event - - if @object == @player - @return_event = yield - end - end - - #If there is a target, return the given block. - def target - return if @return_event - - unless @object.nil? - @return_event = yield - end - end - - #If nothing else matches, return the given block. - def default - @return_event = yield - end - - #Provide output to show player. - def to_player output - @event.to_player = output - @event - end - - #Provide output to show others. - def to_other output - @event.to_other = output - @event - end - - #Provide output to show target. - def to_target output - @event.to_target = output - @event - end - - #Provide output to show blind others. - def to_blind_other output - @event.to_blind_other = output - @event - end - - #Provide output to show deaf others. - def to_deaf_other output - @event.to_deaf_other = output - @event - end - - #Provide output to show blind target. - def to_blind_target output - @event.to_blind_target = output - @event - end - - #Provide output to show deaf target. - def to_deaf_target output - @event.to_deaf_target = output - @event - end - - #Appends suffix to emote. - def set_post - return if not @post - [:to_player, :to_other, :to_target, :to_blind_other, :to_blind_target, :to_deaf_other, :to_deaf_target].each do |t| - if @return_event[t] - if @return_event[t][-1,1] == "." - @return_event[t][-1] = "" - end - - if @post[0,1] == "," - @return_event[t] << @post - else - @return_event[t] << " " << @post - end - - unless ["!", "?", ".", "\"", "'"].include? @post[-1,1] - @return_event[t] << "." - end - end - end - end - - private - - #Find target for emote. - def find_target - if @object.nil? and @event[:object] - @object = @room.find(@event[:object]) || @player.search_inv(@event[:object]) - @event[:target] = @object - end - end - end -end diff --git a/lib/aethyr/core/commands/generic.rb b/lib/aethyr/core/commands/generic.rb deleted file mode 100644 index f820393605b8e2ae2394ff65cc1812b946914e94..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/generic.rb +++ /dev/null @@ -1,484 +0,0 @@ -require 'aethyr/core/issues' -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Generic - class GenericHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ['date', 'delete', 'feel', 'taste', 'smell', 'sniff', 'lick', 'listen', 'health', 'hunger', 'satiety', 'shut', 'status', 'stat', 'st', 'time', 'typo', 'who', 'write']) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(GenericHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^delete me please$/i - action_deleteme({}) - when /^(health)$/i - action_health({}) - when /^(satiety|hunger)$/i - action_satiety({}) - when /^(st|stat|status)$/i - action_status({}) - when /^write\s+(.*)/i - action_write({ :target => $1.strip}) - when /^(listen)(\s+(.+))?$/i - action_listen({ :target => $3}) - when /^(smell|sniff)(\s+(.+))?$/i - action_smell({ :target => $3}) - when /^(taste|lick)(\s+(.+))?$/i - action_taste({ :target => $3}) - when /^(feel)(\s+(.+))?$/i - action_feel({ :target => $3}) - when /^fill\s+(\w+)\s+from\s+(\w+)$/i - action_fill({ :object => $1, - :from => $2}) - when /^who$/i - action_who({}) - when /^time$/i - action_time({}) - when /^date$/i - action_date({}) - when /^help (delete|delete me please)$/i - action_help_deleteme({}) - when /^help health$/i - action_help_health({}) - when /^help (satiety|hunger)$/i - action_help_satiety({}) - when /^help (st|stat|status)$/i - action_help_status({}) - when /^help write/i - action_help_write({ :target => $1.strip}) - when /^help listen$/i - action_help_listen({ :target => $3}) - when /^help (smell|sniff)$/i - action_help_smell({ :target => $3}) - when /^help (taste|lick)$/i - action_help_taste({ :target => $3}) - when /^help feel$/i - action_help_feel({ :target => $3}) - when /^help who$/i - action_help_who({}) - when /^help (date|time)$/i - action_help_date_time({}) - when /^help fill$/i - action_help_fill({}) - end - end - - private - #Display health. - def action_health(event) - @player.output "You are #{@player.health}." - end - - def action_help_health(event) - @player.output <<'EOF' -Command: Health -Syntax: HEALTH - -Shows you how healthy you are. - -You can be: - at full health - a bit bruised - a little beat up - slightly injured - quite injured - slightly wounded - wounded in several places - heavily wounded - bleeding profusely and in serious pain - nearly dead - dead - -See also: STATUS, HUNGER - -EOF - end - - #Display hunger. - def action_satiety(event) - @player.output "You are #{@player.satiety}." - end - - def action_help_satiety(event) - @player.output <<'EOF' -Command: Hunger (or Satiety) -Syntax: HUNGER -Syntax: SATIETY - -Shows you how hungry you are. - -You can be: - completely stuffed - full and happy - full and happy - satisfied - not hungry - slightly hungry - slightly hungry - peckish - hungry - very hungry - famished - starving - literally dying of hunger - -See also: STAT HEALTH - -EOF - end - - #Display status. - def action_status(event) - @player.output("You are #{@player.health}.", true) - @player.output("You are feeling #{@player.satiety}.", true) - @player.output "You are currently #{@player.pose || 'standing up'}." - end - - def action_help_status(event) - @player.output <<'EOF' -Command: Status -Syntax: STATUS -Syntax: STAT -Syntax: ST - -Shows your current health, hunger/satiety, and position. - -See also: INVENTORY, HUNGER, HEALTH - -EOF - end - - #Fill something. - def action_fill(event) - room = $manager.get_object(@player.container) - object = @player.search_inv(event[:object]) || room.find(event[:object]) - from = @player.search_inv(event[:from]) || room.find(event[:from]) - - if object.nil? - @player.output("What would you like to fill?") - return - elsif not object.is_a? LiquidContainer - @player.output("You cannot fill #{object.name} with liquids.") - return - elsif from.nil? - @player.output "There isn't any #{event[:from]} around here." - return - elsif not from.is_a? LiquidContainer - @player.output "You cannot fill #{object.name} from #{from.name}." - return - elsif from.empty? - @player.output "That #{object.generic} is empty." - return - elsif object.full? - @player.output("That #{object.generic} is full.") - return - elsif object == from - @player.output "Quickly flipping #{object.name} upside-down then upright again, you manage to fill it from itself." - return - end - end - - def action_help_fill(event) - @player.output <<'EOF' -Command: Fill -Syntax: FILL [container] FROM [source] - -Fill a container from a source - -EOF - end - - #Display time. - def action_time(event) - @player.output $manager.time - end - - #Display date. - def action_date(event) - @player.output $manager.date - end - - def action_help_date_time(event) - @player.output <<'EOF' -Date and Time - -Syntax: DATE - TIME - -Shows the current date and time in Aethyr. Not completely done yet, but it is a first step. - -EOF - end - - #Show who is in the game. - def action_who(event) - players = $manager.find_all("class", Player) - output = ["The following people are visiting Aethyr:"] - players.sort_by {|p| p.name}.each do |playa| - room = $manager.find playa.container - output << "#{playa.name} - #{room.name if room}" - end - - @player.output output - end - - def action_help_who(event) - @player.output <<'EOF' -Command: Who -Syntax: WHO - -This will list everyone else who is currently in Aethyr and where they happen to be at the moment. - -EOF - end - - #Delete your player. - def action_deleteme(event) - if event[:password] - if $manager.check_password(@player.name, event[:password]) - @player.output "This character #{@player.name} will no longer exist." - @player.quit - $manager.delete_player(@player.name) - else - @player.output "That password is incorrect. You are allowed to continue existing." - end - else - @player.output "To confirm your deletion, please enter your password:" - @player.io.echo_off - @player.expect do |password| - @player.io.echo_on - event[:password] = password - Generic.deleteme(event) - end - end - end - - def action_help_deleteme(event) - @player.output <<'EOF' -Deleting Your Character - -Syntax: DELETE ME PLEASE - -In case you ever need to do so, you can remove your character from the game. Quite permanently. You will need to enter your password as confirmation and that's it. You will be wiped out of time and memory. - -EOF - end - - #Write something. - def action_write(event) - object = @player.search_inv(event[:target]) - - if object.nil? - @player.output "What do you wish to write on?" - return - end - - if not object.info.writable - @player.output "You cannot write on #{object.name}." - return - end - - @player.output "You begin to write on #{object.name}." - - @player.editor(object.readable_text || [], 100) do |data| - unless data.nil? - object.readable_text = data - end - @player.output "You finish your writing." - end - end - - def action_help_write(event) - @player.output <<'EOF' -Command: Write -Syntax: WRITE [target] - -Write something on the specified target. - -EOF - end - - def action_taste(event) - room = $manager.get_object(@player.container) - object = @player.search_inv(event[:target]) || room.find(event[:target]) - - if object == @player or event[:target] == "me" - @player.output "You covertly lick yourself.\nHmm, not bad." - return - elsif object.nil? - @player.output "What would you like to taste?" - return - end - - event[:target] = object - event[:to_player] = "Sticking your tongue out hesitantly, you taste #{object.name}. " - if object.info.taste.nil? or object.info.taste == "" - event[:to_player] << "#{object.pronoun.capitalize} does not taste that great, but has no particular flavor." - else - event[:to_player] << object.info.taste - end - event[:to_target] = "#{@player.name} licks you, apparently in an attempt to find out your flavor." - event[:to_other] = "#{@player.name} hesitantly sticks out #{@player.pronoun(:possessive)} tongue and licks #{object.name}." - room.out_event event - end - - def action_help_taste(event) - @player.output <<'EOF' -Command: Taste -Syntax: TASTE [target] - -Taste the specified target. - -EOF - end - - def action_smell(event) - room = $manager.get_object(@player.container) - if event[:target].nil? - if room.info.smell - event[:to_player] = "You sniff the air. #{room.info.smell}." - else - event[:to_player] = "You sniff the air, but detect no unusual aromas." - end - event[:to_other] = "#{@player.name} sniffs the air." - room.out_event event - return - end - - object = @player.search_inv(event[:target]) || room.find(event[:target]) - - if object == @player or event[:target] == "me" - event[:target] = @player - event[:to_player] = "You cautiously sniff your armpits. " - if rand > 0.6 - event[:to_player] << "Your head snaps back from the revolting stench coming from beneath your arms." - event[:to_other] = "#{@player.name} sniffs #{@player.pronoun(:possessive)} armpits, then recoils in horror." - else - event[:to_player] << "Meh, not too bad." - event[:to_other] = "#{@player.name} sniffs #{@player.pronoun(:possessive)} armpits, then shrugs, apparently unconcerned with #{@player.pronoun(:possessive)} current smell." - end - room.out_event event - return - elsif object.nil? - @player.output "What are you trying to smell?" - return - end - - event[:target] = object - event[:to_player] = "Leaning in slightly, you sniff #{object.name}. " - if object.info.smell.nil? or object.info.smell == "" - event[:to_player] << "#{object.pronoun.capitalize} has no particular aroma." - else - event[:to_player] << object.info.smell - end - event[:to_target] = "#{@player.name} sniffs you curiously." - event[:to_other] = "#{@player.name} thrusts #{@player.pronoun(:possessive)} nose at #{object.name} and sniffs." - room.out_event event - end - - def action_help_smell(event) - @player.output <<'EOF' -Command: Smell -Syntax: SMELL [target] - -Smell the specified target. - -EOF - end - - def action_listen(event) - room = $manager.get_object(@player.container) - if event[:target].nil? - event[:target] = room - if room.info.sound - event[:to_player] = "You listen carefully. #{room.info.sound}." - else - event[:to_player] = "You listen carefully but hear nothing unusual." - end - event[:to_other] = "A look of concentration forms on #{@player.name}'s face as #{@player.pronoun} listens intently." - room.out_event event - return - end - - object = @player.search_inv(event[:target]) || room.find(event[:target]) - - if object == @player or event[:target] == "me" - @player.output "Listening quietly, you can faintly hear your pulse." - return - elsif object.nil? - @player.output "What would you like to listen to?" - return - end - - event[:target] = object - event[:to_player] = "You bend your head towards #{object.name}. " - if object.info.sound.nil? or object.info.sound == "" - event[:to_player] << "#{object.pronoun.capitalize} emits no unusual sounds." - else - event[:to_player] << object.info.sound - end - event[:to_target] = "#{@player.name} listens to you carefully." - event[:to_other] = "#{@player.name} bends #{@player.pronoun(:possessive)} head towards #{object.name} and listens." - room.out_event event - end - - def action_help_listen(event) - @player.output <<'EOF' -Command: Listen -Syntax: LISTEN [target] - -Listen to the specified target. - -EOF - end - - def action_feel(event) - room = $manager.get_object(@player.container) - object = @player.search_inv(event[:target]) || room.find(event[:target]) - - if object == @player or event[:target] == "me" - @player.output "You feel fine." - return - elsif object.nil? - @player.output "What would you like to feel?" - return - end - - event[:target] = object - event[:to_player] = "You reach out your hand and gingerly feel #{object.name}. " - if object.info.texture.nil? or object.info.texture == "" - event[:to_player] << "#{object.pronoun(:possessive).capitalize} texture is what you would expect." - else - event[:to_player] << object.info.texture - end - event[:to_target] = "#{@player.name} reaches out a hand and gingerly touches you." - event[:to_other] = "#{@player.name} reaches out #{@player.pronoun(:possessive)} hand and touches #{object.name}." - room.out_event event - end - - def action_help_feel(event) - @player.output <<'EOF' -Command: Feel -Syntax: FEEL [target] - -Feel the specified target. - -EOF - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(GenericHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/help_handler.rb b/lib/aethyr/core/commands/help_handler.rb deleted file mode 100644 index a37f385e8f302c46830016792bac352fa42f1b5a..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/help_handler.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "aethyr/core/registry" - -module Aethyr - module Extend - module HandleHelp - attr_reader :commands - - def initialize(player, commands, *args) - super(player, *args) - - @commands = commands - end - - def player_input(data) - super(data) - case data[:input] - when /^(help|help topics)$/i - if self.can_help? - self.commands.each do |command| - self.player.output command - end - end - end - end - - def can_help? - true - end - end - - class HelpHandler - include Aethyr::Extend::HandleHelp - - def initialize(player, commands, *args) - super - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/inventory.rb b/lib/aethyr/core/commands/inventory.rb deleted file mode 100644 index 34d9a06f78c6ee5a26f1b4a7e7f61b2c15e5a7cb..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/inventory.rb +++ /dev/null @@ -1,53 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Inventory - class InventoryHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["i", "inv", "inventory"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(InventoryHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^(i|inv|inventory)$/i - action({}) - when /^help (i|inv|inventory)$/i - action_help({}) - end - end - - private - def action_help(event) - player.output <<'EOF' -Command: Inventory -Syntax: INVENTORY - -Displays what you are holding and wearing. - -'i' and 'inv' are shortcuts for inventory. - - -See also: TAKE, DROP, WEAR, REMOVE -EOF - end - - #Shows the inventory of the player. - def action(event) - player.output(player.show_inventory) - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(InventoryHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/issue.rb b/lib/aethyr/core/commands/issue.rb deleted file mode 100644 index 7ddfcd3615a3dd41e0245d644453b8ccc07cd798..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/issue.rb +++ /dev/null @@ -1,131 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Issue - class IssueHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["bug", "typo", "idea"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(IssueHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^(bug|typo|idea)\s+(\d+)\s+(show|del|add|status)(\s+(.+))?$/i - action({ :itype => $1.downcase.to_sym, :issue_id => $2, :option => $3.downcase, :value => $5 }) - when /^(bug|typo|idea)\s+(\d+)/i - action({ :itype => $1.downcase.to_sym, :option => "show", :issue_id => $2 }) - when /^(bug|typo|idea)\s+(del|add|show|status)\s+(\d+)(\s+(.+))?/i - action({ :itype => $1.downcase.to_sym, :option => $2.downcase, :issue_id => $3, :value => $5 }) - when /^(bug|typo|idea)\s+(new|show|del|add|status|list)(\s+(.+))?$/i - action({ :itype => $1.downcase.to_sym, :option => $2.downcase, :value => $4 }) - when /^(bug|typo|idea)\s+(.*)$/i - action({ :itype => $1.downcase.to_sym, :option => "new", :value => $2 }) - when /^help (bug|typo|idea)$/i - action_help({}) - end - end - - private - def action_help(event) - player.output <<'EOF' -Command: Bug -Command: Idea -Command: Typo -Syntax: [BUG|IDEA|TYPO] [issue] -Syntax: [BUG|IDEA|TYPO] [id number] -Syntax: [BUG|IDEA|TYPO] LIST -Syntax: [BUG|IDEA|TYPO] STATUS [id_number] [status] -Syntax: [BUG|IDEA|TYPO] [SHOW|ADD|DEL] [id_number] - -These commands allow players and administrators to report and manipulate feedback about the game. The commands are essentially identical, but should be used to report different things. For the rest of this description, BUG is used. - -Note that players can only see and edit their own feedback, while adminsitrators will see them all. - -BUG <issue> is used to make the initial report. -BUG LIST will list all reports. -BUG ADD can be used to append comments to a report. -BUG STATUS can be used to change the status of a report to a different value (administrators only). - -Examples: -bug When I hit a dwarf with my axe, it doesn't do any damage. -bug list -bug 1 -bug add 1 Actually, this only happens with battleaxes, not all axes. -EOF - end - - def action(event) - case event[:option] - when "new" - issue = Issues.add_issue event[:itype], player.name, event[:value] - player.output "Thank you for submitting #{event[:itype]} ##{issue[:id]}." - when "add" - if not event[:issue_id] - player.output "Please specify a #{event[:itype]} number." - else - denied = Issues.check_access event[:itype], event[:issue_id], player - if denied - player.output denied - else - player.output Issues.append_issue(event[:itype], event[:issue_id], player.name, event[:value]) - end - end - when "del" - if not event[:issue_id] - player.output "Please specify a #{event[:itype]} number." - else - denied = Issues.check_access event[:itype], event[:issue_id], player - if denied - player.output denied - else - player.output Issues.delete_issue(event[:itype], event[:issue_id]) - end - end - when "list" - if player.admin - list = Issues.list_issues event[:itype] - else - list = Issues.list_issues event[:itype], player.name - end - if list.empty? - player.output "No #{event[:itype]}s to list." - else - player.output list - end - when "show" - if not event[:issue_id] - player.output "Please specify a #{event[:itype]} number." - else - denied = Issues.check_access event[:itype], event[:issue_id], player - if denied - player.output denied - else - player.output Issues.show_issue(event[:itype], event[:issue_id]) - end - end - when "status" - if not player.admin - player.output "Only administrators may change a #{event[:itype]}'s status." - elsif not event[:issue_id] - player.output "Please specify a #{event[:itype]} number." - else - player.output Issues.set_status(event[:itype], event[:issue_id], player.name, event[:value]) - end - - end - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(IssueHandler) - end - end - end -end diff --git a/lib/aethyr/core/commands/locking.rb b/lib/aethyr/core/commands/locking.rb deleted file mode 100644 index db9881356d2f64085c5c7f89458745e94273bffe..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/locking.rb +++ /dev/null @@ -1,154 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Locking - class LockingHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["lock", "unlock"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(LockingHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^lock\s+(.*)$/i - action_lock({ :object => $1 }) - when /^unlock\s+(.*)$/i - action_unlock({ :object => $1 }) - when /^help (lock|unlock)$/i - action_help({}) - end - end - - private - def action_help(event) - @player.output <<'EOF' -Command: Lock -Command: Unlock -Syntax: LOCK [object or direction] -Syntax: UNLOCK [object or direction] - -Lock or unlock the given object, if you have a key for it. - -Note that you can lock a door while it is open, then close it. - -See also: OPEN, CLOSE - -EOF - end - - def action_lock(event) - room = $manager.get_object(@player.container) - object = @player.search_inv(event[:object]) || room.find(event[:object]) - - if object.nil? - @player.output('Lock what?') - return - elsif not object.can? :lock or not object.lockable? - @player.output('That object cannot be locked.') - return - elsif object.locked? - @player.output("#{object.name} is already locked.") - return - end - - has_key = false - object.keys.each do |key| - if @player.inventory.include? key - has_key = key - break - end - end - - if has_key or @player.admin - status = object.lock(has_key, @player.admin) - if status - event[:to_player] = "You lock #{object.name}." - event[:to_other] = "#{@player.name} locks #{object.name}." - event[:to_blind_other] = "You hear the click of a lock." - - room.out_event(event) - - if object.is_a? Door and object.connected? - other_side = $manager.find object.connected_to - other_side.lock(has_key) - other_room = $manager.find other_side.container - o_event = event.dup - event[:to_other] = "#{other_side.name} locks from the other side." - event[:to_blind_other] = "You hear the click of a lock." - other_room.out_event(event) - end - else - @player.output("You are unable to lock that #{object.name}.") - end - else - @player.output("You do not have the key to that #{object.name}.") - end - end - - def action_unlock(event) - room = $manager.get_object(@player.container) - object = @player.search_inv(event[:object]) || room.find(event[:object]) - - if object.nil? - @player.output("Unlock what? #{event[:object]}?") - return - elsif not object.can? :unlock or not object.lockable? - @player.output('That object cannot be unlocked.') - return - elsif not object.locked? - @player.output("#{object.name} is already unlocked.") - return - end - - has_key = false - object.keys.each do |key| - if @player.inventory.include? key - has_key = key - break - end - end - - if has_key or @player.admin - status = object.unlock(has_key, @player.admin) - if status - event[:to_player] = "You unlock #{object.name}." - event[:to_other] = "#{@player.name} unlocks #{object.name}." - event[:to_blind_other] = "You hear the clunk of a lock." - - room.out_event(event) - - if object.is_a? Door and object.connected? - other_side = $manager.find object.connected_to - other_side.unlock(has_key) - other_room = $manager.find other_side.container - o_event = event.dup - event[:to_other] = "#{other_side.name} unlocks from the other side." - event[:to_blind_other] = "You hear the click of a lock." - other_room.out_event(event) - end - - return - else - @player.output("You are unable to unlock #{object.name}.") - return - end - else - @player.output("You do not have the key to #{object.name}.") - return - end - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(LockingHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/map.rb b/lib/aethyr/core/commands/map.rb deleted file mode 100644 index 16b84b3417529809978126d2b6276942f6adb659..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/map.rb +++ /dev/null @@ -1,48 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Map - class MapHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["m", "map"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(MapHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^(m|map)$/i - action({}) - when /^help (m|map)$/i - action_help({}) - end - end - - private - def action_help(event) - player.output <<'EOF' -Command: Map -Syntax: MAP - -Displays a map of the area. -EOF - end - - def action(event) - room = $manager.get_object(@player.container) - player.output(room.area.render_map(player, room.area.position(room)), message_type: :map) - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(MapHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/martial_combat.rb b/lib/aethyr/core/commands/martial_combat.rb deleted file mode 100644 index 2fc2bb46b1845aa63938b99f5b5c3a23f8ee7b6c..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/martial_combat.rb +++ /dev/null @@ -1,140 +0,0 @@ -require 'aethyr/core/commands/combat' - -module MartialCombat - class << self - - def kick(event, player, room) - return if not Combat.ready? player - - target = (event.target && room.find(event.target)) || room.find(player.last_target) - - if target.nil? - player.output "Who are you trying to attack?" - return - else - return unless Combat.valid_target? player, target - end - - player.last_target = target.goid - - event.target = target - - event[:to_other] = "#{player.name} kicks #{player.pronoun(:possessive)} foot out at #{target.name}." - event[:to_target] = "#{player.name} kicks #{player.pronoun(:possessive)} foot at you." - event[:to_player] = "You balance carefully and kick your foot out towards #{target.name}." - event[:blockable] = true - - player.balance = false - player.info.in_combat = true - target.info.in_combat = true - - room.out_event event - - event[:action] = :martial_hit - event[:combat_action] = :kick - event[:to_other] = "#{player.name} kicks #{target.name} with considerable violence." - event[:to_target] = "#{player.name} kicks you rather violently." - event[:to_player] = "Your kick makes good contact with #{target.name}." - - Combat.future_event event - end - - def punch(event, player, room) - return unless Combat.ready? player - - target = (event.target && room.find(event.target)) || room.find(player.last_target) - - if target.nil? - player.output "Who are you trying to attack?" - return - else - return unless Combat.valid_target? player, target - end - - player.last_target = target.goid - - event.target = target - - event[:to_other] = "#{player.name} swings #{player.pronoun(:possessive)} clenched fist at #{target.name}." - event[:to_target] = "#{player.name} swings #{player.pronoun(:possessive)} fist straight towards your face." - event[:to_player] = "You clench your hand into a fist and swing it at #{target.name}." - event[:blockable] = true - - player.balance = false - player.info.in_combat = true - target.info.in_combat = true - - room.out_event event - - event[:action] = :martial_hit - event[:combat_action] = :punch - event[:to_other] = "#{player.name} punches #{target.name} directly in the face." - event[:to_target] = "You stagger slightly as #{player.name} punches you in the face." - event[:to_player] = "Your fist lands squarely in #{target.name}'s face." - - Combat.future_event event - end - - def simple_dodge(event, player, room) - return unless Combat.ready? player - - target = (event.target && room.find(event.target)) || room.find(player.last_target) - - if target == player - player.output "You cannot block yourself." - return - elsif target - events = Combat.find_events(:player => target, :target => player, :blockable => true) - else - events = Combat.find_events(:target => player, :blockable => true) - end - - if events.empty? - player.output "What are you trying to dodge?" - return - end - - if target.nil? - target = events[0].player - end - - player.last_target = target.goid - - b_event = events[0] - if rand > 0.5 - b_event[:action] = :martial_miss - b_event[:type] = :MartialCombat - b_event[:to_other] = "#{player.name} twists away from #{target.name}'s attack." - b_event[:to_player] = "#{player.name} twists away from your attack." - b_event[:to_target] = "You manage to twist your body away from #{target.name}'s attack." - end - - event[:target] = target - event[:to_other] = "#{player.name} attempts to dodge #{target.name}'s attack." - event[:to_target] = "#{player.name} attempts to dodge your attack." - event[:to_player] = "You attempt to dodge #{target.name}'s attack." - - player.balance = false - room.out_event event - end - - def martial_hit(event, player, room) - Combat.delete_event event - player.balance = true - event.target.balance = true - player.info.in_combat = false - event.target.info.in_combat = false - Combat.inflict_damage event, player, room, 8 #temporary set amount of damage for now - end - - def martial_miss(event, player, room) - Combat.delete_event event - player.balance = true - event.target.balance = true - player.info.in_combat = false - event.target.info.in_combat = false - room.out_event event - end - - end -end diff --git a/lib/aethyr/core/commands/mobiles.rb b/lib/aethyr/core/commands/mobiles.rb deleted file mode 100644 index 954b264584ea72c23b394c4f7699fd41c450dffc..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/mobiles.rb +++ /dev/null @@ -1,44 +0,0 @@ -module Mobiles - class << self - def teach(event, player, room) - object = $manager.find(event.object, room) - - if object.nil? - player.output "Who are you trying to teach?" - return - end - end - - def expire(event, player, room) - $manager.delete_object player - end - - def respawn(event, player, room) - player.alive = true - player.info.stats.health = player.info.stats.max_health - event.room.add player - end - - def teleport(event, player, room) - if event[:object].is_a? GameObject - object = event[:object] - else - object = $manager.find event[:object] - end - - object.output event[:to_object] if event[:to_object] - - Admin.aput(event, player, room) - - if event[:to_room] - room = $manager.find self.container - room.output event[:to_room], object - end - - if event[:to_exit_room] - exit_room = $manager.find object.container - exit_room.output event[:to_exit_room], object - end - end - end -end diff --git a/lib/aethyr/core/commands/move.rb b/lib/aethyr/core/commands/move.rb deleted file mode 100644 index b28f7d94146087cc8de075fe17b1bc7736a41756..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/move.rb +++ /dev/null @@ -1,82 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Move - class MoveHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["go", "move", "east", "west", "northeast", "northwest", "north", "southeast", "southwest", "south", "e", "w", "nw", "ne", "sw", "se", "n", "s", "up", "down", "u", "d", "in", "out"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(MoveHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^go\s+(.*)$/i - action({:direction => $1.downcase}) - when /^(east|west|northeast|northwest|north|southeast|southwest|south|e|w|nw|ne|sw|se|n|s|up|down|u|d|in|out)(\s+\((.*)\))?$/i - action({:direction => expand_direction($1), - :pre => $3}) - when /^help (go|move|east|west|northeast|northwest|north|southeast|southwest|south|e|w|nw|ne|sw|se|n|s|up|down|u|d|in|out)$/i - action_help({}) - end - end - - private - def action_help(event) - @player.output <<'EOF' -Command: Go -Syntax: GO [direction or exit] - -Move in a particular direction or through a particular exit. - -Example: - -GO EAST - -Note that you can just use EAST, WEST, IN, OUT, UP, DOWN, etc. instead of GO. - -EOF - end - - def action(event) - room = $manager.get_object(@player.container) - exit = room.exit(event[:direction]) - - if exit.nil? - @player.output("You cannot go #{event[:direction]}.") - return - elsif exit.can? :open and not exit.open? - @player.output("That exit is closed. Perhaps you should open it?") - return - end - - new_room = $manager.find(exit.exit_room) - - if new_room.nil? - @player.output("That exit #{exit.name} leads into the void.") - return - end - - room.remove(@player) - new_room.add(@player) - @player.container = new_room.game_object_id - event[:to_player] = "You move #{event[:direction]}." - event[:to_other] = "#{@player.name} leaves #{event[:direction]}." - event[:to_blind_other] = "You hear someone leave." - - room.out_event(event) - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(MoveHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/movement.rb b/lib/aethyr/core/commands/movement.rb deleted file mode 100644 index b692ad48a1a54df2a0c06ab0da7da7f6ce2ed74f..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/movement.rb +++ /dev/null @@ -1,243 +0,0 @@ -require 'aethyr/core/objects/portal' - -#Contains all the movement commands -module Movement - class << self - - #Typical moving. - def move(event, player, room) - dir_exit = room.exit(event[:direction]) - - if dir_exit.nil? - player.output("You cannot go #{event[:direction]}.") - return - elsif dir_exit.is_a? Portal - player.output "You cannot simply go that way." - return - elsif dir_exit.can? :open and not dir_exit.open? - player.output("That exit is closed. Perhaps you should open it?") - return - elsif player.prone? - player.output('You must stand up first.') - return - elsif not player.balance - player.output "You must be balanced to move." - return - elsif player.info.in_combat - Combat.flee(event, player, room) - return - end - - new_room = $manager.find dir_exit.exit_room - event[:exit_room] = dir_exit.exit_room - - if new_room.nil? - player.output('You start to move in that direction, then stop when you realize that exit leads into the void.') - return - end - - if event[:pre] - in_message = "#{event[:pre]}, !name comes in from the !direction." - out_message = "#{event[:pre]}, !name leaves to the !direction." - else - in_message = nil - out_message = nil - end - - event[:to_other] = player.entrance_message(opposite_dir(event[:direction]), in_message) - event[:to_deaf_other] = event[:to_other] - event[:to_blind_other] = "You sense someone nearing you." - room.remove(player) - new_room.add(player) - new_room.out_event(event) - player.container = new_room.game_object_id - event_other = event.dup - event_other[:to_other] = player.exit_message(event_other[:direction], out_message) - event_other[:to_blind_other] = "You hear the sounds of someone leaving." - room.out_event(event_other) - - if player.info.followers - player.info.followers.each do |f| - follower = $manager.find f - room.remove follower - new_room.add follower - - room.output "#{follower.name.capitalize} follows #{player.name} #{event[:direction]}." - end - end - end - - def flee(event, player, room) - Combat.delete_event event - player.balance = true - player.info.in_combat = false - if event.target.info.fleeing - event.target.info.fleeing = false - event.target.balance = true - event.target.info.in_combat = false - event.player = event.target - event.target = nil - event.to_target = event.to_player = event.to_other = nil - event.pre = "Eyes wide with fear" - Movement.move(event, event.player, room) - else - #target already fled - end - end - - def gait(event, player, room) - if event[:phrase].nil? - if player.info.entrance_message - player.output "When you move, it looks something like:", true - player.output player.exit_message("north") - else - player.output "You are walking normally." - end - elsif event[:phrase].downcase == "none" - player.info.entrance_message = nil - player.info.exit_message = nil - player.output "You will now walk normally." - else - player.info.entrance_message = "#{event[:phrase]}, !name comes in from !direction." - player.info.exit_message = "#{event[:phrase]}, !name leaves to !direction." - - player.output "When you move, it will now look something like:", true - player.output player.exit_message("north") - end - end - - #Enter a portal - def enter(event, player, room) - portal = $manager.find(event[:object], room) - if not player.balance - player.output "You cannot use a portal while unbalanced." - return - elsif portal.nil? - player.output "What are you trying to #{event[:portal_action]}?" - return - elsif not portal.is_a? Portal - player.output "You cannot #{event[:portal_action]} #{portal.name}." - return - elsif portal.info.portal_action and portal.info.portal_action != event[:portal_action].to_sym - player.output "You cannot #{event[:portal_action]} #{portal.name}." - return - elsif portal.info.portal_action.nil? and event[:portal_action] != "enter" - player.output "You cannot #{event[:portal_action]} #{portal.name}." - return - end - - new_room = $manager.find portal.exit_room - event[:exit_room] = portal.exit_room - - if new_room.nil? - player.output('You start to move in that direction, then stop when you realize that way leads into the void.') - return - end - - event[:to_other] = portal.entrance_message(player, event[:portal_action]) - event[:to_deaf_other] = event[:to_other] - event[:to_blind_other] = "You sense someone nearing you." - room.remove(player) - player.output portal.portal_message(player, event[:portal_action]) - new_room.add(player) - new_room.out_event(event) - player.container = new_room.game_object_id - event_other = event.dup - event_other[:to_other] = portal.exit_message(player, event_other[:portal_action]) - event_other[:to_blind_other] = "You hear the sounds of someone leaving." - room.out_event(event_other) - - if player.info.followers - player.info.followers.each do |f| - follower = $manager.find f - room.remove follower - new_room.add follower - - room.output "#{follower.name.capitalize} follows #{player.name} #{event[:direction]}." - end - end - end - - #Sit down. - def sit(event, player, room) - if not player.balance - player.output "You cannot sit properly while unbalanced." - return - elsif event[:object].nil? - if player.sitting? - player.output('You are already sitting down.') - elsif player.prone? and player.sit - event[:to_player] = 'You stand up then sit on the ground.' - event[:to_other] = "#{player.name} stands up then sits down on the ground." - event[:to_deaf_other] = event[:to_other] - room.output(event) - elsif player.sit - event[:to_player] = 'You sit down on the ground.' - event[:to_other] = "#{player.name} sits down on the ground." - event[:to_deaf_other] = event[:to_other] - room.out_event(event) - else - player.output('You are unable to sit down.') - end - else - object = $manager.find(event[:object], player.room) - - if object.nil? - player.output('What do you want to sit on?') - elsif not object.can? :sittable? - player.output("You cannot sit on #{object.name}.") - elsif object.occupied_by? player - player.output("You are already sitting there!") - elsif not object.has_room? - player.output("The #{object.generic} #{object.plural? ? "are" : "is"} already occupied.") - elsif player.sit(object) - object.sat_on_by(player) - event[:to_player] = "You sit down on #{object.name}." - event[:to_other] = "#{player.name} sits down on #{object.name}." - event[:to_deaf_other] = event[:to_other] - room.out_event(event) - else - player.output('You are unable to sit down.') - end - end - end - - #Stand up. - def stand(event, player, room) - if not player.prone? - player.output('You are already on your feet.') - return - elsif not player.balance - player.output "You cannot stand while unbalanced." - return - end - - if player.sitting? - object = $manager.find(player.sitting_on, room) - else - object = $manager.find(player.lying_on, room) - end - - if player.stand - event[:to_player] = 'You rise to your feet.' - event[:to_other] = "#{player.name} stands up." - event[:to_deaf_other] = event[:to_other] - room.out_event(event) - object.evacuated_by(player) unless object.nil? - else - player.output('You are unable to stand up.') - end - end - - #Strike a pose. - def pose(event, player, room) - if event[:pose].downcase == "none" - player.pose = nil - player.output "You are no longer posing." - else - player.pose = event[:pose] - player.output "Your pose is now: #{event[:pose]}." - end - end - end -end diff --git a/lib/aethyr/core/commands/news.rb b/lib/aethyr/core/commands/news.rb deleted file mode 100644 index 58d654141e330d1887b940dd316e97379d8ce84d..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/news.rb +++ /dev/null @@ -1,154 +0,0 @@ -module News - class << self - - #Show latest news on a Newsboard. - def latest_news(event, player, room) - board = find_board(event, room) - - if board.nil? - player.output "There do not seem to be any postings here." - return - end - - if not board.is_a? Newsboard - log board.class - end - - offset = event[:offset] || 0 - wordwrap = player.word_wrap || 100 - limit = event[:limit] || player.page_height - - player.output board.list_latest(wordwrap, offset, limit) - end - - #Show all news on a Newsboard. - def all(event, player, room) - board = find_board(event, room) - - if board.nil? - player.output "There do not seem to be any postings here." - return - end - - wordwrap = player.word_wrap || 100 - - player.output board.list_latest(wordwrap, 0, nil) - end - - #Read a specific post. - def read_post(event, player, room) - board = find_board(event, room) - - if board.nil? - player.output "There do not seem to be any postings here." - return - end - - post = board.get_post event[:post_id] - if post.nil? - player.output "No such posting here." - return - end - - if player.info.boards.nil? - player.info.boards = {} - end - - player.info.boards[board.goid] = event[:post_id].to_i - - player.output board.show_post(post, player.word_wrap || 80) - end - - #Write a post. - def write_post(event, player, room) - board = find_board(event, room) - - if board.nil? - player.output "There do not seem to be any postings here." - return - end - - player.output("What is the subject of this post?", true) - - player.expect do |subj| - player.editor do |message| - unless message.nil? - post_id = board.save_post(player, subj, event[:reply_to], message) - player.output "You have written post ##{post_id}." - if board.announce_new - area = $manager.get_object(board.container).area - area.output board.announce_new - end - end - end - end - end - - #Delete a post. - # - #Note: this is not handled very well, as it is not expected - #to be a common occurance. In the future, this will be an admin-only command. - def delete_post(event, player, room) - #if not player.admin - # player.output "You cannot do that." - #end - - board = find_board(event, room) - - if board.nil? - player.output "What newsboard are you talking about?" - return - end - - post = board.get_post event[:post_id] - - if post.nil? - player.output "No such post." - elsif post[:author] != player.name - player.output "You can only delete your own posts." - else - board.delete_post event[:post_id] - player.output "Deleted post ##{event[:post_id]}" - end - end - - #List from last read item onwards. - # - #Not quite working yet. - def list_unread(event, player, room) - board = find_board(event, room) - - if board.nil? - player.output "There do not seem to be any postings here." - return - end - - if player.info.boards.nil? - player.info.boards = {} - end - - player.output board.list_since(player.info.boards[board.goid], player.word_wrap) - end - - #Show posts after a given post. - def list_before(event, player, room) - board = find_board(event, room) - - if board.nil? - player.output "There do not seem to be any postings here." - return - end - - player.output board.list_latest(player.word_wrap, event[:start_index].to_i - 1) - end - - private - - #Find the Newsboard in the room. - def find_board(event, room) - boards = room.inventory.find_all("class", :Newsboard) - boards.first unless boards.nil? - end - - end -end diff --git a/lib/aethyr/core/commands/open.rb b/lib/aethyr/core/commands/open.rb deleted file mode 100644 index 13b34536a49267a76128743513060bd2d4882ce4..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/open.rb +++ /dev/null @@ -1,67 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Open - class OpenHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["open"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(OpenHandler.new(data[:game_object])) - end - - def player_input(data) - super(data) - case data[:input] - when /^open\s+(\w+)$/i - action({ :object => $1 }) - when /^help open$/i - action_help({}) - end - end - - private - def action_help(event) - player.output <<'EOF' -Command: Open -Syntax: OPEN [object or direction] - -Opens the object. For doors and such, it is more accurate to use the direction in which the object lies. - -For example: - -OPEN north - -OPEN door - - -See also: LOCK, UNLOCK, CLOSE - -EOF - end - - def action(event) - room = $manager.get_object(@player.container) - object = expand_direction(event[:object]) - object = player.search_inv(object) || $manager.find(object, room) - - if object.nil? - player.output("Open what?") - elsif not object.can? :open - player.output("You cannot open #{object.name}.") - else - object.open(event) - end - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(OpenHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/quit.rb b/lib/aethyr/core/commands/quit.rb deleted file mode 100644 index 47dfbf4ccb8020b3aaa2cfc8738eac2712e06ad9..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/quit.rb +++ /dev/null @@ -1,49 +0,0 @@ -require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" - -module Aethyr - module Core - module Commands - module Quit - class QuitHandler < Aethyr::Extend::CommandHandler - def initialize(player) - super(player, ["quit"]) - end - - def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(QuitHandler.new(data[:game_object])) - end - - def player_input(data) - case data[:input] - when /^quit$/i - action({}) - when /^help quit$/i - action_help({}) - end - end - - private - def action_help(event) - player.output <<'EOF' -Command: Quit -Syntax: QUIT - -Saves your character and logs you off from the game. - -You shouldn't need this too often. - -EOF - end - - def action(event) - $manager.drop_player player - end - end - - Aethyr::Extend::HandlerRegistry.register_handler(QuitHandler) - end - end - end -end \ No newline at end of file diff --git a/lib/aethyr/core/commands/settings.rb b/lib/aethyr/core/commands/settings.rb deleted file mode 100644 index 5428f4771191fae2caf94f4ee86ebb29cb0ce6a0..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/settings.rb +++ /dev/null @@ -1,125 +0,0 @@ -#Settings commands. -module Settings - class << self - - #Set a configuration option. - def set(event, player, room) - event[:setting].downcase! - case event[:setting] - when 'wordwrap' - value = event[:value] - if player.word_wrap.nil? - player.output("Word wrap is currently off.", true) - else - player.output("Word wrap currently set to #{player.word_wrap}.", true) - end - - if value.nil? - player.output "Please specify 'off' or a value between 10 - 200." - return - elsif value.downcase == 'off' - player.word_wrap = nil - player.output "Word wrap is now disabled." - return - else - value = value.to_i - if value > 200 or value < 10 - player.output "Please use a value between 10 - 200." - return - else - player.word_wrap = value - player.output "Word wrap is now set to: #{value} characters." - return - end - end - when 'pagelength', "page_length" - value = event[:value] - if player.page_height.nil? - player.output("Pagination is currently off.", true) - else - player.output("Page length is currently set to #{player.page_height}.", true) - end - - if value.nil? - player.output "Please specify 'off' or a value between 1 - 200." - return - elsif value.downcase == 'off' - player.page_height = nil - player.output "Output will no longer be paginated." - return - else - value = value.to_i - if value > 200 or value < 1 - player.output "Please use a value between 1 - 200." - return - else - player.page_height = value - player.output "Page length is now set to: #{value} lines." - return - end - - end - when "desc", "description" - player.editor(player.instance_variable_get(:@long_desc) || [], 10) do |data| - unless data.nil? - player.long_desc = data.strip - end - player.output("Set description to:\r\n#{player.long_desc}") - end - else - player.output "No such setting: #{event[:setting]}" - end - end - - #Set colors. - def setcolor(event, player, room) - if event[:option] == "off" - player.io.use_color = false - player.output "Colors disabled." - elsif event[:option] == "on" - player.io.use_color = true - player.output "Colors enabled." - elsif event[:option] == "default" - player.io.to_default - player.output "Colors set to defaults." - else - player.output player.io.set_fg_color(event[:option], event[:color]) - end - end - - #Show color configuration. - def showcolors(event, player, room) - player.output player.io.show_color_config - end - - def setpassword(event, player, room) - if event[:new_password] - if event[:new_password] !~ /^\w{6,20}$/ - player.output "Please only use letters and numbers. Password should be between 6 and 20 characters long." - return - else - $manager.set_password(player, event[:new_password]) - player.output "Your password has been changed." - end - else - player.output "Please enter your current password:", true - player.io.echo_off - player.expect do |password| - if $manager.check_password(player.name, password) - player.output "Please enter your new password:", true - player.io.echo_off - player.expect do |password| - player.io.echo_on - event[:new_password] = password - Settings.setpassword(event, player, room) - end - else - player.output "Sorry, that password is invalid." - player.io.echo_on - end - - end - end - end - end -end diff --git a/lib/aethyr/core/commands/weapon_combat.rb b/lib/aethyr/core/commands/weapon_combat.rb deleted file mode 100644 index c92a55127fbba2fc002e592ca7dfbc191f7fa446..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/commands/weapon_combat.rb +++ /dev/null @@ -1,246 +0,0 @@ -require 'aethyr/core/commands/combat' - -module WeaponCombat - - class << self - - def slash(event, player, room) - - return if not Combat.ready? player - - weapon = get_weapon(player, :slash) - if weapon.nil? - player.output "You are not wielding a weapon you can slash with." - return - end - - target = (event.target && room.find(event.target)) || room.find(player.last_target) - - if target.nil? - player.output "Who are you trying to attack?" - return - else - return unless Combat.valid_target? player, target - end - - player.last_target = target.goid - - event.target = target - - event[:to_other] = "#{weapon.name} flashes as #{player.name} swings it at #{target.name}." - event[:to_target] = "#{weapon.name} flashes as #{player.name} swings it towards you." - event[:to_player] = "#{weapon.name} flashes as you swing it towards #{target.name}." - event[:attack_weapon] = weapon - event[:blockable] = true - - player.balance = false - player.info.in_combat = true - target.info.in_combat = true - - room.out_event event - - event[:action] = :weapon_hit - event[:combat_action] = :slash - event[:to_other] = "#{player.name} slashes across #{target.name}'s torso with #{weapon.name}." - event[:to_target] = "#{player.name} slashes across your torso with #{weapon.name}." - event[:to_player] = "You slash across #{target.name}'s torso with #{weapon.name}." - - Combat.future_event event - - end - - def simple_block(event, player, room) - - return if not Combat.ready? player - - weapon = get_weapon(player, :block) - if weapon.nil? - player.output "You are not wielding a weapon you can block with." - return - end - - target = (event.target && room.find(event.target)) || room.find(player.last_target) - - if target == player - player.output "You cannot block yourself." - return - elsif target - events = Combat.find_events(:player => target, :target => player, :blockable => true) - else - events = Combat.find_events(:target => player, :blockable => true) - end - - if events.empty? - player.output "What are you trying to block?" - return - end - - if target.nil? - target = events[0].player - end - - player.last_target = target.goid - - b_event = events[0] - if rand > 0.5 - b_event[:action] = :weapon_block - b_event[:type] = :WeaponCombat - b_event[:to_other] = "#{player.name} deftly blocks #{target.name}'s attack with #{weapon.name}." - b_event[:to_player] = "#{player.name} deftly blocks your attack with #{weapon.name}." - b_event[:to_target] = "You deftly block #{target.name}'s attack with #{weapon.name}." - end - - event[:target] = target - event[:to_other] = "#{player.name} raises #{player.pronoun(:possessive)} #{weapon.generic} to block #{target.name}'s attack." - event[:to_target] = "#{player.name} raises #{player.pronoun(:possessive)} #{weapon.generic} to block your attack." - event[:to_player] = "You raise your #{weapon.generic} to block #{target.name}'s attack." - - player.balance = false - room.out_event event - end - - #Wield a weapon. - def wield(event, player, room) - weapon = player.inventory.find(event[:weapon]) - if weapon.nil? - weapon = player.equipment.find(event[:weapon]) - if weapon and player.equipment.get_all_wielded.include? weapon - player.output "You are already wielding that." - else - player.output "What are you trying to wield?" - end - return - end - - if not weapon.is_a? Weapon - player.output "#{weapon.name} is not wieldable." - return - end - - if event[:side] - side = event[:side] - if side != "right" and side != "left" - player.output "Which hand?" - return - end - - result = player.equipment.check_wield(weapon, "#{side} wield") - if result - player.output result - return - end - - result = player.equipment.wear(weapon, "#{side} wield") - if result.nil? - player.output "You are unable to wield that." - return - end - event[:to_player] = "You grip #{weapon.name} firmly in your #{side} hand." - else - result = player.equipment.check_wield(weapon) - - if result - player.output result - return - end - - result = player.equipment.wear(weapon) - if result.nil? - player.output "You are unable to wield that weapon." - return - end - - event[:to_player] = "You firmly grip #{weapon.name} and begin to wield it." - end - - player.inventory.remove weapon - event[:to_other] = "#{player.name} wields #{weapon.name}." - room.out_event(event) - end - - #Unwield a weapon. - def unwield(event, player, room) - - if event[:weapon] == "right" || event[:weapon] == "left" - weapon = player.equipment.get_wielded(event[:weapon]) - - if weapon.nil? - player.output "You are not wielding anything in your #{event[:weapon]} hand." - return - end - elsif event[:weapon].nil? - weapon = player.equipment.get_wielded - if weapon.nil? - player.output "You are not wielding anything." - return - end - else - weapon = player.equipment.find(event[:weapon]) - - if weapon.nil? - player.output "What are you trying to unwield?" - return - end - - if not [:left_wield, :right_wield, :dual_wield].include? player.equipment.position_of(weapon) - player.output "You are not wielding #{weapon.name}." - return - end - - end - - if player.equipment.remove(weapon) - player.inventory << weapon - event[:to_player] = "You unwield #{weapon.name}." - event[:to_other] = "#{player.name} unwields #{weapon.name}." - room.out_event(event) - else - player.output "Could not unwield #{weapon.name}." - end - end - - def weapon_hit(event, player, room) - Combat.delete_event event - player.balance = true - event.target.balance = true - player.info.in_combat = false - event.target.info.in_combat = false - Combat.inflict_damage event, player, room, 10 #temporary set amount of damage for now - end - - def weapon_block(event, player, room) - Combat.delete_event event - player.balance = true - event.target.balance = true - player.info.in_combat = false - event.target.info.in_combat = false - room.out_event event - end - - private - - WeaponTypes = { - :sword => [:charge, :thrust, :sweep, :circle_sweep, :slash, :circle_slash, :hilt_slam, :cleave, :behead, :pin, :block], - :hammer => [:charge, :sweep, :cicle_sweep, :bash, :swing, :circle_swing, :crush, :ground_slam, :block], - :axe => [:charge, :thrust, :feint_thrust, :throw, :sweep, :circle_sweep, :bash, :slash, :cleave, :behead, :block], - :dagger => [:charge, :thrust, :feint_thrust, :stab, :gouge, :throw, :slash, :circle_slash, :backstab, :pin, :block], - :pole => [:charge, :thrust, :feint_thrust, :lunge, :throw, :sweep, :circle_sweep, :pin, :block] - } - - def weapon_can? type, attack - WeaponTypes[type.to_sym].include? attack.to_sym - end - - def get_weapon player, attack - weapon = nil - player.equipment.get_all_wielded.each do |w| - if w.is_a? Weapon and w.info.weapon_type and weapon_can?(w.info.weapon_type, attack) - weapon = w - break - end - end - - weapon - end - end -end diff --git a/lib/aethyr/core/components/manager.rb b/lib/aethyr/core/components/manager.rb index b83fc15ca97819db9f89e7713892f766d96744e9..2c88a466b68f1fedd62a61f54a430812e34eec78 100644 --- a/lib/aethyr/core/components/manager.rb +++ b/lib/aethyr/core/components/manager.rb @@ -5,9 +5,10 @@ require 'aethyr/core/errors' require 'aethyr/core/objects/info/calendar' require 'aethyr/core/registry' require 'aethyr/core/util/publisher' +require 'aethyr/core/util/priority_queue' require 'set' -#The Manager class uses the observer model to recieve commands from objects, which +#The Manager class uses the wisper to recieve commands from objects, which #it then passes along to the EventHandler. #The Manager also keeps track of all game objects and takes care of adding, removing, and #finding them. @@ -22,9 +23,12 @@ class Manager < Publisher #a Manager object in an external script. def initialize(objects = nil) Aethyr::Extend::HandlerRegistry.handle(self) + @soft_restart = false @storage = StorageMachine.new @uptime = Time.new.to_i + @future_actions = PriorityQueue.new + @pending_actions = PriorityQueue.new unless objects @cancelled_events = Set.new @@ -43,6 +47,28 @@ class Manager < Publisher end end + def submit_action( action, priority: 0, wait: nil ) + if wait.nil? || wait <= 0 + @pending_actions.push(action, priority) + else + activate_when = Manager::epoch_now + wait + @future_actions.push({:action => action, :priority => priority}, activate_when) + end + end + + def pop_action + # first check for any future actions ready to become active + when_next = @future_actions.min_priority + while when_next && when_next < Manager::epoch_now do + future_next = @future_actions.pop_min + @pending_actions.push(future_next[:action], future_next[:priority]) + when_next = @future_actions.min_priority + end + + #return and pop whatever the next thing in the queue is. + return @pending_actions.pop_min + end + #Checks if a game object ID exists already, to avoid conflicts. def existing_goid? goid @game_objects[goid] || @storage.type_of(goid) @@ -184,7 +210,7 @@ class Manager < Publisher def add_object(game_object, position = nil) @game_objects << game_object unless @game_objects.loaded? game_object.goid - + broadcast(:object_added, { :publisher => self, :game_object => game_object, :position => position}) unless game_object.room.nil? @@ -348,81 +374,6 @@ class Manager < Publisher log "Error when dropping player, but recovering and continuing." end - #Update gets called when an event occurs. The event is just passed along to the EventHandler, unless it is a :quit or :save - #event, in which case the Manager takes care of it. - def update(event) - return if not @running - log "Got event: #{event}", Logger::Medium - if event.nil? - return - elsif event[:type] == :Future - future_event(event) - return - end - - log "Adding event to event handler from #{event[:player]}", Logger::Ultimate - @event_handler.event_queue << event - - #EventMachine.defer lambda {@event_handler.run} - @event_handler.run - end - - #Add a future event. - def future_event(event) - if event[:action] == :call - EventMachine.add_timer(event[:time]) do - if $manager.cancelled? event - $manager.remove_cancelled event - break - end - - e = event[:event].call - - if e.is_a? String - e = CommandParser.parse(event[:player], e) - end - - if e.is_a? Event - $manager.update(e) - end - - end - else - EventMachine.add_timer(event[:time]) do - if $manager.cancelled? event - $manager.remove_cancelled event - break - end - - $manager.update(event[:event]) - end - end - end - - def cancel_event event - if event.is_a? Integer - @cancelled_events << event - else - @cancelled_events << event.object_id - end - end - - def cancelled? event - if event.is_a? Integer - @cancelled_events.include? event - else - @cancelled_events.include? event.object_id - end - end - - def remove_cancelled event - if event.is_a? Integer - @cancelled_event.delete event - else - @cancelled_event.delete event.object_id - end - end - #Calls update on all objects. def update_all #require 'benchmark' @@ -498,4 +449,9 @@ class Manager < Publisher def to_s "The Manager" end + + private + def self.epoch_now + return DateTime.now.strftime('%s').to_i + end end diff --git a/lib/aethyr/core/components/storage.rb b/lib/aethyr/core/components/storage.rb index 688fb58504c635ec3a8b83b67475cabfeea5a954..362b211073b4dcd68048802c265313d4b1c43a55 100644 --- a/lib/aethyr/core/components/storage.rb +++ b/lib/aethyr/core/components/storage.rb @@ -63,16 +63,6 @@ class StorageMachine end end - #Yeah, so whatever on this little deal. Probably should do it better later. - player.use_color = player.io.use_color if player.io - player.color_settings = player.io.color_settings if player.io - - #Okay, this is tricky. We can't serialize the IO object stored in the Player - #objects. To get around this (we don't want to store it anyhow), we temporarily - #set it to nil, then back to whatever it was. - player_connection = player.instance_variable_get(:@player) - player.instance_variable_set(:@player, nil) - log "Saving player: #{player.name}" store_object(player) @@ -81,7 +71,6 @@ class StorageMachine end log "Player saved: #{player.name}" - player.instance_variable_set(:@player, player_connection) end #Sets password for a given player. Accepts player name or player object. @@ -193,16 +182,10 @@ class StorageMachine #Recursively stores object and its inventory. # - #Warning: this temporarily removes the object's observers. + #Warning: this temporarily removes the object's subscribers. def store_object(object) - if object.is_a? Observable - observers = object.instance_variable_get(:@observer_peers) - unless observers.nil? - observers = observers.dup - object.delete_observers - end - end + volatile_data = object.dehydrate() open_store("goids", false) do |gd| gd[object.goid] = object.class.to_s @@ -212,10 +195,6 @@ class StorageMachine gd[object.goid] = Marshal.dump(object) end - if object.is_a? Observable and not observers.nil? - object.instance_variable_set(:@observer_peers, observers) - end - if object.respond_to? :equipment object.equipment.each do |o| store_object(o) unless o.is_a? Player #this shouldn't happen, but who knows @@ -224,6 +203,8 @@ class StorageMachine @saved += 1 + object.rehydrate(volatile_data) + log "Stored #{object} # #{object.game_object_id}", Logger::Ultimate end @@ -325,10 +306,8 @@ class StorageMachine end end - if object.is_a? Observable - fix_observers object - end + object.rehydrate(nil) game_objects << object unless object.container.nil? or game_objects.loaded? object.container @@ -338,6 +317,7 @@ class StorageMachine object.container = ServerConfig.start_room end end + return object end @@ -375,9 +355,8 @@ class StorageMachine object = Marshal.load(gd[id]) log "Loaded #{object}", Logger::Ultimate unless object.nil? or (not include_players and object.is_a? Player) - if object.is_a? Observable - fix_observers object - end + + object.rehydrate(nil) game_objects << object objects << object @@ -498,15 +477,5 @@ class StorageMachine end end - #Fixes issue with changes with Observer between Ruby 1.8.7 and 1.9.1 - def fix_observers object - if RUBY_VERSION < "1.9.0" - object.instance_variable_set(:@observer_peers, []) - else - object.instance_variable_set(:@observer_peers, {}) - end - end - public :update_all_objects! end - diff --git a/lib/aethyr/core/connection/login.rb b/lib/aethyr/core/connection/login.rb index 08eb33c6effa0fba3ad3a1d390f5cb26db008b29..02a04c4ba60b85e006287adee52ad2999971491d 100644 --- a/lib/aethyr/core/connection/login.rb +++ b/lib/aethyr/core/connection/login.rb @@ -8,14 +8,15 @@ require 'aethyr/core/errors' module Login #Get input from io connection and process it - def receive_data(data) - return if data.nil? - data = preprocess_input(data) - return if data == '' + def receive_data + return false if closed? + data = @display.recv + return false if data.nil? + return false if data == '' if data[-1,1] != "\n" @in_buffer << data - return + return true elsif not @in_buffer.empty? data = @in_buffer.join + data @in_buffer.clear @@ -38,6 +39,10 @@ module Login @player.handle_input d else case @state + when :initial + show_resolution_prompt + when :resolution + do_resolution d when :server_menu do_server_menu d when :login_name @@ -57,6 +62,32 @@ module Login end end end + return true + end + + def show_initial + show_resolution_prompt + end + + #Show login menu + def show_resolution_prompt + output "Would you like color (Y/n)? " + @state = :resolution + end + + def do_resolution(data) + data.strip! + log "resolution getting done: #{data}" + case data + when /([nNyY]{1})/ + display.init_colors if $1.downcase.eql? "y" + show_server_menu + when "" + display.init_colors + show_server_menu + else + show_resolution_prompt + end end #Show login menu @@ -129,14 +160,8 @@ module Login return end - if player.color_settings.nil? - @use_color = false - else - @color_settings = player.color_settings - end - @word_wrap = player.word_wrap - player.instance_variable_set(:@player, self) + player.set_connection(self) $manager.add_object(player) @player = player diff --git a/lib/aethyr/core/connection/player_connect.rb b/lib/aethyr/core/connection/player_connect.rb index d2bfa7b43e78648526c61ed518001d8d2173ed59..ed722a7981cb803fbbc2eb22d5d26c7ed895046e 100644 --- a/lib/aethyr/core/connection/player_connect.rb +++ b/lib/aethyr/core/connection/player_connect.rb @@ -15,37 +15,32 @@ class PlayerConnection include Editor #Input buffer - attr_reader :in_buffer, :display - attr_accessor :color_settings, :use_color, :word_wrap - - def initialize(display, addrinfo, *args) + attr_reader :in_buffer, :display, :socket + attr_accessor :word_wrap + + def initialize(socket, addrinfo, *args) super(*args) - @display = display + @display = Display.new(socket) + @socket = socket @in_buffer = [] @paginator = nil - @color_settings = color_settings || to_default - @use_color = false @mccp_to_client = false @mccp_from_client = false @word_wrap = 120 @closed = false - @state = :server_menu + @state = :initial @login_name = nil @login_password = nil @password_attempts = 0 @player = nil @expect_callback = nil @ip_address = Socket.unpack_sockaddr_in(addrinfo)[1] - @color_stack = [] + 200.times{print "\n"} print(File.read(ServerConfig.intro_file), false) if File.exist? ServerConfig.intro_file - ask_mssp if ServerConfig[:mssp] - - ask_mccp if ServerConfig[:mccp] - - show_server_menu + show_initial log "Connection from #{@ip_address}." end @@ -93,45 +88,6 @@ class PlayerConnection end end - def send_data( message, message_type: :main) - message = compress message if @mccp_to_client - - @display.send( message, message_type: message_type) - end - - #Sets colors to defaults - def to_default - @use_color = false - @color_settings = { - "roomtitle" => "fg:green bold", - "object" => "fg:blue", - "player" => "fg:cyan", - "mob" => "fg:yellow bold", - "merchant" => "fg:yellow dim", - "me" => "fg:white bold", - "exit" => "fg:green", - "say" => "fg:white bold", - "tell" => "fg:cyan bold", - "important" => "fg:red bold", - "editor" => "fg:cyan", - "news" => "fg:cyan bold", - "identifier" => "fg:magenta bold", - "water" => "fg:blue", - "waterlow" => "fg:blue dim", - "waterhigh" => "fg:blue bold", - "earth" => "fg:dark_goldenrod", - "earthlow" => "fg:dark_goldenrod dim", - "earthhigh" => "fg:dark_goldenrod bold", - "air" => "fg:white", - "airlow" => "fg:white dim", - "airhigh" => "fg:white bold", - "fire" => "fg:red", - "firelow" => "fg:red dim", - "firehigh" => "fg:red bold", - "regular" => "fg:gray" - } - end - #Checks if the io connection is nil or closed def closed? @closed @@ -139,11 +95,11 @@ class PlayerConnection #Sends message followed by a newline. Also capitalizes #the first letter in the message. - def send_puts( message, message_type: :main) + def send_puts( message, no_newline = false, message_type: :main, internal_clear: false) message = message.to_s first = message.index(/[a-zA-Z]/) message[first,1] = message[first,1] unless first.nil? - self.print(message, true, true, message_type: message_type) + self.print(message, true, !no_newline, message_type: message_type, internal_clear: internal_clear) end alias :output :send_puts @@ -159,316 +115,13 @@ class PlayerConnection end #Send message without newline - def print(message, parse = true, newline = false, message_type: :main) - unless closed? - if parse - colorize message - message.gsub!(/\t/, ' ') - message = paginate(message) - end - if newline and message[-1..-1] != "\n" - if message[-2..-2] == "\r" - message << "\n" - else - message << "\r\n" - end - end - if @use_color - regular_format = FormatState.new(@color_settings["regular"]) - message = regular_format.apply + message + regular_format.revert - end - send_data( message, message_type: message_type) - end - end - - def paginate message - if @player.nil? - return line_wrap(message) - elsif not @player.page_height - return line_wrap(message) - #elsif not @word_wrap - #return message.gsub(/([^\r]?)\n/, '\1' + "\r\n") - end - - ph = @player.page_height - - out = [] - #message = message.gsub(/((\e\[\d+[\;]{0,1}\d*[\;]{0,1}\d*m|[^\r\n\n\s\Z]){#@word_wrap})/, "\\1 ") if @word_wrap - message = wrap(message, @word_wrap).join("\r\n") if @word_wrap - message.scan(/((((\e\[\d+[\;]{0,1}\d*[\;]{0,1}\d*m)|.){1,#{@word_wrap}})(\r\n|\n|\s+|\Z))|(\r\n|\n)/) do |m| - if $2 - out << $2 - else - out << "" - end - end - - if out.length < ph - return out.join("\r\n") - end - - @paginator = KPaginator.new(self, out) - @paginator.more - end - - #Only use if there is no line height - def line_wrap message - message = wrap(message, @word_wrap).join("\n") if @word_wrap - #message = message.gsub(/((\e\[\d+[\;]{0,1}\d*[\;]{0,1}\d*m|[^\r\n\n\s\Z]){#{@word_wrap}})/, "\\1 ") if @word_wrap - message.gsub(/(((\e\[\d+[\;]{0,1}\d*[\;]{0,1}\d*m)|.){1,#{@word_wrap}})(\r\n|\n|\s+|\Z)/, "\\1\n") - end - - #Next page of paginated output - def more - if @paginator and @paginator.more? - self.print(@paginator.more, false) - if not @paginator.more? - @paginator = nil - end - else - @paginator = nil - self.puts "There is no more." - end - end - - #Sets the colors in the string according to the player's preferences. - def colorize string - colors = @color_settings.keys.dup - colors << "raw[^>]*" - colors = colors.join("|") - if @use_color - string.gsub!(/<([\/]{0,1})(#{colors})>/i) do |setting| - if ($1.nil?) || ($1.length <= 0) - color_encode($2) - else - color_decode($2) - end - end - #string.gsub!(/<\/([^>]*)>/, @@colors[@color_settings["regular"]]) - #string.gsub!(/(\"(.*?)")/, @color_settings["quote"] + '\1' + @color_settings["regular"]) - else - string.gsub!(/<([^>]*)>/i, "") - string.gsub!(/<\/([^>]*)>/, "") - end - - string - end - - def color_encode(code) - parent = @color_stack[-1] - code = code.downcase - unless code.start_with? "raw " - result = FormatState.new(@color_settings[code], parent) - else - /raw (?<code>.*)/ =~ code - result = FormatState.new(code, parent) - end - @color_stack << result - result.apply - end - - def color_decode(code) - @color_stack.pop.revert - end - - #Sets the foreground color for a given setting. - def set_fg_color(code, color) - code.downcase! unless code.nil? - color.downcase! unless color.nil? - - if not @color_settings.has_key? code - "No such setting: #{code}" - else - if not @use_color - @color_settings.keys.each do |setting| - @color_settings[setting] = "" - end - @use_color = true - end - - @color_settings[code] = color - "Set #{code} to <#{code}>#{color}</#{code}>." - end - end - - #Returns list of color settings to show the player - def show_color_config - <<-CONF -Colors are currently: #{@use_color ? "Enabled" : "Disabled"} -Text Setting Color ------------------------------------------------ -Room Title roomtitle <roomtitle>#{@color_settings['roomtitle']}</roomtitle> -Object object <object>#{@color_settings['object']}</object> -Player player <player>#{@color_settings['player']}</player> -Mob mob <mob>#{@color_settings['mob']}</mob> -Merchant merchant <merchant>#{@color_settings['merchant']}</merchant> -Me me <me>#{@color_settings['me']}</me> -Exit exit <exit>#{@color_settings['exit']}</exit> -Say say <say>#{@color_settings['say']}</say> -Tell tell <tell>#{@color_settings['tell']}</tell> -Important important <important>#{@color_settings['important']}</important> -Editor editor <editor>#{@color_settings['editor']}</editor> -News news <news>#{@color_settings['news']}</news> -Identifier identifier <identifier>#{@color_settings['identifier']}</identifier> -Fire fire <fire>#{@color_settings['fire']}</fire> -Fire when low firelow <firelow>#{@color_settings['firelow']}</firelow> -Fire when high firehigh <firehigh>#{@color_settings['firehigh']}</firehigh> -Air air <air>#{@color_settings['air']}</air> -Air when low airlow <airlow>#{@color_settings['airlow']}</airlow> -Air when high airhigh <airhigh>#{@color_settings['airhigh']}</airhigh> -Water water <water>#{@color_settings['water']}</water> -Water when low waterlow <waterlow>#{@color_settings['waterlow']}</waterlow> -Water when high waterhigh <waterhigh>#{@color_settings['waterhigh']}</waterhigh> -Earth earth <earth>#{@color_settings['earth']}</earth> -Earth when low earthlow <earthlow>#{@color_settings['earthlow']}</earthlow> -Earth when high earthhigh <earthhigh>#{@color_settings['earthhigh']}</earthhigh> -Regular regular #{@color_settings['regular']} -CONF - + def print(message, parse = true, newline = false, message_type: :main, internal_clear: false) + @display.send(message, parse, add_newline: newline, message_type: message_type, internal_clear: internal_clear) unless closed? end #Close the io connection def close - close_connection_after_writing - end - - def ask_mccp - log "asking mccp" - @display.send_raw IAC + WILL + OPT_COMPRESS2 - end - - def ask_mssp - log "asking mssp" - @display.send_raw IAC + WILL + OPT_MSSP - end - - def send_mssp - log "sending mssp" - mssp_options = nil - options = IAC + SB + OPT_MSSP - - if File.exist? "conf/mssp.yaml" - File.open "conf/mssp.yaml" do |f| - mssp_options = YAML.load(f) - end - - mssp_options.each do |k,v| - options << (MSSP_VAR + k + MSSP_VAL + v.to_s) - end - end - - options << (MSSP_VAR + "PLAYERS" + MSSP_VAL + $manager.find_all("class", Player).length.to_s) - options << (MSSP_VAR + "UPTIME" + MSSP_VAL + $manager.uptime.to_s) - options << (MSSP_VAR + "ROOMS" + MSSP_VAL + $manager.find_all("class", Room).length.to_s) - options << (MSSP_VAR + "AREAS" + MSSP_VAL + $manager.find_all("class", Area).length.to_s) - options << (MSSP_VAR + "ANSI" + MSSP_VAL + "1") - options << (MSSP_VAR + "FAMILY" + MSSP_VAL + "CUSTOM") - options << (MSSP_VAR + "CODEBASE" + MSSP_VAL + "Aethyr " + $AETHYR_VERSION) - options << (MSSP_VAR + "PORT" + MSSP_VAL + ServerConfig.port.to_s) - options << (MSSP_VAR + "MCCP" + MSSP_VAL + (ServerConfig[:mccp] ? "1" : "0")) - options << (IAC + SE) - @display.send_raw options - end - - #Use zlib to compress message (for MCCP) - def compress message - begin - @mccp_to_client.deflate message, Zlib::SYNC_FLUSH - rescue Zlib::DataError - message - end - end - - #Use zlib to decompress message (for MCCP) - def decompress message - p message - #message = "\x78\x01" + message - - begin - Zlib::Inflate.inflate message - rescue Zlib::DataError - message - end - end - - #Pulled straight out of standard net/telnet lib. - #Orginal version by Wakou Aoyama <wakou@ruby-lang.org> - def preprocess_input string - if @mccp_from_client - string = decompress string - end - # combine CR+NULL into CR - string = string.gsub(/#{CR}#{NULL}/no, CR) - - # combine EOL into "\n" - string = string.gsub(/#{EOL}/no, "\n") - - string.gsub!(/#{IAC}( - [#{IAC}#{AO}#{AYT}#{DM}#{IP}#{NOP}]| - [#{DO}#{DONT}#{WILL}#{WONT}] - [#{OPT_BINARY}-#{OPT_COMPRESS2}#{OPT_EXOPL}]| - #{SB}[^#{IAC}]*#{IAC}#{SE} - )/xno) do - if IAC == $1 # handle escaped IAC characters - IAC - elsif AYT == $1 # respond to "IAC AYT" (are you there) - send_data("nobody here but us pigeons" + EOL) - '' - elsif DO == $1[0,1] # respond to "IAC DO x" - if OPT_BINARY == $1[1,1] - send_data(IAC + WILL + OPT_BINARY) - elsif OPT_MSSP == $1[1,1] - send_mssp - elsif OPT_COMPRESS2 == $1[1,1] and ServerConfig[:mccp] - begin - require 'zlib' - send_data(IAC + SB + OPT_COMPRESS2 + IAC + SE) - @mccp_to_client = Zlib::Deflate.new - rescue LoadError - log "Warning: No zlib - cannot do MCCP" - send_data(IAC + WONT + $1[1..1]) - return - end - - else - #send_data(IAC + WONT + $1[1..1]) - end - '' - elsif DONT == $1[0,1] # respond to "IAC DON'T x" with "IAC WON'T x" - if OPT_COMPRESS2 == $1[1,1] - @mccp_to_client = false - send_data(IAC + WONT + $1[1..1]) - end - '' - elsif WILL == $1[0,1] # respond to "IAC WILL x" - if OPT_BINARY == $1[1,1] - send_data(IAC + DO + OPT_BINARY) - elsif OPT_ECHO == $1[1,1] - send_data(IAC + DO + OPT_ECHO) - elsif OPT_SGA == $1[1,1] - send_data(IAC + DO + OPT_SGA) - elsif OPT_COMPRESS2 == $1[1,1] - send_data(IAC + DONT + OPT_COMPRESS2) - else - send_data(IAC + DONT + $1[1..1]) - end - '' - elsif WONT == $1[0,1] # respond to "IAC WON'T x" - if OPT_ECHO == $1[1,1] - send_data(IAC + DONT + OPT_ECHO) - elsif OPT_SGA == $1[1,1] - send_data(IAC + DONT + OPT_SGA) - elsif OPT_COMPRESS2 == $1[1,1] - @mccp_from_client = false - send_data(IAC + DONT + OPT_COMPRESS2) - else - send_data(IAC + DONT + $1[1..1]) - end - '' - else - '' - end - end - return string + display.close + @closed = true end end diff --git a/lib/aethyr/core/connection/server.rb b/lib/aethyr/core/connection/server.rb index 36d21a819bcbdca287bd7368198268ac94ea892f..0326d2f3a16ae66bdc0ba98024908b572b17a907 100644 --- a/lib/aethyr/core/connection/server.rb +++ b/lib/aethyr/core/connection/server.rb @@ -6,13 +6,13 @@ Copyright: 2018, Jeffrey Phillips Freeman License: Apache v2 Copyright 2017 - 2018, Jeffrey Phillips Freeman - + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at - + http://www.apache.org/licenses/LICENSE-2.0 - + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -39,62 +39,65 @@ module Aethyr #Creates the Manager, starts the EventMachine, and closes everything down when the time comes. def initialize(address, port) $manager = Manager.new - + updateTask = Concurrent::TimerTask.new(execution_interval: ServerConfig.update_rate, timeout_interval: 10) do $manager.update_all end saveTask = Concurrent::TimerTask.new(execution_interval: ServerConfig.save_rate, timeout_interval: 30) do - log "Automatic state save."; $manager.save_all + log "Automatic state save." + $manager.save_all end - + updateTask.execute saveTask.execute - - listener = server_socket('0.0.0.0', 8888) - + + listener = server_socket(address, port) + File.open("logs/server.log", "a") { |f| f.puts "#{Time.now} Server started." } log "Server up and running on #{address}:#{port}", 0 - + players = Set.new() loop do - did_something = false # handle the listener #ready, _, _ = IO.select([listener]) socket, addr_info = listener.accept_nonblock(exception: false) if (not socket.nil?) and socket.is_a? Socket - did_something = true players << handle_client(socket, addr_info) end - + + players.each do |player| + if player.closed? + log "Player #{player} has closed connection, removing from server queue" + players.delete(player) + else + player.receive_data + end + end + + next_action = $manager.pop_action + next_action.action unless next_action.nil? + + # TODO this is a hack to fix a bug from calling resizeterm + #check if global refresh is needed + need_refresh = false players.each do |player| - recvd = player.display.recv - did_something = true unless recvd.nil? - player.receive_data(recvd) + need_refresh = true if player.display.global_refresh end - - sleep 0.1 unless did_something + if need_refresh + players.each do |player| + player.display.layout + end + #$manager.find_all("class", Player).each do |player| + # puts "updating display of #{player}" + # player.update_display + #end + end + end - -# 4.times do # Adjust this number for the pool size -# next unless fork.nil? # Parent only calls fork -# loop do # Child does this work -# handle_client(*listener.accept) -# end -# return 0 -# end clean_up_children return 0 # Return code - -# EventMachine.run do -# EventMachine.add_periodic_timer(ServerConfig.update_rate) { $manager.update_all } -# if ServerConfig.save_rate and ServerConfig.save_rate > 0 -# EventMachine.add_periodic_timer(ServerConfig.save_rate * 60) { log "Automatic state save."; $manager.save_all } -# end -# EventMachine.start_server address, port, PlayerConnection -# File.open("logs/server.log", "a") { |f| f.puts "#{Time.now} Server started." } -# log "Server up and running on #{address}:#{port}", 0 -# end + rescue Interrupt => i log "Received interrupt: halting", 0 log i.inspect @@ -108,7 +111,7 @@ module Aethyr $manager.save_all log "Objects saved.", Logger::Normal, true end - + private def server_socket(addr, port) socket = Socket.new(:INET, :SOCK_STREAM) @@ -118,18 +121,17 @@ module Aethyr puts 'Waiting for connections...' socket end - + def handle_client(socket, addrinfo) begin - display = Display.new(socket) - player = PlayerConnection.new(display, addrinfo) + player = PlayerConnection.new(socket, addrinfo) puts "Connected: #{addrinfo.inspect}\n" return player rescue Errno::ECONNRESET, Errno::EPIPE puts " Reset: #{addrinfo.inspect}\n" end end - + def clean_up_children loop do Process.wait # Gather processes as they exit @@ -139,75 +141,18 @@ module Aethyr rescue SystemCallError puts 'All children have exited. Goodbye!' end - -# def process_requests(socket) -# begin -# # initialize ncurses -# scr = Ncurses.newterm("vt100", socket, socket) -# Ncurses.set_term(scr) -# Ncurses.resizeterm(25, 80) -# Ncurses.cbreak # provide unbuffered input -# Ncurses.noecho # turn off input echoing -# Ncurses.nonl # turn off newline translation -# -# Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt -# Ncurses.stdscr.keypad(true) # turn on keypad mode -# -# Ncurses.stdscr.addstr("Press a key to continue") # output string -# Ncurses.stdscr.getch # get a charachter -# -# scr = Ncurses.stdscr -# -# #moving -# scr.clear() # clear screen -# scr.move(5,5) # move cursor -# scr.addstr("move(5,5)") -# scr.refresh() # update screen -# sleep(2) -# scr.move(2,2) -# scr.addstr("move(2,2)") -# scr.refresh() -# sleep(2) -# scr.move(10, 2) -# -# # two_borders -# # make a new window as tall as the screen and half as wide, in the left half -# # of the screen -# one = Ncurses::WINDOW.new(0, Ncurses.COLS() / 2, 0, 0) -# # make one for the right half -# two = Ncurses::WINDOW.new(0, Ncurses.COLS() - (Ncurses.COLS() / 2), -# 0, Ncurses.COLS() / 2) -# one.border(*([0]*8)) -# two.border(*([0]*8)) -# one.move(3,3) -# two.move(2,5) -# one.addstr("move(3,3)") -# two.addstr("move(2,5)") -# two.move(5,3) -# two.addstr("Press a key to continue") -# one.noutrefresh() # copy window to virtual screen, don't update real screen -# two.noutrefresh() -# Ncurses.doupdate() # update read screen -# two.getch() -# -# ensure -# Ncurses.echo -# Ncurses.nocbreak -# Ncurses.nl -# Ncurses.endwin -# end -# end + end - - def self.main + + def self.main if ARGV[0] server_restarts = ARGV[0].to_i else server_restarts = 0 end - + log "Server restart ##{server_restarts}" - + begin #result = RubyProf.profile do Server.new(ServerConfig.address, ServerConfig.port) @@ -223,13 +168,13 @@ module Aethyr else File.open("logs/server.log", "a+") { |f| f.puts "#{Time.now} Server restart on error or interrupt." } end - + log "SERVER RESTARTING - Attempting to restart in 10 seconds...press ^C to stop...", Logger::Important sleep ServerConfig.restart_delay log "RESTARTING SERVER", Logger::Important, true - + program_name = ENV["_"] || "ruby" - + if $manager and $manager.soft_restart exec("#{program_name} server.rb") else diff --git a/lib/aethyr/core/connection/telnet.rb b/lib/aethyr/core/connection/telnet.rb new file mode 100644 index 0000000000000000000000000000000000000000..570e7eabef85a1bd776b3f8ffb050f5e05e2c18a --- /dev/null +++ b/lib/aethyr/core/connection/telnet.rb @@ -0,0 +1,247 @@ + +require 'socket' +require 'aethyr/core/connection/telnet_codes' + +class TelnetScanner + PREAMBLE = [IAC + DO + OPT_LINEMODE, + IAC + SB + OPT_LINEMODE + OPT_ECHO + OPT_BINARY + IAC + SE, + IAC + WILL + OPT_ECHO, + IAC + WILL + OPT_MSSP, + IAC + WONT + OPT_COMPRESS2, + IAC + DO + OPT_NAWS].freeze + + def initialize(socket, display) + @socket = socket + @display = display + @linemode_supported = false + @naws_supported = false + @echo_supported = false + end + + def send_preamble + PREAMBLE.each do |line| + @socket.puts line + end + end + + def supports_naws(does_it) + if does_it + @supports_naws = true + log 'Client supports NAWS' + else + @supports_naws = false + log 'Client does NOT support NAWS' + end + end + + def send_mssp + log 'sending mssp' + mssp_options = nil + options = IAC + SB + OPT_MSSP + + if File.exist? 'conf/mssp.yaml' + File.open 'conf/mssp.yaml' do |f| + mssp_options = YAML.safe_load(f) + end + + mssp_options.each do |k, v| + options << (MSSP_VAR + k + MSSP_VAL + v.to_s) + end + end + + options << (MSSP_VAR + 'PLAYERS' + MSSP_VAL + $manager.find_all('class', Player).length.to_s) + options << (MSSP_VAR + 'UPTIME' + MSSP_VAL + $manager.uptime.to_s) + options << (MSSP_VAR + 'ROOMS' + MSSP_VAL + $manager.find_all('class', Room).length.to_s) + options << (MSSP_VAR + 'AREAS' + MSSP_VAL + $manager.find_all('class', Area).length.to_s) + options << (MSSP_VAR + 'ANSI' + MSSP_VAL + '1') + options << (MSSP_VAR + 'FAMILY' + MSSP_VAL + 'CUSTOM') + options << (MSSP_VAR + 'CODEBASE' + MSSP_VAL + 'Aethyr ' + $AETHYR_VERSION) + options << (MSSP_VAR + 'PORT' + MSSP_VAL + ServerConfig.port.to_s) + options << (MSSP_VAR + 'MCCP' + MSSP_VAL + (ServerConfig[:mccp] ? '1' : '0')) + options << (IAC + SE) + @display.send_raw options + end + + def process_iac + @iac_state = :none if @iac_state.nil? + ch = nil? + begin + ch = @socket.recv_nonblock(1, Socket::MSG_PEEK) + rescue Errno::EWOULDBLOCK + return false + end + return false if ch.nil? + + ch = ch.chr + if @iac_state == :none && ch == IAC + @socket.recv(1) + @iac_state = :IAC + return false + elsif @iac_state == :none + return true + else + @socket.recv(1) if @iac_state != IAC || ch != IAC + + case @iac_state + when :IAC + if ch == WILL + @iac_state = :IAC_WILL + elsif ch == SB + @iac_state = :IAC_SB + elsif ch == WONT + @iac_state = :IAC_WONT + elsif ch == DONT + @iac_state = :IAC_DONT + elsif ch == DO + @iac_state = :IAC_DO + elsif ch == IAC + @iac_state = :none + return true + else + @iac_state = :none + end + + when :IAC_WILL + if OPT_BINARY == ch + @socket.puts(IAC + DO + OPT_BINARY) + elsif ch == OPT_NAWS + supports_naws(true) + elsif ch == OPT_LINEMODE + @linemode_supported = true + elsif OPT_ECHO == ch + @socket.puts(IAC + DONT + OPT_ECHO) + elsif OPT_SGA == ch + @socket.puts(IAC + DO + OPT_SGA) + else + @socket.puts(IAC + DONT + ch) + end + @iac_state = :none + + when :IAC_WONT + if ch == OPT_LINEMODE + @linemode_supported = false + elsif ch == OPT_NAWS + supports_naws(false) + else + @socket.puts(IAC + DONT + ch) + end + @iac_state = :none + + when :IAC_DO + if ch == OPT_BINARY + @socket.puts(IAC + WILL + OPT_BINARY) + elsif ch == OPT_ECHO + @echo_supported = true + elsif ch == OPT_MSSP + send_mssp + @mssp_supported = true + else + @socket.puts(IAC + WONT + ch) + end + @iac_state = :none + + when :IAC_DONT + if ch == OPT_ECHO + @echo_supported = false + elsif ch == OPT_COMPRESS2 + # do nothing + elsif ch == OPT_MSSP + @mssp_supported = false + else + @socket.puts(IAC + WONT + ch) + end + @iac_state = :none + + when :IAC_SB + @iac_state = if ch == OPT_NAWS + :IAC_SB_NAWS + else + :IAC_SB_SOMETHING + end + + when :IAC_SB_NAWS + if ch != IAC + @lwidth = ch.ord + @iac_state = :IAC_SB_NAWS_LWIDTH + else + @iac_state = :IAC_SB_NAWS_IAC + end + + when :IAC_SB_NAWS_IAC + if ch == IAC + @lwidth = IAC + @iac_state = :IAC_SB_NAWS_LWIDTH + else + raise "IAC escape expected" + end + + when :IAC_SB_NAWS_LWIDTH + if ch != IAC + @hwidth = ch.ord + @iac_state = :IAC_SB_NAWS_LWIDTH_HWIDTH + else + @iac_state = :IAC_SB_NAWS_LWIDTH_IAC + end + + when :IAC_SB_NAWS_LWIDTH_IAC + if ch == IAC + @hwidth = IAC + @iac_state = IAC_SB_NAWS_LWIDTH_HWIDTH + else + raise "IAC escape expected" + end + + when :IAC_SB_NAWS_LWIDTH_HWIDTH + @lheight = ch.ord + @iac_state = :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT + if ch == IAC #&& @socket.getch != IAC + raise 'escaped IAC expected but not found' + end + + when :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT + if ch != IAC + @hheight = ch.ord + @iac_state = :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT_HHEIGHT + else + @iac_state = :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT_IAC + end + + when :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT_IAC + if ch == IAC + @hheight = IAC + @iac_state = :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT_HHEIGHT + else + raise "IAC escape expected" + end + + when :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT_HHEIGHT + if ch == IAC + @iac_state = :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT_HHEIGHT_IAC + else + raise "invalid IAC" + end + + when :IAC_SB_NAWS_LWIDTH_HWIDTH_LHEIGHT_HHEIGHT_IAC + if ch == SE + new_width = @lwidth * 256 + @hwidth + new_height = @lheight * 256 + @hheight + log "setting resolution #{new_width} #{new_height}" + @display.resolution = [new_width, new_height] + else + raise 'invalid IAC' + end + @iac_state = :none + when :IAC_SB_SOMETHING + @iac_state = :IAC_SB_SOMETHING_IAC if ch == IAC + + when :IAC_SB_SOMETHING_IAC + @iac_state = :IAC_SB_SOMETHING if ch == IAC + @iac_state = :none if ch == SE + else + @iac_state = :none + end + end + + return false + end +end diff --git a/lib/aethyr/core/help/bug.help b/lib/aethyr/core/help/bug.help index f4f7cae273dc959ee696a84b3de0a0e29c6c02de..2b807760ce053c13cf6d6a2e485e523c8403e346 100644 --- a/lib/aethyr/core/help/bug.help +++ b/lib/aethyr/core/help/bug.help @@ -1,11 +1,11 @@ Command: Bug Command: Idea Command: Typo -Syntax: [BUG|IDEA|TYPO] <issue> -Syntax: [BUG|IDEA|TYPO] <id number> +Syntax: [BUG|IDEA|TYPO] [issue] +Syntax: [BUG|IDEA|TYPO] [id number] Syntax: [BUG|IDEA|TYPO] LIST -Syntax: [BUG|IDEA|TYPO] STATUS <id_number> <status> -Syntax: [BUG|IDEA|TYPO] [SHOW|ADD|DEL] <id_number> +Syntax: [BUG|IDEA|TYPO] STATUS [id_number] [status] +Syntax: [BUG|IDEA|TYPO] [SHOW|ADD|DEL] [id_number] These commands allow players and administrators to report and manipulate feedback about the game. The commands are essentially identical, but should be used to report different things. For the rest of this description, BUG is used. diff --git a/lib/aethyr/core/help/emote.help b/lib/aethyr/core/help/emote.help deleted file mode 100644 index 15ec1baab578e3715f70982a9d00a33cbfd84f3b..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/help/emote.help +++ /dev/null @@ -1,36 +0,0 @@ -Command: Emote -Syntax: EMOTE <action> - -The emote command is used to convey actions to an entire room besides just talking or premade emotes (also called socials). -The simplest way to use this command is by simply typing EMOTE then your actions: - -If I am Joe and I type: -EMOTE runs about wildly - -It will result in the room seeing: -Joe runs about wildly. - -However, there are more complex uses. Try using $me to substitute for your name: - -If I am Joe and I type: -EMOTE eyes crazy, $me runs about wildly. - -It will result in the room seeing: -Eyes crazy, Joe runs about wildly. - - -You may also use $name to substitute other people's names into your emote. - -If I am Joe and I type: -EMOTE bonks $sarah on the head - -The room sees: -Joe bonks Sarah on the head. - -Sarah sees: -Joe bonks you on the head. - -Note that you cannot combine $me and $name in the same emote. - - -See also: EMOTELIST diff --git a/lib/aethyr/core/help/help_entry.rb b/lib/aethyr/core/help/help_entry.rb new file mode 100644 index 0000000000000000000000000000000000000000..f4ba2b9f6dc919dfae40a4718afc7ae5be1b7a8b --- /dev/null +++ b/lib/aethyr/core/help/help_entry.rb @@ -0,0 +1,31 @@ +module Aethyr + module Core + module Help + class HelpEntry + attr_reader :topic, :redirect, :content, :see_also, :aliases, :syntax_formats + + def initialize(topic, redirect: nil, content: nil, see_also: nil, aliases: nil, syntax_formats: nil) + #do some validity checking on the arguments + raise "Topic can not be nil" if topic.nil? + raise "Redirect cant be defined alongside other arguments" unless redirect.nil? || (content.nil? && see_also.nil? && aliases.nil? and syntax_formats.nil?) + raise "either content or redirect must be defined" if redirect.nil? && content.nil? + raise "syntax_format must be defined when content is defined" if (not content.nil?) && (syntax_formats.nil? || syntax_formats.empty?) + + @topic = topic + @redirect = redirect + @content = content + @see_also = see_also + @aliases = aliases + @syntax_formats = syntax_formats + @see_also = [] if @see_also.nil? && (not @content.nil?) + @aliases = [] if @aliases.nil? && (not @content.nil?) + end + + def redirect? + return (not @redirect.nil?) + end + end + + end + end +end diff --git a/lib/aethyr/core/help/help_library.rb b/lib/aethyr/core/help/help_library.rb new file mode 100644 index 0000000000000000000000000000000000000000..e09f115876b84e64439ab6fa33fa1a563e2ab697 --- /dev/null +++ b/lib/aethyr/core/help/help_library.rb @@ -0,0 +1,58 @@ +# coding: utf-8 +module Aethyr + module Core + module Help + class HelpLibrary + def initialize + @help_registry = {} + end + + def entry_register(new_entry) + @help_registry[new_entry.topic] = new_entry + end + + def entry_deregister(topic) + @help_registry.delete(topic) + end + + def search_topics(search_term) + return @help_registry.keys.grep /#{search_term}/ + end + + def topics + return @help_registry.keys.dup + end + + def lookup_topic(topic) + return @help_registry[topic] + end + + def render_topic(topic) + redirected_from = "" + entry = lookup_topic(topic) + while entry.redirect? do + redirected_from = "→ redirected from #{topic}\n\n" if redirected_from.empty? + entry = lookup_topic(entry.redirect) + end + + rendered = redirected_from + + rendered += "Aliases: " + entry.aliases.join(", ") + "\n" unless entry.aliases.empty? + + syntaxes = [] + entry.syntax_formats.each do |syntax| + syntaxes.push "Syntax: #{syntax}" + end + rendered += syntaxes.join("\n") + rendered += "\n\n" unless syntaxes.empty? && aliases.empty? + + rendered += entry.content + "\n" + + rendered += "See also: " + entry.see_also.join(", ") + "\n" unless entry.see_also.empty? + + return rendered + end + end + end + end +end diff --git a/lib/aethyr/core/help/idea.help b/lib/aethyr/core/help/idea.help index f4f7cae273dc959ee696a84b3de0a0e29c6c02de..2b807760ce053c13cf6d6a2e485e523c8403e346 100644 --- a/lib/aethyr/core/help/idea.help +++ b/lib/aethyr/core/help/idea.help @@ -1,11 +1,11 @@ Command: Bug Command: Idea Command: Typo -Syntax: [BUG|IDEA|TYPO] <issue> -Syntax: [BUG|IDEA|TYPO] <id number> +Syntax: [BUG|IDEA|TYPO] [issue] +Syntax: [BUG|IDEA|TYPO] [id number] Syntax: [BUG|IDEA|TYPO] LIST -Syntax: [BUG|IDEA|TYPO] STATUS <id_number> <status> -Syntax: [BUG|IDEA|TYPO] [SHOW|ADD|DEL] <id_number> +Syntax: [BUG|IDEA|TYPO] STATUS [id_number] [status] +Syntax: [BUG|IDEA|TYPO] [SHOW|ADD|DEL] [id_number] These commands allow players and administrators to report and manipulate feedback about the game. The commands are essentially identical, but should be used to report different things. For the rest of this description, BUG is used. diff --git a/lib/aethyr/core/help/reply.help b/lib/aethyr/core/help/reply.help deleted file mode 100644 index ab6101858ae6f3426d6075cbe19a873f7431b447..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/help/reply.help +++ /dev/null @@ -1,6 +0,0 @@ -Command: Reply -Syntax: REPLY <message> - -Reply is a shortcut to send a tell to the last person who sent you a tell. - -See also: TELL diff --git a/lib/aethyr/core/help/say.help b/lib/aethyr/core/help/say.help deleted file mode 100644 index 9c681868f8e8d93f49d8207d7c4cabfab176ef6e..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/help/say.help +++ /dev/null @@ -1,18 +0,0 @@ -Command: Say -Syntax: SAY <message> - -This is the basic command for communication. Everyone in the room hears what you say. -Some formatting is automatic, and a few emoticons are supported at the end of the command. - -Example: say i like cheese -Output: You say, "I like cheese." - -Example: say i like cheese! :) -Output: You smile and exclaim, "I like cheese!" - -You can also specify a prefix in parentheses after the say command. - -Example: say (in trepidation) are you going to take my cheese? -Output: In trepidation, you ask, "Are you going to take my cheese?" - -See also: WHISPER, SAYTO diff --git a/lib/aethyr/core/help/sayto.help b/lib/aethyr/core/help/sayto.help deleted file mode 100644 index 8157465c4c985ee2ccaa69c0aaebdbf1ac41889a..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/help/sayto.help +++ /dev/null @@ -1,16 +0,0 @@ -Command: Say to -Syntax: SAYTO <name> <message> - -Say something to someone in particular, who is in the same room: - -Example: - -sayto bob i like cheese - -Output: - -You say to Bob, "I like cheese." - -Also supports the same variations as the SAY command. - -See also: WHISPER, SAY diff --git a/lib/aethyr/core/help/syntax.rb b/lib/aethyr/core/help/syntax.rb index 2034f2c71ff6aa6b3f4c4a9c6e9d1a721042b65a..bbf0ce1a77544cc7dbe135c87fc71e1e0abd6332 100644 --- a/lib/aethyr/core/help/syntax.rb +++ b/lib/aethyr/core/help/syntax.rb @@ -67,23 +67,23 @@ AREACT [RELOAD|CLEAR] [OBJECT]", TERRAIN HERE TYPE [TYPE] TERRAIN HERE (INDOORS|WATER|UNDERWATER) (YES|NO)", "bug" => -"BUG <issue> +"BUG [issue] BUG <id number> BUG LIST BUG STATUS <id_number> <status> BUG [SHOW|ADD|DEL] <id_number>", "idea" => -"IDEA <issue> +"IDEA [issue] IDEA <id number> IDEA LIST IDEA STATUS <id_number> <status> IDEA [SHOW|ADD|DEL] <id_number>", "typo" => -"TYPO <issue> -TYPO <id number> +"TYPO [issue] +TYPO [id number] TYPO LIST -TYPO STATUS <id_number> <status> -TYPO [SHOW|ADD|DEL] <id_number>", +TYPO STATUS [id_number] [status] +TYPO [SHOW|ADD|DEL] [id_number]", "climb" => "What would you like to climb?", "close" => diff --git a/lib/aethyr/core/help/tell.help b/lib/aethyr/core/help/tell.help deleted file mode 100644 index 8eb5665a31901e78deb18fdf264e43cdb69a4e3c..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/help/tell.help +++ /dev/null @@ -1,10 +0,0 @@ -Command: Tell -Syntax: TELL <player> <message> - -All inhabitants of Aethyr have the ability to communicate privately with each other over long distances. This is done through the TELL command. Those who investigate these kinds of things claim there is some kind of latent telepathy in all of us. However, while no one knows for certain how it works, everyone knows it does. - -Example: -TELL Justin Hey, how's it going? - - -See also: SAY, SAYTO, WHISPER, REPLY diff --git a/lib/aethyr/core/help/whisper.help b/lib/aethyr/core/help/whisper.help deleted file mode 100644 index fa4806a235570de109a06fff2e2a896e77802f57..0000000000000000000000000000000000000000 --- a/lib/aethyr/core/help/whisper.help +++ /dev/null @@ -1,15 +0,0 @@ -Command: Whisper -Syntax: WHISPER <person> <message> - -To communicate with someone in the same room, but privately, use this command. - -Example: - -whisper justin that dog needs a bath - -Output: - -You whisper to Justin, "That dog needs a bath." - - -See also: SAY diff --git a/lib/aethyr/core/input_handlers/admin/acarea.rb b/lib/aethyr/core/input_handlers/admin/acarea.rb new file mode 100644 index 0000000000000000000000000000000000000000..4c81d82dd538454ce10d9840f896f75c00bb47ab --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acarea.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/acarea" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acarea + class AcareaHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acarea" + see_also = nil + syntax_formats = ["ACAREA [NAME]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acarea"], help_entries: AcareaHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^acarea\s+(.*)$/i + name = $1.strip + $manager.submit_action(Aethyr::Core::Actions::Acarea::AcareaCommand.new(@player, {:name => name})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcareaHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acdoor.rb b/lib/aethyr/core/input_handlers/admin/acdoor.rb new file mode 100644 index 0000000000000000000000000000000000000000..014fd6f17bec3aac50474aedd18fb2312afd773a --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acdoor.rb @@ -0,0 +1,55 @@ +require "aethyr/core/actions/commands/acdoor" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acdoor + class AcdoorHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acdoor" + see_also = nil + syntax_formats = ["ACDOOR [DIRECTION] [EXIT_ROOM]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acdoor"], help_entries: AcdoorHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^acdoor\s+(\w+)$/i + direction = $1 + $manager.submit_action(Aethyr::Core::Actions::Acdoor::AcdoorCommand.new(@player, {:direction => direction})) + when /^acdoor\s+(\w+)\s+(.*)$/i + direction = $1.strip + exit_room = $2.strip + $manager.submit_action(Aethyr::Core::Actions::Acdoor::AcdoorCommand.new(@player, {:direction => direction, :exit_room => exit_room})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcdoorHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acexit.rb b/lib/aethyr/core/input_handlers/admin/acexit.rb new file mode 100644 index 0000000000000000000000000000000000000000..86c9437e75599c21d7ed8474aa4bafba8cd73244 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acexit.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/acreate" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acexit + class AcexitHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acexit" + see_also = nil + syntax_formats = ["ACEXIT [DIRECTION] [EXIT_ROOM]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acexit"], help_entries: AcexitHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^acexit\s+(\w+)\s+(.*)$/i + object = "exit" + alt_names = [$1.strip] + args = [$2.strip] + $manager.submit_action(Aethyr::Core::Actions::Acreate::AcreateCommand.new(@player, {:object => object, :alt_names => alt_names, :args => args})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcexitHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acomm.rb b/lib/aethyr/core/input_handlers/admin/acomm.rb new file mode 100644 index 0000000000000000000000000000000000000000..77602537dfbcddf87e0968c15791bd97bdd9a4bc --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acomm.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/acomment" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acomm + class AcommHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acomm" + see_also = nil + syntax_formats = ["ACOMMENT [OBJECT] [COMMENT]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acomm"], help_entries: AcommHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(acomm|acomment)\s+(.*?)\s+(.*)$/i + target = $2 + comment = $3 + $manager.submit_action(Aethyr::Core::Actions::Acomment::AcommentCommand.new(@player, {:target => target, :comment => comment})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcommHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acomment.rb b/lib/aethyr/core/input_handlers/admin/acomment.rb new file mode 100644 index 0000000000000000000000000000000000000000..a4caa0151a4afd0931914de6dc3d9f03ce59aed3 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acomment.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/acomment" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acomment + class AcommentHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acomment" + see_also = nil + syntax_formats = ["ACOMMENT [OBJECT] [COMMENT]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acomment"], help_entries: AcommentHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(acomm|acomment)\s+(.*?)\s+(.*)$/i + target = $2 + comment = $3 + $manager.submit_action(Aethyr::Core::Actions::Acomment::AcommentCommand.new(@player, {:target => target, :comment => comment})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcommentHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/aconfig.rb b/lib/aethyr/core/input_handlers/admin/aconfig.rb new file mode 100644 index 0000000000000000000000000000000000000000..530aa196c66db31949e11a41c54d4bc7aaa0df74 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/aconfig.rb @@ -0,0 +1,55 @@ +require "aethyr/core/actions/commands/aconfig" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Aconfig + class AconfigHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "aconfig" + see_also = nil + syntax_formats = ["ACONFIG", "ACONFIG RELOAD", "ACONFIG [SETTING] [VALUE]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["aconfig"], help_entries: AconfigHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^aconfig(\s+reload)?$/i + setting = "reload" if $1 + $manager.submit_action(Aethyr::Core::Actions::Aconfig::AconfigCommand.new(@player, {:setting => setting})) + when /^aconfig\s+(\w+)\s+(.*)$/i + setting = $1 + value = $2 + $manager.submit_action(Aethyr::Core::Actions::Aconfig::AconfigCommand.new(@player, {:setting => setting, :value => value})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AconfigHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acportal.rb b/lib/aethyr/core/input_handlers/admin/acportal.rb new file mode 100644 index 0000000000000000000000000000000000000000..13875028595bc6a98921a0076c01d0014da6f2d1 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acportal.rb @@ -0,0 +1,54 @@ +require "aethyr/core/actions/commands/acportal" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acportal + class AcportalHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acportal" + see_also = nil + syntax_formats = ["ACPORTAL"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acportal"], help_entries: AcportalHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^acportal(\s+(jump|climb|crawl|enter))?(\s+(.*))?$/i + object = "portal" + alt_names = [] + portal_action = $2 + args = [$4] + $manager.submit_action(Aethyr::Core::Actions::Acportal::AcportalCommand.new(@player, {:object => object, :alt_names => alt_names, :portal_action => portal_action, :args => args})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcportalHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acprop.rb b/lib/aethyr/core/input_handlers/admin/acprop.rb new file mode 100644 index 0000000000000000000000000000000000000000..f94bab925eeb393a6d3fb88c81f62eb93e6d02da --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acprop.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/acreate" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acprop + class AcpropHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acprop" + see_also = nil + syntax_formats = ["ACPROP [GENERIC]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acprop"], help_entries: AcpropHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^acprop\s+(.*)$/i + object = "prop" + generic = $1 + $manager.submit_action(Aethyr::Core::Actions::Acreate::AcreateCommand.new(@player, {:object => object, :generic => generic})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcpropHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acreate.rb b/lib/aethyr/core/input_handlers/admin/acreate.rb new file mode 100644 index 0000000000000000000000000000000000000000..99781b6a573005811b1eb849eb2a28c1baa428db --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acreate.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/acreate" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acreate + class AcreateHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acreate" + see_also = nil + syntax_formats = ["ACREATE [OBJECT_TYPE] [NAME]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acreate"], help_entries: AcreateHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(ac|acreate)\s+(\w+)\s*(.*)$/i + object = $2 + name = $3.strip + $manager.submit_action(Aethyr::Core::Actions::Acreate::AcreateCommand.new(@player, {:object => object, :name => name})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcreateHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/acroom.rb b/lib/aethyr/core/input_handlers/admin/acroom.rb new file mode 100644 index 0000000000000000000000000000000000000000..40eb1a20f0067b72b8c44125228ebe670475a208 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/acroom.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/acroom" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Acroom + class AcroomHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "acroom" + see_also = nil + syntax_formats = ["ACROOM [OUT_DIRECTION] [NAME]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["acroom"], help_entries: AcroomHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^acroom\s+(\w+)\s+(.*)$/i + out_dir = $1 + in_dir = opposite_dir($1) + name = $2 + $manager.submit_action(Aethyr::Core::Actions::Acroom::AcroomCommand.new(@player, {:out_dir => out_dir, :in_dir => in_dir, :name => name})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AcroomHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/adelete.rb b/lib/aethyr/core/input_handlers/admin/adelete.rb new file mode 100644 index 0000000000000000000000000000000000000000..0220da6abc780aab0f5358233d815a4378db66a2 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/adelete.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/adelete" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Adelete + class AdeleteHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "adelete" + see_also = nil + syntax_formats = ["ADELETE [OBJECT]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["adelete"], help_entries: AdeleteHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^adelete\s+(.*)$/i + object = $1 + $manager.submit_action(Aethyr::Core::Actions::Adelete::AdeleteCommand.new(@player, {:object => object})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AdeleteHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/adesc.rb b/lib/aethyr/core/input_handlers/admin/adesc.rb new file mode 100644 index 0000000000000000000000000000000000000000..4e73fab5507d9eb1792b3f8e9b5e12e765dafbb2 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/adesc.rb @@ -0,0 +1,57 @@ +require "aethyr/core/actions/commands/adesc" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Adesc + class AdescHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "adesc" + see_also = nil + syntax_formats = ["ADESC [OBJECT] [DESCRIPTION]", "ADESC INROOM [OBJECT] [DESCRIPTION]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["adesc"], help_entries: AdescHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^adesc\s+inroom\s+(.*?)\s+(.*)$/i + object = $1 + inroom = true + desc = $2 + $manager.submit_action(Aethyr::Core::Actions::Adesc::AdescCommand.new(@player, {:object => object, :inroom => inroom, :desc => desc})) + when /^adesc\s+(.*?)\s+(.*)$/i + object = $1 + desc = $2 + $manager.submit_action(Aethyr::Core::Actions::Adesc::AdescCommand.new(@player, {:object => object, :desc => desc})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AdescHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/admin_handler.rb b/lib/aethyr/core/input_handlers/admin/admin_handler.rb new file mode 100644 index 0000000000000000000000000000000000000000..e1a4f345f0f813a72b16f030fe12721ccd768349 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/admin_handler.rb @@ -0,0 +1,36 @@ +require 'aethyr/core/input_handlers/command_handler' + +module Aethyr + module Extend + class AdminHandler < CommandHandler + def initialize(player, commands, *args, help_entries: []) + super(player, commands, *args, help_entries: help_entries) + end + + protected + def self.object_added(data, child_class) + return unless (data[:game_object].is_a? Player) && data[:game_object].admin + data[:game_object].subscribe(child_class.new(data[:game_object])) + end + + #Tail a file + def tail file, lines = 10 + require 'util/tail' + + output = [] + File::Tail::Logfile.tail(file, :backward => lines, :return_if_eof => true) do |line| + output << line.strip + end + + output << "(#{output.length} lines shown.)" + end + + #Looks in player's inventory and room for name. + #Then checks at global level for GOID. + def find_object(name, event) + $manager.find(name, event[:player]) || $manager.find(name, event[:player].container) || $manager.get_object(name) + end + + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/aforce.rb b/lib/aethyr/core/input_handlers/admin/aforce.rb new file mode 100644 index 0000000000000000000000000000000000000000..a5ad5da83ee063d544f1d754db6b903a444d3514 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/aforce.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/aforce" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Aforce + class AforceHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "aforce" + see_also = nil + syntax_formats = ["AFORCE [OBJECT] [ACTION]"] + aliases = nil + content = <<'EOF' +Forces another player to execute a command. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["aforce"], help_entries: AforceHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^aforce\s+(.*?)\s+(.*)$/i + target = $1 + command = $2 + $manager.submit_action(Aethyr::Core::Actions::Aforce::AforceCommand.new(@player, {:target => target, :command => command})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AforceHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/ahelp.rb b/lib/aethyr/core/input_handlers/admin/ahelp.rb new file mode 100644 index 0000000000000000000000000000000000000000..2be30404068e9ef489e86d5f046e4d59f418a434 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/ahelp.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/ahelp" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Ahelp + class AhelpHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "ahelp" + see_also = nil + syntax_formats = ["AHELP"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["ahelp"], help_entries: AhelpHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^ahelp(.*)$/i + object = $1 + $manager.submit_action(Aethyr::Core::Actions::Ahelp::AhelpCommand.new(@player, {:object => object})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AhelpHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/ahide.rb b/lib/aethyr/core/input_handlers/admin/ahide.rb new file mode 100644 index 0000000000000000000000000000000000000000..1a2831ce45caffe1943a0060f8f0f12b6b2d3b5b --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/ahide.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/ahide" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Ahide + class AhideHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "ahide" + see_also = nil + syntax_formats = ["AHIDE"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["ahide"], help_entries: AhideHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^ahide\s+(.*)$/i + object = $1 + hide = true + $manager.submit_action(Aethyr::Core::Actions::Ahide::AhideCommand.new(@player, {:object => object, :hide => hide})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AhideHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/ainfo.rb b/lib/aethyr/core/input_handlers/admin/ainfo.rb new file mode 100644 index 0000000000000000000000000000000000000000..6214170702c7a3969cc7aa05cda3269dcb723f43 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/ainfo.rb @@ -0,0 +1,63 @@ +require "aethyr/core/actions/commands/ainfo" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Ainfo + class AinfoHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "ainfo" + see_also = nil + syntax_formats = ["AINFO SET [OBJECT] @[ATTRIBUTE] [VALUE]", "AINFO DELETE [OBJECT] @[ATTRIBUTE]", "AINFO [SHOW|CLEAR] [OBJECT]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["ainfo"], help_entries: AinfoHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^ainfo\s+set\s+(.+)\s+@((\w|\.|\_)+)\s+(.*?)$/i + command = "set" + object = $1 + attrib = $2 + value = $4 + $manager.submit_action(Aethyr::Core::Actions::Ainfo::AinfoCommand.new(@player, {:command => command, :object => object, :attrib => attrib, :value => value})) + when /^ainfo\s+(show|clear)\s+(.*)$/i + object = $2 + command = $1 + $manager.submit_action(Aethyr::Core::Actions::Ainfo::AinfoCommand.new(@player, {:object => object, :command => command})) + when /^ainfo\s+(del|delete)\s+(.+)\s+@((\w|\.|\_)+)$/i + command = "delete" + object = $2 + attrib = $3 + $manager.submit_action(Aethyr::Core::Actions::Ainfo::AinfoCommand.new(@player, {:command => command, :object => object, :attrib => attrib})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AinfoHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/alearn.rb b/lib/aethyr/core/input_handlers/admin/alearn.rb new file mode 100644 index 0000000000000000000000000000000000000000..f1b03d224a310c225a8b95ece210c2c8cebd851a --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/alearn.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/alearn" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Alearn + class AlearnHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "alearn" + see_also = nil + syntax_formats = ["ALEARN [SKILL]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["alearn"], help_entries: AlearnHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^alearn\s+(\w+)$/i + skill = $1 + $manager.submit_action(Aethyr::Core::Actions::Alearn::AlearnCommand.new(@player, {:skill => skill})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AlearnHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/alist.rb b/lib/aethyr/core/input_handlers/admin/alist.rb new file mode 100644 index 0000000000000000000000000000000000000000..cfbd20d13017daa2d9731a6768b445364a5c8787 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/alist.rb @@ -0,0 +1,54 @@ +require "aethyr/core/actions/commands/alist" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Alist + class AlistHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "alist" + see_also = nil + syntax_formats = ["ALIST [ATTRIB] [QUERY]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["alist"], help_entries: AlistHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^alist$/i + $manager.submit_action(Aethyr::Core::Actions::Alist::AlistCommand.new(@player, {})) + when /^alist\s+(@\w+|class)\s+(.*)/i + attrib = $2 + match = $1 + $manager.submit_action(Aethyr::Core::Actions::Alist::AlistCommand.new(@player, {:attrib => attrib, :match => match})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AlistHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/alog.rb b/lib/aethyr/core/input_handlers/admin/alog.rb new file mode 100644 index 0000000000000000000000000000000000000000..5ac6900e0a0523995744870a1721cf0af187fd0f --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/alog.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/alog" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Alog + class AlogHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "alog" + see_also = nil + syntax_formats = ["ALOG (DEBUG|NORMAL|HIGH|ULTIMATE|OFF)", "ALOG (PLAYER|SERVER|SYSTEM) [LINES]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["alog"], help_entries: AlogHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^alog\s+(\w+)(\s+(\d+))?$/i + command = $1 + value = $3.downcase if $3 + $manager.submit_action(Aethyr::Core::Actions::Alog::AlogCommand.new(@player, {:command => command, :value => value})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AlogHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/alook.rb b/lib/aethyr/core/input_handlers/admin/alook.rb new file mode 100644 index 0000000000000000000000000000000000000000..3877f7108ae395d1eb7ed3ab926cd4783251ad95 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/alook.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/alook" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Alook + class AlookHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "alook" + see_also = nil + syntax_formats = ["ALOOK [OBJECT]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["alook"], help_entries: AlookHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^alook$/i + $manager.submit_action(Aethyr::Core::Actions::Alook::AlookCommand.new(@player, {})) + when /^alook\s+(.*)$/i + at = $1 + $manager.submit_action(Aethyr::Core::Actions::Alook::AlookCommand.new(@player, {:at => at})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AlookHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/aput.rb b/lib/aethyr/core/input_handlers/admin/aput.rb new file mode 100644 index 0000000000000000000000000000000000000000..db726fc1f1f792bb2cccd76d749cf0f05c74547d --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/aput.rb @@ -0,0 +1,57 @@ +require "aethyr/core/actions/commands/aput" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Aput + class AputHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "aput" + see_also = nil + syntax_formats = ["APUT [OBJECT] IN [CONTAINER]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["aput"], help_entries: AputHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^aput\s+(.*?)\s+in\s+(.*?)\s+at\s+(.*?)$/i + object = $1 + in_var = $2 + at = $3 + $manager.submit_action(Aethyr::Core::Actions::Aput::AputCommand.new(@player, {:object => object, :in => in_var, :at => at})) + when /^aput\s+(.*?)\s+in\s+(.*?)$/i + object = $1 + in_var = $2 + $manager.submit_action(Aethyr::Core::Actions::Aput::AputCommand.new(@player, {:object => object, :in => in_var})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AputHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/areact.rb b/lib/aethyr/core/input_handlers/admin/areact.rb new file mode 100644 index 0000000000000000000000000000000000000000..1a8b57d56e5240513e3e0eba78c661a1834f06ff --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/areact.rb @@ -0,0 +1,62 @@ +require "aethyr/core/actions/commands/areaction" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Areact + class AreactHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "areact" + see_also = nil + syntax_formats = ["AREACT LOAD [OBJECT] [FILE]", "AREACT [RELOAD|CLEAR] [OBJECT]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["areact"], help_entries: AreactHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^areact\s+load\s+(.*?)\s+(\w+)$/i + object = $1 + command = "load" + file = $2 + $manager.submit_action(Aethyr::Core::Actions::Areaction::AreactionCommand.new(@player, {:object => object, :command => command, :file => file})) + when /^areact\s+(reload|clear|show)\s+(.*?)$/i + object = $2 + command = $1 + $manager.submit_action(Aethyr::Core::Actions::Areaction::AreactionCommand.new(@player, {:object => object, :command => command})) + when /^areact\s+(add|delete)\s+(.*?)\s+(\w+)$/i + object = $2 + command = $1 + action_name = $3 + $manager.submit_action(Aethyr::Core::Actions::Areaction::AreactionCommand.new(@player, {:object => object, :command => command, :action_name => action_name})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AreactHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/areas.rb b/lib/aethyr/core/input_handlers/admin/areas.rb new file mode 100644 index 0000000000000000000000000000000000000000..b320ed3b0e2974f59443ff1adc3c2fc4a97eeecf --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/areas.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/commands/areas" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Areas + class AreasHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "areas" + see_also = nil + syntax_formats = ["AREAS"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["areas"], help_entries: AreasHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^areas$/i + $manager.submit_action(Aethyr::Core::Actions::Areas::AreasCommand.new(@player, {})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AreasHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/areload.rb b/lib/aethyr/core/input_handlers/admin/areload.rb new file mode 100644 index 0000000000000000000000000000000000000000..b3949165ec9b0f3b696f4e9a907970b0fb86da89 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/areload.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/areload" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Areload + class AreloadHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "areload" + see_also = nil + syntax_formats = ["ARELOAD [OBJECT]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["areload"], help_entries: AreloadHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^areload\s+(.*)$/i + object = $1 + $manager.submit_action(Aethyr::Core::Actions::Areload::AreloadCommand.new(@player, {:object => object})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AreloadHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/asave.rb b/lib/aethyr/core/input_handlers/admin/asave.rb new file mode 100644 index 0000000000000000000000000000000000000000..5fe068ed2ae629316744d142600f598e3bdd1148 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/asave.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/commands/asave" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Asave + class AsaveHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "asave" + see_also = nil + syntax_formats = ["ASAVE"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["asave"], help_entries: AsaveHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^asave$/i + $manager.submit_action(Aethyr::Core::Actions::Asave::AsaveCommand.new(@player, {})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AsaveHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/aset.rb b/lib/aethyr/core/input_handlers/admin/aset.rb new file mode 100644 index 0000000000000000000000000000000000000000..bdc3e8f4d2b210b16ace9b12efc014e54de429e3 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/aset.rb @@ -0,0 +1,65 @@ +require "aethyr/core/actions/commands/aset" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Aset + class AsetHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "aset" + see_also = nil + syntax_formats = ["ASET [OBJECT] @[ATTRIBUTE] [VALUE]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["aset", "aset!"], help_entries: AsetHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^aset\s+(.+?)\s+(@\w+|smell|feel|texture|taste|sound|listen)\s+(.*)$/i + object = $1 + attribute = $2 + value = $3 + $manager.submit_action(Aethyr::Core::Actions::Aset::AsetCommand.new(@player, {:object => object, :attribute => attribute, :value => value})) + when /^aset!\s+(.+?)\s+(@\w+|smell|feel|texture|taste|sound|listen)\s+(.*)$/i + object = $1 + attribute = $2 + value = $3 + force = true + $manager.submit_action(Aethyr::Core::Actions::Aset::AsetCommand.new(@player, {:object => object, :attribute => attribute, :value => value, :force => force})) + when /^aset!\s+(.+?)\s+(@\w+|smell|feel|texture|taste|sound|listen)\s+(.*)$/i + object = $1 + attribute = $2 + value = $3 + force = true + $manager.submit_action(Aethyr::Core::Actions::Aset::AsetCommand.new(@player, {:object => object, :attribute => attribute, :value => value, :force => force})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AsetHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/ashow.rb b/lib/aethyr/core/input_handlers/admin/ashow.rb new file mode 100644 index 0000000000000000000000000000000000000000..a02b6b88e482109737897351d6474ace40e0e4be --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/ashow.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/ahide" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Ashow + class AshowHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "ashow" + see_also = nil + syntax_formats = ["ASHOW"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["ashow"], help_entries: AshowHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^ashow\s+(.*)$/i + object = $1 + hide = false + $manager.submit_action(Aethyr::Core::Actions::Ahide::AhideCommand.new(@player, {:object => object, :hide => hide})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AshowHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/astatus.rb b/lib/aethyr/core/input_handlers/admin/astatus.rb new file mode 100644 index 0000000000000000000000000000000000000000..2464bd1e9506cffbae00f7b3840c46b27b8a9cfe --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/astatus.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/commands/astatus" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Astatus + class AstatusHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "astatus" + see_also = nil + syntax_formats = ["ASTATUS"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["astatus"], help_entries: AstatusHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^astatus/i + $manager.submit_action(Aethyr::Core::Actions::Astatus::AstatusCommand.new(@player, {})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AstatusHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/ateach.rb b/lib/aethyr/core/input_handlers/admin/ateach.rb new file mode 100644 index 0000000000000000000000000000000000000000..08c0693a710243d89736e3d607aa7b884d315705 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/ateach.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/ateach" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Ateach + class AteachHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "ateach" + see_also = nil + syntax_formats = ["ATEACH [OBJECT] [SKILL]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["ateach"], help_entries: AteachHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^ateach\s+(\w+)\s+(\w+)$/i + target = $1 + skill = $2 + $manager.submit_action(Aethyr::Core::Actions::Ateach::AteachCommand.new(@player, {:target => target, :skill => skill})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AteachHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/awatch.rb b/lib/aethyr/core/input_handlers/admin/awatch.rb new file mode 100644 index 0000000000000000000000000000000000000000..705fb7e3d71b4a10ce4988032b2b08fedfa5951c --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/awatch.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/awatch" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Awatch + class AwatchHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "awatch" + see_also = nil + syntax_formats = ["AWATCH"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["awatch"], help_entries: AwatchHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^awatch\s+((start|stop)\s+)?(.*)$/i + target = $3.downcase if $3 + command = $2.downcase if $2 + $manager.submit_action(Aethyr::Core::Actions::Awatch::AwatchCommand.new(@player, {:target => target, :command => command})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AwatchHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/awho.rb b/lib/aethyr/core/input_handlers/admin/awho.rb new file mode 100644 index 0000000000000000000000000000000000000000..3c7578f7479ce6ff6265554536d74b814249995c --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/awho.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/commands/awho" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Awho + class AwhoHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "awho" + see_also = nil + syntax_formats = ["AWHO"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["awho"], help_entries: AwhoHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^awho/i + $manager.submit_action(Aethyr::Core::Actions::Awho::AwhoCommand.new(@player, {})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AwhoHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/deleteplayer.rb b/lib/aethyr/core/input_handlers/admin/deleteplayer.rb new file mode 100644 index 0000000000000000000000000000000000000000..c9592a0f5db99de833df6709c57a04f6169cefae --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/deleteplayer.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/delete_player" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Deleteplayer + class DeleteplayerHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "deleteplayer" + see_also = nil + syntax_formats = ["DELETEPLAYER"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["deleteplayer"], help_entries: DeleteplayerHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^deleteplayer\s+(\w+)$/i + object = $1.downcase + $manager.submit_action(Aethyr::Core::Actions::DeletePlayer::DeletePlayerCommand.new(@player, {:object => object})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(DeleteplayerHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/restart.rb b/lib/aethyr/core/input_handlers/admin/restart.rb new file mode 100644 index 0000000000000000000000000000000000000000..3a944fa8d244a464c1a2d035aedb1d97f7a8bf42 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/restart.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/commands/restart" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Restart + class RestartHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "restart" + see_also = nil + syntax_formats = ["RESTART"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["restart"], help_entries: RestartHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^restart$/i + $manager.submit_action(Aethyr::Core::Actions::Restart::RestartCommand.new(@player, {})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(RestartHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/admin/terrain.rb b/lib/aethyr/core/input_handlers/admin/terrain.rb new file mode 100644 index 0000000000000000000000000000000000000000..07656ae6a301af7859d74456cf95136514f85da8 --- /dev/null +++ b/lib/aethyr/core/input_handlers/admin/terrain.rb @@ -0,0 +1,57 @@ +require "aethyr/core/actions/commands/terrain" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/admin/admin_handler" + +module Aethyr + module Core + module Commands + module Terrain + class TerrainHandler < Aethyr::Extend::AdminHandler + + def self.create_help_entries + help_entries = [] + + command = "terrain" + see_also = nil + syntax_formats = ["TERRAIN AREA [TYPE]", "TERRAIN HERE TYPE [TYPE]", "TERRAIN HERE (INDOORS|WATER|UNDERWATER) (YES|NO)"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["terrain"], help_entries: TerrainHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^terrain\s+area\s+(.*)$/i + target = "area" + value = $1 + $manager.submit_action(Aethyr::Core::Actions::Terrain::TerrainCommand.new(@player, {:target => target, :value => value})) + when /^terrain\s+(room|here)\s+(type|indoors|underwater|water)\s+(.*)$/ + target = "room" + setting = $2.downcase + value = $3 + $manager.submit_action(Aethyr::Core::Actions::Terrain::TerrainCommand.new(@player, {:target => target, :setting => setting, :value => value})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(TerrainHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/block.rb b/lib/aethyr/core/input_handlers/block.rb new file mode 100644 index 0000000000000000000000000000000000000000..8f36778b44b810575258fcc261ad1dd4762976f0 --- /dev/null +++ b/lib/aethyr/core/input_handlers/block.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/simple_block" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Block + class BlockHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "block" + see_also = ["THRUST", "STATUS"] + syntax_formats = ["BLOCK <target>", "BLOCK"] + aliases = nil + content = <<'EOF' +This is a simple block which uses your weapon to attempt to block an opponent's attack. If you are not wielding a weapon, you will attempt a block with your bare hands. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["block"], help_entries: BlockHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^block(\s+(.*))?$/i + target = $2 + $manager.submit_action(Aethyr::Core::Actions::SimpleBlock::SimpleBlockCommand.new(@player, {:target => target})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(BlockHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/close.rb b/lib/aethyr/core/input_handlers/close.rb new file mode 100644 index 0000000000000000000000000000000000000000..535a34efee513b81d2ac75afb7a4a0f88e3b1788 --- /dev/null +++ b/lib/aethyr/core/input_handlers/close.rb @@ -0,0 +1,58 @@ +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" +require "aethyr/core/util/direction" +require "aethyr/core/help/help_entry" +require "aethyr/core/actions/command_action" +require "aethyr/core/actions/commands/close" + +module Aethyr + module Core + module Commands + module Close + class CloseHandler < Aethyr::Extend::CommandHandler + + include Aethyr::Direction + + def self.create_help_entries + command = "close" + see_also = ["LOCK", "UNLOCK", "OPEN"] + syntax_formats = ["CLOSE [object or direction]"] + content = <<'EOF' +Command: Close +Syntax: CLOSE [object or direction] + +Closes the object. For doors and such, it is more accurate to use the direction in which the object lies. + +For example: + +CLOSE north + +CLOSE door + + +See also: LOCK, UNLOCK, OPEN +EOF + return [Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also)] + end + + def initialize(player) + super(player, ["close"], help_entries: CloseHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(close|shut)\s+(\w+)$/i + CloseCommand.new(@player, :object => $2).action() + end + end + end + Aethyr::Extend::HandlerRegistry.register_handler(CloseHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/command_handler.rb b/lib/aethyr/core/input_handlers/command_handler.rb new file mode 100644 index 0000000000000000000000000000000000000000..c3386f0bca0b130add07d84fb1b605b0bce48a42 --- /dev/null +++ b/lib/aethyr/core/input_handlers/command_handler.rb @@ -0,0 +1,36 @@ +require 'aethyr/core/input_handlers/help_handler' + +module Aethyr + module Extend + + class InputHandler + attr_reader :player + + def initialize(player, *args, **kwargs) + super() + @player = player + end + + def player_input(data) + false + end + end + + class CommandHandler < InputHandler + include Aethyr::Extend::HandleHelp + + def initialize(player, commands, *args, help_entries: [], **kwargs) + super(player, commands, *args, help_entries: help_entries, **kwargs) + end + + protected + #event listener parent that listens for when a new user is added to the manager + def self.object_added(data, child_class = nil) + raise "child_class must be defined, object_added is likely not implemented in the child class" if child_class.nil? + return unless data[:game_object].is_a? Player + data[:game_object].subscribe(child_class.new(data[:game_object])) + end + + end + end +end diff --git a/lib/aethyr/core/input_handlers/dodge.rb b/lib/aethyr/core/input_handlers/dodge.rb new file mode 100644 index 0000000000000000000000000000000000000000..6e18a7bf66e8dff374ebd163e0c7b6284da55aff --- /dev/null +++ b/lib/aethyr/core/input_handlers/dodge.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/simple_dodge" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Dodge + class DodgeHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "dodge" + see_also = nil + syntax_formats = ["DODGE"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["dodge"], help_entries: DodgeHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^dodge(\s+(.*))?$/i + target = $2 if $2 + $manager.submit_action(Aethyr::Core::Actions::SimpleDodge::SimpleDodgeCommand.new(@player, {:target => target})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(DodgeHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/drop.rb b/lib/aethyr/core/input_handlers/drop.rb new file mode 100644 index 0000000000000000000000000000000000000000..702b41233783c1bbfe2e28fdd2d59537e76dcf47 --- /dev/null +++ b/lib/aethyr/core/input_handlers/drop.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/drop" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Drop + class DropHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "drop" + see_also = ["GET", "TAKE", "GRAB"] + syntax_formats = ["DROP [object]"] + aliases = nil + content = <<'EOF' +Removes an object from your inventory and places it gently on the ground. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["drop"], help_entries: DropHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^drop\s+((\w+\s*)*)$/i + $manager.submit_action(Aethyr::Core::Actions::Drop::DropCommand.new(@player, { :object => $1.strip })) + end + end + + private + #Drops an item from the player's inventory into the room. + + end + + Aethyr::Extend::HandlerRegistry.register_handler(DropHandler) + end + end + end +end \ No newline at end of file diff --git a/lib/aethyr/core/input_handlers/emotes/agree.rb b/lib/aethyr/core/input_handlers/emotes/agree.rb new file mode 100644 index 0000000000000000000000000000000000000000..00e82b1ef0d011cd37c05334de2172ff066353b6 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/agree.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/agree" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Agree + class AgreeHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "agree" + see_also = nil + syntax_formats = ["AGREE"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["agree"], help_entries: AgreeHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(agree)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Agree::AgreeCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(AgreeHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/back.rb b/lib/aethyr/core/input_handlers/emotes/back.rb new file mode 100644 index 0000000000000000000000000000000000000000..3686787a9db567d1f5d2fdcc96266c118c64f0e7 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/back.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/back" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Back + class BackHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "back" + see_also = nil + syntax_formats = ["BACK"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["back"], help_entries: BackHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(back)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Back::BackCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(BackHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/blush.rb b/lib/aethyr/core/input_handlers/emotes/blush.rb new file mode 100644 index 0000000000000000000000000000000000000000..83cc9ff4b52f13ca43e8b9537661d6ef46a092a6 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/blush.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/blush" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Blush + class BlushHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "blush" + see_also = nil + syntax_formats = ["BLUSH"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["blush"], help_entries: BlushHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(blush)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Blush::BlushCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(BlushHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/bow.rb b/lib/aethyr/core/input_handlers/emotes/bow.rb new file mode 100644 index 0000000000000000000000000000000000000000..8da2217c8b3aae1d654d7264c65cd10a57fb832d --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/bow.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/bow" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Bow + class BowHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "bow" + see_also = nil + syntax_formats = ["BOW"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["bow"], help_entries: BowHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(bow)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Bow::BowCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(BowHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/brb.rb b/lib/aethyr/core/input_handlers/emotes/brb.rb new file mode 100644 index 0000000000000000000000000000000000000000..fc5224525dbfb7a20c05ea304249c914cf089504 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/brb.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/brb" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Brb + class BrbHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "brb" + see_also = nil + syntax_formats = ["BRB"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["brb"], help_entries: BrbHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(brb)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Brb::BrbCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(BrbHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/bye.rb b/lib/aethyr/core/input_handlers/emotes/bye.rb new file mode 100644 index 0000000000000000000000000000000000000000..bb32281c98ca9f6ed1d0726f4da7a52911c034e5 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/bye.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/bye" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Bye + class ByeHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "bye" + see_also = nil + syntax_formats = ["BYE"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["bye"], help_entries: ByeHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(bye)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Bye::ByeCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(ByeHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/cheer.rb b/lib/aethyr/core/input_handlers/emotes/cheer.rb new file mode 100644 index 0000000000000000000000000000000000000000..d3641a4b3984efb2bf7b291768b88b59295006e2 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/cheer.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/cheer" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Cheer + class CheerHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "cheer" + see_also = nil + syntax_formats = ["CHEER"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["cheer"], help_entries: CheerHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(cheer)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Cheer::CheerCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(CheerHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/cry.rb b/lib/aethyr/core/input_handlers/emotes/cry.rb new file mode 100644 index 0000000000000000000000000000000000000000..a115bb08e19a027094feaaab81e8dbc57067ab62 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/cry.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/cry" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Cry + class CryHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "cry" + see_also = nil + syntax_formats = ["CRY"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["cry"], help_entries: CryHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(cry)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Cry::CryCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(CryHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/curtsey.rb b/lib/aethyr/core/input_handlers/emotes/curtsey.rb new file mode 100644 index 0000000000000000000000000000000000000000..fd968c6abe4ac695eabbb1e09b2a81ffb3db35bb --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/curtsey.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/curtsey" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Curtsey + class CurtseyHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "curtsey" + see_also = nil + syntax_formats = ["CURTSEY"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["curtsey"], help_entries: CurtseyHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(curtsey)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Curtsey::CurtseyCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(CurtseyHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/eh.rb b/lib/aethyr/core/input_handlers/emotes/eh.rb new file mode 100644 index 0000000000000000000000000000000000000000..1538d607e99d581983e95f75fee952404f7e6974 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/eh.rb @@ -0,0 +1,49 @@ +require "aethyr/core/actions/commands/emotes/eh" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Eh + class EhHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "eh" + see_also = nil + syntax_formats = ["EH"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["eh", "eh?"], help_entries: EhHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(eh)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Eh::EhCommand.new(@player, {:object => object, :post => post})) + end + end + end + Aethyr::Extend::HandlerRegistry.register_handler(EhHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/emote.rb b/lib/aethyr/core/input_handlers/emotes/emote.rb new file mode 100644 index 0000000000000000000000000000000000000000..7c421a1306b9f8d70337f17cc89f1840a9e219c9 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/emote.rb @@ -0,0 +1,80 @@ +require "aethyr/core/actions/commands/emotes/emote" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Emote + class EmoteHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "emote" + see_also = nil + syntax_formats = ["EMOTE [action]"] + aliases = nil + content = <<'EOF' +The emote command is used to convey actions to an entire room besides just talking or premade emotes (also called socials). +The simplest way to use this command is by simply typing EMOTE then your actions: + +If I am Joe and I type: +EMOTE runs about wildly + +It will result in the room seeing: +Joe runs about wildly. + +However, there are more complex uses. Try using $me to substitute for your name: + +If I am Joe and I type: +EMOTE eyes crazy, $me runs about wildly. + +It will result in the room seeing: +Eyes crazy, Joe runs about wildly. + + +You may also use $name to substitute other people's names into your emote. + +If I am Joe and I type: +EMOTE bonks $sarah on the head + +The room sees: +Joe bonks Sarah on the head. + +Sarah sees: +Joe bonks you on the head. + +Note that you cannot combine $me and $name in the same emote. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["emote"], help_entries: EmoteHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^emote\s+(.*)/i + show = $1 + $manager.submit_action(Aethyr::Core::Actions::Emote::EmoteCommand.new(@player, {:show => show})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(EmoteHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/emote_handler.rb b/lib/aethyr/core/input_handlers/emotes/emote_handler.rb new file mode 100644 index 0000000000000000000000000000000000000000..95629d44c62084478c9ee11036240fb75f0a2567 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/emote_handler.rb @@ -0,0 +1,12 @@ +require 'aethyr/core/input_handlers/command_handler' + +module Aethyr + module Extend + class EmoteHandler < CommandHandler + def initialize(player, commands, *args, **kwargs) + super(player, commands, *args, **kwargs) + end + + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/er.rb b/lib/aethyr/core/input_handlers/emotes/er.rb new file mode 100644 index 0000000000000000000000000000000000000000..e300061f0c0ea434847c719fb097edfc5e5caab0 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/er.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/er" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Er + class ErHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "er" + see_also = nil + syntax_formats = ["ER"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["er"], help_entries: ErHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(er)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Er::ErCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(ErHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/ew.rb b/lib/aethyr/core/input_handlers/emotes/ew.rb new file mode 100644 index 0000000000000000000000000000000000000000..01d86808766fe4c46ae94a30e9a789def6aaba51 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/ew.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/emotes/ew" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Ew + class EwHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "ew" + see_also = nil + syntax_formats = ["EW"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + return help_entries + end + + + def initialize(player) + super(player, ["ew"], help_entries: EwHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(ew)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Ew::EwCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(EwHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/frown.rb b/lib/aethyr/core/input_handlers/emotes/frown.rb new file mode 100644 index 0000000000000000000000000000000000000000..b13a68806f6f8a13266d801f986607ba424f9f2b --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/frown.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/frown" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Frown + class FrownHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "frown" + see_also = nil + syntax_formats = ["FROWN"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["frown"], help_entries: FrownHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(frown)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Frown::FrownCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(FrownHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/grin.rb b/lib/aethyr/core/input_handlers/emotes/grin.rb new file mode 100644 index 0000000000000000000000000000000000000000..eb75817c54e75eda75a6c8ae8cd19987c0b45c5b --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/grin.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/grin" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Grin + class GrinHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "grin" + see_also = nil + syntax_formats = ["GRIN"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["grin"], help_entries: GrinHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(grin)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Grin::GrinCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(GrinHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/hi.rb b/lib/aethyr/core/input_handlers/emotes/hi.rb new file mode 100644 index 0000000000000000000000000000000000000000..76c0433bc317e77cf13c5d3f0d6918d499b95e23 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/hi.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/hi" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Hi + class HiHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "hi" + see_also = nil + syntax_formats = ["HI"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["hi"], help_entries: HiHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(hi)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Hi::HiCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(HiHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/hm.rb b/lib/aethyr/core/input_handlers/emotes/hm.rb new file mode 100644 index 0000000000000000000000000000000000000000..87c508403beea4a11477d47bd1d498ee8927cfcb --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/hm.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/hm" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Hm + class HmHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "hm" + see_also = nil + syntax_formats = ["HM"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["hm"], help_entries: HmHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(hm)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Hm::HmCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(HmHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/hug.rb b/lib/aethyr/core/input_handlers/emotes/hug.rb new file mode 100644 index 0000000000000000000000000000000000000000..7e12df8aa63935b0c589fc0eefe30b50b96fca06 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/hug.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/hug" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Hug + class HugHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "hug" + see_also = nil + syntax_formats = ["HUG"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["hug"], help_entries: HugHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(hug)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Hug::HugCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(HugHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/huh.rb b/lib/aethyr/core/input_handlers/emotes/huh.rb new file mode 100644 index 0000000000000000000000000000000000000000..7a63aa49fc3e8f6df40e58a84f502959b50bdf86 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/huh.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/huh" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Huh + class HuhHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "huh" + see_also = nil + syntax_formats = ["HUH"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["huh"], help_entries: HuhHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(huh)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Huh::HuhCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(HuhHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/laugh.rb b/lib/aethyr/core/input_handlers/emotes/laugh.rb new file mode 100644 index 0000000000000000000000000000000000000000..6558c1ac54318e4dc89434600c3fae02dd3759d2 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/laugh.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/laugh" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Laugh + class LaughHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "laugh" + see_also = nil + syntax_formats = ["LAUGH"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["laugh"], help_entries: LaughHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(laugh)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Laugh::LaughCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(LaughHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/no.rb b/lib/aethyr/core/input_handlers/emotes/no.rb new file mode 100644 index 0000000000000000000000000000000000000000..ef4e7909fedec3abf1c11df9e8410ca5bd675baa --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/no.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/no" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module No + class NoHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "no" + see_also = nil + syntax_formats = ["NO"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["no"], help_entries: NoHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(no)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::No::NoCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(NoHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/nod.rb b/lib/aethyr/core/input_handlers/emotes/nod.rb new file mode 100644 index 0000000000000000000000000000000000000000..3afc61ee6bd32f9d4f887ed4290e32071c3ba183 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/nod.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/nod" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Nod + class NodHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "nod" + see_also = nil + syntax_formats = ["NOD"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["nod"], help_entries: NodHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(nod)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Nod::NodCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(NodHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/pet.rb b/lib/aethyr/core/input_handlers/emotes/pet.rb new file mode 100644 index 0000000000000000000000000000000000000000..073f3921ba475a57e83634901d688b8211a24ca2 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/pet.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/pet" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Pet + class PetHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "pet" + see_also = nil + syntax_formats = ["PET"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["pet"], help_entries: PetHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(pet)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Pet::PetCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(PetHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/poke.rb b/lib/aethyr/core/input_handlers/emotes/poke.rb new file mode 100644 index 0000000000000000000000000000000000000000..40f6b8c667bcf7589ad774249997282f4ad4a808 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/poke.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/poke" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Poke + class PokeHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "poke" + see_also = nil + syntax_formats = ["POKE"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["poke"], help_entries: PokeHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(poke)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Poke::PokeCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(PokeHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/ponder.rb b/lib/aethyr/core/input_handlers/emotes/ponder.rb new file mode 100644 index 0000000000000000000000000000000000000000..cf44b9b9c751eeb7a0b7401e991d4e1cae0f0347 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/ponder.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/ponder" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Ponder + class PonderHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "ponder" + see_also = nil + syntax_formats = ["PONDER"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["ponder"], help_entries: PonderHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(ponder)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Ponder::PonderCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(PonderHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/shrug.rb b/lib/aethyr/core/input_handlers/emotes/shrug.rb new file mode 100644 index 0000000000000000000000000000000000000000..27ac7f191e600741a3305298e6791812d24c69dc --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/shrug.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/shrug" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Shrug + class ShrugHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "shrug" + see_also = nil + syntax_formats = ["SHRUG"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["shrug"], help_entries: ShrugHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(shrug)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Shrug::ShrugCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(ShrugHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/sigh.rb b/lib/aethyr/core/input_handlers/emotes/sigh.rb new file mode 100644 index 0000000000000000000000000000000000000000..d59d68916fb43765a14a2b574dfb7740a721ca1f --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/sigh.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/sigh" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Sigh + class SighHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "sigh" + see_also = nil + syntax_formats = ["SIGH"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["sigh"], help_entries: SighHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(sigh)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Sigh::SighCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(SighHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/skip.rb b/lib/aethyr/core/input_handlers/emotes/skip.rb new file mode 100644 index 0000000000000000000000000000000000000000..8ddaf2d1c18f1a56e571d6f3445ae0c76382ef98 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/skip.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/skip" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Skip + class SkipHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "skip" + see_also = nil + syntax_formats = ["SKIP"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["skip"], help_entries: SkipHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(skip)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Skip::SkipCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(SkipHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/smile.rb b/lib/aethyr/core/input_handlers/emotes/smile.rb new file mode 100644 index 0000000000000000000000000000000000000000..f8330636945713b7c8e669d23b95c15629435193 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/smile.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/smile" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Smile + class SmileHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "smile" + see_also = nil + syntax_formats = ["SMILE"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["smile"], help_entries: SmileHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(smile)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Smile::SmileCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(SmileHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/snicker.rb b/lib/aethyr/core/input_handlers/emotes/snicker.rb new file mode 100644 index 0000000000000000000000000000000000000000..773aeae5e47b1d05317605928ef135244decec79 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/snicker.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/snicker" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Snicker + class SnickerHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "snicker" + see_also = nil + syntax_formats = ["SNICKER"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["snicker"], help_entries: SnickerHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(snicker)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Snicker::SnickerCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(SnickerHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/uh.rb b/lib/aethyr/core/input_handlers/emotes/uh.rb new file mode 100644 index 0000000000000000000000000000000000000000..67e9651c9abb4c4eea6bd3570618cfb603c9d002 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/uh.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/uh" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Uh + class UhHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "uh" + see_also = nil + syntax_formats = ["UH"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["uh"], help_entries: UhHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(uh)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Uh::UhCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(UhHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/wave.rb b/lib/aethyr/core/input_handlers/emotes/wave.rb new file mode 100644 index 0000000000000000000000000000000000000000..d6e62083f9cbf6a3583e84bc01ad71eefd46d1d7 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/wave.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/wave" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Wave + class WaveHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "wave" + see_also = nil + syntax_formats = ["WAVE"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["wave"], help_entries: WaveHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(wave)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Wave::WaveCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(WaveHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/yawn.rb b/lib/aethyr/core/input_handlers/emotes/yawn.rb new file mode 100644 index 0000000000000000000000000000000000000000..937e4816e4ed46106b87003d12aace75a38acc7e --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/yawn.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/yawn" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Yawn + class YawnHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "yawn" + see_also = nil + syntax_formats = ["YAWN"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["yawn"], help_entries: YawnHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(yawn)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Yawn::YawnCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(YawnHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/emotes/yes.rb b/lib/aethyr/core/input_handlers/emotes/yes.rb new file mode 100644 index 0000000000000000000000000000000000000000..cbc4fd458f597b9398f3513aea1b0e02596f3612 --- /dev/null +++ b/lib/aethyr/core/input_handlers/emotes/yes.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/emotes/yes" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/emotes/emote_handler" + +module Aethyr + module Core + module Commands + module Yes + class YesHandler < Aethyr::Extend::EmoteHandler + + def self.create_help_entries + help_entries = [] + + command = "yes" + see_also = nil + syntax_formats = ["YES"] + aliases = nil + content = <<'EOF' +Please see help for emote instead. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["yes"], help_entries: YesHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(yes)( +([^()]*))?( +((.*)))?$/i + object = $3 + post = $5 + $manager.submit_action(Aethyr::Core::Actions::Yes::YesCommand.new(@player, {:object => object, :post => post})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(YesHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/gait.rb b/lib/aethyr/core/input_handlers/gait.rb new file mode 100644 index 0000000000000000000000000000000000000000..76ba34801d4e753706f872299c15bd4443a8cefb --- /dev/null +++ b/lib/aethyr/core/input_handlers/gait.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/gait" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Gait + class GaitHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "gait" + see_also = nil + syntax_formats = ["GAIT"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["gait"], help_entries: GaitHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^gait(\s+(.*))?$/i + phrase = $2 if $2 + $manager.submit_action(Aethyr::Core::Actions::Gait::GaitCommand.new(@player, {:phrase => phrase})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(GaitHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/generic.rb b/lib/aethyr/core/input_handlers/generic.rb new file mode 100644 index 0000000000000000000000000000000000000000..8c766919d94cb7708716ad8eb098f747f7c34d9e --- /dev/null +++ b/lib/aethyr/core/input_handlers/generic.rb @@ -0,0 +1,268 @@ +require "aethyr/core/actions/commands/feel" +require "aethyr/core/actions/commands/listen" +require "aethyr/core/actions/commands/smell" +require "aethyr/core/actions/commands/taste" +require "aethyr/core/actions/commands/write" +require "aethyr/core/actions/commands/deleteme" +require "aethyr/core/actions/commands/who" +require "aethyr/core/actions/commands/date" +require "aethyr/core/actions/commands/time" +require "aethyr/core/actions/commands/fill" +require "aethyr/core/actions/commands/status" +require "aethyr/core/actions/commands/satiety" +require "aethyr/core/actions/commands/health" +require 'aethyr/core/issues' +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Generic + class GenericHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "health" + see_also = ["STATUS", "HUNGER"] + syntax_formats = ["HEALTH"] + aliases = nil + content = <<'EOF' +Shows you how healthy you are. + +You can be: + at full health + a bit bruised + a little beat up + slightly injured + quite injured + slightly wounded + wounded in several places + heavily wounded + bleeding profusely and in serious pain + nearly dead + dead + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "satiety" + see_also = ["STAT", "HEALTH"] + syntax_formats = ["HUNGER", "SATIETY"] + aliases = nil + content = <<'EOF' +Shows you how hungry you are. + +You can be: + completely stuffed + full and happy + full and happy + satisfied + not hungry + slightly hungry + slightly hungry + peckish + hungry + very hungry + famished + starving + literally dying of hunger + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "status" + see_also = ["INVENTORY", "HUNGER", "HEALTH"] + syntax_formats = ["STATUS", "STAT", "ST"] + aliases = nil + content = <<'EOF' +Shows your current health, hunger/satiety, and position. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "fill" + see_also = nil + syntax_formats = ["FILL [container] FROM [source]"] + aliases = nil + content = <<'EOF' +Fill a container from a source + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "date_time" + see_also = nil + syntax_formats = ["DATE"] + aliases = nil + content = <<'EOF' +Date and Time + + TIME + +Shows the current date and time in Aethyr. Not completely done yet, but it is a first step. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "who" + see_also = nil + syntax_formats = ["WHO"] + aliases = nil + content = <<'EOF' +This will list everyone else who is currently in Aethyr and where they happen to be at the moment. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "deleteme" + see_also = nil + syntax_formats = ["DELETE ME PLEASE"] + aliases = nil + content = <<'EOF' +Deleting Your Character + +In case you ever need to do so, you can remove your character from the game. Quite permanently. You will need to enter your password as confirmation and that's it. You will be wiped out of time and memory. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "write" + see_also = nil + syntax_formats = ["WRITE [target]"] + aliases = nil + content = <<'EOF' +Write something on the specified target. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "taste" + see_also = nil + syntax_formats = ["TASTE [target]"] + aliases = nil + content = <<'EOF' +Taste the specified target. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "smell" + see_also = nil + syntax_formats = ["SMELL [target]"] + aliases = nil + content = <<'EOF' +Smell the specified target. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "listen" + see_also = nil + syntax_formats = ["LISTEN [target]"] + aliases = nil + content = <<'EOF' +Listen to the specified target. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "feel" + see_also = nil + syntax_formats = ["FEEL [target]"] + aliases = nil + content = <<'EOF' +Feel the specified target. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ['date', 'delete', 'feel', 'taste', 'smell', 'sniff', 'lick', 'listen', 'health', 'hunger', 'satiety', 'shut', 'status', 'stat', 'st', 'time', 'typo', 'who', 'write'], help_entries: GenericHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^delete me please$/i + $manager.submit_action(Aethyr::Core::Actions::Deleteme::DeletemeCommand.new(@player, {})) + when /^(health)$/i + $manager.submit_action(Aethyr::Core::Actions::Health::HealthCommand.new(@player, {})) + when /^(satiety|hunger)$/i + $manager.submit_action(Aethyr::Core::Actions::Satiety::SatietyCommand.new(@player, {})) + when /^(st|stat|status)$/i + $manager.submit_action(Aethyr::Core::Actions::Status::StatusCommand.new(@player, {})) + when /^write\s+(.*)/i + $manager.submit_action(Aethyr::Core::Actions::Write::WriteCommand.new(@player, { :target => $1.strip})) + when /^(listen)(\s+(.+))?$/i + $manager.submit_action(Aethyr::Core::Actions::Listen::ListenCommand.new(@player, { :target => $3})) + when /^(smell|sniff)(\s+(.+))?$/i + $manager.submit_action(Aethyr::Core::Actions::Smell::SmellCommand.new(@player, { :target => $3})) + when /^(taste|lick)(\s+(.+))?$/i + $manager.submit_action(Aethyr::Core::Actions::Taste::TasteCommand.new(@player, { :target => $3})) + when /^(feel)(\s+(.+))?$/i + $manager.submit_action(Aethyr::Core::Actions::Feel::FeelCommand.new(@player, { :target => $3})) + when /^fill\s+(\w+)\s+from\s+(\w+)$/i + $manager.submit_action(Aethyr::Core::Actions::Fill::FillCommand.new(@player, { :object => $1, :from => $2})) + when /^who$/i + $manager.submit_action(Aethyr::Core::Actions::Who::WhoCommand.new(@player, {})) + when /^time$/i + $manager.submit_action(Aethyr::Core::Actions::Time::TimeCommand.new(@player, {})) + when /^date$/i + $manager.submit_action(Aethyr::Core::Actions::Date::DateCommand.new(@player, {})) + end + end + + private + #Display health. + + + + + + + + + + + + + + end + + Aethyr::Extend::HandlerRegistry.register_handler(GenericHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/get.rb b/lib/aethyr/core/input_handlers/get.rb new file mode 100644 index 0000000000000000000000000000000000000000..27bea9f44b5368dd39633442f270dc84b07b2ff1 --- /dev/null +++ b/lib/aethyr/core/input_handlers/get.rb @@ -0,0 +1,56 @@ +require "aethyr/core/actions/commands/get" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Get + class GetHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "get" + see_also = ["GIVE"] + syntax_formats = ["GET [object]", "GRAB [object]", "TAKE [object]"] + aliases = ["grab", "take"] + content = <<'EOF' +Pick up an object and put it in your inventory. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["get", "grab", "take"], help_entries: GetHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(get|grab|take)\s+((\w+|\s)*)(\s+from\s+(\w+))/i + $manager.submit_action(Aethyr::Core::Actions::Get::GetCommand.new(@player, { :object => $2.strip, :from => $5 })) + when /^(get|grab|take)\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Get::GetCommand.new(@player, { :object => $2.strip })) + end + end + + private + + #Gets (or takes) an object and puts it in the player's inventory. + + end + + Aethyr::Extend::HandlerRegistry.register_handler(GetHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/give.rb b/lib/aethyr/core/input_handlers/give.rb new file mode 100644 index 0000000000000000000000000000000000000000..e1c964a97550db1b90145f1a3d3f13fb819b0915 --- /dev/null +++ b/lib/aethyr/core/input_handlers/give.rb @@ -0,0 +1,56 @@ +require "aethyr/core/actions/commands/give" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Give + class GiveHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "give" + see_also = ["GET"] + syntax_formats = ["GIVE [object] TO [person]"] + aliases = nil + content = <<'EOF' +Give an object to someone else. Beware, though, they may not want to give it back. + +At the moment, the object must be in your inventory. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["give"], help_entries: GiveHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^give\s+((\w+\s*)*)\s+to\s+(\w+)/i + $manager.submit_action(Aethyr::Core::Actions::Give::GiveCommand.new(@player, { :item => $2.strip, :to => $3 })) + end + end + + private + + #Gives an item to someone else. + + end + + Aethyr::Extend::HandlerRegistry.register_handler(GiveHandler) + end + end + end +end \ No newline at end of file diff --git a/lib/aethyr/core/input_handlers/help.rb b/lib/aethyr/core/input_handlers/help.rb new file mode 100644 index 0000000000000000000000000000000000000000..36672c40aaf5cc19911e39a59de1be700fed63f0 --- /dev/null +++ b/lib/aethyr/core/input_handlers/help.rb @@ -0,0 +1,32 @@ +require 'aethyr/core/registry' +require 'aethyr/core/input_handlers/command_handler' + +module Aethyr + module Core + module Commands + module Help + class HelpHandler < Aethyr::Extend::CommandHandler + def self.object_added(data) + super(data, self) + end + + def initialize(player) + super(player, ["help"]) + end + + def player_input(data) + super(data) + case data[:input] + when /^(help)$/i + self.player.output("Help topics available: " + self.player.help_library.topics.join(", ") + "\n", false) + when /^help (.*)$/i + self.player.output(self.player.help_library.render_topic($1), false) + end + end + end + + Aethyr::Extend::HandlerRegistry.register_handler(HelpHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/help_handler.rb b/lib/aethyr/core/input_handlers/help_handler.rb new file mode 100644 index 0000000000000000000000000000000000000000..6ed8fbff71c0755bee44ab18c987479a38c91f85 --- /dev/null +++ b/lib/aethyr/core/input_handlers/help_handler.rb @@ -0,0 +1,31 @@ +require "aethyr/core/registry" + +module Aethyr + module Extend + module HandleHelp + attr_reader :commands + + def initialize(player, commands, *args, help_entries: [], **kwargs) + super(player, *args, **kwargs) + + @commands = commands + + help_entries.each do |entry| + player.help_library.entry_register entry + end + end + + def can_help? + true + end + end + + class HelpEntryHandler + include Aethyr::Extend::HandleHelp + + def initialize(player, commands, *args, help_entries: [], **kwargs) + super + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/inventory.rb b/lib/aethyr/core/input_handlers/inventory.rb new file mode 100644 index 0000000000000000000000000000000000000000..739379e295466c20c5afe8e3a8e7368d4cb94ef3 --- /dev/null +++ b/lib/aethyr/core/input_handlers/inventory.rb @@ -0,0 +1,56 @@ +require "aethyr/core/actions/commands/inventory" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Inventory + class InventoryHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "inventory" + see_also = ["TAKE", "DROP", "WEAR", "REMOVE"] + syntax_formats = ["INVENTORY"] + aliases = ["i", "inv"] + content = <<'EOF' +Displays what you are holding and wearing. + +'i' and 'inv' are shortcuts for inventory. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["i", "inv", "inventory"], help_entries: InventoryHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(i|inv|inventory)$/i + $manager.submit_action(Aethyr::Core::Actions::Inventory::InventoryCommand.new(@player, {})) + end + end + + private + + #Shows the inventory of the player. + + end + + Aethyr::Extend::HandlerRegistry.register_handler(InventoryHandler) + end + end + end +end \ No newline at end of file diff --git a/lib/aethyr/core/input_handlers/issue.rb b/lib/aethyr/core/input_handlers/issue.rb new file mode 100644 index 0000000000000000000000000000000000000000..c3290652a8a5a5dcc4d4d927c12b5759b2e72646 --- /dev/null +++ b/lib/aethyr/core/input_handlers/issue.rb @@ -0,0 +1,72 @@ +require "aethyr/core/actions/commands/issue" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Issue + class IssueHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "issue" + see_also = nil + syntax_formats = ["[BUG|IDEA|TYPO] [issue]", "[BUG|IDEA|TYPO] [id number]", "[BUG|IDEA|TYPO] LIST", "[BUG|IDEA|TYPO] STATUS [id_number] [status]", "[BUG|IDEA|TYPO] [SHOW|ADD|DEL] [id_number]"] + aliases = ["bug", "typo", "idea"] + content = <<'EOF' +These commands allow players and administrators to report and manipulate feedback about the game. The commands are essentially identical, but should be used to report different things. For the rest of this description, BUG is used. + +Note that players can only see and edit their own feedback, while adminsitrators will see them all. + +BUG [issue] is used to make the initial report. +BUG LIST will list all reports. +BUG ADD can be used to append comments to a report. +BUG STATUS can be used to change the status of a report to a different value (administrators only). + +Examples: +bug When I hit a dwarf with my axe, it doesn't do any damage. +bug list +bug 1 +bug add 1 Actually, this only happens with battleaxes, not all axes. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["bug", "typo", "idea"], help_entries: IssueHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(bug|typo|idea)\s+(\d+)\s+(show|del|add|status)(\s+(.+))?$/i + $manager.submit_action(Aethyr::Core::Actions::Issue::IssueCommand.new(@player, { :itype => $1.downcase.to_sym, :issue_id => $2, :option => $3.downcase, :value => $5 })) + when /^(bug|typo|idea)\s+(\d+)/i + $manager.submit_action(Aethyr::Core::Actions::Issue::IssueCommand.new(@player, { :itype => $1.downcase.to_sym, :option => "show", :issue_id => $2 })) + when /^(bug|typo|idea)\s+(del|add|show|status)\s+(\d+)(\s+(.+))?/i + $manager.submit_action(Aethyr::Core::Actions::Issue::IssueCommand.new(@player, { :itype => $1.downcase.to_sym, :option => $2.downcase, :issue_id => $3, :value => $5 })) + when /^(bug|typo|idea)\s+(new|show|del|add|status|list)(\s+(.+))?$/i + $manager.submit_action(Aethyr::Core::Actions::Issue::IssueCommand.new(@player, { :itype => $1.downcase.to_sym, :option => $2.downcase, :value => $4 })) + when /^(bug|typo|idea)\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Issue::IssueCommand.new(@player, { :itype => $1.downcase.to_sym, :option => "new", :value => $2 })) + end + end + + private + + end + + Aethyr::Extend::HandlerRegistry.register_handler(IssueHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/kick.rb b/lib/aethyr/core/input_handlers/kick.rb new file mode 100644 index 0000000000000000000000000000000000000000..8efb03c9c5c125cef219d77d014106a70e515f9a --- /dev/null +++ b/lib/aethyr/core/input_handlers/kick.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/kick" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Kick + class KickHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "kick" + see_also = nil + syntax_formats = ["KICK"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["kick"], help_entries: KickHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^kick$/i + $manager.submit_action(Aethyr::Core::Actions::Kick::KickCommand.new(@player, {})) + when /^kick\s+(.*)$/i + target = $1 + $manager.submit_action(Aethyr::Core::Actions::Kick::KickCommand.new(@player, {:target => target})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(KickHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/locking.rb b/lib/aethyr/core/input_handlers/locking.rb new file mode 100644 index 0000000000000000000000000000000000000000..0f2a992ebcc87240a846dca0d9983075aad36577 --- /dev/null +++ b/lib/aethyr/core/input_handlers/locking.rb @@ -0,0 +1,58 @@ +require "aethyr/core/actions/commands/unlock" +require "aethyr/core/actions/commands/lock" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Locking + class LockingHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "locking" + see_also = ["OPEN", "CLOSE"] + syntax_formats = ["LOCK [object or direction]", "UNLOCK [object or direction]"] + aliases = ["lock", "unlock"] + content = <<'EOF' +Lock or unlock the given object, if you have a key for it. + +Note that you can lock a door while it is open, then close it. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["lock", "unlock"], help_entries: LockingHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^lock\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Lock::LockCommand.new(@player, { :object => $1 })) + when /^unlock\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Unlock::UnlockCommand.new(@player, { :object => $1 })) + end + end + + private + + + end + + Aethyr::Extend::HandlerRegistry.register_handler(LockingHandler) + end + end + end +end \ No newline at end of file diff --git a/lib/aethyr/core/input_handlers/look.rb b/lib/aethyr/core/input_handlers/look.rb new file mode 100644 index 0000000000000000000000000000000000000000..d6bc9db5a048440c7d582d6c934ffc39809f7c1d --- /dev/null +++ b/lib/aethyr/core/input_handlers/look.rb @@ -0,0 +1,57 @@ +require "aethyr/core/actions/commands/look" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Look + class LookHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "look" + see_also = nil + syntax_formats = ["LOOK", "LOOK [object]", "LOOK IN [object]"] + aliases = ["l"] + content = <<'EOF' +Look by itself will show you your surroundings. + +Look followed by an object will look at that object. + +Look IN will look inside of a container (if it is open). + +'l' is a shortcut for look. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["l", "look"], help_entries: LookHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(l|look)$/i + $manager.submit_action(Aethyr::Core::Actions::Look::LookCommand.new(@player, {})) + when /^(l|look)\s+(in|inside)\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Look::LookCommand.new(@player, { :in => $3 })) + when /^(l|look)\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Look::LookCommand.new(@player, { :at => $2 })) + end + end + end + Aethyr::Extend::HandlerRegistry.register_handler(LookHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/map.rb b/lib/aethyr/core/input_handlers/map.rb new file mode 100644 index 0000000000000000000000000000000000000000..daf9d5431b930559832250023eaf22ac6fbd4c8c --- /dev/null +++ b/lib/aethyr/core/input_handlers/map.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/map" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Map + class MapHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "map" + see_also = nil + syntax_formats = ["MAP"] + aliases = ["m"] + content = <<'EOF' +Displays a map of the area. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["m", "map"], help_entries: MapHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^(m|map)$/i + $manager.submit_action(Aethyr::Core::Actions::Map::MapCommand.new(@player, {})) + end + end + + private + + end + + Aethyr::Extend::HandlerRegistry.register_handler(MapHandler) + end + end + end +end diff --git a/lib/aethyr/core/commands/more.rb b/lib/aethyr/core/input_handlers/more.rb similarity index 50% rename from lib/aethyr/core/commands/more.rb rename to lib/aethyr/core/input_handlers/more.rb index 97ffa7e8b8d4e4e9fbefda9eda33d4d10dda12ac..73bec9ebda6e99a3a8081cb1518d6abe695bd33c 100644 --- a/lib/aethyr/core/commands/more.rb +++ b/lib/aethyr/core/input_handlers/more.rb @@ -1,47 +1,50 @@ +require "aethyr/core/actions/commands/more" require "aethyr/core/registry" -require "aethyr/core/commands/command_handler" +require "aethyr/core/input_handlers/command_handler" module Aethyr module Core module Commands module More class MoreHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "more" + see_also = ["PAGELENGTH"] + syntax_formats = ["MORE"] + aliases = nil + content = <<'EOF' +When the output from the last command was too long to display you can issue this +command to see the next page. If there are multiple pages then this command can +be used multiple times. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + def initialize(player) - super(player, ["more"]) + super(player, ["more"], help_entries: MoreHandler.create_help_entries) end def self.object_added(data) - return unless data[:game_object].is_a? Player - data[:game_object].subscribe(MoreHandler.new(data[:game_object])) + super(data, self) end def player_input(data) super(data) case data[:input] when /^more/i - action({}) - when /^help more/i - action_help({}) + $manager.submit_action(Aethyr::Core::Actions::More::MoreCommand.new(@player, {})) end end private - def action(event) - player.more - end - - def action_help(event) - player.output <<'EOF' -Command: More -Syntax: MORE -When the output from the last command was too long to display you can issue this -command to see the next page. If there are multiple pages then this command can -be used multiple times. - -See also: PAGELENGTH -EOF - end end Aethyr::Extend::HandlerRegistry.register_handler(MoreHandler) diff --git a/lib/aethyr/core/input_handlers/move.rb b/lib/aethyr/core/input_handlers/move.rb new file mode 100644 index 0000000000000000000000000000000000000000..bcf66dd2cc2cdd75302c527398fb5bef97af95f9 --- /dev/null +++ b/lib/aethyr/core/input_handlers/move.rb @@ -0,0 +1,64 @@ +require "aethyr/core/actions/commands/move" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" +require "aethyr/core/util/direction" + +module Aethyr + module Core + module Commands + module Move + class MoveHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "move" + see_also = nil + syntax_formats = ["GO [direction or exit]"] + aliases = ["go", "east", "west", "northeast", "northwest", "north", "southeast", "southwest", "south", "e", "w", "nw", "ne", "sw", "se", "n", "s", "up", "down", "u", "d", "in", "out"] + content = <<'EOF' +Move in a particular direction or through a particular exit. + +Example: + +GO EAST + +Note that you can just use EAST, WEST, IN, OUT, UP, DOWN, etc. instead of GO. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + + include Aethyr::Direction + + def initialize(player) + super(player, ["go", "move", "east", "west", "northeast", "northwest", "north", "southeast", "southwest", "south", "e", "w", "nw", "ne", "sw", "se", "n", "s", "up", "down", "u", "d", "in", "out"], help_entries: MoveHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^go\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Move::MoveCommand.new(@player, {:direction => $1.downcase})) + when /^(east|west|northeast|northwest|north|southeast|southwest|south|e|w|nw|ne|sw|se|n|s|up|down|u|d|in|out)(\s+\((.*)\))?$/i + $manager.submit_action(Aethyr::Core::Actions::Move::MoveCommand.new(@player, {:direction => expand_direction($1), :pre => $3})) + end + end + + private + + end + + Aethyr::Extend::HandlerRegistry.register_handler(MoveHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/news.rb b/lib/aethyr/core/input_handlers/news.rb new file mode 100644 index 0000000000000000000000000000000000000000..e350a14be2d6b309aa3cb7c8d812333f6694b032 --- /dev/null +++ b/lib/aethyr/core/input_handlers/news.rb @@ -0,0 +1,105 @@ +require "aethyr/core/actions/commands/all" +require "aethyr/core/actions/commands/delete_post" +require "aethyr/core/actions/commands/list_unread" +require "aethyr/core/actions/commands/write_post" +require "aethyr/core/actions/commands/read_post" +require "aethyr/core/actions/commands/latest_news" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module News + class NewsHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "news" + see_also = nil + syntax_formats = ["NEWS"] + aliases = nil + content = <<'EOF' +NEWS + +Scattered throughout Aethyr are objects on which one can post notes or read notes left by others. The appearance of these objects may vary from ledgers to large bulletin boards, but they all work the same way. + +The news system is currently still being tinkered on, but here is what works currently: + +-Reading posts + +Lists the latest news. How many posts it lists is dependent on your pagelength. + +Specify how many of the latest posts to show. + +Lists all the news postings. Might be really long. + +Shows the specified post. + +-Writing posts + +First enter a subject for your post, then you will be taken to the editor to write the body of the post. If you decide not to write the post after all, then simply exit the editor without saving. + +Write a reply to an existing post. + +-Deleting posts + +For testing purposes only, you may delete your own posts. This is so you don't feel guilty about posting a bunch of nonsense to try things out. + +Note that this command isn't really well-supported, so it may cause some odd things to happen if there are replies to deleted posts. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["news"], help_entries: NewsHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when "news" + $manager.submit_action(Aethyr::Core::Actions::LatestNews::LatestNewsCommand.new(@player, {})) + when /^news\s+(read\s+)?(\d+)$/i + post_id = $2 + $manager.submit_action(Aethyr::Core::Actions::ReadPost::ReadPostCommand.new(@player, {:post_id => post_id})) + when /^news\s+reply(\s+to\s+)?\s+(\d+)$/i + reply_to = $2 + $manager.submit_action(Aethyr::Core::Actions::WritePost::WritePostCommand.new(@player, {:reply_to => reply_to})) + when /^news\s+unread/i + $manager.submit_action(Aethyr::Core::Actions::ListUnread::ListUnreadCommand.new(@player, {})) + when /^news\s+last\s+(\d+)/i + limit = $1.to_i + $manager.submit_action(Aethyr::Core::Actions::LatestNews::LatestNewsCommand.new(@player, {:limit => limit})) + when /^news\s+delete\s+(\d+)/i + post_id = $1 + $manager.submit_action(Aethyr::Core::Actions::DeletePost::DeletePostCommand.new(@player, {:post_id => post_id})) + when /^news\s+write$/i + $manager.submit_action(Aethyr::Core::Actions::WritePost::WritePostCommand.new(@player, {})) + when /^news\s+all/i + $manager.submit_action(Aethyr::Core::Actions::All::AllCommand.new(@player, {})) + end + end + + private + + + + + + + end + Aethyr::Extend::HandlerRegistry.register_handler(NewsHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/open.rb b/lib/aethyr/core/input_handlers/open.rb new file mode 100644 index 0000000000000000000000000000000000000000..db71a41cafcf713874268941024fce285e9f4ca5 --- /dev/null +++ b/lib/aethyr/core/input_handlers/open.rb @@ -0,0 +1,61 @@ +require "aethyr/core/actions/commands/open" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" +require "aethyr/core/util/direction" + +module Aethyr + module Core + module Commands + module Open + class OpenHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "open" + see_also = ["LOCK", "UNLOCK", "CLOSE"] + syntax_formats = ["OPEN [object or direction]"] + aliases = nil + content = <<'EOF' +Opens the object. For doors and such, it is more accurate to use the direction in which the object lies. + +For example: + +OPEN north + +OPEN door + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + include Aethyr::Direction + + def initialize(player) + super(player, ["open"], help_entries: OpenHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^open\s+(\w+)$/i + $manager.submit_action(Aethyr::Core::Actions::Open::OpenCommand.new(@player, { :object => $1 })) + end + end + + private + + end + + Aethyr::Extend::HandlerRegistry.register_handler(OpenHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/portal.rb b/lib/aethyr/core/input_handlers/portal.rb new file mode 100644 index 0000000000000000000000000000000000000000..a935b9aeca42e96d2e4efa3e48b0509cf8111644 --- /dev/null +++ b/lib/aethyr/core/input_handlers/portal.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/portal" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Portal + class PortalHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "portal" + see_also = nil + syntax_formats = ["PORTAL [OBJECT] (ACTION|EXIT|ENTRANCE|PORTAL) [VALUE]"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["portal"], help_entries: PortalHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^portal\s+(.*?)\s+(action|exit|entrance|portal)\s+(.*)$/i + object = $1 + setting = $2.downcase + value = $3.strip + $manager.submit_action(Aethyr::Core::Actions::Portal::PortalCommand.new(@player, {:object => object, :setting => setting, :value => value})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(PortalHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/pose.rb b/lib/aethyr/core/input_handlers/pose.rb new file mode 100644 index 0000000000000000000000000000000000000000..de0e113d2c072b0cacf3f1d4dab0e1821cf11cea --- /dev/null +++ b/lib/aethyr/core/input_handlers/pose.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/pose" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Pose + class PoseHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "pose" + see_also = nil + syntax_formats = ["POSE"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["pose"], help_entries: PoseHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^pose\s+(.*)$/i + pose = $1.strip + $manager.submit_action(Aethyr::Core::Actions::Pose::PoseCommand.new(@player, {:pose => pose})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(PoseHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/punch.rb b/lib/aethyr/core/input_handlers/punch.rb new file mode 100644 index 0000000000000000000000000000000000000000..b9f4d99acd3f1ded701e416e2f0d25af98f410e6 --- /dev/null +++ b/lib/aethyr/core/input_handlers/punch.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/punch" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Punch + class PunchHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "punch" + see_also = nil + syntax_formats = ["PUNCH"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["punch"], help_entries: PunchHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^punch$/i + $manager.submit_action(Aethyr::Core::Actions::Punch::PunchCommand.new(@player, {})) + when /^punch\s+(.*)$/i + target = $1 + $manager.submit_action(Aethyr::Core::Actions::Punch::PunchCommand.new(@player, {:target => target})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(PunchHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/put.rb b/lib/aethyr/core/input_handlers/put.rb new file mode 100644 index 0000000000000000000000000000000000000000..f58fb04759d253204d295a0d147ae94f4db27445 --- /dev/null +++ b/lib/aethyr/core/input_handlers/put.rb @@ -0,0 +1,52 @@ +require "aethyr/core/actions/commands/put" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Put + class PutHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "put" + see_also = ["LOOK", "TAKE", "OPEN"] + syntax_formats = ["PUT [object] IN [container]"] + aliases = nil + content = <<'EOF' +Puts an object in a container. The container must be open to do so. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["put"], help_entries: PutHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^put((\s+(\d+)\s+)|\s+)(\w+)\s+in\s+(\w+)$/i + $manager.submit_action(Aethyr::Core::Actions::Put::PutCommand.new(@player, { :item => $4, :count => $3.to_i, :container => $5 })) + end + end + + private + + end + + Aethyr::Extend::HandlerRegistry.register_handler(PutHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/quit.rb b/lib/aethyr/core/input_handlers/quit.rb new file mode 100644 index 0000000000000000000000000000000000000000..cf2e25f6dbfff35f51b71594292faf1b63a9bba2 --- /dev/null +++ b/lib/aethyr/core/input_handlers/quit.rb @@ -0,0 +1,54 @@ +require "aethyr/core/actions/commands/quit" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Quit + class QuitHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "quit" + see_also = nil + syntax_formats = ["QUIT"] + aliases = nil + content = <<'EOF' +Saves your character and logs you off from the game. + +You shouldn't need this too often. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["quit"], help_entries: QuitHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + case data[:input] + when /^quit$/i + $manager.submit_action(Aethyr::Core::Actions::Quit::QuitCommand.new(@player, {})) + end + end + + private + + + end + + Aethyr::Extend::HandlerRegistry.register_handler(QuitHandler) + end + end + end +end \ No newline at end of file diff --git a/lib/aethyr/core/input_handlers/remove.rb b/lib/aethyr/core/input_handlers/remove.rb new file mode 100644 index 0000000000000000000000000000000000000000..3a65d45e8daae3de3cbccf2598ef46ac5fbc82c7 --- /dev/null +++ b/lib/aethyr/core/input_handlers/remove.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/remove" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Remove + class RemoveHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "remove" + see_also = ["WEAR", "INVENTORY"] + syntax_formats = ["REMOVE <object>"] + aliases = nil + content = <<'EOF' +Remove an article of clothing or armor. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["remove"], help_entries: RemoveHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^remove\s+(\w+)(\s+from\s+(.*))?$/i + object = $1 + position = $3 + $manager.submit_action(Aethyr::Core::Actions::Remove::RemoveCommand.new(@player, {:object => object, :position => position})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(RemoveHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/say.rb b/lib/aethyr/core/input_handlers/say.rb new file mode 100644 index 0000000000000000000000000000000000000000..e65ba73154c880edda3ba103b5078721252bd581 --- /dev/null +++ b/lib/aethyr/core/input_handlers/say.rb @@ -0,0 +1,90 @@ +require "aethyr/core/actions/commands/say" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Say + class SayHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "say" + see_also = ["WHISPER", "SAYTO"] + syntax_formats = ["SAY [message]"] + aliases = nil + content = <<'EOF' +This is the basic command for communication. Everyone in the room hears what you say. +Some formatting is automatic, and a few emoticons are supported at the end of the command. + +Example: say i like cheese +Output: You say, "I like cheese." + +Example: say i like cheese! :) +Output: You smile and exclaim, "I like cheese!" + +You can also specify a prefix in parentheses after the say command. + +Example: say (in trepidation) are you going to take my cheese? +Output: In trepidation, you ask, "Are you going to take my cheese?" + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "sayto" + see_also = ["WHISPER", "SAY"] + syntax_formats = ["SAYTO [name] [message]"] + aliases = nil + content = <<'EOF' +Say something to someone in particular, who is in the same room: + +Example: + +sayto bob i like cheese + +Output: + +You say to Bob, "I like cheese." + +Also supports the same variations as the SAY command. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["say", "sayto"], help_entries: SayHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^say\s+(\((.*?)\)\s*)?(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Say::SayCommand.new(@player, { :phrase => $3, :pre => $2 })) + when /^sayto\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Say::SayCommand.new(@player, {:target => $1, :phrase => $4, :pre => $3 })) + end + end + + private + + #Says something to the room or to a specific player. + + end + + Aethyr::Extend::HandlerRegistry.register_handler(SayHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/set.rb b/lib/aethyr/core/input_handlers/set.rb new file mode 100644 index 0000000000000000000000000000000000000000..f4d125a18a644a4a80533de7c257e0004b3abb47 --- /dev/null +++ b/lib/aethyr/core/input_handlers/set.rb @@ -0,0 +1,81 @@ +require "aethyr/core/actions/commands/setpassword" +require "aethyr/core/actions/commands/set" +require "aethyr/core/actions/commands/showcolors" +require "aethyr/core/actions/commands/setcolor" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Set + class SetHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "set" + see_also = ["WORDWRAP", "PAGELENGTH", "DESCRIPTION", "COLORS"] + syntax_formats = ["SET <option> [value]"] + aliases = nil + content = <<'EOF' +There are several settings available to you. To see them all, simply use SET. +To see the values available for a certain setting, use SET <option> without a value. + +Example: + +To see your color settings, use + +SET COLOR + +To turn off word wrap, use + +SET WORDWRAP OFF + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["set"], help_entries: SetHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^set\s+colors?\s+(on|off|default)$/i + option = $1 + $manager.submit_action(Aethyr::Core::Actions::Setcolor::SetcolorCommand.new(@player, {:option => option})) + when /^set\s+colors?.*/i + $manager.submit_action(Aethyr::Core::Actions::Showcolors::ShowcolorsCommand.new(@player, {})) + when /^set\s+(\w+)\s*(.*)$/i + setting = $1.strip + value = $2.strip if $2 + $manager.submit_action(Aethyr::Core::Actions::Set::SetCommand.new(@player, {:setting => setting, :value => value})) + when /^set\s+colors?\s+(\w+)\s+(.+)$/i + option = $1 + color = $2 + $manager.submit_action(Aethyr::Core::Actions::Setcolor::SetcolorCommand.new(@player, {:option => option, :color => color})) + when /^set\s+password$/i + $manager.submit_action(Aethyr::Core::Actions::Setpassword::SetpasswordCommand.new(@player, {})) + end + end + + private + + + + + end + Aethyr::Extend::HandlerRegistry.register_handler(SetHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/sit.rb b/lib/aethyr/core/input_handlers/sit.rb new file mode 100644 index 0000000000000000000000000000000000000000..f8912e7eac5fa1838893b033e99e7d0fcd535133 --- /dev/null +++ b/lib/aethyr/core/input_handlers/sit.rb @@ -0,0 +1,58 @@ +require "aethyr/core/actions/commands/sit" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Sit + class SitHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "sit" + see_also = ["STAND"] + syntax_formats = ["SIT", "SIT ON <object>"] + aliases = nil + content = <<'EOF' +Using this command, you can sit on things like chairs and benches. When used without an object, you will sit down on the ground. + +Note that you must stand up before you can move anywhere. + +Example: + +SIT ON stool + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["sit"], help_entries: SitHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^sit\s+on\s+(.*)$/i, /^sit\s+(.*)$/i, /^sit$/i + object = $1.strip if $1 + $manager.submit_action(Aethyr::Core::Actions::Sit::SitCommand.new(@player, {:object => object})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(SitHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/skills.rb b/lib/aethyr/core/input_handlers/skills.rb new file mode 100644 index 0000000000000000000000000000000000000000..a6a23e8bd6963713aa67a7736ad6d63b0163fb1d --- /dev/null +++ b/lib/aethyr/core/input_handlers/skills.rb @@ -0,0 +1,50 @@ +require "aethyr/core/actions/commands/skills" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" +require 'aethyr/core/render/text_util' +include TextUtil + +module Aethyr + module Core + module Commands + module Skills + class SkillsHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "skills" + see_also = nil + syntax_formats = ["SKILLS"] + aliases = nil + content = <<'EOF' +List all your currently known skills, their level, and level up info. +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["skills"], help_entries: SkillsHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^skills$/i + $manager.submit_action(Aethyr::Core::Actions::Skills::SkillsCommand.new(@player, {})) + end + end + end + + Aethyr::Extend::HandlerRegistry.register_handler(SkillsHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/slash.rb b/lib/aethyr/core/input_handlers/slash.rb new file mode 100644 index 0000000000000000000000000000000000000000..df0862a9d812e559e92f4b302b65e3903b8fb706 --- /dev/null +++ b/lib/aethyr/core/input_handlers/slash.rb @@ -0,0 +1,53 @@ +require "aethyr/core/actions/commands/slash" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Slash + class SlashHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "slash" + see_also = nil + syntax_formats = ["SLASH"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["slash"], help_entries: SlashHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^slash$/i + $manager.submit_action(Aethyr::Core::Actions::Slash::SlashCommand.new(@player, {})) + when /^slash\s+(.*)$/i + target = $1 + $manager.submit_action(Aethyr::Core::Actions::Slash::SlashCommand.new(@player, {:target => target})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(SlashHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/stand.rb b/lib/aethyr/core/input_handlers/stand.rb new file mode 100644 index 0000000000000000000000000000000000000000..963178da94b4556fb4f1635a6eb07a05d2a076f4 --- /dev/null +++ b/lib/aethyr/core/input_handlers/stand.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/stand" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Stand + class StandHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "stand" + see_also = ["SIT"] + syntax_formats = ["STAND"] + aliases = nil + content = <<'EOF' +Stand up if you are sitting down. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["stand"], help_entries: StandHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^stand$/i + $manager.submit_action(Aethyr::Core::Actions::Stand::StandCommand.new(@player, {})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(StandHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/tell.rb b/lib/aethyr/core/input_handlers/tell.rb new file mode 100644 index 0000000000000000000000000000000000000000..807c901695907d2a8b4f423fd7160e871194e91d --- /dev/null +++ b/lib/aethyr/core/input_handlers/tell.rb @@ -0,0 +1,73 @@ +require "aethyr/core/actions/commands/reply" +require "aethyr/core/actions/commands/tell" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Tell + class TellHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "tell" + see_also = ["SAY", "SAYTO", "WHISPER", "REPLY"] + syntax_formats = ["TELL [player] [message]"] + aliases = nil + content = <<'EOF' +All inhabitants of Aethyr have the ability to communicate privately with each other over long distances. This is done through the TELL command. Those who investigate these kinds of things claim there is some kind of latent telepathy in all of us. However, while no one knows for certain how it works, everyone knows it does. + +Example: +TELL Justin Hey, how's it going? + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + + + command = "reply" + see_also = ["TELL"] + syntax_formats = ["REPLY [message]"] + aliases = nil + content = <<'EOF' +Reply is a shortcut to send a tell to the last person who sent you a tell. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["tell", "reply"], help_entries: TellHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^tell\s+(\w+)\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Tell::TellCommand.new(@player, {:target => $1, :message => $2 })) + when /^reply\s+(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Reply::ReplyCommand.new(@player, {:message => $1 })) + end + end + + private + + #Tells someone something. + + + end + + Aethyr::Extend::HandlerRegistry.register_handler(TellHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/unwield.rb b/lib/aethyr/core/input_handlers/unwield.rb new file mode 100644 index 0000000000000000000000000000000000000000..334e635e2ed7e48d2a283aeb9f3604657d0a485b --- /dev/null +++ b/lib/aethyr/core/input_handlers/unwield.rb @@ -0,0 +1,57 @@ +require "aethyr/core/actions/commands/unwield" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Unwield + class UnwieldHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "unwield" + see_also = ["WIELD"] + syntax_formats = ["UNWIELD", "UNWIELD <weapon>", "UNWIELD <left|right>"] + aliases = nil + content = <<'EOF' +This command will cause you to unwield a weapon and place it in your inventory. If you do not specify which weapon or which hand you are using to hold the weapon, it will favor your right hand. + +Example: + +UNWIELD halberd +UNWIELD left + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["unwield"], help_entries: UnwieldHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^unwield(\s+(.*))?$/i + weapon = $2 + $manager.submit_action(Aethyr::Core::Actions::Unwield::UnwieldCommand.new(@player, {:weapon => weapon})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(UnwieldHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/wear.rb b/lib/aethyr/core/input_handlers/wear.rb new file mode 100644 index 0000000000000000000000000000000000000000..7bec97e4bc35aefd1351fa2fa69dcbd80d6cbd5d --- /dev/null +++ b/lib/aethyr/core/input_handlers/wear.rb @@ -0,0 +1,55 @@ +require "aethyr/core/actions/commands/wear" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Wear + class WearHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "wear" + see_also = ["REMOVE", "INVENTORY"] + syntax_formats = ["WEAR <object>"] + aliases = nil + content = <<'EOF' +Sytnax: WEAR <object> ON <body part> + +Wear an object. Objects usually have specific places they may be worn. + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["wear"], help_entries: WearHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^wear\s+(\w+)(\s+on\s+(.*))?$/i + object = $1 + position = $3 + $manager.submit_action(Aethyr::Core::Actions::Wear::WearCommand.new(@player, {:object => object, :position => position})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(WearHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/whereis.rb b/lib/aethyr/core/input_handlers/whereis.rb new file mode 100644 index 0000000000000000000000000000000000000000..fb783be5806f0ac3748cc7439846d07ad6f75f50 --- /dev/null +++ b/lib/aethyr/core/input_handlers/whereis.rb @@ -0,0 +1,51 @@ +require "aethyr/core/actions/commands/whereis" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Whereis + class WhereisHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "whereis" + see_also = nil + syntax_formats = ["WHEREIS"] + aliases = nil + content = <<'EOF' +Sorry no help has been written for this command yet +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["whereis"], help_entries: WhereisHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^whereis\s(.*)$/ + object = $1 + $manager.submit_action(Aethyr::Core::Actions::Whereis::WhereisCommand.new(@player, {:object => object})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(WhereisHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/whisper.rb b/lib/aethyr/core/input_handlers/whisper.rb new file mode 100644 index 0000000000000000000000000000000000000000..063e17e39bddea9ba8e4f67c5fca8b106bbdfa8b --- /dev/null +++ b/lib/aethyr/core/input_handlers/whisper.rb @@ -0,0 +1,61 @@ +require "aethyr/core/actions/commands/whisper" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Whisper + class WhisperHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "whisper" + see_also = ["SAY"] + syntax_formats = ["WHISPER [person] [message]"] + aliases = nil + content = <<'EOF' +To communicate with someone in the same room, but privately, use this command. + +Example: + +whisper justin that dog needs a bath + +Output: + +You whisper to Justin, "That dog needs a bath." + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["whisper"], help_entries: WhisperHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^whisper\s+(\w+)\s+(\((.*?)\)\s*)?(.*)$/i + $manager.submit_action(Aethyr::Core::Actions::Whisper::WhisperCommand.new(@player, { :to => $1, :phrase => $4, :pre => $3 })) + end + end + + private + #Whispers to another thing. + + end + + Aethyr::Extend::HandlerRegistry.register_handler(WhisperHandler) + end + end + end +end diff --git a/lib/aethyr/core/input_handlers/wield.rb b/lib/aethyr/core/input_handlers/wield.rb new file mode 100644 index 0000000000000000000000000000000000000000..78f370e2f075197756573f8768c792ef435d3a91 --- /dev/null +++ b/lib/aethyr/core/input_handlers/wield.rb @@ -0,0 +1,59 @@ +require "aethyr/core/actions/commands/wield" +require "aethyr/core/registry" +require "aethyr/core/input_handlers/command_handler" + +module Aethyr + module Core + module Commands + module Wield + class WieldHandler < Aethyr::Extend::CommandHandler + + def self.create_help_entries + help_entries = [] + + command = "wield" + see_also = ["UNWIELD"] + syntax_formats = ["WIELD <item>", "WIELD <item> <left|right>"] + aliases = nil + content = <<'EOF' +This command causes you to wield an item. The item must be wieldable and be present in your inventory. + +You can also specify which hand with which to wield the weapon. If you do not, it will favor your right hand. + +Example: + +WIELD sword left + +EOF + help_entries.push(Aethyr::Core::Help::HelpEntry.new(command, content: content, syntax_formats: syntax_formats, see_also: see_also, aliases: aliases)) + + return help_entries + end + + + def initialize(player) + super(player, ["wield"], help_entries: WieldHandler.create_help_entries) + end + + def self.object_added(data) + super(data, self) + end + + def player_input(data) + super(data) + case data[:input] + when /^wield\s+(.*?)(\s+(\w+))?$/i + weapon = $1 + side = $3 + $manager.submit_action(Aethyr::Core::Actions::Wield::WieldCommand.new(@player, {:weapon => weapon, :side => side})) + end + end + + private + + end + Aethyr::Extend::HandlerRegistry.register_handler(WieldHandler) + end + end + end +end diff --git a/lib/aethyr/core/objects/area.rb b/lib/aethyr/core/objects/area.rb index 5cf6e45cc0583ff4756ec7f4c4000534105c1370..b1620479648c0fbfac40eea04d54425b33a2ede7 100644 --- a/lib/aethyr/core/objects/area.rb +++ b/lib/aethyr/core/objects/area.rb @@ -10,17 +10,17 @@ require 'aethyr/core/objects/traits/location' # info.terrain.area_type = :urban class Area < GridContainer include Location - + attr_accessor :map_type def initialize(*args) super - + @article = "an" @generic = "area" @map_type = :rooms end - + def render_map(player, position, map_rows = 10, map_columns = 10) if @map_type == :rooms return render_rooms(player, position, map_rows, map_columns) @@ -32,7 +32,7 @@ class Area < GridContainer raise "Invalid map type for area!" end end - + private def render_world(player, position, map_rows, map_columns) player_room = self.inventory.find_by_id(player.container) @@ -44,7 +44,7 @@ class Area < GridContainer (0..width).step(1) do |screen_column| column = screen_column + (position[0] - (map_columns / 2)) room = self.find_by_position([column , row]) - + if room.nil? rendered += " " elsif room.eql? player_room @@ -57,7 +57,7 @@ class Area < GridContainer end rendered end - + def render_rooms(player, position, map_rows, map_columns) player_room = self.inventory.find_by_id(player.container) return "The current location doesn't appear on any maps." if position.nil? @@ -72,7 +72,7 @@ class Area < GridContainer until column >= width border_column = (column % 4 == 0); room_column = (column / 4) + (position[0] - (map_rows / 2)) - + room = self.find_by_position([room_column, room_row]) here_room = (room != nil && row < height - 1 && column < width - 1) west = self.find_by_position([room_column - 1, room_row]) @@ -80,7 +80,7 @@ class Area < GridContainer north = self.find_by_position([room_column , room_row + 1 ]) north_room = (column >= width - 1 ? false : north != nil) north_west_room = (row >= height - 1 || column >= width - 1 ? false : self.find_by_position([room_column - 1, room_row + 1]) != nil) - + if border_row if border_column if (here_room and north_west_room) or (west_room and north_room) @@ -157,15 +157,15 @@ class Area < GridContainer column += 2 end end - + column += 1 end rendered += "\r\n" end - + rendered end - + def room_has_nonstandard_exits(room) exits = room.exits.map() { |e| e.alt_names[0] } exits.each do |exit| @@ -173,21 +173,21 @@ class Area < GridContainer end false end - + def render_room(room, player) return " " if room.nil? player_room = self.inventory.find_by_id(player.container) has_player = (player_room.eql? room) - + me_here = has_player other_player_here = (!room.players(true, player).nil?) && (room.players(true, player).length > 0) merchants_here = false zone_change_here = room_has_nonstandard_exits(room) - + up_here = room.exits.map{ |e| e.alt_names[0]}.include?("up") down_here = room.exits.map{ |e| e.alt_names[0]}.include?("down") mobs_here = (!room.mobs.nil?) && (room.mobs.length > 0) - + left_char = " " if zone_change_here left_char = "<exit>☼</exit>" @@ -196,7 +196,7 @@ class Area < GridContainer elsif down_here left_char = "<exit>↓</exit>" end - + right_char = " " if mobs_here right_char = "<mob>*</mob>" @@ -205,12 +205,12 @@ class Area < GridContainer elsif other_player_here right_char = "<player>☺</player>" end - + middle_char = " " if me_here middle_char = "<me>☺</me>" end - + if (left_char.eql? " ") and (not right_char.eql? " ") if mobs_here and merchants_here left_char = "<merchant>☻</merchant>" @@ -222,7 +222,7 @@ class Area < GridContainer right_char = "<exit>↓</exit>" end end - + left_char + middle_char + right_char end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/objects/container.rb b/lib/aethyr/core/objects/container.rb index 221beb72a6b616619440f3f71bda9a764cbe733d..fbe8c047ddcaceb5284f8c783bf00436fcf9d74e 100644 --- a/lib/aethyr/core/objects/container.rb +++ b/lib/aethyr/core/objects/container.rb @@ -84,12 +84,12 @@ class GridContainer < Container @inventory.add(object, position) object.container = @game_object_id end - + def find_by_position(position) @inventory.find_by_position(position) end - + def position game_object @inventory.position(game_object) end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/objects/equipment.rb b/lib/aethyr/core/objects/equipment.rb index 4d97c5cf8c51dd405e27b966903986aee903d164..9273ff4926361dc71954da9d7d7fb768fe8b6df9 100644 --- a/lib/aethyr/core/objects/equipment.rb +++ b/lib/aethyr/core/objects/equipment.rb @@ -7,29 +7,28 @@ class Equipment include HasInventory @@slots = [ + :left_shoulder, + :head, + :right_shoulder, :left_arm, + :torso, :right_arm, - :head, + :left_foot, + :legs, + :right_foot, + :left_hand, + :right_hand, :face, :neck, :left_wrist, :right_wrist, :waist, - :left_foot, - :right_foot, - :left_hand, - :right_hand, :left_ring_finger, :right_ring_finger, :left_ear, :right_ear, :left_ankle, :right_ankle, - :torso, - :arms, - :legs, - :feet, - :hands ] attr_reader :equipment @@ -203,7 +202,7 @@ class Equipment position ||= game_object.position position = sym(position) - if [:arm, :leg, :wield, :wrist, :foot, :ankle, :ring_finger, :ear, :hand].include? position + if [:arm, :wield, :wrist, :foot, :ankle, :ring_finger, :ear, :hand, :shoulder].include? position return position_of(game_object, "left_#{position}".to_sym) || position_of(game_object, "right_#{position}".to_sym) end diff --git a/lib/aethyr/core/objects/game_object.rb b/lib/aethyr/core/objects/game_object.rb index 96201b831d41984e7da517cc5b3504720755d5c9..b2fafb918e3fcdbe96ae331a6f3dfe2d6f363de8 100644 --- a/lib/aethyr/core/objects/game_object.rb +++ b/lib/aethyr/core/objects/game_object.rb @@ -1,14 +1,13 @@ -require 'observer' require 'aethyr/core/util/publisher' require 'aethyr/core/util/log' require 'aethyr/core/objects/inventory' require 'aethyr/core/objects/traits/pronoun' require 'aethyr/core/util/guid' require 'aethyr/core/objects/info/info' +require 'aethyr/core/event' #Base class for all game objects, including players. Should be subclassed to do anything useful. class GameObject < Publisher - include Observable include Pronoun attr_reader :short_desc, :game_object_id, :alt_names, :generic, :article, :sex, :show_in_look, :actions, :balance, :admin, :manager @@ -70,11 +69,11 @@ class GameObject < Publisher @actions = Set.new @admin = false end - + def flags Hash.new @info.flags end - + def add_flag(new_flag) new_flag.negate_flags(@info.flags) @info.flags[new_flag.id] = new_flag @@ -97,11 +96,14 @@ class GameObject < Publisher def update return if @busy @busy = true - if self.is_a? Reacts - self.alert(Event.new(:Generic, :action => :tick)) + begin + if self.is_a? Reacts + self.alert(Event.new(:Generic, :action => :tick)) + end + run + ensure + @busy = false end - run - @busy = false end #Checks if the GameObject is busy in the GameObject#update method. @@ -129,12 +131,6 @@ class GameObject < Publisher def run end - #Just a way to put an event into the system, nothing more, nothing less. - def add_event(event) - changed - notify_observers(event) - end - #Basically, this is where hooks for commands would go. def alert(event) end @@ -263,4 +259,3 @@ class GameObject < Publisher end end - diff --git a/lib/aethyr/core/objects/player.rb b/lib/aethyr/core/objects/player.rb index de2a06d074be9d28ca49d50206a2c91814dea5b9..ec39655e49adb42535ece8fc0fc1c6b14cfb8ed9 100644 --- a/lib/aethyr/core/objects/player.rb +++ b/lib/aethyr/core/objects/player.rb @@ -1,10 +1,10 @@ require 'aethyr/core/objects/living' -require 'aethyr/core/commands/command_parser' require 'aethyr/core/objects/traits/has_inventory' require 'aethyr/core/help/syntax' # TODO : Delete the next to requires require 'aethyr/extensions/skills/map' require 'aethyr/extensions/skills/kick' +require 'aethyr/core/help/help_library' #Base class for all players. class Player < LivingObject @@ -40,8 +40,9 @@ class Player < LivingObject } - attr_reader :admin - attr_accessor :color_settings, :use_color, :reply_to, :page_height + attr_reader :admin, :color_settings, :help_library + attr_accessor :use_color, :reply_to, :page_height + volatile :@help_library, :@player #Create a new player object with the given socket connection. You must also pass in a game_object_id and a room, although if you pass in nil for game_object_id it will auto-generate one for you. def initialize(connection, game_object_id, room, *args) @@ -58,6 +59,10 @@ class Player < LivingObject @blind = false @reply_to = nil @prompt_shown = false + @layout = :basic + @player.display.layout(layout: @layout) + @help_library = Aethyr::Core::Help::HelpLibrary.new + info.stats.satiety = 120 map_skill = Aethyr::Extensions::Skills::Map.new(self.game_object_id) kick_skill = Aethyr::Extensions::Skills::Kick.new(self.game_object_id) @@ -66,6 +71,41 @@ class Player < LivingObject map_skill.add_xp 750 end + def set_connection(new_player) + @player = new_player + @player.display.color_settings = @color_settings + @player.display.layout(layout: @layout) + end + + #called right before saving to temporarily remove volatile data. + def dehydrate + volatile_data = super() + @layout = volatile_data[:@player].display.layout_type + return volatile_data + end + + #This should be called anytime the volatile data needs to be restored or initialized during a save or load + def rehydrate(volatile_data) + super(volatile_data) + @help_library = Aethyr::Core::Help::HelpLibrary.new if @help_library.nil? + end + + def layout + return @layout if @player.display.nil? + return @player.display.layout_type + end + + def layout= new_layout + @layout = new_layout + @player.display.layout(layout: new_layout) + @player.display.refresh_watch_windows(self) + end + + def color_settings= new_color_settings + @color_settings = new_color_settings + @player.display.color_settings = @color_settings + end + #Searches inventory and equipment for item. def has? item inventory.find(item) || equipment.find(item) @@ -113,40 +153,42 @@ class Player < LivingObject #Sends an event to the player. def out_event(event) + message_type = :main + message_type = event[:message_type] unless event[:message_type].nil? if event[:target] == self and event[:player] != self if self.blind? and not self.deaf? - self.output event[:to_blind_target] + self.output(event[:to_blind_target], message_type: message_type) elsif self.deaf? and not self.blind? - self.output event[:to_deaf_target] + self.output(event[:to_deaf_target], message_type: message_type) elsif self.deaf? and self.blind? - self.output event[:to_deafandblind_target] + self.output(event[:to_deafandblind_target], message_type: message_type) else - self.output event[:to_target] + self.output(event[:to_target], message_type: message_type) end elsif event[:player] == self - self.output event[:to_player] + self.output(event[:to_player], message_type: message_type) else if self.blind? and not self.deaf? - self.output event[:to_blind_other] + self.output(event[:to_blind_other], message_type: message_type) elsif self.deaf? and not self.blind? - self.output event[:to_deaf_other] + self.output(event[:to_deaf_other], message_type: message_type) elsif self.deaf? and self.blind? - self.output event[:to_deafandblind_other] + self.output(event[:to_deafandblind_other], message_type: message_type) else - self.output event[:to_other] + self.output(event[:to_other], message_type: message_type) end end end #Outputs a message to the Player. Used for all communication to Player. - def output(message, message_type: :main) + def output(message, no_newline = false, message_type: :main, internal_clear: false) return if message.nil? begin if message.is_a? Array message = message.join("\r\n") end - @player.say(message, message_type: message_type) unless (@player.nil? or @player.closed?) + @player.say(message, no_newline, message_type: message_type, internal_clear: internal_clear) unless (@player.nil? or @player.closed?) rescue Exception => e log "Unable to send message to #{@name}" log e.inspect @@ -155,13 +197,6 @@ class Player < LivingObject end end - #Just outputs a message to the player that we don't know what - #to do with the method call. - def method_missing(*args) - super - self.output("Don't know what do to with: #{args.inspect}") - end - #Handles the input from the Player. Basically, it just takes the #input, feeds it to the CommandParser, then sends the event #(if any) to the Manager. @@ -176,25 +211,7 @@ class Player < LivingObject end clean_input = input.downcase.strip - self.output('Help topics available:') if (clean_input.eql? "help") or (clean_input.eql? "help topics") broadcast(:player_input, {:publisher => self, :input => input}) - event = CommandParser.parse(self, input) - - if event.nil? - if input - doc = Syntax.find(input.strip.split[0].downcase) - if doc - output doc - else - output 'Not sure what you mean by that.' - end - end - elsif @asleep and event[:action] != 'wake' - output 'You cannot do that when you are asleep!' - else - changed - notify_observers(event) - end end #The player's next input will go to the block. @@ -244,6 +261,10 @@ class Player < LivingObject super end + def update_display + @player.display.refresh_watch_windows(self) + end + def run super if info.stats.health < info.stats.max_health - 10 @@ -251,5 +272,6 @@ class Player < LivingObject elsif info.stats.health < info.stats.max_health info.stats.health = info.stats.max_health end + update_display end end diff --git a/lib/aethyr/core/objects/room.rb b/lib/aethyr/core/objects/room.rb index e49b6ebcb496c4153e4417658aa70fdfe745cbe8..bbacb3765612bf122200bde2fa747912439947df 100644 --- a/lib/aethyr/core/objects/room.rb +++ b/lib/aethyr/core/objects/room.rb @@ -14,13 +14,13 @@ require 'aethyr/core/objects/traits/location' # terrain.room_type (Symbol) class Room < Container include Location - + attr_reader :terrain #Create new room. Arguments same as GameObject. def initialize(*args) super(nil, *args) - + @generic = "room" end @@ -36,8 +36,7 @@ class Room < Container object.container = @game_object_id if object.is_a? Player or object.is_a? Mobile - object.output(self.look(object), message_type: :look) unless object.blind? - object.output(self.area.render_map(object, self.area.position(self)), message_type: :map) if object.is_a? Player + object.update_display end end @@ -51,7 +50,7 @@ class Room < Container def exits @inventory.find_all('class', Exit) end - + def players(only_visible = true, exclude = nil) players = Array.new @inventory.each do |item| @@ -59,7 +58,7 @@ class Room < Container end players end - + def mobs(only_visible = true) mobs = Array.new @inventory.each do |item| @@ -67,7 +66,7 @@ class Room < Container end mobs end - + def things(only_visible = true) things = Array.new @inventory.each do |item| @@ -75,7 +74,7 @@ class Room < Container end things end - + def exits(only_visible = true) exits = Array.new @inventory.each do |item| @@ -88,6 +87,7 @@ class Room < Container #Returns a description of the room including: name of the room, room short description, visible people in the room, #visible objects in the room. All pretty-like. def look(player) + return "You cannot see while you are blind" if player.blind? players = Array.new mobs = Array.new things = Array.new @@ -121,7 +121,7 @@ class Room < Container else quantity = item.article end - + idents = ["<identifier>#{item.generic}</identifier>"] idents += item.alt_names.map() {|e| "<identifier>" + e + "</identifier>"} idents = idents.join(', ') @@ -147,7 +147,7 @@ class Room < Container else players = "The following #{players.length <= 1 ? 'player is' : 'players are'} here:\n#{players.list(@inventory, :expanded)}\n" end - + if mobs.empty? mobs = "" else @@ -159,7 +159,7 @@ class Room < Container else things = "There are the following items in the room:\n#{things.list(@inventory, :expanded)}\n" end - + info = "You find some things unusual about this place:\n" info += " Type: " + self.terrain_type.name + "\n" self.flags.values.each do |f| @@ -169,7 +169,6 @@ class Room < Container end info += "\n" - "\n<roomtitle>#{@name}</roomtitle>\n\n#{(@short_desc || '') + add_to_desc}\n\n[Exits: #{exits.list}]\n\n#{info}#{players}#{mobs}#{things}\n" + "<roomtitle>#{@name}</roomtitle>\n\n#{(@short_desc || '') + add_to_desc}\n\n[Exits: #{exits.list}]\n\n#{info}#{players}#{mobs}#{things}" end end - diff --git a/lib/aethyr/core/objects/traits/expires.rb b/lib/aethyr/core/objects/traits/expires.rb index 529747e88621623e5e8dac7030a1fadb6a9718e4..9c8abf69b091cb8b881650865f7f6f779fc40a43 100644 --- a/lib/aethyr/core/objects/traits/expires.rb +++ b/lib/aethyr/core/objects/traits/expires.rb @@ -18,6 +18,6 @@ module Expires private def expire - add_event Event.new(:Mobiles, :action => :expire, :player => self) + raise "expire is not yet properly implemented" end end diff --git a/lib/aethyr/core/objects/traits/location.rb b/lib/aethyr/core/objects/traits/location.rb index cdb679deec98195866d62e30d9d56feb4cb85bda..8045891d44d9ab0e7d9faad7941e818c71555735 100644 --- a/lib/aethyr/core/objects/traits/location.rb +++ b/lib/aethyr/core/objects/traits/location.rb @@ -4,7 +4,6 @@ require 'aethyr/core/util/log' require 'aethyr/core/objects/inventory' require 'aethyr/core/objects/traits/pronoun' require 'aethyr/core/util/guid' -require 'observer' require 'aethyr/core/objects/info/info' module Location @@ -17,12 +16,12 @@ module Location info.terrain.type = terrain_type end end - + def area return self if self.is_a? Area self.parent_area end - + def parent_area return nil if $manager.nil? parent_id = @container @@ -33,17 +32,17 @@ module Location end nil end - + def flags collected_flags = self.parent_area.flags unless self.parent_area.nil? return info.flags.dup if collected_flags.nil? - + self.info.flags.values.each do |f| f.negate_flags(collected_flags) end collected_flags.merge! self.info.flags end - + def terrain_type return info.terrain.type unless info.terrain.type.nil? return self.parent_area.terrain_type unless self.parent_area.nil? diff --git a/lib/aethyr/core/objects/traits/reacts.rb b/lib/aethyr/core/objects/traits/reacts.rb index 529d71ac7e33350c28d32447c6570f8da5e8cb21..716b2434a0f9aaa838b4a689cefb9f4a5f0ee6e3 100644 --- a/lib/aethyr/core/objects/traits/reacts.rb +++ b/lib/aethyr/core/objects/traits/reacts.rb @@ -64,7 +64,8 @@ module Reacts unless action.nil? log "I am doing an action...", Logger::Ultimate changed - notify_observers(action) + #notify_observers(action) + raise "This used to notify observers, not sure how this worked so need to fix this, most likely this will be rewritten before it becomes an issue." else log "Action did not parse: #{reaction}", Logger::Medium end @@ -118,7 +119,8 @@ module Reacts event = CommandParser.parse(self, command) return false if event.nil? #failed to parse - add_event event unless delay + raise "removed events this class no longer works, will probably be rewritten" + #add_event event unless delay event end @@ -273,7 +275,8 @@ module Reacts def teleport item, destination, options = {} event = Event.new :Mobiles, {:action => :teleport, :player => self, :object => item, :in => destination}.merge(options) - add_event event + raise "re removed events this class no longer works and will probably be rewritten" + # add_event event end def follow object, message = nil diff --git a/lib/aethyr/core/objects/traits/respawns.rb b/lib/aethyr/core/objects/traits/respawns.rb index 078afc57f882a5e61d65e4cd99302eedf750746d..98c211ab4db2ac86cadcfd2dcf4f68f54ea55912 100644 --- a/lib/aethyr/core/objects/traits/respawns.rb +++ b/lib/aethyr/core/objects/traits/respawns.rb @@ -59,6 +59,7 @@ module Respawns return end - add_event Event.new(:Mobiles, :player => self, :action => :respawn, :room => room) + raise "respawn no longer works, removed events, will likely be rewritten" + #add_event Event.new(:Mobiles, :player => self, :action => :respawn, :room => room) end end diff --git a/lib/aethyr/core/registry.rb b/lib/aethyr/core/registry.rb index b4ab627fc320f895422ad06a701f0521dd223487..f1220254f1ad5c1bfc8509d84ad5eab1b3954278 100644 --- a/lib/aethyr/core/registry.rb +++ b/lib/aethyr/core/registry.rb @@ -1,45 +1,27 @@ module Aethyr module Extend class HandlerRegistry - @@handlers = Set.new - + @@handlers = Set.new + def self.register_handler(new_handler) raise "Bad handler!" unless new_handler unless @@handlers.include? new_handler @@handlers << new_handler end end - + def self.get_handlers return @@handlers.dup end - + def self.handle(manager) @@handlers.each do |handler| manager.subscribe(handler) end nil end - -# def self.help_handle(input, player) -# @@handlers.values.each do |handler| -# next unless handler.is_a? Aethyr::Extend::HandleHelp -# e = handler.help_handle(input, player) -# return e unless e.nil? -# end -# nil -# end -# -# def self.help_topics(player) -# topics = [] -# @@handlers.values.each do |handler| -# next unless handler.is_a? Aethyr::Extend::HandleHelp -# topics.push *(handler.commands) -# end -# topics -# end end end end -require 'aethyr/core/util/all-commands' \ No newline at end of file +require 'aethyr/core/util/all-commands' diff --git a/lib/aethyr/core/render/display.rb b/lib/aethyr/core/render/display.rb index 4d6c4fa77d7476d783e2f3610843d8cee7070d2b..9a62e883b7ea1e32703c039ca5f3350c6b022f0c 100644 --- a/lib/aethyr/core/render/display.rb +++ b/lib/aethyr/core/render/display.rb @@ -1,276 +1,511 @@ -require "ncursesw" +# coding: utf-8 + +require 'ncursesw' +require 'stringio' require 'aethyr/core/connection/telnet_codes' +require 'aethyr/core/connection/telnet' +require 'aethyr/core/components/manager' +require 'aethyr/core/render/window' class Display - PREAMBLE = [IAC + DO + OPT_LINEMODE, - IAC + SB + OPT_LINEMODE + OPT_ECHO + OPT_BINARY + IAC + SE, - IAC + WILL + OPT_ECHO] - - DEFAULT_HEIGHT = 130 - DEFAULT_WIDTH = 164 - - def initialize socket + attr_reader :layout_type + attr_accessor :color_settings, :use_color + + DEFAULT_HEIGHT = 43 + DEFAULT_WIDTH = 80 + + def initialize(socket, new_color_settings = nil) @height = DEFAULT_HEIGHT @width = DEFAULT_WIDTH - - @socket = socket - PREAMBLE.each do |line| - @socket.puts line - end - - @selected = :input - @screen = Ncurses.newterm("xterm-256color", @socket, @socket) - + @use_color = false + @layout_type = :basic + + @color_settings = new_color_settings || to_default_colors + + @socket = socket # StringIO.new + @scanner = TelnetScanner.new(socket, self) + @scanner.send_preamble + + @screen = Ncurses.newterm('xterm-256color', @socket, @socket) + Ncurses.set_term(@screen) - Ncurses.resizeterm(@height, @width) Ncurses.cbreak # provide unbuffered input Ncurses.noecho # turn off input echoing Ncurses.nonl # turn off newline translation + Ncurses.curs_set(2) # high visibility cursor Ncurses.stdscr.intrflush(false) # turn off flush-on-interrupt Ncurses.stdscr.keypad(true) # turn on keypad mode - - Ncurses.scrollok(Ncurses.stdscr, true) + Ncurses.stdscr.clear - - init_colors + + @windows = { + main: Window.new(@color_settings, buffered: true), + input: Window.new(@color_settings), + map: Window.new(@color_settings), + look: Window.new(@color_settings, buffered: true), + quick_bar: Window.new(@color_settings), + status: Window.new(@color_settings), + chat: Window.new(@color_settings, buffered: true) + } + self.selected = :input layout end - + def init_colors Ncurses.start_color + @use_color = true + @windows.each do |_channel, window| + window.enable_color + end + puts "There are #{Ncurses.COLORS} colors on this client" + Ncurses.assume_default_colors(Color::Foreground.attribute(:white), Color::Background.attribute(:black)) Ncurses.COLORS.times do |fg| Ncurses.COLORS.times do |bg| - Ncurses.init_pair(fg + bg * Ncurses.COLORS, bg, fg) + Ncurses.init_pair(fg + bg * Ncurses.COLORS, fg, bg) end end + update end - - def activate_color(window, fg, bg) - window.attron(fg + bg * Ncurses.COLORS) + + def selected=(channel) + @windows.each do |_channel, window| + window.selected = false + end + @windows[channel].selected = true end - - def layout( layout_type: :full) - case layout_type - when :basic - @window_main_border = Ncurses::WINDOW.new(@height - 3, 0, 0, 0) - @window_main = @window_main_border.derwin(@window_main_border.getmaxy - 2, @window_main_border.getmaxx - 2, 1, 1) - Ncurses.scrollok(@window_main, true) - @window_main.clear - #@window_main.move(@window_main.getmaxy - 2,1) - - @window_input_border = Ncurses::WINDOW.new(3, 0, @height - 3, 0) - @window_input = @window_input_border.derwin(@window_input_border.getmaxy - 2, @window_input_border.getmaxx - 2, 1, 1) - Ncurses.scrollok(@window_input, false) - @window_input.clear - when :full - @window_map_border = Ncurses::WINDOW.new(@height - 29, 0, 0, 0) - @window_map = @window_map_border.derwin(@window_map_border.getmaxy - 2, @window_map_border.getmaxx - 2, 1, 1) - Ncurses.scrollok(@window_map, true) - @window_map.clear - @window_map.move(@window_map.getmaxy - 2,1) - - @window_look_border = Ncurses::WINDOW.new(26, 82, @height - 29, 0) - @window_look = @window_look_border.derwin(@window_look_border.getmaxy - 2, @window_look_border.getmaxx - 2, 1, 1) - Ncurses.scrollok(@window_look, true) - @window_look.clear - @window_look.move(@window_look.getmaxy - 2,1) - - @window_main_border = Ncurses::WINDOW.new(26, 0, @height - 29, 82) - @window_main = @window_main_border.derwin(@window_main_border.getmaxy - 2, @window_main_border.getmaxx - 2, 1, 1) - Ncurses.scrollok(@window_main, true) - @window_main.clear - #@window_main.move(@window_main.getmaxy - 2,1) - - @window_input_border = Ncurses::WINDOW.new(3, 0, @height - 3, 0) - @window_input = @window_input_border.derwin(@window_input_border.getmaxy - 2, @window_input_border.getmaxx - 2, 1, 1) - Ncurses.scrollok(@window_input, false) - @window_input.clear + + def selected + @windows.each do |channel, window| + return channel if window.selected end + :input + end + + def layout(layout: @layout_type) + set_term + puts "layout #{layout} set for resolution #{@width}x#{@height}" + @layout_type = layout + if @layout_type == :wide && @height >= 60 && @width >= 300 + @windows[:quick_bar].create(height: 3, y: @height - 5) + @windows[:map].create(height: @height / 2 + 1, width: 166) + @windows[:look].create(height: @height / 2 - 3, width: 83, y: @height / 2) + @windows[:main].create(height: @height / 2 - 3, width: 83, x: 83, y: @height / 2) + @windows[:chat].create(height: @height - 4, width: @width - 249, x: 166) + @windows[:status].create(height: @height - 4, x: @width - 83) + elsif (@layout_type == :full || @layout_type == :wide) && @height >= 60 && @width >= 249 + @windows[:quick_bar].create(height: 3, y: @height - 5) + @windows[:map].create(height: @height / 2 + 1, width: 166) + @windows[:look].create(height: @height / 2 - 3, width: 83, y: @height / 2) + @windows[:main].create(height: @height / 2 - 3, width: 83, x: 83, y: @height / 2) + @windows[:chat].create(height: @height - 4, x: 166) + @windows[:status].destroy + elsif (@layout_type == :partial || @layout_type == :full || @layout_type == :wide) && @height >= 60 && @width >= 166 + @windows[:status].destroy + @windows[:chat].destroy + @windows[:quick_bar].create(height: 3, y: @height - 5) + @windows[:map].create(height: @height / 2 + 1) + @windows[:look].create(height: @height / 2 - 3, width: 83, y: @height / 2) + @windows[:main].create(height: @height / 2 - 3, x: 83, y: @height / 2) + else + @windows[:map].destroy + @windows[:look].destroy + @windows[:quick_bar].destroy + @windows[:status].destroy + @windows[:chat].destroy + @windows[:main].create(height: @height - 2) + end + @windows[:input].create(height: 3, y: @height - 3) @echo = true update end - - def read_rdy? - ready, _, _ = IO.select([@socket]) - ready.any? + + def resolution + [@width, @height] + end + + def resolution=(resolution) + @width = resolution[0] + @height = resolution[1] + Ncurses.resizeterm(@height, @width) + @global_refresh = true + layout end - + + def global_refresh + retval = @global_refresh + @global_refresh = false + return retval + end + def echo? @echo end - + def echo_on @echo = true end - + def echo_off @echo = false end - + def recv - return nil unless read_rdy? - set_term recvd = read_line(0, 0) + return nil if recvd.nil? + puts "read returned: #{recvd}" recvd + "\n" end - - def send_raw message + + def send_raw(message) @socket.puts message end - - def send (message, message_type: :main, internal_clear: true) + + def send(message, word_wrap = true, message_type: :main, internal_clear: false, add_newline: true) window = nil - case message_type - when :main - window = @window_main - when :look - unless @window_look.nil? - window = @window_look - #window.clear - else - window = @window_main - end - when :map - unless @window_map.nil? - window = @window_map - #window.clear - else - window = @window_main - end - end - raise "window_type not recognized" if window.nil? - - window.clear if internal_clear and not message_type.eql? :main - - message = message.tr("\r", '') - lines = message.split("\n"); - return if lines.empty? - if lines.length > 1 - lines.each do |line| - send line, message_type: message_type, internal_clear: false - end - return + + if @windows[message_type].nil? || !@windows[message_type].exists? + message_type = :main + internal_clear = false end - message = lines[0] - - set_term - #window.scroll - #window.mvaddstr(window.getmaxy - 2, 1, "#{message}\n") - activate_color(window, 2, 0) - window.addstr("#{message}\n") - update + @windows[message_type].clear if internal_clear + @windows[message_type].send(message, word_wrap, add_newline: add_newline) end - + def close set_term Ncurses.echo Ncurses.nocbreak Ncurses.nl Ncurses.endwin + @socket.close end - - private - - def update - @window_main_border.border(*([32]*8)) unless @window_main_border.nil? - @window_input_border.border(*([32]*8)) unless @window_input_border.nil? - @window_map_border.border(*([32]*8)) unless @window_map_border.nil? - @window_look_border.border(*([32]*8)) unless @window_look_border.nil? - - @window_main_border.border(*([0]*8)) if @selected.eql? :main - @window_input_border.border(*([0]*8)) if @selected.eql? :input - @window_map_border.border(*([0]*8)) if @selected.eql? :map - @window_look_border.border(*([0]*8)) if @selected.eql? :look - - @window_main_border.noutrefresh() - @window_main.noutrefresh() - @window_input_border.noutrefresh() - @window_input.noutrefresh() - @window_map_border.noutrefresh() - @window_map.noutrefresh() - @window_look_border.noutrefresh() - @window_look.noutrefresh() - Ncurses.doupdate() + + # Sets colors to defaults + def to_default_colors + @color_settings = { + 'roomtitle' => 'fg:green bold', + 'object' => 'fg:blue', + 'player' => 'fg:cyan', + 'mob' => 'fg:yellow bold', + 'merchant' => 'fg:yellow dim', + 'me' => 'fg:white bold', + 'exit' => 'fg:green', + 'say' => 'fg:white bold', + 'tell' => 'fg:cyan bold', + 'important' => 'fg:red bold', + 'editor' => 'fg:cyan', + 'news' => 'fg:cyan bold', + 'identifier' => 'fg:magenta bold', + 'water' => 'fg:blue', + 'waterlow' => 'fg:blue dim', + 'waterhigh' => 'fg:blue bold', + 'earth' => 'fg:darkgoldenrod', + 'earthlow' => 'fg:darkgoldenrod dim', + 'earthhigh' => 'fg:darkgoldenrod bold', + 'air' => 'fg:white', + 'airlow' => 'fg:white dim', + 'airhigh' => 'fg:white bold', + 'fire' => 'fg:red', + 'firelow' => 'fg:red dim', + 'firehigh' => 'fg:red bold', + 'regular' => 'fg:white bg:black' + } + end + + # Sets the foreground color for a given setting. + def set_color(code, color) + code&.downcase! + color&.downcase! + + if !@color_settings.key? code + "No such setting: #{code}" + else + unless @use_color + @color_settings.keys.each do |setting| + @color_settings[setting] = '' + end + @use_color = true + end + + @color_settings[code] = color + "Set #{code} to <#{code}>#{color}</#{code}>." + end + end + + # Returns list of color settings to show the player + def show_color_config + <<~CONF + Colors are currently: #{@use_color ? 'Enabled' : 'Disabled'} + Text Setting Color + ----------------------------------------------- + Room Title roomtitle <roomtitle>#{@color_settings['roomtitle']}</roomtitle> + Object object <object>#{@color_settings['object']}</object> + Player player <player>#{@color_settings['player']}</player> + Mob mob <mob>#{@color_settings['mob']}</mob> + Merchant merchant <merchant>#{@color_settings['merchant']}</merchant> + Me me <me>#{@color_settings['me']}</me> + Exit exit <exit>#{@color_settings['exit']}</exit> + Say say <say>#{@color_settings['say']}</say> + Tell tell <tell>#{@color_settings['tell']}</tell> + Important important <important>#{@color_settings['important']}</important> + Editor editor <editor>#{@color_settings['editor']}</editor> + News news <news>#{@color_settings['news']}</news> + Identifier identifier <identifier>#{@color_settings['identifier']}</identifier> + Fire fire <fire>#{@color_settings['fire']}</fire> + Fire when low firelow <firelow>#{@color_settings['firelow']}</firelow> + Fire when high firehigh <firehigh>#{@color_settings['firehigh']}</firehigh> + Air air <air>#{@color_settings['air']}</air> + Air when low airlow <airlow>#{@color_settings['airlow']}</airlow> + Air when high airhigh <airhigh>#{@color_settings['airhigh']}</airhigh> + Water water <water>#{@color_settings['water']}</water> + Water when low waterlow <waterlow>#{@color_settings['waterlow']}</waterlow> + Water when high waterhigh <waterhigh>#{@color_settings['waterhigh']}</waterhigh> + Earth earth <earth>#{@color_settings['earth']}</earth> + Earth when low earthlow <earthlow>#{@color_settings['earthlow']}</earthlow> + Earth when high earthhigh <earthhigh>#{@color_settings['earthhigh']}</earthhigh> + Regular regular #{@color_settings['regular']} + CONF + end + + def refresh_watch_windows(player) + if @windows[:look].exists? + room = $manager.get_object(player.container) + if !room.nil? + look_text = room.look(player) + # cleared = false + msg = Window.split_message(look_text, 79).join("\n") + send(msg, message_type: :look, internal_clear: true, add_newline: true) + else + send('Nothing to look at.', message_type: :look, internal_clear: true) + end + end + + if @windows[:map].exists? + room = $manager.get_object(player.container) + if !room.nil? + player.output(room.area.render_map(player, room.area.position(room)), message_type: :map, internal_clear: true) + else + player.output('No map of current area.', message_type: :map, internal_clear: true) + end + end + + if @windows[:quick_bar].exists? + send('this is the quick bar', message_type: :quick_bar, internal_clear: true, add_newline: false) + end + + if @windows[:status].exists? + send('This is the status window', message_type: :status, internal_clear: true, add_newline: false) + end end - + def set_term Ncurses.set_term(@screen) end - + + private + + def update + @windows.each do |channel, window| + window.update unless channel == selected + end + @windows[selected].update # make sure the selected window always takes the last update so border renders properly + Ncurses.doupdate + end def read_line(y, x, - window = @window_input, - max_len = (window.getmaxx - x - 1), - string = "", - cursor_pos = 0) - loop do - window.mvaddstr(y,x,string) if echo? - window.move(y,x+cursor_pos) if echo? - update - - ch = window.getch - puts ch + max_len: (@windows[:input].window_text.getmaxx - x - 1)) + + @read_stage = :none if @read_stage.nil? + if @read_stage == :none + @escape = nil + @cursor_pos = 0 + @input_buffer = '' + @read_stage = :update + end + + if @read_stage == :update + @windows[:input].clear + @windows[:input].window_text.mvaddstr(y, x, @input_buffer) if echo? + @windows[:input].window_text.move(y, x + @cursor_pos) if echo? + # update + @windows[:input].update + Ncurses.doupdate + + @read_stage = :iac + return nil + end + + if @read_stage == :iac + @read_stage = :input if @scanner.process_iac + return nil + end + + ch = @windows[:input].window_text.getch + @read_stage = :iac + puts ch + + unless @escape.nil? + case @escape + + when [27] + case ch + when 91 + @escape = [27, 91] + end + + when [27, 91] + case ch + when 53 # scroll up + @escape = [27, 91, 53] + when 54 # scroll down + @escape = [27, 91, 54] + when 68 + ch = Ncurses::KEY_LEFT + @escape = nil + when 67 + ch = Ncurses::KEY_RIGHT + @escape = nil + when 65 + ch = Ncurses::KEY_UP + @escape = nil + when 66 + ch = Ncurses::KEY_DOWN + @escape = nil + else + @escape = nil + return nil + end + + when [27, 91, 53] + case ch + when 126 # page up + if selected == :input + @windows[:main].buffer_pos += 5 + else + if (@windows[selected].respond_to? :buffer_pos) && !@windows[selected].buffer_pos.nil? + @windows[selected].buffer_pos += 5 + end + end + @escape = nil + return nil + else + @escape = nil + return nil + end + + when [27, 91, 54] + case ch + when 126 # page down + if selected == :input + @windows[:main].buffer_pos -= 5 + else + if (@windows[selected].respond_to? :buffer_pos) && !@windows[selected].buffer_pos.nil? + @windows[selected].buffer_pos -= 5 + end + end + @escape = nil + return nil + else + @escape = nil + return nil + end + else + @escape = nil + return nil + end + end + + if @escape.nil? case ch + when 27 + @escape = [27] when Ncurses::KEY_LEFT - cursor_pos = [0, cursor_pos-1].max + @cursor_pos = [0, @cursor_pos - 1].max + @read_stage = :update when Ncurses::KEY_RIGHT - cursor_pos = [max_len, cursor_pos + 1].min - # similar, implement yourself ! -# when Ncurses::KEY_ENTER, ?\n, ?\r -# return string, cursor_pos, ch # Which return key has been used? + @cursor_pos = [max_len, @cursor_pos + 1, @input_buffer.length].min + @read_stage = :update + when Ncurses::KEY_UP + @windows[:main].buffer_pos += 1 + @read_stage = :update + when Ncurses::KEY_DOWN + @windows[:main].buffer_pos -= 1 + @read_stage = :update when 13 # return - window.clear - @window_main.addstr("≫≫≫≫≫ #{string}\n") if echo? - @selected = :input - update - return string#, cursor_pos, ch # Which return key has been used? - #when Ncurses::KEY_BACKSPACE - when 127 # backspace - string = string[0...([0, cursor_pos-1].max)] + string[cursor_pos..-1] - cursor_pos = [0, cursor_pos-1].max - window.mvaddstr(y, x+string.length, " ") if echo? + @windows[:input].clear + self.selected = :input + @windows[:main].send("\n≫≫≫≫≫ #{@input_buffer}\n\n") if echo? + @windows[:main].buffer_pos = 0 + @windows[:main].update + @read_stage = :none + return @input_buffer # , cursor_pos, ch # Which return key has been used? + # when Ncurses::KEY_BACKSPACE + when 127, "\b".ord, Ncurses::KEY_BACKSPACE # backspace + # string = string[0...([0, cursor_pos-1].max)] + string[cursor_pos..-1] + if @cursor_pos >= 1 + @input_buffer.slice!(@cursor_pos - 1) + @cursor_pos -= 1 + end + # window.mvaddstr(y, x+string.length, " ") if echo? @selected = :input + @read_stage = :update # when etc... when 32..255 # remaining printables - if (cursor_pos < max_len) - #string[cursor_pos,0] = ch - string = string + ch.chr - cursor_pos += 1 + if @cursor_pos < max_len + # string[cursor_pos,0] = ch + @input_buffer.insert(@cursor_pos, ch.chr) + @cursor_pos += 1 end @selected = :input + @read_stage = :update when 9 # tab - case @selected - when :input - @selected = :main - when :main - if not @window_map.nil? - @selected = :map - elsif not @window_look.nil? - @selected = :look - else - @selected = :input - end - when :map - if not @window_look.nil? - @selected = :look - else - @selected = :input - end - when :look - @selected = :input - else - @selected = :input - end + self.selected = case selected + when :input + if @windows[:look].exists? + :look + else + :main + end + when :main + if @windows[:chat].exists? + :chat + elsif @windows[:status].exists? + :status + else + :input + end + when :map + :main + when :look + if @windows[:map].exists? + :map + else + :input + end + when :chat + if @windows[:status].exists? + :status + else + :input + end + when :status + :input + else + :input + end + @read_stage = :update update else log "Unidentified key press: #{ch}" end - end + end + + return nil end -end \ No newline at end of file +end diff --git a/lib/aethyr/core/render/editor.rb b/lib/aethyr/core/render/editor.rb index f808869bbe7466614dc544254bba4fbbbd7a7962..0a0154d2acaeb2314d80d5651263ed52b2c139fe 100644 --- a/lib/aethyr/core/render/editor.rb +++ b/lib/aethyr/core/render/editor.rb @@ -116,7 +116,7 @@ module Editor # #Basically just colors the output. def editor_out message - self.puts "<editor>#{message}</editor>" + self.send_puts "<editor>#{message}</editor>" end #Replace a line in the buffer. diff --git a/lib/aethyr/core/render/format.rb b/lib/aethyr/core/render/format.rb index d8abbb0997b296fffea6b3413760b22fe6a074b1..352ceb4aa5ea2d5ea33d85a4d7a503bef22c6522 100644 --- a/lib/aethyr/core/render/format.rb +++ b/lib/aethyr/core/render/format.rb @@ -1,360 +1,266 @@ #ANSI colors. module Color - module Formatting - @@attributes = [ - [ :bold, "\e[1m"], - [ :dim, "\e[2m"], - [ :underlined, "\e[4m"], - [ :blink, "\e[5m"], - [ :reverse, "\e[7m"] - ] - - @@attributes.each do |c, v| - eval %Q{ - def #{c}(string = nil) - result = '' - result << "#{v}" - if block_given? - result << yield - elsif string - result << string - elsif respond_to?(:to_str) - result << self - else - return result #only switch on - end - result << "\e[0m" - result - end - } - end - - module_function - def attributes - @@attributes.map { |c| c.first } - end - - def attribute att - @@attributes.each do |e| - return e.last if e.first.eql? att - end - nil - end - extend self - end - - module Reset - @@attributes = [ - [ :all, "\e[0m"], - [ :bold, "\e[21m"], - [ :dim, "\e[22m"], - [ :underlined, "\e[24m"], - [ :blink, "\e[25m"], - [ :reverse, "\e[27m"] - ] - - @@attributes.each do |c, v| - eval %Q{ - def #{c}(string = nil) - result = '' - result << "#{v}" - if block_given? - result << yield - elsif string - result << string - elsif respond_to?(:to_str) - result << self - else - return result #only switch on - end - result << "\e[0m" - result - end - } - end - - module_function - def attributes - @@attributes.map { |c| c.first } - end - - def attribute att - @@attributes.each do |e| - return e.last if e.first.eql? att - end - nil - end - extend self - end - + module Foreground @@attributes = [ - [ :magenta, "\e[35m"], - [ :cyan, "\e[36m"], - [ :light_gray, "\e[37m"], - [ :dark_gray, "\e[90m"], - [ :light_red, "\e[91m"], - [ :light_green, "\e[92m"], - [ :light_yellow, "\e[93m"], - [ :light_blue, "\e[94m"], - [ :light_magenta, "\e[95m"], - [ :light_cyan, "\e[96m"], - [ :black, "\e[38;5;0m"], - [ :maroon, "\e[38;5;1m"], - [ :green, "\e[38;5;2m"], - [ :olive, "\e[38;5;3m"], - [ :navy, "\e[38;5;4m"], - [ :purple, "\e[38;5;5m"], - [ :teal, "\e[38;5;6m"], - [ :silver, "\e[38;5;7m"], - [ :grey, "\e[38;5;8m"], - [ :red, "\e[38;5;9m"], - [ :lime, "\e[38;5;10m"], - [ :yellow, "\e[38;5;11m"], - [ :blue, "\e[38;5;12m"], - [ :fuchsia, "\e[38;5;13m"], - [ :aqua, "\e[38;5;14m"], - [ :white, "\e[38;5;15m"], - [ :grey_0, "\e[38;5;16m"], - [ :navy_blue, "\e[38;5;17m"], - [ :dark_blue, "\e[38;5;18m"], - [ :blue_3, "\e[38;5;19m"], - [ :blue_3, "\e[38;5;20m"], - [ :blue_1, "\e[38;5;21m"], - [ :dark_green, "\e[38;5;22m"], - [ :deep_sky_blue_4, "\e[38;5;23m"], - [ :deep_sky_blue_4, "\e[38;5;24m"], - [ :deep_sky_blue_4, "\e[38;5;25m"], - [ :dodger_blue_3, "\e[38;5;26m"], - [ :dodger_blue_2, "\e[38;5;27m"], - [ :green_4, "\e[38;5;28m"], - [ :spring_green_4, "\e[38;5;29m"], - [ :turquoise_4, "\e[38;5;30m"], - [ :deep_sky_blue_3, "\e[38;5;31m"], - [ :deep_sky_blue_3, "\e[38;5;32m"], - [ :dodger_blue_1, "\e[38;5;33m"], - [ :green_3, "\e[38;5;34m"], - [ :spring_green_3, "\e[38;5;35m"], - [ :dark_cyan, "\e[38;5;36m"], - [ :light_sea_green, "\e[38;5;37m"], - [ :deep_sky_blue_2, "\e[38;5;38m"], - [ :deep_sky_blue_1, "\e[38;5;39m"], - [ :green_3, "\e[38;5;40m"], - [ :spring_green_3, "\e[38;5;41m"], - [ :spring_green_2, "\e[38;5;42m"], - [ :cyan_3, "\e[38;5;43m"], - [ :dark_turquoise, "\e[38;5;44m"], - [ :turquoise_2, "\e[38;5;45m"], - [ :green_1, "\e[38;5;46m"], - [ :spring_green_2, "\e[38;5;47m"], - [ :spring_green_1, "\e[38;5;48m"], - [ :medium_spring_green, "\e[38;5;49m"], - [ :cyan_2, "\e[38;5;50m"], - [ :cyan_1, "\e[38;5;51m"], - [ :dark_red, "\e[38;5;52m"], - [ :deep_pink_4, "\e[38;5;53m"], - [ :purple_4, "\e[38;5;54m"], - [ :purple_4, "\e[38;5;55m"], - [ :purple_3, "\e[38;5;56m"], - [ :blue_violet, "\e[38;5;57m"], - [ :orange_4, "\e[38;5;58m"], - [ :grey_37, "\e[38;5;59m"], - [ :medium_purple_4, "\e[38;5;60m"], - [ :slate_blue_3, "\e[38;5;61m"], - [ :slate_blue_3, "\e[38;5;62m"], - [ :royal_blue_1, "\e[38;5;63m"], - [ :chartreuse_4, "\e[38;5;64m"], - [ :dark_sea_green_4, "\e[38;5;65m"], - [ :pale_turquoise_4, "\e[38;5;66m"], - [ :steel_blue, "\e[38;5;67m"], - [ :steel_blue_3, "\e[38;5;68m"], - [ :cornflower_blue, "\e[38;5;69m"], - [ :chartreuse_3, "\e[38;5;70m"], - [ :dark_sea_green_4, "\e[38;5;71m"], - [ :cadet_blue, "\e[38;5;72m"], - [ :cadet_blue, "\e[38;5;73m"], - [ :sky_blue_3, "\e[38;5;74m"], - [ :steel_blue_1, "\e[38;5;75m"], - [ :chartreuse_3, "\e[38;5;76m"], - [ :pale_green_3, "\e[38;5;77m"], - [ :sea_green_3, "\e[38;5;78m"], - [ :aquamarine_3, "\e[38;5;79m"], - [ :medium_turquoise, "\e[38;5;80m"], - [ :steel_blue_1, "\e[38;5;81m"], - [ :chartreuse_2, "\e[38;5;82m"], - [ :sea_green_2, "\e[38;5;83m"], - [ :sea_green_1, "\e[38;5;84m"], - [ :sea_green_1, "\e[38;5;85m"], - [ :aquamarine_1, "\e[38;5;86m"], - [ :dark_slate_gray_2, "\e[38;5;87m"], - [ :dark_red, "\e[38;5;88m"], - [ :deep_pink_4, "\e[38;5;89m"], - [ :dark_magenta, "\e[38;5;90m"], - [ :dark_magenta, "\e[38;5;91m"], - [ :dark_violet, "\e[38;5;92m"], - [ :purple, "\e[38;5;93m"], - [ :orange_4, "\e[38;5;94m"], - [ :light_pink_4, "\e[38;5;95m"], - [ :plum_4, "\e[38;5;96m"], - [ :medium_purple_3, "\e[38;5;97m"], - [ :medium_purple_3, "\e[38;5;98m"], - [ :slate_blue_1, "\e[38;5;99m"], - [ :yellow_4, "\e[38;5;100m"], - [ :wheat_4, "\e[38;5;101m"], - [ :grey_53, "\e[38;5;102m"], - [ :light_slate_grey, "\e[38;5;103m"], - [ :medium_purple, "\e[38;5;104m"], - [ :light_slate_blue, "\e[38;5;105m"], - [ :yellow_4, "\e[38;5;106m"], - [ :dark_olive_green_3, "\e[38;5;107m"], - [ :dark_sea_green, "\e[38;5;108m"], - [ :light_sky_blue_3, "\e[38;5;109m"], - [ :light_sky_blue_3, "\e[38;5;110m"], - [ :sky_blue_2, "\e[38;5;111m"], - [ :chartreuse_2, "\e[38;5;112m"], - [ :dark_olive_green_3, "\e[38;5;113m"], - [ :pale_green_3, "\e[38;5;114m"], - [ :dark_sea_green_3, "\e[38;5;115m"], - [ :dark_slate_gray_3, "\e[38;5;116m"], - [ :sky_blue_1, "\e[38;5;117m"], - [ :chartreuse_1, "\e[38;5;118m"], - [ :light_green_1, "\e[38;5;119m"], - [ :light_green_2, "\e[38;5;120m"], - [ :pale_green_1, "\e[38;5;121m"], - [ :aquamarine_1, "\e[38;5;122m"], - [ :dark_slate_gray_1, "\e[38;5;123m"], - [ :red_3, "\e[38;5;124m"], - [ :deep_pink_4, "\e[38;5;125m"], - [ :medium_violet_red, "\e[38;5;126m"], - [ :magenta_3, "\e[38;5;127m"], - [ :dark_violet, "\e[38;5;128m"], - [ :purple, "\e[38;5;129m"], - [ :dark_orange_3, "\e[38;5;130m"], - [ :indian_red, "\e[38;5;131m"], - [ :hot_pink_3, "\e[38;5;132m"], - [ :medium_orchid_3, "\e[38;5;133m"], - [ :medium_orchid, "\e[38;5;134m"], - [ :medium_purple_2, "\e[38;5;135m"], - [ :dark_goldenrod, "\e[38;5;136m"], - [ :light_salmon_3, "\e[38;5;137m"], - [ :rosy_brown, "\e[38;5;138m"], - [ :grey_63, "\e[38;5;139m"], - [ :medium_purple_2, "\e[38;5;140m"], - [ :medium_purple_1, "\e[38;5;141m"], - [ :gold_3, "\e[38;5;142m"], - [ :dark_khaki, "\e[38;5;143m"], - [ :navajo_white_3, "\e[38;5;144m"], - [ :grey_69, "\e[38;5;145m"], - [ :light_steel_blue_3, "\e[38;5;146m"], - [ :light_steel_blue, "\e[38;5;147m"], - [ :yellow_3, "\e[38;5;148m"], - [ :dark_olive_green_3, "\e[38;5;149m"], - [ :dark_sea_green_3, "\e[38;5;150m"], - [ :dark_sea_green_2, "\e[38;5;151m"], - [ :light_cyan_3, "\e[38;5;152m"], - [ :light_sky_blue_1, "\e[38;5;153m"], - [ :green_yellow, "\e[38;5;154m"], - [ :dark_olive_green_2, "\e[38;5;155m"], - [ :pale_green_1, "\e[38;5;156m"], - [ :dark_sea_green_2, "\e[38;5;157m"], - [ :dark_sea_green_1, "\e[38;5;158m"], - [ :pale_turquoise_1, "\e[38;5;159m"], - [ :red_3, "\e[38;5;160m"], - [ :deep_pink_3, "\e[38;5;161m"], - [ :deep_pink_3, "\e[38;5;162m"], - [ :magenta_3, "\e[38;5;163m"], - [ :magenta_3, "\e[38;5;164m"], - [ :magenta_2, "\e[38;5;165m"], - [ :dark_orange_3, "\e[38;5;166m"], - [ :indian_red, "\e[38;5;167m"], - [ :hot_pink_3, "\e[38;5;168m"], - [ :hot_pink_2, "\e[38;5;169m"], - [ :orchid, "\e[38;5;170m"], - [ :medium_orchid_1, "\e[38;5;171m"], - [ :orange_3, "\e[38;5;172m"], - [ :light_salmon_3, "\e[38;5;173m"], - [ :light_pink_3, "\e[38;5;174m"], - [ :pink_3, "\e[38;5;175m"], - [ :plum_3, "\e[38;5;176m"], - [ :violet, "\e[38;5;177m"], - [ :gold_3, "\e[38;5;178m"], - [ :light_goldenrod_3, "\e[38;5;179m"], - [ :tan, "\e[38;5;180m"], - [ :misty_rose_3, "\e[38;5;181m"], - [ :thistle_3, "\e[38;5;182m"], - [ :plum_2, "\e[38;5;183m"], - [ :yellow_3, "\e[38;5;184m"], - [ :khaki_3, "\e[38;5;185m"], - [ :light_goldenrod_2, "\e[38;5;186m"], - [ :light_yellow_3, "\e[38;5;187m"], - [ :grey_84, "\e[38;5;188m"], - [ :light_steel_blue_1, "\e[38;5;189m"], - [ :yellow_2, "\e[38;5;190m"], - [ :dark_olive_green_1, "\e[38;5;191m"], - [ :dark_olive_green_1, "\e[38;5;192m"], - [ :dark_sea_green_1, "\e[38;5;193m"], - [ :honeydew_2, "\e[38;5;194m"], - [ :light_cyan_1, "\e[38;5;195m"], - [ :red_1, "\e[38;5;196m"], - [ :deep_pink_2, "\e[38;5;197m"], - [ :deep_pink_1, "\e[38;5;198m"], - [ :deep_pink_1, "\e[38;5;199m"], - [ :magenta_2, "\e[38;5;200m"], - [ :magenta_1, "\e[38;5;201m"], - [ :orange_red_1, "\e[38;5;202m"], - [ :indian_red_1, "\e[38;5;203m"], - [ :indian_red_1, "\e[38;5;204m"], - [ :hot_pink, "\e[38;5;205m"], - [ :hot_pink, "\e[38;5;206m"], - [ :medium_orchid_1, "\e[38;5;207m"], - [ :dark_orange, "\e[38;5;208m"], - [ :salmon_1, "\e[38;5;209m"], - [ :light_coral, "\e[38;5;210m"], - [ :pale_violet_red_1, "\e[38;5;211m"], - [ :orchid_2, "\e[38;5;212m"], - [ :orchid_1, "\e[38;5;213m"], - [ :orange_1, "\e[38;5;214m"], - [ :sandy_brown, "\e[38;5;215m"], - [ :light_salmon_1, "\e[38;5;216m"], - [ :light_pink_1, "\e[38;5;217m"], - [ :pink_1, "\e[38;5;218m"], - [ :plum_1, "\e[38;5;219m"], - [ :gold_1, "\e[38;5;220m"], - [ :light_goldenrod_2, "\e[38;5;221m"], - [ :light_goldenrod_2, "\e[38;5;222m"], - [ :navajo_white_1, "\e[38;5;223m"], - [ :misty_rose_1, "\e[38;5;224m"], - [ :thistle_1, "\e[38;5;225m"], - [ :yellow_1, "\e[38;5;226m"], - [ :light_goldenrod_1, "\e[38;5;227m"], - [ :khaki_1, "\e[38;5;228m"], - [ :wheat_1, "\e[38;5;229m"], - [ :cornsilk_1, "\e[38;5;230m"], - [ :grey_100, "\e[38;5;231m"], - [ :grey_3, "\e[38;5;232m"], - [ :grey_7, "\e[38;5;233m"], - [ :grey_11, "\e[38;5;234m"], - [ :grey_15, "\e[38;5;235m"], - [ :grey_19, "\e[38;5;236m"], - [ :grey_23, "\e[38;5;237m"], - [ :grey_27, "\e[38;5;238m"], - [ :grey_30, "\e[38;5;239m"], - [ :grey_35, "\e[38;5;240m"], - [ :grey_39, "\e[38;5;241m"], - [ :grey_42, "\e[38;5;242m"], - [ :grey_46, "\e[38;5;243m"], - [ :grey_50, "\e[38;5;244m"], - [ :grey_54, "\e[38;5;245m"], - [ :grey_58, "\e[38;5;246m"], - [ :grey_62, "\e[38;5;247m"], - [ :grey_66, "\e[38;5;248m"], - [ :grey_70, "\e[38;5;249m"], - [ :grey_74, "\e[38;5;250m"], - [ :grey_78, "\e[38;5;251m"], - [ :grey_82, "\e[38;5;252m"], - [ :grey_85, "\e[38;5;253m"], - [ :grey_89, "\e[38;5;254m"], - [ :grey_93, "\e[38;5;255m"] + [ :grey0, 0], + [ :maroon, 1], + [ :green, 2], + [ :olive, 3], + [ :navy, 4], + [ :purple, 5], + [ :teal, 6], + [ :silver, 7], + [ :grey, 8], + [ :red, 9], + [ :lime, 10], + [ :yellow, 11], + [ :blue, 12], + [ :fuchsia, 13], + [ :aqua, 14], + [ :white, 15], + [ :black, 16], + [ :navyblue, 17], + [ :darkblue, 18], + [ :blue3, 19], + [ :blue3, 20], + [ :blue1, 21], + [ :darkgreen, 22], + [ :deepskyblue4, 23], + [ :deepskyblue4, 24], + [ :deepskyblue4, 25], + [ :dodgerblue3, 26], + [ :dodgerblue2, 27], + [ :green4, 28], + [ :springgreen4, 29], + [ :turquoise4, 30], + [ :deepskyblue3, 31], + [ :deepskyblue3, 32], + [ :dodgerblue1, 33], + [ :green3, 34], + [ :springgreen3, 35], + [ :darkcyan, 36], + [ :lightseagreen, 37], + [ :deepskyblue2, 38], + [ :deepskyblue1, 39], + [ :green3, 40], + [ :springgreen3, 41], + [ :springgreen2, 42], + [ :cyan3, 43], + [ :darkturquoise, 44], + [ :turquoise2, 45], + [ :green1, 46], + [ :springgreen2, 47], + [ :springgreen1, 48], + [ :mediumspringgreen, 49], + [ :cyan2, 50], + [ :cyan1, 51], + [ :cyan, 51], + [ :darkred, 52], + [ :deeppink4, 53], + [ :purple4, 54], + [ :purple4, 55], + [ :purple3, 56], + [ :blueviolet, 57], + [ :orange4, 58], + [ :grey37, 59], + [ :mediumpurple4, 60], + [ :slateblue3, 61], + [ :slateblue3, 62], + [ :royalblue1, 63], + [ :chartreuse4, 64], + [ :darkseagreen4, 65], + [ :paleturquoise4, 66], + [ :steelblue, 67], + [ :steelblue3, 68], + [ :cornflowerblue, 69], + [ :chartreuse3, 70], + [ :darkseagreen4, 71], + [ :cadetblue, 72], + [ :cadetblue, 73], + [ :skyblue3, 74], + [ :steelblue1, 75], + [ :chartreuse3, 76], + [ :palegreen3, 77], + [ :seagreen3, 78], + [ :aquamarine3, 79], + [ :mediumturquoise, 80], + [ :steelblue1, 81], + [ :chartreuse2, 82], + [ :seagreen2, 83], + [ :seagreen1, 84], + [ :seagreen1, 85], + [ :aquamarine1, 86], + [ :darkslategray2, 87], + [ :darkred, 88], + [ :deeppink4, 89], + [ :darkmagenta, 90], + [ :darkmagenta, 91], + [ :darkviolet, 92], + [ :purple, 93], + [ :orange4, 94], + [ :lightpink4, 95], + [ :plum4, 96], + [ :mediumpurple3, 97], + [ :mediumpurple3, 98], + [ :slateblue1, 99], + [ :yellow4, 100], + [ :wheat4, 101], + [ :grey53, 102], + [ :lightslategrey, 103], + [ :mediumpurple, 104], + [ :lightslateblue, 105], + [ :yellow4, 106], + [ :darkolivegreen3, 107], + [ :darkseagreen, 108], + [ :lightskyblue3, 109], + [ :lightskyblue3, 110], + [ :skyblue2, 111], + [ :chartreuse2, 112], + [ :darkolivegreen3, 113], + [ :palegreen3, 114], + [ :darkseagreen3, 115], + [ :darkslategray3, 116], + [ :skyblue1, 117], + [ :chartreuse1, 118], + [ :lightgreen, 119], + [ :lightgreen, 120], + [ :palegreen1, 121], + [ :aquamarine1, 122], + [ :darkslategray1, 123], + [ :red3, 124], + [ :deeppink4, 125], + [ :mediumvioletred, 126], + [ :magenta3, 127], + [ :darkviolet, 128], + [ :purple, 129], + [ :darkorange3, 130], + [ :indianred, 131], + [ :hotpink3, 132], + [ :mediumorchid3, 133], + [ :mediumorchid, 134], + [ :mediumpurple2, 135], + [ :darkgoldenrod, 136], + [ :lightsalmon3, 137], + [ :rosybrown, 138], + [ :grey63, 139], + [ :mediumpurple2, 140], + [ :mediumpurple1, 141], + [ :gold3, 142], + [ :darkkhaki, 143], + [ :navajowhite3, 144], + [ :grey69, 145], + [ :lightsteelblue3, 146], + [ :lightsteelblue, 147], + [ :yellow3, 148], + [ :darkolivegreen3, 149], + [ :darkseagreen3, 150], + [ :darkseagreen2, 151], + [ :lightcyan3, 152], + [ :lightskyblue1, 153], + [ :greenyellow, 154], + [ :darkolivegreen2, 155], + [ :palegreen1, 156], + [ :darkseagreen2, 157], + [ :darkseagreen1, 158], + [ :paleturquoise1, 159], + [ :red3, 160], + [ :deeppink3, 161], + [ :deeppink3, 162], + [ :magenta3, 163], + [ :magenta3, 164], + [ :magenta2, 165], + [ :darkorange3, 166], + [ :indianred, 167], + [ :hotpink3, 168], + [ :hotpink2, 169], + [ :orchid, 170], + [ :mediumorchid1, 171], + [ :orange3, 172], + [ :lightsalmon3, 173], + [ :lightpink3, 174], + [ :pink3, 175], + [ :plum3, 176], + [ :violet, 177], + [ :gold3, 178], + [ :lightgoldenrod3, 179], + [ :tan, 180], + [ :mistyrose3, 181], + [ :thistle3, 182], + [ :plum2, 183], + [ :yellow3, 184], + [ :khaki3, 185], + [ :lightgoldenrod2, 186], + [ :lightyellow3, 187], + [ :grey84, 188], + [ :lightsteelblue1, 189], + [ :yellow2, 190], + [ :darkolivegreen1, 191], + [ :darkolivegreen1, 192], + [ :darkseagreen1, 193], + [ :honeydew2, 194], + [ :lightcyan1, 195], + [ :red1, 196], + [ :deeppink2, 197], + [ :deeppink1, 198], + [ :deeppink1, 199], + [ :magenta2, 200], + [ :magenta1, 201], + [ :magenta, 201], + [ :orangered1, 202], + [ :indianred1, 203], + [ :indianred1, 204], + [ :hotpink, 205], + [ :hotpink, 206], + [ :mediumorchid1, 207], + [ :darkorange, 208], + [ :salmon1, 209], + [ :lightcoral, 210], + [ :palevioletred1, 211], + [ :orchid2, 212], + [ :orchid1, 213], + [ :orange1, 214], + [ :sandybrown, 215], + [ :lightsalmon1, 216], + [ :lightpink1, 217], + [ :pink1, 218], + [ :plum1, 219], + [ :gold1, 220], + [ :lightgoldenrod2, 221], + [ :lightgoldenrod2, 222], + [ :navajowhite1, 223], + [ :mistyrose1, 224], + [ :thistle1, 225], + [ :yellow1, 226], + [ :lightgoldenrod1, 227], + [ :khaki1, 228], + [ :wheat1, 229], + [ :cornsilk1, 230], + [ :grey100, 231], + [ :grey3, 232], + [ :grey7, 233], + [ :grey11, 234], + [ :grey15, 235], + [ :grey19, 236], + [ :grey23, 237], + [ :grey27, 238], + [ :grey30, 239], + [ :grey35, 240], + [ :grey39, 241], + [ :grey42, 242], + [ :grey46, 243], + [ :grey50, 244], + [ :grey54, 245], + [ :grey58, 246], + [ :grey62, 247], + [ :grey66, 248], + [ :grey70, 249], + [ :grey74, 250], + [ :grey78, 251], + [ :grey82, 252], + [ :grey85, 253], + [ :grey89, 254], + [ :grey93, 255], ] @@attributes.each do |c, v| eval %Q{ @@ -375,12 +281,12 @@ module Color end } end - + module_function def attributes @@attributes.map { |c| c.first } end - + def attribute att @@attributes.each do |e| return e.last if e.first.eql? att @@ -389,277 +295,269 @@ module Color end extend self end - + module Background @@attributes = [ - [ :magenta, "\e[45m"], - [ :cyan, "\e[46m"], - [ :light_gray, "\e[47m"], - [ :dark_gray, "\e[100m"], - [ :light_red, "\e[101m"], - [ :light_green, "\e[102m"], - [ :light_yellow, "\e[103m"], - [ :light_blue, "\e[104m"], - [ :light_magenta, "\e[105m"], - [ :light_cyan, "\e[106m"], - [ :black, "\e[48;5;0m"], - [ :maroon, "\e[48;5;1m"], - [ :green, "\e[48;5;2m"], - [ :olive, "\e[48;5;3m"], - [ :navy, "\e[48;5;4m"], - [ :purple, "\e[48;5;5m"], - [ :teal, "\e[48;5;6m"], - [ :silver, "\e[48;5;7m"], - [ :grey, "\e[48;5;8m"], - [ :red, "\e[48;5;9m"], - [ :lime, "\e[48;5;10m"], - [ :yellow, "\e[48;5;11m"], - [ :blue, "\e[48;5;12m"], - [ :fuchsia, "\e[48;5;13m"], - [ :aqua, "\e[48;5;14m"], - [ :white, "\e[48;5;15m"], - [ :grey_0, "\e[48;5;16m"], - [ :navy_blue, "\e[48;5;17m"], - [ :dark_blue, "\e[48;5;18m"], - [ :blue_3, "\e[48;5;19m"], - [ :blue_3, "\e[48;5;20m"], - [ :blue_1, "\e[48;5;21m"], - [ :dark_green, "\e[48;5;22m"], - [ :deep_sky_blue_4, "\e[48;5;23m"], - [ :deep_sky_blue_4, "\e[48;5;24m"], - [ :deep_sky_blue_4, "\e[48;5;25m"], - [ :dodger_blue_3, "\e[48;5;26m"], - [ :dodger_blue_2, "\e[48;5;27m"], - [ :green_4, "\e[48;5;28m"], - [ :spring_green_4, "\e[48;5;29m"], - [ :turquoise_4, "\e[48;5;30m"], - [ :deep_sky_blue_3, "\e[48;5;31m"], - [ :deep_sky_blue_3, "\e[48;5;32m"], - [ :dodger_blue_1, "\e[48;5;33m"], - [ :green_3, "\e[48;5;34m"], - [ :spring_green_3, "\e[48;5;35m"], - [ :dark_cyan, "\e[48;5;36m"], - [ :light_sea_green, "\e[48;5;37m"], - [ :deep_sky_blue_2, "\e[48;5;38m"], - [ :deep_sky_blue_1, "\e[48;5;39m"], - [ :green_3, "\e[48;5;40m"], - [ :spring_green_3, "\e[48;5;41m"], - [ :spring_green_2, "\e[48;5;42m"], - [ :cyan_3, "\e[48;5;43m"], - [ :dark_turquoise, "\e[48;5;44m"], - [ :turquoise_2, "\e[48;5;45m"], - [ :green_1, "\e[48;5;46m"], - [ :spring_green_2, "\e[48;5;47m"], - [ :spring_green_1, "\e[48;5;48m"], - [ :medium_spring_green, "\e[48;5;49m"], - [ :cyan_2, "\e[48;5;50m"], - [ :cyan_1, "\e[48;5;51m"], - [ :dark_red, "\e[48;5;52m"], - [ :deep_pink_4, "\e[48;5;53m"], - [ :purple_4, "\e[48;5;54m"], - [ :purple_4, "\e[48;5;55m"], - [ :purple_3, "\e[48;5;56m"], - [ :blue_violet, "\e[48;5;57m"], - [ :orange_4, "\e[48;5;58m"], - [ :grey_37, "\e[48;5;59m"], - [ :medium_purple_4, "\e[48;5;60m"], - [ :slate_blue_3, "\e[48;5;61m"], - [ :slate_blue_3, "\e[48;5;62m"], - [ :royal_blue_1, "\e[48;5;63m"], - [ :chartreuse_4, "\e[48;5;64m"], - [ :dark_sea_green_4, "\e[48;5;65m"], - [ :pale_turquoise_4, "\e[48;5;66m"], - [ :steel_blue, "\e[48;5;67m"], - [ :steel_blue_3, "\e[48;5;68m"], - [ :cornflower_blue, "\e[48;5;69m"], - [ :chartreuse_3, "\e[48;5;70m"], - [ :dark_sea_green_4, "\e[48;5;71m"], - [ :cadet_blue, "\e[48;5;72m"], - [ :cadet_blue, "\e[48;5;73m"], - [ :sky_blue_3, "\e[48;5;74m"], - [ :steel_blue_1, "\e[48;5;75m"], - [ :chartreuse_3, "\e[48;5;76m"], - [ :pale_green_3, "\e[48;5;77m"], - [ :sea_green_3, "\e[48;5;78m"], - [ :aquamarine_3, "\e[48;5;79m"], - [ :medium_turquoise, "\e[48;5;80m"], - [ :steel_blue_1, "\e[48;5;81m"], - [ :chartreuse_2, "\e[48;5;82m"], - [ :sea_green_2, "\e[48;5;83m"], - [ :sea_green_1, "\e[48;5;84m"], - [ :sea_green_1, "\e[48;5;85m"], - [ :aquamarine_1, "\e[48;5;86m"], - [ :dark_slate_gray_2, "\e[48;5;87m"], - [ :dark_red, "\e[48;5;88m"], - [ :deep_pink_4, "\e[48;5;89m"], - [ :dark_magenta, "\e[48;5;90m"], - [ :dark_magenta, "\e[48;5;91m"], - [ :dark_violet, "\e[48;5;92m"], - [ :purple, "\e[48;5;93m"], - [ :orange_4, "\e[48;5;94m"], - [ :light_pink_4, "\e[48;5;95m"], - [ :plum_4, "\e[48;5;96m"], - [ :medium_purple_3, "\e[48;5;97m"], - [ :medium_purple_3, "\e[48;5;98m"], - [ :slate_blue_1, "\e[48;5;99m"], - [ :yellow_4, "\e[48;5;100m"], - [ :wheat_4, "\e[48;5;101m"], - [ :grey_53, "\e[48;5;102m"], - [ :light_slate_grey, "\e[48;5;103m"], - [ :medium_purple, "\e[48;5;104m"], - [ :light_slate_blue, "\e[48;5;105m"], - [ :yellow_4, "\e[48;5;106m"], - [ :dark_olive_green_3, "\e[48;5;107m"], - [ :dark_sea_green, "\e[48;5;108m"], - [ :light_sky_blue_3, "\e[48;5;109m"], - [ :light_sky_blue_3, "\e[48;5;110m"], - [ :sky_blue_2, "\e[48;5;111m"], - [ :chartreuse_2, "\e[48;5;112m"], - [ :dark_olive_green_3, "\e[48;5;113m"], - [ :pale_green_3, "\e[48;5;114m"], - [ :dark_sea_green_3, "\e[48;5;115m"], - [ :dark_slate_gray_3, "\e[48;5;116m"], - [ :sky_blue_1, "\e[48;5;117m"], - [ :chartreuse_1, "\e[48;5;118m"], - [ :light_green_1, "\e[48;5;119m"], - [ :light_green_2, "\e[48;5;120m"], - [ :pale_green_1, "\e[48;5;121m"], - [ :aquamarine_1, "\e[48;5;122m"], - [ :dark_slate_gray_1, "\e[48;5;123m"], - [ :red_3, "\e[48;5;124m"], - [ :deep_pink_4, "\e[48;5;125m"], - [ :medium_violet_red, "\e[48;5;126m"], - [ :magenta_3, "\e[48;5;127m"], - [ :dark_violet, "\e[48;5;128m"], - [ :purple, "\e[48;5;129m"], - [ :dark_orange_3, "\e[48;5;130m"], - [ :indian_red, "\e[48;5;131m"], - [ :hot_pink_3, "\e[48;5;132m"], - [ :medium_orchid_3, "\e[48;5;133m"], - [ :medium_orchid, "\e[48;5;134m"], - [ :medium_purple_2, "\e[48;5;135m"], - [ :dark_goldenrod, "\e[48;5;136m"], - [ :light_salmon_3, "\e[48;5;137m"], - [ :rosy_brown, "\e[48;5;138m"], - [ :grey_63, "\e[48;5;139m"], - [ :medium_purple_2, "\e[48;5;140m"], - [ :medium_purple_1, "\e[48;5;141m"], - [ :gold_3, "\e[48;5;142m"], - [ :dark_khaki, "\e[48;5;143m"], - [ :navajo_white_3, "\e[48;5;144m"], - [ :grey_69, "\e[48;5;145m"], - [ :light_steel_blue_3, "\e[48;5;146m"], - [ :light_steel_blue, "\e[48;5;147m"], - [ :yellow_3, "\e[48;5;148m"], - [ :dark_olive_green_3, "\e[48;5;149m"], - [ :dark_sea_green_3, "\e[48;5;150m"], - [ :dark_sea_green_2, "\e[48;5;151m"], - [ :light_cyan_3, "\e[48;5;152m"], - [ :light_sky_blue_1, "\e[48;5;153m"], - [ :green_yellow, "\e[48;5;154m"], - [ :dark_olive_green_2, "\e[48;5;155m"], - [ :pale_green_1, "\e[48;5;156m"], - [ :dark_sea_green_2, "\e[48;5;157m"], - [ :dark_sea_green_1, "\e[48;5;158m"], - [ :pale_turquoise_1, "\e[48;5;159m"], - [ :red_3, "\e[48;5;160m"], - [ :deep_pink_3, "\e[48;5;161m"], - [ :deep_pink_3, "\e[48;5;162m"], - [ :magenta_3, "\e[48;5;163m"], - [ :magenta_3, "\e[48;5;164m"], - [ :magenta_2, "\e[48;5;165m"], - [ :dark_orange_3, "\e[48;5;166m"], - [ :indian_red, "\e[48;5;167m"], - [ :hot_pink_3, "\e[48;5;168m"], - [ :hot_pink_2, "\e[48;5;169m"], - [ :orchid, "\e[48;5;170m"], - [ :medium_orchid_1, "\e[48;5;171m"], - [ :orange_3, "\e[48;5;172m"], - [ :light_salmon_3, "\e[48;5;173m"], - [ :light_pink_3, "\e[48;5;174m"], - [ :pink_3, "\e[48;5;175m"], - [ :plum_3, "\e[48;5;176m"], - [ :violet, "\e[48;5;177m"], - [ :gold_3, "\e[48;5;178m"], - [ :light_goldenrod_3, "\e[48;5;179m"], - [ :tan, "\e[48;5;180m"], - [ :misty_rose_3, "\e[48;5;181m"], - [ :thistle_3, "\e[48;5;182m"], - [ :plum_2, "\e[48;5;183m"], - [ :yellow_3, "\e[48;5;184m"], - [ :khaki_3, "\e[48;5;185m"], - [ :light_goldenrod_2, "\e[48;5;186m"], - [ :light_yellow_3, "\e[48;5;187m"], - [ :grey_84, "\e[48;5;188m"], - [ :light_steel_blue_1, "\e[48;5;189m"], - [ :yellow_2, "\e[48;5;190m"], - [ :dark_olive_green_1, "\e[48;5;191m"], - [ :dark_olive_green_1, "\e[48;5;192m"], - [ :dark_sea_green_1, "\e[48;5;193m"], - [ :honeydew_2, "\e[48;5;194m"], - [ :light_cyan_1, "\e[48;5;195m"], - [ :red_1, "\e[48;5;196m"], - [ :deep_pink_2, "\e[48;5;197m"], - [ :deep_pink_1, "\e[48;5;198m"], - [ :deep_pink_1, "\e[48;5;199m"], - [ :magenta_2, "\e[48;5;200m"], - [ :magenta_1, "\e[48;5;201m"], - [ :orange_red_1, "\e[48;5;202m"], - [ :indian_red_1, "\e[48;5;203m"], - [ :indian_red_1, "\e[48;5;204m"], - [ :hot_pink, "\e[48;5;205m"], - [ :hot_pink, "\e[48;5;206m"], - [ :medium_orchid_1, "\e[48;5;207m"], - [ :dark_orange, "\e[48;5;208m"], - [ :salmon_1, "\e[48;5;209m"], - [ :light_coral, "\e[48;5;210m"], - [ :pale_violet_red_1, "\e[48;5;211m"], - [ :orchid_2, "\e[48;5;212m"], - [ :orchid_1, "\e[48;5;213m"], - [ :orange_1, "\e[48;5;214m"], - [ :sandy_brown, "\e[48;5;215m"], - [ :light_salmon_1, "\e[48;5;216m"], - [ :light_pink_1, "\e[48;5;217m"], - [ :pink_1, "\e[48;5;218m"], - [ :plum_1, "\e[48;5;219m"], - [ :gold_1, "\e[48;5;220m"], - [ :light_goldenrod_2, "\e[48;5;221m"], - [ :light_goldenrod_2, "\e[48;5;222m"], - [ :navajo_white_1, "\e[48;5;223m"], - [ :misty_rose_1, "\e[48;5;224m"], - [ :thistle_1, "\e[48;5;225m"], - [ :yellow_1, "\e[48;5;226m"], - [ :light_goldenrod_1, "\e[48;5;227m"], - [ :khaki_1, "\e[48;5;228m"], - [ :wheat_1, "\e[48;5;229m"], - [ :cornsilk_1, "\e[48;5;230m"], - [ :grey_100, "\e[48;5;231m"], - [ :grey_3, "\e[48;5;232m"], - [ :grey_7, "\e[48;5;233m"], - [ :grey_11, "\e[48;5;234m"], - [ :grey_15, "\e[48;5;235m"], - [ :grey_19, "\e[48;5;236m"], - [ :grey_23, "\e[48;5;237m"], - [ :grey_27, "\e[48;5;238m"], - [ :grey_30, "\e[48;5;239m"], - [ :grey_35, "\e[48;5;240m"], - [ :grey_39, "\e[48;5;241m"], - [ :grey_42, "\e[48;5;242m"], - [ :grey_46, "\e[48;5;243m"], - [ :grey_50, "\e[48;5;244m"], - [ :grey_54, "\e[48;5;245m"], - [ :grey_58, "\e[48;5;246m"], - [ :grey_62, "\e[48;5;247m"], - [ :grey_66, "\e[48;5;248m"], - [ :grey_70, "\e[48;5;249m"], - [ :grey_74, "\e[48;5;250m"], - [ :grey_78, "\e[48;5;251m"], - [ :grey_82, "\e[48;5;252m"], - [ :grey_85, "\e[48;5;253m"], - [ :grey_89, "\e[48;5;254m"], - [ :grey_93, "\e[48;5;255m"] + [ :grey0, 0], + [ :maroon, 1], + [ :green, 2], + [ :olive, 3], + [ :navy, 4], + [ :purple, 5], + [ :teal, 6], + [ :silver, 7], + [ :grey, 8], + [ :red, 9], + [ :lime, 10], + [ :yellow, 11], + [ :blue, 12], + [ :fuchsia, 13], + [ :aqua, 14], + [ :white, 15], + [ :black, 16], + [ :navyblue, 17], + [ :darkblue, 18], + [ :blue3, 19], + [ :blue3, 20], + [ :blue1, 21], + [ :darkgreen, 22], + [ :deepskyblue4, 23], + [ :deepskyblue4, 24], + [ :deepskyblue4, 25], + [ :dodgerblue3, 26], + [ :dodgerblue2, 27], + [ :green4, 28], + [ :springgreen4, 29], + [ :turquoise4, 30], + [ :deepskyblue3, 31], + [ :deepskyblue3, 32], + [ :dodgerblue1, 33], + [ :green3, 34], + [ :springgreen3, 35], + [ :darkcyan, 36], + [ :lightseagreen, 37], + [ :deepskyblue2, 38], + [ :deepskyblue1, 39], + [ :green3, 40], + [ :springgreen3, 41], + [ :springgreen2, 42], + [ :cyan3, 43], + [ :darkturquoise, 44], + [ :turquoise2, 45], + [ :green1, 46], + [ :springgreen2, 47], + [ :springgreen1, 48], + [ :mediumspringgreen, 49], + [ :cyan2, 50], + [ :cyan1, 51], + [ :cyan, 51], + [ :darkred, 52], + [ :deeppink4, 53], + [ :purple4, 54], + [ :purple4, 55], + [ :purple3, 56], + [ :blueviolet, 57], + [ :orange4, 58], + [ :grey37, 59], + [ :mediumpurple4, 60], + [ :slateblue3, 61], + [ :slateblue3, 62], + [ :royalblue1, 63], + [ :chartreuse4, 64], + [ :darkseagreen4, 65], + [ :paleturquoise4, 66], + [ :steelblue, 67], + [ :steelblue3, 68], + [ :cornflowerblue, 69], + [ :chartreuse3, 70], + [ :darkseagreen4, 71], + [ :cadetblue, 72], + [ :cadetblue, 73], + [ :skyblue3, 74], + [ :steelblue1, 75], + [ :chartreuse3, 76], + [ :palegreen3, 77], + [ :seagreen3, 78], + [ :aquamarine3, 79], + [ :mediumturquoise, 80], + [ :steelblue1, 81], + [ :chartreuse2, 82], + [ :seagreen2, 83], + [ :seagreen1, 84], + [ :seagreen1, 85], + [ :aquamarine1, 86], + [ :darkslategray2, 87], + [ :darkred, 88], + [ :deeppink4, 89], + [ :darkmagenta, 90], + [ :darkmagenta, 91], + [ :darkviolet, 92], + [ :purple, 93], + [ :orange4, 94], + [ :lightpink4, 95], + [ :plum4, 96], + [ :mediumpurple3, 97], + [ :mediumpurple3, 98], + [ :slateblue1, 99], + [ :yellow4, 100], + [ :wheat4, 101], + [ :grey53, 102], + [ :lightslategrey, 103], + [ :mediumpurple, 104], + [ :lightslateblue, 105], + [ :yellow4, 106], + [ :darkolivegreen3, 107], + [ :darkseagreen, 108], + [ :lightskyblue3, 109], + [ :lightskyblue3, 110], + [ :skyblue2, 111], + [ :chartreuse2, 112], + [ :darkolivegreen3, 113], + [ :palegreen3, 114], + [ :darkseagreen3, 115], + [ :darkslategray3, 116], + [ :skyblue1, 117], + [ :chartreuse1, 118], + [ :lightgreen, 119], + [ :lightgreen, 120], + [ :palegreen1, 121], + [ :aquamarine1, 122], + [ :darkslategray1, 123], + [ :red3, 124], + [ :deeppink4, 125], + [ :mediumvioletred, 126], + [ :magenta3, 127], + [ :darkviolet, 128], + [ :purple, 129], + [ :darkorange3, 130], + [ :indianred, 131], + [ :hotpink3, 132], + [ :mediumorchid3, 133], + [ :mediumorchid, 134], + [ :mediumpurple2, 135], + [ :darkgoldenrod, 136], + [ :lightsalmon3, 137], + [ :rosybrown, 138], + [ :grey63, 139], + [ :mediumpurple2, 140], + [ :mediumpurple1, 141], + [ :gold3, 142], + [ :darkkhaki, 143], + [ :navajowhite3, 144], + [ :grey69, 145], + [ :lightsteelblue3, 146], + [ :lightsteelblue, 147], + [ :yellow3, 148], + [ :darkolivegreen3, 149], + [ :darkseagreen3, 150], + [ :darkseagreen2, 151], + [ :lightcyan3, 152], + [ :lightskyblue1, 153], + [ :greenyellow, 154], + [ :darkolivegreen2, 155], + [ :palegreen1, 156], + [ :darkseagreen2, 157], + [ :darkseagreen1, 158], + [ :paleturquoise1, 159], + [ :red3, 160], + [ :deeppink3, 161], + [ :deeppink3, 162], + [ :magenta3, 163], + [ :magenta3, 164], + [ :magenta2, 165], + [ :darkorange3, 166], + [ :indianred, 167], + [ :hotpink3, 168], + [ :hotpink2, 169], + [ :orchid, 170], + [ :mediumorchid1, 171], + [ :orange3, 172], + [ :lightsalmon3, 173], + [ :lightpink3, 174], + [ :pink3, 175], + [ :plum3, 176], + [ :violet, 177], + [ :gold3, 178], + [ :lightgoldenrod3, 179], + [ :tan, 180], + [ :mistyrose3, 181], + [ :thistle3, 182], + [ :plum2, 183], + [ :yellow3, 184], + [ :khaki3, 185], + [ :lightgoldenrod2, 186], + [ :lightyellow3, 187], + [ :grey84, 188], + [ :lightsteelblue1, 189], + [ :yellow2, 190], + [ :darkolivegreen1, 191], + [ :darkolivegreen1, 192], + [ :darkseagreen1, 193], + [ :honeydew2, 194], + [ :lightcyan1, 195], + [ :red1, 196], + [ :deeppink2, 197], + [ :deeppink1, 198], + [ :deeppink1, 199], + [ :magenta2, 200], + [ :magenta1, 201], + [ :magenta, 201], + [ :orangered1, 202], + [ :indianred1, 203], + [ :indianred1, 204], + [ :hotpink, 205], + [ :hotpink, 206], + [ :mediumorchid1, 207], + [ :darkorange, 208], + [ :salmon1, 209], + [ :lightcoral, 210], + [ :palevioletred1, 211], + [ :orchid2, 212], + [ :orchid1, 213], + [ :orange1, 214], + [ :sandybrown, 215], + [ :lightsalmon1, 216], + [ :lightpink1, 217], + [ :pink1, 218], + [ :plum1, 219], + [ :gold1, 220], + [ :lightgoldenrod2, 221], + [ :lightgoldenrod2, 222], + [ :navajowhite1, 223], + [ :mistyrose1, 224], + [ :thistle1, 225], + [ :yellow1, 226], + [ :lightgoldenrod1, 227], + [ :khaki1, 228], + [ :wheat1, 229], + [ :cornsilk1, 230], + [ :grey100, 231], + [ :grey3, 232], + [ :grey7, 233], + [ :grey11, 234], + [ :grey15, 235], + [ :grey19, 236], + [ :grey23, 237], + [ :grey27, 238], + [ :grey30, 239], + [ :grey35, 240], + [ :grey39, 241], + [ :grey42, 242], + [ :grey46, 243], + [ :grey50, 244], + [ :grey54, 245], + [ :grey58, 246], + [ :grey62, 247], + [ :grey66, 248], + [ :grey70, 249], + [ :grey74, 250], + [ :grey78, 251], + [ :grey82, 252], + [ :grey85, 253], + [ :grey89, 254], + [ :grey93, 255], ] - + @@attributes.each do |c, v| eval %Q{ def #{c}(string = nil) @@ -679,12 +577,12 @@ module Color end } end - + module_function def attributes @@attributes.map { |c| c.first } end - + def attribute att @@attributes.each do |e| return e.last if e.first.eql? att @@ -697,40 +595,76 @@ end class FormatState attr_reader :parent - - def initialize(parent = nil, fg: nil, bg: nil, blink: nil, dim: nil, underlined: nil, bold: nil, reversed: nil) + + def initialize(activate_color, parent = nil, fg: nil, bg: nil, blink: nil, dim: nil, underline: nil, bold: nil, reverse: nil, standout: nil) + @activate_color = activate_color @parent = parent - @fg = fg - @bg = bg + + if fg.is_a? String + if fg.scan(/\D/).empty? + @fg = fg.to_i + else + @fg = Color::Foreground.attribute(fg.to_sym) + end + else + @fg = fg + end + + if bg.is_a? String + if bg.scan(/\D/).empty? + @bg = bg.to_i + else + @bg = Color::Foreground.attribute(bg.to_sym) + end + else + @bg = bg + end + @blink = blink @dim = dim - @underlined = underlined + @underline = underline @bold = bold - @reversed = reversed + @reverse = reverse + @standout = standout end - - def initialize(code, parent = nil) + + def initialize(code, activate_color, parent = nil) + @activate_color = activate_color @parent = parent code_working = code.dup - + code_working.gsub!(/\s\s*/i) do |match| " " end - + fg_text = code_working[/fg\:([a-zA-Z0-9\_]*)\s*/i, 1].dup code_working.gsub!(/fg\:([a-zA-Z0-9\_]*)\s*/i) do |match| "" end - + bg_text = code_working[/bg\:([a-zA-Z0-9\_]*)\s*/i, 1].dup code_working.gsub!(/bg\:([a-zA-Z0-9\_]*)\s*/i) do |match| "" end - + formatting_text = code.strip.split(' ') - - @fg = Color::Foreground.attribute(fg_text.to_sym) unless fg_text.nil? - @bg = Color::Background.attribute(bg_text.to_sym) unless bg_text.nil? + + unless fg_text.nil? + if fg_text.scan(/\D/).empty? + @fg = fg_text.to_i + else + @fg = Color::Foreground.attribute(fg_text.to_sym) + end + end + + unless bg_text.nil? + if bg_text.scan(/\D/).empty? + @bg = bg_text.to_i + else + @bg = Color::Foreground.attribute(bg_text.to_sym) + end + end + formatting_text.each do |format| case format when "blink" @@ -749,71 +683,110 @@ class FormatState @bold = true when "nobold" @bold = false - when "reversed" - @reversed = true - when "noreversed" - @reversed = false + when "reverse" + @reverse = true + when "noreverse" + @reverse = false + when "standout" + @standout = true + when "nostandout" + @standout = false end end end - + def fg return @fg unless @fg.nil? return @parent.fg unless @parent.nil? - nil + Color::Foreground.attribute(:white) end - + def bg return @bg unless @bg.nil? return @parent.bg unless @parent.nil? - nil + Color::Background.attribute(:black) end - + def blink? return @blink unless @blink.nil? return @parent.blink? unless @parent.nil? - nil + false end - + def dim? return @dim unless @dim.nil? return @parent.dim? unless @parent.nil? - nil + false end - + def bold? return @bold unless @bold.nil? return @parent.bold? unless @parent.nil? - nil + false end - - def underlined? - return @underlined unless @underlined.nil? - return @parent.underlined? unless @parent.nil? - nil + + def underline? + return @underline unless @underline.nil? + return @parent.underline? unless @parent.nil? + false end - - def reversed? - return @reversed unless @reversed.nil? - return @parent.reversed? unless @parent.nil? - nil + + def reverse? + return @reverse unless @reversed.nil? + return @parent.reverse? unless @parent.nil? + false end - - def apply - result = "" - result += Color::Reset.all + Color::Reset.blink + Color::Reset.bold + Color::Reset.dim + Color::Reset.underlined + Color::Reset.reverse - result += self.fg unless self.fg.nil? - result += self.bg unless self.bg.nil? - result += Color::Formatting.blink if self.blink? - result += Color::Formatting.dim if self.dim? - result += Color::Formatting.bold if self.bold? - result += Color::Formatting.underlined if self.underlined? - result += Color::Formatting.reversed if self.reversed? - result + + def standout? + return @standout unless @standout.nil? + return @parent.standout? unless @parent.nil? + false end - - def revert - return @parent.apply unless @parent.nil? - return Color::Reset.all + Color::Reset.blink + Color::Reset.bold + Color::Reset.dim + Color::Reset.underlined + Color::Reset.reverse + + def apply(window) + @activate_color.call(self.fg, self.bg) + + if blink? + window.attron(Ncurses::A_BLINK) + else + window.attroff(Ncurses::A_BLINK) + end + + if dim? + window.attron(Ncurses::A_DIM) + else + window.attroff(Ncurses::A_DIM) + end + + if bold? + window.attron(Ncurses::A_BOLD) + else + window.attroff(Ncurses::A_BOLD) + end + + if underline? + window.attron(Ncurses::A_UNDERLINE) + else + window.attroff(Ncurses::A_UNDERLINE) + end + + if reverse? + window.attron(Ncurses::A_REVERSE) + else + window.attroff(Ncurses::A_REVERSE) + end + + if standout? + window.attron(Ncurses::A_STANDOUT) + else + window.attroff(Ncurses::A_STANDOUT) + end + end + + def revert(window) + return @parent.apply(window) unless @parent.nil? + + @activate_color.call(Color::Foreground.attribute(:white), Color::Background.attribute(:black)) + window.attrset(Ncurses::A_NORMAL) end end diff --git a/lib/aethyr/core/render/window.rb b/lib/aethyr/core/render/window.rb new file mode 100644 index 0000000000000000000000000000000000000000..086c687de86fe8e69ae0df9c0afb587db83f5b09 --- /dev/null +++ b/lib/aethyr/core/render/window.rb @@ -0,0 +1,308 @@ +require "ncursesw" + +class Window + attr_reader :window_border, :window_text, :buffer, :buffer_lines, :text_height, :text_width, :x, :y, :height, :width, :buffered, :use_color, :buffer_size, :color_settings, :buffer_pos + attr_accessor :selected + + def initialize( color_settings, buffered: false, buffer_size: 10000, paginate: nil ) + @buffer = [] if buffered + @buffer_lines = [] if buffered + @buffer_pos = 0 if buffered + @buffer_size = buffer_size if buffered + @buffered = buffered + @selected = false + @use_color = false + @color_settings = color_settings + @color_stack = [] + @exists = false + @paginate = paginate + end + + def exists? + return @exists + end + + def create(width: 0, height: 0, x: 0, y: 0) + raise "width out of range" unless width >= 0 + raise "height out of range" unless height >= 0 + raise "x out of range" unless x >= 0 + raise "y out of range" unless y >= 0 + @height = height + @width = width + @x = x + @y = y + + destroy + @exists = true + @window_border = Ncurses::WINDOW.new(@height, @width, @y, @x) + @window_border_height = @window_border.getmaxy - 2 + @window_border_width = @window_border.getmaxx - 2 + @window_text = @window_border.derwin(@window_border_height, @window_border_width, 1, 1) + @text_height = @window_text.getmaxy - 2 + @text_width = @window_text.getmaxx - 2 + Ncurses.scrollok(@window_text, true) + @window_text.clear + @window_text.move(@text_height, 1) + + if buffered + @buffer_pos = 0 if @buffered + parse_buffer + buffer_from = [@buffer_lines.length * -1, -1 * (@height + @buffer_pos + 1)].max + buffer_to = [@buffer_lines.length * -1, (@buffer_pos + 1) * -1].max + + @buffer_lines[buffer_from..buffer_to].each do | message| + render(message) + end + end + end + + def destroy + @exists = false + Ncurses.delwin(@window_border) unless @window_border.nil? + @window_border = nil + @window_text = nil + @selected = false + end + + def update + white_fg = Color::Foreground.attribute(:white) + grey_fg = Color::Foreground.attribute(:grey) + black_bg = Color::Background.attribute(:black) + + if @use_color + activate_color_window(@window_border, grey_fg, black_bg) unless @window_border.nil? + end + + default_border = 32 + @window_border.border(*([default_border]*8)) unless @window_border.nil? + + if @use_color + activate_color_window(@window_border, white_fg, black_bg) if @selected && @window_border.nil? == false + end + + @window_border.border(*([0]*8)) if @selected && @window_border.nil? == false + + @window_border.noutrefresh() unless @window_border.nil? + @window_text.noutrefresh() unless @window_text.nil? + end + + def enable_color + @use_color = true + end + + def activate_color(fg, bg) + activate_color_window(@window_text, fg, bg) + end + + def clear + @window_text.clear + @buffer = [] unless @buffer.nil? + end + + def send (message, word_wrap = true, add_newline: true) + unless @buffer.nil? + @buffer << message.dup + @buffer << "" if add_newline + @buffer.drop(@buffer.length - @buffer_size) if @buffer.length > @buffer_size + end + + message = message.tr("\r", '') + if buffered + render_buffer + else + render(message, add_newline: add_newline) + end + update + end + + def buffer_pos= new_pos + @buffer_pos = new_pos if new_pos <= @buffer_size && new_pos <= @buffer_lines.length - @text_height && new_pos >= 0 + render_buffer + update + end + + def self.split_message(message, cols = @text_width) + new_message = message.gsub(/\t/, ' ') + new_message.tr!("\r", '') + + last_was_text = false + buffer_lines = [] + new_message.split(/(\n)/) do |line| + next if line.nil? || line.length == 0 + if line.length == 1 && line.start_with?("\n") + if last_was_text + last_was_text = false + else + buffer_lines << "" + end + else + buffer_lines.concat(word_wrap(line, cols)) + last_was_text = true + end + end + return buffer_lines + end + + def self.word_wrap(line, cols = @text_width) + lines = [] + new_line = "" + new_line_length = 0 + next_line = "" + next_line_length = 0 + inside_tag = false + line.each_char do |c| + if c =~ /\S/ + next_line += c + if c == "<" + inside_tag = true + elsif c == ">" + inside_tag = false + elsif inside_tag == false + next_line_length += 1 + end + + if next_line_length + new_line_length >= cols + if new_line_length == 0 + lines << new_line + next_line + next_line = "" + new_line = "" + next_line_length = 0 + else + lines << new_line + new_line = "" + new_line_length = 0 + end + end + elsif next_line.length == 0 + new_line += c + new_line_length += 1 unless inside_tag + else + if next_line_length + new_line_length >= cols + lines << (new_line + next_line + c) + new_line = "" + new_line_length = 0 + next_line = "" + next_line_length = 0 + else + new_line += next_line + c + new_line_length += next_line_length + new_line_length += 1 unless inside_tag + next_line = "" + next_line_length = 0 + end + end + end + lines << new_line + next_line if new_line.length > 0 || next_line.length > 0 + return lines + end + + private + # def paginate(message, cols = @text_width) + # return word_wrap(message, cols) if @paginate.nil? + # + # ph = @paginate + # + # out = [] + # #message = message.gsub(/((\e\[\d+[\;]{0,1}\d*[\;]{0,1}\d*m|[^\r\n\n\s\Z]){#@word_wrap})/, "\\1 ") if @word_wrap + # message = wrap(message, @word_wrap).join("\r\n") if @word_wrap + # message.scan(/((((\e\[\d+[\;]{0,1}\d*[\;]{0,1}\d*m)|.){1,#{@word_wrap}})(\r\n|\n|\s+|\Z))|(\r\n|\n)/) do |m| + # if $2 + # out << $2 + # else + # out << "" + # end + # end + # + # if out.length < ph + # return out.join("\r\n") + # end + # + # @paginator = KPaginator.new(self, out) + # @paginator.more + # end + + def activate_color_window(window, fg, bg) + return if not @use_color + #window.attron(fg + bg * Ncurses.COLORS) + if Ncurses.respond_to?(:color_set) + window.color_set(fg + bg * Ncurses.COLORS, nil) + else + window.attrset(Ncurses.COLOR_PAIR(fg + bg * Ncurses.COLORS)) + end + end + + def render_buffer + parse_buffer + buffer_from = [@buffer_lines.length * -1, -1 * (@text_height + @buffer_pos + 1)].max + buffer_to = [@buffer_lines.length * -1, (@buffer_pos + 1) * -1].max + + @window_text.move(0,0) + @buffer_lines[buffer_from..buffer_to].each do | message| + colored_send(message + "\n") + end + end + + def render(message, add_newline: true) + message += "\n" if add_newline + colored_send(message) + end + + def colored_send(message) + regular_format = nil + if @use_color + regular_format = FormatState.new(@color_settings["regular"], self.method(:activate_color)) + regular_format.apply(@window_text) + end + + colors = @color_settings.keys.dup + colors << "raw[^>]*" + colors = colors.join("|") + + message.split(/(<[\/]{0,1}[^>]*>)/i).each do |part| + if part.start_with? "<" + if @use_color + part.match(/<([\/]{0,1})([^>]*)>/i) do + if ($1.nil?) || ($1.length <= 0) + color_encode($2) + else + color_decode($2) + end + end + end + else + @window_text.addstr("#{part}") + end + end + + if @use_color + regular_format.revert(@window_text) + end + end + + def color_encode(code) + parent = @color_stack[-1] + code = code.downcase + code = "regular" if code.nil? || code.empty? || @color_settings[code].nil? + unless code.start_with? "raw " + result = FormatState.new(@color_settings[code], self.method(:activate_color), parent) + else + /raw (?<code>.*)/ =~ code + result = FormatState.new(code, self.method(:activate_color), parent) + end + @color_stack << result + result.apply(@window_text) + end + + def color_decode(code) + @color_stack.pop.revert(@window_text) + end + + def parse_buffer(cols = @text_width) + raise "channel has no buffer" if buffer.nil? + @buffer_lines = [] + + @buffer.each do |message| + @buffer_lines.concat(Window.split_message(message, cols)) + end + end +end diff --git a/lib/aethyr/core/util/all-commands.rb b/lib/aethyr/core/util/all-commands.rb index d1111474ddf611d38148e1fb9677b816a5612fab..2c32c6886c1ac03721d9db31692ceb357e7f1af8 100644 --- a/lib/aethyr/core/util/all-commands.rb +++ b/lib/aethyr/core/util/all-commands.rb @@ -7,20 +7,20 @@ # # require "aethyr/commands/#{f[0..-4]}" #end -#require 'aethyr/core/commands/admin' -#require 'aethyr/core/commands/clothing' -#require 'aethyr/core/commands/combat' -#require 'aethyr/core/commands/communication' -#require 'aethyr/core/commands/custom' -#require 'aethyr/core/commands/emote' -#require 'aethyr/core/commands/generic' -#require 'aethyr/core/commands/martial_combat' -#require 'aethyr/core/commands/mobiles' -#require 'aethyr/core/commands/movement' -#require 'aethyr/core/commands/news' -#require 'aethyr/core/commands/settings' -#require 'aethyr/core/commands/weapon_combat' +#require 'aethyr/core/actions/commands/admin' +#require 'aethyr/core/actions/commands/clothing' +#require 'aethyr/core/actions/commands/combat' +#require 'aethyr/core/actions/commands/communication' +#require 'aethyr/core/actions/commands/custom' +#require 'aethyr/core/actions/commands/emote' +#require 'aethyr/core/actions/commands/generic' +#require 'aethyr/core/actions/commands/martial_combat' +#require 'aethyr/core/actions/commands/mobiles' +#require 'aethyr/core/actions/commands/movement' +#require 'aethyr/core/actions/commands/news' +#require 'aethyr/core/actions/commands/settings' +#require 'aethyr/core/actions/commands/weapon_combat' require 'require_all' -require_all 'lib/aethyr/core/commands' -require_all 'lib/aethyr/extensions/commands' \ No newline at end of file +require_all 'lib/aethyr/core/input_handlers/' +require_all 'lib/aethyr/extensions/input_handlers/' diff --git a/lib/aethyr/core/util/hydration.rb b/lib/aethyr/core/util/hydration.rb new file mode 100644 index 0000000000000000000000000000000000000000..b17be9cacbb5bd738979c01846a109b386dfda2d --- /dev/null +++ b/lib/aethyr/core/util/hydration.rb @@ -0,0 +1,47 @@ +module Aethyr + module Core + module Storage + module Hydration + module Volatile + @@volatile ||= [] + + def volatile(*attrs) + @@volatile = [] if @@volatile.nil? + @@volatile += attrs + @@volatile.uniq! + end + + def volatile_vars + return @@volatile + end + end + + # removes all volatle data but provides it as a map for restoration in rehydrate + def dehydrate + volatile_data = {} + self.class.volatile_vars.each do |attr| + if self.instance_variable_defined?(attr) + volatile_data[attr] = self.instance_variable_get(attr) + begin + self.remove_instance_variable(attr) + rescue NameError + end + end + end + return volatile_data + end + + def rehydrate(volatile_data) + return if volatile_data.nil? + volatile_data.each do |attr, data| + self.instance_variable_set(attr, data) if self.class.volatile_vars.include? attr + end + end + + def self.included(klass) + klass.extend(Volatile) + end + end + end + end +end diff --git a/lib/aethyr/core/util/priority_queue.rb b/lib/aethyr/core/util/priority_queue.rb new file mode 100644 index 0000000000000000000000000000000000000000..19bce22450498d32954cd05a2fc83e2f974cd28b --- /dev/null +++ b/lib/aethyr/core/util/priority_queue.rb @@ -0,0 +1,530 @@ +# coding: utf-8 + +# Pure ruby Priority Queue adopted from here: https://github.com/supertinou/priority-queue +class PriorityQueue + + include Enumerable + + private + + # + def link_nodes(b1, b2) + return link_nodes(b2, b1) if b2.priority < b1.priority + + b2.parent = b1 + child = b1.child + b1.child = b2 + if child + b2.left = child.left + b2.left.right = b2 + b2.right = child + child.left = b2 + else + b2.left = b2 + b2.right = b2 + end + b1.degree += 1 + b2.mark = false # TODO: Check if this is correct, or if b1 should be marked as false + return b1 + end + + # Does not change length + def delete_first + return nil unless @rootlist + + result = @rootlist + if result == result.right + @min = @rootlist = nil + else + @rootlist = result.right + @rootlist.left = result.left + @rootlist.left.right = @rootlist + + result.right = result.left = result + end + return result; + end + + def cut_node(n) + return self unless n.parent + n.parent.degree -= 1 + if n.parent.child == n + if n.right == n + n.parent.child = nil + else + n.parent.child = n.right; + end + end + n.parent = nil + n.right.left = n.left + n.left.right = n.right + + n.right = @rootlist + n.left = @rootlist.left + @rootlist.left.right = n + @rootlist.left = n + + n.mark = false + + return self + end + + # Does not change length + def insert_tree(tree) + if @rootlist == nil + @rootlist = @min = tree + else + l = @rootlist.left + l.right = tree + @rootlist.left = tree + tree.left = l + tree.right = @rootlist + @min = tree if tree.priority < @min.priority + end + self + end + + def consolidate + return self if self.empty? + array_size = (2.0 * Math.log(self.length) / Math.log(2) + 1.0).ceil + tree_by_degree = Array.new(array_size) + + while n = delete_first + while n1 = tree_by_degree[n.degree] + tree_by_degree[n.degree] = nil; + n = link_nodes(n, n1); + end + tree_by_degree[n.degree] = n; + end + + @rootlist = @min = nil; + tree_by_degree.each do | tree | + next unless tree + insert_tree(tree) + end + self + end + + # Node class used internally + class Node # :nodoc: + attr_accessor :parent, :left, :right, :key, :priority, :degree, :mark + attr_reader :child + + def child=(c) + raise "Circular Child" if c == self + raise "Child is neighbour" if c == self.right + raise "Child is neighbour" if c == self.left + @child = c + end + + def to_dot(only_down = false, known_nodes = []) + p known_nodes.map { | n | n.dot_id } + p self.dot_id + result = [] + if only_down + raise "Circular #{caller.inspect}" if known_nodes.include?(self) + known_nodes << self + + result << "#{dot_id} [label=\"#{@key}: #{@priority}\"];" + l = " " + #l << "#{@left.dot_id} <- #{dot_id}; " if @left + l << "#{dot_id} -> #{@left.dot_id} [constraint=false]; " if @left and @left.dot_id < self.dot_id + l << "#{dot_id} -> #{@right.dot_id} [constraint=false];\t\t\t\t/*neighbours*/" if @right and @right.dot_id <= self.dot_id + result << l + result << " #{dot_id} -> #{@child.dot_id}; //child" if @child + result << @child.to_dot(false, known_nodes) if @child + else + n = self + begin + result.concat(n.to_dot(true, known_nodes)) + n = n.right + end while n != self + end + result.flatten.map{|r| " " << r} + end + + def dot_id + "N#{@key}" + end + + def initialize(key, priority) + @key = key; @priority = priority; @degree = 0 + end + end + + public + + # Returns the number of elements of the queue. + # + # q = PriorityQueue.new + # q.length #=> 0 + # q[0] = 1 + # q.length #=> 1 + attr_reader :length + + # Create a new, empty PriorityQueue + def initialize + @nodes = Hash.new + @rootlist = nil + @min = nil + @length = 0 + end + + # Print a priority queue as a dot-graph. The output can be fed to dot from the + # vizgraph suite to create a tree depicting the internal datastructure. + def to_dot + r = ["digraph fibheap {"] + #r << @rootlist.to_dot.join("\n") if @rootlist + r << "ROOT -> #{@rootlist.dot_id};" if @rootlist + @nodes.to_a.sort.each do | (_, n) | + r << " #{n.dot_id} [label=\"#{n.key}: #{n.priority}\"];" + r << " #{n.dot_id} -> #{n.right.dot_id} [constraint=false];" if n.right# and n.dot_id < n.right.dot_id + r << " #{n.dot_id} -> #{n.left.dot_id} [constraint=false];" if n.left #and n.dot_id < n.left.dot_id + r << " #{n.dot_id} -> #{n.child.dot_id}" if n.child + end + r << "}" + r.join("\n") + r + end + + # Call dot and gv displaying the datstructure + def display_dot + puts to_dot + system "echo '#{to_dot}' | twopi -Tps -Groot=ROOT -Goverlap=false> /tmp/dotfile.ps; gv /tmp/dotfile.ps" + end + + # call-seq: + # [key] = priority + # change_priority(key, priority) + # push(key, priority) + # + # Set the priority of a key. + # + # q = PriorityQueue.new + # q["car"] = 50 + # q["train"] = 50 + # q["bike"] = 10 + # q.min #=> ["bike", 10] + # q["car"] = 0 + # q.min #=> ["car", 0] + def change_priority(key, priority) + return push(key, priority) unless @nodes[key] + + n = @nodes[key] + if n.priority < priority # Priority was increased. Remove the node and reinsert. + self.delete(key) + self.push(key, priority); + return self + end + n.priority = priority; + @min = n if n.priority < @min.priority + + return self if !n.parent or n.parent.priority <= n.priority # Already in rootlist or bigger than parent + begin # Cascading Cuts + p = n.parent + cut_node(n) + n = p + end while n.mark and n.parent + n.mark = true if n.parent + + self + end + + # Add an object to the queue. + def push(key, priority) + return change_priority(key, priority) if @nodes[key] + @nodes[key] = node = Node.new(key, priority) + @min = node if !@min or priority < @min.priority + if not @rootlist + @rootlist = node + node.left = node.right = node + else + node.left = @rootlist.left + node.right = @rootlist + @rootlist.left.right = node + @rootlist.left = node + end + @length += 1 + self + end + + # Returns true if the array is empty, false otherwise. + def empty? + @rootlist.nil? + end + + # call-seq: + # [key] -> priority + # + # Return the priority of a key or nil if the key is not in the queue. + # + # q = PriorityQueue.new + # (0..10).each do | i | q[i.to_s] = i end + # q["5"] #=> 5 + # q[5] #=> nil + def [](key) + @nodes[key] and @nodes[key].priority + end + + # call-seq: + # has_key? key -> boolean + # + # Return false if the key is not in the queue, true otherwise. + # + # q = PriorityQueue.new + # (0..10).each do | i | q[i.to_s] = i end + # q.has_key("5") #=> true + # q.has_key(5) #=> false + def has_key?(key) + @nodes.has_key?(key) + end + + alias :[]= :push + + # Call the given block with each [key, priority] pair in the queue + # + # Beware: Changing the queue in the block may lead to unwanted behaviour and + # even infinite loops. + def each + @nodes.each do | key, node | + yield(key, node.priority) + end + end + + # call-seq: + # min -> [object, priority] + # + # Return the pair [object, priority] with minimal priority or nil when the + # queue is empty. + # + # q = PriorityQueue.new + # q["a"] = 10 + # q["b"] = 20 + # q.min #=> ["a", 10] + # q.delete_min #=> ["a", 10] + # q.min #=> ["b", 20] + # q.delete_min #=> ["b", 20] + # q.min #=> nil + def min + [@min.key, @min.priority] rescue nil + end + + # call-seq: + # min_key -> object + # + # Return the key that has the minimal priority or nil when the queue is empty. + # + # q = PriorityQueue.new + # q["a"] = 10 + # q["b"] = 20 + # q.min_key #=> "a" + # q.delete_min #=> ["a", 10] + # q.min_key #=> "b" + # q.delete_min #=> ["b", 20] + # q.min_key #=> nil + def min_key + @min.key rescue nil + end + + # call-seq: + # min_priority -> priority + # + # Return the minimal priority or nil when the queue is empty. + # + # q = PriorityQueue.new + # q["a"] = 10 + # q["b"] = 20 + # q.min_priority #=> 10 + # q.delete_min #=> ["a", 10] + # q.min_priority #=> 20 + # q.delete_min #=> ["b", 20] + # q.min_priority #=> nil + def min_priority + @min.priority rescue nil + end + + # call-seq: + # delete(key) -> [key, priority] + # delete(key) -> nil + # + # Delete a key from the priority queue. Returns nil when the key was not in + # the queue and [key, priority] otherwise. + # + # q = PriorityQueue.new + # (0..10).each do | i | q[i.to_s] = i end + # q.delete(5) #=> ["5", 5] + # q.delete(5) #=> nil + def delete(key) + return nil unless n = @nodes.delete(key) + + if n.child + c = n.child + e = n.child + begin + r = c.right + cut_node(c) + c = r + end while c != e + end + cut_node(n) if n.parent + + if n == n.right + @min = nil; + @rootlist = nil; + else + @rootlist = n.right if @rootlist == n + if @min == n + n1 = n.right + @min = n1 + begin + @min = n1 if n1.priority < @min.priority + n1 = n1.right + end while(n1 != n); + end + n.right.left = n.left + n.left.right = n.right + n.left = n + n.right = n + end + @length -= 1 + return [n.key, n.priority] + end + + # call-seq: + # delete_min_return_key -> key + # + # Delete key with minimal priority and return the key + # + # q = PriorityQueue.new + # q["a"] = 1 + # q["b"] = 0 + # q.delete_min_return_key #=> "b" + # q.delete_min_return_key #=> "a" + # q.delete_min_return_key #=> nil + def delete_min_return_key + delete_min[0] rescue nil + end + + alias pop_min delete_min_return_key + + # call-seq: + # delete_min_return_priority -> priority + # + # Delete key with minimal priority and return the priority value + # + # q = PriorityQueue.new + # q["a"] = 1 + # q["b"] = 0 + # q.delete_min_return_priority #=> 0 + # q.delete_min_return_priority #=> 1 + # q.delete_min_return_priority #=> nil + def delete_min_return_priority + delete_min[1] rescue nil + end + + # call-seq: + # delete_min -> [key, priority] + # + # Delete key with minimal priority and return [key, priority] + # + # q = PriorityQueue.new + # q["a"] = 1 + # q["b"] = 0 + # q.delete_min #=> ["b", 0] + # q.delete_min #=> ["a", 1] + # q.delete_min #=> nil + def delete_min + return nil if self.empty? + result = self.min + + @nodes.delete(@min.key) + + if @length == 1 + @rootlist = @min = nil + @length = 0 + else + min = @min + if @min == @rootlist # If the rootlist is anchored at the minimum, shift to the right + if @rootlist == @rootlist.right + @rootlist = @min = nil + else + @rootlist = @min = @min.right + end + end + min.left.right = min.right; + min.right.left = min.left; + min.left = min.right = min; + if min.child + # Kinder und Eltern trennen, Markierung aufheben + n = min.child; + begin + n.parent = nil; + n.mark = false; + n = n.right; + end while n != min.child + + # Kinder einf�gen + if @rootlist + l1 = @rootlist.left + l2 = n.left + + l1.right = n + n.left = l1 + l2.right = @rootlist + @rootlist.left = l2 + else + @rootlist = n + end + end + + # Gr��e anpassen + @length -= 1 + + # Wieder aufh�bschen + consolidate + end + + result + end + + # Returns a string representation of the priority queue. + def inspect + "<PriorityQueue: #{@nodes.map{|(_, n)| [n.key, n.priority]}.sort_by{|(_,p)|p}.inspect}>" + end + + def initialize_copy(copy) + copy_nodes = @nodes + @nodes = {} + + copy_nodes.each do | (_, cn) | + n = @nodes[cn.key] = Node.new(cn.key, cn.priority) + n.mark = cn.mark + n.degree = cn.degree + end + + copy_nodes.each do | (_, cn) | + n = @nodes[cn.key] + n.left = @nodes[cn.left.key] if cn.left + n.right = @nodes[cn.right.key] if cn.right + n.parent = @nodes[cn.parent.key] if cn.parent + n.child = @nodes[cn.child.key] if cn.child + end + @rootlist = @nodes[@rootlist.key] if @rootlist + @min = @nodes[@min.key] if @min + self + end +end + +if __FILE__ == $0 + q = RubyPriorityQueue.new + + ('a'..'z').each do | n | + q[n] = n[0] + end + q.delete_min + q.delete_min + q.delete_min + q.delete_min + q.display_dot + q.delete_min +end diff --git a/lib/aethyr/core/util/publisher.rb b/lib/aethyr/core/util/publisher.rb index 6d4628bf44587c21a5bb51a2a2bbb669f93e3acc..2b1869230fcb48693b29bf042b14c4048eb1940d 100644 --- a/lib/aethyr/core/util/publisher.rb +++ b/lib/aethyr/core/util/publisher.rb @@ -1,7 +1,11 @@ require 'aethyr/core/util/marshaller' +require 'aethyr/core/util/hydration' require 'wisper' class Publisher + include Aethyr::Core::Storage::Hydration include Marshaller[:@observer_peers, :@local_registrations] include Wisper::Publisher -end \ No newline at end of file + + volatile :@local_registrations +end diff --git a/lib/aethyr/extensions/actions/commands/.keep b/lib/aethyr/extensions/actions/commands/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/lib/aethyr/extensions/input_handlers/.keep b/lib/aethyr/extensions/input_handlers/.keep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391