Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 5 6 [7] 8 9 ... 12

Author Topic: [44.12] Musket-Mod v0.5c: Experimental Wall Breaching  (Read 41356 times)

Splint

  • Bay Watcher
  • War is a valid form of diplomacy.
    • View Profile
Re: [44.12] Musket-Mod v0.4h
« Reply #90 on: August 29, 2018, 06:25:31 am »

My concern is just on how well they do.

Marksdwarves for me in vanilla have just never been worth the material investment (they piss through ammo at a constant rate, necessitating dedicating at least two or three people just to making ammo for them with just a single full squad,) and lacking killing power, since unless a major artery or the brain is hit, it usually takes forever to kill anything with them. Hell, more than half the time hunters can't kill anything besides small game reliably.

These weapons obviously (and understandably) have an even greater material investment, so I'm a bit leery. But I'll give it a shot.

zaporozhets

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4h
« Reply #91 on: August 29, 2018, 07:45:00 am »

My concern is just on how well they do.

Marksdwarves for me in vanilla have just never been worth the material investment (they piss through ammo at a constant rate, necessitating dedicating at least two or three people just to making ammo for them with just a single full squad,) and lacking killing power, since unless a major artery or the brain is hit, it usually takes forever to kill anything with them. Hell, more than half the time hunters can't kill anything besides small game reliably.

These weapons obviously (and understandably) have an even greater material investment, so I'm a bit leery. But I'll give it a shot.

I didn't want them to be golden guns, but someone did complain they were too weak early on in development so I doubled the power and I've not heard any complaints since.
I'd have a play with them in arena mode on a fresh install you can just delete before you decide. Do let me know how you find them, it'd be a great help to get your opinion.
Logged

Grimlocke

  • Bay Watcher
  • *kobold noises*
    • View Profile
Re: [44.12] Musket-Mod v0.4f
« Reply #92 on: August 29, 2018, 11:59:48 am »

About the cannons, I've been considering using [PRESERVE_REAGENT] as well as making the barrel used to build the building a container tool item. All I'd have to do to make be 'loaded' is move reagents to the barrel 'container' until there are no empty barrels (relevant for organ guns), and when firing check for any containers with use_mode == 2 (item used as building item) and spew it out until there is no more left.

I actually considered the thing you suggested for indexing the custom workshop subtypes, but found it shouldn't even be needed. All I need to do when turning clockwise is have the workshop check 'Does my name end in _N, _E or _S? then add 1 to subtype' and 'else, substract 3 from subtype'. Basically the same thing you did except it doesn't check against its own subtype but against a string match in the name. Only problem with that is, I've not been able to read anything from the building raws from the building objects (which seem to be different data structures altogether). I'm probably missing something simple...

I might use that index code snippet at some point though, thanks :)

Also I hadn't considered masterwork announcement spam. Gah. Does it also announce masterwork if its an existing item changing quality later I wonder?

Edit: dfhack.items.moveToContainer isn't moving to container. No error output either. Is it picky about the sort of container used or does it not like me editing the container property in an existing item? I'll try adding some of the tool use tags and risk dwarves storing plump helmets in gun barrels.

Edit yet again: I recall you asking how to move items to the ground, item:moveToGround(cannon.centerx,cannon.centery,cannon.z) seems to do the trick.
« Last Edit: August 29, 2018, 02:41:32 pm by Grimlocke »
Logged
I make Grimlocke's History & Realism Mods. Its got poleaxes, sturdy joints and bloomeries. Now compatible with DF Revised!

zaporozhets

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4f
« Reply #93 on: August 29, 2018, 03:00:38 pm »

About the cannons, I've been considering using [PRESERVE_REAGENT] as well as making the barrel used to build the building a container tool item. All I'd have to do to make be 'loaded' is move reagents to the barrel 'container' until there are no empty barrels (relevant for organ guns), and when firing check for any containers with use_mode == 2 (item used as building item) and spew it out until there is no more left.

I like the idea of putting the stuff in the actual barrel, probably won't change it for this given it'd be functionally the same for a normal cannon but for an organ gun it makes tons of sense for being able to load different barrels.

I actually considered the thing you suggested for indexing the custom workshop subtypes, but found it shouldn't even be needed. All I need to do when turning clockwise is have the workshop check 'Does my name end in _N, _E or _S? then add 1 to subtype' and 'else, substract 3 from subtype'. Basically the same thing you did except it doesn't check against its own subtype but against a string match in the name. Only problem with that is, I've not been able to read anything from the building raws from the building objects (which seem to be different data structures altogether). I'm probably missing something simple...

I might use that index code snippet at some point though, thanks :)

