Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
canHit(owner, target, attackNum) {
if(owner.hp.atMin()) return false;
const hitRoll = Roll(`1d${20 + attackNum}`); // subsequent attacks are less likely to hit
const targetAC = target.getAC();
const myToHitBonus = (Roll(this.toHit) - owner.getToHit(target) - owner.getSkillLevelValue(this.getType()) - (this._itemRef ? this._itemRef.buc-1 : 0)); // cursed: -2, uncursed: 0, blessed: +1
let targetACRoll = 0;
if(targetAC >= 0) {
targetACRoll = targetAC + owner.level - myToHitBonus;
} else {
targetACRoll = Settings.game.baseAC + ROT.RNG.getUniformInt(targetAC, -1) + owner.level - myToHitBonus;
}
return hitRoll < targetACRoll;
}
hitCallback(owner) {
owner.breakConduct('pacifist');
// TODO this should probably be a behavior
if(this.spawn && ROT.RNG.getPercentage() <= this.spawnChance) {
const spawnMe = WeightedExtension(this.spawn).key;
const validTile = _.sample(GameState.world.getValidTilesInRange(owner.x, owner.y, owner.z, 1, (tile) => GameState.world.isTileEmpty(tile.x, tile.y, tile.z)));
if(!validTile) return;
MonsterSpawner.spawnSingle(spawnMe, validTile);
}
return ROT.RNG.getPercentage() <= this.percent;
}
stepRandomly() {
const tiles = GameState.world.getAllTilesInRange(this.x, this.y, this.z, 1);
const validTiles = _.map(tiles, (tile, i) => GameState.world.isTileEmpty(tile.x, tile.y, tile.z) ? i+1 : null); // 1-9 instead of 0-8
let direction = _(validTiles).compact().sample() - 1; // adjustment for array
let newTile = tiles[direction]; // default to a random tile
if(this.lastDirection) {
const probs = calc(this.lastDirection + 1); // adjust for array
const choices = _(validTiles).map(tileIndex => tileIndex ? [tileIndex, probs[tileIndex]] : null).compact().zipObject().value();
direction = parseInt(ROT.RNG.getWeightedValue(choices)) - 1;
newTile = tiles[direction];
}
if(!newTile) return; // surrounded
this.move(newTile);
this.lastDirection = direction;
this.doBehavior('step');
}
die(me) {
if(ROT.RNG.getPercentage() > this.percent) {
MessageQueue.add({ message: `${me.name} explodes a little bit.`, type: MessageTypes.COMBAT });
return;
}
MessageQueue.add({ message: `${me.name} violently explodes!`, type: MessageTypes.COMBAT });
_.each(GameState.world.getValidEntitiesInRange(me.x, me.y, me.z, this.range), (entity) => {
if(me === entity || entity.hp.atMin()) return; // infinite loop prevention
entity.takeDamage(Roll(this.roll), me);
});
}
}
tile.updateTileInfo(t.texture)
} else if (t.type === textures.FOREST.type) {
tile.updateTileInfo(t.texture)
if (between(5, t.elevation, 6) || between(10, t.elevation, 100)) {
tile.updateTileInfo(tree)
} else {
if (getRandomInt(0, 4) > 0) {
let obstacle = ROT.RNG.getWeightedValue(floraFaunaProbability)
tile.updateTileInfo(obstacle)
}
}
// chance of placing an enemy in the open tiles...
if (!tile.blocked()) {
if (getRandomInt(0, 500) === 1) {
// 1% chance
let chosenActor = ROT.RNG.getWeightedValue(mobDistribution)
let possibleActorTextures = actorTextures[chosenActor]
let randomTexture = possibleActorTextures[getRandomInt(0, possibleActorTextures.length - 1)]
// let actor = createActor(chosenActor, x, y, randomTexture)
// tile.actors.push(actor)
}
}
}
}
}
gameMap.playerLocation = [~~(w / 2), ~~(h / 2)]
return gameMap
}
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();
return `The pipes explode! Water spurts out!`;
}
this.ceaseExisting();
return `The sink stops providing water.`;
}
}
}
generateBUC(opts = { cursed: 5, blessed: 5, uncursed: 90 }) {
if(!this.bucName) {
const status = ROT.RNG.getWeightedValue(opts);
this.bucName = status;
}
this.setBUC();
}
return Math.sqrt(a*a + b*b);
};
while(inBadZone) {
const myX = ROT.RNG.getUniformInt(0, SETTINGS.screen.width);
const myY = ROT.RNG.getUniformInt(0, SETTINGS.screen.height);
const me = { x: myX, y: myY };
if(_.filter(this.stars, (star) => distBetween(me, star) < 4).length !== 0 ||
myX >= minX && myX <= maxX &&
myY >= minY && myY <= maxY) {
continue;
}
inBadZone = false;
star = { x: myX, y: myY, phase: ROT.RNG.getUniformInt(0, this.phases.length-1) };
}
this.stars.push(star);
}
export function getWeightedValue(table) {
let rotFormat = {}
for (let key in table) {
rotFormat[key] = table[key].chance
}
return ROT.RNG.getWeightedValue(rotFormat)
}
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;
}