diff --git a/frontend/src/pages/how-to-play/build-ship.mdx b/frontend/src/pages/how-to-play/build-ship.mdx index 31286ac..a4d1716 100644 --- a/frontend/src/pages/how-to-play/build-ship.mdx +++ b/frontend/src/pages/how-to-play/build-ship.mdx @@ -8,22 +8,23 @@ Creates a `ShipState` UTxO locking min ada and a `ShipToken` (minted in this tx) ![createShip diagram](/txs/build-ship.png) -## Lucid Example +## Blaze Example -You can use the following Lucid script to build your ship. The supporting files are available [here](https://github.com/txpipe/asteria/tree/main/offchain). +You can use the following Blaze script to build your ship. The supporting files are available [here](https://github.com/txpipe/asteria/tree/main/offchain). - { + return Buffer.from(hex, 'hex').toString(); +} + const getShipByAddress = (address: string): string => { const encoder = new TextEncoder(); const charCode = encoder.encode(address.charAt(address.length-3))[0]; @@ -41,21 +46,23 @@ const getShipByAddress = (address: string): string => { } const LeaderboardChip: React.FunctionComponent = (props: RecordProps) => ( -
-

- {props.record.ranking} -

-
- -
-

- Pilot: {props.record.pilotName.toUpperCase().slice(-6)}
- Ship: {props.record.shipName.toUpperCase().slice(-6)} -

-
- {`${props.record.distance}km`} + +
+

+ {props.record.ranking} +

+
+ +
+

+ Pilot: {hexToAscii(props.record.pilotName)}
+ Ship: {hexToAscii(props.record.shipName)} +

