CameronC's items/scripts (NEW: the socketSystem)
Re: CameronC's items/scripts (NEW: the socketSystem)
just noted interesting small bug behaviour - in case you have some item which drains energy on equip, it does not work when champion is starving. Seems it is somehow connected with automatic regeneration.
as for the socket that sounds awesome, definitely could be nice addon to some mods, thanks for it !
as for the socket that sounds awesome, definitely could be nice addon to some mods, thanks for it !
Re: CameronC's items/scripts (NEW: the socketSystem)
Oh, that makes sense. Definitely interesting, I'll have to see what the best way to handle this is. Thanks for the info!Drakkan wrote:just noted interesting small bug behaviour - in case you have some item which drains energy on equip, it does not work when champion is starving. Seems it is somehow connected with automatic regeneration.
as for the socket that sounds awesome, definitely could be nice addon to some mods, thanks for it !
The socketSystem has been completely rewritten and I am a million times happier with it now.Here is a brief run down of how it works now and what is included in this new version:
- LordYig's Grimrock 1 gem/alcove pack. I converted the gem definitions to work with Grimrock 2 and the models/icons/descriptions are now the basis for most of the gems in this pack. I have not converted the alcove definitions. LordYig's original gems, now component-based, are included if you want to use them, though the socket gems only need the model/gfxAtlas files. This gem/alcove for Grimrock 1 is on NexusMods here: http://www.nexusmods.com/grimrock/mods/177/
- Aside from the visuals, the system is now entirely item-based. There is no script entity that needs to be in your dungeon. All of the socket gems have a base_object with an onUseItem hook that does all the item checks needed to find the item the champion wants to enchant and passes it along to a Script component inside the same gem being used. So, instead of a massive script to apply the modifications, the gem itself runs its own script on the item passed to it by the onUseItem.
- This means it is entirely self contained and modular. Anyone can make a set of unique and cool gems to modify items and it is very simple to include it in your mod. You simply import the gem file! nothing else. No copying/pasting a massive if/then check into a master script or anything.
Here is a mediafire link to a zip file with all the files: http://www.mediafire.com/download/xjp7i ... -29-14.zip
Github: https://github.com/camcallahan/log2-socketSystem
And here is a more in-depth write up of the new system and the 64 gems included in this release (Not as exciting as it sounds - mostly stat increasing gems, but a few interesting proof-of-concepts in there also). Towards the bottom are the current "needs fixing" list and random musings on what else needs to be worked out.
Code: Select all
general-log2-assets/socketSystem
===================
A D2-style weapon/armor system that allows for gems to be placed into sockets on items to alter their abilities.
The init.lua has an onPickUpItem hook that will
add the required component to allow them to be modified. This can easily be changed to only alter items
some percentage of the time instead of always.
The gem models and GfxIndex icons are from LordYig's gem/alcove pack for Grimrock 1. I converted the gem
definition to be usable in Grimrock 2 and those models/icons/descriptions/names are used as a base for
a lot of the gems in here. I have not gone through and converted any of the alcoves in his pack.
LordYig's Grimrock 1 pack can be found on NexusMods: http://www.nexusmods.com/grimrock/mods/177/
The converted gem definitions are included and imported in this if you want to use those as is or
modify them into more socket gems. Filtering in the editor for itm_ should bring up all of the gems.
The order of the import lines in init.lua is important.
The socketBaseItems.lua MUST come first, as it has an item in there that others use as a base_object.
The other import lines bring in the gems by "type". There are a few types included so far.
The system works by having a base_object all the gems are based on that has an onUseItem hook that does
the various checks to determine if the gem can be used, what item is it being used on, etc. Then, the
onUseItem function calls a Script component within the gem (passing it some information on the item
the gem will be used on) and that function is what actually alters the items. This means, chiefly, there
is no gigantic script entity to place in your dungeon anywhere. It also means that if you want to change
the behaviour of a gem you go to the object definition of the gem and that has every piece of information
you need in one place to change or troubleshoot it. It also lets the gems be separated out across different
files. If you don't want the Skull gems then just comment out that one import line and they won't show up in
the editor and there won't be any code anywhere relating to them. It also means that if someone one makes a
set of gems, as long as you import the base item file you don't have to do anything other than import their
gem file. Super simple, super easy.
Look at the base item and included gems on how to create your own. Basically, all the GEM needs is a Script
component named "triggers" and a function named "insertGem" that accepts the variable itemToEnchant.
Whatever you put in that script will be ran when the gem is right clicked in a champion ahnd while holding
another item. Return true and the gem will be used, return false and it will remain.
Current gems available:
A base set of ELEMENT gems that increase stats/provide resistances. These have a specific effect depending
what type of item they are socketed in. Weapons gain attack power and elemental damage. Shields gain
resistances. Armor gain minor and major stat bonuses.
The SKULL gems switch and change the lower-level properties of an item, like baseDamageStat and
skill requirements. There is a skull for each of the four major stats that will change the stat
used to scale damage up (So maybe a new found hammer can be wielded fiercely by a willpower mage, for
instance). There are also gems to converted heavy_armor requirements to light_armor, and other similar
effects.
The PASSIVE gems are similar to the ELEMENT gems but with less restrictions. They increase stats by a
more limited amount but can be inserted into any type of item with slots. So, while a high level SAPPHIRE
will only provide willpower when put into a chest_armor, one of these willpower gems will give you the
bonus even when put into a shield or weapon. These mostly provide stat bonuses, but there are a few other
things that they can alter as well.
ABILITY gems provide secondary actions. Currently, there is only a small pool of them. There is one for the
base Bolt-type spells for weapons and ones that provide shields with the elemental shield-type spells. There
is also one that provides the ability MUG to a dagger. This allows a champion with a dagger to shake down the
enemy and has a small chance to drop items for the party.
To manually create an item with the ability to accept gems, the weapon/armor requires two components:
- A Counter component named "sockets", set to the max amount of gems the item can accept.
- A Counter component named "gemcount", initially set to the same value as "sockets". This is decreased
when enchanting an item and prevents gems from being used when at 0.
Currently shields, chest pieces, and non-RunePanel weapons can be enchanted. Shields are given 1-2 slots,
chest pieces are given 2-4, and weapons are given 1-2 slot each (Except weapons with the "two_handed" trait
are given 2-4 slots).
To modify an item, place one of the gems into a champion's hand along with the item to enchant in the
other hand. Right-click the gem to enchant the other item being held. The gem will vanish and print out
the effect of the gem.
If the other item being held does not have the correct components to be enchanted then it will print out
that fact and the gem will remain in the champion's hand. Similarly, if the item has no more free sockets
then the gem will have no effect and remain in hand.
To-do/Fixes needed:
- Find a better way to display the amount of free sockets in items. Currently, an item with a gameEffect
will have it erased and replaced with the free socket count. Perhaps a simple gameEffect/description
manager needs to be implemented so that -lines- of information can be retrieved/modified without hurting
other lines of information in the strings.
- secondaryAction spells have charges that DO work, but are not displayed when hovered over the item. Unsure
what is causing this.
- Determine if it is possible to script a sort of setPowerAttackTemplate to dynamically add the predefined
power attacks to weapons... or at least reverse-engineer some of the more interesting ones to use.
NOTE: The gems currently have another Counter component in them named "treasureclass" that is unrelated to
the socketSystem.
Writer and sometimes artist of the very slightly acclaimed comic series Scrambled Circuits. A comic series about a robot written by a human.
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Re: CameronC's items/scripts (NEW: the socketSystem)
All of this!! YES YES YES
Nice work cameronC, impressive indeed...
Regarding fixes - overwriting gameEffects of items...
This is not good!!
I can see
does the overwriting.... surely we could use...
to then
Im trying to mess around with it now, but am experiencing deferred success .... 
Nice work cameronC, impressive indeed...
Regarding fixes - overwriting gameEffects of items...
This is not good!!