Ah, that's a much better way. You mean something like:
Code: [Select]
local cannonDirection = string.sub(df.global.world.raws.buildings.all[cannon.custom_type].code, -2)
if job.reaction_name == "ROTATE_CANNON_R" then
if cannonDirection == "_N" or cannonDirection == "_E" or cannonDirection == "_S" then
cannon.custom_type = cannon.custom_type + 1
else
cannon.custom_type = cannon.custom_type - 3
end
else
if cannonDirection == "_E" or cannonDirection == "_S" or cannonDirection == "_W" then
cannon.custom_type = cannon.custom_type - 1
else
cannon.custom_type = cannon.custom_type + 3
end
end
right?

Also I hadn't considered masterwork announcement spam. Gah. Does it also announce masterwork if its an existing item changing quality later I wonder?

Edit: dfhack.items.moveToContainer isn't moving to container. No error output either. Is it picky about the sort of container used or does it not like me editing the container property in an existing item? I'll try adding some of the tool use tags and risk dwarves storing plump helmets in gun barrels.

I don't really know about either of these things, first one would be a good way of suppressing the announcement. Never done anything with containers but I can imagine it is picky, give me a progress update if you manage it. Can't see how I'd use it personally, but I'd be interested to know.
« Last Edit: August 29, 2018, 03:06:37 pm by zaporozhets »
Logged

thefriendlyhacker

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #94 on: August 30, 2018, 07:17:19 pm »

I have been playing around with something lately, and I have just gotten it to a basically functional point (although I will revisit it later and add/tweak a few things).  I figured that in the meantime you might like to have it for some double barrel muskets or something.
Code: [Select]
----changes the cooldown between each time a creature fires a projectile weapon----
--author thefriendlyhacker
--based on work by Roses, expwnent, zaporozhets and Putnam.

local usage = [====[

ranged/ranged-rof
===========================
This triggers when a unit fires a projectile, and changes the delay (in ticks) until the unit's
next attack.

The new delay is set according to the following formula:
    New Delay = Base Delay + Old Delay * Delay Multiplier
Base delay is set by -delayBase, and Delay Multiplier by -delayMult

For reference, dabbling firers have a normal delay of 80 ticks, legendary +5 firers 48 ticks, and legendary +100 firers 40 ticks.

Several arguments can be added to restrict a particular command to select weapons/ammo (see below)

A set of values can be passed through -delayBase and/or -delayMult.  When only one of the args is multi-value, the other is treated as an equal sized set of identical values.  If both are multi-value sets, they must be of equal length.

The script steps through the set of values when a unit fires a projectile weapon, and keeps track of
the unit's position in the set on a per command, per weapon basis. Beginning at the first
number in the set, the script iterates through the entire pair of sets, using each pair of numbers
to calculate the delay for a single firing event.  Effectively, this allows for variable delay
times.  This can simulate, for example, burst fire weapons, multi-barreled firearms, or autoloading
weapons with a reload time.

After a delay (calculated using -resetBase and -resetMult similar to the equation above), the position in a unit's firing delay set is reset to the first position.

Data does not persist across saves, which will mean that loading saves made in the middle of combat will influence that combat when using variable delays.  Outside of combat, this shouldn't matter.

Usage::
    -name str
        name of the command.  Not optional.
    -clear name (not implemented atm)
        unregisters a named command. If arg is used with no name, unregisters every command
    -reset name (not implemented atm)
        clears all persistant data associated with the named command. If used with no name, clears all data
    -reqProjType subtype or [ subtype1 subtype2 ... ]
        only runs command if the projectile is one of the appropriate subtypes
        example: ITEM_AMMO_BOLTS
    -reqWeaponType subtype or [ subtype1 subtype2 ... ]
        only runs command if the weapon is of one of the appropriate subtypes
        example: ITEM_WEAPON_CROSSBOW
    -reqProjMat mat or [ mat1 mat2 ... ]
        only runs command if the projectile is one of the appropriate material(s)
        examples: INORGANIC:IRON, CREATURE_MAT:DWARF:BRAIN
    -reqWeaponMat mat or [ mat1 mat2 ... ]
        only runs command if the weapon is one of the appropriate material(s)
        same format as -reqProjMat
    -timeBase nbr or [ nbr1 nbr2 ... ] (default 0)
    -timeMult nbr or [ nbr1 nbr2 ... ](default 0)
        timeBase and timeMult are used to set the time until the next attack
        at least one must be set, and the number can be negative or non-integer
        if they are both multi-element tables, they must be of equal length
        -timeBase is a flat number of ticks
        -timeMulti is a multiplier of the base firing delay of the unit
        see above for details
    -neverReset
        never resets position in a loop
    -resetBase nbr (default 0)
    -resetMult nbr (default 5)
      determines how long until a unit's position in the command's firing delay set is reset
      works similarly to timeBase and timeMult, see above for details
]====]
eventful = require 'plugins.eventful'
utils = require 'utils'

