Ask a simple question, get a simple answer

Ask for help about creating mods and scripts for Grimrock 2 or share your tips, scripts, tools and assets with other modders here. Warning: forum contains spoilers!
User avatar
zimberzimber
Posts: 432
Joined: Fri Feb 08, 2013 8:06 pm

Re: Ask a simple question, get a simple answer

Post by zimberzimber »

PedroMoniz wrote:thank you,

A question, is it possible to get the traits? There is an add and a has function, but is there any work around to find the traits?

Code: Select all

Champion:hasTrait(string)
ItemComponent:hasTrait(string)
http://www.grimrock.net/modding/scripting-reference/
My asset pack [v1.10]
Features a bit of everything! :D
minmay
Posts: 2770
Joined: Mon Sep 23, 2013 2:24 am

Re: Ask a simple question, get a simple answer

Post by minmay »

zimberzimber wrote:Question - Can someone please explain to me the point of the 'cloneObject' add-on when you can just define an object from a base one?
defineObject with a baseObject:
- effectively appends the contents of the new components table to the baseObject's components table, so components with new names will be added and components with already-used names will completely overwrite the old ones
- merges the tags table if present
- copies the rest of the fields from the baseObject; if new values are specified for those fields, they overwrite the old ones

JKos's cloneObject addon does all of the above, plus, if the new object specifies a component with the same name as a baseObject component, it inherits the fields from the baseObject component. So this code:

Code: Select all

defineObject{
  name = "cactus",
  placement = "floor",
  components = {
    {
      class = "Model",
      model = "mod_assets/cactus.fbx",
      staticShadow = true,
    }
  }
  editorIcon = 100,
}

defineObject{
  name = "big_cactus",
  baseObject = "cactus",
  components = {
    {
      class = "Model",
      model = "mod_assets/big_cactus.fbx",
    }
  }
}
results in a big_cactus object without staticShadow on its ModelComponent. However, this:

Code: Select all

cloneObject{
  name = "big_cactus",
  baseObject = "cactus",
  components = {
    {
      class = "Model",
      model = "mod_assets/big_cactus.fbx",
    }
  }
}
would result in a big_cactus object with staticShadow, since cloneObject tries to inherit component properties and defineObject does not.
Grimrock 1 dungeon
Grimrock 2 resources
I no longer answer scripting questions in private messages. Please ask in a forum topic or this Discord server.
User avatar
Zo Kath Ra
Posts: 932
Joined: Sat Apr 21, 2012 9:57 am
Location: Germany

Re: Ask a simple question, get a simple answer

Post by Zo Kath Ra »

PedroMoniz wrote:thank you,

A question, is it possible to get the traits? There is an add and a has function, but is there any work around to find the traits?
Do you mean a list of all traits possessed by a champion or item?
User avatar
Isaac
Posts: 3179
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

Traits can be user defined, but here is the list of the official seen in the game: https://github.com/JKos/log2doc/wiki/Traits
PedroMoniz
Posts: 16
Joined: Wed Jan 11, 2017 9:46 pm

Re: Ask a simple question, get a simple answer

Post by PedroMoniz »

Zo Kath Ra wrote:
PedroMoniz wrote:thank you,

A question, is it possible to get the traits? There is an add and a has function, but is there any work around to find the traits?
Do you mean a list of all traits possessed by a champion or item?
yes, at the moment I have a work around but having a getTraits or a way to access the traits would be good.

maybe there is a .traits I am missing
sleepy
Posts: 15
Joined: Wed Feb 04, 2015 2:34 am

Re: Ask a simple question, get a simple answer

Post by sleepy »

I'm not sure if this is a simple question. I'm passing the .model file into GMT 2, out to .obj, into 3DSMax, and back out to .obj, into GMT, and out to .model.
Obviously the problem here is that I'm missing the skeleton.

Is there a way I can open the .model file directly with either 3DS or Blender which will preserve the rigging/node structure?
If not, is there a way I can retrieve mesh and skeleton separately and merge the two?
Or is the only option to animate from scratch when doing any model modification?
Does GrimFBX work for LoG2?

Regardless of if I can pull the LoG skeletons, I still need a way to get that information to .model, which, I'm uncertain of if the Blender plugin can do that given the way it imports. Any pointers would be greatly appreciated. My current thinking is to build entirely from scratch in 3DS, out to .fbx, and hope there's a working method to convert that smoothly into .model; since the game uses .fbx internally. At very least I could then pull the mesh from .obj and just re-rig and animate it.
User avatar
Isaac
Posts: 3179
Joined: Fri Mar 02, 2012 10:02 pm

