Water Turret

by Pi-C

This mod provides an early game Water thrower that does minimal damage but slows down the enemies (use steam for extra damage!) and an advanced turret for extinguishing fires (use "Hardened pipes" to give it extra resistances!).

Content
3 years ago
0.17 - 1.1
5.67K
Combat

i I know how to fix the targeting issues

2 years ago
  • create two new forces: 'waterturret' and 'fire', make the 'waterturret' force friends with player and visa versa, and add 'fire' force to all other force's ceasefire list EXCEPT the 'waterturret' force (this way the only force that considers 'fire' an enemy is the 'waterturret'.
  • keep fire-dummy entity as simple_entity_with_force so it gets targeted as usual.
  • add an on_built function to assign the waterturret entities to the new waterturret force (as friends with the player force it can be mined and all usual stuff)
  • have the fire dummy entities belong to the 'fire' force as the one true enemy of all 'waterturret' (dont change the actual fire-entity obviously)

Im going to prototype this code (I was just using the in game commands to test it and it seems to work really well since it avoids having to use the target_mask system which lets be honest kinda sucks right now without further love from the devs. I'll let you know how it went
Also btw this mod messes with the target mask on asteroids with space exploration meaning they dont get shot by turrets

2 years ago

Thanks for giving this some thought!

  • create two new forces: 'waterturret' and 'fire', make the 'waterturret' force friends with player and visa versa, and add 'fire' force to all other force's ceasefire list EXCEPT the 'waterturret' force (this way the only force that considers 'fire' an enemy is the 'waterturret'.

I think this could work with vanilla Factorio.

  • add an on_built function to assign the waterturret entities to the new waterturret force (as friends with the player force it can be mined and all usual stuff)

I see some problems there with multiplayer games where players are on different forces. If a turret belongs to the force of the player who built it, no player from an enemy force will be able to mine it. But that changes if if the turrets are immediately assigned to a force that's friends with all player forces. Also, I guess changing the force of the turrets could mess up the production or consumption stats -- not sure, it's just a hunch.

Im going to prototype this code (I was just using the in game commands to test it and it seems to work really well since it avoids having to use the target_mask system which lets be honest kinda sucks right now without further love from the devs. I'll let you know how it went

I recently played around with target_masks for guns (the artillery cannon is a "gun" prototype which is separate from the "artillery turret" prototype), but that didn't work, unfortunately …

Also btw this mod messes with the target mask on asteroids with space exploration meaning they dont get shot by turrets

Thanks for the hint, I'll look into that! SE affects several of my mods, but as I haven't played for quite some time, I never know about it until somebody reports a bug.

2 years ago

Ok so did some testing:
- The force re-assignment works perfectly and the water turrets shoot just as expected at the fire dummies and nothing else does; even personal lasers/spidertrons/AAI vehicles! Also the space exploration asteroids work as intended.

  • the obvious issue now is force assignment for each player (if on different forces) as in my testing right now there is only one kinda global 'waterturret' force which is only friends with the default 'player' force. This casues a number of problems, most importantly it stops water turrets from shooting other players and worse means any player can mine any other players water turrets.

Let me first say that I love all the comments in your code it makes it much easier to understand the optimized-obscured code, however I am just not familiar enough with the mod's codebase to be able to implement a fix for above (I did do some simple experiments however which seem promising!)

My idea was to create an additional 'water turret' force for each player force that is then friendly with only that player force and name it based on the name of the player who placed it's force (eg 'SimonsForce' places a waterturret, create (SimonsForce .. "-water-turret") force)
This would require a global variable for player forces (since on_built doesn't return the force of the robot/script that placed it) and instead filter the on_built event for each player force (which does filter for forces when placed by robot/scripts). - this is where I kinda gave up since I don't really know (couldn't be bothered looking it up) how to properly implement a dynamic filter.
Though I would imagine it would just be a case of using a custom event for each new force detected and acting on that current event with a [playerforce].."-water-turret" or something like that

That might sound excessive but checking on built for each player force isn't that expensive at all if its filtered correctly for only player forces.

Hopefully you can get something out of my little experiment or the devs just fix turret masks :)

2 years ago

Note though that the above fix it works fine in non-pvp settings!

2 years ago

My idea was to create an additional 'water turret' force for each player force that is then friendly with only that player force and name it based on the name of the player who placed it's force (eg 'SimonsForce' places a waterturret, create (SimonsForce .. "-water-turret") force)

Creating another force for each force with human players is quite expensive and may break things because Factorio has a hard limit of 64 forces.

This would require a global variable for player forces (since on_built doesn't return the force of the robot/script that placed it) and instead filter the on_built event for each player force (which does filter for forces when placed by robot/scripts). - this is where I kinda gave up since I don't really know (couldn't be bothered looking it up) how to properly implement a dynamic filter.

You probably could check each force for players, and update that list in on_player_changed_force and on_player_joined_game. Filters can be modified with script.set_event_filter when on_force_created or on_forces_merged trigger.

Though I would imagine it would just be a case of using a custom event for each new force detected and acting on that current event with a [playerforce].."-water-turret" or something like that

Somebody must raise a custom event before you can respond to it. The normal events should be sufficient. But if I remember correctly, I had problems with Klonan's construction bots not raising events correctly. (Actually, it may be that was about TILES placed by script, not entities.)

That might sound excessive but checking on built for each player force isn't that expensive at all if its filtered correctly for only player forces.

Filtering by entity type seems to be easier…

Hopefully you can get something out of my little experiment or the devs just fix turret masks :)

The biggest obstacle is that the limit to the number of forces. Perhaps another approach would work: Only extinguisher turrets can be used to extinguish fire, while normal water turrets would attack just enemies. That's not really logical (water should extinguish fire), but would reduce the number of new forces required.

1 year, 11 months ago

You could probably make a player-minable turret that remains on the player force, and spawn a non-minable "extinguisher" force turret in the same place that holds the actual gun. Whenever the fake turret is mined, the "extinguisher" one is destroyed. That way you really only need 2 additional forces.

1 year, 11 months ago

@wildejackson Could you perhaps share your prototype code? Then I'd try to implement my proposed solution.

1 year, 11 months ago

You could probably make a player-minable turret that remains on the player force, and spawn a non-minable "extinguisher" force turret in the same place that holds the actual gun.

I already swap turrets depending on the contents of the pipes they are connected to. That works because there will be just one turret in place -- either a water turret or a steam turret. What you suggest is difficult because there would be two entities (turret that can extinguish fire and the fake entity) at the same position, but only one pipeline. The minable turret must be on top, so it can be mined. But this would mean that it gets the pipe connection and the real entity gets no fluid. So it would probably be necessary to use on_tick to check the fluid box of the minable turret and copy the amount of fluid there to the real turret. That's quite a hacky approach, and I wouldn't wonder if it breaks things …

1 year, 11 months ago
(updated 1 year, 11 months ago)

You could probably make a player-minable turret that remains on the player force, and spawn a non-minable "extinguisher" force turret in the same place that holds the actual gun.

What you suggest is difficult because there would be two entities (turret that can extinguish fire and the fake entity) at the same position, but only one pipeline. The minable turret must be on top, so it can be mined. But this would mean that it gets the pipe connection and the real entity gets no fluid. So it would probably be necessary to use on_tick to check the fluid box of the minable turret and copy the amount of fluid there to the real turret. That's quite a hacky approach, and I wouldn't wonder if it breaks things …

I figured as much. The main challenge is replicating both user place/break behavior and blueprintability - adding a small additional "mining corner" to the turret wouldn't matter for hand mining, but might make blueprints inconvenient. Perhaps a 2-part design of the turret (one half functional, one half base part for player interaction, with item placement sprite combining the 2) might work - or maybe another workaround is needed. I am relatively confident that there is some solution that allows both convenient blueprintability and pvp-aware player minability, but even in the worst case the non-functional "interaction box" will simply appear as a box in blueprints, and would have to be pointed at to mine the turret, which would still be much better than artillery firing napalm shells (or nukes) at fires.

edit: and even without these adaptations, a "single player" setting implementing the faction approach without the pvp minability complications would probably be worth adding, since the vast majority of playthroughs seems to be SP or coop, not pvp.

1 year, 11 months ago

Blueprintability isn't a problem, I think. One prototype could be made to not be blue-printable, and when a build-event triggers, it could be placed by script.

It's the fluid boxes that I'm concerned about -- managing whether or not there is any fluid inside the turret. If only the shooting turret had ammo, hovering above the fake turret would always show that it had no fluid. That could be solved by setting the fluid box contents to the same value as that of the shooting turret, but that would have to run on every tick. But if both turrets have ammo, they will both shoot. In the best case, they will attack the same target automatically (side effect: it would get twice the damage), but I'm afraid they might pick different targets, so you'd also have to synchronize the movement per script. This would be closing the circle again: I've switched to using target_masks because setting targets per script was too heavy on UPS; having to do that for two turrets instead of one would be even worse.

1 year, 11 months ago
(updated 1 year, 11 months ago)

The fluid box and the turret both need to be on the same entity to work w/o script, and that entity needs to be of the "firefighter" faction, and undeconstructable. The deconstructable placer faction associated entity needs to be selectable.

If that selectable entity spans the whole turret, it won't be possible to see its statistics (fluid level, kills, ...) w/o script. So we need to either offset it (small "deconstruction handle" to one side) or designate a non-shooting/non-fluid box part of the turret to that purpose (eg. the front legs of the turret have the deconstruction selection box, the main part has fluid connections and statistics). It's slightly less convenient to use (can't deconstruct by rightclicking the active part) but should work fine. The only problem I see is that in blueprints, only one part of the turret would show up, and I don't know how easy it is to manage the whole-turret hitbox if the BP only contains half of it (I suspect it might place a ghost even though there is not enough space for the whole turret?)

edit: one problem I see with the whole approach is that firefighter turrets obviously won't shoot at units controlled by other players, so for pvp purposes, this approach comes with some limitations either way - though not as much as being unable to use any artillery without friendly fire. One solution would be to stop normal water turrets from deliberately shooting at fires, and reserve the extinguisher turret for that purpose, but then you effectively have just another flamethrower turret using steam instead of oil...

1 year, 8 months ago

Just brainstorming a bit.. Maybe it is possible to add a water\steam tower 1x1 object in the square next to the turret that handles all the liquid stuff?

New response