fb8a3f5658
- Introduced exact arithmetic with support for large integers and fractions in `exact.gd`, `big_integer.gd`, and `exact_value.gd`. - Implemented a comprehensive test suite in `test_exact_math.gd` to validate arithmetic operations against expected results. - Added a README in `math` directory to document the exact arithmetic system and its usage. - Ensured that all arithmetic operations maintain precision without floating-point errors, using a custom representation for large numbers. - Included methods for encoding and decoding exact values for serialization.
70 lines
2.9 KiB
GDScript
70 lines
2.9 KiB
GDScript
extends HBoxContainer
|
|
class_name OwniverseAction
|
|
const E = preload("res://world/owniverse/math/exact.gd")
|
|
|
|
signal action_pressed ( page_id , amount : Variant )
|
|
|
|
@onready var action_labels : Array = [$ActionControl0/Label, $ActionControl1/Label, $ActionControl2/Label, $ActionControl3/Label, $ActionControl4/Label]
|
|
|
|
var page_id: int = E.neg(1)
|
|
var current_item_id = ""
|
|
|
|
var action_values: Dictionary = {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
|
|
|
|
|
|
func set_actions(item_id: String, value: Variant, preview: Callable = Callable()) -> void:
|
|
current_item_id = item_id
|
|
var requests: Array = _get_distribution(value)
|
|
var unique_requests: Array = []
|
|
var displayed: Array = []
|
|
var labels: Dictionary = {}
|
|
# Prefer the largest request (including MAX) when previews or rounded
|
|
# scientific labels coincide. Keep the request paired with its preview.
|
|
for i in range(E.subtract(requests.size(), 1), E.neg(1), E.neg(1)):
|
|
if E.le(requests[i], 0): continue
|
|
var amount: Variant = (preview.call(requests[i]) if preview.is_valid() else requests[i])
|
|
if (((not E.finite(amount)) or E.lt(amount, 1)) or E.ne(amount, E.floor_value(amount))): continue
|
|
var text: String = _format_action_value(amount)
|
|
if (E.contains(displayed, amount) or labels.has(text)): continue
|
|
labels[text] = true
|
|
unique_requests.push_front(requests[i])
|
|
displayed.push_front(amount)
|
|
while E.lt(unique_requests.size(), 5):
|
|
unique_requests.append(0)
|
|
displayed.append(0)
|
|
_set_action_values(unique_requests, displayed)
|
|
|
|
func _get_distribution(value: Variant) -> Array:
|
|
if (E.lt(value, 1) or (not E.finite(value))):
|
|
return [0, 0, 0, 0, 0]
|
|
value = E.floor_value(value)
|
|
var distribution: Array = []
|
|
var power: Variant = 1
|
|
while E.lt(power, value):
|
|
distribution.append(power)
|
|
if E.gt(distribution.size(), 4): distribution.pop_front()
|
|
power = E.multiply(power, 10)
|
|
distribution.append(value)
|
|
while E.lt(distribution.size(), 5): distribution.append(0)
|
|
return distribution
|
|
|
|
func _set_action_values(values: Array, displayed: Array) -> void:
|
|
for ind in range(0, 5):
|
|
action_values[ind] = values[ind]
|
|
# Keep the original request for execution; show the exact planned output.
|
|
var text: String = _format_action_value(displayed[ind])
|
|
if E.ne(action_labels[ind].text, text):
|
|
action_labels[ind].text = text
|
|
action_labels[ind].get_parent().get_node("TextureButton").disabled = E.le(values[ind], 0)
|
|
|
|
|
|
func _format_action_value(value: Variant) -> String:
|
|
if ((E.lt(value, 1) or (not E.finite(value))) or E.ne(value, E.floor_value(value))):
|
|
return ""
|
|
return Global.format_number(value)
|
|
|
|
|
|
func _on_action_button_pressed(button_id: int) -> void:
|
|
if E.gt(action_values.get(button_id, 0), 0):
|
|
action_pressed.emit(page_id, action_values[button_id])
|