--holds individual commands as anon functions
rangedTriggers=rangedTriggers or {}

--3 dimension sparse table for command/creature/firing weapon combos,
--holds the position of a unit in a command's delay set, on a per weapon basis
rangedArrayPos=rangedArrayPos or {}

--
rangedResetTimeouts=rangedResetTimeouts or {}

eventful.enableEvent(eventful.eventType.UNLOAD,1)
eventful.onUnload.rangedTriggerModule = function()
 rangedTriggers = {}
 rangedArrayPos = {}
 rangedResetTimeouts = {}
end

function eventfulFunc(projectile)
  if projectile.distance_flown~=0 then return end
  for funcName,func in pairs(rangedTriggers) do
    if func(projectile,funcName) then return end
  end
 end
eventful.onProjItemCheckMovement.rangedTriggerModule = eventfulFunc

function getCommandFunc(reqProjMats,reqProjTypes,reqWeaponMats,reqWeaponTypes, timeBase, timeMult, resetBase, resetMult, neverReset)
  return function (proj,funcName)
    if not proj.firer then return false end
    local weapon=df.item.find(proj.bow_id)
   
    --dismembered limbs require this
   
    if not weapon then return false end

    --first off,checks to see if this conforms to the command requirements

    local found=false
    for _,mat in ipairs(reqProjMats) do
      if mat==dfhack.matinfo.decode(proj.item):getToken() then found=true end
    end
    if #reqProjMats>0 and not found then return false end
   
    found=false
    for _,mat in ipairs(reqWeaponMats) do
      if mat==dfhack.matinfo.decode(weapon):getToken() then found=true end
    end
    if #reqWeaponMats>0 and not found then return false end
   
    found=false
    if #reqProjTypes>0 and proj.item:getSubtype() ~= -1 then
      for _,itype in ipairs(reqProjTypes) do
        if  dfhack.items.getSubtypeDef(proj.item:getType(),proj.item:getSubtype()).id == itype then
          found=true
        end
      end
    end
    if #reqProjTypes>0 and not found then return false end
   
   
    found=false
    if #reqWeaponTypes>0 and weapon:getSubtype() ~= -1 then
      for _,itype in ipairs(reqWeaponTypes) do
        if  dfhack.items.getSubtypeDef(weapon:getType(),weapon:getSubtype()).id == itype then
          found=true
        end
      end
    end
    if #reqWeaponTypes>0 and not found then return false end
   
    --now, do internal stuff, initialize any rangedArrayPos data when necessary and set/reset the delay trigger 
    local oldThinkCounter=proj.firer.counters.think_counter
    if #timeBase>1 then
      if not rangedArrayPos[funcName][proj.firer.id] then rangedArrayPos[funcName][proj.firer.id]={} end
      if not rangedArrayPos[funcName][proj.firer.id][proj.bow_id] then rangedArrayPos[funcName][proj.firer.id][proj.bow_id]=1 end
      if not neverReset then
        local delayTime=math.max(1,math.floor(oldThinkCounter*resetMult+resetBase))
        if not rangedResetTimeouts[funcName][proj.firer.id] then rangedResetTimeouts[funcName][proj.firer.id]={} end
        if rangedResetTimeouts[funcName][proj.firer.id][proj.bow_id] and dfhack.timeout_active(rangedResetTimeouts[funcName][proj.firer.id][proj.bow_id]) then
          dfhack.timeout_active(rangedResetTimeouts[funcName][proj.firer.id][proj.bow_id],nil)
        end
        --these get used later when the projectile has probably been deleted
        --hence the need to store locally so we don't have dangling references causing segfaults
        local pid=proj.firer.id
        local bowid=proj.bow_id
        rangedResetTimeouts[funcName][pid][bowid]=dfhack.timeout(delayTime,'ticks',function() rangedArrayPos[funcName][pid][bowid]=1 end)
      end
    end
   
    --now the meaty bit - calculate and set the new think_counter time
    if #timeBase>1 then
      proj.firer.counters.think_counter=math.max(1,math.floor(oldThinkCounter*timeMult[rangedArrayPos[funcName][proj.firer.id][proj.bow_id]]+timeBase[rangedArrayPos[funcName][proj.firer.id][proj.bow_id]]))
    else
      proj.firer.counters.think_counter=math.max(1,math.floor(oldThinkCounter*timeMult[1]+timeBase[1]))
    end
    --iterate through the array of times
    if #timeBase>1 then
      rangedArrayPos[funcName][proj.firer.id][proj.bow_id]=rangedArrayPos[funcName][proj.firer.id][proj.bow_id]+1
      if rangedArrayPos[funcName][proj.firer.id][proj.bow_id]>#timeBase then
        rangedArrayPos[funcName][proj.firer.id][proj.bow_id]=1
      end
    end
    return true
   
  end
 
