diff --git a/src/city.gd b/src/city.gd index 6268112..b95beca 100644 --- a/src/city.gd +++ b/src/city.gd @@ -2,12 +2,15 @@ extends Node # a single host const host = preload("res://src/host.tscn") +#const TRAIL_MAX_LENGTH = 30 + ### city attributes export var movement_speed = 100 export var citizens = 100 export var hospital_beds = 20 -export var social_distance = 150 +export var social_distance = 40 + # Called when the node enters the scene tree for the first time. func _ready(): diff --git a/src/city.tscn b/src/city.tscn index 79f6aca..dbad156 100644 --- a/src/city.tscn +++ b/src/city.tscn @@ -33,3 +33,5 @@ shape = SubResource( 2 ) current = true [node name="hosts" type="Node" parent="."] + +[node name="trails" type="Node" parent="."] diff --git a/src/host.gd b/src/host.gd index e5a01e9..6c6acdd 100644 --- a/src/host.gd +++ b/src/host.gd @@ -3,9 +3,11 @@ extends KinematicBody2D const COLOR_BASE = Color.gray const COLOR_DEATH = Color.black +const TRAIL_MAX_LENGTH = 15 # TODO - get each host a randomize name onready var sprite = get_node("Sprite") +onready var outline = get_node("Outline") onready var area = get_node("Area") onready var area_shape = get_node("Area/Shape") onready var infections = get_node("Infections") @@ -19,13 +21,20 @@ var is_quarantined : bool = false setget set_quarantined var is_hospitalized : bool = false setget set_hospitalized # city in which the host belongs to -var city +var city: Node + +var trail: Line2D # movement direction var direction : Vector2 = Vector2(0,0) +var direction_evade : Vector2 = Vector2(0,0) # current speed, comes from city, will be set in birth var movement_speed + +# temporary variables +var tmp_delta = 0 + ### infection attributes # those getters will search through all current infections of a host # is set the host is infected by a given virus @@ -46,11 +55,14 @@ func set_hospitalized(val: bool): is_hospitalized = val func get_infected() -> bool: - return find_infection('is_infected', null) +# return find_infection('is_infected', null) + return is_infected func get_symptoms() -> bool: - return find_infection('is_symptoms', null) +# return find_infection('is_symptoms', null) + return is_symptoms func get_contagious() -> bool: - return find_infection('is_contagious', null) +# return find_infection('is_contagious', null) + return is_contagious # find a given attribute from any (null) or a specific virus func find_infection(attribute, virus = null): @@ -63,6 +75,10 @@ func find_infection(attribute, virus = null): else: return null +func on_infection_change(attribute, value): + if attribute in self: + self.set(attribute, value) + # when a dot is infected by a virus, it get added to the list of infections func infect(virus): #var infection : Infection @@ -74,6 +90,8 @@ func infect(virus): # TODO - change here to duplicate/clone - instead of ref infection.host = self infection.virus = virus + infection.connect("SIGNAL_INFECTION_CHANGE", self, "on_infection_change") + # add infection to hosts list infections.add_child(infection) @@ -131,55 +149,71 @@ func _ready(): func birth(city): self.city = city -func _physics_process(delta: float) -> void: + # add trail + trail = Line2D.new() + trail.width = 1 + # hide it + trail.visible = false + city.get_node("trails").add_child(trail) +func _physics_process(delta: float) -> void: + + tmp_delta += delta + + if tmp_delta > 0.1: + tmp_delta -= 0.1 + add_trail(self.global_position) # if host is dead - slowing down until stopping if is_dead: movement_speed *= 0.99 direction *= 0.99 + trail.visible = false - elif self.is_symptoms: + if is_symptoms: + trail.visible = true if !has_sound(): # if symptoms are shown - make some noise Effects.cough(self) + + set_outline(sprite.modulate) + # check which hosts are nearby + var nearby_infected = false + var nearby_hosts = area.get_overlapping_areas() + if len(nearby_hosts) > 0: + for nearby_host in nearby_hosts: + + var collision_vector = nearby_host.global_position - self.position + var normalized_direction = collision_vector.normalized() + var inverse_distance = area_shape.shape.radius*2 - collision_vector.length() + var inverse_distance_lerped = 1 - inverse_lerp(0, area_shape.shape.radius*2, collision_vector.length()) +# var inverse_distance_lerped = 1 - inverse_lerp(0, pow(area_shape.shape.radius*2, 2), pow(collision_vector.length(),2) ) +# +# print("positions: ", nearby_host.position, " self: ", self.position) +# print("area_shape.shape.radius: ", area_shape.shape.radius) +# print("collision_vector: ", collision_vector) +# print("vector_length: ", collision_vector.length()) +# print("normalized_direction: ", normalized_direction) +# print("inverse_distance: ", inverse_distance) +# print("inverse_distance_lerped: ", inverse_distance_lerped) +# print("#####") + + if nearby_host.owner.is_symptoms and not is_dead: + direction_evade -= inverse_distance_lerped * normalized_direction * delta + nearby_infected = true + set_outline(Color.pink) + if is_symptoms and not nearby_host.owner.is_dead: + nearby_host.owner.direction_evade += inverse_distance_lerped * normalized_direction * delta + nearby_host.owner.set_outline(Color.black) +# nearby_host.owner.direction = nearby_host.owner.direction + (inverse_distance_lerped * normalized_direction * delta) + + # if no infections are nearby - slowdown + if nearby_infected == false: + direction_evade = Vector2(0,0) - # check which hosts are nearby - var nearby_hosts = area.get_overlapping_areas() - if len(nearby_hosts) > 0: - for nearby_host in nearby_hosts: - # print("found host: ", nearby_host) - # print("direction: ", (nearby_host.position - self.position)) - # print("normalized: ", (nearby_host.position - self.position).normalized()) - # print("length: ", (nearby_host.position - self.position).length()) - # print("distance: ", (nearby_host.position - self.position).length()) - # print("#####") - # direction = ( (self.position - ).normalized()).normalized() - # direction = self.position.reflect((nearby_host.position - self.position).normalized()) - var collision_vector = nearby_host.global_position - self.position - var normalized_direction = collision_vector.normalized() - var inverse_distance = area_shape.shape.radius*2 - collision_vector.length() - var inverse_distance_lerped = 1 - inverse_lerp(0, area_shape.shape.radius*2, collision_vector.length()) - # var inverse_distance_lerped = 1 - inverse_lerp(0, pow(area_shape.shape.radius*2, 2), pow(collision_vector.length(),2) ) - # - # print("positions: ", nearby_host.position, " self: ", self.position) - # print("area_shape.shape.radius: ", area_shape.shape.radius) - # print("collision_vector: ", collision_vector) - # print("vector_length: ", collision_vector.length()) - # print("normalized_direction: ", normalized_direction) - # print("inverse_distance: ", inverse_distance) - # print("inverse_distance_lerped: ", inverse_distance_lerped) - # print("#####") - - #if is_symptoms or nearby_host.owner.is_symptoms: - - direction = direction - (inverse_distance_lerped * normalized_direction * delta) / (len(nearby_hosts)) - nearby_host.owner.direction = nearby_host.owner.direction + (inverse_distance_lerped * normalized_direction * delta) / (len(nearby_hosts)) - # nearby_host.owner.direction = nearby_host.owner.direction + (inverse_distance_lerped * normalized_direction * delta) - # Get velocity - var velocity = movement_speed * direction + var velocity = movement_speed * (direction + direction_evade) # if host show symptoms, drop movement speed if self.is_symptoms: @@ -192,15 +226,24 @@ func _physics_process(delta: float) -> void: if collision != null: # bounce on collision direction = direction.bounce(collision.normal) + direction_evade = direction_evade.bounce(collision.normal) if collision.collider.get_script() == load("res://src/host.gd"): # if 2 hosts meet meet(collision.collider) else: # only if no collision was registered pass +func add_trail(point: Vector2): + trail.add_point(point) + if len(trail.points) > TRAIL_MAX_LENGTH: + trail.remove_point(0) + +# check if current node does already have a sound set func has_sound(): return has_node("sound") # change color modulation of host func set_color(color: Color): sprite.modulate = color +func set_outline(color: Color): + outline.modulate = color diff --git a/src/host.tscn b/src/host.tscn index 401477c..62adda3 100644 --- a/src/host.tscn +++ b/src/host.tscn @@ -7,7 +7,7 @@ radius = 4.97443 [sub_resource type="CircleShape2D" id=2] -radius = 50.0 +radius = 40.0 [node name="host" type="KinematicBody2D"] script = ExtResource( 2 ) @@ -15,6 +15,11 @@ script = ExtResource( 2 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource( 1 ) +[node name="Outline" type="Sprite" parent="."] +modulate = Color( 0.898039, 0.0392157, 0.0392157, 1 ) +scale = Vector2( 0.14, 0.14 ) +texture = ExtResource( 1 ) + [node name="Sprite" type="Sprite" parent="."] scale = Vector2( 0.1, 0.1 ) texture = ExtResource( 1 ) @@ -25,3 +30,5 @@ texture = ExtResource( 1 ) [node name="Shape" type="CollisionShape2D" parent="Area"] shape = SubResource( 2 ) + +[node name="Line2D" type="Line2D" parent="."] diff --git a/src/infection.gd b/src/infection.gd index 164cb2e..6932870 100644 --- a/src/infection.gd +++ b/src/infection.gd @@ -18,6 +18,7 @@ signal SIGNAL_SYMPTOMS signal SIGNAL_CURED signal SIGNAL_IMMUNE signal SIGNAL_DEATH +signal SIGNAL_INFECTION_CHANGE # infection.connect("SIGNAL_VULNERABLE", infection, "on_contagion") # infection.emit_signal("SIGNAL_CONTAGIOUS") @@ -110,18 +111,21 @@ func on_infected(): is_infected = true host.set_color(COLOR_INFECTED) emit_signal("SIGNAL_INFECTED") + emit_signal("SIGNAL_INFECTION_CHANGE", "is_infected", is_infected) func on_contagion(): if Effects.chance(virus.chance_of_contagion): is_contagious = true host.set_color(COLOR_CONTAGIOUS) emit_signal("SIGNAL_CONTAGIOUS") + emit_signal("SIGNAL_INFECTION_CHANGE", "is_contagious", is_contagious) func on_symptoms(): if Effects.chance(virus.chance_of_symptoms): is_symptoms = true host.set_color(COLOR_SYMPTOMS) emit_signal("SIGNAL_SYMPTOMS") + emit_signal("SIGNAL_INFECTION_CHANGE", "is_symptoms", is_symptoms) func on_cure(): if Effects.chance(virus.chance_of_cure): @@ -129,17 +133,21 @@ func on_cure(): is_contagious = false is_symptoms = false timer_to_death = -1 - host.set_color(COLOR_VULNERABLE) emit_signal("SIGNAL_CURED") + emit_signal("SIGNAL_INFECTION_CHANGE", "is_infected", false) + emit_signal("SIGNAL_INFECTION_CHANGE", "is_contagious", false) + emit_signal("SIGNAL_INFECTION_CHANGE", "is_symptoms", false) if Effects.chance(virus.chance_of_immune): is_immune = true host.set_color(COLOR_IMMUNE) emit_signal("SIGNAL_IMMUNE") + emit_signal("SIGNAL_INFECTION_CHANGE", "is_immune", is_immune) else: # was not immunized - pass + host.set_color(COLOR_VULNERABLE) + emit_signal("SIGNAL_VULNERABLE") else: # could not be cured.. # another try after timer_to_cure @@ -160,3 +168,8 @@ func on_death(): is_infected = false host.set_color(host.COLOR_DEATH) emit_signal("SIGNAL_DEATH") + emit_signal("SIGNAL_INFECTION_CHANGE", "is_infected", false) + emit_signal("SIGNAL_INFECTION_CHANGE", "is_contagious", false) + emit_signal("SIGNAL_INFECTION_CHANGE", "is_symptoms", false) + emit_signal("SIGNAL_INFECTION_CHANGE", "is_immune", false) + emit_signal("SIGNAL_INFECTION_CHANGE", "is_dead", host.is_dead) diff --git a/src/main.gd b/src/main.gd index 442976f..5d272fb 100644 --- a/src/main.gd +++ b/src/main.gd @@ -13,5 +13,5 @@ func _physics_process(delta: float) -> void: tmp += delta if tmp > 3: - tmp = 0 -# print("sum speed: ",sum_speed) + tmp -= 3 + print("sum speed: ",sum_speed)