Thursday, September 30, 2021

Can You Drink Tainted Water?

Can you drink tainted water safely?  Yes

If you are drinking it directly from the tainted source (i.e. river or lake), you will barely get sick (probably not even enough to notice it) and will completely recover before you're thirsty again.

If you are drinking it from a bottle, it can be safe if you only drink a small amount.  The more you drink, the sicker you will get.  If you drink too much, you can die.


Drinking Tainted Water From a River

When you drink water from a river (or lake) the code starts in the ISWorldObjectContextMenu.lua file, in onDrink:

ISWorldObjectContextMenu.onDrink = function(worldobjects, waterObject, player)
    local playerObj = getSpecificPlayer(player)
	if not waterObject:getSquare() or not luautils.walkAdj(playerObj, waterObject:getSquare(), true) then
		return
	end
	local waterAvailable = waterObject:getWaterAmount()
	local thirst = playerObj:getStats():getThirst()
	local waterNeeded = math.floor((thirst + 0.005) / 0.1)
	local waterConsumed = math.min(waterNeeded, waterAvailable)
	ISTimedActionQueue.add(ISTakeWaterAction:new(playerObj, nil, waterConsumed, waterObject, (waterConsumed * 10) + 15, nil));
end

When you drink from a river, you have all the water you need to we're mainly concerned about your thirst and waterNeeded.

Thirst is a value between 0 and 1, and represents how thirsty you are.

WaterNeeded takes your thirst (0-1) to calculate the amount of water you need, so becomes a value between 0 and 10.

WaterConsumed, in this case, is equal to waterNeeded

We send waterConsumed to ISTakeWaterAction.lua, inside ISTakeWaterAction:perform()

        if self.waterObject:isTaintedWater() then
            self.character:getBodyDamage():setPoisonLevel(self.character:getBodyDamage():getPoisonLevel() + self.waterUnit);
        end

We see the consequences of drinking the tainted water.  The amount you drank (10 units max) is added to the current poison level.

That means, if you were completely healthy before, you can have a maximum PoisonLevel of 10.  What does that mean?

We can look in the BodyDamage class, in the update() method, to see:

        if (this.PoisonLevel > 0.0f) {
            if (this.PoisonLevel > 10.0f && this.getParentChar().getMoodles().getMoodleLevel(MoodleType.Sick) >= 1) {
                f += 0.0035f * Math.min(this.PoisonLevel / 10.0f, 3.0f) * GameTime.instance.getMultiplier();
            }
            float f3 = 0.0f;
            if (this.getParentChar().getMoodles().getMoodleLevel(MoodleType.FoodEaten) > 0) {
                f3 = 1.5E-4f * (float)this.getParentChar().getMoodles().getMoodleLevel(MoodleType.FoodEaten);
            }
            this.PoisonLevel = (float)((double)this.PoisonLevel - ((double)f3 + ZomboidGlobals.PoisonLevelDecrease * (double)GameTime.instance.getMultiplier()));
            if (this.PoisonLevel < 0.0f) {
                this.PoisonLevel = 0.0f;
            }
            this.setFoodSicknessLevel(this.getFoodSicknessLevel() + this.getInfectionGrowthRate() * (float)(2 + Math.round(this.PoisonLevel / 10.0f)) * GameTime.instance.getMultiplier());
            if (this.getFoodSicknessLevel() > 100.0f) {
                this.setFoodSicknessLevel(100.0f);
            }
        }

Being healthy and drinking directly from the river gives us a maximum PoisonLevel of 10, so there is no effect here.

And you can see here that the PoisonLevel goes down.

So unless you were already poisoned, you will take no damage.  And by the time you are naturally thirsty again (unless you do something to increase your thirst like eat something that increases your thirst), your poison level will have dropped to 0, so it will be safe for you to drink from the river again.

So drinking from a tainted natural water source, like a river, is safe so long as you were already healthy.  You will recover from the minor negative effect before you are thirsty again.


Drinking Tainted Water From a Bottle

Let's quickly compare this to drinking tainted water from a bottle, which starts in ISInventoryPaneContextMenu.lua:

ISInventoryPaneContextMenu.onDrinkForThirst = function(waterContainer, playerObj)
    local thirst = playerObj:getStats():getThirst()
    local units = math.min(math.ceil(thirst / 0.1), 10)
    units = math.min(units, waterContainer:getDrainableUsesInt())
    ISInventoryPaneContextMenu.transferIfNeeded(playerObj, waterContainer)
    ISTimedActionQueue.add(ISDrinkFromBottle:new(playerObj, waterContainer, units))
