v50 Steam/Premium information for editors
  • v50 information can now be added to pages in the main namespace. v0.47 information can still be found in the DF2014 namespace. See here for more details on the new versioning policy.
  • Use this page to report any issues related to the migration.
This notice may be cached—the current version can be found here.

Difference between revisions of "Demon/script"

From Dwarf Fortress Wiki
Jump to navigation Jump to search
(from 53.15 creatures.lua)
 
(added demon_names block)
 
Line 1: Line 1:
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
 +
demon_names={
 +
    {name="demon",names="demons",name_adj="demonic",cond=function(options) return true end},
 +
    {name="devil",names="devils",name_adj="devilish",cond=function(options) return true end},
 +
    {name="fiend",names="fiends",name_adj="fiendish",cond=function(options) return true end},
 +
    {name="brute",names="brutes",name_adj="brutish",cond=function(options) return adj_exploitable_check(options.fadj) end},
 +
    {name="monster",names="monsters",name_adj="monster",cond=function(options) return true end},
 +
    {name="spirit",names="spirits",name_adj="spirit",cond=function(options) return options.intangible end},
 +
    {name="ghost",names="ghosts",name_adj="ghost",cond=function(options) return options.intangible end},
 +
    {name="banshee",names="banshees",name_adj="banshee",cond=function(options) return options.intangible end},
 +
    {name="haunt",names="haunts",name_adj="haunt",cond=function(options) return options.intangible end},
 +
    {name="phantom",names="phantoms",name_adj="phantom",cond=function(options) return options.intangible end},
 +
    {name="specter",names="specters",name_adj="specter",cond=function(options) return options.intangible end},
 +
    {name="wraith",names="wraiths",name_adj="wraith",cond=function(options) return options.intangible end},
 +
}
 +
 
creatures.demon.default=function(demon_type,difficulty,tok)
 
creatures.demon.default=function(demon_type,difficulty,tok)
 
     local tbl={}
 
     local tbl={}

Latest revision as of 08:30, 30 June 2026

demon_names={
    {name="demon",names="demons",name_adj="demonic",cond=function(options) return true end},
    {name="devil",names="devils",name_adj="devilish",cond=function(options) return true end},
    {name="fiend",names="fiends",name_adj="fiendish",cond=function(options) return true end},
    {name="brute",names="brutes",name_adj="brutish",cond=function(options) return adj_exploitable_check(options.fadj) end},
    {name="monster",names="monsters",name_adj="monster",cond=function(options) return true end},
    {name="spirit",names="spirits",name_adj="spirit",cond=function(options) return options.intangible end},
    {name="ghost",names="ghosts",name_adj="ghost",cond=function(options) return options.intangible end},
    {name="banshee",names="banshees",name_adj="banshee",cond=function(options) return options.intangible end},
    {name="haunt",names="haunts",name_adj="haunt",cond=function(options) return options.intangible end},
    {name="phantom",names="phantoms",name_adj="phantom",cond=function(options) return options.intangible end},
    {name="specter",names="specters",name_adj="specter",cond=function(options) return options.intangible end},
    {name="wraith",names="wraiths",name_adj="wraith",cond=function(options) return options.intangible end},
}

