ArnoldSmith86 / virtualtabletop

a virtual surface in the browser on which you can play board, dice and card games
https://virtualtabletop.io
GNU General Public License v3.0
173 stars 31 forks source link

setting `stackOffsetX` from `0` to `40` offsets the cards inside the pile #2320

Open ArnoldSmith86 opened 2 months ago

ArnoldSmith86 commented 2 months ago

QuickDownload without assets 2024-09-22 2003 - Unnamed.vtt.zip

Click Offset 40 in the top right.

It doesn't do anything in hand.

Also: setting it back to 0 doesn't do anything.

bjalder26 commented 4 weeks ago

It looks like these are the related functions in holder.js:

  async onPropertyChange(property, oldValue, newValue) {
    await super.onPropertyChange(property, oldValue, newValue);
    if(property == 'dropOffsetX' || property == 'dropOffsetY' || property == 'stackOffsetX' || property == 'stackOffsetY') {
      await this.updateAfterShuffle();
    }
  }

async updateAfterShuffle() {
    if(!this.get('stackOffsetX') && !this.get('stackOffsetY'))
      return;

    const children = this.children();
    for(const owner of new Set(children.map(c=>c.get('owner')))) {
      await this.rearrangeChildren(children.filter(c=>!c.get('owner') || c.get('owner')===owner).sort((a, b)=>{
        return a.get('z') - b.get('z');
      }));
    }
  }
}

async rearrangeChildren(children, card) {
    if(this.preventRearrangeDuringPileDrop)
      return;

    let xOffset = 0;
    let yOffset = 0;
    let z = 1;

    for(const child of children) {
      const newX = this.get('dropOffsetX') + xOffset;
      const newY = this.get('dropOffsetY') + yOffset;
      const newZ = z++;

      await child.setPosition(newX, newY, newZ);

      xOffset += !child.get('overlap') && this.get('stackOffsetX') ? child.get('width' ) + 4 : this.get('stackOffsetX');
      yOffset += !child.get('overlap') && this.get('stackOffsetY') ? child.get('height') + 4 : this.get('stackOffsetY');
    }
  }

stackOffsetX: 0 evaluates as a null value, so !this.get('stackOffsetX') will evaluate as true in updateAfterShuffle() and it will just return rather than updating.

I'm not sure how the piles should behave when stackOffsetX or stackOffsetY are updated, but it looks like currently they don't break the pile (and reset the parent to the holder) and they offset cards from the pile.

It seems like the workaround for this would be to preventPiles on the holder, then set the stackOffsetY to 0.0000001.