end

It calculates the number of units in much the same way as drinking from the river, except it limits the amount you can drink to how much is available in the container.  But the maximum is 10 units, so let's look at that.  

We move to ISDrinkFromBottle:

function ISDrinkFromBottle:drink(food, percentage)
    -- calcul the percentage drank
    if percentage > 0.95 then
        percentage = 1.0;
    end
    local uses = math.floor(self.uses * percentage + 0.001);

    for i=1,uses do
        if not self.character:getInventory():contains(self.item) then
            break
        end
        if self.character:getStats():getThirst() > 0 then
            self.character:getStats():setThirst(self.character:getStats():getThirst() - 0.1);
            if self.character:getStats():getThirst() < 0 then
                self.character:getStats():setThirst(0);
            end
            if self.item:isTaintedWater() then
                self.character:getBodyDamage():setPoisonLevel(self.character:getBodyDamage():getPoisonLevel() + 10);
            end
            self.item:Use();
        end
    end

end

Here you can see that it adds 10 to the PoisonLevel for EACH USE of the bottle.  In this example, that's 10 times because that's how much water you want to drink at maximum thirst.  That's 100 poison, which is enough to kill you.  But you can also see that if you hadn't been very thirsty, and had only wanted 1 unit, that would have corresponded to a poison value of 10 which we saw earlier is easily handled.


What About Prone To Illness or Weak Stomach?

It looks to me like Prone To Illness only affects colds (so not food sickness) and mortality length.

And it looks to me like Weak Stomach only affects foods you eat (so not water).

So I don't think either of those traits affects drinking tainted water.


Extra:  Lemongrass

I'll also mention here that in the IsoGameCharacter class it shows that when you eat lemongrass (ReduceFoodSickness level of 12), it reduces both your food sickness level and your poison level.  In case you want to carry some lemongrass for emergencies.

        if (this.BodyDamage.getFoodSicknessLevel() > 0.0f && (float)food.getReduceFoodSickness() > 0.0f && this.effectiveEdibleBuffTimer <= 0.0f) {
            float f4 = this.BodyDamage.getFoodSicknessLevel();
            this.BodyDamage.setFoodSicknessLevel(this.BodyDamage.getFoodSicknessLevel() - (float)food.getReduceFoodSickness() * f);
            if (this.BodyDamage.getFoodSicknessLevel() < 0.0f) {
                this.BodyDamage.setFoodSicknessLevel(0.0f);
            }
            float f5 = this.BodyDamage.getPoisonLevel();
            this.BodyDamage.setPoisonLevel(this.BodyDamage.getPoisonLevel() - (float)food.getReduceFoodSickness() * f);
            if (this.BodyDamage.getPoisonLevel() < 0.0f) {
                this.BodyDamage.setPoisonLevel(0.0f);
            }
            this.effectiveEdibleBuffTimer = this.Traits.IronGut.isSet() ? Rand.Next((float)80.0f, (float)150.0f) : (this.Traits.WeakStomach.isSet() ? Rand.Next((float)120.0f, (float)230.0f) : Rand.Next((float)200.0f, (float)280.0f));
        }


Thanks for reading!  If you see any mistakes or if you have any questions you'd like me to answer by looking at the code, let me know!

4 comments:

  1. So weak stomach isn't bad as I thought

    ReplyDelete
  2. Was interesting to read. Thanks.

    ReplyDelete
  3. Took me time to read all the comments, but I really enjoyed the article. It proved to be Very helpful to me and I am sure to all the commenters here! It’s always nice when you can not only be informed, but also entertained! shop

    ReplyDelete
  4. Be aware of the source of your water when traveling abroad. Even while tainted water appears clean, it still contains dangerous germs, viruses, and parasites. For most travelers, the safest alternative is factory-sealed bottled water. But depending on where it comes from and how it has been processed, some bottled water can be dangerous. Always search for factory-sealed, unopened bottles of water or other beverages.

    boring water sydney

    ReplyDelete

Do Gloves Protect You From Broken Glass?

Yes, gloves protect you from handling broken glass - any pair of gloves.  But gloves are not needed when removing broken glass from a smashe...