Class: Missions::Mission

Inherits:
Object show all
Defined in:
lib/missions/mission.rb

Overview

Set of objectives created by a user (usually a npc) and assigned to another for completion.

Incorprates callbacks to determine if user is eligable to accept mission, if/when mission is completed, and to run handlers at various points during the mission cycle.

Constant Summary collapse

CALLBACKS =

Attributes which correspond to mission cycle callbacks

[:requirements, :assignment_callbacks, :victory_conditions,
:victory_callbacks, :failure_callbacks]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Mission

Mission initializer

Parameters:

  • args (Hash) (defaults to: {})

    hash of options to initialize mission with

Options Hash (args):

  • :id,'id' (String)

    id to assign to the mission

  • :title,'title' (String)

    title of the mission

  • :description,'description' (String)

    description of the mission

  • :creator_id,'creator_id' (String)

    id of user that created the mission

  • :assigned_to_id,'assigned_to_id' (String)

    id of user that the mission is assigned to

  • :assigned_time,'assigned_time' (Time)

    time the mission was assigned to user

  • :timeout,'timeout' (Integer)

    seconds which mission assignment is valid for

  • :orig_callbacks,'orig_callbacks' (Array<String>)

    callbacks which to register with orig_callbacks

  • :requirements,'requirements' (Array<String,Callables>)

    requirements which to validate upon assigning mission

  • :assignment_callbacks,'assignment_callbacks' (Array<String,Callables>)

    callbacks which to invoke upon assigning mission

  • :victory_conditions,'victory_conditions' (Array<String,Callables>)

    conditions which to determine if mission is completed

  • :victory_callbacks,'victory_callbacks' (Array<String,Callables>)

    callbacks which to invoke upon successful mission completion

  • :failure_callbacks,'failure_callbacks' (Array<String,Callables>)

    callbacks which to invoke upon mission failure

  • :mission, (Missions::Mission)

    'mission' mission to copy attributes from


223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# File 'lib/missions/mission.rb', line 223

def initialize(args = {})
  attr_from_args args,
    :id                   => nil,
    :title                =>  "",
    :description          =>  "",
    :mission_data         =>  {},
    :creator_id      => nil,
    :assigned_to_id       => nil,
    :assigned_time        => nil,
    :timeout              => nil,
    :orig_callbacks       =>  {},
    :requirements         =>  [],
    :assignment_callbacks =>  [],
    :victory_conditions   =>  [],
    :victory_callbacks    =>  [],
    :failure_callbacks    =>  [],
    :victorious           => false,
    :failed               => false

  @assigned_time = Time.parse(@assigned_time) if @assigned_time.is_a?(String)

  # convert all mission data keys to strings
  @mission_data.keys.each { |k|
    unless k.is_a?(String)
      @mission_data[k.to_s] = @mission_data[k]
      @mission_data.delete(k)
    end
  }

  CALLBACKS.each { |cb|
    c = "@#{cb}".intern
    i = self.instance_variable_get(c)
    unless i.is_a?(Array)
      i = [i]
      self.instance_variable_set(c, i)
    end
  }
end

Instance Attribute Details

#assigned_timeObject

Time mission was assigned to user


122
123
124
# File 'lib/missions/mission.rb', line 122

def assigned_time
  @assigned_time
end

#assigned_toObject

Handle to Users::User who is assigned to the mission


102
103
104
# File 'lib/missions/mission.rb', line 102

def assigned_to
  @assigned_to
end

#assigned_to_idObject

Id of user who is assigned to the mission


89
90
91
# File 'lib/missions/mission.rb', line 89

def assigned_to_id
  @assigned_to_id
end

#assignment_callbacksObject

Array of callbacks which to invoke on assignment


111
112
113
# File 'lib/missions/mission.rb', line 111

def assignment_callbacks
  @assignment_callbacks
end

#creatorObject

Handle to Users::User who created the mission


62
63
64
# File 'lib/missions/mission.rb', line 62

def creator
  @creator
end

#creator_idObject

Id of user who created the mission


59
60
61
# File 'lib/missions/mission.rb', line 59

