PRESSURE for pneumatic weapons

Hello, Just got a question/idea. How hard it would be to code PRESSURE device working similarly to UPS?
For air guns, like when you have some gun which use UPS_drain, to give air guns AIR_drain? So you just give your pneumatic bolter mod to accessories which will drain AIR from some tank, like paintball guns do, and make loading of those guns quickier. With penalty being need to charge pressure tank.
And why is Vortex bolter using vortex stone as medium weaker than crank powered one?

Another idea, we have those nice solar backpacks, what about other sorts of power backpacks? Reactor CBM is no more, so what about we make it into the same backpack we moved the Solars CBM? It will be almost same as wearable UPS but able to connect to same port as solar backpack. With potential to make another ones? Gasoline backpack? Diesel backpack? You name it.

Adding pressure devices would be moderately complicated. You’d be digging into the guts of item.cpp and itype.cpp, and those aren’t the friendliest bits of code in the codebase. But it wouldn’t be impossible, just challenging.
Start by cloning the repository and browsing the code.


Call the ‘pressure device’ by its name - You want an air tank, something under pressure like for divers, and a mechanical or electrical pump of sorts to refill empty tanks.
Couldn’t you take the hand-crank charger as a base for a mechanical pump, add the air tanks as a magazine and refill them using the pump? The pneumatic weapons then just need to check if there’s a filled air tank, similar to the way UPS-weapons check, or am I looking at it the wrong way?


Now to your question about the Reactor/Diesel/Gas Backpack.
I…don’t see that happening.
In order to make a solar backpack, you take a solar panel (14kg ingame, average ones nowadays seem to clock in at around 18kg), take off most of the casing and unnecessary metal (byproducts: sheet metal + scrap) and basically shove everything into a backpack, which then, with most of the casing gone, still has a weight of 7,5kg.
You can’t do that with the other options you named though.
For the ‘Reactor backpack’ you would need a minireactor, which weighs 27kg You can’t take of any casings or plating though, or you’d die due to radiation, so the backpack would clock in at nearly 30kg after adding some more wires and power converters and so on. Plus, Plutonium is pretty heavy too.

The Gas/Diesel pack would most likely consist of an Engine strapped to your back, taking in fuel and putting out energy via an alternator? If that’s the case you’d look at 20kg for the engine (1 cylinder engine) + the alternator + a gas tank filled with gas + the power converter. Again, you’d end up at around 30kg of weight on your back.

Let’s also mention that both Minireactor and any kind of engine would get pretty hot after a while. Hell, you could cook on an engine block after it was used for a while. I’m pretty sure you do NOT want something like that in a fabric bag on your back, the bag and you could catch fire, and you would feel extremely uncomfortable.

Welp, better start it easy.
So to make almost full copy of UPS system, with just difference in medium (electricity -> air), all i need to change (add) is in item.cpp and itype.cpp?
Better start learning to code in C++. (pointers and all that -> stuff, as i am used to industrial PLCs coding, way different)

Back to backpack thing.
Recently, there was added that new flashy gasoline power cell CBM. For someone who dont want to install that to ones body, but still find it RP interesting, way to install it into backpack instead is pretty interesting to me. Same goes with that minireactor CBM we had earlier. Did it weigted 27kg back then? And do i look like i want to have same reactor we use in car on my back? What for? I want to dissect one of the labs cyborgs and put his micro reactor as my reserve power source. Coz i like that idea of tinkering you have in cata. OxiHydrogen power cells are thing too. We can get hydrogen tanks from labs. Why not make it into power cell for our apliances. Not coz they are super OP, but even people today have fun making them at home for little fun projects. Hydrogen power cell CBM would even make more sense than gasoline CMB. With some machine making hydrogen from solar power + water combo in your base, albeit rly slow to make it game friendly. If i only knew better C++ to add some functions. Almost everything else would be just JSON changes then, just for RP sake.