end
 
local validArgs = utils.invert({
 'help',
 'clear',
 'reset',
 'name',
 'reqProjMat',
 'reqProjType',
 'reqWeaponMat',
 'reqWeaponType',
 'timeBase',
 'timeMult',
 'neverReset',
 'delayBase',
 'delayMult'
})

if moduleMode then return end

local args = utils.processArgs({...}, validArgs)

if args.help then
 print(usage)
 return
end

if args.clear then
  return --todo, code below won't work
  --rangedTriggers[args.clear]=nil
  --rangedArrayPos[args.clear]=nil
  --if dfhack.timeoutActive(rangedDelayedReset[args.clear]) then
   -- dfhack.timeoutActive(rangedDelayedReset[args.clear],nil)
  --end
end

if args.reset then
  return --todo
end

local reqProjMats={}
local reqProjTypes={}
local reqWeaponMats={}
local reqWeaponTypes={}
local timeBase={0}
local timeMult={0}
local resetBase=0
local resetMult=5
local neverReset=false

if type(args.reqProjMat)=='string' then
  reqProjMats={args.reqProjMat}
elseif type(args.reqProjMat)=='table' then
  reqProjMats=args.reqProjMat
end
if type(args.reqProjType)=='string' then
  reqProjTypes={args.reqProjType}
elseif type(args.reqProjType)=='table' then
  reqProjTypes=args.reqProjType
end
if type(args.reqWeaponMat)=='string' then
  reqWeaponMats={args.reqWeaponMat}
elseif type(args.reqWeaponMat)=='table' then
  reqWeaponMats=args.reqWeaponsMat
end
if type(args.reqWeaponType)=='string' then
  reqWeaponTypes={args.reqWeaponType}
elseif type(args.reqWeaponType)=='table' then
  reqWeaponTypes=args.reqWeaponType
end


if not args.timeBase and not args.timeMult then
  error("-timeBase or -timeMult must be defined")
end

if args.timeBase and type(args.timeBase)=='string' then
  timeBase={args.timeBase}
elseif args.timeBase then
  timeBase=args.timeBase
end

if args.timeMult and type(args.timeMult)=='string' then
  timeMult={args.timeMult}
elseif args.timeMult then
  timeMult=args.timeMult 
end


for i,numb in ipairs(timeBase) do
  timeBase[i]=tonumber(numb)
  if not timeBase[i] then
    error("all elements of timeBase must be numbers")
  end
end

for i,numb in ipairs(timeMult) do
  timeMult[i]=tonumber(numb)
  if not timeMult[i] then
    error("all elements of timeMult must be numbers")
  end
end

if #timeBase>1 and #timeMult>1 and #timeBase~=#timeMult then
  error("-timeBase and -timeMult must be the same length when they are both tables")
end

if #timeBase>1 and #timeMult==1 then
  for i=#timeMult+1,#timeBase do
    timeMult[i]=timeMult[1]
  end
end

if #timeMult>1 and #timeBase==1 then
  for i=#timeBase+1,#timeMult do
    timeBase[i]=timeBase[1]
  end
end

if args.resetBase then
  resetBase=tonumber(args.resetBase)
  if not resetBase then error("resetBase must be a number") end
end

if args.resetMult then
  resetMult=tonumber(args.resetMult)
  if not resetMult then error("resetMult must be a number") end
end

if args.neverReset then
  neverReset=true
end

if not args.name then error("-name must be specified") end

rangedTriggers[args.name]=getCommandFunc(reqProjMats,reqProjTypes,reqWeaponMats,reqWeaponTypes, timeBase, timeMult, resetBase, resetMult, neverReset)
rangedArrayPos[args.name]={}
rangedResetTimeouts[args.name]={}
I *think* it works without any issues, but I wouldn't be surprised if I screwed something up somewhere, so test it and tell me how it goes. Also tell me if the documentation is understandable - my technical writing skills are mediocre at best.

Of course, anyone else is welcome to use it as well if they want to.

EDIT:I missed a couple of bugs - only the last script call would actually function correctly, and passing tables to both timeMult and timeBase would throw an error.  Those are now fixed.  Also, now it uses the built in item find(id) function instead of my own home rolled one.  Code has been updated above.
« Last Edit: September 02, 2018, 07:52:10 pm by thefriendlyhacker »
Logged
Fallout Equestria Redux - that's right, it's back

