Skip to content

Commit

Permalink
Directly Import Gunsmith Pouch
Browse files Browse the repository at this point in the history
Just to directly pull it in, we can refactor the files later if so desired.  The Readme & Build scripts have all been updated to reflect the new additions

Credits to Skelegant for the Pouch sprite, and Mohl/Caligari87 for the Ammo/Gunsmith Pouch code.
  • Loading branch information
UndeadZeratul committed Jun 22, 2023
1 parent 992aec4 commit 656edbf
Show file tree
Hide file tree
Showing 18 changed files with 308 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: build PK3
uses: montudor/action-zip@v1
with:
args: zip -r "universal-reloader-${{ github.ref_name }}.pk3" . -i sprites/* zscript/* CREDITS.* LICENSE MAPINFO.* README.* TEXTURES.* WTBLKLST.* ZSCRIPT.*
args: zip -r "universal-reloader-${{ github.ref_name }}.pk3" . -i sprites/* zscript/* CVARINFO.* KEYCONF.* LANGUAGE.* LICENSE MAPINFO.* MENUDEF README.* TEXTURES.* WTBLKLST.* ZSCRIPT.*
- name: Release PK3
uses: softprops/[email protected]
with:
Expand Down
5 changes: 0 additions & 5 deletions CREDITS.txt

This file was deleted.

2 changes: 1 addition & 1 deletion MAPINFO.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
gameinfo
{
AddEventHandlers = "URLSpawnHandler"
AddEventHandlers = "URLSpawnHandler", "GunsmithPouchSpawner"
}
34 changes: 28 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,30 @@
### Important
---
- This mod requires [AceCoreLib](https://github.com/HDest-Community/AceCoreLib).
# Universal Reloader
_This mod requires [AceCoreLib](https://github.com/HDest-Community/AceCoreLib)_

### Notes
---
- Universal reloaders can only be found in backpacks. They are also sold by the [Merchant](https://github.com/HDest-Community/Merchant) if you have that loaded.
![thumbnail](./screenshots/thumbnail.png)

This mod adds a configurale device that can assemble and disassemble most rounds provided by both Vanilla HDest as well as those provided by [HDBulletLib-Recasted](https://github.com/HDest-Community/HDBulletLib-Recasted).

### Universal Reloader
- Loadout code is `url`.
- Universal reloaders can only be found in backpacks. They are also sold by the [Merchant](https://github.com/HDest-Community/Merchant) if you have that loaded.

![example-recipe](./screenshots/example-recipe.png)
![options-menu](./screenshots/options-menu.png)
![recipe-options](./screenshots/recipe-options.png)

### Gunsmith Pouch
- Loadout code is `gsp`.
- Gunsmith Pouches can be found in the wild. They will hold the various crafting materials created by disassembling ammunition.

![gunsmith-pouch](./screenshots/gunsmith-pouch-gui.png)

## Credits
#### Code
- Universal Reloader: Accensus
- Gunsmith Pouch: Mohl
- _Based off of the Ammo Pouch by Caligari87_

#### Sprites
- Universal Reloader: Mor'ladim
- Gunsmith Pouch: Skelegant
22 changes: 22 additions & 0 deletions TEXTURES.gunsmithPouch
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Texture definitions generated by SLADE3
// on Wed Jun 21 20:26:39 2023

Sprite "GSPPB0", 22, 14
{
XScale 0.870
YScale 1.200
Offset 11, 14
Patch "GSPPA0", 0, 0
{
Rotate 180
}
}

Sprite "GSPPC0", 22, 14
{
Offset 11, 14
Patch "GSPPA0", 0, 0
Patch "STASQGR", 15, 0
}

// End of texture definitions
File renamed without changes.
6 changes: 6 additions & 0 deletions ZSCRIPT.zsc
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
version "4.10"

#include "zscript/gunsmithpouch/gunsmithpouch.zsc"
#include "zscript/gunsmithpouch/gunsmithpouch_bulk.zsc"
#include "zscript/gunsmithpouch/gunsmithpouch_hud.zsc"
#include "zscript/gunsmithpouch/gunsmithpouch_itemstorage.zsc"
#include "zscript/gunsmithpouch/gunsmithpouch_spawning.zsc"

#include "zscript/universalreloader/spawnHandler.zsc"

#include "zscript/universalreloader/items/universalReloader.zsc"
Expand Down
Binary file added screenshots/example-recipe.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/gunsmith-pouch-gui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/options-menu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/recipe-options.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added screenshots/thumbnail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added sprites/GSPPA0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions zscript/gunsmithpouch/gunsmithpouch.zsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const HDLD_GSPouch = "gsp";

//==================================================
// Base Definition
//==================================================
class GunsmithPouch : HDBackpack {
default {
tag "Gunsmith's Pouch";
HDBackpack.MaxCapacity 200;
Inventory.Icon "GSPPA0";
Inventory.PickupMessage "Picked up a gunsmith's pouch, for all your gunpowder!";
scale 0.6;
hdweapon.wornlayer 0;
hdweapon.refid HDLD_GSPouch;
}

override string, double GetPickupSprite() { return "GSPPA0", 1.0; }

override void BeginPlay() {
super.BeginPlay();
Storage = new('GSP_ItemStorage');
weaponstatus[GSP_AMOUNT] = max(weaponstatus[GSP_AMOUNT], 1);
UpdateCapacity();
}

override void PostBeginPlay() {
super.PostBeginPlay();
weaponstatus[GSP_AMOUNT] = max(weaponstatus[GSP_AMOUNT], 1);
UpdateCapacity();
}

// Thanks Accensus for figuring out multiple pouches in loadout codes!
override void LoadoutConfigure(string input) {
int amt = input.ToInt();
if (amt > 0)
{
weaponstatus[GSP_AMOUNT] = amt;
UpdateCapacity();
}
super.LoadoutConfigure(input);
}

States {
Spawn:
GSPP ABC -1 NoDelay
{
if (invoker.Storage.TotalBulk ~== 0)
{
frame = 1;
}
else if (target)
{
translation = target.translation;
frame = 2;
}
invoker.bNO_AUTO_SWITCH = false;
}
Stop;
User3:
#### # 0 A_MagManager("");
goto Ready;
}

enum GSPouchSlots {
GSP_AMOUNT
}
}
53 changes: 53 additions & 0 deletions zscript/gunsmithpouch/gunsmithpouch_bulk.zsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//==================================================
// Bulk and Multiple Pouches
//==================================================
extend class GunsmithPouch {
override double WeaponBulk() {
int calcamount = min(max(weaponstatus[GSP_AMOUNT], 1), 5);
double reductionfactor = 0.15 + min(0.05 * calcamount, 0.5);
double basebulk = 35* max(weaponstatus[GSP_AMOUNT], 1);
return max((Storage ? Storage.TotalBulk * reductionfactor : 0), basebulk);
}

override void UpdateCapacity() {
MaxCapacity = default.MaxCapacity / max(hd_encumbrance, 0.01);
Storage.MaxBulk = MaxCapacity * max(weaponstatus[GSP_AMOUNT], 1);
}

override void actualpickup(actor other,bool silent) {
GunsmithPouch HeldGSP=GunsmithPouch(other.findinventory("GunsmithPouch"));
if (HeldGSP) {
HeldGSP.weaponstatus[GSP_AMOUNT]++;
HeldGSP.UpdateCapacity();
for (int i = 0; i < Storage.Items.Size(); i++) {
StorageItem MoveItem = Storage.Items[i];
int AmountToMove = MoveItem.Amounts.Size() > 0 ? MoveItem.Amounts[0] : 0;
HeldGSP.Storage.AddAmount(MoveItem.ItemClass, AmountToMove);
}
self.destroy();
return;
}
super.actualpickup(other, silent);
}

override inventory CreateTossable(int amt) {
bool DoSplit = (weaponstatus[GSP_AMOUNT] > 1);
amount = weaponstatus[GSP_AMOUNT]; // Hack to satisfy CreateTossable expectations
GunsmithPouch DroppedGSP = GunsmithPouch(super.CreateTossable(amt));
DroppedGSP.weaponstatus[GSP_AMOUNT] = 1;
DroppedGSP.UpdateCapacity();
if (DoSplit) {
weaponstatus[GSP_AMOUNT]--;
StorageItem SelItem = Storage.GetSelectedItem();
if (!SelItem || Storage.Items.Size() <= 0) { return DroppedGSP;}
int AmountInPouch = SelItem.Amounts.Size() > 0 ? SelItem.Amounts[0] : 0;
double UnitBulk = HDPickup(getdefaultbytype(SelItem.ItemClass)).bulk * hdmath.getencumbrancemult();
UnitBulk = max(UnitBulk, 0.01);
int AmountToMove = int((DroppedGSP.Storage.MaxBulk - DroppedGSP.Storage.TotalBulk) / UnitBulk);
AmountToMove = min(AmountToMove, AmountInPouch);
DroppedGSP.Storage.AddAmount(SelItem.ItemClass, AmountToMove);
Storage.RemoveItem(SelItem, null, null, AmountToMove);
}
return DroppedGSP;
}
}
59 changes: 59 additions & 0 deletions zscript/gunsmithpouch/gunsmithpouch_hud.zsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//============================================
// HUD stuff, mostly copypasta from HDBackpack
//============================================
extend class GunsmithPouch {
override void DrawHUDStuff(HDStatusBar sb, HDWeapon hdw, HDPlayerPawn hpl)
{
int BaseOffset = -80;

sb.DrawString(sb.pSmallFont, "\c[DarkBrown][] [] [] \c[DarkGreen]Gunsmith Pouch\c[DarkBrown] [] [] []", (0, BaseOffset), sb.DI_SCREEN_CENTER | sb.DI_TEXT_ALIGN_CENTER);
string BulkString = "Total Bulk: \cf"..int(Storage.TotalBulk).."\c-";
if (weaponstatus[GSP_AMOUNT] > 1) { BulkString = BulkString.." --- Pouches: \cf"..weaponstatus[GSP_AMOUNT].."\c-"; }
sb.DrawString(sb.pSmallFont, BulkString, (0, BaseOffset + 10), sb.DI_SCREEN_CENTER | sb.DI_TEXT_ALIGN_CENTER);

int ItemCount = Storage.Items.Size();

if (ItemCount == 0)
{
sb.DrawString(sb.pSmallFont, "Empty.", (0, BaseOffset + 30), sb.DI_SCREEN_CENTER | sb.DI_TEXT_ALIGN_CENTER, Font.CR_DARKGRAY);
return;
}

StorageItem SelItem = Storage.GetSelectedItem();
if (!SelItem)
{
return;
}

for (int i = 0; i < (ItemCount > 1 ? 5 : 1); ++i)
{
int RealIndex = (Storage.SelItemIndex + (i - 2)) % ItemCount;
if (RealIndex < 0)
{
RealIndex = ItemCount - abs(RealIndex);
}

vector2 Offset = ItemCount > 1 ? (-100, 8) : (0, 0);
switch (i)
{
case 1: Offset = (-50, 4); break;
case 2: Offset = (0, 0); break;
case 3: Offset = (50, 4); break;
case 4: Offset = (100, 8); break;
}

StorageItem CurItem = Storage.Items[RealIndex];
bool CenterItem = Offset ~== (0, 0);
sb.DrawImage(CurItem.Icons[0], (Offset.x, BaseOffset + 40 + Offset.y), sb.DI_SCREEN_CENTER | sb.DI_ITEM_CENTER, CenterItem && !CurItem.HaveNone() ? 1.0 : 0.6, CenterItem ? (50, 30) : (30, 20), CenterItem ? (4.0, 4.0) : (3.0, 3.0));
}

sb.DrawString(sb.pSmallFont, SelItem.NiceName, (0, BaseOffset + 60), sb.DI_SCREEN_CENTER | sb.DI_TEXT_ALIGN_CENTER, Font.CR_FIRE);

int AmountInBackpack = SelItem.Amounts.Size() > 0 ? SelItem.Amounts[0] : 0;
sb.DrawString(sb.pSmallFont, "In pouch: "..sb.FormatNumber(AmountInBackpack, 1, 6), (0, BaseOffset + 70), sb.DI_SCREEN_CENTER | sb.DI_TEXT_ALIGN_CENTER, AmountInBackpack > 0 ? Font.CR_BROWN : Font.CR_DARKBROWN);

int AmountOnPerson = GetAmountOnPerson(hpl.FindInventory(SelItem.ItemClass));
sb.DrawString(sb.pSmallFont, "On person: "..sb.FormatNumber(AmountOnPerson, 1, 6), (0, BaseOffset + 78), sb.DI_SCREEN_CENTER | sb.DI_TEXT_ALIGN_CENTER, AmountOnPerson > 0 ? Font.CR_WHITE : Font.CR_DARKGRAY);

}
}
24 changes: 24 additions & 0 deletions zscript/gunsmithpouch/gunsmithpouch_itemstorage.zsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//==================================================
// Item Storage Definitions
// Expand this later with UASINFO?
//==================================================
class GSP_ItemStorage : ItemStorage {
override int CheckConditions(Inventory item, class<Inventory> cls) {
bool valid = (
(item && (item is 'HDRel_CraftingMaterial')) ||
(cls && (cls is 'HDRel_CraftingMaterial'))
);

if (!valid) { return IType_Invalid; }
return super.CheckConditions(item,cls);
}

override int GetOperationSpeed(class<Inventory> item, int operation) {
switch (clamp(operation, 0, 2)) {
case 0: return 0; break; //extract
case 1: return 0; break; //pocket
case 2: return 0; break; //insert
}
return 10;
}
}
47 changes: 47 additions & 0 deletions zscript/gunsmithpouch/gunsmithpouch_spawning.zsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//============================================
// Spawning
//============================================
class WildGSP : IdleDummy {
override void postbeginplay() {
super.postbeginplay();
let SpawnedGSP=GunsmithPouch(spawn("GunsmithPouch",pos,ALLOW_REPLACE));
SpawnedGSP.vel = vel;
SpawnedGSP.RandomContents();
self.destroy();
}
}

class GunsmithPouchSpawner : EventHandler {
int alreadyspawned;
int failspawn;

override void WorldThingSpawned(WorldEvent e) {
if(level.maptime > 1) { return; }
if(!e.Thing) { return; }
if(e.Thing is "Inventory" && Inventory(e.Thing).Owner) { return; }

bool spawnable = (
e.Thing.GetClassName() == "HDAmBox" ||
e.Thing.GetClassName() == "DeadRifleman" ||
e.Thing.GetClassName() == "ReallyDeadRifleman");

int chance = 5 + (5 * failspawn) - (50 * alreadyspawned);
chance = clamp(chance, 0, 100);

if(spawnable) {
if (random(0, 100) <= chance) {
//console.printf("ammopouch spawn chance %i, success", chance);
let SpawnedPouch = Actor.Spawn('WildGSP', (e.Thing.pos.x, e.Thing.pos.y, e.Thing.pos.z + 5));
SpawnedPouch.vel.x += frandom(-2,2);
SpawnedPouch.vel.y += frandom[spawnstuff](-2,2);
SpawnedPouch.vel.z += frandom[spawnstuff](1,2);
alreadyspawned++;
if (e.Thing.GetClassName() == "HDAmBox") { e.Thing.destroy(); }
}
else {
//console.printf("ammopouch spawn chance %i, fail", chance);
failspawn++;
}
}
}
}

0 comments on commit 656edbf

Please sign in to comment.