-
Couldn't load subscription status.
- Fork 198
Make Void slow down while consuming piles of books #1393
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
Play this branch at https://endlessm.github.io/threadbare/branches/endlessm/void-indigestion. (This launches the game from the start, not directly at the change(s) in this pull request.) |
|
This is a draft for now because:
The pile of books is intended to be placeholder. Is made out of existing assets. Also it is pullable, but the way TileMapCover works is meant for static props (the |
|
I'm also appending a commit for the player that I'm testing locally. Seems a good candidate to impeding the player to be stuck after transpasing a collision shape. |
Oh, ouch. I wonder if an alternative could be to stipulate that only things that can be collided with can be covered, and then use collisions rather than looking up tilemap coordinates when deciding what to hide. |
Add a pile of books that has a float metadata "ingest_time" and is set to 2.0. This will be used to stop the Void spreading enemy for that amount of seconds. For testing, this prop is also hookable and will move towards the player, colliding with it. So the player could change its place or bring it from other "islands" with the grappling hook.
In TileMapCover: Report the nodes as they are being consumed. And fix the function documentation comment, previously it was also returning true or false if nodes (not tiles) were consumed. In the enemy new ingesting state, it does nothing more than waiting. Transition to this state if the metadata of a consumed node says to be ingested, and set the waiting to that amount of time. Also emit particles when not the enemy is not moving. The previous solution for emitting particles when not consuming stuff was distance-based. Now if the enemy is standing in the new INGESTING state, nothing would be displayed.
844ac44 to
4ca53d4
Compare
Could be, I'll check! For now the way to stop the Void for a little bit is to position the player so the pile of books is between the player and the void. I guess if we go with this, we may need an arrow indicator pointing to the position that the void is, when it is off screen. I remember that we need that anyways for the magical threads, when they appear off screen (not for the Lore, but a StoryQuest can be designed to do it). |
| ## direct children of [member consumable_node_holders]. | ||
| ## Return true if any cells were consumed. | ||
| func consume_cells(cells: Array[Vector2i], immediate: bool = false) -> bool: | ||
| ## Return true if any nodes were consumed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started doing a data class for returning here:
class ConsumedInfo:
var has_consumed_cells: bool
var consumed_nodes: Array[Node2D]
And then I realized that the docstring I added for this function is wrong. It has been always returning if nodes were consumed, not cells.
|
I have appended a fixup after seeing errors for the Tween.finished signal trying to be connected multiple times. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm kind of on the fence about this. I like the idea but I find it hard to grab the props fast enough for it to help.
I tried designing a little zig-zag where you:
- grapple right
- grab books from the right
- grapple down
- grab books from below
- grapple right
in the hope that this would make it easier to aim (you don't need to retarget to catch the books) but it didn't really work because unless you time it just right, the enemy just moves diagonally to follow you and doesn't eat the books.
I wonder if it would work if the enemy had a detection circle around it (perhaps 3× the radius that it eats) where, if something tastier than storyweaver was in that circle, it would temporarily retarget to that, eat it, and then go back to chasing storyweaver?
| if cells: | ||
| set_cells_terrain_connect(cells, terrain_set, _terrain_id) | ||
|
|
||
| var consumed_nodes := [] as Array[Node2D] | ||
| for cell in cells: | ||
| consume(cell, immediate) | ||
| return true | ||
| return false | ||
| var nodes := consume(cell, immediate) | ||
| consumed_nodes.append_array(nodes) | ||
| return consumed_nodes | ||
| return [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if cells: | |
| set_cells_terrain_connect(cells, terrain_set, _terrain_id) | |
| var consumed_nodes := [] as Array[Node2D] | |
| for cell in cells: | |
| consume(cell, immediate) | |
| return true | |
| return false | |
| var nodes := consume(cell, immediate) | |
| consumed_nodes.append_array(nodes) | |
| return consumed_nodes | |
| return [] | |
| var consumed_nodes: Array[Node2D] | |
| if cells: | |
| set_cells_terrain_connect(cells, terrain_set, _terrain_id) | |
| for cell in cells: | |
| var nodes := consume(cell, immediate) | |
| consumed_nodes.append_array(nodes) | |
| return consumed_nodes |
| _consumed_nodes[coord] = nodes | ||
| return consumed_nodes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's confusing to have a local variable with the same name (minus an underscore) as a class field.
| return | ||
| return [] | ||
|
|
||
| var consumed_nodes := [] as Array[Node2D] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As above I think you can spell this as:
| var consumed_nodes := [] as Array[Node2D] | |
| var consumed_nodes: Array[Node2D] |
and I believe it gets initialised to empty array (not null)
| for node in consumed_nodes: | ||
| if node.has_meta(&"ingest_time"): | ||
| var previous_state := state | ||
| state = State.INGESTING | ||
| await get_tree().create_timer(node.get_meta(&"ingest_time")).timeout | ||
| state = previous_state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| for node in consumed_nodes: | |
| if node.has_meta(&"ingest_time"): | |
| var previous_state := state | |
| state = State.INGESTING | |
| await get_tree().create_timer(node.get_meta(&"ingest_time")).timeout | |
| state = previous_state | |
| var ingest_time := 0.0 | |
| for node in consumed_nodes: | |
| ingest_time += node.get_meta(&"ingest_time", 0.0) | |
| if ingest_time > 0: | |
| var previous_state := state | |
| state = State.INGESTING | |
| await get_tree().create_timer(ingest_time).timeout | |
| state = previous_state |
| tween.finished.connect( | ||
| _on_consumed_node_tween_finished.bind(node), CONNECT_REFERENCE_COUNTED | ||
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could connect to the tween's finish function just once with:
tween.finished.connect(_on_consumed_nodes_finished.bind(nodes))
and change its implementation to have a for loop?
|
@wjt thanks for playing with this mechanic, great observations. I'll see if a detection circle would help here or otherwise we can drop the idea. I'm marking this as draft so we don't merge the exploration by mistake. |
Resolves #1222