zaporozhets

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #95 on: August 30, 2018, 08:59:17 pm »

I have been playing around with something lately, and I have just gotten it to a basically functional point (although I will revisit it later and add/tweak a few things).  I figured that in the meantime you might like to have it for some double barrel muskets or something.
Code: [Select]
I *think* it works without any issues, but I wouldn't be surprised if I screwed something up somewhere, so test it and tell me how it goes. Also tell me if the documentation is understandable - my technical writing skills are mediocre at best.

Of course, anyone else is welcome to use it as well if they want to.

Bloody hell mate! I'm both impressed and shamed.
All I can contribute is df.item.find(item_id) and you can get persistence by hijacking a (hopefully) unused field in the bow if there is one. I think you just made a lot of modders very happy.
Definitely get it included as one of the built-in modtools when it's finished.
Logged

thefriendlyhacker

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #96 on: August 30, 2018, 10:34:16 pm »

...
All I can contribute is df.item.find(item_id)...
Ah, so I was blind.  Good to know.
Quote
...and you can get persistence by hijacking a (hopefully) unused field in the bow if there is one.
...
Ehhh, I don't particularly like the idea of sticking data in random bits of apparently currently hopefully unused memory. It just reeks of "this will bite me in the ass later in excitingly exotic ways".  Not to mention the fact that I have several bits of data I need to keep track of, and I would need to change the script logic to remove the "each weapon+firer+command combo has it's own data" stuff (and deal with a bunch of edge cases I avoided by using the current logic), and I intend to add some other scripts of a similar nature at a later date, so I am going to need to hijack a lot of unused memory.

With all that, it is probably easier in the long run to take the rather weird data structures provided by dfhack's existing persistent storage lua interface (read:paper thin wrapper over some internal DF data structure that dfhack commandeered), write a wrapper that treats each entry as a linked list element with a flag for type, and then go swap out the current table based implementation with a persistent linked list version that is virtually identical logic wise besides some code to restart lost timeout calls, and maybe deleting unneeded tables/linked lists when calling the delayed reset function to minimize the potential accumulation of several megabytes of memory/hard disk overhead in a long running fort.  The only serious piece of coding I would need to do is the wrapper itself, and the difficulty in that will stem from me being fairly unfamiliar with Lua more than anything else.

All this will come later, though.  For the moment, I am going to stress test what I have already by adding script calls for most of Fallout Equestria's firearms, mod in a reaction to create SMGs, and maybe mod in another reaction to duct tape two SMGs to a chainsaw glaive for funsies and maximum firepower (I shall call it a storm glaive, and it shall be glorious).
Logged
Fallout Equestria Redux - that's right, it's back

zaporozhets

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #97 on: August 31, 2018, 01:29:58 am »

Ehhh, I don't particularly like the idea of sticking data in random bits of apparently currently hopefully unused memory. It just reeks of "this will bite me in the ass later in excitingly exotic ways".  Not to mention the fact that I have several bits of data I need to keep track of, and I would need to change the script logic to remove the "each weapon+firer+command combo has it's own data" stuff (and deal with a bunch of edge cases I avoided by using the current logic), and I intend to add some other scripts of a similar nature at a later date, so I am going to need to hijack a lot of unused memory.

With all that, it is probably easier in the long run to take the rather weird data structures provided by dfhack's existing persistent storage lua interface (read:paper thin wrapper over some internal DF data structure that dfhack commandeered), write a wrapper that treats each entry as a linked list element with a flag for type, and then go swap out the current table based implementation with a persistent linked list version that is virtually identical logic wise besides some code to restart lost timeout calls, and maybe deleting unneeded tables/linked lists when calling the delayed reset function to minimize the potential accumulation of several megabytes of memory/hard disk overhead in a long running fort.  The only serious piece of coding I would need to do is the wrapper itself, and the difficulty in that will stem from me being fairly unfamiliar with Lua more than anything else.

Probably a good shout on the 'unused' memory, I considered using the built-in persistent storage to store venom types for chemical shells, but my lack of experience and the warning about significant overhead scared me off.
Forgive me if this is a completely asinine question, but mightn't it be easier and more lightweight to simply hold the necessary stuff in memory until the player saves and then write to an external file, with a game state listener to load it in again with the save? Might be more lightweight than storing it in histfigs (if the persistent tables still are) and you'd get finer control over the whole process.

