Author Topic: How do I change the ID of a tile on the map during a ground battle?  (Read 1147 times)

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 125
  • Sorry for my bEd English
    • View Profile
Is there a good working way to change the ID of a tile during a ground battle? Like changing a tile to its “dead” version.
To realize my idea, at a certain point in the game (at the beginning of a certain turn) certain tiles should change their appearance to other tiles.

I tried to use a pre-detonated special explosive that only deals damage to terrain:
Code: [Select]
terrains:
  - name: XBASE
    addOnly: true
    mapDataSets:
      - BLANKS
      - XBASE1
      - XBASE2
      - XCOMWALL
      - XCOMBITS
      - STARGATE
    mapBlocks:
      - name: STARGA00
        width: 10
        length: 10
        items:
          STR_SWITCH_STARGATE:
            - [2, 4, 0]
            - [3, 4, 0]
            - [2, 4, 1]
            - [3, 4, 1]
        fuseTimers:
          STR_SWITCH_STARGATE: [1, 1]
items:
  - type: STR_SWITCH_STARGATE
    size: 0.3
    weight: 9999
    power: 500
    damageAlter:
      RandomType: 3
      FixRadius: 1
      ToArmorPre: 0.0
      ToArmor: 0.0
      ToHealth: 0.0
      ToWound: 0.0
      ToStun: 0.0
      ToTile: 1.0
    damageType: 3
    battleType: 4
This only works when “FixRadius: 1” is specified, but it plays the explosion animation and sets neighboring tiles on fire or smoke. I tried using a value of “FixRadius: 0”, but in this case nothing happens at all - the explosives just disappear.

Perhaps what I have in mind can be solved with Y-scripts?

Offline Delian

  • Colonel
  • ****
  • Posts: 469
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #1 on: August 21, 2024, 01:09:26 pm »
There's no direct way to change the tiles, however you can craft explosions in such a way that they'd only affect the specific tiles. For instance, you could set the armor of a certain type of tile to be 1, and then set off a few weak explosions that do 2 damage to the whole map. Set their RandomType to 3, a very large FixRadius, and RadiusReduction to 0.

If you want an explosion to affect only 1 tile, then set a very high RadiusReduction.

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 125
  • Sorry for my bEd English
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #2 on: August 21, 2024, 01:24:24 pm »
If you want an explosion to affect only 1 tile, then set a very high RadiusReduction.
I set “RadiusReduction: 50000”, but the explosion animation is still present. I want the tile to “die” without any animation, as if it was hit by a very deadly bullet.

For instance, you could set the armor of a certain type of tile to be 1, and then set off a few weak explosions that do 2 damage to the whole map. Set their RandomType to 3, a very large FixRadius, and RadiusReduction to 0.
Unfortunately, this option is not suitable, because in this case this tile can be destroyed with any weapon. In my scenario, there will be a fierce battle around these tiles and destroying them by the player or AI is not allowed.

Offline Delian

  • Colonel
  • ****
  • Posts: 469
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #3 on: August 21, 2024, 01:54:34 pm »
So, turn explosion animation off (I think by setting hitAnimFrames to 1 and setting hitAnimation to an empty sprite)
« Last Edit: August 21, 2024, 02:01:14 pm by Delian »

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 125
  • Sorry for my bEd English
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #4 on: September 16, 2024, 10:27:13 am »
Well, all of the above tips, when implemented in-game look pretty bad. Even with the explosion animation disabled, the “explosion” still sets fire to the tile and leaves a smoke trail.
Also, if I need to change the identifiers of the same tile several times during a battle, using explosives looks even worse. Especially when I need to change the appearance of a large three-dimensional group of tiles (like a 6x2x3 tile structure).

So I had a suggestion to make a new script operation that changes the specified tile to its “dead” version. Something like this:
Code: [Select]
Script operations:
Name: Tile.setDeathVersion                   Args: [ptre Tile] [var int]   Desc: integer - what part of tile must be convert to death version, 0x1 - floor, 0x2 - westwall, 0x4 - eastwall

Changing a tile to its “dead” version must be done without any animation, sounds or other visual effects.
If the specified tile does not have its “dead” version, the script does nothing.

Offline Delian

  • Colonel
  • ****
  • Posts: 469
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #5 on: September 16, 2024, 12:11:12 pm »
the “explosion” still sets fire to the tile and leaves a smoke trail
set damageAlter.FireThreshold and damageAlter.SmokeThreshold to some high values then

Offline Meridian

  • Global Moderator
  • Commander
  • *****
  • Posts: 9057
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #6 on: September 16, 2024, 12:51:26 pm »
So I had a suggestion to make a new script operation that changes the specified tile to its “dead” version. Something like this:
Code: [Select]
Script operations:
Name: Tile.setDeathVersion                   Args: [ptre Tile] [var int]   Desc: integer - what part of tile must be convert to death version, 0x1 - floor, 0x2 - westwall, 0x4 - eastwall

Changing a tile to its “dead” version must be done without any animation, sounds or other visual effects.
If the specified tile does not have its “dead” version, the script does nothing.