def creator_id
  @creator_id
end

#descriptionObject

Description of the mission


49
50
51
# File 'lib/missions/mission.rb', line 49

def description
  @description
end

#failedObject

Boolean indicating if user was failed mission


149
150
151
# File 'lib/missions/mission.rb', line 149

def failed
  @failed
end

#failure_callbacksObject

Array of callbacks which to invoke on failure


188
189
190
# File 'lib/missions/mission.rb', line 188

def failure_callbacks
  @failure_callbacks
end

#idObject

Unique string id of the mission


43
44
45
# File 'lib/missions/mission.rb', line 43

def id
  @id
end

#mission_dataObject

Generic key/value store for data in the mission context, for use by the various callbacks


56
57
58
# File 'lib/missions/mission.rb', line 56

def mission_data
  @mission_data
end

#orig_callbacksObject

Original callbacks registered with mission. Used to restore missions from json backups and such


25
26
27
# File 'lib/missions/mission.rb', line 25

def orig_callbacks
  @orig_callbacks
end

#requirementsObject

Array of mission assignment requirements


76
77
78
# File 'lib/missions/mission.rb', line 76

def requirements
  @requirements
end

#timeoutObject

Time user has to complete mission


130
131
132
# File 'lib/missions/mission.rb', line 130

def timeout
  @timeout
end

#titleObject

Title of the mission


46
47
48
# File 'lib/missions/mission.rb', line 46

def title
  @title
end

#victoriousObject

Boolean indicating if user was victorious in mission


146
147
148
# File 'lib/missions/mission.rb', line 146

def victorious
  @victorious
end

#victory_callbacksObject

Array of callbacks which to invoke on victory


169
170
171
# File 'lib/missions/mission.rb', line 169

def victory_callbacks
  @victory_callbacks
end

#victory_conditionsObject

Array of mission victory conditions


158
159
160
# File 'lib/missions/mission.rb', line 158

def victory_conditions
  @victory_conditions
end

Class Method Details

.json_create(o) ⇒ Object

Create new mission from json representation


314
315
316
317
# File 'lib/missions/mission.rb', line 314

def self.json_create(o)
  mission = new(o['data'])
  return mission
end

Instance Method Details

#active?Boolean

Retuns boolean indicating if mission is active, eg assigned, not expired and not victorious / failed

Returns:

  • (Boolean)

153
154
155
# File 'lib/missions/mission.rb', line 153

def active?
  assigned? && !self.expired? && !self.victorious && !self.failed
end

#assign_to(user) ⇒ Object

Assign mission to the specified user


114
115
116
117
118
119
# File 'lib/missions/mission.rb', line 114

def assign_to(user)
  return unless self.assignable_to?(user)
  @assigned_to    = user
  @assigned_to_id = user.id
  @assigned_time = Time.now
end

#assignable_to?(user) ⇒ Boolean

Return boolean indicating if user meets requirements to be assigned to this mission

Returns:

  • (Boolean)

80
81
82
83
84
85
86
# File 'lib/missions/mission.rb', line 80

def assignable_to?(user)
  !@assigned_to_id &&
  @requirements.all? { |req|
    # TODO catch exceptions (return false if any?)
    req.call self, user
  }
end

#assigned?Boolean

Return boolean indicating if mission is assigned

Returns:

  • (Boolean)

125
126
127
# File 'lib/missions/mission.rb', line 125

def assigned?
  !@assigned_to_id.nil?
end

#assigned_to?(user) ⇒ Boolean

Return boolean indicating if mission is assigned to the the specified user

Returns:

  • (Boolean)

93
94
95
96
97
98
99
# File 'lib/missions/mission.rb', line 93

def assigned_to?(user)
  if user.is_a?(Users::User)
    return @assigned_to_id == user.id
  end

  return @assigned_to_id == user
end

#clear_assignment!Object

Clear mission assignment


139
140
141
142
143
# File 'lib/missions/mission.rb', line 139

def clear_assignment!
  @assigned_to    = nil
  @assigned_to_id = nil
  @assigned_time  = nil