All this will come later, though.  For the moment, I am going to stress test what I have already by adding script calls for most of Fallout Equestria's firearms, mod in a reaction to create SMGs, and maybe mod in another reaction to duct tape two SMGs to a chainsaw glaive for funsies and maximum firepower (I shall call it a storm glaive, and it shall be glorious).

A sturmglaive does indeed sound a glorious weapon.
I couldn't help but notice the postponed energy weapons in Equestria and wondered if you saw the rubbishy attempt at a lasgun posted earlier. I've been having some fun with trying to turn it into a tesla rifle using hot syndrome gas (that causes paralysis and blisters on contact and can melt bodyparts) rather than spawning in a projectile when the beam hits and I think something vaguely like that (without the paralysis and shoddy attempt at curving/branching) would make good fallout-esque laser weapons:

Logged

Meph

  • Bay Watcher
    • View Profile
    • worldbicyclist
Re: [44.12] Musket-Mod v0.4i
« Reply #98 on: August 31, 2018, 08:38:54 am »

Seeing that gif: could I please have randomized lightning strikes when it rains ingame, pretty please? ;)
Logged
::: ☼Meph Tileset☼☼Map Tileset☼- 32x graphic sets with TWBT :::
::: ☼MASTERWORK DF☼ - A comprehensive mod pack now on Patreon - 250.000+ downloads and counting :::
::: WorldBicyclist.com - Follow my bike tours around the world - 148 countries visited :::

zaporozhets

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #99 on: August 31, 2018, 03:31:05 pm »

Seeing that gif: could I please have randomized lightning strikes when it rains ingame, pretty please? ;)

I had a quick look and found df.weather_type[dfhack.world.ReadCurrentWeather()] so it should be possible to check that every n ticks for rain and use an rng to control the chances of lightning spawns. Not too experienced with timeout loops so it would be quite rough, but functional. Some more data on weather duration and so on would be helpful but I was unable to find any.

After having a play today, I need to get an inorganic gas 'lightning' that is more reliable in melting limbs and such, doesn't seem to transfer its heat as well as I previously thought. Making it hotter didn't work so I'll have to try more dense and failing that, spawning a couple of tiles of flow when the beam touches a unit. Would be nice for weather if the gas interacted with the world more too.

Edit: Both increasing the density and number of individual flows spawned when a unit is detected made it reliably deadly, but also occasionally melts parts of the user. A fight between an automusket wielding dwarf and one with a lightning gun lead to them both dying of bodily disintegration. Needs more work.

I'd also need to rewrite it to make up a path from the top of the skybox to the ground rather than get one from a projectile, not sure if the top z-level is hardcoded or related to the altitude of the embark. Edit: Found some stuff related to map dimensions in 'df.global.world.map'.

There are also a few console errors related to branching that need to be ironed out (due to always doing this stuff when tired).

Once that's all figured out it should be straightforward but the player would usually only see one tile of lightning anyway which could be more easily achieved by:
https://github.com/Pheosics/v24-r3_Scripts/blob/master/hack/scripts/flow/customweather.lua

Edit:
Okay, it's done. I'm having to release this with a disclaimer though: I put the check frequency waayy too high whilst I was writing it and my PC had a seizure and crashed. I had a bunch of stuff open, hadn't freshly booted in weeks, was watching a stream and listening to music and was running the script every tick. Might have been a thermal shutdown as it was on my laptop.
I've changed much about how it works and it's not happened again but I wanted to give people fair warning.

I put a bunch of variables at the top to tweak it to your liking. Only tested it in arena mode.

http://dffd.bay12games.com/file.php?id=13997
« Last Edit: September 01, 2018, 11:36:51 am by zaporozhets »
Logged

cltail

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #100 on: September 05, 2018, 11:19:06 am »

I was looking into the possibility of making a civ that would use these weapons, but it seems like right now if i gave them the weapons they would make them out of whatever materials they wanted (including wood, I think.) unless I only gave them steel for everything, which i really don't want to do. I know for a fact that the guns work perfectly fine as any material, all the reactions and scripts are already fine with anything.

I'm not worried about balance issues, a copper musket will be much less effective in caving in someone's head than a steel one would, and the steel musket's bayonet would be considerably sharper. I just don't want there to be a situation where the player would go "Why can they make guns out of anything, and I can't?"

Ideally i would just let the player make anything to compensate for the fact I have no control over what other civs make their guns out of. I would have just done that myself instead of complaining here if I knew of any way to have the custom workshop allow any metal in a reasonable way that doesn't involve making a custom reaction for every single metal, or letting dwarves pick whatever metal they want - forcing the player to mess with stockpiles to force a specific material.
Logged

zaporozhets

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #101 on: September 05, 2018, 12:27:16 pm »

