Jump to content

Which LUA file to edit for infinite lightsource fuel?


Memmorath

Recommended Posts

Which file to edit for infine lightsource fuel, specifically lamp light sources fueled by lightbulbs? The file ISLightActions.lua in "ProjectZomboid\media\lua\client\TimedActions" seems like would be the place, however, I'm not sure if I understand it correctly. Pasted below is the code I think I'm supposed to edit? (specifically the "o.maxTime" value?; also how long is one unit of "time"?

 

Any help would be appreciated.

 

function ISLightActions:new(mode, character, lightswitch, item)
    local o             = {};
    setmetatable(o, self);
    self.__index        = self;
    o.mode              = mode;
    o.character         = character;
    o.lightswitch       = lightswitch;
    o.item              = item;
    o.stopOnWalk        = true;
    o.stopOnRun         = true;
    o.maxTime           = 300;
    if mode=="AddLightBulb" or mode=="RemoveLightBulb" then
        o.maxTime = 120;
    elseif mode=="AddBattery" or mode=="RemoveBattery" then
        o.maxTime = 60;
    end

 

Edited by Memmorath
Link to comment
Share on other sites

that chunk of code you linked is not the right one, I know that much. That block of code relates to the character action of physically interacting with a lightsource, e.g. actually pressing the light switch. Those numbers are milliseconds I believe; definitely less than a second.

 

I'll see if I can find you the correct chunk.

Edited by ohgodspidersno
Link to comment
Share on other sites

1 minute ago, ohgodspidersno said:

that chunk of code you linked is not the right one, I know that much. That block of code relates to the character action of using a lightsource. Those numbers are milliseconds I believe; definitely less than a second.

 

I'll see if I can find you the correct chunk.

Character action of a lightsource? You mean like a Flashlight or a torch?

Link to comment
Share on other sites

Yes, and possibly also a lamp or light switch but I'll have to look at the rest of the file first to say for sure.

 

The main point is that this code is all about a player action, and not how the item itself behaves.

Edited by ohgodspidersno
Link to comment
Share on other sites

I'm still looking up how to change lamps...

 

In the meantime (if you were wondering) you can make flashlights infinite/last longer by going to their item script and changing their Type or their UseDelta. Smaller UseDelta will make it last longer. I think if you change the Type to "Normal" it will last forever, but you'd have to check for yourself.

 

I'll let you know when I find out how to modify stationary lamps

Link to comment
Share on other sites

This will do the trick:

 

Create a lua file:

media/lua/server/memmorath_infinite_lamp.lua

 

Paste this in the file:


local ISLightSource_create_original = ISLightSource.create

function ISLightSource:create(x, y, z, north, sprite, ...)
    ISLightSource_create_original(self, x, y, z, north, sprite, ...)
    self.javaObject:setLifeDelta(0);
end


 

 

Note:

This will only affect lamps that are built while the mod is enabled. That means:

1. Existing lamps you made before loading the mod will still drain power

2. Any new lamps you make will be infinite forever, even after you disable the mod.

Link to comment
Share on other sites

For the curious, here's what's happening

 

local ISLightSource_create_original = ISLightSource.create

That line makes a copy of the original function in charge of constructing new light source, like Lamp on Pole. This copy is called "ISLightSource_create_original". I'm calling it "original" because we're about to change the one that the game will actually use. ISLightSource_create_original, is a backup of the original, vanilla, unchanged function.

 

 

function ISLightSource:create(x, y, z, north, sprite, ...)
    .....
end

This is now overwriting the function in charge of constructing a new light source. Everything that happens inside this function is what will run when you build a light source

Now looking at the contents:

function ISLightSource:create(x, y, z, north, sprite, ...)
    ISLightSource_create_original(self, x, y, z, north, sprite, ...)
    self.javaObject:setLifeDelta(0);
end

The first line,  "ISLightSource_create_original(self, x, y, z, north, sprite, ...)" executes the copy of the function we made at the beginning. In other words, this line just makes the function do what it normally would.

 

Now let's look at the second line, "self.javaObject:setLifeDelta(0);"

"self" is how the function refers to itself, including all of the various variables and stuff that belong to it, so self.javaObject is the specific javaObject that the function is creating right now (in our case, the lamp pole your character is building). LifeDelta is the amount of battery power it consumes every millisceond. so "setLifeDelta(0)" is saying "use 0 (zero) energy every millisecond" which means it will never use up any battery and will last forever.

 

 

Edited by ohgodspidersno
Link to comment
Share on other sites

You're a wizard, thank you for the indepth explanation as well. The change affecting newly build lightsources with batteries, such as the carpentry item "Lamp on a Post" ,makes sense, but how about those lamps found on tables and such (the ones that essentially use lightbulbs)?

Link to comment
Share on other sites

Right, so I did some tinkering (thank you for pointing me in the right direction). Turns out, at least for the battery-powered items, I can achieve all this by modifying the item scripts.

(I'm not sure if the entire item script code is needed, but for the sake of this post I'll just post the relevant info)

 

Would be ideal to find which file has the lightbulb life for outdoor / indoor lamps, but at least this is already halfway there.

 

Below are the default and modified values. 

 

-- Default values:
-- Battery useDelta = 0.00001, (Lamp on Post; depletes roughly 5 % over 24 hours)
-- Hand Torch useDelta = 0.0004, (didn't actually check the default deplete rate)
-- Flashlight useDelta = 0.0009, (takes roughly 4,5 hours to fully deplete)


-- Modified values:
-- Battery useDelta = 0.000001, (900 % increase; not good in math, but will take a long time to deplete)
-- Hand Torch useDelta = 0.00004, (900 % increase; depletes 23 % over 24 hours, so should take over 4 days to fully deplete)
-- Flashlight useDelta = 0.00003, (2900 % increase; depletes 17 % over 24 hours, so should take almost 6 days to fully deplete)

 

This also means it is safe to deactive and reactive the mod; it will return to default depletation rate on mod deactivation.

 

Edited by Memmorath
Link to comment
Share on other sites

Probably not the file I'm looking for, but:

ProjectZomboid\zombie\iso\IsoLightSource.class

 

Below is the code. Although I don't really understand code, it seems to me it only controls lightswitch lights inside houses, correct? 

 

package zombie.iso;

import zombie.characters.IsoPlayer;
import zombie.core.opengl.RenderSettings;
import zombie.SandboxOptions;
import zombie.GameTime;
import zombie.iso.objects.IsoLightSwitch;
import java.util.ArrayList;
import zombie.iso.areas.IsoBuilding;

public class IsoLightSource
{
    public static int NextID;
    public int ID;
    public int x;
    public int y;
    public int z;
    public float r;
    public float g;
    public float b;
    public float rJNI;
    public float gJNI;
    public float bJNI;
    public int radius;
    public boolean bActive;
    public boolean bWasActive;
    public boolean bActiveJNI;
    public int life;
    public int startlife;
    public IsoBuilding localToBuilding;
    public boolean bHydroPowered;
    public ArrayList<IsoLightSwitch> switches;
    public IsoChunk chunk;
    public Object lightMap;
    
    public IsoLightSource(final int x, final int y, final int z, final float r, final float g, final float b, final int radius) {
        this.life = -1;
        this.startlife = -1;
        this.bHydroPowered = false;
        this.switches = new ArrayList<IsoLightSwitch>(0);
        this.x = x;
        this.y = y;
        this.z = z;
        this.r = r;
        this.g = g;
        this.b = b;
        this.radius = radius;
        this.bActive = true;
    }
    
    public IsoLightSource(final int x, final int y, final int z, final float r, final float g, final float b, final int radius, final IsoBuilding localToBuilding) {
        this.life = -1;
        this.startlife = -1;
        this.bHydroPowered = false;
        this.switches = new ArrayList<IsoLightSwitch>(0);
        this.x = x;
        this.y = y;
        this.z = z;
        this.r = r;
        this.g = g;
        this.b = b;
        this.radius = radius;
        this.bActive = true;
        this.localToBuilding = localToBuilding;
    }
    
    public IsoLightSource(final int x, final int y, final int z, final float r, final float g, final float b, final int radius, final int n) {
        this.life = -1;
        this.startlife = -1;
        this.bHydroPowered = false;
        this.switches = new ArrayList<IsoLightSwitch>(0);
        this.x = x;
        this.y = y;
        this.z = z;
        this.r = r;
        this.g = g;
        this.b = b;
        this.radius = radius;
        this.bActive = true;
        this.life = n;
        this.startlife = n;
    }
    
    public void update() {
        final IsoGridSquare gridSquare = IsoWorld.instance.CurrentCell.getGridSquare(this.x, this.y, this.z);
        if (this.bHydroPowered && GameTime.instance.NightsSurvived >= SandboxOptions.instance.getElecShutModifier() && (gridSquare == null || !gridSquare.haveElectricity())) {
            this.bActive = false;
            return;
        }
        if (!this.bActive) {
            return;
        }
        if (this.localToBuilding != null) {
            this.r = RenderSettings.getInstance().getAmbientForPlayer(IsoPlayer.getPlayerIndex()) * 0.7f;
            this.g = RenderSettings.getInstance().getAmbientForPlayer(IsoPlayer.getPlayerIndex()) * 0.7f;
            this.b = RenderSettings.getInstance().getAmbientForPlayer(IsoPlayer.getPlayerIndex()) * 0.7f;
        }
        if (this.life > 0) {
            --this.life;
        }
        if (this.localToBuilding != null && gridSquare != null) {
            this.r = RenderSettings.getInstance().getAmbientForPlayer(IsoPlayer.getPlayerIndex()) * 0.8f * IsoGridSquare.rmod * 0.7f;
            this.g = RenderSettings.getInstance().getAmbientForPlayer(IsoPlayer.getPlayerIndex()) * 0.8f * IsoGridSquare.gmod * 0.7f;
            this.b = RenderSettings.getInstance().getAmbientForPlayer(IsoPlayer.getPlayerIndex()) * 0.8f * IsoGridSquare.bmod * 0.7f;
        }
        for (int i = this.x - this.radius; i < this.x + this.radius; ++i) {
            for (int j = this.y - this.radius; j < this.y + this.radius; ++j) {
                for (int k = 0; k < 8; ++k) {
                    final IsoGridSquare gridSquare2 = IsoWorld.instance.CurrentCell.getGridSquare(i, j, k);
                    if (gridSquare2 != null) {
                        if (this.localToBuilding == null || this.localToBuilding == gridSquare2.getBuilding()) {
                            final LosUtil.TestResults lineClear = LosUtil.lineClear(gridSquare2.getCell(), this.x, this.y, this.z, gridSquare2.getX(), gridSquare2.getY(), gridSquare2.getZ(), false);
                            if ((gridSquare2.getX() == this.x && gridSquare2.getY() == this.y && gridSquare2.getZ() == this.z) || lineClear != LosUtil.TestResults.Blocked) {
                                float n;
                                if (Math.abs(gridSquare2.getZ() - this.z) <= 1) {
                                    n = IsoUtils.DistanceTo((float)this.x, (float)this.y, 0.0f, (float)gridSquare2.getX(), (float)gridSquare2.getY(), 0.0f);
                                }
                                else {
                                    n = IsoUtils.DistanceTo((float)this.x, (float)this.y, (float)this.z, (float)gridSquare2.getX(), (float)gridSquare2.getY(), (float)gridSquare2.getZ());
                                }
                                if (n <= this.radius) {
                                    final float n2 = 1.0f - n / this.radius;
                                    float n3 = n2 * n2;
                                    if (this.life > -1) {
                                        n3 *= this.life / (float)this.startlife;
                                    }
                                    final float n4 = n3 * this.r * 2.0f;
                                    final float n5 = n3 * this.g * 2.0f;
                                    final float n6 = n3 * this.b * 2.0f;
                                    gridSquare2.setLampostTotalR(gridSquare2.getLampostTotalR() + n4);
                                    gridSquare2.setLampostTotalG(gridSquare2.getLampostTotalG() + n5);
                                    gridSquare2.setLampostTotalB(gridSquare2.getLampostTotalB() + n6);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    public int getX() {
        return this.x;
    }
    
    public void setX(final int x) {
        this.x = x;
    }
    
    public int getY() {
        return this.y;
    }
    
    public void setY(final int y) {
        this.y = y;
    }
    
    public int getZ() {
        return this.z;
    }
    
    public void setZ(final int z) {
        this.z = z;
    }
    
    public float getR() {
        return this.r;
    }
    
    public void setR(final float r) {
        this.r = r;
    }
    
    public float getG() {
        return this.g;
    }
    
    public void setG(final float g) {
        this.g = g;
    }
    
    public float getB() {
        return this.b;
    }
    
    public void setB(final float b) {
        this.b = b;
    }
    
    public int getRadius() {
        return this.radius;
    }
    
    public void setRadius(final int radius) {
        this.radius = radius;
    }
    
    public boolean isActive() {
        return this.bActive;
    }
    
    public void setActive(final boolean bActive) {
        this.bActive = bActive;
    }
    
    public boolean wasActive() {
        return this.bWasActive;
    }
    
    public void setWasActive(final boolean bWasActive) {
        this.bWasActive = bWasActive;
    }
    
    public ArrayList<IsoLightSwitch> getSwitches() {
        return this.switches;
    }
    
    public void setSwitches(final ArrayList<IsoLightSwitch> switches) {
        this.switches = switches;
    }
    
    public void clearInfluence() {
        for (int i = this.x - this.radius; i < this.x + this.radius; ++i) {
            for (int j = this.y - this.radius; j < this.y + this.radius; ++j) {
                for (int k = 0; k < 8; ++k) {
                    final IsoGridSquare gridSquare = IsoWorld.instance.CurrentCell.getGridSquare(i, j, k);
                    if (gridSquare != null) {
                        gridSquare.setLampostTotalR(0.0f);
                        gridSquare.setLampostTotalG(0.0f);
                        gridSquare.setLampostTotalB(0.0f);
                    }
                }
            }
        }
    }
    
    public boolean isInBounds(final int n, final int n2, final int n3, final int n4) {
        return this.x >= n && this.x < n3 && this.y >= n2 && this.y < n4;
    }
    
    public boolean isInBounds() {
        final IsoChunkMap[] chunkMap = IsoWorld.instance.CurrentCell.ChunkMap;
        for (int i = 0; i < IsoPlayer.numPlayers; ++i) {
            if (!chunkMap[i].ignore) {
                if (this.isInBounds(chunkMap[i].getWorldXMinTiles(), chunkMap[i].getWorldYMinTiles(), chunkMap[i].getWorldXMaxTiles(), chunkMap[i].getWorldYMaxTiles())) {
                    return true;
                }
            }
        }
        return false;
    }
    
    public boolean isHydroPowered() {
        return this.bHydroPowered;
    }
    
    public IsoBuilding getLocalToBuilding() {
        return this.localToBuilding;
    }
    
    static {
        IsoLightSource.NextID = 1;
    }
}

 

Link to comment
Share on other sites

Do you want to make it

19 hours ago, Memmorath said:

You're a wizard, thank you for the indepth explanation as well. The change affecting newly build lightsources with batteries, such as the carpentry item "Lamp on a Post" ,makes sense, but how about those lamps found on tables and such (the ones that essentially use lightbulbs)?

 

You're welcome! Do you want the lamps to work even if they aren't linked to a power source?

Link to comment
Share on other sites

18 hours ago, ohgodspidersno said:

So you want to lower the amount of power they drain from a generator?


Not quite. I'm fine with whatever power they drain. The issue is that after "some period of time", placeable lamp furniture go dark, and the lightbulb needs to be replaced. I don't know if  lightbulbs have an actual duration meter (like batteries do),  but since the lamps require new lightbulbs from time to time I assume that is the case. I spent few hours digging through all game files, but didn't really know what I was looking for. In essence, I'd like to change the placeable lightbulb lamp fixture behaviour to last 10-15 times longer before the lightbulb needs to be replaced.

Edited by Memmorath
Link to comment
Share on other sites

3 hours ago, ohgodspidersno said:

I can't find anything in the code. It might just be in the Java with no way for us to access it via lua.

 

Perhaps you could try changing the item lighbulb to have MaxCondition = 1500 ?

 

I'm fairly certain the MaxCondition in lightbulbs has to do with Vehicle Headlights, but since I never tested changing that, I can't say for sure. At least for me, whenever I find a lightbulb and place it as a vehicle headlight, it's condition is 10%. Whereas headlights found already installed in vehicles have condition between 0-100.  

Link to comment
Share on other sites

You can only see the condition in the vehicle context menu but that doesn't necessarily mean it isn't affected by normal lamps. You'd have to test though, I'm not confident either way.

 

But I did notice that the lightbulbs that died first for me were very low condition when I first put them in my lamps

Edited by ohgodspidersno
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...