...........

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!
NutJob
Posts: 426
Joined: Sun Oct 19, 2014 6:35 pm

Re: [ [ Script ] ] -- Starting Items for Party

Post by NutJob »

Mysterious wrote:Hi NutJob. With that Script you made would you be able to create a Demo Mod, just 1 small level so we could see how your code works please Thxs :)
Sure, it's DungeonDemogorgon.zip and has the compiled version (.dat) and the source. I'm not claiming this is bug free because it's not though over the next few weeks when I find time I'll do my best to clean it up and make it a little more user friendly. Still have a lot to learn with this editor (and LUA; never used this scripting language).

I'm not sure if everyones game folder is the same but mine is located at: C:\Users\<user_name>\Documents\Almost Human\Legend of Grimrock 2\Dungeons
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: [ [ Script ] ] -- Starting Items for Party

Post by Drakkan »

Hi NutJob. in case you will have some time, please could you slightly change your script that it will give starting items defined by modder to particular party members and directly equip them ? (for example member1 will have equiped iron helm etc... you get the point). I am not sure if you already mapped all inventroy slots, so not sure how hard it could be.
Breath from the unpromising waters.
Eye of the Atlantis
NutJob
Posts: 426
Joined: Sun Oct 19, 2014 6:35 pm

Re: [ [ Script ] ] -- Starting Items for Party

Post by NutJob »

Drakkan wrote:Hi NutJob. in case you will have some time, please could you slightly change your script that it will give starting items defined by modder to particular party members and directly equip them ? (for example member1 will have equiped iron helm etc... you get the point). I am not sure if you already mapped all inventroy slots, so not sure how hard it could be.
It's weighted system so you change the items and how much factors into giving the champion a weapon (skills, class, primeStat, and position in party). If you change the weapons be sure to name it exactly like the baseName.

Edit: also feel free to add/remove skills (alchemy, accuracy, athletics, critical, concentration, armors, light_weapons, dodge, heavy_weapons, fire_magic, missile_weapons, air_magic, throwing, earth_magic, firearms, water_magic) to the factored-in-weight of item inclusion. I just added some standard ones; These are string references so use them like shown; ex. air_magic not Air Magic and don't 'quote' them.
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: [Script - WIP] -- Starting Items for Party

Post by Drakkan »

Hi NutJob. I tried equip scripts - I managed to equip weapon on start based on class and I also understand the skill managment. But feq questions

1. I´d like my champion equip also some armor or item in inventory, not just weapon(s). is that possible ?

2. I don not understand how to manage the second script or what is it for ? when I try to trigger some of these functions, it fall with some error. please advice.

