Another creature has claws, but I couldn't figure out how to specify all of them. I just went with its right front hand (glossed as a "claw"), but that guy defaults to its primary bite attack as well.
It works fine for the mod it's in... I just want these guys to pop up and fight rather than wander off... but in a perfect world I would convince them they are in a normal fight rather than driving them berserk.
This script is called by the mod when a miner strikes "Living Stone." Whether the creature is an Awakened Stone or a Wyrm, and whether it is friendly or hostile, is decided by mod logic outside this script as passed through command line arguments.
A "hostile" creature is induced to attack immediately. A "friendly" Awakened Stone is tame; a "friendly" Wyrm is simply a wild animal.
-- create Awakened Stone creature
-- modtools/syndrome-trigger -syndrome "wake andesite" -command [tesb-wake -caste ANDESITE -miner \\UNIT_ID -location [ \\LOCATION ] ]
--[=[
Only the caste ID is required, all others have defaults (though default x,y,z exists only when cursor is visible)
Includes portions of Rubble's announce.lua, Roses' add_attack.lua and expwent's unit-info-viewer.lua
Calls spawn-unit.lua to spawn the actual creature, falling back to tesb-spawn-unit.lua if needed
--]=]
local utils=require 'utils'
validArgs = validArgs or utils.invert({
'help',
'caste',
'wyrm',
'miner',
'location',
'friendly',
'unfriendly',
'custom'
})
local args = utils.processArgs({...}, validArgs)
if args.help then
print([[scripts/tesb-spawn.lua
arguments:
-help
Print this help message
-caste
Specify the type of awakened stone
This parameter is required
-wyrm
Spawn a wyrm instead of an awakened stone
Wyrms are never friendly
-location [ x y z ]
The location to spawn the awakened stone
Will default to the cursor location, if the cursor is displayed
-miner
Unit ID of creature causing the spawn
If miner has the caste's favor syndrome, the creature spawns Tame
If miner is omitted, "Something" without favor awakens the creature
-friendly
If flag is present, the awakened stone will be Tame
-unfriendly
If flag is present, the awakened stone will be a wild animal
-custom
If flag is present, use tesb-spawn-unit even if spawn-unit is available
Note: -friendly and -unfriendly override the miner's favor status
]])
return
end
function Announce(caste_id,unit_id,is_friendly,is_wyrm) -- Create an in-game announcement that a stone has awakened
-- Rubble's Announcement command, customized by Dirst for The Earth Strikes Back mod
--[[
Rubble Announcement DFHack Command
Copyright 2013-2014 Milo Christiansen
This software is provided 'as-is', without any express or implied warranty. In
no event will the authors be held liable for any damages arising from the use of
this software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to
the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim
that you wrote the original software. If you use this software in a product, an
acknowledgment in the product documentation would be appreciated but is not
required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
]]
if not dfhack.isMapLoaded() then
dfhack.printerr('Error: Map is not loaded.')
return
end
local caste_name = string.upper(string.sub(caste_id,1,1))..string.lower(string.sub(caste_id,2,-1))
if caste_name == "Rocksalt" then -- Special handling for two-word stone
caste_name = "Rock Salt"
end
local unit_name
if not unit_id then
unit_name = "Something" -- The player activated the script in an interactive window.
else
unit_name = dfhack.TranslateName(dfhack.units.getVisibleName(df.unit.find(unit_id)))
end
if is_wyrm then
text = unit_name.." has released a newly-hatched "..caste_name.." Wyrm!"
color_id = "COLOR_RED"
else
if is_friendly == true then
text = unit_name.." has awakened a creature of Living "..caste_name
color_id = "COLOR_WHITE"
else
text = unit_name.." has incurred the wrath of an Awakened "..caste_name
color_id = "COLOR_RED"
end
end
local color = _G[color_id]
dfhack.gui.showAnnouncement(text, color)
print(text)
end
function IsItFriendly(caste,miner,is_friendly,is_unfriendly)
-- is_unfriendly overrides is_friendly which overrides miner's status
-- The default is false if nothing was specified
local verdict = false
if is_unfriendly then -- Command line flag
verdict = false
elseif is_friendly then -- Command line flag
verdict = true
elseif miner then
local miner_unit = df.unit.find(miner)
local syndrome_list = miner_unit.syndromes.active
if caste == "ROCKSALT" then caste = "rock salt" end -- Special handling for two-word stone
local favor_syndrome_name = string.lower(caste).." favor"
for index,syndrome in ipairs(syndrome_list) do -- No need to check for 0 syndromes because this script is called by a syndrome-trigger
local syndrome_info = df.syndrome.find(syndrome.type)
if syndrome_info.syn_name == favor_syndrome_name then -- Unit has the appropriate "favor" syndrome
verdict = true
break
end
end
end
return verdict
end
-- add_attack() from a prototype of Roses' add_attack.lua
function add_attack(attacker_id,defender_id,target,weapon)
attacker = df.unit.find(attacker_id)
defender = df.unit.find(defender_id)
j = 0
while j < 1 do
action = df.unit_action:new()
action.id = attacker.next_action_id
attacker.next_action_id = attacker.next_action_id + 1
action.type = 1
attack = action.data.attack
attack.target_unit_id = defender_id
attack.attack_item_id = -1
attack.target_body_part_id = tonumber(target)
attack.attack_body_part_id = tonumber(weapon)
attack.unk_30 = 1
attack.attack_id = 0
attack.flags = 0
attack.unk_28 = 100
attack.unk_2c = 100
attack.unk_38 = 100
attack.unk_3c = 100
attack.timer1 = 1
attack.timer2 = 1
for i,x in pairs(attack.unk_4) do
attack.unk_4[i] = 0
end
attack.unk_4.wrestle_type = -1
attacker.actions:insert('#',action)
j = j + 1
end
end
-- Conversion table of CASTE_IDs to caste indices
local caste_table = {
["ANDESITE"] = 0,
["BASALT"] = 1,
["CHALK"] = 2,
["CHERT"] = 3,
["CLAYSTONE"] = 4,
["CONGLOMERATE"] = 5,
["DACITE"] = 6,
["DIORITE"] = 7,
["DOLOMITE"] = 8,
["GABBRO"] = 9,
["GNEISS"] = 10,
["GRANITE"] = 11,
["LIMESTONE"] = 12,
["MARBLE"] = 13,
["MUDSTONE"] = 14,
["PHYLLITE"] = 15,
["QUARTZITE"] = 16,
["RHYOLITE"] = 17,
["ROCKSALT"] = 18,
["SANDSTONE"] = 19,
["SCHIST"] = 20,
["SHALE"] = 21,
["SILTSTONE"] = 22,
["SLATE"] = 23
}
local argFriendly
local argCustom
local spawn_cmd
argCustom = (string.match(dfhack.run_command_silent("spawn-unit -help"),"-age ")~="-age ")
if args.custom or argCustom==true then
spawn_cmd = "tesb-spawn-unit"
else
spawn_cmd = "spawn-unit"
end
argFriendly = IsItFriendly(args.caste,args.miner,args.friendly,args.unfriendly)
Announce(args.caste,args.miner,argFriendly,args.wyrm)
local command = "-caste "..caste_table[args.caste].." -age 0"
if args.location then
command = command.." -position [ "..args.location[1].." "..args.location[2].." "..args.location[3].." ]"
-- Spawn 0 to 2 Pet Rocks alongside the Awakened Stone or Wyrm.
-- The castes of Pet Rocks are in the same order as those of large creature.
if math.random(0,2) == 2 then dfhack.run_command(spawn_cmd.." -race TESB_PET_ROCK "..command) end
if math.random(0,3) == 3 then dfhack.run_command(spawn_cmd.." -race TESB_PET_ROCK "..command) end
end
if args.wyrm then
if argFriendly == false then
dfhack.run_command(spawn_cmd.." -race TESB_WYRM "..command.." -civ_id \\-1")
-- Induce attack if miner provided
if args.miner then
local wyrm_id = df.global.unit_next_id-1
wyrm = df.unit.find(wyrm_id)
miner = df.unit.find(args.miner)
wyrm.opponent.unit_id = args.miner
wyrm.opponent.unit_pos.x = miner.pos.x
wyrm.opponent.unit_pos.y = miner.pos.y
wyrm.opponent.unit_pos.z = miner.pos.z
wyrm.opponent.anon_1 = 300
wyrm.mood = 7
add_attack(wyrm_id,args.miner,3,12) -- Unit targets head, but seems to ignore instructions to attack with its tail
end
else
dfhack.run_command(spawn_cmd.." -race TESB_WYRM "..command.." -civ_id \\-1")
end
else
if argFriendly == false then
dfhack.run_command(spawn_cmd.." -race TESB_AWAKENED_STONE "..command.." -civ_id \\-1")
-- Induce attack if miner provided
if args.miner then
local stone_id = df.global.unit_next_id-1
stone = df.unit.find(stone_id)
miner = df.unit.find(args.miner)
stone.opponent.unit_id=args.miner
stone.opponent.unit_pos.x = miner.pos.x
stone.opponent.unit_pos.y = miner.pos.y
stone.opponent.unit_pos.z = miner.pos.z
stone.opponent.anon_1 = 300
stone.mood = 7
add_attack(stone_id,args.miner,3,5) -- Unit targets head, but seems to ignore instructions to attack with its right front claw
end
else
dfhack.run_command(spawn_cmd.." -race TESB_AWAKENED_STONE "..command)
end
end