creatures.demon.default=function(demon_type,difficulty,tok)
    local tbl={}
    local l2=get_debug_logger(2)
    l2(tok,demon_type,difficulty)
    local options={
        is_evil=true,
        pick_sphere_rcm=true,
        strong_attack_tweak=true,
        always_nobreathe=true,
        force_goo=true,
        intangible_flier=true,
        fixed_temp=10040,
        forced_odor_chance=2,
        forced_odor_string="brimstone",
        forced_odor_level=90,
        sickness_name="demon sickness",
        feature_flavor_adj=true,
        fire_immune=true,
        token=tok
    }
    if demon_type=="unique" then
        tbl=split_to_lines(tbl,[[
[UNIQUE_DEMON]
[SPREAD_EVIL_SPHERES_IF_RULER]

[NATURAL_SKILL:WRESTLING:14]
[NATURAL_SKILL:BITE:14]
[NATURAL_SKILL:GRASP_STRIKE:14]
[NATURAL_SKILL:STANCE_STRIKE:14]
[NATURAL_SKILL:MELEE_COMBAT:14]
[NATURAL_SKILL:RANGED_COMBAT:14]
[NATURAL_SKILL:DODGING:14]
[NATURAL_SKILL:SITUATIONAL_AWARENESS:14]

[CAN_LEARN][CAN_SPEAK][DIFFICULTY:10]
        ]])
        options.humanoidable_only=true
        options.can_learn=true
    else
        tbl=split_to_lines(tbl,[[
[DEMON]

[NATURAL_SKILL:WRESTLING:10]
[NATURAL_SKILL:BITE:10]
[NATURAL_SKILL:GRASP_STRIKE:10]
[NATURAL_SKILL:STANCE_STRIKE:10]
[NATURAL_SKILL:MELEE_COMBAT:10]
[NATURAL_SKILL:RANGED_COMBAT:10]
[NATURAL_SKILL:DODGING:10]
[NATURAL_SKILL:SITUATIONAL_AWARENESS:10]
        ]])
        if(demon_type=="humanoid_beast") then options.humanoidable_only=true end
        if one_in(2) then 
            tbl[#tbl+1]="[CAN_LEARN][CAN_SPEAK]"
            options.can_learn=true
        end
        tbl=split_to_lines(tbl,[[
[LARGE_ROAMING]
[LARGE_PREDATOR][DIFFICULTY:]]..tostring(difficulty)..[[]
[BIOME:SUBTERRANEAN_CHASM]
[UNDERGROUND_DEPTH:5:5]
[POPULATION_NUMBER:5:10]
[CLUSTER_NUMBER:1:5]
]])
        options.fallback_pref_str="horrifying features"
    end
    pick_random({
        function()
            tbl[#tbl+1]="[CASTE:FEMALE]"
            tbl[#tbl+1]="[FEMALE]"
            tbl[#tbl+1]="[CASTE:MALE]"
            tbl[#tbl+1]="[MALE]"
            tbl[#tbl+1]="[SELECT_CASTE:ALL]"
        end,
        function()
            tbl[#tbl+1]="[MALE]"
        end,
        function()
            tbl[#tbl+1]="[FEMALE]"
        end,
        function()
            tbl[#tbl+1]="[NO_GENDER]"
        end
    })()
    tbl=split_to_lines(tbl,[[[PHYS_ATT_RANGE:STRENGTH:450:1050:1150:1250:1350:1550:2250]
[PHYS_ATT_RANGE:TOUGHNESS:450:1050:1150:1250:1350:1550:2250]
[PHYS_ATT_RANGE:ENDURANCE:450:1050:1150:1250:1350:1550:2250]
[PHYS_ATT_RANGE:RECUPERATION:450:1050:1150:1250:1350:1550:2250]
[PHYS_ATT_RANGE:DISEASE_RESISTANCE:700:1300:1400:1500:1600:1800:2500]
[MENT_ATT_RANGE:ANALYTICAL_ABILITY:1250:1500:1750:2000:2500:3000:5000]
[MENT_ATT_RANGE:FOCUS:1250:1500:1750:2000:2500:3000:5000]
[MENT_ATT_RANGE:WILLPOWER:1250:1500:1750:2000:2500:3000:5000]
[MENT_ATT_RANGE:PATIENCE:0:333:666:1000:2333:3666:5000]
[MENT_ATT_RANGE:MEMORY:1250:1500:1750:2000:2500:3000:5000]
[MENT_ATT_RANGE:LINGUISTIC_ABILITY:450:1050:1150:1250:1350:1550:2250]
[MENT_ATT_RANGE:MUSICALITY:0:333:666:1000:2333:3666:5000]
[MENT_ATT_RANGE:SOCIAL_AWARENESS:700:1300:1400:1500:1600:1800:2500]
[PERSONALITY:ANXIETY_PROPENSITY:0:0:0]
[PERSONALITY:DEPRESSION_PROPENSITY:0:0:0]
[PERSONALITY:BASHFUL:0:0:0]
[PERSONALITY:STRESS_VULNERABILITY:0:0:0]
[PERSONALITY:FRIENDLINESS:0:0:0]
[PERSONALITY:ASSERTIVENESS:100:100:100]
[PERSONALITY:DISDAIN_ADVICE:100:100:100]
[PERSONALITY:CHEER_PROPENSITY:0:0:0]
[PERSONALITY:GRATITUDE:0:0:0]
[PERSONALITY:TRUST:0:0:0]
[PERSONALITY:ALTRUISM:0:0:0]
[PERSONALITY:SWAYED_BY_EMOTIONS:0:0:0]
[PERSONALITY:CRUELTY:100:100:100]
[PERSONALITY:PRIDE:100:100:100]
[PERSONALITY:GREED:100:100:100]
[NO_DRINK][NO_EAT][NO_SLEEP]
[BODY_APPEARANCE_MODIFIER:HEIGHT:90:95:98:100:102:105:110]
[BODY_APPEARANCE_MODIFIER:BROADNESS:90:95:98:100:102:105:110]
[MAGMA_VISION]
[EVIL]
[FANCIFUL]
[SUPERNATURAL]
]])
    add_regular_tokens(tbl,options)
    local available_sphere_cur={}
    local available_sphere={}
    options.spheres={}
    l2("Starting spheres")
    for k,v in pairs(world.spheres) do
        available_sphere_cur[k]=true
        available_sphere[k]=true
    end
    --ANY SPHERE COLLECTION + ONE EVIL + NO PURE GOOD/CIVIS/FLUFF STUFF
    available_sphere_cur.AGRICULTURE=false;
    available_sphere_cur.BALANCE=false;
    available_sphere_cur.CHARITY=false;
    available_sphere_cur.CONSOLATION=false;
    available_sphere_cur.COURAGE=false;
    available_sphere_cur.DUTY=false;
    available_sphere_cur.FAMILY=false;
    available_sphere_cur.FERTILITY=false;
    available_sphere_cur.FESTIVALS=false;
    available_sphere_cur.FORGIVENESS=false;
    available_sphere_cur.FREEDOM=false;
    available_sphere_cur.GENEROSITY=false;
    available_sphere_cur.HAPPINESS=false;
    available_sphere_cur.HEALING=false;
    available_sphere_cur.HOSPITALITY=false;
    available_sphere_cur.JUSTICE=false;
    available_sphere_cur.LABOR=false;
    available_sphere_cur.LOVE=false;
    available_sphere_cur.LOYALTY=false;
    available_sphere_cur.MARRIAGE=false;
    available_sphere_cur.MERCY=false;
    available_sphere_cur.OATHS=false;
    available_sphere_cur.PEACE=false;
    available_sphere_cur.PREGNANCY=false;
    available_sphere_cur.RAINBOWS=false;
    available_sphere_cur.REVELRY=false;
    available_sphere_cur.SACRIFICE=false;
    available_sphere_cur.TRADE=false;
    available_sphere_cur.TRAVELERS=false;
    available_sphere_cur.TRUTH=false;
    available_sphere_cur.VALOR=false;
    available_sphere_cur.WISDOM=false;
    local branch_number=trandom(2)+1
    while branch_number > 0 do
        local candidates={}
        -- not cleverness, just paranoia
        if branch_number<=1 then
            for k,v in ipairs(evil_spheres) do
                if available_sphere_cur[v] then candidates[#candidates+1]=v end
            end
        end
        if #candidates==0 then
            for k,v in pairsByKeys(available_sphere_cur) do
                if v then candidates[#candidates+1]=k end
            end
        end
        if #candidates then
            local new_s = pick_random(candidates)
            add_sphere_mpp(options.spheres,new_s,available_sphere,available_sphere_cur)
            while one_in(2) do
                candidates={}
                for k,v in pairsByKeys(world.spheres[new_s].friends) do
                    if available_sphere_cur[k] then
                        candidates[#candidates+1]=k
                    end
                end
                new_s = pick_random(candidates)
                if new_s then
                    add_sphere_mpp(options.spheres,new_s,available_sphere,available_sphere_cur)
                else
                    break
                end
            end
        end
        branch_number = branch_number-1
    end
    l2("Done with spheres")
    options.beast_only=demon_type=="humanoid_beast" or demon_type=="beast"
    if demon_type=="flying_spirit" then
        options.always_insubstantial=true
        options.always_make_uniform=true
    end
    populate_sphere_info(tbl,options)
    local rcp=get_random_creature_profile(options)
    local body_size = difficulty==6 and (400000+trandom(9)*10000 + trandom(11)*1000) or (10000000)
    add_body_size(tbl,math.max(body_size, rcp.min_size),options)
    tbl[#tbl+1]="[CREATURE_TILE:'&']"
    build_procgen_creature(rcp,tbl,options)
    tbl[#tbl+1]="[GO_TO_START]"
    options.flavor_adj = options.flavor_adj or {}
    options.potential_end_phrase = options.potential_end_phrase or {}
    local name_str=""
    if (#options.flavor_adj>0 or #options.potential_end_phrase>0) and one_in(3) then
        if trandom(#options.flavor_adj + #options.potential_end_phrase) > #options.flavor_adj then
            options.eadj=pick_random(options.potential_end_phrase)
            local name=pick_random_conditional(demon_names,"cond",options)
            name_str=name.name..options.eadj..":"..name.names..options.eadj..":"..name.name_adj..options.eadj
        else
            options.fadj=pick_random(options.flavor_adj)
            local name=pick_random_conditional(demon_names,"cond",options)
            name_str=options.fadj.." "..name.name..":"..options.fadj.." "..name.names..":"..name.name_adj
        end
    elseif not options.name_mat or #options.name_mat==0 then
        local name=pick_random_conditional(demon_names,"cond",options)
        name_str=rcp.name_string.." "..name.name..":"..rcp.name_string.." "..name.names..":"..rcp.name_string.." "..name.name_adj
    else
        local name=pick_random_conditional(demon_names,"cond",options)
        local nmm=pick_random(options.name_mat)
        if one_in(2) then
            name_str=name.name.." of "..nmm..":"..name.names.." of "..nmm..":"..name.name.." of "..nmm
        else
            name_str=nmm.." "..name.name..":"..nmm.." "..name.names..":"..nmm..":"..name.name_adj
        end
    end
    if name_str=="" then
        local name=pick_random_conditional(demon_names,"cond",options)
        name_str=rcp.name_string.." "..name.name..":"..rcp.name_string.." "..name.names..":"..rcp.name_string.." "..name.name_adj
    end
    if name_str=="" then
        name_str="glitch demon:glitch demons:glitch demon"
    end
    tbl[#tbl+1]="[NAME:"..name_str.."]"
    tbl[#tbl+1]="[CASTE_NAME:"..name_str.."]"
    return {raws=tbl,weight=1}
end