Oh yeah! certinaly.
local eventful = require 'plugins.eventful'
local lightningInorganicIndx = 1
local curviness = 5 --maximum lightning apex deviation from line to target
dfhack.onStateChange.musket = function(state) --find lightning independent of load order
if state == SC_WORLD_LOADED then
for indx, inorganic in pairs(df.global.world.raws.inorganics) do
if inorganic.id == "LIGHTNING" then
lightningInorganicIndx = indx
end
end
end
end
local defaultSmoke = {5, 10, 25} --default muzzle smoke
local weaponProperties = { --currently just for muzzle smoke amounts. will turn into 2d array if needed for more stuff in future but trying to avoid too many table lookups
--normal weapons
["ITEM_WEAPON_RIFLE_RAIL1"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL2"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL3"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL4"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL5"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL6"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL7"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL8"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_RAIL9"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL1"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL2"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL3"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL4"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL5"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL6"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL7"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL8"] = defaultSmoke,
["ITEM_WEAPON_RIFLE_COIL9"] = defaultSmoke,
["ITEM_WEAPON_ROCKET_COIL"] = defaultSmoke,
["ITEM_WEAPON_ROCKET_RAIL"] = defaultSmoke,
["ITEM_WEAPON_SHOTGUN1"] = defaultSmoke,
["ITEM_WEAPON_SHOTGUN2"] = defaultSmoke,
["ITEM_WEAPON_SHOTGUN3"] = defaultSmoke,
["ITEM_WEAPON_SHOTGUN4"] = defaultSmoke,
["ITEM_WEAPON_SHOTGUN5"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_RAIL1"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_RAIL2"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_RAIL3"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_COIL1"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_COIL2"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_COIL3"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_SCATTER1"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_SCATTER2"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_SCATTER3"] = defaultSmoke,
["ITEM_WEAPON_PISTOL_SCATTER2"] = defaultSmoke,
["ITEM_WEAPON_SNIPER_RAIL"] = defaultSmoke,
["ITEM_WEAPON_SNIPER_COIL"] = defaultSmoke,
}
eventful.onProjItemCheckMovement.sniper = function(projectile)
if df.item.find(projectile.bow_id) ~= nil then --fucking explosions destroying weapons
local weaponType = df.item.find(projectile.bow_id).subtype.id
if string.find(weaponType, "_SNIPER_", 11) then
if projectile.distance_flown == 0 then
weaponMod(projectile, weaponType) --apply unique weapon effects
elseif projectile.distance_flown <= 3 then
musketSmoke(projectile, 5, weaponProperties[weaponType][projectile.distance_flown]) --muzzle smoke
end
end
end
end
eventful.onProjItemCheckMovement.coil = function(projectile)
if df.item.find(projectile.bow_id) ~= nil then --fucking explosions destroying weapons
local weaponType = df.item.find(projectile.bow_id).subtype.id
if string.find(weaponType, "_COIL", 11) then
if projectile.distance_flown == 0 then
weaponMod(projectile, weaponType) --apply unique weapon effects
elseif projectile.distance_flown <= 3 then
musketSmoke(projectile, 5, weaponProperties[weaponType][projectile.distance_flown]) --muzzle smoke
end
end
end
end
eventful.onProjItemCheckMovement.shotgun = function(projectile)
if df.item.find(projectile.bow_id) ~= nil then --fucking explosions destroying weapons
local weaponType = df.item.find(projectile.bow_id).subtype.id
if string.find(weaponType, "_SHOTGUN", 11) then
if projectile.distance_flown == 0 then
weaponMod(projectile, weaponType) --apply unique weapon effects
elseif projectile.distance_flown <= 3 then
musketSmoke(projectile, 5, weaponProperties[weaponType][projectile.distance_flown]) --muzzle smoke
end
end
end
end
eventful.onProjItemCheckMovement.rocket = function(projectile)
if df.item.find(projectile.bow_id) ~= nil then --fucking explosions destroying weapons
local weaponType = df.item.find(projectile.bow_id).subtype.id
if string.find(weaponType, "_ROCKET_", 11) then
if projectile.distance_flown == 0 then
weaponMod(projectile, weaponType) --apply unique weapon effects
elseif projectile.distance_flown <= 3 then
musketSmoke(projectile, 5, weaponProperties[weaponType][projectile.distance_flown]) --muzzle smoke
elseif weaponType == "ITEM_WEAPON_GUN_ROCKETLAUNCHER" then
musketSmoke(projectile, 5, 5)
if projectile.distance_flown >= 30 then --rocket becomes unstable
setInaccuracy(projectile, 2)
end
end
end
end
end
eventful.onProjItemCheckImpact.RPG = function(projectile)
if dfhack.items.getSubtypeDef(projectile.item:getType(),projectile.item:getSubtype()) ~= nil then
local ammoType = projectile.item.subtype.id
if string.find(ammoType, "_RPG", 9) then
if ammoType == "ITEM_AMMO_GUN_GRENADES" then
musketSmoke(projectile, 6, 15)
musketSmoke(projectile, 3, 40)
elseif ammoType == "ITEM_AMMO_RPG1" then
destroyConstructions(projectile)
musketSmoke(projectile, 6, 45)
elseif ammoType == "ITEM_AMMO_RPG2" then
destroyConstructions(projectile)
musketSmoke(projectile, 6, 45)
elseif ammoType == "ITEM_AMMO_RPG3" then
destroyConstructions(projectile)
musketSmoke(projectile, 6, 45)
end
deleteProjectile(projectile)
end
end
end
eventful.onProjItemCheckMovement.pistol = function(projectile)
if df.item.find(projectile.bow_id) ~= nil then --fucking explosions destroying weapons
local weaponType = df.item.find(projectile.bow_id).subtype.id
if string.find(weaponType, "_PISTOL_", 11) then
if projectile.distance_flown == 0 then
weaponMod(projectile, weaponType) --apply unique weapon effects
elseif projectile.distance_flown <= 3 then
musketSmoke(projectile, 5, weaponProperties[weaponType][projectile.distance_flown]) --muzzle smoke
end
end
end
end
eventful.onProjItemCheckMovement.rail = function(projectile)
if df.item.find(projectile.bow_id) ~= nil then --fucking explosions destroying weapons
local weaponType = df.item.find(projectile.bow_id).subtype.id
if string.find(weaponType, "_RAIL", 11) then
if projectile.distance_flown == 0 then
weaponMod(projectile, weaponType) --apply unique weapon effects
elseif projectile.distance_flown <= 3 then
musketSmoke(projectile, 5, weaponProperties[weaponType][projectile.distance_flown]) --muzzle smoke
end
end
end
end
--[[general purpose functions]]
function musketSmoke(projectile, type, amount)
return dfhack.maps.spawnFlow(projectile.cur_pos, type, projectile.item.mat_type, projectile.item.mat_index, amount) --mat stuff only applies to hand mortar concussion dust
end
function weaponMod(projectile, weaponType)
if weaponType == "ITEM_WEAPON_RIFLE_RAIL1" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL2" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL3" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL4" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL5" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL6" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL7" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL8" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_RAIL9" then
setFireRate(projectile, 20)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL1" then
setFireRate(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL2" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL3" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL4" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL5" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL6" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL7" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL8" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_RIFLE_COIL9" then
setFireRate(projectile, 10)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_SHOTGUN1" or weaponType == "ITEM_WEAPON_SHOTGUN2" then
blunderShot(projectile)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_SHOTGUN3" or weaponType == "ITEM_WEAPON_SHOTGUN4" then
blunderShot(projectile)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_SHOTGUN5" then
blunderShot(projectile)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_GUN_TESLAGUN" then --"Yes, I loved that pigeon, I loved her as a man loves a woman, and she loved me."
setFireRate(projectile, 30)
lightningStrike(projectile)
deleteProjectile(projectile)
elseif weaponType == "ITEM_WEAPON_ROCKET_RAIL" then
setFireRate(projectile, 120)
elseif weaponType == "ITEM_WEAPON_ROCKET_COIL" then
setFireRate(projectile,120)
elseif weaponType == "ITEM_WEAPON_PISTOL_RAIL1" then
setFireRate(projectile, 40)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_RAIL2" then
setFireRate(projectile, 40)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_RAIL3" then
setFireRate(projectile, 40)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_COIL1" then
setFireRate(projectile, 30)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_COIL2" then
setFireRate(projectile,30)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_COIL" then
setFireRate(projectile, 30)
setInaccuracy(projectile, 10)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_SCATTER1" then
setFireRate(projectile, 50)
blunderShot(projectile)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_SCATTER2" then
setFireRate(projectile, 50)
blunderShot(projectile)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_PISTOL_SCATTER3" then
setFireRate(projectile, 50)
blunderShot(projectile)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_SNIPER_RAIL" then
setFireRate(projectile, 50)
laserStrike(projectile)
elseif weaponType == "ITEM_WEAPON_SNIPER_COIL" then
setFireRate(projectile, 50)
laserStrike(projectile)
end
end
function setFireRate(projectile, rate)
if projectile.firer ~= nil then
projectile.firer.counters.think_counter = rate --normal crossbow rate is 80
end
end
function setInaccuracy(projectile, deviation)
projectile.target_pos.x = projectile.target_pos.x + math.random(-deviation, deviation)
projectile.target_pos.y = projectile.target_pos.y + math.random(-deviation, deviation)
end
function deleteProjectile(projectile)
projectile.item.flags.garbage_collect = true
local noPos = {x = -1, y = -1, z = -1} --here be multi-tile dragons
projectile.origin_pos = noPos
projectile.prev_pos = noPos
projectile.cur_pos = noPos
end
function destroyConstructions(projectile)
--[[linear search through df.global.world.constructions comparing each construction pos with offset projectile pos to find construction and get material information is too slow,
this precludes checking wall strength and flying chunks of masonry unless a way of obtaining construction index without searching is found.
not sure how to go about with building destruction, one way is invoking garbage collection on contained items but there is a delay with this method.
not figure out how to get tree destruction to produce logs
]]
local offsetPos = df.coord:new()
for yOffset = -3, 3 do
for xOffset = -1 , 1 do --3x3 for ease, dynamic size offset for variable explosions would be something like local min = median(size) - size; for(i=min, size - median(size)) do... ; 5 == -2, -1, 0, 1, 2
offsetPos.x = projectile.cur_pos.x + xOffset
offsetPos.y = projectile.cur_pos.y + yOffset
offsetPos.z = projectile.cur_pos.z
local tileType = dfhack.maps.getTileBlock(projectile.cur_pos).tiletype[offsetPos.x %16][offsetPos.y %16]
if (tileType >= 490 and tileType <= 514) then --constructed walls, fortifications, stairs and ramps
dfhack.maps.getTileBlock(projectile.cur_pos).tiletype[offsetPos.x%16][offsetPos.y%16] = 489 --transmute to floor (tried rubble, didn't work very well)
dfhack.maps.spawnFlow(offsetPos, 5, -1, -1, 20) --smoke to be replaced with cave-in dust if faster material lookup is found
elseif (tileType >= 91 and tileType <= 200) then --trees, branches, roots
dfhack.maps.getTileBlock(projectile.cur_pos).tiletype[offsetPos.x%16][offsetPos.y%16] = 32 --transmute to empty space
end
end
end
df.global.world.cavein_flags[0] = true
for indx, column in ipairs(df.global.world.map.map_block_columns) do
column.flags[0] = true
end
end
function blunderShot(projectile)
if projectile.firer ~= nil then
local shot = projectile.item
shot:setSubtype(shot:getSubtype() + 1) --original cartridge is perfectly good so transmuting it to pellet
for i = 0, 4, 1 do
local pellet = df.item.find(dfhack.items.createItem(shot:getType(), shot:getSubtype(), shot.mat_type, shot.mat_index, projectile.firer))
pellet.flags.forbid = true
pellet.quality = projectile.item.quality
local pelletProjectile = dfhack.items.makeProjectile(pellet)
pelletProjectile.origin_pos.x = projectile.origin_pos.x + math.random(-1, 1)
pelletProjectile.origin_pos.y = projectile.origin_pos.y + math.random(-1, 1)
pelletProjectile.origin_pos.z = projectile.origin_pos.z
pelletProjectile.prev_pos.x = projectile.origin_pos.x
pelletProjectile.prev_pos.y = projectile.origin_pos.y
pelletProjectile.prev_pos.z = projectile.origin_pos.z
pelletProjectile.cur_pos.x = projectile.origin_pos.x
pelletProjectile.cur_pos.y = projectile.origin_pos.y
pelletProjectile.cur_pos.z = projectile.origin_pos.z
pelletProjectile.target_pos.x = projectile.target_pos.x + math.random(-20, 20)
pelletProjectile.target_pos.y = projectile.target_pos.y + math.random(-20, 20)
pelletProjectile.target_pos.z = projectile.target_pos.z
pelletProjectile.flags.no_impact_destroy = false
pelletProjectile.flags.bouncing = false
pelletProjectile.flags.piercing = projectile.flags.piercing
pelletProjectile.flags.parabolic = false
pelletProjectile.flags.unk9 = false
pelletProjectile.flags.no_collide = false
pelletProjectile.distance_flown = projectile.distance_flown
pelletProjectile.fall_threshold = projectile.fall_threshold
pelletProjectile.min_hit_distance = projectile.min_hit_distance
pelletProjectile.min_ground_distance = projectile.min_ground_distance
pelletProjectile.fall_counter = 0
pelletProjectile.fall_delay = 0
pelletProjectile.hit_rating = projectile.hit_rating
pelletProjectile.unk22 = projectile.unk22
pelletProjectile.bow_id = projectile.bow_id
pelletProjectile.unk_v40_1 = projectile.unk_v40_1
pelletProjectile.speed_x = projectile.speed_x
pelletProjectile.speed_y = projectile.speed_x
pelletProjectile.speed_z = projectile.speed_x
end
end
end
function getLine(origin_pos, target_pos) --returns [1] line position table, [2] size of table/length of line
local line = {}
line[0] = origin_pos
lineCount = 0
local directionVector = df.coord:new()
directionVector.x = target_pos.x - origin_pos.x
directionVector.y = target_pos.y - origin_pos.y
directionVector.z = target_pos.z - origin_pos.z
local targetDistance = findDistance(origin_pos, target_pos)
local stepAmount = 1 / targetDistance
local step = stepAmount
local linePath = df.coord:new()
while step <= 1 do
lineCount = lineCount + 1
linePath.x = math.floor(origin_pos.x + (directionVector.x * step) + 0.5)
linePath.y = math.floor(origin_pos.y + (directionVector.y * step) + 0.5)
linePath.z = math.floor(origin_pos.z + (directionVector.z * step) + 0.5)
line[lineCount] = {x = linePath.x, y = linePath.y, z = linePath.z}
if not checkTile(linePath) then
break
end
step = step + stepAmount
end
return {line, lineCount}
end
function checkTile(position)
local passable = false
if dfhack.maps.getTileBlock(position) ~= nil then
if dfhack.maps.getTileBlock(position).occupancy[position.x%16][position.y%16].unit == true then --found unit
for i = 1, 15 do --spawn extra lightning to melt unit more effectively (maybe too effectively atm)
drawLightning({position}, 5000)
end
passable = false --end line drawing, no chain lightning yet
elseif dfhack.maps.getTileBlock(position).walkable[position.x%16][position.y%16] ~= 0 then --found to be walkable
passable = true
elseif dfhack.maps.getTileBlock(position).tiletype[position.x%16][position.y%16] == 32 then --found empty space
passable = true
elseif dfhack.maps.getTileBlock(position).tiletype[position.x%16][position.y%16] == 1 then --found stairs
passable = true
end
end
return passable
end
function findDistance(originPos, targetPos)
local distance = 0
for dimension, value in pairs(originPos) do
if value > targetPos[dimension] then
distance = distance + value - targetPos[dimension]
else
distance = distance + targetPos[dimension] - value
end
end
return distance
end
function curveLine(line) --removed branching/forking for now
local linePosArray = line[1]
local lineArraySize = line[2]
local midLine = linePosArray[math.floor(lineArraySize/2)] --always halfway down main path, might add some variation to this later
midLine = {x = midLine.x + math.random(-curviness, curviness), y = midLine.y + math.random(-curviness, curviness), z = midLine.z} --add random curve apex
local firstLeg = getLine(linePosArray[1], midLine)[1]
local secondLeg = getLine(midLine, linePosArray[lineArraySize])[1]
for i = 1, #secondLeg do
firstLeg[#firstLeg+1] = secondLeg
end
return firstLeg
end
function drawLightning(posArray, amount)
for posIndx, pos in pairs(posArray) do
if pos ~= nil then
local ionizedGas = dfhack.maps.spawnFlow(pos, 9, 0, lightningInorganicIndx, amount)
if ionizedGas ~= nil then ionizedGas.expanding = 0 end
end
end
end
function laserStrike(projectile)
if projectile.item:getSubtype() ~= -1 and dfhack.items.getSubtypeDef(projectile.item:getType(),projectile.item:getSubtype()).id == "ITEM_AMMO_BULLET1" then
--draw laser flow along projectile path and return any hit units
local hitUnit = drawLaser(projectile)
elseif projectile.item:getSubtype() ~= -1 and dfhack.items.getSubtypeDef(projectile.item:getType(),projectile.item:getSubtype()).id == "ITEM_AMMO_BULLET2" then
--draw laser flow along projectile path and return any hit units
local hitUnit = drawLaser(projectile)
if projectile.firer ~= nil and hitUnit ~= nil then
--get distance between firer and unit hit by beam
local targetDistance = findDistance(projectile.firer.pos.x, hitUnit.pos.x)
targetDistance = targetDistance + findDistance(projectile.firer.pos.y, hitUnit.pos.y)
targetDistance = targetDistance + findDistance(projectile.firer.pos.z, hitUnit.pos.z)
end
end
end
function drawLaser(projectile)
--draw a line to target
local directionVector = df.coord:new()
directionVector.x = projectile.target_pos.x - projectile.origin_pos.x
directionVector.y = projectile.target_pos.y - projectile.origin_pos.y
directionVector.z = projectile.target_pos.z - projectile.origin_pos.z
local targetDistance = findDistance(projectile.origin_pos.x, projectile.target_pos.x)
targetDistance = targetDistance + findDistance(projectile.origin_pos.y, projectile.target_pos.y)
targetDistance = targetDistance + findDistance(projectile.origin_pos.z, projectile.target_pos.z)
local stepAmount = 1 / targetDistance
local step = stepAmount
local linePath = df.coord:new()
while step <= 1 do
linePath.x = math.floor(projectile.origin_pos.x + (directionVector.x * step) + 0.5)
linePath.y = math.floor(projectile.origin_pos.y + (directionVector.y * step) + 0.5)
linePath.z = math.floor(projectile.origin_pos.z + (directionVector.z * step) + 0.5)
local tile = checkTile(linePath) --check tile is passable, function needs to be messed with
if tile[1] and not tile[0] then --passable but no unit
dfhack.maps.spawnFlow(linePath, 9, 0, 0, 50).expanding = 0 --might need to be changed if laser inorganic mat_type and mat_index are at different indexes
elseif tile[0] then --found unit
return tile[0]
else
break --hit something not passable: stop drawing laser
end
step = step + stepAmount
end
end
function findDistance(originDimension, targetDimension) --should find distance between two points in one dimension so needs to be called for all 3 (laziness)
local distance
if originDimension > targetDimension then
distance = originDimension - targetDimension
else
distance = targetDimension - originDimension
end
return distance
end
function checkTile(position) --check a given tile along line, returns {unit hit if any (unit), tile was found to be passable (bool)}
local results = {nil, false}
if dfhack.maps.getTileBlock(position) ~= nil then
if dfhack.maps.getTileBlock(position).occupancy[position.x%16][position.y%16].unit == true then --found unit
results[0] = dfhack.units.getUnitsInBox(position.x,position.y,position.z,position.x,position.y,position.z)[1]
results[1] = true
elseif dfhack.maps.getTileBlock(position).walkable[position.x%16][position.y%16] ~= 0 then --found to be walkable
results[1] = true
elseif dfhack.maps.getTileBlock(position).tiletype[position.x%16][position.y%16] == 32 then --found empty space
results[1] = true
elseif dfhack.maps.getTileBlock(position).tiletype[position.x%16][position.y%16] == 1 then --found stairs
results[1] = true
end
end
return results
end
function deleteProjectile(projectile)
--should teleport projectile to lands unknown whilst waiting for garbage collection
projectile.origin_pos.x = -1
projectile.origin_pos.y = -1
projectile.origin_pos.z = -1
projectile.prev_pos.x = -1
projectile.prev_pos.y = -1
projectile.prev_pos.z = -1
projectile.cur_pos.x = -1
projectile.cur_pos.y = -1
projectile.cur_pos.z = -1
projectile.item.flags.garbage_collect = true
end
Alright, the one highlighted is what you mainly want to focus on when modifying this script. Red is where you give weapons there modification effect. Blue is where those modification effect are applied to the weapon. And lastly green is where you give the guns it's smokey effects when fired.
Some things to note when working on blue.
whenever you add a new weapon the one highlighted in yellow tells the script to find "_SHOTGUN" In the raw so it can later be applied in green. I haven't really test this. Probably you can do away with the way I did it and just put "WEAPON_" to apply effects to all weapons. But I prefer to keep it the way it is.
setFireRate(projectile,n) = This set the rate of fire. 80 is where the original rate of fire for crossbow and bows are. So if you want faster fire rate lower it. Machines gun would probably be around 5 or so.
setInaccuracy(projectile, n) = The higher the number more innaccuracy the gun is.
laserStrike(projectile) = This one draws a laser when it hit something.
blunderShot(projectile) = This turn cartridge into pellets still havent figured out how to turn other ammo type into pellets like slugs, or buckshots and such.
It's should be somewhere here, if you like you could poke around and see where it may be.
That's pretty much it really, I am not really a script writer, and it was only thanks to my basic understanding of code that I was able to modify the script. Honestly would like a more experience script writer to improve on the script.