From 82028789e7a129e077a45e429c598d7a1a715dd5 Mon Sep 17 00:00:00 2001 From: Jakob Feldmann Date: Tue, 18 May 2021 15:23:09 +0200 Subject: [PATCH] Midair boost, easier walljump, dpad fix, physic adjustments --- project.godot | 6 ++-- src/Actor/Blobby.gd | 62 +++++++++++++++++++++------------ src/Actor/Blobby.tscn | 35 ++++++++++--------- src/Actor/Camera2D.gd | 31 +++++++++++++++++ src/Actor/Player.gd | 24 ++++++++----- src/Actor/PlayerStateMachine.gd | 56 +++++++++++++++++++++-------- src/Levels/ApproxLevel.tscn | 16 ++++----- 7 files changed, 155 insertions(+), 75 deletions(-) create mode 100644 src/Actor/Camera2D.gd diff --git a/project.godot b/project.godot index 9397589..589dc98 100644 --- a/project.godot +++ b/project.godot @@ -62,16 +62,16 @@ window/stretch/shrink=4.5 move_left={ "deadzone": 0.5, -"events": [ Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) -, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) +"events": [ Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":14,"pressure":0.0,"pressed":false,"script":null) ] } move_right={ "deadzone": 0.5, "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null) -, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":15,"pressure":0.0,"pressed":false,"script":null) ] } jump={ diff --git a/src/Actor/Blobby.gd b/src/Actor/Blobby.gd index 672de82..a07470f 100644 --- a/src/Actor/Blobby.gd +++ b/src/Actor/Blobby.gd @@ -1,11 +1,14 @@ extends Player -export var init_boost := false export var jump_buffer_filled := false onready var wall_touch_direction = 0 onready var left_wall_raycasts = $WallRaycasts/LeftWallRaycast onready var right_wall_raycasts = $WallRaycasts/RightWallRaycast onready var player_state_machine = $PlayerStateMachine +onready var init_boost = player_state_machine.init_boost +onready var init_boost_type = player_state_machine.init_boost_type +onready var camera_tween = $Camera2D/ShiftTween +onready var camera = $Camera2D func _on_EnemyDetector_area_entered(area: Area2D) -> void: @@ -83,7 +86,10 @@ func calculate_grounded_velocity( ( ( acceleration_force[state].x - + init_acceleration_force[state] * int(init_boost) + + ( + init_acceleration_force[init_boost_type] + * int(init_boost) + ) ) / mass ) @@ -128,14 +134,26 @@ func is_touching_wall_completely() -> bool: return true +# TODO Player gets stuck to a wall easily func is_correct_walljump_input(direction: Vector2) -> bool: return ( - Input.is_action_just_pressed("jump") + is_touching_wall_completely() + && Input.is_action_just_pressed("jump") && abs(direction.x + wall_touch_direction) < 1 && abs(direction.x + wall_touch_direction) >= 0 ) +func is_correct_airstrafe_input() -> bool: + return ( + air_strafe_charges > 0 + && ( + Input.is_action_just_pressed("move_left") + || Input.is_action_just_pressed("move_right") + ) + ) + + func convert_velocity_to_force(velocity, mass, delta) -> float: return (velocity * mass) / delta @@ -144,20 +162,16 @@ func convert_force_to_velocity(force, mass, delta) -> float: return (force / mass) * delta -# TODO Save this static number somewhere else -func get_ground_friction() -> float: - return 22.0 - - # TODO Comments for parameters func calculate_deceleration_force(_gravity: float, mass: float, delta: float) -> float: - return get_ground_friction() * _gravity * mass * delta + return normal_floor_friction * _gravity * mass * delta func calculate_jump_velocity( linear_velocity: Vector2, delta: float, direction: Vector2 ) -> Vector2: var state = self.get_node("PlayerStateMachine").state + var walljumping = is_correct_walljump_input(direction) if ( Input.is_action_just_pressed("jump") && state != "jump" @@ -172,14 +186,12 @@ func calculate_jump_velocity( ((acceleration_force[state].y + additive_jump_force) / mass) * -1 ) - if ( - is_touching_wall_completely() - && is_correct_walljump_input(direction) - && ! is_on_floor() - ): + + # TODO Das eskaliert ab und an komplett + if walljumping && ! is_on_floor(): # The faster you are moving up the farther the walljump goes linear_velocity.y = (acceleration_force["walljump"].y / mass) * -1 - linear_velocity.x += max_velocity["walljump"] * direction.x + linear_velocity.x += acceleration_force["walljump"].x * direction.x if ! Input.is_action_pressed("jump"): # TODO This is so good not gonna lie @@ -194,9 +206,14 @@ func calculate_jump_velocity( else: linear_velocity.y += _gravity * delta + # TODO Dis shizzle buggy if _velocity.x == 0: linear_velocity.x += inair_velocity * direction.x + if is_correct_airstrafe_input() && ! walljumping: + linear_velocity.x += (direction.x * acceleration_force["air_strafe"].x) + air_strafe_charges -= 1 + return linear_velocity @@ -210,9 +227,13 @@ func calculate_fall_velocity( else: linear_velocity.y = max_velocity["fall"] if _velocity.x == 0: + # TODO this is weird linear_velocity.x += inair_velocity * direction.x if Input.is_action_just_pressed("jump"): jump_buffer_filled = true + if is_correct_airstrafe_input(): + linear_velocity.x += (direction.x * acceleration_force["air_strafe"].x) + air_strafe_charges -= 1 return linear_velocity @@ -222,13 +243,13 @@ func calculate_wallslide_velocity( # Walljump mechanics if is_correct_walljump_input(direction): # TODO This +0.01 indicates a larger problem with division through possible 0 values!! - var multiplicator = max(min(1, 1000 / (_velocity.y + 0.01)), 0.5) + var multiplicator = max(min(1, 1000 / (_velocity.y + 0.01)), 0.9) linear_velocity.y += ( (acceleration_force["walljump"].y / mass) * -1 * multiplicator ) - linear_velocity.x += max_velocity["walljump"] * direction.x + linear_velocity.x += acceleration_force["walljump"].x * direction.x else: linear_velocity.y += _gravity * delta * 0.4 # linear_velocity.x += inair_velocity * direction.x @@ -241,14 +262,9 @@ func calculate_stomp_velocity(linear_velocity: Vector2, impulse: float) -> Vecto return out -func execute_movement() -> void: +func execute_movement(direction) -> void: _velocity = move_and_slide(_velocity, FLOOR_NORMAL) # TODO Replace .get_nodes with $ and put them to file beginning if possible - # var camera = self.get_node("Camera2D") - # if _velocity.x < 0: - # camera.transform.origin.x = -100 - # if _velocity.x > 0: - # camera.transform.origin.x = 100 func die() -> void: diff --git a/src/Actor/Blobby.tscn b/src/Actor/Blobby.tscn index 9a4be63..521b627 100644 --- a/src/Actor/Blobby.tscn +++ b/src/Actor/Blobby.tscn @@ -1,10 +1,9 @@ -[gd_scene load_steps=8 format=2] +[gd_scene load_steps=7 format=2] [ext_resource path="res://start-assets/approx mannequin.png" type="Texture" id=1] [ext_resource path="res://src/Actor/PlayerStateMachine.gd" type="Script" id=2] -[ext_resource path="res://src/RayCasters/RayCaster.gd" type="Script" id=3] -[ext_resource path="res://src/RayCasters/RayCastDebugLines.gd" type="Script" id=4] [ext_resource path="res://src/Actor/Blobby.gd" type="Script" id=5] +[ext_resource path="res://src/Actor/Camera2D.gd" type="Script" id=6] [sub_resource type="RectangleShape2D" id=1] extents = Vector2( 10.6846, 20.1701 ) @@ -15,6 +14,7 @@ extents = Vector2( 11.2458, 19.4685 ) [node name="Blobby" type="KinematicBody2D"] collision_mask = 8 script = ExtResource( 5 ) +jump_buffer_filled = null [node name="Player" type="Sprite" parent="."] texture = ExtResource( 1 ) @@ -22,20 +22,23 @@ texture = ExtResource( 1 ) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource( 1 ) -[node name="RayCaster" type="Node2D" parent="CollisionShape2D"] -script = ExtResource( 3 ) - -[node name="RayCastDebugLines" type="Line2D" parent="CollisionShape2D/RayCaster"] -script = ExtResource( 4 ) - [node name="Camera2D" type="Camera2D" parent="."] +position = Vector2( 80, 0 ) current = true limit_left = 0 limit_top = 0 limit_smoothed = true drag_margin_h_enabled = true drag_margin_v_enabled = true -smoothing_enabled = true +drag_margin_left = 0.08 +drag_margin_top = 0.08 +drag_margin_right = 0.08 +drag_margin_bottom = 0.07 +editor_draw_limits = true +editor_draw_drag_margin = true +script = ExtResource( 6 ) + +[node name="ShiftTween" type="Tween" parent="Camera2D"] [node name="EnemyDetector" type="Area2D" parent="."] monitorable = false @@ -62,7 +65,7 @@ margin_top = -34.2836 margin_right = 25.6614 margin_bottom = -20.2836 custom_colors/font_color = Color( 0, 0, 0, 1 ) -text = "Coochie" +text = "Ihre Werbung" align = 1 valign = 1 __meta__ = { @@ -76,13 +79,13 @@ __meta__ = { [node name="Left_Wallcast1" type="RayCast2D" parent="WallRaycasts/LeftWallRaycast"] position = Vector2( -10.706, -8.03844 ) enabled = true -cast_to = Vector2( -1, 0 ) +cast_to = Vector2( -2, 0 ) collision_mask = 9 [node name="Left_Wallcast2" type="RayCast2D" parent="WallRaycasts/LeftWallRaycast"] position = Vector2( -10.706, 14.8466 ) enabled = true -cast_to = Vector2( -1, 0 ) +cast_to = Vector2( -2, 0 ) collision_mask = 9 [node name="RightWallRaycast" type="Node2D" parent="WallRaycasts"] @@ -90,13 +93,13 @@ collision_mask = 9 [node name="Right_Wallcast1" type="RayCast2D" parent="WallRaycasts/RightWallRaycast"] position = Vector2( 10.6962, -8.03844 ) enabled = true -cast_to = Vector2( 1, 0 ) +cast_to = Vector2( 2, 0 ) collision_mask = 9 [node name="Right_Wallcast2" type="RayCast2D" parent="WallRaycasts/RightWallRaycast"] -position = Vector2( 10.6962, 14.8466 ) +position = Vector2( 11, 14.8466 ) enabled = true -cast_to = Vector2( 1, 0 ) +cast_to = Vector2( 2, 0 ) collision_mask = 9 [connection signal="area_entered" from="EnemyDetector" to="." method="_on_EnemyDetector_area_entered"] diff --git a/src/Actor/Camera2D.gd b/src/Actor/Camera2D.gd new file mode 100644 index 0000000..7f1f683 --- /dev/null +++ b/src/Actor/Camera2D.gd @@ -0,0 +1,31 @@ +extends Camera2D + +var horizontal_facing = 0 +var camera_x_shift = 80 + +onready var prev_camera_pos = get_camera_position() +onready var tween = $ShiftTween + + +func _process(delta: float) -> void: + _check_facing() + prev_camera_pos = get_camera_position() + + +# TODO Smoothing the camera limits in godot ruins this +func _check_facing(): + var new_h_facing = sign(get_camera_position().x - prev_camera_pos.x) + if new_h_facing != 0 && horizontal_facing != new_h_facing: + horizontal_facing = new_h_facing + var target_offset = camera_x_shift * new_h_facing + + tween.interpolate_property( + self, + "transform:origin:x", + self.transform.origin.x, + target_offset, + 1.2, + Tween.TRANS_SINE, + Tween.EASE_OUT + ) + tween.start() diff --git a/src/Actor/Player.gd b/src/Actor/Player.gd index a0794f0..79395b0 100644 --- a/src/Actor/Player.gd +++ b/src/Actor/Player.gd @@ -5,22 +5,28 @@ const FLOOR_NORMAL := Vector2.UP var stomp_feedback := 1000.0 var inair_velocity := 21 -var wallslide_threshold := 1000 +var wallslide_threshold := 300 +var normal_floor_friction := 28 var max_velocity := { - "walk": 130, "run": 180, "fall": 987, "walljump": 150, "idle": 130 + "walk": 120, "run": 160, "fall": 400, "walljump": 150, "idle": 120 } var velocity_jump_boost_ratio := 0.1967 # This is added to the acceleration force initially -var init_acceleration_force := {"walk": 4181, "run": 6765, "idle": 4181} +var init_acceleration_force := { + "idle_walk": 4181, "idle_run": 5765, "walk_run": 1000 +} # newtonmeters is the unit var acceleration_force := { - "walk": Vector2(2584, 2200), - "idle": Vector2(2584, 2200), - "run": Vector2(2584, 2200), - "walljump": Vector2(2548, 2200) + "walk": Vector2(2000, 1800), + "idle": Vector2(2000, 1800), + "run": Vector2(2000, 1800), + "walljump": Vector2(130, 1800), + "air_strafe": Vector2(60, 0) } -var _gravity := 1667.0 +var _gravity := 1111.0 # Kilograms -var mass := 6 +var mass := 6.5 var _velocity := Vector2.ZERO + +var air_strafe_charges := 1 diff --git a/src/Actor/PlayerStateMachine.gd b/src/Actor/PlayerStateMachine.gd index 1e756dc..d39bfea 100644 --- a/src/Actor/PlayerStateMachine.gd +++ b/src/Actor/PlayerStateMachine.gd @@ -2,6 +2,8 @@ extends StateMachine onready var coyoteTimer = $CoyoteTimer export var coyote_hanging = false +export var init_boost = false +export var init_boost_type = "idle_walk" onready var jumpBufferTimer = $JumpBufferTimer @@ -13,7 +15,7 @@ func _ready(): add_state("jump") add_state("fall") add_state("wallslide") - print_debug(states) + state = states.idle set_state(states.idle) @@ -46,38 +48,46 @@ func _state_logic(delta): _: print("don't panik") - parent._velocity = handle_input_ref.call_func(delta) - parent.execute_movement() + var direction = get_horizontal_direction() + + parent._velocity = handle_input_ref.call_func(delta, direction) + parent.execute_movement(direction) -func handle_idle_input(delta, direction := get_horizontal_direction()) -> Vector2: +func handle_idle_input(delta, direction) -> Vector2: if Input.is_action_pressed("boost_move"): return parent.handle_grounded_movement(delta, direction) else: return parent.handle_grounded_movement(delta, direction) -func handle_walk_input(delta, direction := get_horizontal_direction()) -> Vector2: +func handle_walk_input(delta, direction) -> Vector2: return parent.handle_grounded_movement(delta, direction) -func handle_run_input(delta, direction := get_horizontal_direction()) -> Vector2: +func handle_run_input(delta, direction) -> Vector2: return parent.handle_grounded_movement(delta, direction) -func handle_jump_input(delta, direction := get_horizontal_direction()) -> Vector2: +func handle_jump_input(delta, direction) -> Vector2: return parent.handle_jump_movement(delta, direction) -func handle_fall_input(delta, direction := get_horizontal_direction()) -> Vector2: +func handle_fall_input(delta, direction) -> Vector2: return parent.handle_fall_movement(delta, direction) -func handle_wallslide_input(delta, direction := get_horizontal_direction()) -> Vector2: +func handle_wallslide_input(delta, direction) -> Vector2: return parent.handle_wallslide_movement(delta, direction) func get_horizontal_direction() -> Vector2: + #TODO Check if this is fixed yet + if Input.get_connected_joypads().size() > 0: + if Input.is_joy_button_pressed(Input.get_connected_joypads()[0], 14): + return Vector2(-1, 0) + if Input.is_joy_button_pressed(Input.get_connected_joypads()[0], 15): + return Vector2(1, 0) return Vector2( ( Input.get_action_strength("move_right") @@ -136,15 +146,33 @@ func _get_transition(delta): coyote_hanging = false if new_state != self.state: return new_state - parent.init_boost = false + init_boost = false return null func _enter_state(new_state, old_state): - if new_state == "run" || "walk": - parent.init_boost = true - if old_state == "run" && new_state == "walk": - parent.init_boost = false + if old_state == "idle" && new_state == "walk" || new_state == "run": + init_boost = true + init_boost_type = old_state + "_" + new_state + if old_state == "walk" && new_state == "run": + init_boost = true + init_boost_type = old_state + "_" + new_state + if ( + ["fall", "jump", "wallslide"].has(old_state) + && ["idle", "walk", "run"].has(new_state) + ): + parent.air_strafe_charges = 1 + # if old_state == "run" && new_state == "walk": + # init_boost = false + + # TODO This may be hard to keep track of if many states are added + # if (old_state != "run" || "walk" || "idle") && parent.is_on_floor(): + # emit_signal("got_grounded") + # if ( + # (old_state == "run" || "walk" || "idle" || "wallslide") + # && ! parent.is_on_floor() + # ): + # emit_signal("got_ungrounded") func _exit_state(old_state, new_state): diff --git a/src/Levels/ApproxLevel.tscn b/src/Levels/ApproxLevel.tscn index d2ef4d2..5b09929 100644 --- a/src/Levels/ApproxLevel.tscn +++ b/src/Levels/ApproxLevel.tscn @@ -60,6 +60,7 @@ __meta__ = { [node name="Blobby" parent="." instance=ExtResource( 1 )] position = Vector2( 85.2018, 551.133 ) +jump_buffer_filled = null [node name="Player" parent="Blobby" index="0"] position = Vector2( 0.279999, 0 ) @@ -67,18 +68,13 @@ position = Vector2( 0.279999, 0 ) [node name="CollisionShape2D" parent="Blobby" index="1"] position = Vector2( 0, 0.14032 ) -[node name="RayCastDebugLines" parent="Blobby/CollisionShape2D/RayCaster" index="0"] -points = PoolVector2Array( -6.10207, -4.13742 ) - [node name="Camera2D" parent="Blobby" index="2"] +limit_top = 272 limit_right = 974 limit_bottom = 638 -smoothing_enabled = false -drag_margin_left = 0.15 -drag_margin_top = 0.15 -drag_margin_right = 0.15 -drag_margin_bottom = 0.15 -editor_draw_limits = true +limit_smoothed = false +smoothing_speed = 1.0 +drag_margin_bottom = 0.08 [node name="CollisionShape2D" parent="Blobby/EnemyDetector" index="0"] position = Vector2( 0, 0.14032 ) @@ -115,6 +111,6 @@ cell_custom_transform = Transform2D( 16, 0, 0, 16, 0, 0 ) collision_layer = 8 collision_mask = 2147483648 format = 1 -tile_data = PoolIntArray( 0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0, 4, 0, 0, 5, 0, 0, 6, 0, 0, 7, 0, 0, 8, 0, 0, 9, 0, 0, 10, 0, 0, 11, 0, 0, 12, 0, 0, 13, 0, 0, 14, 0, 0, 15, 0, 0, 16, 0, 0, 17, 0, 0, 18, 0, 0, 19, 0, 0, 20, 0, 0, 21, 0, 0, 22, 0, 0, 23, 0, 0, 24, 0, 0, 25, 0, 0, 26, 0, 0, 27, 0, 0, 28, 0, 0, 29, 0, 0, 30, 0, 0, 31, 0, 0, 32, 0, 0, 33, 0, 0, 34, 0, 0, 35, 0, 0, 36, 0, 0, 37, 0, 0, 38, 0, 0, 39, 0, 0, 40, 0, 0, 41, 0, 0, 42, 0, 0, 43, 0, 0, 44, 0, 0, 45, 0, 0, 46, 0, 0, 47, 0, 0, 48, 0, 0, 49, 0, 0, 50, 0, 0, 51, 0, 0, 52, 0, 0, 53, 0, 0, 54, 0, 0, 55, 0, 0, 56, 0, 0, 57, 0, 0, 58, 0, 0, 59, 0, 0, 60, 0, 0, 65536, 0, 0, 65596, 0, 0, 131072, 0, 0, 131132, 0, 0, 196608, 0, 0, 196668, 0, 0, 262144, 0, 0, 262204, 0, 0, 327680, 0, 0, 327740, 0, 0, 393216, 0, 0, 393276, 0, 0, 458752, 0, 0, 458812, 0, 0, 524288, 0, 0, 524348, 0, 0, 589824, 0, 0, 589884, 0, 0, 655360, 0, 0, 655420, 0, 0, 720896, 0, 0, 720956, 0, 0, 786432, 0, 0, 786492, 0, 0, 851968, 0, 0, 852028, 0, 0, 917504, 0, 0, 917564, 0, 0, 983040, 0, 0, 983100, 0, 0, 1048576, 0, 0, 1048636, 0, 0, 1114112, 0, 0, 1114172, 0, 0, 1179648, 0, 0, 1179708, 0, 0, 1245184, 0, 0, 1245244, 0, 0, 1310720, 0, 0, 1310780, 0, 0, 1376256, 0, 0, 1376316, 0, 0, 1441792, 0, 0, 1441852, 0, 0, 1507328, 0, 0, 1507388, 0, 0, 1572864, 0, 0, 1572865, 0, 0, 1572866, 0, 0, 1572867, 0, 0, 1572924, 0, 0, 1638400, 0, 0, 1638401, 0, 0, 1638402, 0, 0, 1638455, 0, 0, 1638456, 0, 0, 1638460, 0, 0, 1703936, 0, 0, 1703937, 0, 0, 1703938, 0, 0, 1703943, 0, 0, 1703944, 0, 0, 1703996, 0, 0, 1769472, 0, 0, 1769473, 0, 0, 1769474, 0, 0, 1769479, 0, 0, 1769480, 0, 0, 1769481, 0, 0, 1769482, 0, 0, 1769483, 0, 0, 1769487, 0, 0, 1769488, 0, 0, 1769489, 0, 0, 1769495, 0, 0, 1769500, 0, 0, 1769501, 0, 0, 1769502, 0, 0, 1769503, 0, 0, 1769504, 0, 0, 1769532, 0, 0, 1835008, 0, 0, 1835009, 0, 0, 1835044, 0, 0, 1835045, 0, 0, 1835067, 0, 0, 1835068, 0, 0, 1900544, 0, 0, 1900565, 0, 0, 1900566, 0, 0, 1900584, 0, 0, 1900585, 0, 0, 1900586, 0, 0, 1900587, 0, 0, 1900588, 0, 0, 1900603, 0, 0, 1900604, 0, 0, 1966080, 0, 0, 1966138, 0, 0, 1966139, 0, 0, 1966140, 0, 0, 2031616, 0, 0, 2031663, 0, 0, 2031664, 0, 0, 2031665, 0, 0, 2031666, 0, 0, 2031674, 0, 0, 2031675, 0, 0, 2031676, 0, 0, 2097152, 0, 0, 2097209, 0, 0, 2097210, 0, 0, 2097211, 0, 0, 2097212, 0, 0, 2162688, 0, 0, 2162742, 0, 0, 2162743, 0, 0, 2162744, 0, 0, 2162745, 0, 0, 2162746, 0, 0, 2162747, 0, 0, 2162748, 0, 0, 2228224, 0, 0, 2228277, 0, 0, 2228278, 0, 0, 2228279, 0, 0, 2228280, 0, 0, 2228281, 0, 0, 2228282, 0, 0, 2228283, 0, 0, 2228284, 0, 0, 2293760, 0, 0, 2293775, 0, 0, 2293776, 0, 0, 2293813, 0, 0, 2293814, 0, 0, 2293815, 0, 0, 2293816, 0, 0, 2293817, 0, 0, 2293818, 0, 0, 2293819, 0, 0, 2293820, 0, 0, 2359296, 0, 0, 2359297, 0, 0, 2359298, 0, 0, 2359299, 0, 0, 2359300, 0, 0, 2359301, 0, 0, 2359302, 0, 0, 2359303, 0, 0, 2359304, 0, 0, 2359305, 0, 0, 2359306, 0, 0, 2359307, 0, 0, 2359308, 0, 0, 2359309, 0, 0, 2359310, 0, 0, 2359311, 0, 0, 2359312, 0, 0, 2359313, 0, 0, 2359314, 0, 0, 2359315, 0, 0, 2359316, 0, 0, 2359317, 0, 0, 2359321, 0, 0, 2359322, 0, 0, 2359323, 0, 0, 2359324, 0, 0, 2359325, 0, 0, 2359326, 0, 0, 2359327, 0, 0, 2359328, 0, 0, 2359329, 0, 0, 2359330, 0, 0, 2359331, 0, 0, 2359332, 0, 0, 2359333, 0, 0, 2359334, 0, 0, 2359335, 0, 0, 2359336, 0, 0, 2359342, 0, 0, 2359343, 0, 0, 2359344, 0, 0, 2359345, 0, 0, 2359346, 0, 0, 2359347, 0, 0, 2359348, 0, 0, 2359349, 0, 0, 2359350, 0, 0, 2359351, 0, 0, 2359352, 0, 0, 2359353, 0, 0, 2359354, 0, 0, 2359355, 0, 0, 2359356, 0, 0, 2424832, 0, 0, 2424833, 0, 0, 2424834, 0, 0, 2424835, 0, 0, 2424836, 0, 0, 2424837, 0, 0, 2424838, 0, 0, 2424839, 0, 0, 2424840, 0, 0, 2424841, 0, 0, 2424842, 0, 0, 2424843, 0, 0, 2424844, 0, 0, 2424845, 0, 0, 2424846, 0, 0, 2424847, 0, 0, 2424848, 0, 0, 2424849, 0, 0, 2424850, 0, 0, 2424851, 0, 0, 2424852, 0, 0, 2424853, 0, 0, 2424854, 0, 0, 2424857, 0, 0, 2424858, 0, 0, 2424859, 0, 0, 2424860, 0, 0, 2424861, 0, 0, 2424862, 0, 0, 2424863, 0, 0, 2424864, 0, 0, 2424865, 0, 0, 2424866, 0, 0, 2424867, 0, 0, 2424868, 0, 0, 2424869, 0, 0, 2424870, 0, 0, 2424871, 0, 0, 2424872, 0, 0, 2424873, 0, 0, 2424874, 0, 0, 2424878, 0, 0, 2424879, 0, 0, 2424880, 0, 0, 2424881, 0, 0, 2424882, 0, 0, 2424883, 0, 0, 2424884, 0, 0, 2424885, 0, 0, 2424886, 0, 0, 2424887, 0, 0, 2424888, 0, 0, 2424889, 0, 0, 2424890, 0, 0, 2424891, 0, 0, 2424892, 0, 0, 2490368, 0, 0, 2490369, 0, 0, 2490370, 0, 0, 2490371, 0, 0, 2490372, 0, 0, 2490373, 0, 0, 2490374, 0, 0, 2490375, 0, 0, 2490376, 0, 0, 2490377, 0, 0, 2490378, 0, 0, 2490379, 0, 0, 2490380, 0, 0, 2490381, 0, 0, 2490382, 0, 0, 2490383, 0, 0, 2490384, 0, 0, 2490385, 0, 0, 2490386, 0, 0, 2490387, 0, 0, 2490388, 0, 0, 2490389, 0, 0, 2490390, 0, 0, 2490393, 0, 0, 2490394, 0, 0, 2490395, 0, 0, 2490396, 0, 0, 2490397, 0, 0, 2490398, 0, 0, 2490399, 0, 0, 2490400, 0, 0, 2490401, 0, 0, 2490402, 0, 0, 2490403, 0, 0, 2490404, 0, 0, 2490405, 0, 0, 2490406, 0, 0, 2490407, 0, 0, 2490408, 0, 0, 2490409, 0, 0, 2490410, 0, 0, 2490414, 0, 0, 2490415, 0, 0, 2490416, 0, 0, 2490417, 0, 0, 2490418, 0, 0, 2490419, 0, 0, 2490420, 0, 0, 2490421, 0, 0, 2490422, 0, 0, 2490423, 0, 0, 2490424, 0, 0, 2490425, 0, 0, 2490426, 0, 0, 2490427, 0, 0, 2490428, 0, 0, 2555904, 0, 0, 2555905, 0, 0, 2555906, 0, 0, 2555907, 0, 0, 2555908, 0, 0, 2555909, 0, 0, 2555910, 0, 0, 2555911, 0, 0, 2555912, 0, 0, 2555913, 0, 0, 2555914, 0, 0, 2555915, 0, 0, 2555916, 0, 0, 2555917, 0, 0, 2555918, 0, 0, 2555919, 0, 0, 2555920, 0, 0, 2555921, 0, 0, 2555922, 0, 0, 2555923, 0, 0, 2555924, 0, 0, 2555925, 0, 0, 2555926, 0, 0, 2555927, 0, 0, 2555928, 0, 0, 2555929, 0, 0, 2555930, 0, 0, 2555931, 0, 0, 2555932, 0, 0, 2555933, 0, 0, 2555934, 0, 0, 2555935, 0, 0, 2555936, 0, 0, 2555937, 0, 0, 2555938, 0, 0, 2555939, 0, 0, 2555940, 0, 0, 2555941, 0, 0, 2555942, 0, 0, 2555943, 0, 0, 2555944, 0, 0, 2555945, 0, 0, 2555946, 0, 0, 2555947, 0, 0, 2555948, 0, 0, 2555949, 0, 0, 2555950, 0, 0, 2555951, 0, 0, 2555952, 0, 0, 2555953, 0, 0, 2555954, 0, 0, 2555955, 0, 0, 2555956, 0, 0, 2555957, 0, 0, 2555958, 0, 0, 2555959, 0, 0, 2555960, 0, 0, 2555961, 0, 0, 2555962, 0, 0, 2555963, 0, 0, 2555964, 0, 0 ) +tile_data = PoolIntArray( 1114112, 0, 0, 1114113, 0, 0, 1114114, 0, 0, 1114115, 0, 0, 1114116, 0, 0, 1114117, 0, 0, 1114118, 0, 0, 1114119, 0, 0, 1114120, 0, 0, 1114121, 0, 0, 1114122, 0, 0, 1114123, 0, 0, 1114124, 0, 0, 1114125, 0, 0, 1114126, 0, 0, 1114127, 0, 0, 1114128, 0, 0, 1114129, 0, 0, 1114130, 0, 0, 1114131, 0, 0, 1114132, 0, 0, 1114133, 0, 0, 1114134, 0, 0, 1114135, 0, 0, 1114136, 0, 0, 1114137, 0, 0, 1114138, 0, 0, 1114139, 0, 0, 1114140, 0, 0, 1114141, 0, 0, 1114142, 0, 0, 1114143, 0, 0, 1114144, 0, 0, 1114145, 0, 0, 1114146, 0, 0, 1114147, 0, 0, 1114148, 0, 0, 1114149, 0, 0, 1114150, 0, 0, 1114151, 0, 0, 1114152, 0, 0, 1114153, 0, 0, 1114154, 0, 0, 1114155, 0, 0, 1114156, 0, 0, 1114157, 0, 0, 1114158, 0, 0, 1114159, 0, 0, 1114160, 0, 0, 1114161, 0, 0, 1114162, 0, 0, 1114163, 0, 0, 1114164, 0, 0, 1114165, 0, 0, 1114166, 0, 0, 1114167, 0, 0, 1114168, 0, 0, 1114169, 0, 0, 1114170, 0, 0, 1114171, 0, 0, 1114172, 0, 0, 1179648, 0, 0, 1179708, 0, 0, 1245184, 0, 0, 1245244, 0, 0, 1310720, 0, 0, 1310780, 0, 0, 1376256, 0, 0, 1376316, 0, 0, 1441792, 0, 0, 1441852, 0, 0, 1507328, 0, 0, 1507388, 0, 0, 1572864, 0, 0, 1572865, 0, 0, 1572866, 0, 0, 1572867, 0, 0, 1572924, 0, 0, 1638400, 0, 0, 1638401, 0, 0, 1638402, 0, 0, 1638460, 0, 0, 1703936, 0, 0, 1703937, 0, 0, 1703938, 0, 0, 1703943, 0, 0, 1703944, 0, 0, 1703996, 0, 0, 1769472, 0, 0, 1769473, 0, 0, 1769474, 0, 0, 1769479, 0, 0, 1769480, 0, 0, 1769481, 0, 0, 1769482, 0, 0, 1769483, 0, 0, 1769487, 0, 0, 1769488, 0, 0, 1769489, 0, 0, 1769495, 0, 0, 1769500, 0, 0, 1769501, 0, 0, 1769502, 0, 0, 1769503, 0, 0, 1769504, 0, 0, 1769526, 0, 0, 1769527, 0, 0, 1769532, 0, 0, 1835008, 0, 0, 1835009, 0, 0, 1835044, 0, 0, 1835045, 0, 0, 1835068, 0, 0, 1900544, 0, 0, 1900565, 0, 0, 1900566, 0, 0, 1900584, 0, 0, 1900585, 0, 0, 1900586, 0, 0, 1900587, 0, 0, 1900588, 0, 0, 1900604, 0, 0, 1966080, 0, 0, 1966139, 0, 0, 1966140, 0, 0, 2031616, 0, 0, 2031663, 0, 0, 2031664, 0, 0, 2031675, 0, 0, 2031676, 0, 0, 2097152, 0, 0, 2097201, 0, 0, 2097202, 0, 0, 2097208, 0, 0, 2097209, 0, 0, 2097210, 0, 0, 2097211, 0, 0, 2097212, 0, 0, 2162688, 0, 0, 2162744, 0, 0, 2162745, 0, 0, 2162746, 0, 0, 2162747, 0, 0, 2162748, 0, 0, 2228224, 0, 0, 2228241, 0, 0, 2228277, 0, 0, 2228278, 0, 0, 2228279, 0, 0, 2228280, 0, 0, 2228281, 0, 0, 2228282, 0, 0, 2228283, 0, 0, 2228284, 0, 0, 2293760, 0, 0, 2293771, 0, 0, 2293777, 0, 0, 2293778, 0, 0, 2293813, 0, 0, 2293814, 0, 0, 2293815, 0, 0, 2293816, 0, 0, 2293817, 0, 0, 2293818, 0, 0, 2293819, 0, 0, 2293820, 0, 0, 2359296, 0, 0, 2359297, 0, 0, 2359298, 0, 0, 2359299, 0, 0, 2359300, 0, 0, 2359301, 0, 0, 2359302, 0, 0, 2359303, 0, 0, 2359304, 0, 0, 2359305, 0, 0, 2359306, 0, 0, 2359307, 0, 0, 2359308, 0, 0, 2359309, 0, 0, 2359310, 0, 0, 2359311, 0, 0, 2359312, 0, 0, 2359313, 0, 0, 2359314, 0, 0, 2359315, 0, 0, 2359316, 0, 0, 2359317, 0, 0, 2359321, 0, 0, 2359322, 0, 0, 2359323, 0, 0, 2359324, 0, 0, 2359325, 0, 0, 2359326, 0, 0, 2359327, 0, 0, 2359328, 0, 0, 2359329, 0, 0, 2359330, 0, 0, 2359331, 0, 0, 2359332, 0, 0, 2359333, 0, 0, 2359334, 0, 0, 2359335, 0, 0, 2359336, 0, 0, 2359342, 0, 0, 2359343, 0, 0, 2359344, 0, 0, 2359345, 0, 0, 2359346, 0, 0, 2359347, 0, 0, 2359348, 0, 0, 2359349, 0, 0, 2359350, 0, 0, 2359351, 0, 0, 2359352, 0, 0, 2359353, 0, 0, 2359354, 0, 0, 2359355, 0, 0, 2359356, 0, 0, 2424832, 0, 0, 2424833, 0, 0, 2424834, 0, 0, 2424835, 0, 0, 2424836, 0, 0, 2424837, 0, 0, 2424838, 0, 0, 2424839, 0, 0, 2424840, 0, 0, 2424841, 0, 0, 2424842, 0, 0, 2424843, 0, 0, 2424844, 0, 0, 2424845, 0, 0, 2424846, 0, 0, 2424847, 0, 0, 2424848, 0, 0, 2424849, 0, 0, 2424850, 0, 0, 2424851, 0, 0, 2424852, 0, 0, 2424853, 0, 0, 2424854, 0, 0, 2424857, 0, 0, 2424858, 0, 0, 2424859, 0, 0, 2424860, 0, 0, 2424861, 0, 0, 2424862, 0, 0, 2424863, 0, 0, 2424864, 0, 0, 2424865, 0, 0, 2424866, 0, 0, 2424867, 0, 0, 2424868, 0, 0, 2424869, 0, 0, 2424870, 0, 0, 2424871, 0, 0, 2424872, 0, 0, 2424873, 0, 0, 2424874, 0, 0, 2424878, 0, 0, 2424879, 0, 0, 2424880, 0, 0, 2424881, 0, 0, 2424882, 0, 0, 2424883, 0, 0, 2424884, 0, 0, 2424885, 0, 0, 2424886, 0, 0, 2424887, 0, 0, 2424888, 0, 0, 2424889, 0, 0, 2424890, 0, 0, 2424891, 0, 0, 2424892, 0, 0, 2490368, 0, 0, 2490369, 0, 0, 2490370, 0, 0, 2490371, 0, 0, 2490372, 0, 0, 2490373, 0, 0, 2490374, 0, 0, 2490375, 0, 0, 2490376, 0, 0, 2490377, 0, 0, 2490378, 0, 0, 2490379, 0, 0, 2490380, 0, 0, 2490381, 0, 0, 2490382, 0, 0, 2490383, 0, 0, 2490384, 0, 0, 2490385, 0, 0, 2490386, 0, 0, 2490387, 0, 0, 2490388, 0, 0, 2490389, 0, 0, 2490390, 0, 0, 2490393, 0, 0, 2490394, 0, 0, 2490395, 0, 0, 2490396, 0, 0, 2490397, 0, 0, 2490398, 0, 0, 2490399, 0, 0, 2490400, 0, 0, 2490401, 0, 0, 2490402, 0, 0, 2490403, 0, 0, 2490404, 0, 0, 2490405, 0, 0, 2490406, 0, 0, 2490407, 0, 0, 2490408, 0, 0, 2490409, 0, 0, 2490410, 0, 0, 2490414, 0, 0, 2490415, 0, 0, 2490416, 0, 0, 2490417, 0, 0, 2490418, 0, 0, 2490419, 0, 0, 2490420, 0, 0, 2490421, 0, 0, 2490422, 0, 0, 2490423, 0, 0, 2490424, 0, 0, 2490425, 0, 0, 2490426, 0, 0, 2490427, 0, 0, 2490428, 0, 0, 2555904, 0, 0, 2555905, 0, 0, 2555906, 0, 0, 2555907, 0, 0, 2555908, 0, 0, 2555909, 0, 0, 2555910, 0, 0, 2555911, 0, 0, 2555912, 0, 0, 2555913, 0, 0, 2555914, 0, 0, 2555915, 0, 0, 2555916, 0, 0, 2555917, 0, 0, 2555918, 0, 0, 2555919, 0, 0, 2555920, 0, 0, 2555921, 0, 0, 2555922, 0, 0, 2555923, 0, 0, 2555924, 0, 0, 2555925, 0, 0, 2555926, 0, 0, 2555927, 0, 0, 2555928, 0, 0, 2555929, 0, 0, 2555930, 0, 0, 2555931, 0, 0, 2555932, 0, 0, 2555933, 0, 0, 2555934, 0, 0, 2555935, 0, 0, 2555936, 0, 0, 2555937, 0, 0, 2555938, 0, 0, 2555939, 0, 0, 2555940, 0, 0, 2555941, 0, 0, 2555942, 0, 0, 2555943, 0, 0, 2555944, 0, 0, 2555945, 0, 0, 2555946, 0, 0, 2555947, 0, 0, 2555948, 0, 0, 2555949, 0, 0, 2555950, 0, 0, 2555951, 0, 0, 2555952, 0, 0, 2555953, 0, 0, 2555954, 0, 0, 2555955, 0, 0, 2555956, 0, 0, 2555957, 0, 0, 2555958, 0, 0, 2555959, 0, 0, 2555960, 0, 0, 2555961, 0, 0, 2555962, 0, 0, 2555963, 0, 0, 2555964, 0, 0 ) [editable path="Blobby"]