Almost the same idea i had. 3 tiers of charging for start. One like hand-crank, second with micro electro motor and plutonium cells, third use vortex stone. Diferent charge ratios, loudness and volume/weight numbers. 2 tanks, one small like canteen on leg, one bigger on back. you could even make CBM for providing fake air tank if thats possible.

Coz now, pneu weapons are not even close to bows anymore. Reloading one bolt for whole minute? Eight times in row? I get you need to spend 80% of that charging the weapon, but still. Why we should even bother with that? Tihar is even badder in this. Still realoading by one marble at time? 15 times in row? More than minute per one? I would have muscles like rambo by the end of the third day using one of those weapons. Having to choose betwen them and bows IRL, what would you go for? Even if you love them as hardcore Metro enthusiast? Yea, i know i can just change them in like 30 sec in ranged.json, but i like the idea of progress. I want to find way to make them better from RP perspective after testing them on some zeds and trying to improve their performance. And contribute to comunity a bit.

I would suggest to start with the advanced UPS (which IIRC is powered with plutonium bars) and make it wearable. Maybe you could craft a wearable advanced UPS with a shoulder strap so it goes to the torso.

In fact, I would make it a bit heavier, as you will want to add armor to the UPS to avoid zombies destroying it :slight_smile:

Yea, some mod i use made UPS wearable, so i am planing to use that as base. Practicaly copy whole UPS code, but make it use air instead of electricity.
Now i only need to find all the places where i need to make change. First two places are those item.cpp and itype.cpp . Any idea where else i need to look? Probably tool.json to add air tank. Flags too?

The historical Girandoni air rifle took 1,500 strokes of a hand pump to recharge its air reservoir. Modern technology makes for better hand pumps and better air tanks than what people could make in 1790, but it’s still a lot of effort to charge something up above 100 PSI.

Poking through the code for ups:

