Hermios / RailPowerSystem

Connect rails to electric and signals circuits, and use electric trains
1 stars 0 forks source link

[Feature] Built-in locomotive battery #42

Closed Vasyanator closed 4 days ago

Vasyanator commented 6 days ago

If accumulators are used to create a locomotive, why can't it run at all without electrified rails? I suggest either just letting the locomotive run for a while without electrified rails and then charging, or dividing the locomotive into 2 types - with and without a built-in battery.

Hermios commented 6 days ago

This is a good point. Originally, they could, but I had to change the design because of collateral issues. Now, the reason why they cannot run is purely a programmatical issue. The best I can do is changing the receipt to remove batteries

Vasyanator commented 6 days ago

I've tried implementing this, but so far I haven't been able to display the battery charge in the object properties (the menu that appears when the cursor is hovered over). Here is my code in locomotive.lua:

locomotive = {}
custom_prototypes[electric_locomotive] = locomotive

-- Initialize a new locomotive entity with electric properties
function locomotive:new(entity)
    return {
        entity = entity,
        burner = entity.burner,
        train = entity.train,
        energy_buffer = 10000000, -- Simulated battery capacity (10 MJ)
        energy_buffer_max = 10000000, -- Maximum simulated battery capacity
        max_charge_rate = 100000 -- Maximum charge rate (100 kW per tick)
    }
end

-- Update function to handle charging and discharging the locomotive's battery
function locomotive:update()
    if not self.entity.valid then
        return
    end

    -- Check if the locomotive is on electrified rails and if the rail exists and is valid
    local rail = global.custom_entities[(self.train.front_rail or self.train.back_rail) and (self.train.front_rail or self.train.back_rail).unit_number]
    if rail and rail.accu and rail.accu.energy then
        -- Safeguard: Ensure the values are not nil and are numbers
        local max_charge_rate = self.max_charge_rate or 0
        local rail_energy = rail.accu.energy or 0
        local buffer_space = (self.energy_buffer_max or 0) - (self.energy_buffer or 0)

        -- Charge the energy buffer from the rail power, but limit it by max_charge_rate
        local charge_amount = math.min(max_charge_rate, rail_energy, buffer_space)
        self.energy_buffer = self.energy_buffer + charge_amount
        rail.accu.energy = rail.accu.energy - charge_amount
    end

    -- If the burner needs more energy and the energy buffer has enough
    if self.burner.heat < self.burner.heat_capacity * 0.1 and self.energy_buffer > 0 then
        -- Transfer energy from the buffer to the burner
        local required_energy = self.burner.heat_capacity * 0.99 - self.burner.heat
        local power_transfer = math.min(self.energy_buffer, required_energy)
        self.burner.heat = self.burner.heat + power_transfer
        self.energy_buffer = self.energy_buffer - power_transfer
    end
end

I was also thinking the same thing about longer burning “fuel”

Hermios commented 4 days ago

In your code, you don't consider energy provider (rail.accu), so basically, you have just free energy until the buffer is empty.... Then it just never works anymore. what makes your code works is mostly a bigger buffer. I can try that. I will set a bugger to 40MJ, which means 2 personal batteries. Let see what it gives.