Просмотр исходного кода

:sparkles: lots of balancing improvements

Felix Bytow 10 месяцев назад
Родитель
Сommit
7a3328c3de
3 измененных файлов с 47 добавлено и 8 удалено
  1. 36 5
      assets/scenes/demon.gd
  2. 3 1
      assets/scenes/player_spawn_zone.gd
  3. 8 2
      screens/game.gd

+ 36 - 5
assets/scenes/demon.gd

@@ -7,6 +7,9 @@ class_name Demon
 
 @onready var gun_shot_sound: AudioStreamPlayer = $GunShotSound
 
+@export var shot_probability: float = 0.5
+var sp_modifier: float = 0.0
+
 var ammo: int = 0
 
 enum State {
@@ -25,6 +28,9 @@ func _process(_delta: float) -> void:
 	vision_polygon.visible = GlobalInput.visible_vision
 
 func _physics_process(_delta: float) -> void:
+	if state != State.STATE_IDLE:
+		return
+		
 	vision.force_shapecast_update()
 	if not vision.is_colliding():
 		return
@@ -32,7 +38,15 @@ func _physics_process(_delta: float) -> void:
 	var foe = vision.get_collider(0)
 	if foe == null || not (foe is Area2D):
 		return
-	shoot_at(foe as Area2D)
+	
+	var value = randf()
+	var actual_probability = shot_probability + sp_modifier
+	if value <= actual_probability:
+		sp_modifier = 0.0
+		await shoot_at(foe as Area2D)
+	else:
+		sp_modifier += 0.1
+		print("%s: not shooting (%.2f > %.2f)" % [name, value, actual_probability])
 
 func _on_mouse_entered():
 	if not GlobalInput.is_dragging():
@@ -71,7 +85,7 @@ func shoot_at(foe: Area2D) -> void:
 	if state != State.STATE_IDLE:
 		return
 	
-	print("%s: %d/%d" % [name, ammo, Game.max_ammo])
+	print("%s: Ammo = %d/%d" % [name, ammo, Game.max_ammo])
 	
 	if ammo <= 0:
 		await reload()
@@ -80,10 +94,27 @@ func shoot_at(foe: Area2D) -> void:
 		ammo -= 1
 		gun_shot_sound.play()
 		sprite.play("shoot")
-		if foe.has_method("die"):
-			foe.die()
+		
+		var distance: float = clampf((foe.global_position - global_position).length(), 140.0, 250.0)
+		var distance_percent: float = 1.0 - ((distance - 140.0) / 110.0)
+		#print(distance_percent)
+		var speed: float = minf(foe.speed, 100.0)
+		var speed_percent: float = 1.0 - ((speed - 64.0) / 36.0)
+		#print(speed_percent)
+		var base = Game.base_accuracy
+		var rest = (1.0 - base) / 2.0
+		var hit_chance: float = Game.base_accuracy + distance_percent * rest + speed_percent * rest
+		print("%s: Shooting at %s with %.2f hit chance" % [name, foe.name, hit_chance])
+		
+		var hit: float = randf()
+		if hit > hit_chance:
+			print("%s: missed shot (%.2f > %.2f)" % [name, hit, hit_chance])
 		else:
-			foe.queue_free()
+			if foe.has_method("die"):
+				foe.die()
+			else:
+				foe.queue_free()
+		
 		await sprite.animation_finished
 		if ammo <= 0:
 			await reload()

+ 3 - 1
assets/scenes/player_spawn_zone.gd

@@ -7,7 +7,8 @@ class_name PlayerSpawnZone
 const DEMON_SCENE: PackedScene = preload("res://assets/scenes/demon.tscn")
 
 func add_survivor() -> void:
-	if get_tree().get_nodes_in_group("survivor").size() >= 9:
+	var demon_count = get_tree().get_nodes_in_group("survivor").size()
+	if demon_count >= 9:
 		return
 	
 	var spot = find_first_free_spot()
@@ -15,6 +16,7 @@ func add_survivor() -> void:
 		return
 	
 	var demon = DEMON_SCENE.instantiate()
+	demon.name = "Demon #%d" % (demon_count + 1)
 	spot.add_child(demon)
 
 func find_first_free_spot() -> Node2D:

+ 8 - 2
screens/game.gd

@@ -39,6 +39,7 @@ enum Loot {
 const RELOAD_TIME: float = 4.0
 static var reload_time: float = RELOAD_TIME # seconds
 static var max_ammo: int = 1 # shots
+static var base_accuracy: float = 0.33 # percent
 
 var phase: Phase = Phase.PHASE_SETUP:
 	set(new_value):
@@ -158,7 +159,8 @@ const LOOT_SURVIVOR: String = "+1 SURVIVOR"
 const LOOT_HEALTH: String = "+3 HEALTH"
 const LOOT_AMMO: String = "BIGGER MAGAZINES"
 const LOOT_RELOAD_TIME: String = "FASTER RELOADING"
-const LOOTS: Array[String] = [LOOT_SURVIVOR, LOOT_HEALTH, LOOT_AMMO, LOOT_RELOAD_TIME]
+const LOOT_ACCURACY: String = "HIGHER ACCURACY"
+const LOOTS: Array[String] = [LOOT_SURVIVOR, LOOT_HEALTH, LOOT_AMMO, LOOT_RELOAD_TIME, LOOT_ACCURACY]
 
 func end_combat() -> void:
 	phase = Phase.PHASE_LOOT
@@ -168,6 +170,8 @@ func end_combat() -> void:
 	ui_root.add_child(vs)
 	var loots: Array[String] = []
 	loots.assign(LOOTS)
+	if get_survivors().size() >= 9:
+		loots.erase(LOOT_SURVIVOR)
 	loots.shuffle()
 	vs.set_loot_options(loots[0], loots[1], loots[2])
 	await vs.loot_selected
@@ -178,7 +182,6 @@ func end_combat() -> void:
 		self.waves_completed += 1
 		self.phase = Phase.PHASE_SETUP
 		self.next_phase_button.disabled = false
-		self.reset_survivors()
 		match loot:
 			LOOT_SURVIVOR:
 				self.player_spawn.add_survivor()
@@ -188,6 +191,9 @@ func end_combat() -> void:
 				Game.reload_time *= 0.9
 			LOOT_AMMO:
 				Game.max_ammo += 1
+			LOOT_ACCURACY:
+				Game.base_accuracy += 0.1
+		self.reset_survivors()
 	)
 	GlobalInput.dragging_disabled = false