Class: Quake::Entity

Inherits:
Object
  • Object
show all
Defined in:
lib/quake/entity.rb

Overview

Represents a parsed entity from the BSP entities lump. All Quake entities (players, monsters, items, triggers, brush models) are defined as key-value property bags in the BSP entity string.

Constant Summary collapse

FL_FLY =
1
FL_SWIM =
2
FL_CLIENT =
8
FL_MONSTER =
32
FL_GODMODE =
64
IT_ARMOR1 =
8192
IT_ARMOR2 =
16_384
IT_ARMOR3 =
32_768
IT_ARMOR_MASK =
IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(properties = {}) ⇒ Entity

Returns a new instance of Entity.



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/quake/entity.rb', line 27

def initialize(properties = {})
  @properties = properties.dup
  @classname = properties["classname"] || ""
  @spawnflags = (properties["spawnflags"] || "0").to_i
  apply_spawn_defaults

  # Parse common fields
  @position = parse_vec3(@properties["origin"]) || Math::Vec3::ORIGIN
  @velocity = parse_vec3(@properties["velocity"]) || Math::Vec3::ORIGIN
  @angle = (@properties["angle"] || "0").to_f
  @angles = parse_vec3(@properties["angles"]) || Math::Vec3::ORIGIN

  # Brush model reference: "*1", "*2", etc.
  @model_index = nil
  if (model_str = @properties["model"])
    @model_index = model_str[1..].to_i if model_str.start_with?("*")
  end

  # Targeting
  @target = @properties["target"]
  @targetname = @properties["targetname"]
  @killtarget = @properties["killtarget"]

  # Movement/behavior
  @speed = quake_float("speed", default_speed, zero_defaults_for: [
                         "func_door", "func_plat", "func_button", "func_train",
                         "trigger_push", "trigger_monsterjump"
                       ])
  @wait = quake_float("wait", default_wait, zero_defaults_for: [
                        "func_door", "func_button", "trigger_multiple", "trap_shooter"
                      ])
  @lip = quake_float("lip", default_lip, zero_defaults_for: ["func_door", "func_button"])
  @health = (@properties["health"] || default_health).to_f
  @height = quake_float("height", default_height, zero_defaults_for: ["trigger_monsterjump"])
  @sounds = (@properties["sounds"] || "0").to_i
  @message = @properties["message"]
  @count = quake_int("count", default_count, zero_defaults_for: ["trigger_counter"])
  @frame = quake_int("frame", default_frame)
  @skin = quake_int("skin", default_skin)
  @flags = quake_int("flags", "0") | default_runtime_flags
  @takedamage = quake_int("takedamage", default_takedamage)
  @armortype = quake_float("armortype", "0")
  @armorvalue = quake_float("armorvalue", "0")
  @invincible_finished = quake_float("invincible_finished", "0")
  @items = quake_int("items", "0")
  @super_damage_finished = quake_float("super_damage_finished", "0")
  @dmg_take = quake_float("dmg_take", "0")
  @dmg_save = quake_float("dmg_save", "0")
  @dmg_inflictor = nil
  @effects = quake_int("effects", "0") if @properties.key?("effects")
  @style = quake_int("style", default_style, zero_defaults_for: ["light_fluorospark"])

  # Runtime state
  @state = :idle
  @think_time = 0.0
  @move_dir = Math::Vec3::ORIGIN
end

Instance Attribute Details

#angleObject

Returns the value of attribute angle.



18
19
20
# File 'lib/quake/entity.rb', line 18

def angle
  @angle
end

#anglesObject

Returns the value of attribute angles.



18
19
20
# File 'lib/quake/entity.rb', line 18

def angles
  @angles
end

#armortypeObject

Returns the value of attribute armortype.



18
19
20
# File 'lib/quake/entity.rb', line 18

def armortype
  @armortype
end

#armorvalueObject

Returns the value of attribute armorvalue.



18
19
20
# File 'lib/quake/entity.rb', line 18

def armorvalue
  @armorvalue
end

#classnameObject

Returns the value of attribute classname.



18
19
20
# File 'lib/quake/entity.rb', line 18

def classname
  @classname
end

#countObject

Returns the value of attribute count.



18
19
20
# File 'lib/quake/entity.rb', line 18

def count
  @count
end

#dmg_inflictorObject

Returns the value of attribute dmg_inflictor.



18
19
20
# File 'lib/quake/entity.rb', line 18

def dmg_inflictor
  @dmg_inflictor
end

#dmg_saveObject

Returns the value of attribute dmg_save.



18
19
20
# File 'lib/quake/entity.rb', line 18

def dmg_save
  @dmg_save
end

#dmg_takeObject

Returns the value of attribute dmg_take.



18
19
20
# File 'lib/quake/entity.rb', line 18

def dmg_take
  @dmg_take
end

#effectsObject

Returns the value of attribute effects.



18
19
20
# File 'lib/quake/entity.rb', line 18

def effects
  @effects
end

#flagsObject

Returns the value of attribute flags.



18
19
20
# File 'lib/quake/entity.rb', line 18

def flags
  @flags
end

#frameObject

Returns the value of attribute frame.



18
19
20
# File 'lib/quake/entity.rb', line 18

def frame
  @frame
end

#healthObject

Returns the value of attribute health.



18
19
20
# File 'lib/quake/entity.rb', line 18

def health
  @health
end

#heightObject

Returns the value of attribute height.



18
19
20
# File 'lib/quake/entity.rb', line 18

def height
  @height
end

#invincible_finishedObject

Returns the value of attribute invincible_finished.



18
19
20
# File 'lib/quake/entity.rb', line 18