Re: Ask a simple question, get a simple answer

Post by Isaac »

You need Blender version 2.71, 2.72, or 2.73, and Bitcopy's Grimrock import/export script. GMT is an LoG1 tool; it knows the model format, but does not know the animation format for LoG2.


viewtopic.php?f=22&t=8086

With these installed, you can import and export models and animations [rigging] for both games.
sleepy
Posts: 15
Joined: Wed Feb 04, 2015 2:34 am

Re: Ask a simple question, get a simple answer

Post by sleepy »

thank you. I was using the recent build of Blender. That's probably why the positioning was so off on everything.

EDIT: time to start learning Blender.
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Ask a simple question, get a simple answer

Post by akroma222 »

PedroMoniz wrote:
Zo Kath Ra wrote:
PedroMoniz wrote:thank you,
A question, is it possible to get the traits? There is an add and a has function, but is there any work around to find the traits?
Do you mean a list of all traits possessed by a champion or item?
yes, at the moment I have a work around but having a getTraits or a way to access the traits would be good.
maybe there is a .traits I am missing
PedroMoniz, this thread will help to read over....
viewtopic.php?f=22&t=14541&hilit=traitManager&start=10

Also, minmay's traitManager script
( TO ADD/REMOVE A TRAIT PROPERLY WHEN EQUIPPING ITEMS)
SpoilerShow

Code: Select all

    -- USAGE: Instead of calling champion:addTrait and
    -- champion:removeTrait, call traitManager.addTrait and
    -- traitManager.removeTrait. This will prevent equipment swapping
    -- from destroying permanent traits and the like.
    -- For example, instead of champion:addTrait("tough",true) call
    -- traitManager.addTrait(champion,"tough",true).
    -- Note: You shouldn't (and can't) use this script for skill
    -- traits (such as quick_strike) as the counts would be
    -- rendered inaccurate anyway by players increasing their skills.
     
    TRAIT_LIST = {
       -- Regular traits.
       
       head_hunter = true,
       skilled = true,
       fast_learner = true,
       rage = true,
       fast_metabolism = true,
       endure_elements = true,
       poison_immunity = true,
       chitin_armor = true,
       quick = true,
       mutation = true,
       aggressive = true,
       agile = true,
       healthy = true,
       athletic = true,
       strong_mind = true,
       aura = true,
       tough = true,
       cold_resistant = true,
       evasive = true,
       fire_resistant = true,
       weapon_specialization = true,
       endurance = true,
       lightning_speed = true,
       natural_armor = true,
       poison_resistant = true,
       uncanny_speed = true,
       leadership = true,
       nightstalker = true,
       
       -- Skill traits. Currently excluded.
       
       --[["pack_mule",
       "meditation",
       "two_handed_mastery",
       "light_armor_proficiency",
       "heavy_armor_proficiency",
       "armor_expert",
       "shield_expert",
       "staff_defence",
       "improved_alchemy",
       "bomb_expert",
       "backstab",
       "assassin",
       "firearm_mastery",
       "dual_wield",
       "improved_dual_wield",
       "piercing_arrows",
       "double_throw",
       "reach",
       "uncanny_speed",
       "fire_mastery",
       "air_mastery",
       "earth_mastery",
       "water_mastery"]]
       
    --LoG1 skill traits
       --[["greater_lightning_bolt",
       "air_circle",
       "light_armor",
       "heavy_armor",
       "shield_expert",
       "backstab",
       "reach_attack",
       "improved_backstab",
       "quick_strike",
       "improved_critical",
       "piercing_attack",
       "improved_quick_strike",
       "assassin_master",
       "endurance",
       "porter",
       "chop",
       "cleave",
       "rampage",
       "axe_master",
       "stab",
       "piercing_strike",
       "flurry_slashes",
       "dagger_master",
       "stealth",
       "light_armor",
       "improved_stealth",
       "improved_poison_bolt",
       "earth_circle",
       "greater_fireball",
       "fire_circle",
       "improved_frostbolt",
       "ice_circle",
       "bash",
       "crushing_blow",
       "devastating_blow",
       "mace_master",
       "quick_shot",
       "improved_quick_shot",
       "volley",
       "master_archer",
       "combat_caster",
       "improved_combat_caster",
       "archmage",
       "light_armor",
       "slash",
       "parry",
       "thrust",
       "flurry_slashes",
       "sword_master",
       "quick_throw",
       "improved_quick_throw",
       "double_throw",
       "throwing_master",
       "jab",
       "kick",
       "three_point_technique"]]
    }

    traits = {}

    -- add a trait and increase "level" of that trait by 1
    function addTrait(champion,trait,silent)
       if not TRAIT_LIST[trait] then
          print("warning: invalid trait: "..trait)
       end

       if traits[champion:getOrdinal()][trait] == 0 then
          champion:addTrait(trait,silent)
       end
       traits[champion:getOrdinal()][trait] = traits[champion:getOrdinal()][trait] + 1
    end

    -- decrease "level" of a trait by 1, removing it if it reaches 0
    function removeTrait(champion,trait)
       --local name = champion:getName()
       if traits[champion:getOrdinal()][trait] == 1 then
          champion:removeTrait(trait)
          --hudPrint(""..name.." gained the agile trait.")
       end
       traits[champion:getOrdinal()][trait] = traits[champion:getOrdinal()][trait] - 1
    end

    -- get the traits the party started with
    function gatherInitialTraits()
       for i = 1, 4 do
          local champion = party.party:getChampion(i)
          traits[champion:getOrdinal()] = {}
          for trait,dummy in pairs(TRAIT_LIST) do
             if champion:hasTrait(trait) then
                traits[champion:getOrdinal()][trait] = 1
             else
                traits[champion:getOrdinal()][trait] = 0
             end
          end
       end
    end
    gatherInitialTraits()
