Модель предметов по базе ремейка: узлы, деревья, знание
Протокол: - ItemData читает таблицу items/items.csv (218 предметов ремейка) и отдает числа: урон, дальность, темп, прочность, сколько ресурса за удар. - ItemType: поля rid, researchScrap, techTreeBench, techTreeScrap, techTreeParent, admin. Урон по частям тела делится как в ремейке: голова вдвое, руки и ноги четыре пятых. Число в исходнике главнее таблицы. - ItemRegistry: 218 предметов с рецептами, ценой исследования и веткой дерева. Новые вещи: salvage-тесак, бронедвери, гаражи, взрывчатка, компоненты, еда, мусор, верстаки и печи. - NodeType: узлы с запасом (дерево 500/750/1000, камень 750, металл 500, сера 200) и меткой: крестик на дереве до двух, горячая точка на руде до трех. - TechTree: ветки верстаков с предками, 125/250/500 скрапа. - Новые пакеты: Dig, BreakProgress, CraftStart, CraftUpdate, ResearchStart, ResearchUpdate, TechTreeUnlock, KnownRecipes, TechTreeState, ContainerOpen, ContainerTake, LearnBlueprint. Сервер: - Knowledge: что игрок знает - рецепты и открытые узлы деревьев. - Crafter: проверка рецепта, уровня верстака и ингредиентов; время крафта по формуле плана. - ResearchTable: предмет плюс скрап, десять секунд, предмет превращается в чертёж; чертёж изучается и открывает рецепт. - ResourceNode: запас, метка, последний удар отдает остаток. - JunkPile: две-четыре бочки (серая - скрап и мусор, синяя - компонент, красная - нефть и топливо) и ящик с едой; пустая мусорка исчезает через 60-180 секунд. - RoadNetwork: сетка дорог и кольцо, точки спавна мусорки; генератор кладет асфальт и ровняет дорогу по ширине. - Проверка досягаемости вынесена из changeBlock, игрок получил benchLevel. - Сессия отвечает на новые пакеты, при входе шлет известные рецепты и открытые узлы. Тесты: протокол 24 + 10, сервер 74 (было 57). Форк собирается чисто.
This commit is contained in:
@@ -0,0 +1,353 @@
|
||||
package net.rustnotmc.protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Tests for the item table, the registry, the trees and the nodes.
|
||||
*
|
||||
* The numbers here come from the table of the remake. A test that pins them
|
||||
* down is what stops a change in the table from quietly changing the game:
|
||||
* when the numbers move, the test says so.
|
||||
*/
|
||||
public final class ItemTest {
|
||||
|
||||
private static int checks;
|
||||
private static int failed;
|
||||
private static final List<String> failures = new ArrayList<String>();
|
||||
|
||||
public static void main(String[] args) {
|
||||
run("the table is read", new Runnable() {
|
||||
public void run() { testTableLoads(); }
|
||||
});
|
||||
run("the table holds the numbers of the remake", new Runnable() {
|
||||
public void run() { testTableNumbers(); }
|
||||
});
|
||||
run("every item of the registry is in the table", new Runnable() {
|
||||
public void run() { testRegistryMatchesTable(); }
|
||||
});
|
||||
run("the tool takes the numbers of the table", new Runnable() {
|
||||
public void run() { testToolNumbers(); }
|
||||
});
|
||||
run("the damage is split over the body", new Runnable() {
|
||||
public void run() { testDamageSplit(); }
|
||||
});
|
||||
run("the trees cost what the plan says", new Runnable() {
|
||||
public void run() { testTreePrices(); }
|
||||
});
|
||||
run("a branch has to be walked", new Runnable() {
|
||||
public void run() { testTreeParents(); }
|
||||
});
|
||||
run("the nodes hold what the plan says", new Runnable() {
|
||||
public void run() { testNodePools(); }
|
||||
});
|
||||
run("the mark of a node grows and stops", new Runnable() {
|
||||
public void run() { testNodeMarkers(); }
|
||||
});
|
||||
run("the new packets survive the round trip", new Runnable() {
|
||||
public void run() { testPackets(); }
|
||||
});
|
||||
|
||||
System.out.println("");
|
||||
if (failed == 0) {
|
||||
System.out.println(" " + checks + " checks passed.");
|
||||
return;
|
||||
}
|
||||
System.out.println(" " + failed + " of " + checks + " checks FAILED:");
|
||||
for (int i = 0; i < failures.size(); i++) {
|
||||
System.out.println(" " + failures.get(i));
|
||||
}
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
private static void testTableLoads() {
|
||||
yes("the table is not empty", ItemData.size() > 200);
|
||||
ItemData.Row rock = ItemData.byRid("rock");
|
||||
yes("the rock is in the table", rock != null);
|
||||
if (rock != null) {
|
||||
eq("the rock hurts ten", Integer.valueOf(10), Integer.valueOf(rock.damage));
|
||||
eq("the rock takes fifty wood", Integer.valueOf(50), Integer.valueOf(rock.wood));
|
||||
eq("the rock takes thirty five ore", Integer.valueOf(35), Integer.valueOf(rock.ore));
|
||||
eq("the rock lasts a hundred", Integer.valueOf(100), Integer.valueOf(rock.durability));
|
||||
eq("the rock swings every two seconds", Integer.valueOf(40),
|
||||
Integer.valueOf(rock.cooldown));
|
||||
}
|
||||
ItemData.Row hatchet = ItemData.byRid("ironaxe");
|
||||
yes("the hatchet is in the table", hatchet != null);
|
||||
if (hatchet != null) {
|
||||
eq("the hatchet takes eighty five wood", Integer.valueOf(85),
|
||||
Integer.valueOf(hatchet.wood));
|
||||
eq("the hatchet hurts twenty five", Integer.valueOf(25),
|
||||
Integer.valueOf(hatchet.damage));
|
||||
eq("the hatchet lasts three hundred", Integer.valueOf(300),
|
||||
Integer.valueOf(hatchet.durability));
|
||||
}
|
||||
}
|
||||
|
||||
private static void testTableNumbers() {
|
||||
// The numbers the plan writes down have to be the numbers the table
|
||||
// holds, otherwise the two drift apart.
|
||||
eq("the tree of a poor one is five hundred", Integer.valueOf(500),
|
||||
Integer.valueOf(NodeType.byId(NodeType.TREE_POOR).pool));
|
||||
eq("the tree of an ordinary one is seven hundred fifty", Integer.valueOf(750),
|
||||
Integer.valueOf(NodeType.byId(NodeType.TREE_COMMON).pool));
|
||||
eq("a dead tree is a thousand", Integer.valueOf(1000),
|
||||
Integer.valueOf(NodeType.byId(NodeType.TREE_DEAD).pool));
|
||||
eq("a stone outcrop is seven hundred fifty", Integer.valueOf(750),
|
||||
Integer.valueOf(NodeType.byId(NodeType.STONE).pool));
|
||||
eq("a metal deposit is five hundred", Integer.valueOf(500),
|
||||
Integer.valueOf(NodeType.byId(NodeType.METAL).pool));
|
||||
eq("a sulfur deposit is two hundred", Integer.valueOf(200),
|
||||
Integer.valueOf(NodeType.byId(NodeType.SULFUR).pool));
|
||||
}
|
||||
|
||||
private static void testRegistryMatchesTable() {
|
||||
int withRid = 0;
|
||||
for (ItemType type : ItemRegistry.all()) {
|
||||
if (type.rid == null) {
|
||||
continue;
|
||||
}
|
||||
withRid++;
|
||||
yes("the table knows " + type.rid, ItemData.byRid(type.rid) != null);
|
||||
}
|
||||
yes("most items come from the table", withRid > 90);
|
||||
// And the other way round: the table may know more than we do, but
|
||||
// everything it knows that we also know has to be the same item.
|
||||
for (ItemType type : ItemRegistry.all()) {
|
||||
if (type.rid == null) {
|
||||
continue;
|
||||
}
|
||||
ItemData.Row row = ItemData.byRid(type.rid);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
if (row.damage > 0) {
|
||||
eq("the damage of " + type.rid, Integer.valueOf(row.damage),
|
||||
Integer.valueOf(type.damage(ItemType.TORSO)));
|
||||
}
|
||||
if (row.durability > 0) {
|
||||
eq("the durability of " + type.rid, Integer.valueOf(row.durability),
|
||||
Integer.valueOf(type.durability));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testToolNumbers() {
|
||||
ItemType rock = ItemRegistry.require(ItemRegistry.ROCK);
|
||||
yes("the rock gathers wood", rock.gather(ResourceClass.TREE) != null);
|
||||
eq("the rock takes fifty wood a swing", Integer.valueOf(50),
|
||||
Integer.valueOf(rock.gather(ResourceClass.TREE).damage));
|
||||
eq("the rock takes thirty five ore a swing", Integer.valueOf(35),
|
||||
Integer.valueOf(rock.gather(ResourceClass.STONE).damage));
|
||||
yes("the rock has no pickaxe", rock.gather(ResourceClass.TREE) != null);
|
||||
|
||||
ItemType hatchet = ItemRegistry.require(ItemRegistry.HATCHET);
|
||||
eq("the hatchet takes eighty five wood", Integer.valueOf(85),
|
||||
Integer.valueOf(hatchet.gather(ResourceClass.TREE).damage));
|
||||
yes("the hatchet does not mine", hatchet.gather(ResourceClass.STONE) == null);
|
||||
|
||||
ItemType pickaxe = ItemRegistry.require(ItemRegistry.PICKAXE);
|
||||
eq("the pickaxe takes a hundred ore", Integer.valueOf(100),
|
||||
Integer.valueOf(pickaxe.gather(ResourceClass.STONE).damage));
|
||||
yes("the pickaxe does not cut", pickaxe.gather(ResourceClass.TREE) == null);
|
||||
}
|
||||
|
||||
private static void testDamageSplit() {
|
||||
ItemType rock = ItemRegistry.require(ItemRegistry.ROCK);
|
||||
eq("the head takes twice", Integer.valueOf(20),
|
||||
Integer.valueOf(rock.damage(ItemType.HEAD)));
|
||||
eq("the torso takes the number", Integer.valueOf(10),
|
||||
Integer.valueOf(rock.damage(ItemType.TORSO)));
|
||||
eq("the arms take four fifths", Integer.valueOf(8),
|
||||
Integer.valueOf(rock.damage(ItemType.ARMS)));
|
||||
eq("the legs take four fifths", Integer.valueOf(8),
|
||||
Integer.valueOf(rock.damage(ItemType.LEGS)));
|
||||
}
|
||||
|
||||
private static void testTreePrices() {
|
||||
eq("the tree of the first workbench costs a hundred twenty five",
|
||||
Integer.valueOf(125), Integer.valueOf(TechTree.PRICE_L1));
|
||||
eq("the tree of the second workbench costs two hundred fifty",
|
||||
Integer.valueOf(250), Integer.valueOf(TechTree.PRICE_L2));
|
||||
eq("the tree of the third workbench costs five hundred",
|
||||
Integer.valueOf(500), Integer.valueOf(TechTree.PRICE_L3));
|
||||
eq("the hatchet costs a hundred twenty five", Integer.valueOf(125),
|
||||
Integer.valueOf(TechTree.costOf(ItemRegistry.HATCHET)));
|
||||
eq("the hatchet sits in the tree of the first workbench", Integer.valueOf(1),
|
||||
Integer.valueOf(TechTree.forItem(ItemRegistry.HATCHET).bench));
|
||||
eq("the salvaged axe sits in the tree of the second workbench", Integer.valueOf(2),
|
||||
Integer.valueOf(TechTree.forItem(ItemRegistry.SALVAGED_AXE).bench));
|
||||
eq("the armored door sits in the tree of the third workbench", Integer.valueOf(3),
|
||||
Integer.valueOf(TechTree.forItem(ItemRegistry.ARMORED_DOOR).bench));
|
||||
eq("the rock is in no tree", Integer.valueOf(0),
|
||||
Integer.valueOf(TechTree.costOf(ItemRegistry.ROCK)));
|
||||
}
|
||||
|
||||
private static void testTreeParents() {
|
||||
Set<Integer> nothing = new HashSet<Integer>();
|
||||
yes("the root of a branch can be opened",
|
||||
TechTree.canOpen(ItemRegistry.SALVAGED_HAMMER, nothing));
|
||||
yes("the next one cannot",
|
||||
!TechTree.canOpen(ItemRegistry.HATCHET, nothing));
|
||||
|
||||
Set<Integer> withHammer = new HashSet<Integer>();
|
||||
withHammer.add(Integer.valueOf(ItemRegistry.SALVAGED_HAMMER));
|
||||
yes("with the hammer the hatchet opens",
|
||||
TechTree.canOpen(ItemRegistry.HATCHET, withHammer));
|
||||
yes("with the hammer the sword does not",
|
||||
!TechTree.canOpen(ItemRegistry.SALVAGED_SWORD, withHammer));
|
||||
|
||||
Set<Integer> withHatchet = new HashSet<Integer>(withHammer);
|
||||
withHatchet.add(Integer.valueOf(ItemRegistry.HATCHET));
|
||||
yes("with the hatchet the sword opens",
|
||||
TechTree.canOpen(ItemRegistry.SALVAGED_SWORD, withHatchet));
|
||||
}
|
||||
|
||||
private static void testNodePools() {
|
||||
eq("the ordinary tree holds seven hundred fifty", Integer.valueOf(750),
|
||||
Integer.valueOf(NodeType.byId(NodeType.TREE_COMMON).pool));
|
||||
eq("the tree gives wood", Integer.valueOf(ItemRegistry.WOOD),
|
||||
Integer.valueOf(NodeType.byId(NodeType.TREE_COMMON).dropItem));
|
||||
eq("the outcrop gives stones", Integer.valueOf(ItemRegistry.STONE),
|
||||
Integer.valueOf(NodeType.byId(NodeType.STONE).dropItem));
|
||||
eq("the deposit gives metal", Integer.valueOf(ItemRegistry.METAL),
|
||||
Integer.valueOf(NodeType.byId(NodeType.METAL).dropItem));
|
||||
eq("the sulfur deposit gives sulfur", Integer.valueOf(ItemRegistry.SULFUR),
|
||||
Integer.valueOf(NodeType.byId(NodeType.SULFUR).dropItem));
|
||||
yes("a tree has a cross", NodeType.byId(NodeType.TREE_COMMON).hasMarker());
|
||||
yes("an outcrop has a hot spot", NodeType.byId(NodeType.STONE).hasMarker());
|
||||
}
|
||||
|
||||
private static void testNodeMarkers() {
|
||||
NodeType tree = NodeType.byId(NodeType.TREE_COMMON);
|
||||
eq("a swing without the cross is the plain one", Integer.valueOf(85),
|
||||
Integer.valueOf(tree.swingDamage(85, 0)));
|
||||
eq("the first cross adds an eighth", Integer.valueOf(96),
|
||||
Integer.valueOf(tree.swingDamage(85, 1)));
|
||||
eq("the cross stops at twice", Integer.valueOf(170),
|
||||
Integer.valueOf(tree.swingDamage(85, 100)));
|
||||
|
||||
NodeType ore = NodeType.byId(NodeType.STONE);
|
||||
eq("the first hot spot adds half", Integer.valueOf(75),
|
||||
Integer.valueOf(ore.swingDamage(50, 1)));
|
||||
eq("the hot spot stops at three times", Integer.valueOf(150),
|
||||
Integer.valueOf(ore.swingDamage(50, 100)));
|
||||
}
|
||||
|
||||
private static void testPackets() {
|
||||
Packets.Dig dig = new Packets.Dig(Packets.Dig.START, 10, -60, 30, 2);
|
||||
Packets.Dig digBack = Packets.Dig.read(new Buf(dig.write().toByteArray()));
|
||||
eq("the action survives", Integer.valueOf(Packets.Dig.START),
|
||||
Integer.valueOf(digBack.action));
|
||||
eq("the place survives", Integer.valueOf(10), Integer.valueOf(digBack.x));
|
||||
eq("the face survives", Integer.valueOf(2), Integer.valueOf(digBack.face));
|
||||
yes("a start is a start", digBack.start());
|
||||
|
||||
Packets.BreakProgress progress = new Packets.BreakProgress(1, 2, 3, 7);
|
||||
Packets.BreakProgress progressBack =
|
||||
Packets.BreakProgress.read(new Buf(progress.write().toByteArray()));
|
||||
eq("the stage survives", Integer.valueOf(7), Integer.valueOf(progressBack.stage));
|
||||
eq("the place survives", Integer.valueOf(3), Integer.valueOf(progressBack.z));
|
||||
|
||||
Packets.CraftUpdate craft = new Packets.CraftUpdate(ItemRegistry.HATCHET, 1, 12, "");
|
||||
Packets.CraftUpdate craftBack =
|
||||
Packets.CraftUpdate.read(new Buf(craft.write().toByteArray()));
|
||||
eq("the item survives", Integer.valueOf(ItemRegistry.HATCHET),
|
||||
Integer.valueOf(craftBack.item));
|
||||
eq("the seconds survive", Integer.valueOf(12), Integer.valueOf(craftBack.secondsLeft));
|
||||
yes("an empty reason means fine", craftBack.ok());
|
||||
|
||||
Packets.CraftUpdate refused = new Packets.CraftUpdate(0, 0, 0, "no scrap");
|
||||
Packets.CraftUpdate refusedBack =
|
||||
Packets.CraftUpdate.read(new Buf(refused.write().toByteArray()));
|
||||
yes("a reason means no", !refusedBack.ok());
|
||||
eq("the reason survives", "no scrap", refusedBack.reason);
|
||||
|
||||
Packets.ResearchUpdate research =
|
||||
new Packets.ResearchUpdate(ItemRegistry.PICKAXE, 10, "");
|
||||
Packets.ResearchUpdate researchBack =
|
||||
Packets.ResearchUpdate.read(new Buf(research.write().toByteArray()));
|
||||
eq("the researched item survives", Integer.valueOf(ItemRegistry.PICKAXE),
|
||||
Integer.valueOf(researchBack.item));
|
||||
yes("a research that works has no reason", researchBack.ok());
|
||||
|
||||
Packets.TechTreeUnlock unlock = new Packets.TechTreeUnlock(ItemRegistry.HATCHET);
|
||||
Packets.TechTreeUnlock unlockBack =
|
||||
Packets.TechTreeUnlock.read(new Buf(unlock.write().toByteArray()));
|
||||
eq("the node survives", Integer.valueOf(ItemRegistry.HATCHET),
|
||||
Integer.valueOf(unlockBack.item));
|
||||
|
||||
Packets.KnownRecipes known = new Packets.KnownRecipes(new int[]{1, 2, 3});
|
||||
Packets.KnownRecipes knownBack =
|
||||
Packets.KnownRecipes.read(new Buf(known.write().toByteArray()));
|
||||
eq("the recipes survive", Integer.valueOf(3),
|
||||
Integer.valueOf(knownBack.items.length));
|
||||
eq("the last recipe survives", Integer.valueOf(3),
|
||||
Integer.valueOf(knownBack.items[2]));
|
||||
|
||||
Packets.TechTreeState state = new Packets.TechTreeState(new int[]{18, 16});
|
||||
Packets.TechTreeState stateBack =
|
||||
Packets.TechTreeState.read(new Buf(state.write().toByteArray()));
|
||||
eq("the opened nodes survive", Integer.valueOf(2),
|
||||
Integer.valueOf(stateBack.items.length));
|
||||
|
||||
Packets.Slot[] slots = new Packets.Slot[]{
|
||||
new Packets.Slot(ItemRegistry.SCRAP, 4, -1),
|
||||
Packets.Slot.of(null)};
|
||||
Packets.ContainerOpen open = new Packets.ContainerOpen(9, "Food", slots);
|
||||
Packets.ContainerOpen openBack =
|
||||
Packets.ContainerOpen.read(new Buf(open.write().toByteArray()));
|
||||
eq("the title survives", "Food", openBack.title);
|
||||
eq("the slots survive", Integer.valueOf(2), Integer.valueOf(openBack.slots.length));
|
||||
eq("what is in the slot survives", Integer.valueOf(ItemRegistry.SCRAP),
|
||||
Integer.valueOf(openBack.slots[0].item));
|
||||
eq("an empty slot is nothing", Integer.valueOf(ItemRegistry.NOTHING),
|
||||
Integer.valueOf(openBack.slots[1].item));
|
||||
|
||||
Packets.ContainerTake take = new Packets.ContainerTake(9, 0);
|
||||
Packets.ContainerTake takeBack =
|
||||
Packets.ContainerTake.read(new Buf(take.write().toByteArray()));
|
||||
eq("the container survives", Integer.valueOf(9), Integer.valueOf(takeBack.id));
|
||||
eq("the slot survives", Integer.valueOf(0), Integer.valueOf(takeBack.slot));
|
||||
|
||||
Packets.LearnBlueprint learn = new Packets.LearnBlueprint(ItemRegistry.PICKAXE);
|
||||
Packets.LearnBlueprint learnBack =
|
||||
Packets.LearnBlueprint.read(new Buf(learn.write().toByteArray()));
|
||||
eq("the blueprint survives", Integer.valueOf(ItemRegistry.PICKAXE),
|
||||
Integer.valueOf(learnBack.item));
|
||||
}
|
||||
|
||||
private static void run(String name, Runnable body) {
|
||||
checks++;
|
||||
int before = failed;
|
||||
try {
|
||||
body.run();
|
||||
} catch (Throwable t) {
|
||||
failed++;
|
||||
failures.add(name + ": threw " + t);
|
||||
t.printStackTrace();
|
||||
return;
|
||||
}
|
||||
if (failed == before) {
|
||||
System.out.println(" ok " + name);
|
||||
} else {
|
||||
System.out.println(" FAIL " + name);
|
||||
}
|
||||
}
|
||||
|
||||
private static void eq(Object what, Object expected, Object actual) {
|
||||
if (expected == null ? actual != null : !expected.equals(actual)) {
|
||||
failed++;
|
||||
failures.add(what + ": expected " + expected + " but got " + actual);
|
||||
}
|
||||
}
|
||||
|
||||
private static void yes(String what, boolean condition) {
|
||||
if (!condition) {
|
||||
failed++;
|
||||
failures.add(what);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,7 +545,12 @@ public final class ProtocolTest {
|
||||
Packets.WORLD_JOIN, Packets.CHUNK_DATA, Packets.BLOCK_CHANGE,
|
||||
Packets.PLAYER_MOVE, Packets.ENTITY_MOVE, Packets.PING, Packets.PONG,
|
||||
Packets.ENTITY_SPAWN, Packets.ENTITY_REMOVE, Packets.LAUNCHER_AUTH,
|
||||
Packets.SET_GAME_MODE,
|
||||
Packets.SET_GAME_MODE, Packets.INVENTORY, Packets.INVENTORY_SLOT,
|
||||
Packets.DIG, Packets.BREAK_PROGRESS, Packets.CRAFT_START, Packets.CRAFT_UPDATE,
|
||||
Packets.RESEARCH_START, Packets.RESEARCH_UPDATE, Packets.TECH_TREE_UNLOCK,
|
||||
Packets.KNOWN_RECIPES, Packets.TECH_TREE_STATE,
|
||||
Packets.CONTAINER_OPEN, Packets.CONTAINER_TAKE,
|
||||
Packets.LEARN_BLUEPRINT,
|
||||
Packets.DISCONNECT,
|
||||
};
|
||||
for (int i = 0; i < ids.length; i++) {
|
||||
@@ -565,9 +570,9 @@ public final class ProtocolTest {
|
||||
Integer.valueOf(rock.damage(ItemType.HEAD)));
|
||||
eq("and the torso for ten", Integer.valueOf(10),
|
||||
Integer.valueOf(rock.damage(ItemType.TORSO)));
|
||||
eq("the rock takes ten off a tree", Integer.valueOf(10),
|
||||
eq("the rock takes fifty off a tree", Integer.valueOf(50),
|
||||
Integer.valueOf(rock.gather(ResourceClass.TREE).damage));
|
||||
eq("and five off an ore", Integer.valueOf(5),
|
||||
eq("and thirty five off an ore", Integer.valueOf(35),
|
||||
Integer.valueOf(rock.gather(ResourceClass.METAL).damage));
|
||||
eq("the rock is known from the start", Boolean.TRUE,
|
||||
Boolean.valueOf(rock.knownByDefault));
|
||||
@@ -579,12 +584,12 @@ public final class ProtocolTest {
|
||||
|
||||
ItemType hatchet = ItemRegistry.require(ItemRegistry.STONE_HATCHET);
|
||||
eq("the stone hatchet is an axe", ToolClass.AXE, hatchet.tool);
|
||||
eq("it takes twenty off a tree", Integer.valueOf(20),
|
||||
eq("it takes eighty off a tree", Integer.valueOf(80),
|
||||
Integer.valueOf(hatchet.gather(ResourceClass.TREE).damage));
|
||||
|
||||
ItemType pickaxe = ItemRegistry.require(ItemRegistry.STONE_PICKAXE);
|
||||
eq("the stone pickaxe is a pickaxe", ToolClass.PICKAXE, pickaxe.tool);
|
||||
eq("it takes sixteen off an ore", Integer.valueOf(16),
|
||||
eq("it takes eighty off an ore", Integer.valueOf(80),
|
||||
Integer.valueOf(pickaxe.gather(ResourceClass.METAL).damage));
|
||||
yes("and it does not cut trees", pickaxe.gather(ResourceClass.TREE) == null);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user