Thief and Inventory APIs
This commit adds the Thief character with starter graphics (no animations). The Thief walks back and forth and will steal items from other doodads, including the player. For singleton items that have no quantity, like the Colored Keys, the Thief will only steal one if he does not already have it. Quantitied items like the Small Key are always stolen. Flexibility in the playable character is introduced: Boy, Azulian, Bird, and Thief all respond to playable controls. There is not currently a method to enable these apart from modifying balance.PlayerCharacterDoodad at compile time. New and Changed Doodads * Thief: new doodad that walks back and forth and will steal items from other characters inventory. * Bird: has no inventory and cannot pick up items, unless player controlled. Its hitbox has also been fixed so it collides with floors correctly - not something normally seen in the Bird. * Boy: opts in to have inventory. * Keys (all): only gives themselves to actors having inventories. JavaScript API - New functions available * Self.IsPlayer() - returns if the current actor IS the player. * Self.SetInventory(bool) - doodads must opt-in to having an inventory. Keys should only give themselves to doodads having an inventory. * Self.HasInventory() bool * Self.AddItem(filename, qty) * Self.RemoveItem(filename, qty) * Self.HasItem(filename) * Self.Inventory() - returns map[string]int * Self.ClearInventory() * Self.OnLeave(func(e)) now receives a CollideEvent as parameter instead of the useless actor ID. Notably, e.Actor is the leaving actor and e.Settled is always true. Other Changes * Play Mode: if playing as a character which doesn't obey gravity, such as the bird, antigravity controls are enabled by default. If you `import antigravity` you can turn gravity back on. * Doodad collision scripts are no longer run in parallel goroutines. It made the Thief's job difficult trying to steal items in many threads simultaneously!
This commit is contained in:
parent
f8ddf512a9
commit
a40cc0602e
|
@ -7,6 +7,7 @@ function main() {
|
|||
|
||||
Self.SetHitbox(0, 0, 32, 32)
|
||||
Self.SetMobile(true);
|
||||
Self.SetInventory(true);
|
||||
Self.SetGravity(true);
|
||||
Self.AddAnimation("walk-left", 100, ["red-wl1", "red-wl2", "red-wl3", "red-wl4"]);
|
||||
Self.AddAnimation("walk-right", 100, ["red-wr1", "red-wr2", "red-wr3", "red-wr4"]);
|
||||
|
@ -16,7 +17,7 @@ function main() {
|
|||
var sampleRate = 5;
|
||||
var lastSampledX = 0;
|
||||
|
||||
setInterval(function() {
|
||||
setInterval(function () {
|
||||
if (sampleTick % sampleRate === 0) {
|
||||
var curX = Self.Position().X;
|
||||
var delta = Math.abs(curX - lastSampledX);
|
||||
|
@ -33,7 +34,7 @@ function main() {
|
|||
Self.SetVelocity(Vector(Vx, 0.0));
|
||||
|
||||
if (!Self.IsAnimating()) {
|
||||
Self.PlayAnimation("walk-"+direction, null);
|
||||
Self.PlayAnimation("walk-" + direction, null);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
|
|
@ -9,11 +9,12 @@ function main() {
|
|||
|
||||
Self.SetMobile(true);
|
||||
Self.SetGravity(true);
|
||||
Self.SetInventory(true);
|
||||
Self.SetHitbox(7, 4, 17, 28);
|
||||
Self.AddAnimation("walk-left", 100, ["blu-wl1", "blu-wl2", "blu-wl3", "blu-wl4"]);
|
||||
Self.AddAnimation("walk-right", 100, ["blu-wr1", "blu-wr2", "blu-wr3", "blu-wr4"]);
|
||||
|
||||
Events.OnKeypress(function(ev) {
|
||||
Events.OnKeypress(function (ev) {
|
||||
Vx = 0;
|
||||
Vy = 0;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// Red bird mob.
|
||||
// Bird
|
||||
|
||||
function main() {
|
||||
var speed = 4;
|
||||
var Vx = Vy = 0;
|
||||
|
@ -13,11 +14,16 @@ function main() {
|
|||
|
||||
Self.SetMobile(true);
|
||||
Self.SetGravity(false);
|
||||
Self.SetHitbox(0, 10, 46, 32);
|
||||
Self.SetHitbox(0, 0, 46, 32);
|
||||
Self.AddAnimation("fly-left", 100, ["left-1", "left-2"]);
|
||||
Self.AddAnimation("fly-right", 100, ["right-1", "right-2"]);
|
||||
|
||||
Events.OnCollide(function(e) {
|
||||
// Player Character controls?
|
||||
if (Self.IsPlayer()) {
|
||||
return player();
|
||||
}
|
||||
|
||||
Events.OnCollide(function (e) {
|
||||
if (e.Actor.IsMobile() && e.InHitbox) {
|
||||
return false;
|
||||
}
|
||||
|
@ -29,7 +35,7 @@ function main() {
|
|||
var lastSampledX = 0;
|
||||
var lastSampledY = 0;
|
||||
|
||||
setInterval(function() {
|
||||
setInterval(function () {
|
||||
if (sampleTick % sampleRate === 0) {
|
||||
var curX = Self.Position().X;
|
||||
var delta = Math.abs(curX - lastSampledX);
|
||||
|
@ -46,7 +52,39 @@ function main() {
|
|||
Self.SetVelocity(Vector(Vx, 0.0));
|
||||
|
||||
if (!Self.IsAnimating()) {
|
||||
Self.PlayAnimation("fly-"+direction, null);
|
||||
Self.PlayAnimation("fly-" + direction, null);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// If under control of the player character.
|
||||
function player() {
|
||||
Self.SetInventory(true);
|
||||
Events.OnKeypress(function (ev) {
|
||||
Vx = 0;
|
||||
Vy = 0;
|
||||
|
||||
if (ev.Up) {
|
||||
Vy = -playerSpeed;
|
||||
} else if (ev.Down) {
|
||||
Vy = playerSpeed;
|
||||
}
|
||||
|
||||
if (ev.Right) {
|
||||
if (!Self.IsAnimating()) {
|
||||
Self.PlayAnimation("fly-right", null);
|
||||
}
|
||||
Vx = playerSpeed;
|
||||
} else if (ev.Left) {
|
||||
if (!Self.IsAnimating()) {
|
||||
Self.PlayAnimation("fly-left", null);
|
||||
}
|
||||
Vx = -playerSpeed;
|
||||
} else {
|
||||
Self.StopAnimation();
|
||||
animating = false;
|
||||
}
|
||||
|
||||
Self.SetVelocity(Vector(Vx, Vy));
|
||||
})
|
||||
}
|
|
@ -8,12 +8,13 @@ function main() {
|
|||
var animFrame = animStart;
|
||||
|
||||
Self.SetMobile(true);
|
||||
Self.SetInventory(true);
|
||||
Self.SetGravity(true);
|
||||
Self.SetHitbox(0, 0, 32, 52);
|
||||
Self.AddAnimation("walk-left", 200, ["stand-left", "walk-left-1", "walk-left-2", "walk-left-3", "walk-left-2", "walk-left-1"]);
|
||||
Self.AddAnimation("walk-right", 200, ["stand-right", "walk-right-1", "walk-right-2", "walk-right-3", "walk-right-2", "walk-right-1"]);
|
||||
|
||||
Events.OnKeypress(function(ev) {
|
||||
Events.OnKeypress(function (ev) {
|
||||
Vx = 0;
|
||||
Vy = 0;
|
||||
|
||||
|
|
|
@ -12,6 +12,10 @@ boy() {
|
|||
cd boy/
|
||||
make
|
||||
cd ..
|
||||
|
||||
cd thief/
|
||||
make
|
||||
cd ..
|
||||
}
|
||||
|
||||
buttons() {
|
||||
|
|
|
@ -2,11 +2,13 @@ function main() {
|
|||
var color = Self.GetTag("color");
|
||||
var quantity = color === "small" ? 1 : 0;
|
||||
|
||||
Events.OnCollide(function(e) {
|
||||
Events.OnCollide(function (e) {
|
||||
if (e.Settled) {
|
||||
Sound.Play("item-get.wav")
|
||||
e.Actor.AddItem(Self.Filename, quantity);
|
||||
Self.Destroy();
|
||||
if (e.Actor.HasInventory()) {
|
||||
Sound.Play("item-get.wav")
|
||||
e.Actor.AddItem(Self.Filename, quantity);
|
||||
Self.Destroy();
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
11
dev-assets/doodads/thief/Makefile
Normal file
11
dev-assets/doodads/thief/Makefile
Normal file
|
@ -0,0 +1,11 @@
|
|||
ALL: build
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
doodad convert -t "Thief" stand-right.png stand-left.png \
|
||||
thief.doodad
|
||||
doodad install-script thief.js thief.doodad
|
||||
|
||||
doodad edit-doodad --tag "category=creatures" thief.doodad
|
||||
|
||||
cp *.doodad ../../../assets/doodads/
|
BIN
dev-assets/doodads/thief/stand-left.png
Normal file
BIN
dev-assets/doodads/thief/stand-left.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
BIN
dev-assets/doodads/thief/stand-right.png
Normal file
BIN
dev-assets/doodads/thief/stand-right.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
104
dev-assets/doodads/thief/thief.js
Normal file
104
dev-assets/doodads/thief/thief.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
// Thief
|
||||
|
||||
function main() {
|
||||
Self.SetMobile(true);
|
||||
Self.SetGravity(true);
|
||||
Self.SetInventory(true);
|
||||
Self.SetHitbox(0, 0, 32, 58);
|
||||
Self.AddAnimation("walk-left", 200, ["stand-left"]); //, "walk-left-1", "walk-left-2", "walk-left-3", "walk-left-2", "walk-left-1"]);
|
||||
Self.AddAnimation("walk-right", 200, ["stand-right"]); //, "walk-right-1", "walk-right-2", "walk-right-3", "walk-right-2", "walk-right-1"]);
|
||||
|
||||
// Controlled by the player character?
|
||||
if (Self.IsPlayer()) {
|
||||
return playable();
|
||||
}
|
||||
return ai();
|
||||
}
|
||||
|
||||
// Enemy Doodad AI.
|
||||
function ai() {
|
||||
// Walks back and forth.
|
||||
var Vx = Vy = 0.0,
|
||||
playerSpeed = 4,
|
||||
direction = "right",
|
||||
lastSampledX = 0,
|
||||
sampleTick = 0,
|
||||
sampleRate = 2,
|
||||
stolenItems = {}; // map item->qty
|
||||
|
||||
setInterval(function () {
|
||||
if (sampleTick % sampleRate === 0) {
|
||||
var curX = Self.Position().X,
|
||||
delta = Math.abs(curX - lastSampledX);
|
||||
if (delta < 5) {
|
||||
direction = direction === "right" ? "left" : "right";
|
||||
}
|
||||
lastSampledX = curX;
|
||||
}
|
||||
sampleTick++;
|
||||
|
||||
Vx = parseFloat(playerSpeed * (direction === "left" ? -1 : 1));
|
||||
Self.SetVelocity(Vector(Vx, Vy));
|
||||
|
||||
Self.StopAnimation();
|
||||
Self.PlayAnimation("walk-" + direction, null);
|
||||
}, 100);
|
||||
|
||||
// Steals your items.
|
||||
Events.OnCollide(function (e) {
|
||||
if (!e.Settled) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Steal inventory
|
||||
var stolen = 0;
|
||||
if (e.Actor.HasInventory()) {
|
||||
var myInventory = Self.Inventory(),
|
||||
theirInventory = e.Actor.Inventory();
|
||||
|
||||
for (var key in theirInventory) {
|
||||
if (!theirInventory.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var value = theirInventory[key];
|
||||
if (value > 0 || myInventory[key] === undefined) {
|
||||
e.Actor.RemoveItem(key, value);
|
||||
Self.AddItem(key, value);
|
||||
stolenItems[key] = value;
|
||||
stolen += (value === 0 ? 1 : value);
|
||||
}
|
||||
}
|
||||
|
||||
// Notify the player if it was them.
|
||||
if (e.Actor.IsPlayer() && stolen > 0) {
|
||||
Flash("Watch out for thieves! %d item%s stolen!", parseInt(stolen), stolen === 1 ? ' was' : 's were');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If under control of the player character.
|
||||
function playable() {
|
||||
Events.OnKeypress(function (ev) {
|
||||
Vx = 0;
|
||||
Vy = 0;
|
||||
|
||||
if (ev.Right) {
|
||||
if (!Self.IsAnimating()) {
|
||||
Self.PlayAnimation("walk-right", null);
|
||||
}
|
||||
Vx = playerSpeed;
|
||||
} else if (ev.Left) {
|
||||
if (!Self.IsAnimating()) {
|
||||
Self.PlayAnimation("walk-left", null);
|
||||
}
|
||||
Vx = -playerSpeed;
|
||||
} else {
|
||||
Self.StopAnimation();
|
||||
animating = false;
|
||||
}
|
||||
|
||||
// Self.SetVelocity(Point(Vx, Vy));
|
||||
})
|
||||
}
|
Loading…
Reference in New Issue
Block a user