I can see
Code: Select all
item.go.item:setGameEffect(tostring(weaponSockets).." free sockets.")
Code: Select all
local gEffect = item.go.item:getGameEffect
Code: Select all
item.go.item:setGameEffect(gEffect ....... add this line of game effect somehow ....... tostring(weaponSockets).." free sockets.")

Labyrinth of Lies (viewtopic.php?f=14&t=4400)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Re: CameronC's items/scripts (NEW: the socketSystem)
Will definitely be trying these out Cameron.
There is certainly some really exciting stuff coming out.
There is certainly some really exciting stuff coming out.

Re: CameronC's items/scripts (NEW: the socketSystem)
Thanks guys. Firstly, I think I've got the gameEffect stuff working. It's not pretty right now but it seems functional.
new init.lua onPickUpItem hook:
replace the code in the base_socket_gem onUseItem hook, towards the bottom if placeGem statement:
GitHub also updated.
It makes some assumptions to work, mainly that the amount of sockets in an item is single digit. When I have time to clean it up I think I'd like to make it a small function that can be used to add lines of information to the gameEffect of an item and also update those lines of information while keeping the order and formatting in place. We'll see.
new init.lua onPickUpItem hook:
Code: Select all
onPickUpItem = function(self, item)
-- General Triggers Below (Skill/Trait triggers, etc)
local theGameEffect = item.go.item:getGameEffect()
local beforeGE = ""
if theGameEffect ~= nil then beforeGE = "\n" end
if theGameEffect == nil then theGameEffect = "" end
beforeGE = theGameEffect .. beforeGE
if item.go.item:hasTrait("shield") and not item.go:getComponent("sockets") then
local shieldSockets = math.random(1, 2)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(shieldSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(shieldSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
elseif item.go.item:hasTrait("chest_armor") and not item.go:getComponent("sockets") then
local chestSockets = math.random(2, 4)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(chestSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(chestSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
elseif (item.go:getComponent("meleeattack") or item.go:getComponent("rangedattack") or item.go:getComponent("firearmattack")) then
if item.go.item:hasTrait("two_handed") then
local weaponSockets = math.random(2, 4)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(weaponSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(weaponSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
else
local weaponSockets = math.random(1, 2)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(weaponSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(weaponSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
end
end
return
end,
},
Code: Select all
if placeGem then
local gameEffectFull = itemToEnchant.go.item:getGameEffect()
local gameEffectBefore = ""
local gameEffectAfter = ""
local gameEffectSearch = "Free Sockets"
local start = 0
local finish = 0
itemToEnchant.go.gemcount:decrement()
local gameEffectReplace = "- Free Sockets ("..tostring(itemToEnchant.go.gemcount:getValue()).."/"..tostring(itemToEnchant.go.sockets:getValue())..")"
start, finish = string.find(gameEffectFull, gameEffectSearch)
start = start - 2
gameEffectBefore = string.sub(gameEffectFull, 1, start-1)
gameEffectAfter = string.sub(gameEffectFull, finish+8)
itemToEnchant.go.item:setGameEffect(gameEffectBefore..gameEffectReplace..gameEffectAfter)
hudPrint("The " .. self.go.item:getUiName() .. " disappears and enchants the " .. baseUiName .. ".")
if gemEffect ~= nil then hudPrint(gemEffect) end
return true
end
It makes some assumptions to work, mainly that the amount of sockets in an item is single digit. When I have time to clean it up I think I'd like to make it a small function that can be used to add lines of information to the gameEffect of an item and also update those lines of information while keeping the order and formatting in place. We'll see.
Writer and sometimes artist of the very slightly acclaimed comic series Scrambled Circuits. A comic series about a robot written by a human.
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Re: CameronC's items/scripts (NEW: the socketSystem)
Sorry for the double post 
Here are three simple scripts to store, remove, and update non-standard information in the gameEffect string. In the example of the gems/sockets, the onPickUpItem would pass the item and the plain-text string with the socket information("- Free Sockets (2/2)" for example) to the geAddInformation function. Then, when a gem is placed in an item it would call geReplaceInformation("Free Sockets", newSocketInformation). That script searches for the term "Free Sockets" in the gameEffect table for that item and changes it to the new string passed to it and rebuilds the gameEffect string with the proper new lines and stuff added. It seems to be able to handle whatever tests I throw at it. Hope this is useful to someone.
I'd like to keep the sockets/gems as independent as possible but this might be worth requiring in a dungeon. Not sure yet.

Here are three simple scripts to store, remove, and update non-standard information in the gameEffect string. In the example of the gems/sockets, the onPickUpItem would pass the item and the plain-text string with the socket information("- Free Sockets (2/2)" for example) to the geAddInformation function. Then, when a gem is placed in an item it would call geReplaceInformation("Free Sockets", newSocketInformation). That script searches for the term "Free Sockets" in the gameEffect table for that item and changes it to the new string passed to it and rebuilds the gameEffect string with the proper new lines and stuff added. It seems to be able to handle whatever tests I throw at it. Hope this is useful to someone.
Code: Select all
--[[
These three scripts will create a database of information
inside an items gameEffect string and allow it to be easily
manipulated. Lines of information can be added and removed.
The calls then, after adding or removing information, rebuild
the gameEffect string of that item with a new line character
after each information string. The function can also search
through the database of information and replace lines with
new or updated information and rebuild the gameEffect string
in the same order. I hope this can be useful to display
non-standard and uncommon item information in an easy and
simple way.
--]]
complexEffects = { }
function geAddInformation(item, information, otherInformation)
if not complexEffects[item] then
complexEffects[item] = { item.item:getGameEffect() }
end
if type(information) == "number" then
table.insert(complexEffects[item], information, otherInformation)
return true
end
if complexEffects[item][1] == nil then
complexEffects[item][1] = information
else
table.insert(complexEffects[item], #complexEffects[item]+1, information)
end
local newGameEffect = ""
for i = 1, #complexEffects[item] do
local spacing = ""
if i >= 2 then spacing = "\n" end
newGameEffect = newGameEffect..spacing..complexEffects[item][i]
end
item.item:setGameEffect(newGameEffect)
return true
end
function geRemoveInformation(item, information)
if not complexEffects[item] then return false end
if type(information) == "number" then
table.remove(complexEffects[item], information)
return true
end
for i = 1, #complexEffects[item] do
if string.find(complexEffects[item][i], information) then
table.remove(complexEffects[item], i)
break
end
end
local newGameEffect = ""
for i = 1, #complexEffects[item] do
local spacing = ""
if i >= 2 then spacing = "\n" end
newGameEffect = newGameEffect..spacing..complexEffects[item][i]
end
item.item:setGameEffect(newGameEffect)
return true
end
function geReplaceInformation(item, information, newInformation)
if not complexEffects[item] then return false end
if type(information) == "number" then
complexEffects[item][information] = newInformation
return true
end
for i = 1, #complexEffects[item] do
if string.find(complexEffects[item][i], information) then
complexEffects[item][i] = newInformation
break
end
end
local newGameEffect = ""
for i = 1, #complexEffects[item] do
local spacing = ""
if i >= 2 then spacing = "\n" end
newGameEffect = newGameEffect..spacing..complexEffects[item][i]
end
item.item:setGameEffect(newGameEffect)
return true
end
Writer and sometimes artist of the very slightly acclaimed comic series Scrambled Circuits. A comic series about a robot written by a human.
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Re: CameronC's items/scripts (NEW: the socketSystem)
Excellent!! Works great cameronC
My precious little gameEffects remain intact! hehehe
Thank you again
...oh! and those gameffect functions are going to come in real handy, for many people!

My precious little gameEffects remain intact! hehehe
Thank you again

...oh! and those gameffect functions are going to come in real handy, for many people!
Labyrinth of Lies (viewtopic.php?f=14&t=4400)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Re: CameronC's items/scripts (NEW: the socketSystem)
Sorry to bother you again haha
A small thing, easy fix I imagine.... (this is your baby, otherwise Id just go ahead and do it)
Each time you pick up a (weapon in my case)... the script adds a new line of game effect...
If you pick up and drop and pick up something multiple times you get something like this:

A small thing, easy fix I imagine.... (this is your baby, otherwise Id just go ahead and do it)
Each time you pick up a (weapon in my case)... the script adds a new line of game effect...
If you pick up and drop and pick up something multiple times you get something like this:
SpoilerShow
Labyrinth of Lies (viewtopic.php?f=14&t=4400)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Legacy of Lies (viewtopic.php?f=22&t=12983&hilit=+legacy)
Re: CameronC's items/scripts (NEW: the socketSystem)
Oh yeah, silly oversight on my part. Fixed.
Here is the onPickUp again.
Here is the onPickUp again.
Code: Select all
onPickUpItem = function(self, item)
-- General Triggers Below (Skill/Trait triggers, etc)
local theGameEffect = item.go.item:getGameEffect()
local beforeGE = ""
if theGameEffect ~= nil then beforeGE = "\n" end
if theGameEffect == nil then theGameEffect = "" end
beforeGE = theGameEffect .. beforeGE
if item.go.item:hasTrait("shield") and not item.go:getComponent("sockets") then
local shieldSockets = math.random(1, 2)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(shieldSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(shieldSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
elseif item.go.item:hasTrait("chest_armor") and not item.go:getComponent("sockets") then
local chestSockets = math.random(2, 4)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(chestSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(chestSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
elseif (item.go:getComponent("meleeattack") or item.go:getComponent("rangedattack") or item.go:getComponent("firearmattack")) and not item.go:getComponent("sockets") then
if item.go.item:hasTrait("two_handed") then
local weaponSockets = math.random(2, 4)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(weaponSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(weaponSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
else
local weaponSockets = math.random(1, 2)
item.go:createComponent("Counter", "sockets")
item.go.sockets:setValue(weaponSockets)
item.go:createComponent("Counter", "gemcount")
item.go.gemcount:setValue(weaponSockets)
item.go.item:setGameEffect(beforeGE.."- Free Sockets ("..tostring(item.go.gemcount:getValue()).."/"..tostring(item.go.sockets:getValue())..").")
end
end
return
end,
Writer and sometimes artist of the very slightly acclaimed comic series Scrambled Circuits. A comic series about a robot written by a human.
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Grimrock 2 socketSystem: viewtopic.php?f=22&t=8546 / Github
Re: CameronC's items/scripts (NEW: the socketSystem)
Hello CameronC
I installed this script in my dungeon, but it does not work.
Browsing the forum I saw that it only took two scripts: socketSystem.lua and socketItems.lua
and when I wanted to download the given link does not work https://github.com/camcallahan/general- ... cketSystem error 404
Would it be possible to put them on the site
Thanks

I installed this script in my dungeon, but it does not work.
Browsing the forum I saw that it only took two scripts: socketSystem.lua and socketItems.lua
and when I wanted to download the given link does not work https://github.com/camcallahan/general- ... cketSystem error 404

Would it be possible to put them on the site

Thanks