$ git grep ups_charges src/
src/bionics.cpp:213:        int ups_charges = charges_of( "UPS" );
src/bionics.cpp:217:            ammo_count = std::min( ammo_count, ups_charges / ups_drain );
src/item.cpp:8769:        draincount += type->gun->ups_charges;
src/item.cpp:8771:            draincount += mod->type->gunmod->ups_charges;
src/item_factory.cpp:1455:    assign( jo, "ups_charges", slot.ups_charges, strict, 0 );
src/item_factory.cpp:1834:    assign( jo, "ups_charges", slot.ups_charges );
src/itype.h:486:    int ups_charges = 0;
src/itype.h:576:    int ups_charges = 0;
src/npcmove.cpp:1254:    int ups_charges = charges_of( "UPS" );
src/npcmove.cpp:1271:                   m->get_gun_ups_drain() > ups_charges ||
src/npcmove.cpp:3093:    const int ups_charges = charges_of( "UPS" );
src/npcmove.cpp:3096:    [this, &best, &best_value, ups_charges, can_use_gun, use_silent]( const item & it ) {
src/npcmove.cpp:3105:                ammo_count = std::min( ammo_count, ups_charges / ups_drain );

and then reviewing those files, it turns out that ups drain is encapsulated in get_gun_drain_ups:

$ git grep get_gun_ups_drain src/
src/avatar_action.cpp:660:        if( gun->get_gun_ups_drain() > 0 ) {
src/avatar_action.cpp:661:            const int ups_drain = gun->get_gun_ups_drain();
src/bionics.cpp:215:        int ups_drain = weapon.get_gun_ups_drain();
src/character.cpp:3169:    int ups_drain = gun.get_gun_ups_drain();
src/item.cpp:1548:        if( mod->get_gun_ups_drain() && parts->test( iteminfo_parts::AMMO_UPSCOST ) ) {
src/item.cpp:1550:                               "Uses <stat>%i</stat> charges of UPS per shot", mod->get_gun_ups_drain() ),
src/item.cpp:1551:                               mod->get_gun_ups_drain() ) );
src/item.cpp:8765:int item::get_gun_ups_drain() const
src/item.h:1905:        int get_gun_ups_drain() const;
src/npcmove.cpp:1271:                   m->get_gun_ups_drain() > ups_charges ||
src/npcmove.cpp:3103:            int ups_drain = it.get_gun_ups_drain();
src/ranged.cpp:338:    if( !gun.has_flag( "VEHICLE" ) && gun.get_gun_ups_drain() > 0 ) {
src/ranged.cpp:339:        shots = std::min( shots, static_cast<int>( charges_of( "UPS" ) / gun.get_gun_ups_drain() ) );
src/ranged.cpp:412:            use_charges( "UPS", gun.get_gun_ups_drain() );
src/turret.cpp:234:    auto ups = part->base.get_gun_ups_drain() * part->base.gun_current_mode().qty;
src/turret.cpp:274:    veh->drain( fuel_type_battery, mode->get_gun_ups_drain() * shots );

So that’s the basic structure you’re going to want to modify. use_charges() is already generic, so I think that’s as far down the rabbit hole as you need to go.

My recommendation would be to make get_gun_ups_drain() generic, something like get_gun_other_drain( const itype_id &what ), and add replace int ups_charges with std::set<std::pair<itype_id, int>> other_charges. Then add a function that returns other_charges and change all the logic that drains UPS charges to drain the charge for each itype_id in other_charges.

In JSON, you’d replace "ups_charges": 9 with "other_charges": { "UPS": 9 } for existing items, but new items could have stuff like "other_charges": { "UPS": 9, "pressurized_air": 10, "blood_human": 1, "tortured_soul": 1 } for a hypothetical weapon that ran off UPS, pressurized air, human blood, and tortured souls, or more mundanely "other_charges": { "pressurized_air": 10 } for a pneumatic bolt driver.

Actually, I just realized those are instructions for making pneumatic guns that fire from generic pressurized tanks located somewhere in your gear.

If you want guns that fire shots from two magazines, both carried by the gun, you’re going to have to modify ammo_current() and ammo_consume() and associated functions. The process for figuring that out is similar: git grep for the functions in the src directory, read the code, and continue grepping as necessary.

You’d want to add a function like int ammo_type_count() to item:: which returns the number of ammo types that a gun consumes for each projectile, then loop through ammo_current() or ammo_consume() for each ammo type. Most guns would only have 1 ammo_type_count(), but some could have more.

1 Like

That was really helpful. I especialy love that part with hypothetical weapon. Would be lovely for magiclysm in biomancer or technomancer class. I just realized that would take a lot of effort, but why not, i suppose that would really add a lot of content to the game, so in some distant or near future, i am rly gonna look into this stuff. I would love to have it in cata, if it wont impede generals ideas you lot have for way game is intended to go. As we have quite impresive technology in cata timeline, i suppose, it wont be rly that imposible to have better pumps to do the job. Handcracked would took a lot of time, but once we got into electropumps and vortex stones, or magic as it is thing now, possibilities would be great. Not rly locked only into air pressure as you recomended making charges more generic. I just hope my programing skills would hold into my hopes for this. And that i am not annoying with all my questions.

1 Like

Mostly sounds like this would be handy for coding more realistic paint-ball guns. :slight_smile:

Questions are fine if they lead to contributions in the future =)

And understand that I don’t know anything or even most things, so I am really the one-eyed man leading the blind here at best.

A few people have proposed this in the very recent past, (and two have implemented it), but those implementations have been rejected in favor of this solution.

OUCH, the whole thing of setting account for github, and the whole process of making it to work on my pc was tedious, even with guide. Not that it wasnt helpfull enough (well, some steps were ignored in that guide, like; first of all, download git program from another site if you want to actualy use this guide), but that could be like well known knowledge i just didnt had at that time. Gonna jump into trial-error first steps in modifying source code now. Any idea how the funtcion to return other_charges should look like?

something close to:

std::set<std::pair<itype_id, int>> item::get_other_charges()
    return other_charges;

it’s setting up other_charges in item that is tricky.

that was all? i feared i forgot something, coz it looked too quick and easy. I will look into it more tomorow in work. thx for quick answer