Skip to content
This repository has been archived by the owner on Jan 4, 2023. It is now read-only.

Implemented scripting, enter/exit hooks, for teleporter rooms #33

Merged
merged 6 commits into from
Dec 31, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ source 'https://rubygems.org'

gem 'eventmachine'
gem 'colorize'
gem 'rspec'
gem 'rspec-mocks'
gem 'facets'
gem 'pry'
gem 'pry-remote'
gem 'pry-rescue'
gem 'pry-stack_explorer'
gem 'malloc_trim'
gem 'memory_profiler'
gem 'get_process_mem'
gem 'parser' # needed for lib/script.rb

group :test do
gem 'rspec'
gem 'rspec-mocks'
end

group :test, :development do
gem 'pry'
gem 'pry-remote'
gem 'pry-rescue'
gem 'pry-stack_explorer'
gem 'memory_profiler'
gem 'get_process_mem'
end
14 changes: 8 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.0)
binding_of_caller (0.8.0)
debug_inspector (>= 0.0.1)
coderay (1.1.2)
Expand All @@ -13,18 +14,19 @@ GEM
get_process_mem (0.2.5)
ffi (~> 1.0)
interception (0.5)
malloc_trim (0.1.0)
memory_profiler (0.9.14)
method_source (0.9.0)
pry (0.11.3)
method_source (0.9.2)
parser (2.7.0.0)
ast (~> 2.4.0)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-remote (0.1.8)
pry (~> 0.9)
slop (~> 3.0)
pry-rescue (1.4.5)
pry-rescue (1.5.0)
interception (>= 0.5)
pry
pry (>= 0.12.0)
pry-stack_explorer (0.4.9.3)
binding_of_caller (>= 0.7)
pry (>= 0.9.11)
Expand All @@ -51,8 +53,8 @@ DEPENDENCIES
eventmachine
facets
get_process_mem
malloc_trim
memory_profiler
parser
pry
pry-remote
pry-rescue
Expand Down
28 changes: 28 additions & 0 deletions data/world/base.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,31 @@
- viewable:
short: a red rubber ball
long: a red rubber ball is on the floor

- id: base:act/teleporter
components:
- hook:
event: :on_enter
script: base:script/teleporter/enter
- hook:
event: :on_exit
script: base:script/teleporter/exit
- teleporter

- id: base:script/teleporter/enter
components:
- script: !script |
here = args[:here]
unless porter = get_component(here, :teleporter)
error "#{here} missing teleporter component"
return
end
entity = args[:entity]
port = get_component!(entity, :teleport)
port[:dest] = porter[:dest]
port[:time] = now + porter[:delay]
- id: base:script/teleporter/exit
components:
- script: !script |
remove_component(args[:entity], :teleport)
11 changes: 11 additions & 0 deletions data/world/limbo/rooms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
list:
- limbo:spawn/mob/puff
- limbo:spawn/obj/limbo-chest
- hook:
event: :on_enter
script: limbo:script/balls

- base: base:exit
link: base:room/void.exits.up
Expand Down Expand Up @@ -73,3 +76,11 @@
components:
- spawn:
entity: limbo:mob/puff

- id: limbo:script/balls
components:
- script: !script |
actor = args[:entity]
send_to_char(char: actor,
buf: "A small &Rred&0 ball appears in your hand!\n")
spawn_at(dest: actor, base: 'base:obj/junk/ball')
3 changes: 1 addition & 2 deletions lib/command/movement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ def traverse_passage(actor, name)
else
dest = get_component(passage, :destination) or
fault "passage #{passage} has no destination!"
move_entity(entity: actor, dest: dest.entity)
Command::Look.show_room(actor, dest.entity)
move_entity(entity: actor, dest: dest.entity, look: true)
end
end
end
Expand Down
21 changes: 21 additions & 0 deletions lib/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,25 @@ def ==(other)
self.class == other.class && to_h == other.to_h
end
alias eql? ==

# []
#
# Get the value for a field. Slower method created to support Script.
def [](key)
key = key.to_sym unless key.is_a?(Symbol)
raise KeyError, "key not found: #{key}" unless
self.class.fields.include?(key)
send(key)
end

# []=
#
# Set the value for a field. Slower than calling the setter directly.
# Implemented to support Script.
def []=(key, value)
key = key.to_sym unless key.is_a?(Symbol)
raise KeyError, "key not found: #{key}" unless
self.class.fields.include?(key)
send("#{key}=", value)
end
end
74 changes: 74 additions & 0 deletions lib/components.rb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,80 @@ class ConnectionComponent < Component
field :buf, default: '' # String of pending output
end

# Used to run scripts when specific events occur in the world.
#
class HookComponent < Component
# due to compositing architecture, we're going to permit multiple hooks
not_unique

# Event when this script should be run
#
# will_enter: Entity (entity) will be added to (dest) entity's
# ContainerComponent. May be blocked by returning :deny.
# This hook will be called before the character performs 'look'
# in the dest room.
#
# Script arguments:
# entity: Entity being moved
# src: entity's current location; may be nil
# dest: destination entity
#
# on_enter: Entity (entity) has been added to (here) entity's
# ContainerComponent.
# This hook will be caled after the character performs 'look' in
# here.
#
# Script arguments:
# entity: Entity that was added
# here: entity's current location
#
# will_exit: Entity (entity) will removed from (src) entity's
# ContainerComponent. May be blocked by returning :deny.
# Script arguments:
#
# entity: Entity being moved
# src: entity's current location; may be nil
# dest: destination entity
#
# on_exit: Entity (entity) has been removed from (here) entity's
# ContainerComponent.
#
# Script arguments:
# entity: Entity that was removed
# here: entity's current location
field :event, valid: %i{ will_enter on_enter will_exit on_exit }

# This points at the entity id for the script that should be run
field :script
end

# This component holds configuration for a teleporter. It is used by the
# teleporter script.
class TeleporterComponent < Component

# destination entity
field :dest

# delay before entity should be moved
field :delay, valid: proc { |v| v.is_a?(Integer) }, default: 10
end

# This component is added to an entity that will be teleported at a later time.
# It is added by the teleporter script
class TeleportComponent < Component
# destination entity
field :dest, valid: proc { |v| v.nil? or World.entity_exists?(v) }

# Time at which they should be teleported
field :time
end

# Component that holds a script
class ScriptComponent < Component
# Script instance
field :script, clone: false
end

### QUESTIONABLE COMPONENTS ###
class AffectComponent < Component
not_unique
Expand Down
Loading