end

#clone(args = {}) ⇒ Object

Return a copy of this mission, setting any additional attributes given


281
282
283
284
285
# File 'lib/missions/mission.rb', line 281

def clone(args = {})
  m = Mission.new
  m.update(args.merge(:mission => self))
  m
end

#completed?Boolean

Returns boolean indicating if mission was completed or not

Returns:

  • (Boolean)

162
163
164
165
166
# File 'lib/missions/mission.rb', line 162

def completed?
  @victory_conditions.all? { |vc|
    vc.call self
  }
end

#expired?Boolean

Returns boolean indicating if time to complete mission has expired

Returns:

  • (Boolean)

134
135
136
# File 'lib/missions/mission.rb', line 134

def expired?
  assigned? && ((@assigned_time + @timeout) < Time.now)
end

#failed!Object

Set mission failure to true

Raises:

  • (RuntimeError)

191
192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/missions/mission.rb', line 191

def failed!
  raise RuntimeError, "must be assigned"             unless assigned?
  raise RuntimeError, "cannot already be victorious" if @victorious
  @victorious = false
  @failed     = true

  @failure_callbacks.each { |fcb|
    begin
      fcb.call self
    rescue Exception => e
      ::RJR::Logger.warn "error in mission #{self.id} failure: #{e}"
    end
  }
end

#restore_callbacksObject

Restore callbacks from orig_callbacks


36
37
38
39
40
# File 'lib/missions/mission.rb', line 36

def restore_callbacks
  CALLBACKS.each { |cb|
    self.instance_variable_set "@#{cb}".intern, @orig_callbacks[cb.to_s]
  }
end

#store_callbacksObject

Store current callbacks to orig_callbacks


28
29
30
31
32
33
# File 'lib/missions/mission.rb', line 28

def store_callbacks
  @orig_callbacks = {}
  CALLBACKS.each { |cb|
    @orig_callbacks[cb.to_s] = self.instance_variable_get "@#{cb}".intern
  }
end

#to_json(*a) ⇒ Object

Convert mission to json representation and return it


288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/missions/mission.rb', line 288

def to_json(*a)
  {
    'json_class' => self.class.name,
    'data'       => {:id => id,
                     :title => title, :description => description,
                     :mission_data => mission_data,
                     :creator_id => creator_id,
                     :assigned_to_id => assigned_to_id,
                     :timeout => timeout,
                     :assigned_time => assigned_time,
                     :orig_callbacks       => orig_callbacks,
                     :requirements         => requirements,
                     :assignment_callbacks => assignment_callbacks,
                     :victory_conditions   => victory_conditions,
                     :victory_callbacks    => victory_callbacks,
                     :failure_callbacks    => failure_callbacks,
                     :victorious => victorious, :failed => failed}
  }.to_json(*a)
end

#to_sObject

Convert mission to human readable string and return it


309
310
311
# File 'lib/missions/mission.rb', line 309

def to_s
  "mission-#{@id}"
end

#update(args = {}) ⇒ Object

Update the mission from the specified args


265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/missions/mission.rb', line 265

def update(args = {})
  attrs = [:id, :title, :description, :mission_data,
           :creator_id, :assigned_to_id, :assigned_time,
           :timeout, :requirements, :assignment_callbacks,
           :victory_conditions, :victory_callbacks,
           :failure_callbacks, :victorious,
           :failed]

  [:mission, 'mission'].each { |mission|
    update_from(args[mission], *attrs) if args.is_a?(Hash) && args[mission]
  }

  update_from(args, *attrs)
end

#victory!Object

Set mission victory to true

Raises:

  • (RuntimeError)

172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/missions/mission.rb', line 172

def victory!
  raise RuntimeError, "must be assigned"         unless assigned?
  raise RuntimeError, "cannot already be failed" if @failed
  @victorious = true
  @failed     = false

  @victory_callbacks.each { |vcb|
    begin
      vcb.call self
    rescue Exception => e
      ::RJR::Logger.warn "error in mission #{self.id} victory: #{e}"
    end
  }
end