Showing posts with label vehicles. Show all posts
Showing posts with label vehicles. Show all posts

Saturday, August 21, 2021

Quick PZ Code Questions



Here are quick answers to some PZ questions, without much code context.  Let me know if you want me to do deeper looks into some of these systems!

1. How far away do house alarms alert zombies?

700 tiles

From the AmbientSoundManager class

            Ambient ambient = new Ambient("burglar2", roomDef.x + roomDef.getW() / 2, roomDef.y + roomDef.getH() / 2, 700.0f, f);


2. How frequently do foraging zones refresh themselves?

50,000 game seconds, or close to 14 in-game hours.

From ISScavengeAction.lua

        if getGametimeTimestamp() - zone:getLastActionTimestamp() > 50000 then
            --            print("refill zone");
            zone:setName(tostring(scavengeZoneNumber));
            zone:setOriginalName(tostring(scavengeZoneNumber));


3. Can wound infections kill you?

No.  It's hard to prove that something can't happen in code (because maybe I'm not looking at the right place to see the code that does something), but you can try searching for related terms in the code.  If I wanted to show my evidence, I'd list all the terms I searched, and show that the hits did not lead to any damage or deaths.

I found that at their worst, wound infections cause up to 10 pain (and pain goes up to 100).  So don't worry too much about wound infections, but take care of them if you can.  Multiple infections add up.

From the BodyPart class, WoundInfectionLevel is part of the getPain calculation:

        if (this.getWoundInfectionLevel() > 0.0f) {
            f += this.getWoundInfectionLevel();

And you can see here that WoundInfectionLevel is 10 at worst.

                if (this.getWoundInfectionLevel() > 10.0f) {
                    this.setWoundInfectionLevel(10.0f);
                }


4. Does being an axe man increase your swing speed in combat?

Yes.  By 25%.

Here is some code from calculateCombatSpeed, in the IsoGameCharacter class, showing that an Axeman using an Axe has a multipler on the chop tree speed.

        if (handWeapon != null && this.Traits.Axeman.isSet() && handWeapon.getCategories().contains("Axe")) {
            f *= this.getChopTreeSpeed();
        }

And you can see here in the same class that ChopTreeSpeed is 1.25 if you have AxeMan, but only 1.0 if you don't.

    public float getChopTreeSpeed() {
        return (this.Traits.Axeman.isSet() ? 1.25f : 1.0f) * GameTime.getAnimSpeedFix();
    }


5. Can you OD on pills besides sleeping pills?

No.  Again, I can't really prove the code doesn't exist, but the code I examined for overdosing on sleeping pills doesn't have an equivalent for the other pills (pain, vitamins, antidepressants, betablockers).  Antibiotics are considered to be food, and you also can't OD on them.


6. Do zombies hear the large vehicle backup alert?

No.  I should do a post on the sound system in the future to go into detail, but I can demonstrate this by comparing it to how the car horn is handled.  Both sounds are generated in the BaseVehicle class:

WorldSoundManager.instance.addSound((Object)this, (int)this.getX(), (int)this.getY(), (int)this.getZ(), 150, 150, false);

That is a line from when the car horn sounds.  The 150, 150 describes the radius the sound carries, and the volume.  FYI car horns can be heard by zombies for 150 tiles.

The backup sound does something different:

        if (this.script.getSounds().backSignalEnable) {
            this.soundBackMoveSignal = this.emitter.playSoundLoopedImpl(this.script.getSounds().backSignal);
            this.emitter.set3D(this.soundBackMoveSignal, !this.isAnyListenerInside());
        }

No radius or volume, because this sound is only for the player.  Like music or the level-up sound.  Zombies can't hear it.


Thanks for reading!  If you notice a mistake or if you have any questions, please let me know!

Thursday, August 19, 2021

Engine Quality Facts

Twitch streamer RoyaleWithCheeseTV asked me to take a look at Engine Quality.

I've always wanted to more about engine quality, so I thought I'd take a look!

What I found:

  • Initial engine quality is random, based partially by the vehicle stats and vehicle type
  • Engine quality affects whether it will start
  • 100% engines always start (99% of the time they do)
  • 99% engines fail to start ~20% of the time
  • Temperature affects whether an engine will start (if the quality is < 65)
  • Engine quality affects hotwiring - lower quality engines are easier to hotwire

Here's how I found it:

I was surprised to see that engines appear to be created in the lua code, in Vehicles.lua:

function Vehicles.Create.Engine(vehicle, part)
	if SandboxVars.VehicleEasyUse then
		vehicle:setEngineFeature(100, 30, vehicle:getScript():getEngineForce());
		return;
	end
	part:setRandomCondition(nil);
	local type = VehicleType.getTypeFromName(vehicle:getVehicleType());
	local engineQuality = 100;
	if type then
		local baseQuality = vehicle:getScript():getEngineQuality() * type:getBaseVehicleQuality();
		-- bit of randomize
		engineQuality = ZombRand(baseQuality - 10, baseQuality + 10);
	end
	engineQuality = ZombRand(engineQuality - 5, engineQuality + 5);
	engineQuality = math.max(engineQuality, 0)
	engineQuality = math.min(engineQuality, 100)

	local engineLoudness = vehicle:getScript():getEngineLoudness() or 100;
	engineLoudness = engineLoudness * (SandboxVars.ZombieAttractionMultiplier or 1);

	local qualityBoosted = engineQuality * 1.6;
	if qualityBoosted > 100 then qualityBoosted = 100; end
	local qualityModifier = math.max(0.6, ((qualityBoosted) / 100));
	local enginePower = vehicle:getScript():getEngineForce() * qualityModifier;

	vehicle:setEngineFeature(engineQuality, engineLoudness, enginePower);
end

Looks like the engine quality is randomly determined, based partially on the vehicle definition in the script and the vehicle type.

Also looks like engine power is affected by the engine quality (but probably only upon engine creation).  So there will be a correlation between engine quality and engine power.

After a little grepping, I confimed that the BaseVehicle class was where the engine quality is used in the code:

    private void updateEngineStarting() {
        if (this.getBatteryCharge() <= 0.1f) {
            this.engineDoStartingFailedNoPower();
            return;
        }
        VehiclePart vehiclePart = this.getPartById("GasTank");
        if (vehiclePart != null && vehiclePart.getContainerContentAmount() <= 0.0f) {
            this.engineDoStartingFailed();
            return;
        }
        int n = 0;
        float f = ClimateManager.getInstance().getAirTemperatureForSquare(this.getSquare());
        if (this.engineQuality < 65 && f <= 2.0f) {
            n = Math.min((2 - (int)f) * 2, 30);
        }
        if (!SandboxOptions.instance.VehicleEasyUse.getValue() && this.engineQuality < 100 && Rand.Next((int)(this.engineQuality + 50 - n)) <= 30) {
            this.engineDoStartingFailed();
            return;
        }
        if (Rand.Next((int)this.engineQuality) != 0) {
            this.engineDoStartingSuccess();
        } else {
            this.engineDoRetryingStarting();
        }
    }

As expected, engine quality affects whether or not an engine starts (per attempt).

I didn't know that 100% engines never fail!  (if enginequality = 100 it just skips over the failure code) (with caveat below)

In regular warm weather, 99% engines fail to start ~20% of the time.  (99 + 50) = 149.  Random chance of 0-148 being 30 or under is ~20%.

I didn't know that cold temperatures reduce the chance that an engine will start!  I've only played in winter twice.  Basically, if the temperature is 2 or lower (probably Celsius, but I haven't confirmed), that will modify "n" (to an upper limit of 30, with a temp of -13 or colder) that will reduce the chance the engine will start (if the quality of that engine is < 65).

Despite what I said earlier, there is a 1% chance that a 100% quality engine will not start.  After getting through the other possible obstacles to starting, the engine has a 1 in engineQuality chance of not starting.  I guess what I'm saying is that a 100% quality engine will have a 100% chance of getting to a point where it will start 99% of the time.

Another surprise for me was that engine quality affects (vanilla) hotwiring!

    public void tryHotwire(int n) {
        int n2 = Math.max(100 - this.getEngineQuality(), 5);
        n2 = Math.min(n2, 50);
        int n3 = n * 4;
        int n4 = n2 + n3;
        boolean bl = false;
        if (Rand.Next((int)100) <= n4) {
            this.setHotwired(true);
            bl = true;
        } else if (Rand.Next((int)100) <= 10 - n) {
            this.setHotwiredBroken(true);
            bl = true;
        } else if (GameServer.bServer) {
            LuaManager.GlobalObject.playServerSound((String)"VehicleHotwireFail", (IsoGridSquare)this.square);
        } else if (this.getDriver() != null) {
            this.getDriver().getEmitter().playSound("VehicleHotwireFail");
        }
        if (bl && GameServer.bServer) {
            this.updateFlags = (short)(this.updateFlags | 0x1000);
        }
    }

Here's how this appears to work:

  • The worse your engine quality, the higher n2 is.
  • n2 gets to be either n2 or 50, whichever is lower
  • The higher n2 is, the higher n4 is
  • The higher n4 is, the more of a chance of a successful hotwire.

So, the better quality engines are more difficult to hotwire (with limits).

That's it!  

Thanks for reading.  If you see any mistakes I made or have any questions, please let me know!

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...