And if you are changing skill Levels with item equips - a similar script so skill levels are changed properly
SpoilerShow

Code: Select all

    -----------------------------------------------------------------\
    ------------------------------------------------------------written by Akroma
    --Put this in a script entity (skillManager) in your dungeon
    --To increase skills use:    skillUp(champion,skill,levelup,silent)
    --to decrease skills use:    skillDown(champion,skill,leveldown,silent)
    --do not use a negative (-) sign in front of leveldown^^
    ---------------------------------------------------------------------------------
    -----------------------------------------------------------------SKILL_LIST

    SKILL_LIST = {
       alchemy = true,
       athletics = true,
       concentration = true,
       light_weapons = true,
       heavy_weapons = true,
       missile_weapons = true,
       poison_immunity = true,
       throwing = true,
       firearms = true,
       accuracy = true,
       critical = true,
       armors = true,
       dodge = true,
       fire_magic = true,
       air_magic = true,
       earth_magic = true,
       water_magic = true
    }

    ----------------------------------------------------------------

    skillsTotal = {}

    skillsBonus = {}

    skillsBase = {}

    skillsMaxCapCount = {}

    -----------------------------------------------------------------gatherInitialSkillLevels()
    function gatherInitialSkillLevels()
       for i = 1, 4 do
          local champion = party.party:getChampion(i)      
          skillsTotal[champion:getOrdinal()] = {}
          skillsBonus[champion:getOrdinal()] = {}
          skillsBase[champion:getOrdinal()] = {}
          skillsMaxCapCount[champion:getOrdinal()] = {}
          for skill,dummy in pairs(SKILL_LIST) do
             local cSkill = champion:getSkillLevel(skill)
             skillsTotal[champion:getOrdinal()][skill] = cSkill
             skillsBase[champion:getOrdinal()][skill] = cSkill
             skillsBonus[champion:getOrdinal()][skill] = 0
             skillsMaxCapCount[champion:getOrdinal()][skill] = 0
          end
       end
    end

    gatherInitialSkillLevels()

    ----------------------------------------------------------------skillUp(champion,skill,levelup,silent)

    function skillUp(champion,skill,levelup,silent)

       local tempbonus = skillsBonus[champion:getOrdinal()][skill] + levelup
       local capcount = skillsMaxCapCount[champion:getOrdinal()][skill]
       local cSkill = champion:getSkillLevel(skill)
       if cSkill == 5 then
          capcount = capcount + levelup
       end
       champion:trainSkill(skill,levelup, false)
       gatherSkillLevelsUp(champion, skill, tempbonus, capcount)
       
       print(""..skill.." bonus = "..skillsBonus[champion:getOrdinal()][skill].."")
       print(""..skill.." base = "..skillsBase[champion:getOrdinal()][skill].."")
       print(""..skill.." total = "..skillsTotal[champion:getOrdinal()][skill].."")
       print(""..skill.." capcount = "..skillsMaxCapCount[champion:getOrdinal()][skill].."")
       
    end
       
    -----------------------------------------------------------------gatherSkillLevelsUp(champion,skill, tempbonus, capcount)
    function gatherSkillLevelsUp(champion,skill, tempbonus, capcount)
       
       local cSkill = champion:getSkillLevel(skill) + capcount
       skillsTotal[champion:getOrdinal()][skill] = cSkill
       skillsBonus[champion:getOrdinal()][skill] = tempbonus
       skillsBase[champion:getOrdinal()][skill] = skillsTotal[champion:getOrdinal()][skill] - tempbonus
       skillsMaxCapCount[champion:getOrdinal()][skill] = capcount
    end

    -----------------------------------------------------------------skillDown(champion,skill,leveldown,silent)
    function skillDown(champion,skill,leveldown,silent)

       local tempbonus = skillsBonus[champion:getOrdinal()][skill] - leveldown
       local capcount = skillsMaxCapCount[champion:getOrdinal()][skill]
       local cSkill = champion:getSkillLevel(skill)
       
       stripSkillBonuses(champion, skill, cSkill, leveldown, capcount)
       champion:trainSkill(skill,(-leveldown + capcount), false)
       gatherSkillLevelsDown(champion, skill, tempbonus, capcount)
       
       print(""..skill.." bonus = "..skillsBonus[champion:getOrdinal()][skill].."")
       print(""..skill.." base = "..skillsBase[champion:getOrdinal()][skill].."")
       print(""..skill.." total = "..skillsTotal[champion:getOrdinal()][skill].."")
       print(""..skill.." capcount = "..skillsMaxCapCount[champion:getOrdinal()][skill].."")
    end

    -----------------------------------------------------------------gatherSkillLevelsDown(champion, skill, tempbonus, capcount)
    function gatherSkillLevelsDown(champion, skill, tempbonus, capcount)
          
       local cSkill = champion:getSkillLevel(skill)
       skillsTotal[champion:getOrdinal()][skill] = cSkill + tempbonus
       skillsBonus[champion:getOrdinal()][skill] = tempbonus
       if cSkill == 5 then   
          skillsMaxCapCount[champion:getOrdinal()][skill] = tempbonus
       end
    end

    --------------------------------------------------------------------------
    -------------------------------------------------- -----------------------SKILL_BONUSES

    SKILL_BONUSES = {

              alchemy = {
                 [4] = "improved_alchemy",
                 [5] = "bomb_expert"
              },
          athletics = {
                 [3] = "pack_mule"
              },
          concentration = {
                 [3] = "meditation"
              },
          light_weapons = {
                 [3] = "dual_wield",
                 [5] = "improved_dual_wield"
              },
          heavy_weapons = {
                 [5] = "two_handed_mastery"
              },
          missile_weapons = {
                 [4] = "piercing_arrows"
              },
          throwing = {
                 [5] = "double_throw"
              },
          firearms = {
                 [5] = "firearm_mastery"
              },
          accuracy = {
                 [2] = "reach"
              },
          critical = {
                 [3] = "backstab",
               [5] = "assassin"
              },
          armors = {
                 [3] = "uncanny_speed"
          },
          fire_magic = {
                 [5] = "fire_mastery"
              },
          air_magic = {
                 [5] = "air_mastery"
              },
          earth_magic = {
                 [5] = "earth_mastery"
              },
          water_magic = {
                 [5] = "water_mastery"
              }
    }
    ------------------------------------------------------------------------------stripSkillBonuses(champion, skill, cSkill, leveldown, capcount)

       function stripSkillBonuses(champion, skill, cSkill, leveldown, capcount)

              for s,bonuses in pairs(SKILL_BONUSES) do
             if s == skill then
                    local sLevel = cSkill
                    local bonus = bonuses[(sLevel + capcount)]
                    if bonus then
                         champion:removeTrait(bonus)
                   print(""..bonus.." removed")
                   hudPrint(""..champion:getName().." loses the "..bonus.." trait.")
                    end
                 end
              end
        end
       
User avatar
akroma222
Posts: 1029
Joined: Thu Oct 04, 2012 10:08 am

Re: Ask a simple question, get a simple answer

Post by akroma222 »

Question - can we recreate Attack Swipes ??
I know all the Attack Swipe models are in the asset pack, using "swipe01" material.
...and also that we can set new materials/textures etc etc
Just wondering if we can actually override / replicate / mimic the Attack Swipes ??
Ta!
Post Reply