I was looking into the possibility of making a civ that would use these weapons, but it seems like right now if i gave them the weapons they would make them out of whatever materials they wanted (including wood, I think.) unless I only gave them steel for everything, which i really don't want to do. I know for a fact that the guns work perfectly fine as any material, all the reactions and scripts are already fine with anything.

I'm not worried about balance issues, a copper musket will be much less effective in caving in someone's head than a steel one would, and the steel musket's bayonet would be considerably sharper. I just don't want there to be a situation where the player would go "Why can they make guns out of anything, and I can't?"

Ideally i would just let the player make anything to compensate for the fact I have no control over what other civs make their guns out of. I would have just done that myself instead of complaining here if I knew of any way to have the custom workshop allow any metal in a reasonable way that doesn't involve making a custom reaction for every single metal, or letting dwarves pick whatever metal they want - forcing the player to mess with stockpiles to force a specific material.

I know how you feel, this bothers me too.
It wouldn't be a problem to allow only metals (of all types), like the bullet reaction does, but it would be nicer to allow firearms to use only weapons grade metals without the tedium of a separate reaction for each metal for each weapon.

I think the trick would be making use of a tag like [METAL_WEAPON_MAT] or [ITEMS_WEAPON] where the metal reagent is specified but I know next to nothing about raw modding and have no idea how to use these tags.

Failing that, another way of doing it would be having the barrels made as a tool at the metalsmith's forge so as to make use of the native metal choice menu, and requiring the barrel in the musket reaction in place of the current steel bars.
Might be too micromanage-y for some players, though.

I'm hoping Grim or thefriendlyhacker or Meph another competent person comes along to help you and I out with this. I'm just finishing up with the re-implemented chemical weapons and then a bunch of nearly-finished other stuff on the to-do list like the lightning gun, but I'll be sure to devote some more time to this in future once I get this update out.
Until then, you might have problems with cannon rotation if you put it in your mod ATM, it's currently dependent on custom workshop load order because I'm an idiot.

Keep me posted if you have any breakthroughs.
« Last Edit: September 05, 2018, 02:53:20 pm by zaporozhets »
Logged

thefriendlyhacker

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #102 on: September 05, 2018, 06:24:48 pm »

I was looking into the possibility of making a civ that would use these weapons, but it seems like right now if i gave them the weapons they would make them out of whatever materials they wanted (including wood, I think.) unless I only gave them steel for everything, which i really don't want to do. I know for a fact that the guns work perfectly fine as any material, all the reactions and scripts are already fine with anything.

I'm not worried about balance issues, a copper musket will be much less effective in caving in someone's head than a steel one would, and the steel musket's bayonet would be considerably sharper. I just don't want there to be a situation where the player would go "Why can they make guns out of anything, and I can't?"

Ideally i would just let the player make anything to compensate for the fact I have no control over what other civs make their guns out of. I would have just done that myself instead of complaining here if I knew of any way to have the custom workshop allow any metal in a reasonable way that doesn't involve making a custom reaction for every single metal, or letting dwarves pick whatever metal they want - forcing the player to mess with stockpiles to force a specific material.
Here is an idea you could try that is a little hacky but that gets the job done.  Add a tool called a "firearm components" or whatever, and another called a "heavy firearm components".  Make six custom reactions (copper,bronze, bismuth bronze, iron, steel, candy) per component, with 1 bar for normal components and two bars for heavy parts, and then use one of those components in the making of each firearm, taking the component item's metal as the product weapon's metal.  That will let the player use whatever weapon metal materials they want without bloating workshop menus with dozens of custom reactions.

Oh, and afaik most civs only use ranged weapons made of weapon metals. Unless you are giving guns to an elf type civ that uses wood, I don't think wooden firearms are a problem.  Barring a civ that uses wooden weapons, the only time you will see wood guns is artifacts.
Logged
Fallout Equestria Redux - that's right, it's back

Grimlocke

  • Bay Watcher
  • *kobold noises*
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #103 on: September 05, 2018, 07:30:39 pm »

Civs will have ranged weapon made only from metals with the [ITEMS_WEAPON_RANGED], removing this from bronze and iron really makes sense in general. Only if they are treehuggers, they will use wood instead, but the ability to make a wooden musket will still show up in the bowyers workshop in fortress mode and I think there are some instances where wooden ranged weapons turn up in adventurer mode, so perfect it is not.

Best solution is usually to just not add the special ranged weapons to your own civ and make them with reactions instead, since you have to do some really unsubtle dfhack things to get rid of the automatically spawned weapon production jobs. I personally only added iron and bronze for one type and steel and bronze for the other type of firearm I added, lead and rock for small arms ammunition and iron and rock for cannons. The number of reactions is a dozen or so, including some weapons that are made in two stages. Since material doesn't factor much or at all into how ranged weapons perform there isn't a whole lot of a point out of making them out of high-grade stuff.

