Problem with vehicle speeds

Place to get help with not working mods / modding interface.
Pi-C
Smart Inserter
Smart Inserter
Posts: 1757
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Problem with vehicle speeds

Post by Pi-C »

I've a strange problem with vehicle speeds in one of my mods. Basically, I let a tank run forwards to a standing car. The tank is controlled by my mod, so on_tick is run for it.

When the tank hits the car, on_entitiy_damaged will be triggered (event.entity: the car, event.cause: the tank). From the perspective of the tank, I can see the car in front; from the perspective of the car, the tank is in front. I then use tank.prototype.weight and tank.speed as well as car.prototype.weight and car.speed to calculate the bounce speeds of both vehicles. Then I set tank.speed to and car.speed to the respective bounce speeds. I log tank.speed in various places, and the same negative speed is displayed all the time, until the end of the event handler.

Next, on_entity_damaged will be triggered again, but this time the tank is both event.entity and event.cause, so I quit immediately. The log shows that the tank still has the same speed as when the event was triggered for tank+car. However, when the handler for on_tick is run the next time (immediately after the second time on_entity_damaged was run), tank.speed is 0.

You can see the problem in the following screenshot: The pair of boxes (yellow: front, red: back) fits exactly around the tank's collision_box, which indicates that the tank hasn't moved backwards one bit. The smaller boxes with the gap between them indicate where the car was standing at the moment of impact. It has been pushed out of the picture by the impact from the tank.
crash.png
crash.png (2.55 MiB) Viewed 743 times
I've also tried it the other way around: Got into the car (which is not controlled by my mod), and crashed frontally into the tank. This time, the tank was bouncing a bit (because it's much heavier than the car, the impact has only a weak effect) but the car came to a full stop. However, the log did show that both bouncing speeds didn't change until the end of the second on_entity_damaged.

There really isn't any other mod running except for the Lua API global Variable Viewer (gvv), so this must be either an issue of my mod or something coming from the base game. Given that in both cases event.cause of on_entity_damaged was stopped in its tracks while event.entity did bounce, I'm inclined to say that there may be some mechanics in vanilla which I don't understand.

I've attached the relevant portion of the log file (the on_tick immediately before the crash, both on_entity_damaged events, and the beginning of on_tick following the crash). There are multiple places where I've logged the speed of tank and car, just to find out whether something in my code would set the speed of the tank (or rather: the event.cause of on_entity_damaged) to 0, but it is at the original bouncing speed all the time.

I'd be extremely glad if somebody could shed some light on this! :-)
Attachments
log.txt
(32.98 KiB) Downloaded 56 times
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Pi-C
Smart Inserter
Smart Inserter
Posts: 1757
Joined: Sun Oct 14, 2018 8:13 am
Contact:

Re: Problem with vehicle speeds

Post by Pi-C »

I guess I've figured it out: defines.events.on_entity_damaged will be called for each damaged entity. If event.damage_type is "impact", i.e. if vehicle A crashes into vehicle B, the event will first be raised for vehicle B, and B.health will be event.final_health while A.health still is the same as before the crash. I can only heal B at this point (because the damage hasn't been applied yet to A), and when my event handler is done, B.health will be at the value I've set.

As an impact will damage both A and B, the event will be raised next for A, with the damage the vehicle dealt to itself while crashing, and now I can heal A. The event may be raised even a third time if A and B have been moving toward each other. This time, A will be event.entity and its health will have been reduced to event.final_health again, while B will be event.cause.

I assume that the game will not only apply damage when defines.events.on_entity_damaged is raised, but also set the speed of vehicles to 0 if they took impact damage. That would explain why A.speed would be 0 at the start of the next tick although I've set it to a different value.

For my calculations of bounce speeds I need both A and B. They are only guaranteed to exist the first time the event is raised, so when that happened I'd heal both entities, change their speeds, and set a flag for ignoring the following events. I've now changed that: I still set the flags the first time the event is raised, but when the event is raised for an entity that has the flag set, I'll only restore health and skip the calculations. On the next tick, my handler for defines.events.on_tick will remove the flag if it exists and set the initial bouncing speed just once.
A good mod deserves a good changelog. Here's a tutorial (WIP) about Factorio's way too strict changelog syntax!
Post Reply

Return to “Modding help”