Maybe you can first say where and how you even want to call this function:

Which script hook?
How do you get the pointer/reference to the tile or tiles (and their tile parts) that should be affected?

PS: also the name of the function is very confusing, if I understand correctly you don't want to set the value of the tile death version, you want to set the value of the tile current version... so I would call the function `Tile.convertToDeathVersion` or `Tile.convertToDieMCD` or if we wanted to use the same name as in C++ code then simply just `Tile.destroy`

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 125
  • Sorry for my bEd English
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #7 on: September 16, 2024, 02:01:24 pm »
I think this operation may be available in all script hooks where you can get a pointer to a tile via BattleGame.getTile.

As for the general algorithm for handling this function, I came up with the following (at least for the story I want to implement):
1. On the map block, you specify where a special spawner item will be located (using the spawnUnit parameter), which will create a special tech unit instead when the map is created.
2. When this technical unit is created, the script hook createUnit is triggered. Here the current coordinates of this unit are written to the global tags of the battle game via BattleGame.setTag. After that it is forcibly destroyed, so that there is no corpse in its place.
3. Now the script hook newTurnUnit checks the current turn and its correspondence to the planned scenario. If it does, the “transforming” of the tiles takes place:
   3.1. Based on the previously specified global tags of the game, which contain the coordinates of the technical unit, using the operation BattleGame.getTile the necessary tiles are selected and then this new function of converting them into “dead” variants is used.
   3.2. In another global tag it is written that the tile changes have taken place and when moving to the next unit in the newTurnUnit all these tile conversions do not need to be performed.
4. Further, after a few more game turns, according to the idea of the scenario, this script again performs the transformation of tiles into their “dead” versions.
5. To make the transformations between tiles look more correct I came up with the idea of looping their dead versions on each other: tile1 has tile2 as its dead version, and tile2 has tile1 as its dead version. This way, from the player's point of view, the structure of these tiles is indestructible, which is what I need in my scenario.

As for the name of the operation - make it as convenient and clear as you like. It is important for me that this function works, and how it is called is not important :)

Offline Yankes

  • Commander
  • *****
  • Posts: 3329
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #8 on: September 16, 2024, 02:18:05 pm »
Maybe you can first say where and how you even want to call this function:

Which script hook?
How do you get the pointer/reference to the tile or tiles (and their tile parts) that should be affected?

PS: also the name of the function is very confusing, if I understand correctly you don't want to set the value of the tile death version, you want to set the value of the tile current version... so I would call the function `Tile.convertToDeathVersion` or `Tile.convertToDieMCD` or if we wanted to use the same name as in C++ code then simply just `Tile.destroy`
Yup, name `destroy` is better, we can bikeshedding it more.

For getting tile, you can now access it directly from battle game in any modifying script hook. only problems is mark tile to alter as we do not have lot of feedback what is in tile aside of items or units.

If we add destruction of tile, then I would add opening normal doors too, only problem is updating LOS after this as sometimes engine could not expect changes to map.

Offline Meridian

  • Global Moderator
  • Commander
  • *****
  • Posts: 9057
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #9 on: September 16, 2024, 02:20:16 pm »
ok, I'll check with Yankes if there are any problems with exposing this method to scripts


Which script hook?

newTurnUnit

How do you get the pointer/reference to the tile or tiles (and their tile parts) that should be affected?

direct access by coordinates (coordinates retrieved from a global tag)
« Last Edit: September 16, 2024, 02:22:43 pm by Meridian »

Offline Kozinsky

  • Colonel
  • ****
  • Posts: 125
  • Sorry for my bEd English
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #10 on: September 16, 2024, 02:31:12 pm »
For getting tile, you can now access it directly from battle game in any modifying script hook. only problems is mark tile to alter as we do not have lot of feedback what is in tile aside of items or units.

So how do these operations work? Here the modder specifies which part of the tile the script should use:
Code: [Select]
Name: Tile.isDiscovered                       Args: [ptr Tile] [var int]                            Desc: Check what part of tile is discovered, 0x1 - floor, 0x2 - westwall, 0x4 - eastwall
Name: Tile.makeDiscovered                     Args: [ptre Tile] [int]                               Desc: Make part of tile discovered, 0x1 - floor (will make both walls visible too), 0x2 - westwall, 0x4 - eastwall

Offline Yankes

  • Commander
  • *****
  • Posts: 3329
    • View Profile
Re: How do I change the ID of a tile on the map during a ground battle?
« Reply #11 on: September 16, 2024, 03:12:45 pm »
I mean some thing different. You have no idea what is in tile, do it is part of Craft or Ufo, is this floor of Ufo or grass ground.
As they is no way to add custom tags to map (as most of it is defined by old ufo binary files) you need treat whole map as one "back box".

Of corse you can "tag" tile by placing some items there but it will break if something move this item from this spot (like floor get destroyed by script itself).
e.g. you can reveal alien that shoot you but you can't reveal path to him.

In long time I plan improve this to be more sane but it need lot of work and planing (ETA couple of years after looking on my current pace).