There is also the really radical solution of adding a dfhack item trigger that magically transforms dumb things like wooden bullets into lead bullets. I might actually have to look into that if I don't find another way to tinker with melee combat balance; dfhack eventful's onUnitAttack event listener seems to run after attacks hit and is thus not really useful at all for tinkering with melee balance.

More on topic, I've added damage falloff, dfhack command line weapon/ammo property population and various other stuffs to the ranged weapon script and gave up on trying to get items in a workshop into a container that is a building item in that workshop and just went went 'delete them and spawn a new one'. It's simple not possible to get the !@#&^!( things out of the workshop through any of the stock DFhack or vmethod functions, best I managed to do was weirdly making them exist both in the workshop and on the floor at the same time which didn't help. Dropping them from a height worked but I'd have to do some weird timeout thing and get it to be smart about finding a place to drop from aaand... none of that is any more graceful than just duping the items, copying the itemquality and deleting the obstinate buggers in the workshop.

Job/reaction triggers also have the same problem as onUnitAttack in that they run just after or before the thing I want to modify exists. (job time in this case, I want to make firing the cannon not take forever).
Logged
I make Grimlocke's History & Realism Mods. Its got poleaxes, sturdy joints and bloomeries. Now compatible with DF Revised!

zaporozhets

  • Bay Watcher
    • View Profile
Re: [44.12] Musket-Mod v0.4i
« Reply #104 on: September 08, 2018, 07:42:06 pm »


Thanks for the help guys. Might be necessary to make something to write the reactions for me and hide them away behind reaction categories like the metalsmith's does.

More on topic, I've added damage falloff, dfhack command line weapon/ammo property population and various other stuffs to the ranged weapon script and gave up on trying to get items in a workshop into a container that is a building item in that workshop and just went went 'delete them and spawn a new one'. It's simple not possible to get the !@#&^!( things out of the workshop through any of the stock DFhack or vmethod functions, best I managed to do was weirdly making them exist both in the workshop and on the floor at the same time which didn't help. Dropping them from a height worked but I'd have to do some weird timeout thing and get it to be smart about finding a place to drop from aaand... none of that is any more graceful than just duping the items, copying the itemquality and deleting the obstinate buggers in the workshop.

Job/reaction triggers also have the same problem as onUnitAttack in that they run just after or before the thing I want to modify exists. (job time in this case, I want to make firing the cannon not take forever).

Interesting, does the damage falloff modulate sharpness or something using distance_flown?

I want to spend some more time with trying to get items out of buildings, what you've said about dropping from a height could be useful.
If the ammo can't be moved through changing fields (though I still hope it can be), you could maybe teleport it to {0, 0, map.z_count} and then instantly moveToGround() it to the position of the muzzle given by checkDirection(cannon, nil, 2) in the cannon script.
Janky as hell, but no-one would know.

I'm worried a reaction with no product (and no createItem()) wouldn't train the siege operation skill of the firer, though, so it would need to be increased manually if this is the case.

As for reaction speed, did you do some tests with firer skill?
Using armoks-blessing during testing increases the reaction speed significantly, you would just need to increment the units SIEGEOPERATE skill +=20 onJobInitiated() and decrement -=20 onJobCompleted(), if it doesn't bother you that cancelling the job might permabuff the firer.
Could add a timeout debuff rather than onJobCompleted() and have a skill level check before applying the buff (preventing double buffing) to avoid that I guess.

I've been thinking about adding something similar for rotate and fire, but my hands are full ATM working on next version, twbt is a pain and I'm battling brain fog.
Had to merge the weapons scripts (hope you don't think I'm aping you too much with that, Grim) as they were beginning to trip up over one-another due to explosions destroying items before they could be removed on impact and causing many other weirdnesses like "floaty ricochets" where the projectile would serenely drift around the map after hitting something. Think that one was the distance_flown counter resetting on impact and triggering the accuracy modifier.
Unified existence checks are much easier to manage and I won't keep accidentally overwriting event listeners like an idiot now.

Edit: On a similar note to the skill buff thing, I noticed your post mentioning cannon operator fear in the History & Realism Mod thread, I'm very curious how you've managed to avoid that. The only way I can think of doing it is onJobInitiated() applying a temporary syndrome that adds the NOFEAR tag to the firer.
« Last Edit: September 08, 2018, 08:00:03 pm by zaporozhets »
Logged
Pages: 1 ... 5 6 [7] 8 9 ... 12