Class: Quake::Game::PlayerState
- Inherits:
-
Object
- Object
- Quake::Game::PlayerState
- Defined in:
- lib/quake/game/player_state.rb
Overview
Tracks player game state: health, armor, ammo, weapons. Separate from physics (Physics::Player handles movement/collision).
Defined Under Namespace
Classes: FireResult
Constant Summary collapse
- WEAPONS =
%i[axe shotgun super_shotgun nailgun super_nailgun grenade_launcher rocket_launcher lightning_gun].freeze
- WEAPON_MODELS =
{ axe: "progs/v_axe.mdl", shotgun: "progs/v_shot.mdl", super_shotgun: "progs/v_shot2.mdl", nailgun: "progs/v_nail.mdl", super_nailgun: "progs/v_nail2.mdl", grenade_launcher: "progs/v_rock.mdl", rocket_launcher: "progs/v_rock2.mdl", lightning_gun: "progs/v_light.mdl" }.freeze
- WEAPON_AMMO =
Ammo type per weapon
{ axe: nil, shotgun: :shells, super_shotgun: :shells, nailgun: :nails, super_nailgun: :nails, grenade_launcher: :rockets, rocket_launcher: :rockets, lightning_gun: :cells }.freeze
- POWERUP_DURATIONS =
{ biosuit: 30.0, pentagram: 30.0, ring: 30.0, quad: 30.0 }.freeze
- EF_DIMLIGHT =
8- EF_BLUE =
64- EF_RED =
128- POWERUP_EFFECT_BITS =
EF_DIMLIGHT | EF_BLUE | EF_RED
- FL_CLIENT =
8- FL_GODMODE =
64- FL_WATERJUMP =
2048- FL_JUMPRELEASED =
4096- WEAPON_ITEM_INDEX =
{ shotgun: 0, super_shotgun: 1, nailgun: 2, super_nailgun: 3, grenade_launcher: 4, rocket_launcher: 5, lightning_gun: 6 }.freeze
- WEAPON_FIRE =
QuakeC weapons.qc/player.qc weapon fire parameters.
{ axe: { cooldown: 0.5, ammo_type: nil, ammo_cost: 0, sound: "weapons/ax1.wav", range: 64.0, damage: 20, animation_frames: 1..4, kind: :axe }, shotgun: { cooldown: 0.5, ammo_type: :shells, ammo_cost: 1, sound: "weapons/guncock.wav", pellets: 6, range: 2048.0, spread_x: 0.04, spread_y: 0.04, damage: 4, kick: :small, animation_frames: 1..6, kind: :bullets }, super_shotgun: { cooldown: 0.7, ammo_type: :shells, ammo_cost: 2, sound: "weapons/shotgn2.wav", pellets: 14, range: 2048.0, spread_x: 0.14, spread_y: 0.08, damage: 4, kick: :big, animation_frames: 1..6, kind: :bullets }, nailgun: { cooldown: 0.2, ammo_type: :nails, ammo_cost: 1, sound: "weapons/rocket1i.wav", range: 1000.0, damage: 9, kick: :small, animation_frames: 1..8, kind: :spike }, super_nailgun: { cooldown: 0.2, ammo_type: :nails, ammo_cost: 2, sound: "weapons/spike2.wav", range: 1000.0, damage: 18, kick: :small, animation_frames: 1..8, kind: :spike }, rocket_launcher: { cooldown: 0.8, ammo_type: :rockets, ammo_cost: 1, sound: "weapons/sgun1.wav", range: 1000.0, damage: 100, damage_variance: 20, radius_damage: 120, kick: :small, animation_frames: 1..6, kind: :rocket }, lightning_gun: { cooldown: 0.1, ammo_type: :cells, ammo_cost: 1, sound: "weapons/lhit.wav", range: 600.0, damage: 30, kick: :small, animation_frames: 1..4, kind: :lightning }, grenade_launcher: { cooldown: 0.6, ammo_type: :rockets, ammo_cost: 1, sound: "weapons/grenade.wav", damage: 120, radius_damage: 120, kick: :small, animation_frames: 1..6, kind: :grenade } }.freeze
- MAX_HEALTH =
Max ammo capacities (from Quake defs.qc)
100- MAX_MEGA_HEALTH =
250- MAX_ARMOR =
200- MAX_SHELLS =
100- MAX_NAILS =
200- MAX_ROCKETS =
100- MAX_CELLS =
100- DEAD_NO =
0- DEAD_DYING =
1- DEAD_DEAD =
2- DEAD_RESPAWNABLE =
3- DEFAULT_VIEW_OFFSET =
Math::Vec3.new(0.0, 0.0, 22.0)
- DEATH_VIEW_OFFSET =
Math::Vec3.new(0.0, 0.0, -8.0)
- GIB_VIEW_OFFSET =
Math::Vec3.new(0.0, 0.0, 8.0)
- ARMOR_SAVE =
{ 0 => 0.0, 1 => 0.3, 2 => 0.6, 3 => 0.8, 0.0 => 0.0, 0.3 => 0.3, 0.6 => 0.6, 0.8 => 0.8 }.freeze
- AMMO_CAPS =
{ shells: MAX_SHELLS, nails: MAX_NAILS, rockets: MAX_ROCKETS, cells: MAX_CELLS }.freeze
- WEAPON_PICKUP_RANK =
QuakeC items.qc RankForWeapon: lower ranks are preferred on pickup.
{ lightning_gun: 1, rocket_launcher: 2, super_nailgun: 3, grenade_launcher: 4, super_shotgun: 5, nailgun: 6 }.freeze
Instance Attribute Summary collapse
-
#ammo ⇒ Object
readonly
Returns the value of attribute ammo.
-
#armor ⇒ Object
Returns the value of attribute armor.
-
#armor_type ⇒ Object
Returns the value of attribute armor_type.
-
#b_switch ⇒ Object
Returns the value of attribute b_switch.
-
#centerprint ⇒ Object
Returns the value of attribute centerprint.
-
#current_weapon ⇒ Object
Returns the value of attribute current_weapon.
-
#deadflag ⇒ Object
Returns the value of attribute deadflag.
-
#deathtype ⇒ Object
Returns the value of attribute deathtype.
-
#effects ⇒ Object
readonly
Returns the value of attribute effects.
-
#face_anim_time ⇒ Object
Returns the value of attribute face_anim_time.
-
#flags ⇒ Object
Returns the value of attribute flags.
-
#frags ⇒ Object
Returns the value of attribute frags.
-
#health ⇒ Object
Returns the value of attribute health.
-
#keys_owned ⇒ Object
readonly
Returns the value of attribute keys_owned.
-
#megahealth_rot_time ⇒ Object
readonly
Returns the value of attribute megahealth_rot_time.
-
#powerup_finished ⇒ Object
readonly
Returns the value of attribute powerup_finished.
-
#powerup_warning_time ⇒ Object
readonly
Returns the value of attribute powerup_warning_time.
-
#serverflags ⇒ Object
readonly
Returns the value of attribute serverflags.
-
#show_hostile ⇒ Object
Returns the value of attribute show_hostile.
-
#view_offset ⇒ Object
Returns the value of attribute view_offset.
-
#w_switch ⇒ Object
Returns the value of attribute w_switch.
-
#weapon_gettime ⇒ Object
readonly
Returns the value of attribute weapon_gettime.
-
#weapon_model ⇒ Object
Returns the value of attribute weapon_model.
-
#weapons_owned ⇒ Object
readonly
Returns the value of attribute weapons_owned.
Instance Method Summary collapse
-
#add_ammo(type, amount, auto_switch: false, water_level: 0) ⇒ Object
Add ammo, returns true if picked up.
-
#add_armor(points, type) ⇒ Object
Add armor, returns true if picked up.
- #add_backpack(ammo:, weapon: nil, water_level: 0, game_time: nil, b_switch: nil) ⇒ Object
-
#add_health(amount, mega: false, game_time: nil) ⇒ Object
Add health, returns true if picked up.
- #add_key(key) ⇒ Object
- #add_powerup(powerup, game_time:, finish_time: nil) ⇒ Object
- #add_sigil(flags) ⇒ Object
- #advance_serverflags_command ⇒ Object
- #alive? ⇒ Boolean
- #apply_changelevel_parms ⇒ Object
- #backpack_weapon_switch_allowed?(weapon, water_level, b_switch) ⇒ Boolean
- #best_weapon(water_level: 0) ⇒ Object
- #can_fire_current_weapon? ⇒ Boolean
- #classname ⇒ Object
- #clear_powerups_on_death ⇒ Object
- #clear_temporary_powerups ⇒ Object
- #consume_key(key) ⇒ Object
- #current_ammo_count ⇒ Object
- #current_ammo_type ⇒ Object
- #current_weapon_cooldown ⇒ Object
- #current_weapon_model ⇒ Object
- #effective_fire_definition ⇒ Object
- #fire_current_weapon(water_level: 0, deathmatch: 0) ⇒ Object
-
#give_weapon(weapon, ammo_type: nil, ammo_amount: 0, water_level: 0, game_time: nil, w_switch: nil) ⇒ Object
Give weapon, returns true if Quake weapon_touch accepts the pickup.
- #handle_impulse_command(impulse) ⇒ Object
- #has_key?(key) ⇒ Boolean
-
#initialize ⇒ PlayerState
constructor
A new instance of PlayerState.
- #invulnerable_to_damage?(game_time:) ⇒ Boolean
-
#next_weapon ⇒ Object
Cycle to next owned weapon (mousewheel or number keys).
- #powerup_active?(powerup, game_time:) ⇒ Boolean
- #powerup_item_active?(powerup, game_time:) ⇒ Boolean
- #prev_weapon ⇒ Object
- #record_weapon_gettime(weapon, game_time) ⇒ Object
- #reset_spawn_runtime_fields ⇒ Object
- #reset_to_new_parms ⇒ Object
-
#select_weapon(slot) ⇒ Object
Select weapon by slot number (1-8).
- #selectable_weapon?(weapon) ⇒ Boolean
- #switch_to_best_weapon(water_level: 0) ⇒ Object
- #take_damage(amount, game_time: nil) ⇒ Object
- #update_megahealth(game_time) ⇒ Object
- #update_powerup_effects(game_time) ⇒ Object
- #update_powerups(game_time) ⇒ Object
- #weapon_code(weapon) ⇒ Object
- #weapon_pickup_rank(weapon) ⇒ Object
- #weapon_switch_allowed?(weapon, water_level, w_switch) ⇒ Boolean
Constructor Details
#initialize ⇒ PlayerState
Returns a new instance of PlayerState.
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 |
# File 'lib/quake/game/player_state.rb', line 172 def initialize @health = 100 @armor = 0 @armor_type = 0 # 0=none, 1=green(30%), 2=yellow(60%), 3=red(80%) @current_weapon = :shotgun @weapons_owned = Set.new([:axe, :shotgun]) @keys_owned = Set.new @serverflags = 0 @flags = FL_CLIENT @ammo = { shells: 25, nails: 0, rockets: 0, cells: 0 } @powerup_finished = {} @powerup_warning_time = {} @weapon_gettime = {} @megahealth_rot_time = nil @effects = 0 @deathtype = "" @deadflag = DEAD_NO @view_offset = DEFAULT_VIEW_OFFSET @weapon_model = nil @face_anim_time = 0.0 @frags = 0 @show_hostile = 0.0 @b_switch = 8 @w_switch = 8 @centerprint = nil end |
Instance Attribute Details
#ammo ⇒ Object (readonly)
Returns the value of attribute ammo.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def ammo @ammo end |
#armor ⇒ Object
Returns the value of attribute armor.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def armor @armor end |
#armor_type ⇒ Object
Returns the value of attribute armor_type.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def armor_type @armor_type end |
#b_switch ⇒ Object
Returns the value of attribute b_switch.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def b_switch @b_switch end |
#centerprint ⇒ Object
Returns the value of attribute centerprint.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def centerprint @centerprint end |
#current_weapon ⇒ Object
Returns the value of attribute current_weapon.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def current_weapon @current_weapon end |
#deadflag ⇒ Object
Returns the value of attribute deadflag.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def deadflag @deadflag end |
#deathtype ⇒ Object
Returns the value of attribute deathtype.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def deathtype @deathtype end |
#effects ⇒ Object (readonly)
Returns the value of attribute effects.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def effects @effects end |
#face_anim_time ⇒ Object
Returns the value of attribute face_anim_time.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def face_anim_time @face_anim_time end |
#flags ⇒ Object
Returns the value of attribute flags.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def flags @flags end |
#frags ⇒ Object
Returns the value of attribute frags.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def frags @frags end |
#health ⇒ Object
Returns the value of attribute health.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def health @health end |
#keys_owned ⇒ Object (readonly)
Returns the value of attribute keys_owned.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def keys_owned @keys_owned end |
#megahealth_rot_time ⇒ Object (readonly)
Returns the value of attribute megahealth_rot_time.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def megahealth_rot_time @megahealth_rot_time end |
#powerup_finished ⇒ Object (readonly)
Returns the value of attribute powerup_finished.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def powerup_finished @powerup_finished end |
#powerup_warning_time ⇒ Object (readonly)
Returns the value of attribute powerup_warning_time.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def powerup_warning_time @powerup_warning_time end |
#serverflags ⇒ Object (readonly)
Returns the value of attribute serverflags.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def serverflags @serverflags end |
#show_hostile ⇒ Object
Returns the value of attribute show_hostile.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def show_hostile @show_hostile end |
#view_offset ⇒ Object
Returns the value of attribute view_offset.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def view_offset @view_offset end |
#w_switch ⇒ Object
Returns the value of attribute w_switch.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def w_switch @w_switch end |
#weapon_gettime ⇒ Object (readonly)
Returns the value of attribute weapon_gettime.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def weapon_gettime @weapon_gettime end |
#weapon_model ⇒ Object
Returns the value of attribute weapon_model.
166 167 168 |
# File 'lib/quake/game/player_state.rb', line 166 def weapon_model @weapon_model end |
#weapons_owned ⇒ Object (readonly)
Returns the value of attribute weapons_owned.
169 170 171 |
# File 'lib/quake/game/player_state.rb', line 169 def weapons_owned @weapons_owned end |
Instance Method Details
#add_ammo(type, amount, auto_switch: false, water_level: 0) ⇒ Object
Add ammo, returns true if picked up
570 571 572 573 574 575 576 577 578 579 580 581 |
# File 'lib/quake/game/player_state.rb', line 570 def add_ammo(type, amount, auto_switch: false, water_level: 0) return false unless alive? cap = AMMO_CAPS[type] return false unless cap return false if @ammo[type] >= cap old_best = best_weapon(water_level: water_level) if auto_switch @ammo[type] = [@ammo[type] + amount, cap].min @current_weapon = best_weapon(water_level: water_level) if auto_switch && @current_weapon == old_best true end |
#add_armor(points, type) ⇒ Object
Add armor, returns true if picked up
391 392 393 394 395 396 397 398 399 400 401 402 403 |
# File 'lib/quake/game/player_state.rb', line 391 def add_armor(points, type) return false unless alive? # QuakeC armor_touch compares armortype * armorvalue against # incoming type * value, where armortype is the save fraction. current_protection = ARMOR_SAVE.fetch(@armor_type, 0.0) * @armor incoming_protection = ARMOR_SAVE.fetch(type, 0.0) * points return false if current_protection >= incoming_protection @armor = [points, MAX_ARMOR].min @armor_type = type true end |
#add_backpack(ammo:, weapon: nil, water_level: 0, game_time: nil, b_switch: nil) ⇒ Object
583 584 585 586 587 588 589 590 591 592 593 594 595 596 |
# File 'lib/quake/game/player_state.rb', line 583 def add_backpack(ammo:, weapon: nil, water_level: 0, game_time: nil, b_switch: nil) return false unless alive? ammo.each do |type, amount| add_ammo(type, amount) if amount.positive? end if weapon current = @current_weapon give_weapon(weapon, game_time: game_time) @current_weapon = current unless backpack_weapon_switch_allowed?(weapon, water_level, b_switch) end true end |
#add_health(amount, mega: false, game_time: nil) ⇒ Object
Add health, returns true if picked up
365 366 367 368 369 370 371 372 373 374 |
# File 'lib/quake/game/player_state.rb', line 365 def add_health(amount, mega: false, game_time: nil) max = mega ? MAX_MEGA_HEALTH : MAX_HEALTH return false if @health <= 0 return false if @health >= max amount = amount.to_f.ceil @health = [@health + amount, max].min @megahealth_rot_time = game_time.to_f + 5.0 if mega && game_time true end |
#add_key(key) ⇒ Object
414 415 416 417 418 419 420 |
# File 'lib/quake/game/player_state.rb', line 414 def add_key(key) return false unless alive? return false if @keys_owned.include?(key) @keys_owned.add(key) true end |
#add_powerup(powerup, game_time:, finish_time: nil) ⇒ Object
405 406 407 408 409 410 411 412 |
# File 'lib/quake/game/player_state.rb', line 405 def add_powerup(powerup, game_time:, finish_time: nil) return false unless alive? duration = POWERUP_DURATIONS.fetch(powerup) @powerup_finished[powerup] = finish_time&.to_f || game_time.to_f + duration @powerup_warning_time[powerup] = 1.0 true end |
#add_sigil(flags) ⇒ Object
430 431 432 433 434 435 436 |
# File 'lib/quake/game/player_state.rb', line 430 def add_sigil(flags) return false unless alive? sigil_flags = flags.to_i & 15 @serverflags |= sigil_flags true end |
#advance_serverflags_command ⇒ Object
438 439 440 |
# File 'lib/quake/game/player_state.rb', line 438 def advance_serverflags_command @serverflags = (@serverflags * 2) + 1 end |
#alive? ⇒ Boolean
258 259 260 |
# File 'lib/quake/game/player_state.rb', line 258 def alive? @health > 0 end |
#apply_changelevel_parms ⇒ Object
484 485 486 487 488 489 490 491 492 493 494 495 |
# File 'lib/quake/game/player_state.rb', line 484 def apply_changelevel_parms if @health <= 0 reset_to_new_parms return end @keys_owned.clear clear_temporary_powerups @megahealth_rot_time = nil @health = [[@health, 50].max, 100].min @ammo[:shells] = 25 if @ammo[:shells] < 25 end |
#backpack_weapon_switch_allowed?(weapon, water_level, b_switch) ⇒ Boolean
598 599 600 601 602 603 604 |
# File 'lib/quake/game/player_state.rb', line 598 def backpack_weapon_switch_allowed?(weapon, water_level, b_switch) return false if weapon == :lightning_gun && water_level.positive? switch_limit = b_switch.to_i switch_limit = 8 if switch_limit.zero? weapon_code(weapon) <= switch_limit end |
#best_weapon(water_level: 0) ⇒ Object
304 305 306 307 308 309 310 311 312 |
# File 'lib/quake/game/player_state.rb', line 304 def best_weapon(water_level: 0) return :lightning_gun if water_level <= 1 && @weapons_owned.include?(:lightning_gun) && @ammo[:cells] >= 1 return :super_nailgun if @weapons_owned.include?(:super_nailgun) && @ammo[:nails] >= 2 return :super_shotgun if @weapons_owned.include?(:super_shotgun) && @ammo[:shells] >= 2 return :nailgun if @weapons_owned.include?(:nailgun) && @ammo[:nails] >= 1 return :shotgun if @weapons_owned.include?(:shotgun) && @ammo[:shells] >= 1 :axe end |
#can_fire_current_weapon? ⇒ Boolean
266 267 268 269 270 271 272 |
# File 'lib/quake/game/player_state.rb', line 266 def can_fire_current_weapon? _weapon, fire = effective_fire_definition return false unless fire ammo_type = fire[:ammo_type] ammo_type.nil? || @ammo[ammo_type] >= fire[:ammo_cost] end |
#classname ⇒ Object
262 263 264 |
# File 'lib/quake/game/player_state.rb', line 262 def classname "player" end |
#clear_powerups_on_death ⇒ Object
480 481 482 |
# File 'lib/quake/game/player_state.rb', line 480 def clear_powerups_on_death clear_temporary_powerups end |
#clear_temporary_powerups ⇒ Object
521 522 523 524 525 |
# File 'lib/quake/game/player_state.rb', line 521 def clear_temporary_powerups @powerup_finished.clear @powerup_warning_time.clear @effects &= ~POWERUP_EFFECT_BITS end |
#consume_key(key) ⇒ Object
426 427 428 |
# File 'lib/quake/game/player_state.rb', line 426 def consume_key(key) @keys_owned.delete?(key) end |
#current_ammo_count ⇒ Object
203 204 205 206 |
# File 'lib/quake/game/player_state.rb', line 203 def current_ammo_count type = current_ammo_type type ? @ammo[type] : nil # nil = infinite (axe) end |
#current_ammo_type ⇒ Object
199 200 201 |
# File 'lib/quake/game/player_state.rb', line 199 def current_ammo_type WEAPON_AMMO[@current_weapon] end |
#current_weapon_cooldown ⇒ Object
318 319 320 |
# File 'lib/quake/game/player_state.rb', line 318 def current_weapon_cooldown WEAPON_FIRE.dig(@current_weapon, :cooldown) || 0.0 end |
#current_weapon_model ⇒ Object
208 209 210 211 212 |
# File 'lib/quake/game/player_state.rb', line 208 def current_weapon_model return @weapon_model unless @weapon_model.nil? WEAPON_MODELS[@current_weapon] end |
#effective_fire_definition ⇒ Object
547 548 549 550 551 552 553 554 555 556 557 |
# File 'lib/quake/game/player_state.rb', line 547 def effective_fire_definition if @current_weapon == :super_shotgun && @ammo[:shells] == 1 return [:shotgun, WEAPON_FIRE[:shotgun]] end if @current_weapon == :super_nailgun && @ammo[:nails] == 1 return [:nailgun, WEAPON_FIRE[:nailgun]] end [@current_weapon, WEAPON_FIRE[@current_weapon]] end |
#fire_current_weapon(water_level: 0, deathmatch: 0) ⇒ Object
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 |
# File 'lib/quake/game/player_state.rb', line 274 def fire_current_weapon(water_level: 0, deathmatch: 0) weapon, fire = effective_fire_definition return nil unless fire unless can_fire_current_weapon? @current_weapon = best_weapon(water_level: water_level) return nil end ammo_type = fire[:ammo_type] @ammo[ammo_type] -= fire[:ammo_cost] if ammo_type && deathmatch.to_i != 4 damage = fire[:damage] damage = 75 if weapon == :axe && deathmatch.to_i > 3 FireResult.new( weapon: weapon, sound: fire[:sound], pellets: fire[:pellets], range: fire[:range], spread_x: fire[:spread_x], spread_y: fire[:spread_y], damage: damage, damage_variance: fire[:damage_variance], radius_damage: fire[:radius_damage], kick: fire[:kick], animation_frames: fire[:animation_frames], kind: fire[:kind] ) end |
#give_weapon(weapon, ammo_type: nil, ammo_amount: 0, water_level: 0, game_time: nil, w_switch: nil) ⇒ Object
Give weapon, returns true if Quake weapon_touch accepts the pickup.
619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 |
# File 'lib/quake/game/player_state.rb', line 619 def give_weapon(weapon, ammo_type: nil, ammo_amount: 0, water_level: 0, game_time: nil, w_switch: nil) return false unless alive? had_weapon = @weapons_owned.include?(weapon) @weapons_owned.add(weapon) record_weapon_gettime(weapon, game_time) unless had_weapon add_ammo(ammo_type, ammo_amount) if ammo_type && ammo_amount > 0 if weapon_pickup_rank(weapon) < weapon_pickup_rank(@current_weapon) && weapon_switch_allowed?(weapon, water_level, w_switch) @current_weapon = weapon end true end |
#handle_impulse_command(impulse) ⇒ Object
245 246 247 248 249 250 251 252 253 254 255 256 |
# File 'lib/quake/game/player_state.rb', line 245 def handle_impulse_command(impulse) command = impulse.to_i if (1..WEAPONS.size).cover?(command) select_weapon(command) elsif command == 10 next_weapon elsif command == 11 advance_serverflags_command elsif command == 12 prev_weapon end end |
#has_key?(key) ⇒ Boolean
422 423 424 |
# File 'lib/quake/game/player_state.rb', line 422 def has_key?(key) @keys_owned.include?(key) end |
#invulnerable_to_damage?(game_time:) ⇒ Boolean
451 452 453 454 |
# File 'lib/quake/game/player_state.rb', line 451 def invulnerable_to_damage?(game_time:) finished = @powerup_finished[:pentagram] finished && finished >= game_time.to_f end |
#next_weapon ⇒ Object
Cycle to next owned weapon (mousewheel or number keys)
215 216 217 218 219 220 221 222 223 224 |
# File 'lib/quake/game/player_state.rb', line 215 def next_weapon idx = WEAPONS.index(@current_weapon) || 0 WEAPONS.size.times do idx = (idx + 1) % WEAPONS.size if selectable_weapon?(WEAPONS[idx]) @current_weapon = WEAPONS[idx] return end end end |
#powerup_active?(powerup, game_time:) ⇒ Boolean
442 443 444 |
# File 'lib/quake/game/player_state.rb', line 442 def powerup_active?(powerup, game_time:) (@powerup_finished[powerup] || 0.0) > game_time.to_f end |
#powerup_item_active?(powerup, game_time:) ⇒ Boolean
446 447 448 449 |
# File 'lib/quake/game/player_state.rb', line 446 def powerup_item_active?(powerup, game_time:) finished = @powerup_finished[powerup] finished && finished >= game_time.to_f end |
#prev_weapon ⇒ Object
226 227 228 229 230 231 232 233 234 235 |
# File 'lib/quake/game/player_state.rb', line 226 def prev_weapon idx = WEAPONS.index(@current_weapon) || 0 WEAPONS.size.times do idx = (idx - 1) % WEAPONS.size if selectable_weapon?(WEAPONS[idx]) @current_weapon = WEAPONS[idx] return end end end |
#record_weapon_gettime(weapon, game_time) ⇒ Object
647 648 649 650 651 652 |
# File 'lib/quake/game/player_state.rb', line 647 def record_weapon_gettime(weapon, game_time) index = WEAPON_ITEM_INDEX[weapon] return unless index && game_time @weapon_gettime[index] = game_time.to_f end |
#reset_spawn_runtime_fields ⇒ Object
497 498 499 500 501 502 503 504 505 506 507 |
# File 'lib/quake/game/player_state.rb', line 497 def reset_spawn_runtime_fields @flags = FL_CLIENT @deathtype = "" @deadflag = DEAD_NO @view_offset = DEFAULT_VIEW_OFFSET @weapon_model = nil @face_anim_time = 0.0 @show_hostile = 0.0 @weapon_gettime.clear clear_temporary_powerups end |
#reset_to_new_parms ⇒ Object
509 510 511 512 513 514 515 516 517 518 519 |
# File 'lib/quake/game/player_state.rb', line 509 def reset_to_new_parms @health = 100 @armor = 0 @armor_type = 0 @current_weapon = :shotgun @weapons_owned = Set.new([:axe, :shotgun]) @keys_owned.clear reset_spawn_runtime_fields @ammo = { shells: 25, nails: 0, rockets: 0, cells: 0 } @megahealth_rot_time = nil end |
#select_weapon(slot) ⇒ Object
Select weapon by slot number (1-8)
238 239 240 241 242 243 |
# File 'lib/quake/game/player_state.rb', line 238 def select_weapon(slot) return unless (1..WEAPONS.size).cover?(slot) weapon = WEAPONS[slot - 1] @current_weapon = weapon if selectable_weapon?(weapon) end |
#selectable_weapon?(weapon) ⇒ Boolean
559 560 561 562 563 564 565 566 567 |
# File 'lib/quake/game/player_state.rb', line 559 def selectable_weapon?(weapon) return false unless @weapons_owned.include?(weapon) fire = WEAPON_FIRE[weapon] return false unless fire ammo_type = fire[:ammo_type] ammo_type.nil? || @ammo[ammo_type] >= fire[:ammo_cost] end |
#switch_to_best_weapon(water_level: 0) ⇒ Object
314 315 316 |
# File 'lib/quake/game/player_state.rb', line 314 def switch_to_best_weapon(water_level: 0) @current_weapon = best_weapon(water_level: water_level) end |
#take_damage(amount, game_time: nil) ⇒ Object
527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 |
# File 'lib/quake/game/player_state.rb', line 527 def take_damage(amount, game_time: nil) amount = amount.to_f save = (ARMOR_SAVE.fetch(@armor_type, 0.0) * amount).ceil if save >= @armor save = @armor @armor_type = 0 end @armor -= save return { take: 0, save: save } if (@flags & FL_GODMODE) != 0 if game_time && invulnerable_to_damage?(game_time: game_time) return { take: 0, save: save } end take = (amount - save).ceil @health -= take @health = -99 if @health < -99 { take: take, save: save } end |
#update_megahealth(game_time) ⇒ Object
376 377 378 379 380 381 382 383 384 385 386 387 388 |
# File 'lib/quake/game/player_state.rb', line 376 def update_megahealth(game_time) return unless @megahealth_rot_time if @health <= MAX_HEALTH @megahealth_rot_time = nil return end return if game_time < @megahealth_rot_time ticks = ((game_time - @megahealth_rot_time).floor + 1).to_i @health = [@health - ticks, MAX_HEALTH].max @megahealth_rot_time += ticks @megahealth_rot_time = nil if @health <= MAX_HEALTH end |
#update_powerup_effects(game_time) ⇒ Object
466 467 468 469 470 471 472 473 474 475 476 477 478 |
# File 'lib/quake/game/player_state.rb', line 466 def update_powerup_effects(game_time) @effects &= ~POWERUP_EFFECT_BITS if powerup_active?(:pentagram, game_time: game_time) @effects |= EF_DIMLIGHT @effects |= EF_RED end if powerup_active?(:quad, game_time: game_time) @effects |= EF_DIMLIGHT @effects |= EF_BLUE end end |
#update_powerups(game_time) ⇒ Object
456 457 458 459 460 461 462 463 464 |
# File 'lib/quake/game/player_state.rb', line 456 def update_powerups(game_time) now = game_time.to_f update_powerup_effects(now) @powerup_finished.delete_if do |powerup, finished| expired = finished < now @powerup_warning_time.delete(powerup) if expired expired end end |
#weapon_code(weapon) ⇒ Object
606 607 608 609 610 611 612 613 614 615 616 |
# File 'lib/quake/game/player_state.rb', line 606 def weapon_code(weapon) case weapon when :super_shotgun then 3 when :nailgun then 4 when :super_nailgun then 5 when :grenade_launcher then 6 when :rocket_launcher then 7 when :lightning_gun then 8 else 1 end end |
#weapon_pickup_rank(weapon) ⇒ Object
643 644 645 |
# File 'lib/quake/game/player_state.rb', line 643 def weapon_pickup_rank(weapon) WEAPON_PICKUP_RANK.fetch(weapon, 7) end |
#weapon_switch_allowed?(weapon, water_level, w_switch) ⇒ Boolean
635 636 637 638 639 640 641 |
# File 'lib/quake/game/player_state.rb', line 635 def weapon_switch_allowed?(weapon, water_level, w_switch) return false if weapon == :lightning_gun && water_level.positive? switch_limit = w_switch.to_i switch_limit = 8 if switch_limit.zero? weapon_code(weapon) <= switch_limit end |