Code: Select all

    function getPrimaryStat(_party)
       -- should be a table containing the character object
       local _c;
       -- if nothing's passed then get it
       if _party == nil then _c = getParty(false) end
       -- or get one party member
       if type(_party) == "number" then _c = getParty(_party) end
       if type(_party) == "table" then _c = _party end
       if type(_c) ~= "table" then print("Unknown parameter_value:_party") return end

       local _stats = returnTbl("main_attributes")
       local _traits = returnTbl("main_traits")

       local _attributeInfluence = {}


       local countPrimeTraits = 0;
       local forcePrime = nil;
       local bTrait = false;
       local inc_v = 0; local high_v = 0; local high_stat = ""; local bTrait = false;

       for id,obj in ipairs(_c) do


          forcePrime = nil;
          countPrimeTraits = 0;
          for _,string in ipairs(_traits) do
             bTrait = obj:hasTrait(string)
             if bTrait then

                countPrimeTraits = countPrimeTraits + 1

                forcePrime = 'willpower'
                if string == "muscular" then forcePrime = 'strength'
                elseif string == "agile" then forcePrime = 'dexterity' end

             end
          end


          if countPrimeTraits > 1 then
             forcePrime = nil
          end


          if forcePrime ~= nil then
             _attributeInfluence[id] = forcePrime
          else

             high_v = 0; high_stat = ""
             for _,string in ipairs(_stats) do
                if string ~= 'vitality' then
                   inc_v = obj:getCurrentStat(string)
                   if inc_v > high_v then
                      high_v = inc_v; high_stat = string
                   end
                end
             end


             _attributeInfluence[id] = high_stat
          end

       end


       if #_attributeInfluence < 1 then
          print("Error _attributeInfluence Table not populated")
          return
       end

       return _attributeInfluence;

    end

    function getSkillSet(_party, bReturnVal)
       -- should be a table containing the character object
       local _c;
       -- if nothing's passed then get it
       if _party == nil then _c = getParty(false) end
       -- or get one character
       if type(_party) == "number" then _c = getParty(_party) end
       if type(_c) ~= "table" then print("Unknown parameter_value:_party") return end
       if bReturnVal == nil then bReturnVal = false end
       if type(bReturnVal) ~= "boolean" then
          print("Expecting boolean. getSkillSet:bReturnVal")
          return
       end



       local _r = {}

       local _skills = returnTbl("skills")


       local skillLevel = 0;
       for id,obj in ipairs(_c) do
          _r[id] = {}
          for i=1, #_skills do
             skillLevel = obj:getSkillLevel(_skills[i])
             if skillLevel > 0 then
                if bReturnVal ~= true then
                   table.insert(_r[id],_skills[i])
                else
                   _r[id][_skills[i]] = skillLevel
                end
             end
          end
       end

       return _r

    end

    function determinPrimaryHand(level)

    end



    function returnTbl(s)
       if type(s) ~= "string" then print("Parameter must be a string") end
       local _pSkills = {'alchemy','accuracy','athletics','critical',
       'concentration','armors','light_weapons','dodge',
       'heavy_weapons','fire_magic','missile_weapons',
       'air_magic','throwing','earth_magic','firearms',
       'water_magic'}
       local _pAttributes = {'strength', 'dexterity', 'vitality', 'willpower'}
       local _pTraits = {'muscular', 'agile', 'strong_mind'}
       if s == "main_attributes" then return _pAttributes end
       if s == "main_traits" then return _pTraits end
       if s == "skills" then return _pSkills end
       print("Unknown parameter:returnTbl")
    end

    function getParty(b)
       -- true: will get all character even if disabled
       -- false: will only get enabled characters
       -- number: will always get that character, even if the character is disabled
       local t = {}; local p = party.party; local x = nil;
       if b==nil then b=true end
       if type(b) == "number" then
          if b >= 1 and b < 5 then table.insert(t,p:getChampion(math.floor(b))) end
          return t
       end
       if b~=true then b=false end
       for i=1,4 do
          x = p:getChampion(i)
          if x:getEnabled() or b then table.insert(t,x) end
       end
       return t
    end


    function grantExp(exp,split,allowDead)
       local c = nil; local p = party.party; local a = {}; local perc = 0;
       if type(exp) == "string" then
          exp = trim(exp)
          if exp:sub(-1) == "%" then
             perc = exp:sub(1, -2) * 1;
          end

       else
          if exp == nil then print("Experience not set"); return false end
          if exp < 5 then print("Seriously, give out more experience than "..exp); return false end
       end

       if perc > 0 then
          -- no way to getMaxExp???
          local tblExpLevels = {
             1, 3, 6, 10, 15,
             21, 28, 36, 45, 55,
             75, 100, 150, 200, 250,
             300, 400, 500, 1000, 2000
          }
          local currCharLevel = 0;
          local expReqToLevel = 0;
          local startExp = 0;
          local tallyExp = 0;
          for i=1, 4 do
             c = p:getChampion(i)
             if c:getEnabled() then
                if c:isAlive() or allowDead then
                   currCharLevel = p:getChampion(i):getLevel() * 1
                   expReqToLevel = tblExpLevels[currCharLevel] * 1000
                   startExp = 0
                   if currCharLevel > 1 then
                      startExp = (tblExpLevels[(currCharLevel - 1)] * 1000)
                   end
                   tallyExp = (expReqToLevel - startExp) + tallyExp
                end
             end
          end

          if tallyExp > 0 then
             exp = math.ceil(  (perc / 100) * tallyExp)
             -- force split
             split = true
          end

       end

       if split == nil then split = true
       elseif type(split) ~= "boolean" then
          print("The split parameter must be set to true, false, or left blank")
          return false
       end
       if allowDead == nil then allowDead = false
       elseif type(allowDead) ~= "boolean" then
          print("The allowDead parameter must be set to true, false, or left blank")
          return false
       end

       for i=1, 4 do
          c = p:getChampion(i)
          if c:getEnabled() then
             if c:isAlive() or allowDead then
                table.insert(a,i)
             end
          end
       end

       if split ~= false then
          exp = math.ceil(exp / #a)
       end

       for _,n in ipairs(a) do
          p:getChampion(n):gainExp(exp)
       end
    end

    function trim(s)
        return s:find'^%s*$' and '' or s:match'^%s*(.*%S)'
    end
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
QuintinStone
Posts: 72
Joined: Sat Nov 01, 2014 9:58 pm

Re: ...........

Post by QuintinStone »

With NutJob's script removed, I built my own. It's a lot lot less versatile than what I've seen of NutJob's, but it serves my needs. Crappy weapons, basic clothing, some food, other miscellaneous items. Because of the dungeon I'm working on, it also gives a shovel to the first 2 champions.

I launch the script via a 0 second timer that starts when the game starts.

Code: Select all

function equipChampions()
	if party ~= nil then
		for i=1,4 do
			if party.party:getChampion(i) ~= nil then
				local skill = findPrimarySkill(party.party:getChampion(i))
				giveEquipment(party.party:getChampion(i), skill, i)
			end
		end
	end
end

function findPrimarySkill(champ)
	local skill_list = { "armors", "missile_weapons", "throwing", "firearms", "light_weapons", "heavy_weapons", "concentration", "alchemy" }
	if champ == nil then
		--hudPrint("nil champion")
		return
	end
	--local scroll = spawn("scroll",party.level, party.x, party.y, party.elevation, party.facing)
	local text = ""
	local primary = ""
	local maxskill = 0
	for _,skill_name in ipairs(skill_list) do
		if champ:getSkillLevel(skill_name) == nil then
			text = text .. skill_name .. " is nil\r\n"
		else
			text = text .. skill_name .. " = " .. champ:getSkillLevel(skill_name) .. "\r\n"
		end
		if champ:getSkillLevel(skill_name) >= maxskill then
			primary = skill_name
			maxskill = champ:getSkillLevel(skill_name)
		end
	end
	--scroll.scrollitem:setScrollText(text)
	--scroll.scrollitem:setTextAlignment("left")
	if maxskill == 0 then
		return "none"
	else
		return primary
	end
end

function giveEquipment(champ, skill, ord)
	--hudPrint(champ:getName() .. " " .. skill)
	local inv = {}
	local right
	local left
	local armor = {}
	for i=1,32 do
		local old
		if champ:getItem(i) ~= nil then
			old = champ:getItem(i)
			champ:removeItemFromSlot(i)
			--delayedCall(self.go.id, 0.2, "delayedDestroy", old.go.id);
			--old.go:setPosition(1,1,1,1,1)
		end
	end
	if skill == "armors" then
		armor[#armor+1] = spawn("leather_brigandine")
		armor[#armor+1] = spawn("leather_cuisse")
		armor[#armor+1] = spawn("leather_boots")
	else
		armor = randomClothes()
	end
	if skill == "missile_weapons" then
		right = spawn("sling")
		left = spawn("rock")
		left.item:setStackSize(5)
		inv[#inv+1] = spawn("potion_healing")
	elseif skill == "throwing" then
		right = spawn("throwing_knife")
		right.item:setStackSize(5)
		inv[#inv+1] = spawn("potion_healing")
	elseif skill == "firearms" then
		right = spawn("flintlock")
		left = spawn("pellet_box")
		left.item:setStackSize(10)
		inv[#inv+1] = spawn("potion_healing")
	elseif skill == "light_weapons" then
		right = spawn("hand_axe")
		inv[#inv+1] = spawn("potion_healing")
	elseif skill == "heavy_weapons" then
		right = spawn("bone_club")
		inv[#inv+1] = spawn("potion_healing")
	elseif skill == "concentration" then
		right = spawn("whitewood_wand")
		inv[#inv+1] = spawn("potion_energy")
	elseif skill == "alchemy" then
		right = spawn("mortar")
		left = spawn("torch")
		inv[#inv+1] = spawn("blooddrop_cap")
		inv[#inv+1] = spawn("etherweed")
	else
		-- No useful skill
		right = spawn("torch")
		left = spawn("compass")
		inv[#inv+1] = spawn("rope")
	end
	if ord == 1 or ord == 2 then
		if left == nil then
			left = spawn("shovel")
		else
			inv[#inv+1] = spawn("shovel")
		end
	end
	if ord == 3 then
		inv[#inv+1] = spawn("sack")
	end
	if ord == 4 then
		if left == nil then
			left = spawn("torch")
		else
			inv[#inv+1] = spawn("torch")
		end
	end
	for _,food in ipairs(randomFood()) do
		table.insert(inv, food)
	end
	-- Armor
	for _,item in ipairs(armor) do
		local slot = findArmorSlot(item.item)
		champ:insertItem(slot, item.item)
	end
	-- Right hand
	if right ~= nil then
		champ:insertItem(2, right.item)
	end
	-- Left hand
	if left ~= nil then
		champ:insertItem(1, left.item)
	end
	-- Inventory
	for i,item in ipairs(inv) do
		champ:insertItem(12+i, item.item)
		if item.item:hasTrait("herb") then
			item.item:setStackSize(3)
		end
	end

end

function findArmorSlot(item)
	if item:hasTrait("chest_armor") then
		return 4
	elseif item:hasTrait("cloak") then
		return 7
	elseif item:hasTrait("helmet") then
		return 3
	elseif item:hasTrait("necklace") then
		return 8
	elseif item:hasTrait("gloves") then
		return 9
	elseif item:hasTrait("boots") then
		return 6
	elseif item:hasTrait("leg_armor") then
		return 5
	elseif item:hasTrait("bracers") then
		return 10
	end
	return 13
end

function randomClothes()
	local shirt_list = { "tattered_shirt", "tattered_shirt", "peasant_tunic", "xafi_robe" }
	local pants_list = { "loincloth", "torn_breeches", "peasant_breeches", "torn_breeches", "peasant_breeches", "xafi_khakis", "silk_hose" }
	local shoe_list = { "sandals", "shoes", "sandals", "shoes", "pointy_shoes", "nomad_boots" }
	local list = {}
	list[#list+1] = spawn(shirt_list[math.random(1, #shirt_list)])
	list[#list+1] = spawn(pants_list[math.random(1, #pants_list)])
	list[#list+1] = spawn(shoe_list[math.random(1, #shoe_list)])
	return list
end


function randomFood()
	local food_list = { "rat_swarm_shank", "rat_shank", "rat_jerky", "horned_fruit", "boiled_beetle", "borra", "lizard_stick", "silver_roach", "smoked_bass", "cheese", "fjeld_warg_meat", "baked_maggot", "sausage", "mole_jerky", "pitroot_bread", "turtle_eggs", "bread" }
	local list = {}
	local nut = 500
	while nut > 0 do
		local food = spawn(food_list[math.random(1, #food_list)])
		list[#list+1] = food
		nut = nut - food.usableitem:getNutritionValue()
	end
	return list
end
Crypt of Zulfar
User avatar
Drakkan
Posts: 1318
Joined: Mon Dec 31, 2012 12:25 am

Re: ...........

Post by Drakkan »

QuintinStone wrote:With NutJob's script removed, I built my own. It's a lot lot less versatile than what I've seen of NutJob's, but it serves my needs. Crappy weapons, basic clothing, some food, other miscellaneous items. Because of the dungeon I'm working on, it also gives a shovel to the first 2 champions.

I launch the script via a 0 second timer that starts when the game starts.

Code: Select all

function equipChampions()
end
thats hell of a script ! I just used simply version here:
viewtopic.php?f=22&t=8342&p=84331&hilit ... ems#p84331

but still missing script for setting starting skills / traits. Dont you wanna make it ? :)
Breath from the unpromising waters.
Eye of the Atlantis
User avatar
QuintinStone
Posts: 72
Joined: Sat Nov 01, 2014 9:58 pm

Re: ...........

Post by QuintinStone »

Drakkan wrote:but still missing script for setting starting skills / traits. Dont you wanna make it ? :)
What would it do exactly? I personally wouldn't want to make a dungeon that undid the work someone went through customizing their party.
Crypt of Zulfar
Post Reply