Interactions

This commit is contained in:
Rendo 2025-12-26 01:31:21 +05:00
commit 4f6c151e25
31 changed files with 498 additions and 12 deletions

View file

@ -0,0 +1,12 @@
extends Node
var amount: float = 1.0
func _on_interactible_interacted(with: DraggableObject) -> void:
if with.is_in_group("flask"):
with.get_node("%Inventory").add_inventory(%Inventory.extract(%Inventory.total_amount * amount))
func _on_h_slider_value_changed(value: float) -> void:
amount = value
$"../HBoxContainer/Label".text = str(int(value*100.0)).pad_zeros(3) + "%"

View file

@ -0,0 +1 @@
uid://duirfi4j26g2i

View file

@ -7,6 +7,7 @@ class_name Interactible
var current_draggable: DraggableObject
var current_interaction: Interactible
signal begin_interaction(with: DraggableObject)
signal interacted(with: DraggableObject)
func _ready() -> void:
@ -15,7 +16,9 @@ func _ready() -> void:
canceled.connect(cancel_interaction)
func try_interact(draggable: DraggableObject) -> bool:
if draggable.interactible != null and visible == false:
if draggable.interactible != null and visible == false:
current_draggable = draggable
begin_interaction.emit(current_draggable)
if instant:
interact()
else:

View file

@ -0,0 +1,20 @@
extends Node
var mini_inventory: Array[RuntimeSubstanceData] = []
signal inventory_updated(substances: Array[RuntimeSubstanceData])
func _on_interactible_interacted(with: DraggableObject) -> void:
if with.is_in_group("solid_source") and mini_inventory == []:
mini_inventory = [RuntimeSubstanceData.new()]
mini_inventory[0].substance = with.get_node("SubstanceData").substance
mini_inventory[0].amount = 5
mini_inventory[0].temperature = 20
elif with.is_in_group("solid_source") and mini_inventory != []:
mini_inventory = []
elif with.is_in_group("flask") and mini_inventory != []:
with.get_node("%Inventory").add_inventory(mini_inventory)
mini_inventory = []
elif with.is_in_group("flask") and mini_inventory == []:
mini_inventory = with.get_node("%Inventory").extract_solid(5)
inventory_updated.emit(mini_inventory)

View file

@ -0,0 +1 @@
uid://cefmx4p018028

View file

@ -0,0 +1,22 @@
extends Node
var add_amount: float
func _on_interaction_interacted(with: DraggableObject) -> void:
if with.is_in_group("flask"):
var subs: RuntimeSubstanceData = RuntimeSubstanceData.new()
subs.amount = add_amount
subs.substance = $"../../SubstanceData".substance
subs.temperature = 20
with.get_node("%Inventory").add_substance(subs)
$"../HBoxContainer/SpinBox".value = 0
func _on_progress_bar_value_changed(value: float) -> void:
$"../HBoxContainer/SpinBox".set_value_no_signal(value)
add_amount = value
func _on_spin_box_value_changed(value: float) -> void:
$"../HBoxContainer/ProgressBar".set_value_no_signal(value)
add_amount = value

View file

@ -0,0 +1 @@
uid://bhnptwotw5bs8

View file

