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;
}
brightenColor(color) {
// console.log(color);
let hsl_color = ROT.Color.rgb2hsl(ROT.Color.fromString(color))
hsl_color[2] *= 1.25
return ROT.Color.toRGB(ROT.Color.hsl2rgb(hsl_color))
},
brightenColor(color) {
// console.log(color);
let hsl_color = ROT.Color.rgb2hsl(ROT.Color.fromString(color))
hsl_color[2] *= 1.25
return ROT.Color.toRGB(ROT.Color.hsl2rgb(hsl_color))
},
// this.scheduler.add(new PlayerController(), true) // Add the player to the scheduler
this.scheduler.add(this.player, true) // Add the player to the scheduler
this.scheduler.add(this.display, true)
let actors = this.map.getActors()
for (let actor of actors) {
if (actor.seenTiles) actor.seenTiles = []
// Some 'actor' objects do not take turns, such as ladders / items
if (actor !== this.player && actor instanceof Actor) {
this.scheduler.add(actor, true)
// if the actor is goal driven, clear their current goals
if (actor.subscribeToEventStream) actor.clearGoals()
}
}
// emit a new spawned event when each actor gets loaded in
actors.forEach(actor => this.eventStream.emit('EntitySpawnedEvent', { entity: actor }))
this.engine = new ROT.Engine(this.scheduler) // Create new engine with the newly created scheduler
},
scheduleAllActors() {
// Set up the ROT engine and scheduler
this.scheduler = new ROT.Scheduler.Simple()
// this.scheduler.add(new PlayerController(), true) // Add the player to the scheduler
this.scheduler.add(this.player, true) // Add the player to the scheduler
this.scheduler.add(this.display, true)
let actors = this.map.getActors()
for (let actor of actors) {
if (actor.seenTiles) actor.seenTiles = []
// Some 'actor' objects do not take turns, such as ladders / items
if (actor !== this.player && actor instanceof Actor) {
this.scheduler.add(actor, true)
// if the actor is goal driven, clear their current goals
if (actor.subscribeToEventStream) actor.clearGoals()
}
}
// emit a new spawned event when each actor gets loaded in
actors.forEach(actor => this.eventStream.emit('EntitySpawnedEvent', { entity: actor }))
this.engine = new ROT.Engine(this.scheduler) // Create new engine with the newly created scheduler
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.`;
}
}
}