diff --git a/PLAN.md b/PLAN.md index 6689205..3ae4360 100644 --- a/PLAN.md +++ b/PLAN.md @@ -759,23 +759,65 @@ ROLE_ELDER / ROLE_CREATOR`). EntityPlayerSP` (в `src-overlay`), рядом `RsxMovementInput extends MovementInputFromOptions` и `RsxPlayerTuning` с числами. -| что | ванильно | у нас | -|---|---|---| -| скорость подкрадывания | ~1.30 блока/с (множитель 0.3) | **1.5 блока/с** (множитель 0.34746) | -| высота прыжка | 1.25 блока (импульс 0.42) | **1.35 блока** (импульс 0.43713) | +| что | ванильно | у нас | как считается | +|---|---|---|---| +| скорость подкрадывания | ~1.30 блока/с (множитель 0.3) | **1.5 блока/с** | множитель 0.34746; ванильный 0.3 отменяется, ставится наш (×1.158) | +| высота прыжка с места | 1.25 блока (импульс 0.42) | **1.5 блока** (0.46341) | высота в конфиге класса игрока, импульс обратным счётом по физике | +| высота прыжка в движении | 1.25 блока | **1.25 блока** (ванильная) | ходьба и бег не меняются, спринт-толчок ванильный | +| высота при подкрадывании | 1.65 блока | **1.45 блока** | проходит в щель 1.5 блока | +| высота глаз в подкрадывании | 1.54 | **1.37** | иначе глаза выше головы | -- Скорость прыжка считается по высоте: `v = 0.42 · √(h / 1.25)`. -- Подкрадывание: ванильный множитель 0.3 отменяется и ставится наш. -- **Правило пользователя:** если задать значение меньше, оно не принимается — - подкрадывание остаётся 1.5 блока/с, прыжок 1.5 блока. Значения по умолчанию - (1.5 и 1.35) через это правило не проходят. -- Переопределяется из командной строки: `-Drsx.sneakSpeed=1.6 -Drsx.jumpHeight=1.4`. +- Скорость прыжка считается обратным счётом по физике ваниллы (гравитация 0.08, + сопротивление 0.98): формула `v = 0.42·√(h/1.25)` давала 1.48 вместо 1.5. +- Значения живут в `RsxPlayerTuning` — это и есть «конфиг игрока»: переписали код + игрока — поменяли числа. Переопределение из командной строки: + `-Drsx.sneakSpeed=`, `-Drsx.jumpHeight=`, `-Drsx.jumpHeightStanding=`, + `-Drsx.crouchHeight=`. - Мобы прыгают как в ванилле: переопределение живёт в `RsxPlayer`, а не в `EntityLivingBase`. -- Патчи в ванильное дерево — три строки (`PlayerControllerMP` создаёт - `RsxPlayer`, `Minecraft` создаёт `RsxMovementInput`), вся логика — в нашем коде. +- Патчи в ванильное дерево — три строки: `PlayerControllerMP` создаёт `RsxPlayer`, + `Minecraft` создаёт `RsxMovementInput`, `EntityPlayer.updateSize` берёт высоту + подкрадывания из нашего класса. Вся логика — в нашем коде. -### 2.9 Декомпил ремейка лежит на диске +### 2.9 Броня: семь мест и три зоны урона + +**Семь мест**, как в базе ремейка (без пояса): + +| слот | слои | предметы ремейка | +|---|---|---| +| голова | 1 | `helmet` (13) | +| лицо | 1 | `hat` — повязка (1) | +| грудь | 2 | `plate` (одежда, 9) + `jacket` (броня, 6) | +| ноги | 2 | `pants` (одежда, 6) + `kilt` (броня, 2) | +| руки | 1 | `gloves` (5) | +| стопы | 1 | `boots` (3) | +| полный костюм | 1 | `suit` (1) — хазмат, заменяет остальные | + +- Данные 46 предметов одежды выгружены в `items.csv` (слот, слой, какие части + тела закрывает, сколько снимает из каждого вида вреда) и заведены в реестр. +- **Три зоны урона**: голова (верхние 0.4 высоты) **×2** (так в Rust), тело **×1**, + ноги (нижние 0.4) **×0.75** (наше правило; в Rust не документировано). +- Одежда снимает вред **только там, где закрывает**: маска не спасает от удара + в грудь. +- Удар приходит пакетом `Attack` (цель, точка попадания, рука) — в ванильном + `CPacketUseEntity` точка есть, в нашем протоколе добавили. + +### 2.10 AABB: редактор хитбоксов + +- **Данные** (`rsx-protocol`): `Hitbox` (имя, зона, min/max, поворот) и наборы по + моделям; пакеты `Hitboxes` (определения), `HitboxInstances` (где стоят модели), + `HitboxesReload` (клиент просит перечитать файл). +- **Сервер**: `HitboxRegistry` читает JSON (по умолчанию `world/hitboxes.json`, + можно указать `--hitboxes`), перечитывает по запросу и шлёт наборы игрокам. + Сломанный файл не стирает рабочие коробки, а объясняет причину. +- **Клиент**: `RsxHitboxDebug` рисует коробки через `RenderGlobal.drawBoundingBox` + с подписями `DebugRenderer`, красит зоны (голова красная, тело жёлтое, ноги + синие). Команды: `/rsx hitboxes on|off|reload|list|show NAME`. +- **API**: `rsx-plugin-api` (новый модуль) — интерфейс `Hitboxes`: плагин + регистрирует свои коробки. +- Область: наши структуры (узлы, мусорка, постройки) и игроки с зонами. + +### 2.11 Декомпил ремейка лежит на диске `G:\src-decoded` (5207 файлов, строки расшифрованы), также `G:\src`, `G:\builds\v31\src{,-decoded}` и `G:\decompiled-rustex`. Это **исходники клиента @@ -1013,12 +1055,15 @@ rsx-client\scripts\run-game.ps1 # клиент ремейка (`ItemData`), `NodeType`, `TechTree`, 218 предметов в реестре. Не сделано: **клиентский рендер своих предметов** (хотбар и рука) и иконки из атласа. 2. **Шаг B** — сделано: `Dig`/`BreakProgress` в протоколе, проверка досягаемости - на сервере, тег `admin` в типах предметов. Не сделано: узлы в мире (шаг C), - трещины на клиенте, 4 клиентских патча. -3. **Шаг C** — сделано: `ResourceNode` (HP, запас, метка), `JunkPile` (бутылки, + на сервере, тег `admin` в типах предметов, пакет `Attack` с точкой попадания, + клиент шлёт удар (патч `PlayerControllerMP`). Не сделано: узлы в мире (шаг C), + трещины на клиенте, серверный боевой код (жизнь, смерть, респавн). +3. **Шаг C** — сделано: `ResourceNode` (HP, запас, метка), `JunkPile` (бочки, ящик с едой, таймер исчезновения), `RoadNetwork` + дороги в генераторе - (сетка и кольцо, ровная по ширине). Не сделано: мусорка в мире (спавн и - респавн у дороги), станции крафта (верстак в мире), постройка по сокетам. + (сетка и кольцо, ровная по ширине), `Knowledge`, `Crafter`, `ResearchTable`, + семь слотов брони с данными ремейка, три зоны урона, редактор хитбоксов. + Не сделано: мусорка в мире (спавн и респавн у дороги), станции крафта (верстак + в мире), постройка по сокетам, клиентский рендер брони. 4. **Шаг D** — конфиг, мир 4000×4000 один раз, барьер. 5. **Шаг E** — транспорт на NIO. 6. **Шаг F** — DistantView. diff --git a/game-fork/patches/decompiler-fixes.txt b/game-fork/patches/decompiler-fixes.txt index 11ce877..3425dc9 100644 --- a/game-fork/patches/decompiler-fixes.txt +++ b/game-fork/patches/decompiler-fixes.txt @@ -1277,3 +1277,16 @@ import org.lwjgl.opengl.ContextCapabilities; f1 = net.rustnotmc.client.RsxPlayerTuning.crouchHeight(); } else { +# A hit has to say where it landed, because the head is worth more than the +# body. The vanilla packet does not carry that, so the server gets one of ours. +=== FILE net/minecraft/client/multiplayer/PlayerControllerMP.java +--- BEFORE + public void attackEntity(EntityPlayer entityplayer, Entity entity) { + this.syncCurrentPlayItem(); + this.connection.sendPacket(new CPacketUseEntity(entity)); +--- AFTER + public void attackEntity(EntityPlayer entityplayer, Entity entity) { + this.syncCurrentPlayItem(); + this.connection.sendPacket(new CPacketUseEntity(entity)); + net.rustnotmc.client.net.RsxNetworkManager.reportAttack(this.mc, entity); + diff --git a/game-fork/src-overlay/net/rustnotmc/client/net/RsxNetworkManager.java b/game-fork/src-overlay/net/rustnotmc/client/net/RsxNetworkManager.java index 9e2a21c..67601d2 100644 --- a/game-fork/src-overlay/net/rustnotmc/client/net/RsxNetworkManager.java +++ b/game-fork/src-overlay/net/rustnotmc/client/net/RsxNetworkManager.java @@ -265,6 +265,26 @@ public final class RsxNetworkManager extends NetworkManager { } } + /** + * Tells the server where a hit landed. + * + * The server counts the damage, and it needs to know where the hit + * landed: a hit on the head is worth twice a hit on the body. + */ + public static void reportAttack(Minecraft mc, net.minecraft.entity.Entity target) { + RsxNetworkManager manager = active(); + if (manager == null || mc == null || target == null) { + return; + } + if (mc.objectMouseOver == null + || mc.objectMouseOver.typeOfHit != net.minecraft.util.math.RayTraceResult.Type.ENTITY) { + return; + } + net.minecraft.util.math.Vec3d hit = mc.objectMouseOver.hitVec; + manager.send(Packets.ATTACK, new Packets.Attack(target.getEntityId(), + (float) hit.x, (float) hit.y, (float) hit.z, Packets.Attack.HAND_MAIN)); + } + /** * Asks the server to read its box file again. * diff --git a/rsx-protocol/src/main/java/net/rustnotmc/protocol/Hitbox.java b/rsx-protocol/src/main/java/net/rustnotmc/protocol/Hitbox.java index 4811794..f9ed182 100644 --- a/rsx-protocol/src/main/java/net/rustnotmc/protocol/Hitbox.java +++ b/rsx-protocol/src/main/java/net/rustnotmc/protocol/Hitbox.java @@ -26,6 +26,15 @@ public final class Hitbox { /** The legs of a player. */ public static final String PART_LEGS = "legs"; + /** The head of a player is covered by the piece. */ + public static final int ZONE_HEAD = 1; + + /** The torso and the arms of a player are covered by the piece. */ + public static final int ZONE_BODY = 2; + + /** The legs of a player are covered by the piece. */ + public static final int ZONE_LEGS = 4; + public final String name; public final String part; public final float minX; diff --git a/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemRegistry.java b/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemRegistry.java index 4e123af..2fd835f 100644 --- a/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemRegistry.java +++ b/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemRegistry.java @@ -132,6 +132,36 @@ public final class ItemRegistry { public static final int SNAP_TRAP = 105; public static final int WOODEN_FLOOR_SPIKES = 106; public static final int TORCH = 107; + public static final int METALFACEMASK = 108; + public static final int BURLAPBOOTS = 109; + public static final int WOODPANTS = 110; + public static final int BUCKETHELMET = 111; + public static final int BURLAPHELMET = 112; + public static final int HEAVYHELMET = 113; + public static final int BOOTS = 114; + public static final int SNOWJACKET = 115; + public static final int HAT = 116; + public static final int BALACLAVA = 117; + public static final int JACKET = 118; + public static final int BONEHELMET = 119; + public static final int WOODHELMET = 120; + public static final int HOODIE = 121; + public static final int WOODCHEST = 122; + public static final int METALCHEST = 123; + public static final int RIOTHELMET = 124; + public static final int BURLAPCHEST = 125; + public static final int BONEARMOR = 126; + public static final int HEAVYPANTS = 127; + public static final int SHIRT = 128; + public static final int HIDEHALTERNECK = 129; + public static final int HAZMATSUIT = 130; + public static final int HAGI = 131; + public static final int WOLFHEADDRESS = 132; + public static final int COFFECANHELMET = 133; + public static final int BURLAPPANTS = 134; + public static final int BURLAPGLOVES = 135; + public static final int LONGTSHIRT = 136; + public static final int HEAVYCHEST = 137; private static final Map TYPES = new LinkedHashMap(); @@ -194,23 +224,162 @@ public final class ItemRegistry { define(ItemType.of(MUSHROOM, "Mushroom").rid("mushroom")); // The rubbish of a junk pile. - define(ItemType.of(BANDANA_MASK, "Bandana Mask").rid("maskbandana")); - define(ItemType.of(TANK_TOP, "Tank Top").rid("tanktop")); - define(ItemType.of(SHORTS, "Shorts").rid("shorts")); - define(ItemType.of(T_SHIRT, "T-Shirt").rid("tshirt")); - define(ItemType.of(PANTS, "Pants").rid("pants")); - define(ItemType.of(LEATHER_GLOVES, "Leather Gloves").rid("leathergloves")); - define(ItemType.of(BASEBALL_CAP, "Baseball Cap").rid("baseballcap")); - define(ItemType.of(BOONIE_HAT, "Boonie Hat").rid("booniehat")); - define(ItemType.of(HIDE_PANTS, "Hide Pants").rid("hidepants")); - define(ItemType.of(HIDE_BOOTS, "Hide Boots").rid("hideboots")); - define(ItemType.of(HIDE_SKIRT, "Hide Skirt").rid("hideskirt")); - define(ItemType.of(HIDE_CHEST, "Hide Chest").rid("hidechest")); - define(ItemType.of(HIDE_PONCHO, "Hide Poncho").rid("hideponcho")); - define(ItemType.of(ROADSIGN_JACKET, "Road Sign Jacket").rid("roadsignjacket")); - define(ItemType.of(ROADSIGN_KILT, "Road Sign Kilt").rid("roadsignkilt")); - define(ItemType.of(ROADSIGN_GLOVES, "Road Sign Gloves").rid("roadsigngloves")); + define(ItemType.of(BANDANA_MASK, "Maskbandana").rid("maskbandana") + .armor(2, 0, new int[]{5, 10, 3, 3, 10, 0}, 1)); + define(ItemType.of(TANK_TOP, "Tanktop").rid("tanktop") + .armor(3, 0, new int[]{10, 10, 3, 2, 2, 0}, 2)); + define(ItemType.of(SHORTS, "Shorts").rid("shorts") + .armor(4, 0, new int[]{10, 10, 3, 2, 7, 0}, 6)); + define(ItemType.of(T_SHIRT, "Tshirt").rid("tshirt") + .armor(3, 0, new int[]{15, 15, 5, 3, 6, 0}, 2)); + define(ItemType.of(PANTS, "Pants").rid("pants") + .armor(4, 0, new int[]{15, 15, 3, 5, 8, 0}, 6)); + define(ItemType.of(LEATHER_GLOVES, "Leathergloves").rid("leathergloves") + .armor(5, 0, new int[]{5, 5, 2, 4, 5, 0}, 2)); + define(ItemType.of(BASEBALL_CAP, "Baseballcap").rid("baseballcap") + .armor(1, 0, new int[]{10, 10, 3, 1, 7, 0}, 1)); + define(ItemType.of(BOONIE_HAT, "Booniehat").rid("booniehat") + .armor(1, 0, new int[]{15, 15, 3, 2, 7, 0}, 1)); + define(ItemType.of(HIDE_PANTS, "Hidepants").rid("hidepants") + .armor(4, 0, new int[]{10, 10, 8, 2, 4, 0}, 6)); + define(ItemType.of(HIDE_BOOTS, "Hideboots").rid("hideboots") + .armor(6, 0, new int[]{5, 5, 3, 2, 5, 0}, 4)); + define(ItemType.of(HIDE_SKIRT, "Hideskirt").rid("hideskirt") + .armor(4, 0, new int[]{10, 10, 3, 2, 7, 0}, 6)); + define(ItemType.of(HIDE_CHEST, "Hidechest").rid("hidechest") + .armor(3, 0, new int[]{15, 15, 8, 3, 5, 0}, 2)); + define(ItemType.of(HIDE_PONCHO, "Hideponcho").rid("hideponcho") + .armor(3, 1, new int[]{10, 40, 5, 8, 8, 5}, 2)); + define(ItemType.of(ROADSIGN_JACKET, "Roadsignjacket").rid("roadsignjacket") + .armor(3, 1, new int[]{20, 25, 10, 0, -8, 0}, 2)); + define(ItemType.of(ROADSIGN_KILT, "Roadsignkilt").rid("roadsignkilt") + .armor(4, 1, new int[]{20, 25, 10, 0, -8, 0}, 6)); + define(ItemType.of(ROADSIGN_GLOVES, "Roadsigngloves").rid("roadsigngloves") + .armor(5, 0, new int[]{10, 25, 10, 0, -8, 0}, 2)); + + // The clothes of the original game: seven places, and the chest and + // the legs have two layers. What each piece takes away is in the + // table of the remake (items.csv). + define(ItemType.of(METALFACEMASK, "Metalfacemask") + .rid("metalfacemask") + .armor(1, 0, new int[]{50, 70, 8, 0, -4, 8}, 1)); + + define(ItemType.of(BURLAPBOOTS, "Burlapboots") + .rid("burlapboots") + .armor(6, 0, new int[]{5, 5, 2, 2, 3, 0}, 4)); + + define(ItemType.of(WOODPANTS, "Woodpants") + .rid("woodpants") + .armor(4, 1, new int[]{10, 40, 5, 5, 0, 5}, 6)); + + define(ItemType.of(BUCKETHELMET, "Buckethelmet") + .rid("buckethelmet") + .armor(1, 0, new int[]{20, 50, 8, 4, 6, 8}, 1)); + + define(ItemType.of(BURLAPHELMET, "Burlaphelmet") + .rid("burlaphelmet") + .armor(1, 0, new int[]{15, 15, 3, 2, 7, 0}, 1)); + + define(ItemType.of(HEAVYHELMET, "Heavyhelmet") + .rid("heavyhelmet") + .armor(1, 0, new int[]{90, 80, 13, 7, -17, 17}, 1)); + + define(ItemType.of(BOOTS, "Boots") + .rid("boots") + .armor(6, 0, new int[]{10, 10, 3, 3, 8, 0}, 4)); + + define(ItemType.of(SNOWJACKET, "Snowjacket") + .rid("snowjacket") + .armor(3, 1, new int[]{20, 30, 5, 20, 17, 0}, 2)); + + define(ItemType.of(HAT, "Hat") + .rid("hat") + .armor(1, 0, new int[]{10, 10, 3, 1, 7, 0}, 1)); + + define(ItemType.of(BALACLAVA, "Balaclava") + .rid("balaclava") + .armor(1, 0, new int[]{15, 15, 3, 3, 13, 3}, 1)); + + define(ItemType.of(JACKET, "Jacket") + .rid("jacket") + .armor(3, 1, new int[]{15, 20, 7, 5, 10, 0}, 2)); + + define(ItemType.of(BONEHELMET, "Bonehelmet") + .rid("bonehelmet") + .armor(1, 0, new int[]{25, 40, 13, 4, 0, 7}, 1)); + + define(ItemType.of(WOODHELMET, "Woodhelmet") + .rid("woodhelmet") + .armor(1, 0, new int[]{15, 25, 3, 2, 7, 0}, 1)); + + define(ItemType.of(HOODIE, "Hoodie") + .rid("hoodie") + .armor(3, 0, new int[]{20, 15, 6, 5, 8, 0}, 2)); + + define(ItemType.of(WOODCHEST, "Woodchest") + .rid("woodchest") + .armor(3, 1, new int[]{10, 40, 5, 5, 0, 5}, 2)); + + define(ItemType.of(METALCHEST, "Metalchest") + .rid("metalchest") + .armor(3, 1, new int[]{25, 20, 3, 0, -8, 0}, 2)); + + define(ItemType.of(RIOTHELMET, "Riothelmet") + .rid("riothelmet") + .armor(1, 0, new int[]{25, 80, 13, 5, 6, 8}, 1)); + + define(ItemType.of(BURLAPCHEST, "Burlapchest") + .rid("burlapchest") + .armor(3, 0, new int[]{10, 10, 3, 2, 7, 0}, 2)); + + define(ItemType.of(BONEARMOR, "Bonearmor") + .rid("bonearmor") + .armor(5, 0, new int[]{25, 40, 13, 4, 0, 7}, 6)); + + define(ItemType.of(HEAVYPANTS, "Heavypants") + .rid("heavypants") + .armor(4, 0, new int[]{75, 70, 12, 7, -17, 17}, 6)); + + define(ItemType.of(SHIRT, "Shirt") + .rid("shirt") + .armor(3, 0, new int[]{15, 15, 5, 3, 6, 0}, 2)); + + define(ItemType.of(HIDEHALTERNECK, "Hidehalterneck") + .rid("hidehalterneck") + .armor(3, 0, new int[]{10, 10, 3, 2, 7, 0}, 2)); + + define(ItemType.of(HAZMATSUIT, "Hazmatsuit") + .rid("hazmatsuit") + .armor(7, 0, new int[]{30, 30, 8, 50, 8, 5}, 7)); + + define(ItemType.of(HAGI, "Hagi") + .rid("hagi") + .armor(3, 0, new int[]{0, 0, 0, 0, 0, 0}, 2)); + + define(ItemType.of(WOLFHEADDRESS, "Wolfheaddress") + .rid("wolfheaddress") + .armor(1, 0, new int[]{30, 60, 10, 4, 6, 13}, 1)); + + define(ItemType.of(COFFECANHELMET, "Coffecanhelmet") + .rid("coffecanhelmet") + .armor(1, 0, new int[]{35, 50, 8, 5, 0, 8}, 1)); + + define(ItemType.of(BURLAPPANTS, "Burlappants") + .rid("burlappants") + .armor(4, 0, new int[]{10, 10, 3, 2, 7, 0}, 6)); + + define(ItemType.of(BURLAPGLOVES, "Burlapgloves") + .rid("burlapgloves") + .armor(5, 0, new int[]{0, 5, 2, 3, 4, 0}, 2)); + + define(ItemType.of(LONGTSHIRT, "Longtshirt") + .rid("longtshirt") + .armor(3, 0, new int[]{15, 15, 6, 5, 10, 0}, 2)); + + define(ItemType.of(HEAVYCHEST, "Heavychest") + .rid("heavychest") + .armor(5, 0, new int[]{75, 70, 12, 7, -17, 17}, 2)); // The tools. The numbers of the gather and the damage are from the // table of the remake; what a tool is for is ours. define(ItemType.of(ROCK, "Rock") diff --git a/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemType.java b/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemType.java index 6953a5a..65843db 100644 --- a/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemType.java +++ b/rsx-protocol/src/main/java/net/rustnotmc/protocol/ItemType.java @@ -40,6 +40,28 @@ public final class ItemType { public static final int ARMS = 2; public static final int LEGS = 3; + /** The kinds of harm a piece of clothing can take away. */ + public static final int HARM_PROJECTILE = 0; + public static final int HARM_MELEE = 1; + public static final int HARM_BITE = 2; + public static final int HARM_RADIATION = 3; + public static final int HARM_COLD = 4; + public static final int HARM_EXPLOSION = 5; + public static final int HARM_COUNT = 6; + + /** The slots a piece of clothing can be worn in. */ + public static final int ARMOR_NONE = 0; + public static final int ARMOR_HEAD = 1; + public static final int ARMOR_FACE = 2; + public static final int ARMOR_CHEST = 3; + public static final int ARMOR_LEGS = 4; + public static final int ARMOR_HANDS = 5; + public static final int ARMOR_FEET = 6; + public static final int ARMOR_FULL_BODY = 7; + + /** How many slots of clothing a player has. */ + public static final int ARMOR_SLOTS = 7; + /** The id of the item in the remake, or null when it has none. */ public final String rid; @@ -85,12 +107,28 @@ public final class ItemType { /** How to make one, or null when the item is not made but gathered. */ public final Recipe recipe; + /** + * The slot of clothing this goes in, or {@link #ARMOR_NONE}. + * + * The chest and the legs have two layers: the clothes under and the + * armour over. The layer says which of the two it is. + */ + public final int armorSlot; + public final int armorLayer; + + /** How much of each kind of harm the piece takes away, in percent. */ + public final int[] protection; + + /** Which parts of a player the piece covers. */ + public final int coveredZones; + private final Gather[] gathers; public ItemType(String rid, int id, String name, ToolClass tool, int harvestLevel, int durability, int[] damage, int bench, boolean knownByDefault, boolean admin, int researchScrap, int techTreeBench, int techTreeScrap, - int techTreeParent, Recipe recipe, Gather[] gathers) { + int techTreeParent, Recipe recipe, Gather[] gathers, + int armorSlot, int armorLayer, int[] protection, int coveredZones) { if (damage == null || damage.length != 4) { throw new IllegalArgumentException("the damage needs four body parts"); } @@ -110,6 +148,10 @@ public final class ItemType { this.techTreeParent = techTreeParent; this.recipe = recipe; this.gathers = gathers == null ? new Gather[ResourceClass.values().length] : gathers; + this.armorSlot = armorSlot; + this.armorLayer = armorLayer; + this.protection = protection == null ? new int[HARM_COUNT] : protection; + this.coveredZones = coveredZones; } /** A starting point for defining an item. */ @@ -141,6 +183,10 @@ public final class ItemType { private int techTreeScrap; private int techTreeParent; private Recipe recipe; + private int armorSlot = ARMOR_NONE; + private int armorLayer; + private int[] protection; + private int coveredZones; private final Gather[] gathers = new Gather[ResourceClass.values().length]; private Builder(int id, String name) { @@ -254,11 +300,27 @@ public final class ItemType { return this; } + /** + * Says that this is a piece of clothing. + * + * The slot is one of the ARMOR_ constants, the layer says whether it + * goes under or over, the protection is how much of each kind of harm + * it takes away and the zones are the parts of a player it covers. + */ + public Builder armor(int slot, int layer, int[] protection, int coveredZones) { + this.armorSlot = slot; + this.armorLayer = layer; + this.protection = protection; + this.coveredZones = coveredZones; + return this; + } + public ItemType build() { return new ItemType(this.rid, this.id, this.name, this.tool, this.harvestLevel, this.durability, this.damage, this.bench, this.knownByDefault, this.admin, this.researchScrap, this.techTreeBench, this.techTreeScrap, - this.techTreeParent, this.recipe, this.gathers); + this.techTreeParent, this.recipe, this.gathers, this.armorSlot, + this.armorLayer, this.protection, this.coveredZones); } } diff --git a/rsx-protocol/src/main/java/net/rustnotmc/protocol/Packets.java b/rsx-protocol/src/main/java/net/rustnotmc/protocol/Packets.java index 4f31fc5..7788a8c 100644 --- a/rsx-protocol/src/main/java/net/rustnotmc/protocol/Packets.java +++ b/rsx-protocol/src/main/java/net/rustnotmc/protocol/Packets.java @@ -158,6 +158,9 @@ public final class Packets { /** The client asks the server to read its box file again. */ public static final int HITBOXES_RELOAD = 0x2C; + /** The client hits something. */ + public static final int ATTACK = 0x2D; + /** * One slot of the inventory and what is in it now. * @@ -931,19 +934,38 @@ public final class Packets { /** The slot the player is holding. */ public final int held; + /** + * The clothing the player wears: seven places, two layers each. + * + * The order is the head, the face, the chest, the legs, the hands, + * the feet and the whole body, and inside each place the clothes + * under come before the armour over. + */ + public final Slot[] armor; + public Inventory(Slot[] slots, int held) { + this(slots, held, new Slot[0]); + } + + public Inventory(Slot[] slots, int held, Slot[] armor) { this.slots = slots; this.held = held; + this.armor = armor == null ? new Slot[0] : armor; } public Buf write() { - Buf buf = new Buf(16 + this.slots.length * 12); + Buf buf = new Buf(16 + (this.slots.length + this.armor.length) * 12); buf.writeVarInt(this.held); buf.writeVarInt(this.slots.length); for (int i = 0; i < this.slots.length; i++) { Slot slot = this.slots[i] == null ? Slot.of(null) : this.slots[i]; slot.write(buf); } + buf.writeVarInt(this.armor.length); + for (int i = 0; i < this.armor.length; i++) { + Slot slot = this.armor[i] == null ? Slot.of(null) : this.armor[i]; + slot.write(buf); + } return buf; } @@ -957,7 +979,15 @@ public final class Packets { for (int i = 0; i < count; i++) { slots[i] = Slot.read(in); } - return new Inventory(slots, held); + int worn = in.readVarInt(); + if (worn < 0 || worn > 64) { + throw new ProtocolException("that much clothing is not real"); + } + Slot[] armor = new Slot[worn]; + for (int i = 0; i < worn; i++) { + armor[i] = Slot.read(in); + } + return new Inventory(slots, held, armor); } } @@ -1531,6 +1561,49 @@ public final class Packets { } } + /** + * The client hits something. + * + * The place of the hit matters: a hit on the head hurts twice as much as + * a hit on the body, and the clothing only takes a part of the harm away + * where it covers the body. + */ + public static final class Attack implements Packet { + + /** The hand that holds the weapon. */ + public static final int HAND_MAIN = 0; + public static final int HAND_OFF = 1; + + public final int target; + public final float x; + public final float y; + public final float z; + public final int hand; + + public Attack(int target, float x, float y, float z, int hand) { + this.target = target; + this.x = x; + this.y = y; + this.z = z; + this.hand = hand; + } + + public Buf write() { + Buf buf = new Buf(24); + buf.writeVarInt(this.target); + buf.writeFloat(this.x); + buf.writeFloat(this.y); + buf.writeFloat(this.z); + buf.writeVarInt(this.hand); + return buf; + } + + public static Attack read(Buf in) { + return new Attack(in.readVarInt(), in.readFloat(), in.readFloat(), + in.readFloat(), in.readVarInt()); + } + } + /** * Every packet id this build knows, and what it decodes into. * @@ -1574,6 +1647,7 @@ public final class Packets { map.put(Integer.valueOf(HITBOXES), "Hitboxes"); map.put(Integer.valueOf(HITBOX_INSTANCES), "HitboxInstances"); map.put(Integer.valueOf(HITBOXES_RELOAD), "HitboxesReload"); + map.put(Integer.valueOf(ATTACK), "Attack"); map.put(Integer.valueOf(DISCONNECT), "Disconnect"); return map; } diff --git a/rsx-protocol/src/main/resources/items/items.csv b/rsx-protocol/src/main/resources/items/items.csv index bb5faf8..ec8f1f0 100644 --- a/rsx-protocol/src/main/resources/items/items.csv +++ b/rsx-protocol/src/main/resources/items/items.csv @@ -1,219 +1,219 @@ -rid,name,category,material,nid,damage,range,cooldown,reach,durability,durability_max,wood,ore,skinning,ammo,ammo_type,weapon_id,gun,throw,model,icon,zoom_x,zoom_y,zoom_z,zoom_count,heal,fast_heal,calories,hydration,radiation,bleeding,consume_time,food_cooldown,eat_sound,armor_projectile,armor_melee,armor_bite,armor_cold,armor_explosion,armor_radiation,armor_speed_reduction,armor_slot -ironaxe,,tools,metalwood,2048,25,3,31,4,300,300,85,,1,,,,,1,,hatchet,1,4,1,17,,,,,,,,,,,,,,,,, -boneclub,Club,weapon,metalwood,3072,16,3,16,4,300,300,60,44,0.5,,,,,1,,boneclub,0,10,0,20,,,,,,,,,,,,,,,,, -largewoodbox,Wood Box,items,wood,516,,,,,300,300,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -blueberries,,medical,rubber,2562,,,,,,,,,,,,,,,,,,,,,0,10,30,20,0,0,5,18,,,,,,,,, -metalfacemask,Facemask,clothes,metalhollow,1542,,,,,800,800,,,,,,,,,,,,,,,,,,,,,,,,50,70,8,-4,8,0,0,hat -burlapboots,Shoes,clothes,cloth,1543,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,2,3,0,2,0,boots -woodpants,Armor Pants,clothes,wood,1544,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,0,5,5,0,kilt -hmlmg,,weapon,gun,3081,,,,200,2500,2500,,,,6,2,13,1,,hmlmg,hmlmg,-5.5,2.9,3.5,20,,,,,,,,,,,,,,,,, -hidepants,Pants,clothes,leather,1548,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,8,4,0,2,0,pants -cookedchicken,Chicken,medical,meat,2572,,,,,,,,,,,,,,,,,,,,,10,0,40,3,0,0,5,20,,,,,,,,, -homemadelandmine,Landmine,traps,metalmedium,4097,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -sulfur,,res,charcol,1039,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -mushroom,,medical,meat,2576,,,,,,,,,,,,,,,,,,,,,0,3,15,5,0,0,5,18,,,,,,,,, -metalblade,Blade,res,metalhollow,1043,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -beancangrenade,Grenade,weapon,canfull,3089,,,,,,,,,,,,,,,,beancangrenade,,,,,,,,,,,,,,,,,,,,, -pistolbullet,Bullet,ammo,metal,3592,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -cookedpork,Pork,medical,meat,2577,,,,,,,,,,,,,,,,,,,,,5,0,60,1,0,0,5,20,,,,,,,,, -cookeddeermeat,Deer Meat,medical,meat,2579,,,,,,,,,,,,,,,,,,,,,10,0,40,3,0,0,5,20,,,,,,,,, -mediumpresent,Present,tools,leather,2053,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -semiautomaticrifle,Rifle,weapon,gun,3095,,,,200,1300,1300,,,,6,2,8,1,,semiautomaticrifle,semiautomaticrifle,-4.99,1.1,1.8,15,,,,,,,,,,,,,,,,, -gunpowder,Powder,res,snow,1052,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hqm_ore,Quality Metal Ore,res,stone,1056,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -tanktop,Top,clothes,leather,1571,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,2,0,2,0,plate -customsmg,SMG,weapon,gun,3100,,,,200,800,800,,,,8,0,5,1,,customsmg,customsmg,-5.51,1.6,2,15,,,,,,,,,,,,,,,,, -12gaugebuckshot,Gauge Buckshot,ammo,leather,3584,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -rawhumanmeat,Human Meat,medical,,2589,,,,,,,,,,,,,,,,,,,,,0,-9,5,-3,0,0,5,18,,,,,,,,, -woodendoor,Door,building,wood,13,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -buckethelmet,Helmet,clothes,metalthinhollow,1579,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,20,50,8,6,8,4,0,helmet -lr300assaultrifle,Assault Rifle,weapon,gun,3104,,,,200,2500,2500,,,,30,2,10,1,,lr300assaultrifle,lr300assaultrifle,-5.33,0.55,5,15,,,,,,,,,,,,,,,,, -baseballcap,Cap,clothes,cloth,1536,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,1,0,helmet -targetingcomputer,Computer,res,smalldevice,1025,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -waterpipeshotgun,Shotgun,weapon,gun,3078,,,,200,200,200,,,,1,8,15,1,,waterpipeshotgun,waterpipeshotgun,-3.79,2.65,3,15,,,,,,,,,,,,,,,,, -burlaphelmet,Headwrap,clothes,cloth,1541,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,7,0,2,0,hat -rawchickenbreast,Chicken Breast,medical,meat,2567,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,, -emptytunacan,Tuna Can,res,canempty,1035,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -boneknife,Knife,weapon,metalwood,3083,16,3,16,4,250,250,,,1,,,,,1,,boneknife,0,7,0,20,,,,,,,,,,,,,,,,, -rawwolfmeat,Wolf Meat,medical,,2571,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,, -heavyhelmet,Plate Helmet,clothes,metalhollowlarge,1547,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,90,80,13,-17,17,7,20,hat -mp5a4,,weapon,gun,3086,,,,200,1500,1500,,,,8,0,7,1,,mp5a4,mp5a4,-5.89,2.05,5.5,15,,,,,,,,,,,,,,,,, -boots,,clothes,leather,1551,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,8,0,3,0,boots -stonepickaxe,Pickaxe,tools,metalwood,2064,17,3,32,4,160,160,,80,0.71,,,,,1,,stonepickaxe,2,4,1,17,,,,,,,,,,,,,,,,, -thompson,,weapon,gun,3087,,,,200,800,800,,,,7,0,6,1,,thompson,thompson,-3.878,1.6,1.9,15,,,,,,,,,,,,,,,,, -woodenladder,Ladder,building,woodmed,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -key,Key,tools,metal,2068,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -wolfskull,Skull,res,bone,1048,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -salvagedhammer,Hammer,tools,metalmediumrattley,2051,30,3,19,4,400,400,40,59,0.45,,,,,1,,salvagedhammer,-3,5,0,20,,,,,,,,,,,,,,,,, -snowjacket,Jacket,clothes,cloth,1558,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,20,30,5,17,0,20,0,plate -binoculars,,tools,gun,2055,,,,,,,,,,,,,,,,binoculars,,,,,,,,,,,,,,,,,,,,, -huntingbow,Bow,weapon,woodlight,3094,,,,200,100,100,,,,,6,19,1,,huntingbow,huntingbow,-5.25,7.8,6,15,,,,,,,,,,,,,,,,, -woodenarrow,Arrow,ammo,woodlight,3589,,,,,,,,,,,,,,,,woodenarrow,,,,,,,,,,,,,,,,,,,,, -handmadeshell,Shell,ammo,leather,3591,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -largemedkit,Medkit,medical,plasticmedium,2582,,,,,,,,,,,,,,,,largemedkit,,,,,100,10,0,0,0,-100,0,20,,,,,,,,, -tshirt,,clothes,cloth,1573,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,5,6,0,3,0,plate -crudeoil,Oil,res,leather,1062,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -charcoal,,res,charcol,1064,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hv556rifleammo,5.56 Rifle Ammo,ammo,metal,3588,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -metalfragment,Fragments,res,metal,1024,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -furnace,,items,stone,517,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hqm,Quality Metal,res,metal,1028,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -cookedwolfmeat,Wolf Meat,medical,meat,2560,,,,,,,,,,,,,,,,,,,,,5,0,60,1,0,0,5,20,,,,,,,,, -building_plan,Plan,building,paper,5,,,,,,,,,,,,,,,,buildingplan,,,,,,,,,,,,,,,,,,,,, -rocketlauncher,Launcher,weapon,metalhollowlarge,3080,,,,200,,,,,,,,,1,,,rocketlauncher,-3.45,6,3.5,20,,,,,,,,,,,,,,,,, -sheetmetal,Metal,res,metalsheet,1032,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -chocolatebar,Bar,medical,leather,2569,,,,,,,,,,,,,,,,,,,,,1,0,100,2,0,0,5,18,,,,,,,,, -emptypropanetank,Propane Tank,res,metalhollow,1033,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -lowgradefuel,Grade Fuel,res,liquidcontainer,1037,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -12gaugeslug,Gauge Slug,ammo,leather,3587,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -waterjug,Jug,medical,plasticjunk,2574,,,,,,,,,,,,,,,,waterjug,,,,,,,,,,,,,,,,,,,,, -wood,,res,wood,1040,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hat,Hat,clothes,cloth,1552,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,1,0,helmet -balaclava,Balaclava,clothes,cloth,1556,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,13,3,3,0,hat -dieselbarrel,Fuel,res,metalbars,1050,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -stoneaxe,Hatchet,tools,metalwood,2056,15,3,32,4,160,160,80,,0.59,,,,,1,,stoneaxe,2,4,1,17,,,,,,,,,,,,,,,,, -jacket,,clothes,cloth,1562,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,15,20,7,10,0,5,0,jacket -bonehelmet,Helmet,clothes,leather,1565,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,40,13,0,7,4,0,hat -roadsignkilt,Sign Kilt,clothes,metalsheet,1568,,,,,600,600,,,,,,,,,,,,,,,,,,,,,,,,20,25,10,-8,0,0,0,kilt -roadsigns,Signs,res,metalsheet,1058,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hideboots,Boots,clothes,leather,1574,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,3,5,0,2,0,boots -metalspring,Spring,res,spring,1061,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -semiautomaticbody,Automatic Body,res,gun,1065,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -explosive556rifleammo,5.56 Rifle Ammo,ammo,metal,3593,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -woodhelmet,Armor Helmet,clothes,wood,1538,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,15,25,3,7,0,2,0,helmet -mace,,weapon,metalhollow,3074,60,3,35,4,300,300,,,0.83,,,,,1,,mace,-4,8,0,20,,,,,,,,,,,,,,,,, -boltactionrifle,Action Rifle,weapon,gun,3075,,,,200,600,600,,,,1,2,11,1,,boltactionrifle,boltactionrifle,-3.35,2.585,3.2,15,,,,,,,,,,,,,,,,, -rope,,res,cloth,1029,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -booniehat,Hat,clothes,cloth,1540,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,7,0,2,0,helmet -machete,,weapon,metalmediumrattley,3079,35,3,20,4,300,300,,,0.83,,,,,1,,machete,2,8,-1,25,,,,,,,,,,,,,,,,, -sleepingbag,Bag,items,cloth,522,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -apple,,medical,thickrubbery,2568,,,,,,,,,,,,,,,,,,,,,0,2,30,15,0,0,5,18,,,,,,,,, -spas12shotgun,Shotgun,weapon,gun,3084,,,,200,800,800,,,,6,8,18,1,,spas12shotgun,spas12shotgun,-2.435,2.1,3,20,,,,,,,,,,,,,,,,, -combatknife,Knife,weapon,metalknife,3085,35,3,16,4,250,250,,,1,,,,,1,,combatknife,2,6,0,25,,,,,,,,,,,,,,,,, -metalwindowbars,Window Bars,building,metalbars,7,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -codelock,Lock,building,smalldevice,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -pythonrevolver,Revolver,weapon,gun,3088,,,,200,600,600,,,,6,0,3,1,,pythonrevolver,pythonrevolver,-4.6,2.3,2,15,,,,,,,,,,,,,,,,, -recycler,,items,wood,521,,,,,750,750,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -roadsignjacket,Sign Jacket,clothes,metalsheet,1555,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,20,25,10,-8,0,0,0,jacket -salvagedicepick,Icepick,tools,metalmediumrattley,2049,40,3,28,4,1500,1500,,100,0.71,,,,,1,,salvagedicepick,-2.4,4.5,0,25,,,,,,,,,,,,,,,,, -pumpshotgun,Shotgun,weapon,gun,3091,,,,200,400,400,,,,4,8,17,1,,pumpshotgun,pumpshotgun,-3.477,2.95,4,15,,,,,,,,,,,,,,,,, -hideskirt,Skirt,clothes,leather,1560,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,pants -stonespear,Spear,weapon,metalwood,3093,35,5,32,6,400,400,,,,,,,,1,,stonespear,2,8,-1,25,,,,,,,,,,,,,,,,, -shotguntrap,Trap,traps,wood,4096,,,,,300,300,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -woodenwindowbars,Window Bars,building,woodmed,3,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -eokapistol,Pistol,weapon,gun,3098,,,,200,100,100,,,,1,8,14,1,,eokapistol,eokapistol,0,0,0,1000000,,,,,,,,,,,,,,,,, -cactusflesh,Flesh,medical,,2580,,,,,,,,,,,,,,,,,,,,,3,0,5,20,0,0,5,18,,,,,,,,, -canoftuna,of Tuna,medical,canfull,2581,,,,,,,,,,,,,,,,,,,,,2,0,50,15,0,0,5,18,,,,,,,,, -stone,,res,stone,1055,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -roadsigngloves,Gloves,clothes,cloth,1569,,,,,600,0,,,,,,,,,,,,,,,,,,,,,,,,10,25,10,-8,0,0,0,gloves -workbenchlevel2,Bench Level 2,items,metallarge,512,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hoodie,,clothes,cloth,1570,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,20,15,6,8,0,5,0,plate -workbenchlevel1,Bench Level 1,items,wood,513,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -workbenchlevel3,Bench Level 3,items,metallarge,515,,,,,750,750,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -antirad,Pills,medical,pills,2586,,,,,,,,,,,,,,,,none,,,,,0,0,0,-10,-25,0,10,30,,,,,,,,, -556rifleammo,Rifle Ammo,ammo,metal,3585,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -rawdeermeat,Deer Meat,medical,meat,2587,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,, -woodchest,Chestplate,clothes,wood,1576,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,0,5,5,0,jacket -leathergloves,Gloves,clothes,cloth,1578,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,2,5,0,4,0,gloves -crossbow,,weapon,gun,3073,,,,200,200,200,,,,1,6,20,1,,crossbow,crossbow,-7.4,4.1,5,15,,,,,,,,,,,,,,,,, -nailgun,,weapon,gun,3076,,,,200,100,100,,,,6,5,21,1,,nailgun,nailgun,-3.315,1.667,3.5,15,,,,,,,,,,,,,,,,, -granolabar,Bar,medical,leather,2565,,,,,,,,,,,,,,,,,,,,,5,0,60,0,0,0,5,20,,,,,,,,, -snaptrap,Trap,traps,metalmedium,4099,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -timedexplosivecharge,Explosive Charge,tools,leather,2059,,,,,,,,,,,,,,,,timedexplosivecharge,,,,,,,,,,,,,,,,,,,,, -meatpork,Pork,medical,meat,2570,,,,,,,,,,,,,,,,,,,,,-2,0,60,0,0,0,5,20,,,,,,,,, -woodstoragebox,Storage Box,items,woodmed,514,,,,,150,150,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -sheetmetaldoubledoor,Metal Double Door,building,metalhollowlarge,10,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -gears,,res,metalmedium,1045,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -metalchest,Chest Plate,clothes,metalhollowlarge,1557,,,,,800,800,,,,,,,,,,,,,,,,,,,,,,,,25,20,3,-8,0,0,0,jacket -rawbearmeat,Bear Meat,medical,meat,2578,,,,,,,,,,,,,,,,,,,,,-2,0,10,10,0,0,5,20,,,,,,,,, -humanskull,Skull,res,bone,1049,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -revolver,,weapon,gun,3092,,,,200,300,300,,,,4,0,1,1,,revolver,revolver,-3.2,1.102,3.3,15,,,,,,,,,,,,,,,,, -smgbody,Body,res,gun,1051,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -satchelcharge,Charge,tools,leather,2057,,,,,,,,,,,,,,,,satchelcharge,,,,,,,,,,,,,,,,,,,,, -garagedoor,Door,building,metalsheet,4,,,,,600,600,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -leather,,res,leather,1054,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -smallpresent,Present,tools,leather,2061,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -animalfat,Fat,res,meat,1063,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -candycaneclub,Cane Club,medical,leather,2588,,,,,,,,,,,,,,,,,,,,,16,0,300,100,0,0,5,20,,,,,,,,, -riothelmet,Helmet,clothes,leather,1577,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,80,13,6,8,5,0,helmet -supplysignal,Signal,tools,gun,2065,,,,,,,,,,,,,,,,supplysignal,,,,,,,,,,,,,,,,,,,,, -bluekeycard,Keycard,res,plasticjunk,1026,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -assaultrifle,Rifle,weapon,gun,3077,,,,200,2000,2000,,,,4,2,12,1,,assaultrifle,assaultrifle,-6.49,2.4,4.5,20,,,,,,,,,,,,,,,,, -nailgunnails,Nails,ammo,metal,3590,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -bandage,,medical,cloth,2566,,,,,,,,,,,,,,,,bandage,,,,,0,5,0,0,0,-50,80,22,,,,,,,,, -rock,,tools,stone,2060,10,2,40,3,100,100,50,35,0.5,,,,,1,,rock,5,7,1,15,,,,,,,,,,,,,,,,, -burlapchest,Shirt,clothes,cloth,1546,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,plate -scrap,,res,metalmediumloose,1034,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -floorgrill,grill,building,metalbars,6,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -bonearmor,Armor,clothes,leather,1549,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,40,13,0,7,4,0,boots -potato,,medical,thickrubbery,2573,,,,,,,,,,,,,,,,,,,,,6,0,125,5,0,0,5,18,,,,,,,,, -metal_ore,Ore,res,stone,1041,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -sewingkit,Kit,res,bone,1042,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -shorts,,clothes,cloth,1553,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,pants -tarp,,res,tarp,1044,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -woodenspear,Spear,weapon,metalwood,3090,25,4,32,5,250,250,,,,,,,,1,,woodenspear,2,8,-1,25,,,,,,,,,,,,,,,,, -plantfiber,Fiber,res,meat,1047,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -toolcupboard,Cupboard,building,wood,1,,,,,100,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -m92pistol,Pistol,weapon,gun,3096,,,,200,800,800,,,,15,0,4,1,,m92pistol,m92pistol,-5.18,2.1,3.3,15,,,,,,,,,,,,,,,,, -torch,,tools,metalwood,2058,,,,,,,,,,,,,,,,torch,,,,,,,,,,,,,,,,,,,,, -heavypants,Plate Pants,clothes,metalhollowlarge,1566,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,75,70,12,-17,17,7,30,kilt -m39rifle,Rifle,weapon,gun,3099,,,,200,1500,1500,,,,20,2,9,1,,m39rifle,m39rifle,-8.08,3.8,4,20,,,,,,,,,,,,,,,,, -smallwaterbottle,Water Bottle,medical,plasticjunk,2584,,,,,,,,,,,,,,,,smallwaterbottle,,,,,,,,,,,,,,,,,,,,, -shirt,,clothes,cloth,1572,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,5,6,0,3,0,plate -strengthenedglasswindow,Glass Window,building,metalbars,9,,,,,350,350,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -researchtable,Table,items,metallarge,518,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -keylock,Lock,building,metal,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -lowhp,,items,,519,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -armoreddoor,Door,building,metalhollowlarge,14,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -salvagedcleaver,Cleaver,weapon,metalwood,3102,60,3,35,4,400,400,,,0.83,,,,,1,,salvagedcleaver,-3,5,0,20,,,,,,,,,,,,,,,,, -armoreddoubledoor,Double Door,building,metalhollowlarge,0,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -pants,,clothes,cloth,1539,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,8,0,5,0,pants -sulfur_ore,Ore,res,stone,1027,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -corn,,medical,leather,2561,,,,,,,,,,,,,,,,,,,,,6,0,75,10,0,0,5,20,,,,,,,,, -cookedbearmeat,Bear Meat,medical,meat,2564,,,,,,,,,,,,,,,,,,,,,5,0,100,1,0,0,5,20,,,,,,,,, -explosives,,res,leather,1030,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -salvagedsword,Sword,weapon,metalmediumrattley,3082,50,3,25,4,300,300,,,0.83,,,,,1,,salvagedsword,-3.16,5.5,0,20,,,,,,,,,,,,,,,,, -hidehalterneck,Halterneck,clothes,leather,1545,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,plate -techtrash,Trash,res,plasticjunk,1036,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -largepresent,Present,tools,leather,2062,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hazmatsuit,Suit,clothes,tarp,1550,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,30,30,8,8,5,50,0,suit -horsedung,Dung,res,meat,1038,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -campfire,,items,wood,520,,,,,50,50,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hideponcho,Poncho,clothes,leather,1554,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,8,5,8,0,jacket -electricfuse,Fuse,res,smalldevice,1046,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hvpistolammo,Pistol Ammo,ammo,metal,3594,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -salvagedaxe,Axe,tools,metalmediumrattley,2054,40,3,28,4,1500,1500,100,,1,,,,,1,,salvagedaxe,3,4,0,30,,,,,,,,,,,,,,,,, -hagi,,clothes,,1564,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,plate -wolfheaddress,Headdress,clothes,leather,1567,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,30,60,10,6,13,4,0,helmet -torch_fire,,tools,metalwood,2066,,,,,,,,,,,,,,,,torch,,,,,,,,,,,,,,,,,,,,, -cloth,,res,cloth,1066,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -longsword,,weapon,metalmediumrattley,3103,75,3,35,4,400,400,,,0.83,,,,,1,,longsword,-3,6,0,20,,,,,,,,,,,,,,,,, -coffecanhelmet,Can Helmet,clothes,metalthinhollow,1537,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,35,50,8,0,8,5,0,hat -hammer,,tools,metalwood,2050,,,,,,,,,,,,,,,,hammer,,,,,,,,,,,,,,,,,,,,, -death,,tools,,2052,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -blackraspberries,Raspberries,medical,,2563,,,,,,,,,,,,,,,,,,,,,0,10,40,20,0,0,5,18,,,,,,,,, -reinforcedglasswindow,Glass Window,building,metalbars,2,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -metalpipe,Pipe,res,metalhollow,1031,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -highvelocityarrow,Velocity Arrow,ammo,woodlight,3586,,,,,,,,,,,,,,,,highvelocityarrow,,,,,,,,,,,,,,,,,,,,, -medicalsyringe,Syringe,medical,smalldevice,2575,,,,,,,,,,,,,,,,medicalsyringe,,,,,20,15,0,0,-10,0,14,10,,,,,,,,, -wooddoubledoor,Double Door,building,wood,12,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -sheetmetaldoor,Metal Door,building,metalhollowlarge,15,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -maskbandana,Mask,clothes,cloth,1559,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,10,3,10,0,3,0,hat -burlappants,Trousers,clothes,cloth,1561,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,pants -semiautomaticpistol,Pistol,weapon,gun,3097,,,,200,600,600,,,,4,0,2,1,,semiautomaticpistol,semiautomaticpistol,-5.35,2.69,4.3,15,,,,,,,,,,,,,,,,, -woodenfloorspikes,Floor Spikes,traps,wood,4098,,,,,100,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -hidechest,Vest,clothes,leather,1563,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,8,5,0,3,0,plate -fertilizer,,res,meat,1053,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -canofbeans,of Beans,medical,canfull,2583,,,,,,,,,,,,,,,,,,,,,4,0,100,25,0,0,5,18,,,,,,,,, -riflebody,Body,res,gun,1057,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -cookedhumanmeat,Human Meat,medical,,2585,,,,,,,,,,,,,,,,,,,,,2,0,30,-30,0,0,5,18,,,,,,,,, -backpack,,tools,,2063,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -bonefragments,Fragments,res,bone,1059,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -cctvcamera,Camera,res,smalldevice,1060,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -burlapgloves,Gloves,clothes,cloth,1575,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,0,5,2,4,0,3,0,gloves -longtshirt,T-Shirt,clothes,cloth,1580,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,6,10,0,5,0,plate -doublebarrelshotgun,Barrel Shotgun,weapon,gun,3101,,,,200,200,200,,,,1,8,16,1,,doublebarrelshotgun,doublebarrelshotgun,-8.6,5.8,5,15,,,,,,,,,,,,,,,,, -pumpkin,,medical,thickrubbery,2590,,,,,,,,,,,,,,,,,,,,,10,0,100,30,0,0,5,18,,,,,,,,, -ironpickaxe,,tools,metalwood,2067,30,3,32,4,300,300,,100,0.45,,,,,1,,pickaxe,1,4,1,17,,,,,,,,,,,,,,,,, -emptycanofbeans,Can Of Beans,res,canempty,1067,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, -heavychest,Plate Jacket,clothes,metalhollowlarge,1581,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,75,70,12,-17,17,7,30,plate +rid,name,category,material,nid,damage,range,cooldown,reach,durability,durability_max,wood,ore,skinning,ammo,ammo_type,weapon_id,gun,throw,model,icon,zoom_x,zoom_y,zoom_z,zoom_count,heal,fast_heal,calories,hydration,radiation,bleeding,consume_time,food_cooldown,eat_sound,armor_projectile,armor_melee,armor_bite,armor_cold,armor_explosion,armor_radiation,armor_speed_reduction,armor_slot,armor_layer,armor_zones +ironaxe,,tools,metalwood,2048,25,3,31,4,300,300,85,,1,,,,,1,,hatchet,1,4,1,17,,,,,,,,,,,,,,,,,,, +boneclub,Club,weapon,metalwood,3072,16,3,16,4,300,300,60,44,0.5,,,,,1,,boneclub,0,10,0,20,,,,,,,,,,,,,,,,,,, +largewoodbox,Wood Box,items,wood,516,,,,,300,300,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +blueberries,,medical,rubber,2562,,,,,,,,,,,,,,,,,,,,,0,10,30,20,0,0,5,18,,,,,,,,,,, +metalfacemask,Facemask,clothes,metalhollow,1542,,,,,800,800,,,,,,,,,,,,,,,,,,,,,,,,50,70,8,-4,8,0,0,1,0,1 +burlapboots,Shoes,clothes,cloth,1543,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,2,3,0,2,0,6,0,4 +woodpants,Armor Pants,clothes,wood,1544,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,0,5,5,0,4,1,6 +hmlmg,,weapon,gun,3081,,,,200,2500,2500,,,,6,2,13,1,,hmlmg,hmlmg,-5.5,2.9,3.5,20,,,,,,,,,,,,,,,,,,, +hidepants,Pants,clothes,leather,1548,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,8,4,0,2,0,4,0,6 +cookedchicken,Chicken,medical,meat,2572,,,,,,,,,,,,,,,,,,,,,10,0,40,3,0,0,5,20,,,,,,,,,,, +homemadelandmine,Landmine,traps,metalmedium,4097,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +sulfur,,res,charcol,1039,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +mushroom,,medical,meat,2576,,,,,,,,,,,,,,,,,,,,,0,3,15,5,0,0,5,18,,,,,,,,,,, +metalblade,Blade,res,metalhollow,1043,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +beancangrenade,Grenade,weapon,canfull,3089,,,,,,,,,,,,,,,,beancangrenade,,,,,,,,,,,,,,,,,,,,,,, +pistolbullet,Bullet,ammo,metal,3592,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +cookedpork,Pork,medical,meat,2577,,,,,,,,,,,,,,,,,,,,,5,0,60,1,0,0,5,20,,,,,,,,,,, +cookeddeermeat,Deer Meat,medical,meat,2579,,,,,,,,,,,,,,,,,,,,,10,0,40,3,0,0,5,20,,,,,,,,,,, +mediumpresent,Present,tools,leather,2053,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +semiautomaticrifle,Rifle,weapon,gun,3095,,,,200,1300,1300,,,,6,2,8,1,,semiautomaticrifle,semiautomaticrifle,-4.99,1.1,1.8,15,,,,,,,,,,,,,,,,,,, +gunpowder,Powder,res,snow,1052,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hqm_ore,Quality Metal Ore,res,stone,1056,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +tanktop,Top,clothes,leather,1571,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,2,0,2,0,3,0,2 +customsmg,SMG,weapon,gun,3100,,,,200,800,800,,,,8,0,5,1,,customsmg,customsmg,-5.51,1.6,2,15,,,,,,,,,,,,,,,,,,, +12gaugebuckshot,Gauge Buckshot,ammo,leather,3584,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +rawhumanmeat,Human Meat,medical,,2589,,,,,,,,,,,,,,,,,,,,,0,-9,5,-3,0,0,5,18,,,,,,,,,,, +woodendoor,Door,building,wood,13,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +buckethelmet,Helmet,clothes,metalthinhollow,1579,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,20,50,8,6,8,4,0,1,0,1 +lr300assaultrifle,Assault Rifle,weapon,gun,3104,,,,200,2500,2500,,,,30,2,10,1,,lr300assaultrifle,lr300assaultrifle,-5.33,0.55,5,15,,,,,,,,,,,,,,,,,,, +baseballcap,Cap,clothes,cloth,1536,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,1,0,1,0,1 +targetingcomputer,Computer,res,smalldevice,1025,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +waterpipeshotgun,Shotgun,weapon,gun,3078,,,,200,200,200,,,,1,8,15,1,,waterpipeshotgun,waterpipeshotgun,-3.79,2.65,3,15,,,,,,,,,,,,,,,,,,, +burlaphelmet,Headwrap,clothes,cloth,1541,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,7,0,2,0,1,0,1 +rawchickenbreast,Chicken Breast,medical,meat,2567,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,,,, +emptytunacan,Tuna Can,res,canempty,1035,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +boneknife,Knife,weapon,metalwood,3083,16,3,16,4,250,250,,,1,,,,,1,,boneknife,0,7,0,20,,,,,,,,,,,,,,,,,,, +rawwolfmeat,Wolf Meat,medical,,2571,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,,,, +heavyhelmet,Plate Helmet,clothes,metalhollowlarge,1547,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,90,80,13,-17,17,7,20,1,0,1 +mp5a4,,weapon,gun,3086,,,,200,1500,1500,,,,8,0,7,1,,mp5a4,mp5a4,-5.89,2.05,5.5,15,,,,,,,,,,,,,,,,,,, +boots,,clothes,leather,1551,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,8,0,3,0,6,0,4 +stonepickaxe,Pickaxe,tools,metalwood,2064,17,3,32,4,160,160,,80,0.71,,,,,1,,stonepickaxe,2,4,1,17,,,,,,,,,,,,,,,,,,, +thompson,,weapon,gun,3087,,,,200,800,800,,,,7,0,6,1,,thompson,thompson,-3.878,1.6,1.9,15,,,,,,,,,,,,,,,,,,, +woodenladder,Ladder,building,woodmed,16,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +key,Key,tools,metal,2068,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +wolfskull,Skull,res,bone,1048,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +salvagedhammer,Hammer,tools,metalmediumrattley,2051,30,3,19,4,400,400,40,59,0.45,,,,,1,,salvagedhammer,-3,5,0,20,,,,,,,,,,,,,,,,,,, +snowjacket,Jacket,clothes,cloth,1558,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,20,30,5,17,0,20,0,3,1,2 +binoculars,,tools,gun,2055,,,,,,,,,,,,,,,,binoculars,,,,,,,,,,,,,,,,,,,,,,, +huntingbow,Bow,weapon,woodlight,3094,,,,200,100,100,,,,,6,19,1,,huntingbow,huntingbow,-5.25,7.8,6,15,,,,,,,,,,,,,,,,,,, +woodenarrow,Arrow,ammo,woodlight,3589,,,,,,,,,,,,,,,,woodenarrow,,,,,,,,,,,,,,,,,,,,,,, +handmadeshell,Shell,ammo,leather,3591,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +largemedkit,Medkit,medical,plasticmedium,2582,,,,,,,,,,,,,,,,largemedkit,,,,,100,10,0,0,0,-100,0,20,,,,,,,,,,, +tshirt,,clothes,cloth,1573,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,5,6,0,3,0,3,0,2 +crudeoil,Oil,res,leather,1062,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +charcoal,,res,charcol,1064,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hv556rifleammo,5.56 Rifle Ammo,ammo,metal,3588,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +metalfragment,Fragments,res,metal,1024,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +furnace,,items,stone,517,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hqm,Quality Metal,res,metal,1028,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +cookedwolfmeat,Wolf Meat,medical,meat,2560,,,,,,,,,,,,,,,,,,,,,5,0,60,1,0,0,5,20,,,,,,,,,,, +building_plan,Plan,building,paper,5,,,,,,,,,,,,,,,,buildingplan,,,,,,,,,,,,,,,,,,,,,,, +rocketlauncher,Launcher,weapon,metalhollowlarge,3080,,,,200,,,,,,,,,1,,,rocketlauncher,-3.45,6,3.5,20,,,,,,,,,,,,,,,,,,, +sheetmetal,Metal,res,metalsheet,1032,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +chocolatebar,Bar,medical,leather,2569,,,,,,,,,,,,,,,,,,,,,1,0,100,2,0,0,5,18,,,,,,,,,,, +emptypropanetank,Propane Tank,res,metalhollow,1033,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +lowgradefuel,Grade Fuel,res,liquidcontainer,1037,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +12gaugeslug,Gauge Slug,ammo,leather,3587,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +waterjug,Jug,medical,plasticjunk,2574,,,,,,,,,,,,,,,,waterjug,,,,,,,,,,,,,,,,,,,,,,, +wood,,res,wood,1040,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hat,Hat,clothes,cloth,1552,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,1,0,1,0,1 +balaclava,Balaclava,clothes,cloth,1556,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,13,3,3,0,1,0,1 +dieselbarrel,Fuel,res,metalbars,1050,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +stoneaxe,Hatchet,tools,metalwood,2056,15,3,32,4,160,160,80,,0.59,,,,,1,,stoneaxe,2,4,1,17,,,,,,,,,,,,,,,,,,, +jacket,,clothes,cloth,1562,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,15,20,7,10,0,5,0,3,1,2 +bonehelmet,Helmet,clothes,leather,1565,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,40,13,0,7,4,0,1,0,1 +roadsignkilt,Sign Kilt,clothes,metalsheet,1568,,,,,600,600,,,,,,,,,,,,,,,,,,,,,,,,20,25,10,-8,0,0,0,4,1,6 +roadsigns,Signs,res,metalsheet,1058,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hideboots,Boots,clothes,leather,1574,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,3,5,0,2,0,6,0,4 +metalspring,Spring,res,spring,1061,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +semiautomaticbody,Automatic Body,res,gun,1065,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +explosive556rifleammo,5.56 Rifle Ammo,ammo,metal,3593,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +woodhelmet,Armor Helmet,clothes,wood,1538,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,15,25,3,7,0,2,0,1,0,1 +mace,,weapon,metalhollow,3074,60,3,35,4,300,300,,,0.83,,,,,1,,mace,-4,8,0,20,,,,,,,,,,,,,,,,,,, +boltactionrifle,Action Rifle,weapon,gun,3075,,,,200,600,600,,,,1,2,11,1,,boltactionrifle,boltactionrifle,-3.35,2.585,3.2,15,,,,,,,,,,,,,,,,,,, +rope,,res,cloth,1029,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +booniehat,Hat,clothes,cloth,1540,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,7,0,2,0,1,0,1 +machete,,weapon,metalmediumrattley,3079,35,3,20,4,300,300,,,0.83,,,,,1,,machete,2,8,-1,25,,,,,,,,,,,,,,,,,,, +sleepingbag,Bag,items,cloth,522,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +apple,,medical,thickrubbery,2568,,,,,,,,,,,,,,,,,,,,,0,2,30,15,0,0,5,18,,,,,,,,,,, +spas12shotgun,Shotgun,weapon,gun,3084,,,,200,800,800,,,,6,8,18,1,,spas12shotgun,spas12shotgun,-2.435,2.1,3,20,,,,,,,,,,,,,,,,,,, +combatknife,Knife,weapon,metalknife,3085,35,3,16,4,250,250,,,1,,,,,1,,combatknife,2,6,0,25,,,,,,,,,,,,,,,,,,, +metalwindowbars,Window Bars,building,metalbars,7,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +codelock,Lock,building,smalldevice,8,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +pythonrevolver,Revolver,weapon,gun,3088,,,,200,600,600,,,,6,0,3,1,,pythonrevolver,pythonrevolver,-4.6,2.3,2,15,,,,,,,,,,,,,,,,,,, +recycler,,items,wood,521,,,,,750,750,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +roadsignjacket,Sign Jacket,clothes,metalsheet,1555,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,20,25,10,-8,0,0,0,3,1,2 +salvagedicepick,Icepick,tools,metalmediumrattley,2049,40,3,28,4,1500,1500,,100,0.71,,,,,1,,salvagedicepick,-2.4,4.5,0,25,,,,,,,,,,,,,,,,,,, +pumpshotgun,Shotgun,weapon,gun,3091,,,,200,400,400,,,,4,8,17,1,,pumpshotgun,pumpshotgun,-3.477,2.95,4,15,,,,,,,,,,,,,,,,,,, +hideskirt,Skirt,clothes,leather,1560,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,4,0,6 +stonespear,Spear,weapon,metalwood,3093,35,5,32,6,400,400,,,,,,,,1,,stonespear,2,8,-1,25,,,,,,,,,,,,,,,,,,, +shotguntrap,Trap,traps,wood,4096,,,,,300,300,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +woodenwindowbars,Window Bars,building,woodmed,3,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +eokapistol,Pistol,weapon,gun,3098,,,,200,100,100,,,,1,8,14,1,,eokapistol,eokapistol,0,0,0,1000000,,,,,,,,,,,,,,,,,,, +cactusflesh,Flesh,medical,,2580,,,,,,,,,,,,,,,,,,,,,3,0,5,20,0,0,5,18,,,,,,,,,,, +canoftuna,of Tuna,medical,canfull,2581,,,,,,,,,,,,,,,,,,,,,2,0,50,15,0,0,5,18,,,,,,,,,,, +stone,,res,stone,1055,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +roadsigngloves,Gloves,clothes,cloth,1569,,,,,600,0,,,,,,,,,,,,,,,,,,,,,,,,10,25,10,-8,0,0,0,5,0,2 +workbenchlevel2,Bench Level 2,items,metallarge,512,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hoodie,,clothes,cloth,1570,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,20,15,6,8,0,5,0,3,0,2 +workbenchlevel1,Bench Level 1,items,wood,513,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +workbenchlevel3,Bench Level 3,items,metallarge,515,,,,,750,750,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +antirad,Pills,medical,pills,2586,,,,,,,,,,,,,,,,none,,,,,0,0,0,-10,-25,0,10,30,,,,,,,,,,, +556rifleammo,Rifle Ammo,ammo,metal,3585,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +rawdeermeat,Deer Meat,medical,meat,2587,,,,,,,,,,,,,,,,,,,,,-9,0,20,0,0,0,5,20,,,,,,,,,,, +woodchest,Chestplate,clothes,wood,1576,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,0,5,5,0,3,1,2 +leathergloves,Gloves,clothes,cloth,1578,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,5,2,5,0,4,0,5,0,2 +crossbow,,weapon,gun,3073,,,,200,200,200,,,,1,6,20,1,,crossbow,crossbow,-7.4,4.1,5,15,,,,,,,,,,,,,,,,,,, +nailgun,,weapon,gun,3076,,,,200,100,100,,,,6,5,21,1,,nailgun,nailgun,-3.315,1.667,3.5,15,,,,,,,,,,,,,,,,,,, +granolabar,Bar,medical,leather,2565,,,,,,,,,,,,,,,,,,,,,5,0,60,0,0,0,5,20,,,,,,,,,,, +snaptrap,Trap,traps,metalmedium,4099,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +timedexplosivecharge,Explosive Charge,tools,leather,2059,,,,,,,,,,,,,,,,timedexplosivecharge,,,,,,,,,,,,,,,,,,,,,,, +meatpork,Pork,medical,meat,2570,,,,,,,,,,,,,,,,,,,,,-2,0,60,0,0,0,5,20,,,,,,,,,,, +woodstoragebox,Storage Box,items,woodmed,514,,,,,150,150,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +sheetmetaldoubledoor,Metal Double Door,building,metalhollowlarge,10,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +gears,,res,metalmedium,1045,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +metalchest,Chest Plate,clothes,metalhollowlarge,1557,,,,,800,800,,,,,,,,,,,,,,,,,,,,,,,,25,20,3,-8,0,0,0,3,1,2 +rawbearmeat,Bear Meat,medical,meat,2578,,,,,,,,,,,,,,,,,,,,,-2,0,10,10,0,0,5,20,,,,,,,,,,, +humanskull,Skull,res,bone,1049,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +revolver,,weapon,gun,3092,,,,200,300,300,,,,4,0,1,1,,revolver,revolver,-3.2,1.102,3.3,15,,,,,,,,,,,,,,,,,,, +smgbody,Body,res,gun,1051,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +satchelcharge,Charge,tools,leather,2057,,,,,,,,,,,,,,,,satchelcharge,,,,,,,,,,,,,,,,,,,,,,, +garagedoor,Door,building,metalsheet,4,,,,,600,600,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +leather,,res,leather,1054,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +smallpresent,Present,tools,leather,2061,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +animalfat,Fat,res,meat,1063,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +candycaneclub,Cane Club,medical,leather,2588,,,,,,,,,,,,,,,,,,,,,16,0,300,100,0,0,5,20,,,,,,,,,,, +riothelmet,Helmet,clothes,leather,1577,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,80,13,6,8,5,0,1,0,1 +supplysignal,Signal,tools,gun,2065,,,,,,,,,,,,,,,,supplysignal,,,,,,,,,,,,,,,,,,,,,,, +bluekeycard,Keycard,res,plasticjunk,1026,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +assaultrifle,Rifle,weapon,gun,3077,,,,200,2000,2000,,,,4,2,12,1,,assaultrifle,assaultrifle,-6.49,2.4,4.5,20,,,,,,,,,,,,,,,,,,, +nailgunnails,Nails,ammo,metal,3590,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +bandage,,medical,cloth,2566,,,,,,,,,,,,,,,,bandage,,,,,0,5,0,0,0,-50,80,22,,,,,,,,,,, +rock,,tools,stone,2060,10,2,40,3,100,100,50,35,0.5,,,,,1,,rock,5,7,1,15,,,,,,,,,,,,,,,,,,, +burlapchest,Shirt,clothes,cloth,1546,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,3,0,2 +scrap,,res,metalmediumloose,1034,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +floorgrill,grill,building,metalbars,6,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +bonearmor,Armor,clothes,leather,1549,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,25,40,13,0,7,4,0,5,0,6 +potato,,medical,thickrubbery,2573,,,,,,,,,,,,,,,,,,,,,6,0,125,5,0,0,5,18,,,,,,,,,,, +metal_ore,Ore,res,stone,1041,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +sewingkit,Kit,res,bone,1042,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +shorts,,clothes,cloth,1553,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,4,0,6 +tarp,,res,tarp,1044,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +woodenspear,Spear,weapon,metalwood,3090,25,4,32,5,250,250,,,,,,,,1,,woodenspear,2,8,-1,25,,,,,,,,,,,,,,,,,,, +plantfiber,Fiber,res,meat,1047,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +toolcupboard,Cupboard,building,wood,1,,,,,100,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +m92pistol,Pistol,weapon,gun,3096,,,,200,800,800,,,,15,0,4,1,,m92pistol,m92pistol,-5.18,2.1,3.3,15,,,,,,,,,,,,,,,,,,, +torch,,tools,metalwood,2058,,,,,,,,,,,,,,,,torch,,,,,,,,,,,,,,,,,,,,,,, +heavypants,Plate Pants,clothes,metalhollowlarge,1566,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,75,70,12,-17,17,7,30,4,0,6 +m39rifle,Rifle,weapon,gun,3099,,,,200,1500,1500,,,,20,2,9,1,,m39rifle,m39rifle,-8.08,3.8,4,20,,,,,,,,,,,,,,,,,,, +smallwaterbottle,Water Bottle,medical,plasticjunk,2584,,,,,,,,,,,,,,,,smallwaterbottle,,,,,,,,,,,,,,,,,,,,,,, +shirt,,clothes,cloth,1572,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,5,6,0,3,0,3,0,2 +strengthenedglasswindow,Glass Window,building,metalbars,9,,,,,350,350,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +researchtable,Table,items,metallarge,518,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +keylock,Lock,building,metal,11,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +lowhp,,items,,519,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +armoreddoor,Door,building,metalhollowlarge,14,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +salvagedcleaver,Cleaver,weapon,metalwood,3102,60,3,35,4,400,400,,,0.83,,,,,1,,salvagedcleaver,-3,5,0,20,,,,,,,,,,,,,,,,,,, +armoreddoubledoor,Double Door,building,metalhollowlarge,0,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +pants,,clothes,cloth,1539,,,,,400,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,3,8,0,5,0,4,0,6 +sulfur_ore,Ore,res,stone,1027,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +corn,,medical,leather,2561,,,,,,,,,,,,,,,,,,,,,6,0,75,10,0,0,5,20,,,,,,,,,,, +cookedbearmeat,Bear Meat,medical,meat,2564,,,,,,,,,,,,,,,,,,,,,5,0,100,1,0,0,5,20,,,,,,,,,,, +explosives,,res,leather,1030,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +salvagedsword,Sword,weapon,metalmediumrattley,3082,50,3,25,4,300,300,,,0.83,,,,,1,,salvagedsword,-3.16,5.5,0,20,,,,,,,,,,,,,,,,,,, +hidehalterneck,Halterneck,clothes,leather,1545,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,3,0,2 +techtrash,Trash,res,plasticjunk,1036,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +largepresent,Present,tools,leather,2062,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hazmatsuit,Suit,clothes,tarp,1550,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,30,30,8,8,5,50,0,7,0,7 +horsedung,Dung,res,meat,1038,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +campfire,,items,wood,520,,,,,50,50,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hideponcho,Poncho,clothes,leather,1554,,,,,400,400,,,,,,,,,,,,,,,,,,,,,,,,10,40,5,8,5,8,0,3,1,2 +electricfuse,Fuse,res,smalldevice,1046,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hvpistolammo,Pistol Ammo,ammo,metal,3594,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +salvagedaxe,Axe,tools,metalmediumrattley,2054,40,3,28,4,1500,1500,100,,1,,,,,1,,salvagedaxe,3,4,0,30,,,,,,,,,,,,,,,,,,, +hagi,,clothes,,1564,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,0,2 +wolfheaddress,Headdress,clothes,leather,1567,,,,,0,0,,,,,,,,,,,,,,,,,,,,,,,,30,60,10,6,13,4,0,1,0,1 +torch_fire,,tools,metalwood,2066,,,,,,,,,,,,,,,,torch,,,,,,,,,,,,,,,,,,,,,,, +cloth,,res,cloth,1066,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +longsword,,weapon,metalmediumrattley,3103,75,3,35,4,400,400,,,0.83,,,,,1,,longsword,-3,6,0,20,,,,,,,,,,,,,,,,,,, +coffecanhelmet,Can Helmet,clothes,metalthinhollow,1537,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,35,50,8,0,8,5,0,1,0,1 +hammer,,tools,metalwood,2050,,,,,,,,,,,,,,,,hammer,,,,,,,,,,,,,,,,,,,,,,, +death,,tools,,2052,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +blackraspberries,Raspberries,medical,,2563,,,,,,,,,,,,,,,,,,,,,0,10,40,20,0,0,5,18,,,,,,,,,,, +reinforcedglasswindow,Glass Window,building,metalbars,2,,,,,500,500,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +metalpipe,Pipe,res,metalhollow,1031,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +highvelocityarrow,Velocity Arrow,ammo,woodlight,3586,,,,,,,,,,,,,,,,highvelocityarrow,,,,,,,,,,,,,,,,,,,,,,, +medicalsyringe,Syringe,medical,smalldevice,2575,,,,,,,,,,,,,,,,medicalsyringe,,,,,20,15,0,0,-10,0,14,10,,,,,,,,,,, +wooddoubledoor,Double Door,building,wood,12,,,,,200,200,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +sheetmetaldoor,Metal Door,building,metalhollowlarge,15,,,,,250,250,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +maskbandana,Mask,clothes,cloth,1559,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,5,10,3,10,0,3,0,2,0,1 +burlappants,Trousers,clothes,cloth,1561,,,,,300,0,,,,,,,,,,,,,,,,,,,,,,,,10,10,3,7,0,2,0,4,0,6 +semiautomaticpistol,Pistol,weapon,gun,3097,,,,200,600,600,,,,4,0,2,1,,semiautomaticpistol,semiautomaticpistol,-5.35,2.69,4.3,15,,,,,,,,,,,,,,,,,,, +woodenfloorspikes,Floor Spikes,traps,wood,4098,,,,,100,100,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +hidechest,Vest,clothes,leather,1563,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,8,5,0,3,0,3,0,2 +fertilizer,,res,meat,1053,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +canofbeans,of Beans,medical,canfull,2583,,,,,,,,,,,,,,,,,,,,,4,0,100,25,0,0,5,18,,,,,,,,,,, +riflebody,Body,res,gun,1057,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +cookedhumanmeat,Human Meat,medical,,2585,,,,,,,,,,,,,,,,,,,,,2,0,30,-30,0,0,5,18,,,,,,,,,,, +backpack,,tools,,2063,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +bonefragments,Fragments,res,bone,1059,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +cctvcamera,Camera,res,smalldevice,1060,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +burlapgloves,Gloves,clothes,cloth,1575,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,0,5,2,4,0,3,0,5,0,2 +longtshirt,T-Shirt,clothes,cloth,1580,,,,,200,0,,,,,,,,,,,,,,,,,,,,,,,,15,15,6,10,0,5,0,3,0,2 +doublebarrelshotgun,Barrel Shotgun,weapon,gun,3101,,,,200,200,200,,,,1,8,16,1,,doublebarrelshotgun,doublebarrelshotgun,-8.6,5.8,5,15,,,,,,,,,,,,,,,,,,, +pumpkin,,medical,thickrubbery,2590,,,,,,,,,,,,,,,,,,,,,10,0,100,30,0,0,5,18,,,,,,,,,,, +ironpickaxe,,tools,metalwood,2067,30,3,32,4,300,300,,100,0.45,,,,,1,,pickaxe,1,4,1,17,,,,,,,,,,,,,,,,,,, +emptycanofbeans,Can Of Beans,res,canempty,1067,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, +heavychest,Plate Jacket,clothes,metalhollowlarge,1581,,,,,1000,1000,,,,,,,,,,,,,,,,,,,,,,,,75,70,12,-17,17,7,30,5,0,2 diff --git a/rsx-protocol/src/test/java/net/rustnotmc/protocol/ItemTest.java b/rsx-protocol/src/test/java/net/rustnotmc/protocol/ItemTest.java index 13abf96..d3f6315 100644 --- a/rsx-protocol/src/test/java/net/rustnotmc/protocol/ItemTest.java +++ b/rsx-protocol/src/test/java/net/rustnotmc/protocol/ItemTest.java @@ -317,6 +317,22 @@ public final class ItemTest { Packets.LearnBlueprint.read(new Buf(learn.write().toByteArray())); eq("the blueprint survives", Integer.valueOf(ItemRegistry.PICKAXE), Integer.valueOf(learnBack.item)); + + Packets.Attack attack = new Packets.Attack(7, 1.5F, 2.5F, 3.5F, + Packets.Attack.HAND_MAIN); + Packets.Attack attackBack = + Packets.Attack.read(new Buf(attack.write().toByteArray())); + eq("the target survives", Integer.valueOf(7), Integer.valueOf(attackBack.target)); + near("the place of the hit survives", 2.5, attackBack.y); + eq("the hand survives", Integer.valueOf(Packets.Attack.HAND_MAIN), + Integer.valueOf(attackBack.hand)); + } + + private static void near(Object what, double expected, double actual) { + if (Math.abs(expected - actual) > 0.0001D) { + failed++; + failures.add(what + ": expected " + expected + " but got " + actual); + } } private static void run(String name, Runnable body) { diff --git a/rsx-protocol/src/test/java/net/rustnotmc/protocol/ProtocolTest.java b/rsx-protocol/src/test/java/net/rustnotmc/protocol/ProtocolTest.java index dc79f72..fd21b02 100644 --- a/rsx-protocol/src/test/java/net/rustnotmc/protocol/ProtocolTest.java +++ b/rsx-protocol/src/test/java/net/rustnotmc/protocol/ProtocolTest.java @@ -551,6 +551,8 @@ public final class ProtocolTest { Packets.KNOWN_RECIPES, Packets.TECH_TREE_STATE, Packets.CONTAINER_OPEN, Packets.CONTAINER_TAKE, Packets.LEARN_BLUEPRINT, + Packets.HITBOXES, Packets.HITBOX_INSTANCES, Packets.HITBOXES_RELOAD, + Packets.ATTACK, Packets.DISCONNECT, }; for (int i = 0; i < ids.length; i++) { diff --git a/rsx-server-core/scripts/test.ps1 b/rsx-server-core/scripts/test.ps1 index acdb7a9..a545cd7 100644 --- a/rsx-server-core/scripts/test.ps1 +++ b/rsx-server-core/scripts/test.ps1 @@ -52,6 +52,7 @@ $suites = @( 'net.rustnotmc.server.item.InventoryTest', 'net.rustnotmc.server.craft.CraftTest', 'net.rustnotmc.server.hitbox.HitboxTest', + 'net.rustnotmc.server.combat.DamageTest', 'net.rustnotmc.server.PlayTest' ) foreach ($suite in $suites) { diff --git a/rsx-server-core/src/main/java/net/rustnotmc/server/ClientSession.java b/rsx-server-core/src/main/java/net/rustnotmc/server/ClientSession.java index 31de3d2..4dd2906 100644 --- a/rsx-server-core/src/main/java/net/rustnotmc/server/ClientSession.java +++ b/rsx-server-core/src/main/java/net/rustnotmc/server/ClientSession.java @@ -232,6 +232,9 @@ public final class ClientSession implements Runnable { case Packets.HITBOXES_RELOAD: onHitboxesReload(frame); return true; + case Packets.ATTACK: + onAttack(frame); + return true; case Packets.PLAYER_MOVE: onPlayerMove(frame); return true; @@ -637,6 +640,44 @@ public final class ClientSession implements Runnable { send(Packets.INVENTORY, this.player.inventory().toPacket()); } + /** + * The client hits something. + * + * The place of the hit decides how much it hurts, and the clothing of the + * one who is hit takes a part of it away. The client never decides any of + * that: it says where it hit, and the server counts. + */ + private void onAttack(Frame frame) { + if (this.state != SessionState.PLAYING || this.player == null) { + return; + } + Packets.Attack attack = Packets.Attack.read(new Buf(frame.body())); + Player target = this.server.playerByEntity(attack.target); + if (target == null || target == this.player) { + return; + } + net.rustnotmc.protocol.ItemType weapon = this.player.inventory() + .inHand().type(); + if (weapon == null) { + return; + } + float base = weapon.damage(net.rustnotmc.protocol.ItemType.TORSO); + if (base <= 0) { + return; + } + String zone = net.rustnotmc.server.combat.Damage.zoneOf(attack.y, target.y(), + net.rustnotmc.server.Player.HEIGHT); + float hurt = net.rustnotmc.server.combat.Damage.apply(base, zone, + target.inventory().armor(), + net.rustnotmc.protocol.ItemType.HARM_MELEE); + if (target.damage(hurt)) { + this.server.log(this.account + " killed " + target.account()); + } else { + this.server.log(this.account + " hit " + target.account() + " for " + + (int) hurt + " (" + zone + ")"); + } + } + /** * The client wants the box file read again. * diff --git a/rsx-server-core/src/main/java/net/rustnotmc/server/Player.java b/rsx-server-core/src/main/java/net/rustnotmc/server/Player.java index 5191e33..cf2f8f5 100644 --- a/rsx-server-core/src/main/java/net/rustnotmc/server/Player.java +++ b/rsx-server-core/src/main/java/net/rustnotmc/server/Player.java @@ -30,6 +30,12 @@ public final class Player { /** How far a player may reach to change a block, in blocks. */ public static final double REACH = 5.0D; + /** How much life a player has, and how much a full bar holds. */ + public static final float MAX_HEALTH = 100.0F; + + /** How tall a player is, in blocks. */ + public static final float HEIGHT = 1.8F; + /** How far a player may see, in chunks, unless it asks for less. */ public static final int DEFAULT_VIEW_DISTANCE = 6; @@ -56,6 +62,9 @@ public final class Player { /** What the player is carrying. The server owns it. */ private final Inventory inventory; + /** How much life the player has left. */ + private float health = MAX_HEALTH; + /** What the player knows: the recipes and the nodes of the trees. */ private final Knowledge knowledge; @@ -66,6 +75,32 @@ public final class Player { private int craftItem = ItemRegistry.NOTHING; private int craftSecondsLeft; + /** How much life the player has left. */ + public float health() { + return this.health; + } + + /** + * Hurts the player. + * + * Returns true when the hit was the last one. + */ + public boolean damage(float amount) { + if (amount <= 0.0F) { + return false; + } + this.health -= amount; + if (this.health < 0.0F) { + this.health = 0.0F; + } + return this.health <= 0.0F; + } + + /** Gives the player their life back. */ + public void heal(float amount) { + this.health = Math.min(MAX_HEALTH, this.health + amount); + } + Player(ClientSession session, int playerId, int entityId, String account, double[] spawn) { this(session, playerId, entityId, account, spawn, diff --git a/rsx-server-core/src/main/java/net/rustnotmc/server/Server.java b/rsx-server-core/src/main/java/net/rustnotmc/server/Server.java index 4af764c..693f309 100644 --- a/rsx-server-core/src/main/java/net/rustnotmc/server/Server.java +++ b/rsx-server-core/src/main/java/net/rustnotmc/server/Server.java @@ -125,6 +125,21 @@ public final class Server { return this.players; } + /** + * The player with that entity id, or null. + * + * The client only knows the entity id of what it sees, so that is the + * number a hit comes with. + */ + public Player playerByEntity(int entityId) { + for (Player player : this.players.values()) { + if (player.entityId() == entityId) { + return player; + } + } + return null; + } + /** How far a new player sees, in chunks. */ public int viewDistance() { return this.viewDistance; diff --git a/rsx-server-core/src/main/java/net/rustnotmc/server/combat/Damage.java b/rsx-server-core/src/main/java/net/rustnotmc/server/combat/Damage.java new file mode 100644 index 0000000..a41baaa --- /dev/null +++ b/rsx-server-core/src/main/java/net/rustnotmc/server/combat/Damage.java @@ -0,0 +1,131 @@ +package net.rustnotmc.server.combat; + +import net.rustnotmc.protocol.Hitbox; +import net.rustnotmc.protocol.ItemStack; +import net.rustnotmc.protocol.ItemType; + +/** + * How much a hit hurts. + * + * A hit lands somewhere on the target, and where it landed decides how much + * it hurts: a hit on the head hurts twice as much as a hit on the body, and a + * hit on the legs hurts a little less. That is the rule of the original game, + * and the head is the only place where it is written down. + * + * The clothing takes a part of the harm away, but only for the parts of the + * body it covers: a hat does nothing for a hit in the chest. + */ +public final class Damage { + + /** How much a hit on the head hurts, against a hit on the body. */ + public static final float HEAD_MULTIPLIER = 2.0F; + + /** How much a hit on the legs hurts, against a hit on the body. */ + public static final float LEGS_MULTIPLIER = 0.75F; + + /** How tall the head of a player is, in blocks. */ + public static final float HEAD_HEIGHT = 0.4F; + + /** How tall the legs of a player are, in blocks. */ + public static final float LEGS_HEIGHT = 0.4F; + + private Damage() { + } + + /** + * Where a hit landed. + * + * @param hitY where the hit landed + * @param feetY where the feet of the target are + * @param height how tall the target is + */ + public static String zoneOf(double hitY, double feetY, double height) { + double above = hitY - feetY; + if (above < 0.0D) { + above = 0.0D; + } + if (above > height) { + above = height; + } + if (above >= height - HEAD_HEIGHT) { + return Hitbox.PART_HEAD; + } + if (above < LEGS_HEIGHT) { + return Hitbox.PART_LEGS; + } + return Hitbox.PART_BODY; + } + + /** How much a hit on that zone hurts, before the clothing. */ + public static float multiplier(String zone) { + if (Hitbox.PART_HEAD.equals(zone)) { + return HEAD_MULTIPLIER; + } + if (Hitbox.PART_LEGS.equals(zone)) { + return LEGS_MULTIPLIER; + } + return 1.0F; + } + + /** + * How much of a kind of harm the clothing takes away. + * + * The pieces that cover the zone are added up, and the sum never goes + * past a whole. + */ + public static float protection(ItemStack[][] armor, String zone, int harm) { + int total = 0; + for (int i = 0; i < armor.length; i++) { + for (int layer = 0; layer < armor[i].length; layer++) { + ItemStack stack = armor[i][layer]; + if (stack == null || stack.isEmpty()) { + continue; + } + ItemType type = stack.type(); + if (type == null || type.armorSlot == ItemType.ARMOR_NONE) { + continue; + } + if (!covers(type, zone)) { + continue; + } + if (harm < 0 || harm >= type.protection.length) { + continue; + } + total += type.protection[harm]; + } + } + if (total > 100) { + total = 100; + } + if (total < 0) { + total = 0; + } + return total / 100.0F; + } + + /** + * How much damage a hit does. + * + * The base damage of the weapon, times the zone, minus what the clothing + * takes away. + */ + public static float apply(float base, String zone, ItemStack[][] armor, int harm) { + float withZone = base * multiplier(zone); + float taken = protection(armor, zone, harm); + return withZone * (1.0F - taken); + } + + /** True when a piece of clothing covers that zone. */ + public static boolean covers(ItemType type, String zone) { + if (type.coveredZones == 0) { + return false; + } + if (Hitbox.PART_HEAD.equals(zone)) { + return (type.coveredZones & Hitbox.ZONE_HEAD) != 0; + } + if (Hitbox.PART_LEGS.equals(zone)) { + return (type.coveredZones & Hitbox.ZONE_LEGS) != 0; + } + return (type.coveredZones & Hitbox.ZONE_BODY) != 0; + } +} diff --git a/rsx-server-core/src/main/java/net/rustnotmc/server/item/Inventory.java b/rsx-server-core/src/main/java/net/rustnotmc/server/item/Inventory.java index ac823b8..cf5f96a 100644 --- a/rsx-server-core/src/main/java/net/rustnotmc/server/item/Inventory.java +++ b/rsx-server-core/src/main/java/net/rustnotmc/server/item/Inventory.java @@ -27,10 +27,24 @@ public final class Inventory { private final ItemStack[] slots = new ItemStack[SLOTS]; private int held; + /** + * The clothing the player wears. + * + * Seven places, as in the original game: the head, the face, the chest, + * the legs, the hands, the feet and the whole body. The chest and the legs + * have two layers, the clothes under and the armour over. + */ + private final ItemStack[][] armor = + new ItemStack[net.rustnotmc.protocol.ItemType.ARMOR_SLOTS][2]; + public Inventory() { for (int i = 0; i < SLOTS; i++) { this.slots[i] = ItemStack.EMPTY; } + for (int i = 0; i < this.armor.length; i++) { + this.armor[i][0] = ItemStack.EMPTY; + this.armor[i][1] = ItemStack.EMPTY; + } } /** @@ -156,7 +170,69 @@ public final class Inventory { for (int i = 0; i < SLOTS; i++) { out[i] = Packets.Slot.of(get(i)); } - return new Packets.Inventory(out, this.held); + return new Packets.Inventory(out, this.held, armorToPacket()); + } + + /** + * The clothing as the client is told about it. + * + * Seven places, two layers each, so fourteen stacks. + */ + private Packets.Slot[] armorToPacket() { + Packets.Slot[] out = new Packets.Slot[this.armor.length * 2]; + for (int i = 0; i < this.armor.length; i++) { + for (int layer = 0; layer < 2; layer++) { + out[i * 2 + layer] = Packets.Slot.of(this.armor[i][layer]); + } + } + return out; + } + + /** + * The piece of clothing in a slot, or nothing. + * + * The layer is zero for the clothes under and one for the armour over. + */ + public ItemStack armor(int slot, int layer) { + if (slot < 0 || slot >= this.armor.length || layer < 0 || layer > 1) { + return ItemStack.EMPTY; + } + ItemStack stack = this.armor[slot][layer]; + return stack == null ? ItemStack.EMPTY : stack; + } + + /** Puts a piece of clothing in a slot. */ + public void setArmor(int slot, int layer, ItemStack stack) { + if (slot < 0 || slot >= this.armor.length || layer < 0 || layer > 1) { + return; + } + this.armor[slot][layer] = stack == null ? ItemStack.EMPTY : stack; + } + + /** Every piece of clothing, slot by slot and layer by layer. */ + public ItemStack[][] armor() { + return this.armor; + } + + /** + * Puts a piece of clothing on, if it fits where it goes. + * + * Returns the piece that was in the way, or nothing. + */ + public ItemStack wear(int item) { + net.rustnotmc.protocol.ItemType type = + net.rustnotmc.protocol.ItemRegistry.byId(item); + if (type == null || type.armorSlot == net.rustnotmc.protocol.ItemType.ARMOR_NONE) { + return null; + } + int slot = type.armorSlot - 1; + int layer = type.armorLayer; + if (slot < 0 || slot >= this.armor.length) { + return null; + } + ItemStack was = armor(slot, layer); + setArmor(slot, layer, ItemStack.of(item, 1)); + return was.isEmpty() ? null : was; } /** The slots that are not empty, for a look at what a player carries. */ diff --git a/rsx-server-core/src/test/java/net/rustnotmc/server/combat/DamageTest.java b/rsx-server-core/src/test/java/net/rustnotmc/server/combat/DamageTest.java new file mode 100644 index 0000000..87054e9 --- /dev/null +++ b/rsx-server-core/src/test/java/net/rustnotmc/server/combat/DamageTest.java @@ -0,0 +1,173 @@ +package net.rustnotmc.server.combat; + +import net.rustnotmc.protocol.Hitbox; +import net.rustnotmc.protocol.ItemRegistry; +import net.rustnotmc.protocol.ItemStack; +import net.rustnotmc.protocol.ItemType; +import net.rustnotmc.server.item.Inventory; + +/** + * Tests how much a hit hurts. + * + * The rules are the ones of the original game: the head is worth twice the + * body, the legs a little less, and a piece of clothing only takes a part of + * the harm away where it covers the body. + */ +public final class DamageTest { + + private static int checks; + private static int failed; + private static final java.util.List failures = new java.util.ArrayList(); + + public static void main(String[] args) { + run("a hit on the head is worth more", new Throwing() { + public void go() { testZones(); } + }); + run("the multipliers are the ones of the original", new Throwing() { + public void go() { testMultipliers(); } + }); + run("the clothing only helps where it covers", new Throwing() { + public void go() { testProtection(); } + }); + run("the clothing is worn in seven places", new Throwing() { + public void go() { testSlots(); } + }); + run("the clothes come out of the remake's table", new Throwing() { + public void go() { testTable(); } + }); + + System.out.println(); + for (int i = 0; i < failures.size(); i++) { + System.out.println(" FAIL " + failures.get(i)); + } + System.out.println(); + System.out.println("checks: " + checks + ", failed: " + failed); + if (failed != 0) { + System.out.println("FAILED"); + System.exit(1); + } + System.out.println("OK"); + } + + private interface Throwing { + void go() throws Exception; + } + + private static void run(String name, Throwing body) { + checks++; + int before = failed; + try { + body.go(); + } 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); + } + } + + private static void near(Object what, double expected, double actual) { + if (Math.abs(expected - actual) > 0.0001D) { + failed++; + failures.add(what + ": expected " + expected + " but got " + actual); + } + } + + private static void testZones() { + // a player of 1.8 blocks: the head is the top 0.4, the legs the bottom + eq("a hit on the top of the head", Hitbox.PART_HEAD, + Damage.zoneOf(1.75D, 0.0D, 1.8D)); + eq("a hit on the face", Hitbox.PART_HEAD, + Damage.zoneOf(1.45D, 0.0D, 1.8D)); + eq("a hit on the chest", Hitbox.PART_BODY, + Damage.zoneOf(1.0D, 0.0D, 1.8D)); + eq("a hit on the belly", Hitbox.PART_BODY, + Damage.zoneOf(0.5D, 0.0D, 1.8D)); + eq("a hit on the legs", Hitbox.PART_LEGS, + Damage.zoneOf(0.3D, 0.0D, 1.8D)); + eq("a hit below the feet", Hitbox.PART_LEGS, + Damage.zoneOf(-1.0D, 0.0D, 1.8D)); + } + + private static void testMultipliers() { + near("the head", 2.0D, Damage.multiplier(Hitbox.PART_HEAD)); + near("the body", 1.0D, Damage.multiplier(Hitbox.PART_BODY)); + near("the legs", 0.75D, Damage.multiplier(Hitbox.PART_LEGS)); + } + + private static void testProtection() { + // a mask covers the head and takes away half of a bullet + ItemType mask = ItemRegistry.require(ItemRegistry.METALFACEMASK); + yes("the mask is a piece of clothing", mask.armorSlot == ItemType.ARMOR_HEAD); + yes("the mask covers the head", Damage.covers(mask, Hitbox.PART_HEAD)); + yes("the mask does not cover the body", !Damage.covers(mask, Hitbox.PART_BODY)); + + Inventory inventory = new Inventory(); + inventory.setArmor(mask.armorSlot - 1, mask.armorLayer, ItemStack.of(mask.id, 1)); + near("a bullet in the head is half taken", 0.5D, + Damage.protection(inventory.armor(), Hitbox.PART_HEAD, + ItemType.HARM_PROJECTILE)); + near("a bullet in the body is not taken", 0.0D, + Damage.protection(inventory.armor(), Hitbox.PART_BODY, + ItemType.HARM_PROJECTILE)); + near("and a melee hit in the head is mostly taken", 0.7D, + Damage.protection(inventory.armor(), Hitbox.PART_HEAD, + ItemType.HARM_MELEE)); + } + + private static void testSlots() { + Inventory inventory = new Inventory(); + eq("seven places", Integer.valueOf(7), + Integer.valueOf(inventory.armor().length)); + eq("two layers each", Integer.valueOf(2), + Integer.valueOf(inventory.armor()[0].length)); + + ItemType helmet = ItemRegistry.require(ItemRegistry.BUCKETHELMET); + ItemStack was = inventory.wear(helmet.id); + yes("nothing was in the way", was == null); + eq("the helmet is on the head", Integer.valueOf(helmet.id), + Integer.valueOf(inventory.armor(0, 0).item)); + + ItemType jacket = ItemRegistry.require(ItemRegistry.METALCHEST); + inventory.wear(jacket.id); + eq("the chest armour is over the clothes", Integer.valueOf(jacket.id), + Integer.valueOf(inventory.armor(2, 1).item)); + eq("and the clothes stay under", Integer.valueOf(0), + Integer.valueOf(inventory.armor(2, 0).item)); + } + + private static void testTable() { + // the numbers of the clothes come from the table of the remake + ItemType mask = ItemRegistry.require(ItemRegistry.METALFACEMASK); + eq("the mask takes away fifty of a bullet", Integer.valueOf(50), + Integer.valueOf(mask.protection[ItemType.HARM_PROJECTILE])); + eq("and seventy of a blow", Integer.valueOf(70), + Integer.valueOf(mask.protection[ItemType.HARM_MELEE])); + + ItemType suit = ItemRegistry.require(ItemRegistry.HAZMATSUIT); + eq("the hazmat suit is a whole body", Integer.valueOf(ItemType.ARMOR_FULL_BODY), + Integer.valueOf(suit.armorSlot)); + yes("it covers everything", Damage.covers(suit, Hitbox.PART_HEAD) + && Damage.covers(suit, Hitbox.PART_BODY) + && Damage.covers(suit, Hitbox.PART_LEGS)); + } +} diff --git a/tools/extract-items.py b/tools/extract-items.py index 2eecf58..93072da 100644 --- a/tools/extract-items.py +++ b/tools/extract-items.py @@ -28,6 +28,15 @@ LANG = ROOT / "assets" / "rustex" / "legacy" / "minecraft" / "rustex_lang" / "en OUT_CSV = ROOT / "rsx-protocol" / "src" / "main" / "resources" / "items" / "items.csv" OUT_TEXTS = ROOT / "rsx-protocol" / "src" / "main" / "resources" / "items" / "item-texts.json" +# The slots of clothing, as the remake names them, and our seven places: +# the head, the face, the chest, the legs, the hands, the feet and the whole +# body. The chest and the legs have two layers. +SLOT_NAMES = { + "helmet": "1", "hat": "2", "plate": "3", "jacket": "3", + "pants": "4", "kilt": "4", "gloves": "5", "boots": "6", "suit": "7", +} +LAYER_NAMES = {"plate": "0", "jacket": "1", "pants": "0", "kilt": "1"} + # The columns of the table, in the order they are written. COLUMNS = [ "rid", "name", "category", "material", "nid", @@ -242,6 +251,30 @@ def parse_lang(text: str): return out +def read_armor(records): + """The clothing of every item: the slot, the layer and what it covers.""" + out = {} + for rec in records: + m = re.search(r'rid:"([^"]+)"', rec) + s = re.search(r'armorslot\.([a-z_]+):1b', rec) + if not (m and s): + continue + slot = SLOT_NAMES.get(s.group(1)) + if slot is None: + continue + layer = LAYER_NAMES.get(s.group(1), "0") + zones = 0 + if "dorend.head:1b" in rec: + zones |= 1 + if ("dorend.body:1b" in rec or "dorend.left_arm:1b" in rec + or "dorend.right_arm:1b" in rec): + zones |= 2 + if "dorend.left_leg:1b" in rec or "dorend.right_leg:1b" in rec: + zones |= 4 + out[m.group(1)] = (slot, layer, str(zones)) + return out + + def main() -> int: if not STACKS.is_file(): print("нет stacks.json:", STACKS) @@ -268,10 +301,21 @@ def main() -> int: # What the table has to tell us about the weapons. guns = [i for i in items if i.get("gun")] print("огнестрела в таблице:", len(guns)) - for gun in guns: - print(" %-22s id=%-3s магазин=%-3s модель=%s" - % (gun["rid"], gun.get("weapon_id", "?"), gun.get("ammo", "?"), - gun.get("model", "-"))) + + # and the clothing: the slot it goes in, the layer and what it covers + armor = read_armor(STACKS.read_text(encoding="utf-8", errors="replace").split("\n")) + for item in items: + slot, layer, zones = armor.get(item["rid"], ("", "", "")) + item["armor_slot"] = slot + item["armor_layer"] = layer + item["armor_zones"] = zones + columns = COLUMNS + ["armor_layer", "armor_zones"] + with OUT_CSV.open("w", encoding="utf-8", newline="") as handle: + writer = csv.DictWriter(handle, fieldnames=columns, extrasaction="ignore") + writer.writeheader() + for item in items: + writer.writerow({key: item.get(key, "") for key in columns}) + print("с одеждой:", sum(1 for i in items if i.get("armor_slot"))) return 0