@ -3,4 +3,109 @@ extends Node
class_name Inventory
@export var open_on_top: bool
var inventory: Array[RuntimeSubstanceData]
var inventory: Dictionary[StringName,RuntimeSubstanceData]
var mean_temperature: float:
set(new_temperature):
mean_temperature = new_temperature
temperature_changed.emit(new_temperature)
update_temperature()
var total_amount: float:
set(value):
pass
get:
var result: float = 0
for sub in inventory:
result += inventory[sub].amount
return result
signal inventory_changed(substances: Array[RuntimeSubstanceData])
signal temperature_changed(to: float)
func add_substance(data: RuntimeSubstanceData) -> void:
if data.substance.scientific_name in inventory:
inventory[data.substance.scientific_name].add(data)
else:
inventory[data.substance.scientific_name] = data
check_for_reactions()
recalculate_temperature()
inventory_changed.emit(inventory.values())
func add_inventory(substances: Array[RuntimeSubstanceData]) -> void:
for sub in substances:
add_substance(sub)
func extract(amount: float) -> Array[RuntimeSubstanceData]:
if len(inventory) == 0:
return []
var result: Array[RuntimeSubstanceData] = []
var extract_amount = amount/len(inventory)
var sorted_by_amount: Array[RuntimeSubstanceData] = inventory.values()
sorted_by_amount.sort_custom(sort_by_amount)
for substance: RuntimeSubstanceData in sorted_by_amount:
var result_substance: RuntimeSubstanceData = substance.duplicate()
if substance.amount >= extract_amount:
result_substance.amount = extract_amount
inventory[result_substance.substance.scientific_name].amount -= extract_amount
else:
extract_amount += (extract_amount - result_substance.amount)/len(sorted_by_amount)
inventory[result_substance.substance.scientific_name].amount = 0
result.append(result_substance)
if inventory[result_substance.substance.scientific_name].amount == 0:
inventory.erase(result_substance.substance.scientific_name)
inventory_changed.emit(inventory.values())
return result
func extract_solid(amount: float) -> Array[RuntimeSubstanceData]:
if len(inventory) == 0:
return []
var result: Array[RuntimeSubstanceData] = []
var extract_amount = amount/len(inventory)
var sorted_by_amount: Array[RuntimeSubstanceData] = inventory.values()
sorted_by_amount.sort_custom(sort_by_amount)
sorted_by_amount = sorted_by_amount.filter(filter_solids)
for substance: RuntimeSubstanceData in sorted_by_amount:
var result_substance: RuntimeSubstanceData = substance.duplicate()
if substance.amount >= extract_amount:
result_substance.amount = extract_amount
inventory[result_substance.substance.scientific_name].amount -= extract_amount
else:
extract_amount += (extract_amount - result_substance.amount)/len(sorted_by_amount)
inventory[result_substance.substance.scientific_name].amount = 0
result.append(result_substance)
if inventory[result_substance.substance.scientific_name].amount == 0:
inventory.erase(result_substance.substance.scientific_name)
inventory_changed.emit(inventory.values())
return result
func sort_by_amount(a: RuntimeSubstanceData, b: RuntimeSubstanceData) -> bool:
return a.amount < b.amount
func filter_solids(a: RuntimeSubstanceData) -> bool:
return a.substance.melting_point > a.temperature
func update_temperature() -> void:
if len(inventory) == 0:
mean_temperature = 0
return
for sub in inventory:
inventory[sub].temperature = mean_temperature
check_for_reactions()
func recalculate_temperature() -> void:
if len(inventory) == 0:
mean_temperature = 0
return
var temperature_sum: float = 0
for sub in inventory:
temperature_sum += inventory[sub].temperature
mean_temperature = temperature_sum / len(inventory)
func check_for_reactions() -> void:
pass

View file

@ -2,6 +2,6 @@ extends Resource
class_name Reaction
@export var input_substances: Array[Substance]
@export var output_substances: Array[Substance]
@export var input_substances: Array[ReactionSubstance]
@export var output_substances: Array[ReactionSubstance]
@export var reaction_temperature: float = -1

View file

@ -0,0 +1,6 @@
extends Resource
class_name ReactionSubstance
@export var coefficient: int
@export var substance: Substance

View file

@ -0,0 +1 @@
uid://bb8o8l6u6fiai

View file

@ -6,6 +6,7 @@ class_name Substance
@export var scientific_name: StringName
@export var melting_point: float
@export var boiling_point: float
@export var liquid_transparency: float = 0.5
@export var color: Color
@export var prefer_scientific_name: bool
@export var is_solution: bool

View file

@ -5,3 +5,15 @@ class_name RuntimeSubstanceData
var substance: Substance
var amount: float
var temperature: float = 20.0
func add(data: RuntimeSubstanceData) -> void:
temperature = (temperature + data.temperature)/2.0
amount += data.amount
func duplicate() -> RuntimeSubstanceData:
var new_substance = RuntimeSubstanceData.new()
new_substance.substance = substance
new_substance.amount = amount
new_substance.temperature = temperature
return new_substance

46
src/substance_display.gd Normal file
View file

@ -0,0 +1,46 @@
extends MeshInstance3D
enum DisplayType{
Fluid,
Solid,
}
@export var display_type: DisplayType
func update_material(substances: Array[RuntimeSubstanceData]) -> void:
var mat: StandardMaterial3D = material_override
if len(substances) == 0:
visible = false
return
else:
visible = true
var total_weight = 0
for sub in substances:
total_weight += sub.amount
var alpha: float = 0
var color: Color = Color.WHITE
for sub in substances:
if display_type == DisplayType.Fluid:
alpha += sub.substance.liquid_transparency
color = color.lerp(sub.substance.color,sub.amount/total_weight)
if display_type == DisplayType.Fluid:
alpha /= len(substances)
color.a = alpha
mat.albedo_color = color
func update_material_unfiltered(substances: Array[RuntimeSubstanceData]):
match display_type:
DisplayType.Fluid:
var fluids = substances.filter(filter_liquids)
update_material(fluids)
DisplayType.Solid:
var solids = substances.filter(filter_solids)
update_material(solids)
func filter_liquids(sub: RuntimeSubstanceData): return sub.substance.melting_point < sub.temperature or sub.substance.is_solution
func filter_solids(sub: RuntimeSubstanceData): return sub.substance.melting_point > sub.temperature and not sub.substance.is_solution

View file

@ -0,0 +1 @@
uid://dig825r70a0sn

View file

@ -9,6 +9,8 @@ func _ready() -> void:
jar_fill_material.albedo_color = substance.color
if substance.melting_point > 20 and not substance.is_solution:
jar_fill_material.albedo_texture = preload("res://assets/textures/solid.png")
get_parent().add_to_group("solid_source")
else:
jar_fill_material.albedo_color.a = substance.liquid_transparency
get_parent().add_to_group("fluid_source")