def invincible_finished
  @invincible_finished
end

#itemsObject

Returns the value of attribute items.



18
19
20
# File 'lib/quake/entity.rb', line 18

def items
  @items
end

#killtargetObject

Returns the value of attribute killtarget.



18
19
20
# File 'lib/quake/entity.rb', line 18

def killtarget
  @killtarget
end

#lightstyleObject

Returns the value of attribute lightstyle.



18
19
20
# File 'lib/quake/entity.rb', line 18

def lightstyle
  @lightstyle
end

#lipObject

Returns the value of attribute lip.



18
19
20
# File 'lib/quake/entity.rb', line 18

def lip
  @lip
end

#messageObject

Returns the value of attribute message.



18
19
20
# File 'lib/quake/entity.rb', line 18

def message
  @message
end

#model_indexObject

Returns the value of attribute model_index.



18
19
20
# File 'lib/quake/entity.rb', line 18

def model_index
  @model_index
end

#move_dirObject

Returns the value of attribute move_dir.



18
19
20
# File 'lib/quake/entity.rb', line 18

def move_dir
  @move_dir
end

#positionObject

Returns the value of attribute position.



18
19
20
# File 'lib/quake/entity.rb', line 18

def position
  @position
end

#propertiesObject

Returns the value of attribute properties.



18
19
20
# File 'lib/quake/entity.rb', line 18

def properties
  @properties
end

#skinObject

Returns the value of attribute skin.



18
19
20
# File 'lib/quake/entity.rb', line 18

def skin
  @skin
end

#soundsObject

Returns the value of attribute sounds.



18
19
20
# File 'lib/quake/entity.rb', line 18

def sounds
  @sounds
end

#spawnflagsObject

Returns the value of attribute spawnflags.



18
19
20
# File 'lib/quake/entity.rb', line 18

def spawnflags
  @spawnflags
end

#speedObject

Returns the value of attribute speed.



18
19
20
# File 'lib/quake/entity.rb', line 18

def speed
  @speed
end

#stateObject

Returns the value of attribute state.



18
19
20
# File 'lib/quake/entity.rb', line 18

def state
  @state
end

#styleObject

Returns the value of attribute style.



18
19
20
# File 'lib/quake/entity.rb', line 18

def style
  @style
end

#super_damage_finishedObject

Returns the value of attribute super_damage_finished.



18
19
20
# File 'lib/quake/entity.rb', line 18

def super_damage_finished
  @super_damage_finished
end

#targetObject

Returns the value of attribute target.



18
19
20
# File 'lib/quake/entity.rb', line 18

def target
  @target
end

#targetnameObject

Returns the value of attribute targetname.



18
19
20
# File 'lib/quake/entity.rb', line 18

def targetname
  @targetname
end

#think_timeObject

Returns the value of attribute think_time.



18
19
20
# File 'lib/quake/entity.rb', line 18

def think_time
  @think_time
end

#velocityObject

Returns the value of attribute velocity.



18
19
20
# File 'lib/quake/entity.rb', line 18

def velocity
  @velocity
end

#waitObject

Returns the value of attribute wait.



18
19
20
# File 'lib/quake/entity.rb', line 18

def wait
  @wait
end

Instance Method Details

#[](key) ⇒ Object



85
# File 'lib/quake/entity.rb', line 85

def [](key) = @properties[key]

#absorb_damage(amount, game_time: nil) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/quake/entity.rb', line 105

def absorb_damage(amount, game_time: nil)
  damage = amount.to_f
  save = (@armortype * damage).ceil
  if save >= @armorvalue
    save = @armorvalue
    @armortype = 0.0
    @items -= @items & IT_ARMOR_MASK
  end
  @armorvalue -= save
  protected = (@flags & FL_GODMODE) != 0 ||
              (game_time && @invincible_finished.positive? && @invincible_finished >= game_time.to_f)
  take = protected ? 0.0 : (damage - save).ceil.to_f
  { take: take, save: save.to_f, protected: protected }
end

#apply_health_damage(taken) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/quake/entity.rb', line 120

def apply_health_damage(taken)
  @health -= taken
  @health = -99.0 if @health < -99.0
  if @health <= 0
    @removed = true
  end
end

#brush_entity?Boolean

Returns:

  • (Boolean)


87
# File 'lib/quake/entity.rb', line 87

def brush_entity? = !@model_index.nil?

#damageable?Boolean

Returns:

  • (Boolean)


91
92
93
94
95
# File 'lib/quake/entity.rb', line 91

def damageable?
  return false if removed?

  @takedamage != 0
end

#forward_vectorObject

Direction vector from the "angle" field (Quake convention)



129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/quake/entity.rb', line 129

def forward_vector
  return angles_forward_vector if @angles != Math::Vec3::ORIGIN

  case @angle.to_i
  when -1 # UP
    Math::Vec3.new(0.0, 0.0, 1.0)
  when -2 # DOWN
    Math::Vec3.new(0.0, 0.0, -1.0)
  else
    rad = @angle * ::Math::PI / 180.0
    Math::Vec3.new(::Math.cos(rad), ::Math.sin(rad), 0.0)
  end
end

#removed?Boolean

Returns:

  • (Boolean)


89
# File 'lib/quake/entity.rb', line 89

def removed? = !!@removed

#take_damage(amount, game_time: nil) ⇒ Object



97
98
99
100
101
102
103
# File 'lib/quake/entity.rb', line 97

def take_damage(amount, game_time: nil)
  return 0.0 unless damageable?

  result = absorb_damage(amount, game_time: game_time)
  apply_health_damage(result[:take]) if result[:take].positive?
  result[:take].to_f
end