+
+ {`${props.record.distance}km`} +
-
+ ); const LeaderboardRow: React.FunctionComponent = (props: RecordProps) => ( @@ -65,13 +72,19 @@ const LeaderboardRow: React.FunctionComponent = (props: RecordProps - {props.record.address.replace('#0', '')} + + {props.record.address.replace('#0', '')} + - {props.record.pilotName.toUpperCase().slice(-6)} + {hexToAscii(props.record.pilotName)} - {props.record.shipName.toUpperCase().slice(-6)} + {hexToAscii(props.record.shipName)} {props.record.fuel} @@ -139,7 +152,7 @@ export default function Leaderboard() {
{data && data.leaderboard && data.leaderboard.slice(0, 3).map(record => - + )}
@@ -153,7 +166,7 @@ export default function Leaderboard() { {getPageData().map(record => - + )} diff --git a/frontend/src/pages/map/index.tsx b/frontend/src/pages/map/index.tsx index 08aec8b..07c1a1b 100644 --- a/frontend/src/pages/map/index.tsx +++ b/frontend/src/pages/map/index.tsx @@ -10,7 +10,8 @@ export default function Map() { ['fuelPolicyId', current().fuelPolicyId], ['shipAddress', current().shipAddress], ['fuelAddress', current().fuelAddress], - ['asteriaAddress', current().asteriaAddress] + ['asteriaAddress', current().asteriaAddress], + ['explorerUrl', current().explorerUrl], ]); return `/visualizer/index.html?${params.toString()}`; }; diff --git a/frontend/src/stores/challenge.ts b/frontend/src/stores/challenge.ts index 1d82dd4..f1917e1 100644 --- a/frontend/src/stores/challenge.ts +++ b/frontend/src/stores/challenge.ts @@ -8,6 +8,7 @@ export interface Challenge { fuelAddress: string; asteriaAddress: string; network: string; + explorerUrl: string; } export interface ChallengeStoreState { @@ -27,6 +28,7 @@ export const useChallengeStore = create((set, get) => ({ fuelAddress: 'addr_test1wr7g448cgxqmshwqfaacc2vyky5jsnzwyuh0ghxkgszhtlgzrxj63', asteriaAddress: 'addr_test1wqdsuy97njefz53rkhd4v6a2kuqk0md5mrn996ygwekrdyq369wjg', network: 'preview', + explorerUrl: 'https://preview.cexplorer.io/tx/', }], current: () => get().challenges[get().selected], select: (index: number) => set(() => ({ selected: index })), diff --git a/godot-visualizer/scripts/global.gd b/godot-visualizer/scripts/global.gd index f4658a9..a53d9a3 100644 --- a/godot-visualizer/scripts/global.gd +++ b/godot-visualizer/scripts/global.gd @@ -7,6 +7,8 @@ var ships: Array[ShipData] = [] var fuels: Array[FuelData] = [] var asteria: AsteriaData = null +var explorer_url = "" + func init_data(data: Variant): ships = [] @@ -27,10 +29,10 @@ func init_data(data: Variant): )) if item["__typename"] == "Fuel": - fuels.append(FuelData.new(item["fuel"], position)) + fuels.append(FuelData.new(item["id"], item["fuel"], position)) if item["__typename"] == "Asteria": - asteria = AsteriaData.new(item["totalRewards"], position) + asteria = AsteriaData.new(item["id"], item["totalRewards"], position) func get_ships(): return ships @@ -47,6 +49,12 @@ func get_grid_size(): func get_cell_size(): return cell_size +func set_explorer_url(_explorer_url: String): + explorer_url = _explorer_url + +func get_explorer_url(): + return explorer_url + class ShipData: var id: String = "" @@ -64,18 +72,22 @@ class ShipData: class FuelData: + var id: String = "" var fuel: int = 0 var position: Vector2 = Vector2(0, 0) - func _init(_fuel: int, _position: Vector2): + func _init(_id: String, _fuel: int, _position: Vector2): + id = _id fuel = _fuel position = _position class AsteriaData: + var id: String = "" var totalRewards: int = 0 var position: Vector2 = Vector2(0, 0) - func _init(_totalRewards: int, _position: Vector2): + func _init(_id: String, _totalRewards: int, _position: Vector2): + id = _id totalRewards = _totalRewards position = _position diff --git a/godot-visualizer/scripts/main.gd b/godot-visualizer/scripts/main.gd index 1ca2f8f..599c78d 100644 --- a/godot-visualizer/scripts/main.gd +++ b/godot-visualizer/scripts/main.gd @@ -10,6 +10,7 @@ var fuel_policy_id = "" var ship_address = "" var fuel_address = "" var asteria_address = "" +var explorer_url = "" const headers = ["Content-Type: application/json"] const query = """ @@ -39,9 +40,11 @@ const query = """ } }, ... on Fuel { + id, fuel }, ... on Asteria { + id, totalRewards } } @@ -65,13 +68,16 @@ func _process(delta: float) -> void: $GUICanvasLayer/CenterContainer/Loader.rotation += delta * 10 -func _ready(): +func _ready(): api_url = JavaScriptBridge.eval("new URL(window.location.href).searchParams.get('apiUrl')") shipyard_policy_id = JavaScriptBridge.eval("new URL(window.location.href).searchParams.get('shipyardPolicyId')") fuel_policy_id = JavaScriptBridge.eval("new URL(window.location.href).searchParams.get('fuelPolicyId')") ship_address = JavaScriptBridge.eval("new URL(window.location.href).searchParams.get('shipAddress')") fuel_address = JavaScriptBridge.eval("new URL(window.location.href).searchParams.get('fuelAddress')") asteria_address = JavaScriptBridge.eval("new URL(window.location.href).searchParams.get('asteriaAddress')") + explorer_url = JavaScriptBridge.eval("new URL(window.location.href).searchParams.get('explorerUrl')") + + Global.set_explorer_url(explorer_url) $HTTPRequest.request_completed.connect(_on_request_completed) fetch_data() @@ -120,14 +126,16 @@ func update_tooltip_position(position: Vector2) -> void: func _on_map_hide_tooltip() -> void: + Input.set_default_cursor_shape(Input.CURSOR_ARROW) $GUICanvasLayer/Tooltip.visible = false func _on_map_show_ship_tooltip(ship: Global.ShipData) -> void: + Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND) $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Title.text = "SHIP" $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label1.text = "Position | %d, %d" % [ship.position.x, ship.position.y] - $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label2.text = "Ship Token | %s" % ship.shipTokenName - $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label3.text = "Pilot Token | %s" % ship.pilotTokenName + $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label2.text = "Ship Token | %s" % ship.shipTokenName.hex_decode().get_string_from_utf8() + $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label3.text = "Pilot Token | %s" % ship.pilotTokenName.hex_decode().get_string_from_utf8() $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label4.text = "Fuel | %s" % ship.fuel $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label1.visible = true $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label2.visible = true @@ -137,6 +145,7 @@ func _on_map_show_ship_tooltip(ship: Global.ShipData) -> void: func _on_map_show_fuel_tooltip(fuel: Global.FuelData) -> void: + Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND) $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Title.text = "FUEL PELLET" $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label1.text = "Position | %d, %d" % [fuel.position.x, fuel.position.y] $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label2.text = "Fuel | %s" % fuel.fuel @@ -148,6 +157,7 @@ func _on_map_show_fuel_tooltip(fuel: Global.FuelData) -> void: func _on_map_show_asteria_tooltip(asteria: Global.AsteriaData) -> void: + Input.set_default_cursor_shape(Input.CURSOR_POINTING_HAND) $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Title.text = "ASTERIA" $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label1.text = "Position | %d, %d" % [asteria.position.x, asteria.position.y] $GUICanvasLayer/Tooltip/MarginContainer/VBoxContainer/Label2.text = "Total rewards | %s" % asteria.totalRewards diff --git a/godot-visualizer/scripts/map.gd b/godot-visualizer/scripts/map.gd index 9c6eea8..9d7f257 100644 --- a/godot-visualizer/scripts/map.gd +++ b/godot-visualizer/scripts/map.gd @@ -18,6 +18,8 @@ var mouse_entered_minimap = false var mouse_entered_minimap_control = false var mouse_entered_modal = false +var current_id = "" + func _on_main_dataset_updated() -> void: const center = Vector2(0, 0) @@ -42,6 +44,13 @@ func _on_main_dataset_updated() -> void: $Entities.add_child(asteria) +func _input(event): + if event is InputEventMouseButton and event.pressed and current_id != "": + JavaScriptBridge.eval("window.open('%s%s', '_blank')" % [ + Global.get_explorer_url(), current_id.split("#")[0] + ]) + + func _process(delta: float) -> void: var cell_size = Global.get_cell_size() var mouse_position = get_viewport().get_mouse_position() / $Camera.zoom @@ -58,17 +67,22 @@ func _process(delta: float) -> void: if asteria and asteria.position == cell_position: $Cell.animation = "filled" show_asteria_tooltip.emit(asteria) + current_id = asteria.id elif ships.size() > 0: $Cell.animation = "filled" show_ship_tooltip.emit(ships[0]) + current_id = ships[0].id elif fuels.size() > 0: $Cell.animation = "filled" show_fuel_tooltip.emit(fuels[0]) + current_id = fuels[0].id else: $Cell.animation = "empty" hide_tooltip.emit() + current_id = "" else: hide_tooltip.emit() + current_id = "" func is_mouse_hover_gui() -> bool: