<commit_before>
import ROT from 'rot-js';
import Tile from '../../definitions/tile';
import GameState from '../../init/gamestate';
import * as FountainEffects from '../../content/effects/fountain';
import * as ThroneEffects from '../../content/effects/throne';
import * as SinkDrinkEffects from '../../content/effects/sink-drink';
import * as SinkKickEffects from '../../content/effects/sink-kick';
import { Tiles as Glyphs } from '../../constants/glyphs';
import { Special as SpecialGlyphColors, Tiles as GlyphColors } from '../../constants/glyphColors';

export class Door extends Tile {
  constructor() {
    const isClosed = !!Math.round(ROT.RNG.getUniform());
    const openChar = isClosed ? Glyphs.DoorOpenHorizontal : Glyphs.DoorClosed;
    super(openChar, GlyphColors.Door);
    this._isAIPassable = true;

    this.opacity = !~~isClosed;
    this.density = !~~isClosed;
  }

  // the door should look different than the walls next to it
  getOpenChar(basedOn) {
    const leftTileGlyph = basedOn.glyph.key;
    return leftTileGlyph === Glyphs.DoorOpenHorizontal ? Glyphs.DoorOpenVertical : Glyphs.DoorOpenHorizontal;
  }

  canInteract() {
    return this.density;
  }

  setProperCharacter(basedOn = GameState.world.getTile(this.x - 1, this.y, this.z)) {
    const isOpen = this.density;
    const toggleChar = isOpen ? Glyphs.DoorClosed : this.getOpenChar(basedOn);
    this.glyph.key = toggleChar;
  }

  interact(entity) {
    this.opacity = !this.opacity;
    this.density = !this.density;
    this.setProperCharacter();

    return `${entity.name} ${this.density ? 'closed': 'opened'} the door.`;
  }
}

export class SelykAltar extends Tile {
  constructor() { super(Glyphs.Altar, SpecialGlyphColors.Selyk); }

  canInteract(entity) {
    return this.distBetween(entity) <= 1;
  }

  interact(entity) {
    entity._ascended = true;
    return `${entity.name} has acended to the Selykian Plane.`;
  }
}

export class Fountain extends Tile {
  constructor() {
    super(Glyphs.Fountain, GlyphColors.Fountain);
    this.density = 1;
  }

  canInteract(entity) {
    return this.distBetween(entity) <= 1;
  }

  interact(entity) {
    const effect = this.getRandomEffect(FountainEffects);
    effect.use(entity, this);
    if(ROT.RNG.getPercentage() <= 33) {
      this.ceaseExisting();
      return `The fountain dried up!`;
    }
  }
}

export class Throne extends Tile {
  constructor() {
    super(Glyphs.Throne, GlyphColors.Throne);
  }

  canInteract(entity) {
    return this.distBetween(entity) === 0;
  }

  interact(entity) {
    const effect = this.getRandomEffect(ThroneEffects);
    effect.use(entity, this);
    if(ROT.RNG.getPercentage() <= 33) {
      this.ceaseExisting();
      return `The throne vanishes in a puff of logic!`;
    }
  }
}

export class Sink extends Tile {
  constructor() {
    super(Glyphs.Sink, GlyphColors.Sink);
    this.density = 1;
  }

  canInteract(entity) {
    return this.distBetween(entity) <= 1;
  }

  becomeFountain() {
    GameState.world.placeNewTile(Fountain, this.x, this.y, this.z);
  }

