flow: hoe!
This commit is contained in:
parent
9e9ad39685
commit
41c271752e
|
@ -357,6 +357,17 @@ export class App extends decorate(class {}) {
|
|||
this.stage.camera = camera;
|
||||
// Avoid the initial 'lerp.
|
||||
camera.realPosition = camera.position;
|
||||
// Manage held item.
|
||||
entity.on('activeSlotIndexChanged', (oldIndex, newIndex) => {
|
||||
const oldItem = entity.itemInSlot(oldIndex);
|
||||
if (oldItem) {
|
||||
oldItem.wielder = null;
|
||||
}
|
||||
const newItem = entity.itemInSlot(newIndex);
|
||||
if (newItem) {
|
||||
newItem.wielder = entity;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import {behaviorItemFromJSON} from '@avocado/behavior';
|
||||
import {compose, TickingPromise} from '@avocado/core';
|
||||
import {compose, Property, TickingPromise} from '@avocado/core';
|
||||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {Image} from '@avocado/graphics';
|
||||
|
||||
const decorate = compose(
|
||||
Property('wielder', {
|
||||
track: true,
|
||||
emit: function (...args) {
|
||||
this.entity.emit(...args);
|
||||
},
|
||||
}),
|
||||
StateProperty('qty', {
|
||||
track: true,
|
||||
}),
|
||||
|
|
181
common/traits/tool.trait.js
Normal file
181
common/traits/tool.trait.js
Normal file
|
@ -0,0 +1,181 @@
|
|||
import {compose} from '@avocado/core';
|
||||
import {StateProperty, Trait} from '@avocado/entity';
|
||||
import {Color, Primitives} from '@avocado/graphics';
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
|
||||
const decorate = compose(
|
||||
);
|
||||
|
||||
// Tools.
|
||||
export class Tool extends decorate(Trait) {
|
||||
|
||||
static defaultParams() {
|
||||
return {
|
||||
target: {
|
||||
type: 'projection',
|
||||
distance: 1,
|
||||
length: 1,
|
||||
width: 1,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static type() {
|
||||
return 'tool';
|
||||
}
|
||||
|
||||
constructor(entity, params, state) {
|
||||
super(entity, params, state);
|
||||
if (AVOCADO_CLIENT) {
|
||||
this.guidePrimitives = new Primitives();
|
||||
}
|
||||
if (1 !== this.params.target.length % 2) {
|
||||
throw new Error("Tool::params.target.length must be odd!");
|
||||
}
|
||||
if (1 !== this.params.target.width % 2) {
|
||||
throw new Error("Tool::params.target.width must be odd!");
|
||||
}
|
||||
this.targets = [];
|
||||
}
|
||||
|
||||
calculateTargetStart() {
|
||||
const wielder = this.entity.wielder;
|
||||
if (!wielder) {
|
||||
return;
|
||||
}
|
||||
if (!wielder.is('directional')) {
|
||||
return;
|
||||
}
|
||||
if (!wielder.is('layered')) {
|
||||
return;
|
||||
}
|
||||
const tile = Vector.floor(wielder.tile);
|
||||
const distance = this.params.target.distance;
|
||||
return Vector.add(
|
||||
tile,
|
||||
Vector.directionalProjection(wielder.direction, [0, distance]),
|
||||
);
|
||||
}
|
||||
|
||||
calculateTargets() {
|
||||
this.targets = [];
|
||||
const wielder = this.entity.wielder;
|
||||
if (!wielder) {
|
||||
return;
|
||||
}
|
||||
if (!wielder.is('layered')) {
|
||||
return;
|
||||
}
|
||||
const layer = wielder.layer;
|
||||
if (!layer) {
|
||||
return;
|
||||
}
|
||||
const tile = Vector.floor(wielder.tile);
|
||||
const tileset = layer.tileset;
|
||||
if (!tileset) {
|
||||
return;
|
||||
}
|
||||
if (!wielder.is('directional')) {
|
||||
return;
|
||||
}
|
||||
const direction = wielder.direction;
|
||||
const start = this.calculateTargetStart();
|
||||
const width = (this.params.target.width - 1) / 2;
|
||||
for (let i = -width; i < (width + 1); ++i) {
|
||||
for (let j = 0; j < this.params.target.length; ++j) {
|
||||
this.targets.push(Vector.add(
|
||||
start,
|
||||
Vector.directionalProjection(direction, [i, j]),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onWielderDirectionChanged() {
|
||||
this.calculateTargets();
|
||||
this.renderPrimitives();
|
||||
}
|
||||
|
||||
onWielderPositionChanged() {
|
||||
this.repositionPrimitives();
|
||||
}
|
||||
|
||||
renderPrimitives() {
|
||||
this.guidePrimitives.clear();
|
||||
const wielder = this.entity.wielder;
|
||||
if (!wielder) {
|
||||
return;
|
||||
}
|
||||
if (!wielder.is('layered')) {
|
||||
return;
|
||||
}
|
||||
const layer = wielder.layer;
|
||||
if (!layer) {
|
||||
return;
|
||||
}
|
||||
const tile = Vector.floor(wielder.tile);
|
||||
const tileset = layer.tileset;
|
||||
if (!tileset) {
|
||||
return;
|
||||
}
|
||||
const tileSize = tileset.tileSize;
|
||||
for (let i = 0; i < this.targets.length; ++i) {
|
||||
const target = this.targets[i];
|
||||
const relativeTarget = Vector.sub(target, tile);
|
||||
const scaledRelativeTarget = Vector.mul(relativeTarget, tileSize);
|
||||
this.guidePrimitives.drawRectangle(
|
||||
Rectangle.compose(scaledRelativeTarget, tileSize),
|
||||
Primitives.lineStyle(new Color(255, 255, 255), 1),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
repositionPrimitives() {
|
||||
const wielder = this.entity.wielder;
|
||||
if (!wielder) {
|
||||
return;
|
||||
}
|
||||
if (!wielder.is('layered')) {
|
||||
return;
|
||||
}
|
||||
this.guidePrimitives.position = Vector.scale(wielder.tileOffset, -1);
|
||||
}
|
||||
|
||||
listeners() {
|
||||
return {
|
||||
|
||||
wielderChanged: (oldWielder, newWielder) => {
|
||||
if (oldWielder && oldWielder.is('visible')) {
|
||||
oldWielder.off(
|
||||
'positionChanged',
|
||||
this.onWielderPositionChanged,
|
||||
);
|
||||
oldWielder.off(
|
||||
'directionChanged',
|
||||
this.onWielderDirectionChanged,
|
||||
);
|
||||
oldWielder.container.removeChild(this.guidePrimitives);
|
||||
}
|
||||
if (newWielder && newWielder.is('visible')) {
|
||||
newWielder.on(
|
||||
'positionChanged',
|
||||
this.onWielderPositionChanged,
|
||||
this,
|
||||
);
|
||||
newWielder.on(
|
||||
'directionChanged',
|
||||
this.onWielderDirectionChanged,
|
||||
this,
|
||||
);
|
||||
newWielder.container.addChild(this.guidePrimitives);
|
||||
}
|
||||
this.calculateTargets();
|
||||
this.renderPrimitives();
|
||||
this.repositionPrimitives();
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
resource/hoe.png
Normal file
BIN
resource/hoe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 247 B |
|
@ -70,6 +70,10 @@ export function createEntityForConnection(socket) {
|
|||
qty: 1,
|
||||
uri: '/rock.entity.json',
|
||||
},
|
||||
2: {
|
||||
qty: 1,
|
||||
uri: '/hoe.entity.json',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -30,6 +30,8 @@ import {potionJSON} from './fixtures/potion.entity';
|
|||
writeFixture('potion.entity.json', potionJSON());
|
||||
import {rockJSON} from './fixtures/rock.entity';
|
||||
writeFixture('rock.entity.json', rockJSON());
|
||||
import {hoeJSON} from './fixtures/hoe.entity';
|
||||
writeFixture('hoe.entity.json', hoeJSON());
|
||||
// Write rooms.
|
||||
import {kittyFireJSON} from './fixtures/kitty-fire.room';
|
||||
writeFixture('kitty-fire.room.json', kittyFireJSON());
|
||||
|
|
25
server/fixtures/hoe.entity.js
Normal file
25
server/fixtures/hoe.entity.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
// Hoe.
|
||||
export function hoeJSON() {
|
||||
return {
|
||||
traits: {
|
||||
existent: {},
|
||||
item: {
|
||||
params: {
|
||||
slotImages: {
|
||||
default: '/hoe.png',
|
||||
},
|
||||
},
|
||||
},
|
||||
tool: {
|
||||
params: {
|
||||
target: {
|
||||
type: 'projection',
|
||||
distance: 1,
|
||||
length: 3,
|
||||
width: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
Loading…
Reference in New Issue
Block a user