Class: Quake::Game::ItemPickups
- Inherits:
-
Object
- Object
- Quake::Game::ItemPickups
- Defined in:
- lib/quake/game/item_pickups.rb
Overview
Handles item pickup logic: checks proximity between player and item entities, applies effects to PlayerState, marks items as picked up.
Constant Summary collapse
- PICKUP_RADIUS =
units (roughly player bbox width)
32.0- PLAYER_MINS =
Math::Vec3.new(-16.0, -16.0, -24.0)
- PLAYER_MAXS =
Math::Vec3.new(16.0, 16.0, 32.0)
- ITEMS =
Pickup definitions: classname -> { type:, ... }
{ # Health "item_health" => { type: :health, amount: 25 }, # Armor "item_armor1" => { type: :armor, points: 100, armor_type: 1 }, # green "item_armor2" => { type: :armor, points: 150, armor_type: 2 }, # yellow "item_armorInv" => { type: :armor, points: 200, armor_type: 3 }, # red # Ammo "item_shells" => { type: :ammo, ammo_type: :shells, amount: 20, big_amount: 40 }, "item_spikes" => { type: :ammo, ammo_type: :nails, amount: 25, big_amount: 50 }, "item_rockets" => { type: :ammo, ammo_type: :rockets, amount: 5, big_amount: 10 }, "item_cells" => { type: :ammo, ammo_type: :cells, amount: 6, big_amount: 12 }, "item_weapon" => { type: :legacy_weapon_ammo }, # Weapons (give weapon + starting ammo) "weapon_supershotgun" => { type: :weapon, weapon: :super_shotgun, ammo_type: :shells, ammo_amount: 5 }, "weapon_nailgun" => { type: :weapon, weapon: :nailgun, ammo_type: :nails, ammo_amount: 30 }, "weapon_supernailgun" => { type: :weapon, weapon: :super_nailgun, ammo_type: :nails, ammo_amount: 30 }, "weapon_grenadelauncher" => { type: :weapon, weapon: :grenade_launcher, ammo_type: :rockets, ammo_amount: 5 }, "weapon_rocketlauncher" => { type: :weapon, weapon: :rocket_launcher, ammo_type: :rockets, ammo_amount: 5 }, "weapon_lightning" => { type: :weapon, weapon: :lightning_gun, ammo_type: :cells, ammo_amount: 15 }, # Powerups "item_artifact_super_damage" => { type: :powerup, powerup: :quad }, "item_artifact_invulnerability" => { type: :powerup, powerup: :pentagram }, "item_artifact_envirosuit" => { type: :powerup, powerup: :biosuit }, "item_artifact_invisibility" => { type: :powerup, powerup: :ring }, # Keys "item_key1" => { type: :key, key: :silver }, "item_key2" => { type: :key, key: :gold }, # Episode runes "item_sigil" => { type: :sigil }, # Dropped by killed players in QuakeC DropBackpack. "item_backpack" => { type: :backpack } }.freeze
- BACKPACK_WEAPONS =
{ 1 => :shotgun, 2 => :super_shotgun, 4 => :nailgun, 8 => :super_nailgun, 16 => :grenade_launcher, 32 => :rocket_launcher, 64 => :lightning_gun, 4096 => :axe }.freeze
- SUB_REGEN_SOUND =
"items/itembk2.wav"- WEAPON_NETNAMES =
QuakeC items.qc netnames used by the "You got the ..." sprints.
{ super_shotgun: "Double-barrelled Shotgun", nailgun: "nailgun", super_nailgun: "Super Nailgun", grenade_launcher: "Grenade Launcher", rocket_launcher: "Rocket Launcher", lightning_gun: "Thunderbolt" }.freeze
- AMMO_NETNAMES =
{ shells: "shells", nails: "nails", rockets: "rockets", cells: "cells" }.freeze
- LEGACY_AMMO_NETNAMES =
Legacy item_weapon boxes use "spikes" for nails (items.qc).
{ shells: "shells", nails: "spikes", rockets: "rockets" }.freeze
- POWERUP_NETNAMES =
{ quad: "Quad Damage", pentagram: "Pentagram of Protection", ring: "Ring of Shadows", biosuit: "Biosuit" }.freeze
- KEY_NETNAMES =
{ silver: "silver key", gold: "gold key" }.freeze
- BACKPACK_WEAPON_NETNAMES =
items.qc BackpackTouch netnames (set in DropBackpack spawns).
{ axe: "Axe", shotgun: "Shotgun", super_shotgun: "Double-barrelled Shotgun", nailgun: "Nailgun", super_nailgun: "Super Nailgun", grenade_launcher: "Grenade Launcher", rocket_launcher: "Rocket Launcher", lightning_gun: "Thunderbolt" }.freeze
Instance Method Summary collapse
- #add_entity(ent) ⇒ Object
-
#check_pickups(player_pos, player_state, game_time: 0.0, water_level: 0) ⇒ Object
Check for pickups near player position.
- #hide_picked_item(ent, defn, game_time) ⇒ Object
-
#initialize(entities, deathmatch: 0) ⇒ ItemPickups
constructor
A new instance of ItemPickups.
- #owns_megahealth_rot_for?(player_state) ⇒ Boolean
- #picked_up?(entity) ⇒ Boolean
- #update(game_time, player_state: nil) ⇒ Object
Constructor Details
#initialize(entities, deathmatch: 0) ⇒ ItemPickups
Returns a new instance of ItemPickups.
134 135 136 137 138 |
# File 'lib/quake/game/item_pickups.rb', line 134 def initialize(entities, deathmatch: 0) @item_entities = entities.select { |e| ITEMS.key?(e.classname) } @picked_up = Set.new # entity object_ids that have been collected @deathmatch = deathmatch.to_i end |
Instance Method Details
#add_entity(ent) ⇒ Object
140 141 142 |
# File 'lib/quake/game/item_pickups.rb', line 140 def add_entity(ent) @item_entities << ent if ITEMS.key?(ent.classname) end |
#check_pickups(player_pos, player_state, game_time: 0.0, water_level: 0) ⇒ Object
Check for pickups near player position. Returns array of pickup event hashes (for sound/effect triggering).
170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/quake/game/item_pickups.rb', line 170 def check_pickups(player_pos, player_state, game_time: 0.0, water_level: 0) return [] unless player_state.alive? events = [] @item_entities.each do |ent| next if ent.removed? next if @picked_up.include?(ent.object_id) next if ent.instance_variable_get(:@solid) == 0 next unless touches_item?(player_pos, ent) defn = ITEMS[ent.classname] next unless defn # Built before try_pickup mutates PlayerState (QuakeC prints # from pre-pickup state, e.g. BackpackTouch weapon ownership). = (defn, ent, player_state) picked = try_pickup(player_state, defn, ent, game_time: game_time, water_level: water_level) if picked leaves_item = leave_weapon_pickup?(defn) unless leaves_item @picked_up.add(ent.object_id) hide_picked_item(ent, defn, game_time) end events << { classname: ent.classname, type: defn[:type], entity: ent, sound: pickup_sound(defn, ent), extra_sounds: ent.instance_variable_get(:@extra_pickup_sounds), use_targets: !leaves_item, message: } end end events end |
#hide_picked_item(ent, defn, game_time) ⇒ Object
222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/quake/game/item_pickups.rb', line 222 def hide_picked_item(ent, defn, game_time) if defn[:type] == :backpack ent.instance_variable_set(:@removed, true) else ent.instance_variable_set(:@mdl, ent["model"]) unless ent.instance_variable_get(:@mdl) ent.properties["model"] = "" ent.instance_variable_set(:@solid, 0) return if dropped_powerup?(ent, defn) schedule_regen(ent, defn, game_time) end end |
#owns_megahealth_rot_for?(player_state) ⇒ Boolean
214 215 216 217 218 219 220 |
# File 'lib/quake/game/item_pickups.rb', line 214 def owns_megahealth_rot_for?(player_state) @item_entities.any? do |ent| @picked_up.include?(ent.object_id) && ent.instance_variable_get(:@think) == :item_megahealth_rot && ent.instance_variable_get(:@owner).equal?(player_state) end end |
#picked_up?(entity) ⇒ Boolean
210 211 212 |
# File 'lib/quake/game/item_pickups.rb', line 210 def picked_up?(entity) @picked_up.include?(entity.object_id) end |
#update(game_time, player_state: nil) ⇒ Object
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/quake/game/item_pickups.rb', line 144 def update(game_time, player_state: nil) events = [] @item_entities.each do |ent| next if ent.removed? if ent.instance_variable_get(:@think) == :sub_remove && ent.think_time <= game_time ent.instance_variable_set(:@removed, true) next end next unless @picked_up.include?(ent.object_id) next if ent.think_time > game_time case ent.instance_variable_get(:@think) when :sub_regen regen_item(ent) events << { classname: ent.classname, type: :respawn, entity: ent, sound: SUB_REGEN_SOUND } when :item_megahealth_rot update_megahealth_item(ent, game_time) end end events end |