  interact(entity) {
    if(ROT.RNG.getPercentage() <= 0) {
      this.getRandomEffect(SinkDrinkEffects).use(entity, this);
    } else {
      this.getRandomEffect(SinkKickEffects).use(entity, this);
    }

    // break chance
    if(ROT.RNG.getPercentage() <= 0) {

      // it might turn into a fountain, but probably not
      if(ROT.RNG.getPercentage() <= 20) {
        this.becomeFountain();<commit_msg>fixing sink traps<commit_after>
import ROT from 'rot-js';
import Tile from '../../definitions/tile';
import GameState from '../../init/gamestate';
import * as FountainEffects from '../../content/effects/fountain';
import * as ThroneEffects from '../../content/effects/throne';
import * as SinkDrinkEffects from '../../content/effects/sink-drink';
import * as SinkKickEffects from '../../content/effects/sink-kick';
import { Tiles as Glyphs } from '../../constants/glyphs';
import { Special as SpecialGlyphColors, Tiles as GlyphColors } from '../../constants/glyphColors';

export class Door extends Tile {
  constructor() {
    const isClosed = !!Math.round(ROT.RNG.getUniform());
    const openChar = isClosed ? Glyphs.DoorOpenHorizontal : Glyphs.DoorClosed;
    super(openChar, GlyphColors.Door);
    this._isAIPassable = true;

    this.opacity = !~~isClosed;
    this.density = !~~isClosed;
  }

  // the door should look different than the walls next to it
  getOpenChar(basedOn) {
    const leftTileGlyph = basedOn.glyph.key;
    return leftTileGlyph === Glyphs.DoorOpenHorizontal ? Glyphs.DoorOpenVertical : Glyphs.DoorOpenHorizontal;
  }

  canInteract() {
    return this.density;
  }

  setProperCharacter(basedOn = GameState.world.getTile(this.x - 1, this.y, this.z)) {
    const isOpen = this.density;
    const toggleChar = isOpen ? Glyphs.DoorClosed : this.getOpenChar(basedOn);
    this.glyph.key = toggleChar;
  }

  interact(entity) {
    this.opacity = !this.opacity;
    this.density = !this.density;
    this.setProperCharacter();

    return `${entity.name} ${this.density ? 'closed': 'opened'} the door.`;
  }
}

export class SelykAltar extends Tile {
  constructor() { super(Glyphs.Altar, SpecialGlyphColors.Selyk); }

  canInteract(entity) {
    return this.distBetween(entity) <= 1;
  }

  interact(entity) {
    entity._ascended = true;
    return `${entity.name} has acended to the Selykian Plane.`;
  }
}

export class Fountain extends Tile {
  constructor() {
    super(Glyphs.Fountain, GlyphColors.Fountain);
    this.density = 1;
  }

  canInteract(entity) {
    return this.distBetween(entity) <= 1;
  }

  interact(entity) {
    const effect = this.getRandomEffect(FountainEffects);
    effect.use(entity, this);
    if(ROT.RNG.getPercentage() <= 33) {
      this.ceaseExisting();
      return `The fountain dried up!`;
    }
  }
}

export class Throne extends Tile {
  constructor() {
    super(Glyphs.Throne, GlyphColors.Throne);
  }

  canInteract(entity) {
    return this.distBetween(entity) === 0;
  }

  interact(entity) {
    const effect = this.getRandomEffect(ThroneEffects);
    effect.use(entity, this);
    if(ROT.RNG.getPercentage() <= 33) {
      this.ceaseExisting();
      return `The throne vanishes in a puff of logic!`;
    }
  }
}

export class Sink extends Tile {
  constructor() {
    super(Glyphs.Sink, GlyphColors.Sink);
    this.density = 1;
  }

  canInteract(entity) {
    return this.distBetween(entity) <= 1;
  }

  becomeFountain() {
    GameState.world.placeNewTile(Fountain, this.x, this.y, this.z);
  }

  interact(entity) {
    if(ROT.RNG.getPercentage() <= 60) {
      this.getRandomEffect(SinkDrinkEffects).use(entity, this);
    } else {
      this.getRandomEffect(SinkKickEffects).use(entity, this);
    }

    // break chance
    if(ROT.RNG.getPercentage() <= 30) {

      // it might turn into a fountain, but probably not
      if(ROT.RNG.getPercentage() <= 20) {
        this.becomeFountain();
{'fraction_non_alphanumeric': 0.13906520484708598, 'fraction_numerical': 0.004616272360069244, 'mean_word_length': 3.314250155569384, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3419222', 'n_tokens_mistral': 2439, 'n_tokens_neox': 2349, 'n_words': 491}