Jump to content

Brybry

Member
  • Posts

    213
  • Joined

Community Answers

  1. Brybry's post in Applying an XP Boost (not XP Multiplier) to a perk post-character creation was marked as the answer   
    I come bearing ugly presents
    function applyTraitBoostsToPlayer(player, traitName) if not player or not instanceof(player, "IsoPlayer") then print("Error in applyTraitToPlayer: invalid player = "..tostring(player)); return end if not traitName or type(traitName) ~= "string" or player:HasTrait(traitName) then print("Error in applyTraitToPlayer: invalid traitName or player already has trait: "..tostring(traitName)); return end local trait = TraitFactory.getTrait(traitName); if not trait then print("Error in applyTraitToPlayer: trait "..tostring(traitName).." doesn't exist"); return end -- Get existing perks from the player xpBoostMap for caching local xpBoostMap = transformIntoKahluaTable(player:getDescriptor():getXPBoostMap()); local cachedPerks = {}; -- Cache old perk/xp values and set the perk level to 0 for perk, value in pairs(xpBoostMap) do local oldValues = {}; oldValues.level = player:getPerkLevel(perk); local totalXP = player:getXp():getXP(perk); local levelXP = getXPForPerkLevel(perk, oldValues.level); oldValues.xp = totalXP - levelXP; -- Value here is actually java.lang.Integer so convert it oldValues.boost = value:intValue(); cachedPerks[perk] = oldValues; player:level0(perk); end -- Add trait to the player via applyTraits. This applies XP boost and appropriate levels local traitList = ArrayList.new(); traitList:add(traitName); player:applyTraits(traitList); -- Add back old perk levels and XP from cached values for perk, oldValues in pairs(cachedPerks) do local xp = player:getXp(); local curLevel = player:getPerkLevel(perk); local oldLevel = oldValues.level; local oldBoost = oldValues.boost; local targetLevel = oldLevel + curLevel - oldBoost; -- counteracts applyTraits() str/fit +5 if perk == Perks.Strength or perk == Perks.Fitness then targetLevel = targetLevel - 5; end if targetLevel > curLevel then for i = curLevel, targetLevel do player:LevelPerk(perk); end elseif targetLevel < curLevel then for i = curLevel, targetLevel+1, -1 do player:LoseLevel(perk); end end xp:setXPToLevel(perk, player:getPerkLevel(perk)); xp:AddXPNoMultiplier(perk, oldValues.xp); endendfunction getXPForPerkLevel(perk, level) if not perk or not level then return 0 end local target = nil; for i = 0, PerkFactory.PerkList:size() - 1 do local info = PerkFactory.PerkList:get(i); if info:getType() == perk then target = info; break; end end if not target then return 0 end return target:getTotalXpForLevel(level);end 
    Gist in case I update anything
     
    I might be able to do a cleaner method since it may be possible to use getXPBoostMap():put() if I can create (or clone) a java.lang.Integer object but I'll have to play with it to see if that will work out.
     
    If you only want the XP Boost but not the initial perk levels from the trait then set targetLevel = oldLevel and remove the strength/fitness offset bit.
  2. Brybry's post in Detect that the player is using an item was marked as the answer   
    You can hook the ISReadABook timed action (which I believe is used for all literature reading.)
     
    Here are some examples:
    -- Basic hook example, multiple mods can hook the same function this way and potentially still be compatible-- Future proofed against argument and return value changeslocal oldISReadABook_perform = ISReadABook.perform;function ISReadABook:perform(...) print("My hooked code here"); return oldISReadABook_perform(self, ...);end-- Hook example where the original function is called firstfunction ISReadABook:perform(...) local ret = oldISReadABook_perform(self, ...); print("My hooked code here"); return ret;end-- Hook example where arguments are checkedif table.pack == nil then table.pack = function(...) return { n = select("#", ...), ... } endendfunction ISReadABook:perform(...) local ret = oldISReadABook_perform(self, ...); local args = table.pack(...); if args[1] == "foobar" then print("My hooked code here"); end return ret;endYou might want update() instead of perform(), depending. I just used that as an example. If you want specific to newspaper/etc results then you can check self.item
     
    Clarification for anyone confused about where self comes from: function foo:bar() in lua is just syntax sugar for function foo.bar(self) and so you're saving a copy of the old function, then overriding it with a new function, and then calling the old function and passing along self to keep the pseudo-OOPness working.
  3. Brybry's post in Can't run ProjectZomboidServer was marked as the answer   
    Don't run it as administrator, that'll cause issues.
     
    Your issue is probably some security or anti-virus software causing the "access is denied" message.
     
    It's unlikely, but possible, that you have weird permissions on your user's Temp folder but it's almost certainly anti-virus/security software.
    You can go to C:\Users\Thomas\AppData\Local\Temp\ and check the properties of sqlite-3.8.10.1-25f36d0f-ef17-4729-8206-d1f55b90a700-sqlitejdbc.dll and make sure it's not read only and that user "Thomas" has Full Control permissions.
     
    Optionally as a workaround you could replace "sqlite-jdbc-3.8.10.1.jar" in the server .bat with "sqlitejdbc-v056.jar" as I don't think that version uses the Temp directory.
    Also, what version of windows? And 32 or 64bit?
  4. Brybry's post in Freeze player in place was marked as the answer   
    getPlayer():setBlockMovement(true); will stop movement with keys (and controller, I think) but it won't stop context menu movement.
  5. Brybry's post in getModData() was marked as the answer   
    Pretty sure getPrimaryHandItem() is returning null (because not holding anything) and you're trying to call getModData() on a null object.
     
    Try 
    local function equippedTimes() local player = getPlayer(); local primary = player:getPrimaryHandItem(); if primary ~= nil then local pModData = primary:getModData(); pModData.name = "Primary"; print(pModData.name); endend
  6. Brybry's post in getModData() was marked as the answer   
    Pretty sure getPrimaryHandItem() is returning null (because not holding anything) and you're trying to call getModData() on a null object.
     
    Try 
    local function equippedTimes() local player = getPlayer(); local primary = player:getPrimaryHandItem(); if primary ~= nil then local pModData = primary:getModData(); pModData.name = "Primary"; print(pModData.name); endend
  7. Brybry's post in My friend can't connect to me server was marked as the answer   
    The file order looks fine so have him try doing a Steam Library->Right click Project Zomboid->Properties->Local Files tab->Verify Integrity of Game Cache.
     
    If it's a private server for only you and your friends you can set DoLuaChecksum=false in Zomboid/Server/servertest.ini and your friend will be able to play with you for sure.
  8. Brybry's post in My friend can't connect to me server was marked as the answer   
    The file order looks fine so have him try doing a Steam Library->Right click Project Zomboid->Properties->Local Files tab->Verify Integrity of Game Cache.
     
    If it's a private server for only you and your friends you can set DoLuaChecksum=false in Zomboid/Server/servertest.ini and your friend will be able to play with you for sure.
  9. Brybry's post in getFileWriter - relative / direct path (b32.3) was marked as the answer   
    You want getModFileWriter(String modId, String filename, boolean createIfNull, boolean append)not getFileWriter.
  10. Brybry's post in getFileWriter - relative / direct path (b32.3) was marked as the answer   
    You want getModFileWriter(String modId, String filename, boolean createIfNull, boolean append)not getFileWriter.
  11. Brybry's post in How exactly does calling the Java functions with Lua work? was marked as the answer   
    It's not just plonking a get in front of things.
     
    Some Java classes/objects are explicitly exported and so you can access them (at least for the first level) like a Lua table:
    For example, PerkFactory.getPerk()
     
    Some things are accessible through explicitly exported functions like getPlayer() which returns a java object and so you access it like:
    getPlayer():getInventory()
     
    getPlayer():getInventory() (which IsoPlayer inherits from IsoGameCharacter) returns an ItemContainer (this is different from InventoryContainer which is a type of InventoryItem) which does not have a public setCapacity() function.
    The Capacity field/member is public but sadly there isn't way to get/set that. Or, rather, there is at the moment using reflection but access to reflection is probably being removed in the near future.
     
    Note that the javadoc I linked to there is over a year out of date and so won't have every function/class.
    You can dump (print to console or write to a file) the lua environment table to help see what you have access to.
    There might be some documentation floating around where someone has already done that.
  12. Brybry's post in How exactly does calling the Java functions with Lua work? was marked as the answer   
    It's not just plonking a get in front of things.
     
    Some Java classes/objects are explicitly exported and so you can access them (at least for the first level) like a Lua table:
    For example, PerkFactory.getPerk()
     
    Some things are accessible through explicitly exported functions like getPlayer() which returns a java object and so you access it like:
    getPlayer():getInventory()
     
    getPlayer():getInventory() (which IsoPlayer inherits from IsoGameCharacter) returns an ItemContainer (this is different from InventoryContainer which is a type of InventoryItem) which does not have a public setCapacity() function.
    The Capacity field/member is public but sadly there isn't way to get/set that. Or, rather, there is at the moment using reflection but access to reflection is probably being removed in the near future.
     
    Note that the javadoc I linked to there is over a year out of date and so won't have every function/class.
    You can dump (print to console or write to a file) the lua environment table to help see what you have access to.
    There might be some documentation floating around where someone has already done that.
  13. Brybry's post in item distribution(yes another one:P) was marked as the answer   
    I would think that 
    WeaponUpgrades.Pistol = {"testingmod.Laser","testingmod.RedDot","testingmod.IronSight"}; would work. Odd.
     
    Something like this might work and be slightly more concise:
    local Pistol = WeaponUpgrades.Pistol;for i = 1, #Pistol do   if Pistol[i] == "Base.Laser" then     Pistol[i] = "testingmod.Laser";  elseif Pistol[i] == "Base.IronSight" then     Pistol[i] = "testingmod.IronSight";  elseif Pistol[i] == "Base.RedDot" then     Pistol[i] = "testingmod.RedDot"; endend
  14. Brybry's post in Have a building option choose between different items was marked as the answer   
    subMenuIndustrial:addOption("Small Propane Tank", worldobjects, BuildingMod.onSmallPropaneTank,  square, player);I believe that will pass worldobjects, square, player to onSmallPropaneTank but your second argument in onSmallPropaneTank is player
    Try:
    BuildingMod.onSmallPropaneTank = function(worldobjects, square, player)To better explain the error message you're seeing "getInventory of non-table: null" says that you're trying to call getInventory() on a null variable which is probably what getSpecificPlayer() is returning since it's not actually being passed a player.
    I think you can use something like print("Debug: player "..tostring(player)); print("Debug: specificplayer"..tostring(getSpecificPlayer(player))) in the future to help pin it down.
  15. Brybry's post in Get a Public Integer from a class was marked as the answer   
    Try player:getClass():getField("OnlineID"):getInt(player) where player is an IsoPlayer
    For strings use just get(player), etc
     
    I think in theory that since IsoPlayer is a serializable that you could probably get it that way somehow.
×
×
  • Create New...