Skip to content

Bind handling#60

Open
kristomu wants to merge 27 commits intocknave:mainfrom
kristomu:bind-handling
Open

Bind handling#60
kristomu wants to merge 27 commits intocknave:mainfrom
kristomu:bind-handling

Conversation

@kristomu
Copy link
Copy Markdown
Contributor

Another Oktrollber-inspired bout of coding: while I was creating my game, I noticed that after editing, the game would sometimes cause weird behavior in ZZT (including reads from unallocated memory). I think this was due to dangling #bind indices and indices that didn't change as copied objects around, hence this.

The patch resolves bind index chains and cycles (A->B->C or A->B->C->A) on loading and saving a board. On pasting it uses the following reasoning:

  • If copying a bunch of bound objects without what they're bound to, to a board that doesn't have that object, it makes one of them the new source and relinks the others.
  • If the destination does have that object (or another object with the same program), it links every object to that object.
  • If the paste selection contains both bound objects and the object they link to, then the relation is preserved, even if the destination board has a different number of objects than the source board or has other objects with the same program.

It relinks bind indices when cutting stuff as well: if the original source object of bound objects is removed, then one of the bound objects becomes the new source and they all link to it. And finally it does a reasonable job of preserving follower/leader chains, though it won't turn segments into heads.

Now placing a player won't erase what's on the wrong initial player
coords. This problem came up in some worlds produced by my ZZT puzzle
generator. (Not really related to #BIND functionality improvement.)
This should keep any breaking #BIND links from making ZZT behave
unpredictably.
This will be used for determining if the destination of copy and paste
has the source for bound objects.
The first part moves objects that would be overwritten and are
bound to by other objects outside the pasting area, out of the
pasting area.
Now I just need to find out how to copy params and extend the param
array without running afoul of KevEdit's internal malloc/free
calculus.
Known bugs:
	- There are some double frees I need to track down.
	- It copies paramless tiles if the param would exceed the limit,
		instead of omitting them.

The double frees don't happen if the user unloads and reloads the board
between cuts and pastes. So there's something strange going on with
tile.param, I suspect.
This fixes the double free that goes away on board reload.
There's still one when copying multiple bound objects without
their source to the same board they're from.

In addition, copying multiple objects with the same source (but
without the source) to another board makes them all unbound; only
one of them should, and the rest should bind to it instead.

The latter problem is with misc.c:544. Find out just what's going
on later.
The bug was caused by not incrementing a counter properly. This
has been moved to the beginning of the relevant loops so there's
less special casing going on.
We might argue that the new pasting function is so complex that it
shouldn't be used until the user has decided where to place the
selection. But if that's a problem, a simple "|| preview_mode" on
the "If there are no objects to add" if statement should do the job
much more easily.
…ctions.

This fixes a subtle bug where copying the player would overwrite adjacent
tiles, and consistently using isselected_both makes the code easier to
understand even when not strictly necessary.

Add parentheses to a macro in keys.h as well.
@asiekierka
Copy link
Copy Markdown
Contributor

asiekierka commented Nov 17, 2023

The PR is complex, so maybe that's already been done, but I'd like to note down to make sure that the object being bound to should ideally always come before the objects binding to it in the stat order. ZZT prefers it that way.

These fix operations are done on board load and save, and on pasting
something onto a board. Previously it would only normalize on a board
being saved or loaded.
@kristomu
Copy link
Copy Markdown
Contributor Author

Done.

This is more true to what ZZT itself does.
@kristomu
Copy link
Copy Markdown
Contributor Author

Some tests/demos of the patch's functionality: https://munsterhjelm.no/km/zzt/kevtest.zzt

@kristomu
Copy link
Copy Markdown
Contributor Author

If the PR is too imposing, I could try to split it into different components or see if anything could be simplified.

@kristomu
Copy link
Copy Markdown
Contributor Author

It's been a while, so I thought I'd comment. Any chance of getting this incorporated, or should I refactor or split it up into something less extensive?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants