[Question]
  [
## Introduction:
Before the task, here is what every element does on the map:
**Plain land** (`X`): This does nothing.
**Destroyed land** (`-`): This is the same as plain land, but destroyed by a bomb.
**The active bomb** (`!`): On a map, this will destroy everything in a 3x3 square:
```
XXXXX                         XXXXX
XXXXX                         X---X
XX!XX     > will become >     X---X
XXXXX                         X---X
XXXXX                         XXXXX
```
**The passive bomb** (`@`): It does nothing, until it is detonated by another bomb. This also has a **3x3** square explosion radius:
```
XXXXX                         XXXXX
XXXXX                         XXXXX
XX@XX     > will become >     XX@XX (nothing happened)
XXXXX                         XXXXX
XXXXX                         XXXXX
```
But:
```
XXXXX                         XXXXX
XXXXX                         X---X
XX@XX     > will become >     ----X (both bombs have exploded)
X!XXX                         ----X
XXXXX                         ---XX
```
**The nuke** (`~`): It does nothing, until it is detonated by another bomb. The difference is that this bomb has a **5x5** square explosion radius:
```
XXXXX                         XXXXX
XXXXX                         XXXXX
XX~XX     > will become >     XX~XX (nothing happened)
XXXXX                         XXXXX
XXXXX                         XXXXX
```
But:
```
XXXXX                         -----
XXXXX                         -----
XX~XX     > will become >     ----- (both bombs have exploded)
X!XXX                         -----
XXXXX                         -----
```
## The task
* Given a **9x9 map**, output the map *after* the chain reaction.
* You may provide a function or a program.
* This is [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the submission with the least amount of bytes wins!
## Test cases
Test case 1 (*3 steps*):
```
XXXXXXXXX           XXXXXXXXX
----XXXXX           ----XXXXX
XXXX@XXXX           XXXX@XXXX
XXXXXXXX-           XXX---XX-
XXXX@XXXX     >     ------XXX
XXXXXXXX-           ------XX-
XX~XXXXXX           -----XXXX
X!XXXXXX-           -----XXX-
XXXXXXXXX           -----XXXX
```
Test case 2 (*2 steps*):
```
XXXXXXXXX           XXXXXXXXX
XXXXXXXXX           XXXXXXXXX
XX~XXXXXX           XX~XXXXXX
---------           ---------
XXXX!XXXX     >     XXX---XXX
XXXXXXXXX           XXX------
XXX@@X@!X           XXX@@----
XXXXXXXXX           XXXXX----
XXXXXXXXX           XXXXXXXXX
```
Test case 3 (*2 steps*):
```
XXXXXXXXX           XXXXXXXXX
XXXXXXXXX           XXXXXXXXX
XX~XXXXXX           XX~XXXXXX
XXXXXXXXX           XXX---XXX
XXXX!XXXX     >     XXX---XXX
XXXXXXXXX           XXX------
XXX@@X@!X           XXX@@----
XXXXXXXXX           XXXXX----
XXXXXXXXX           XXXXXXXXX
```
Test case 4 (*1 step*):
```
XXXXXXXXX           XXXXXXXXX
XXXX-XXXX           XXXX-XXXX
XXXXXXXXX           XXX---XXX
XX-X!X-XX           XX-----XX
XXXXXXXXX     >     XXX---XXX
XX-----XX           XX-----XX
XXXX-XXXX           XXXX-XXXX
XXXXXXXXX           XXXXXXXXX
XXXXXXXXX           XXXXXXXXX
```
Test case 5 (*9 steps*):
```
!XXXXXXXX           ---XXXXXX
X@XXXXXXX           ----XXXXX
XX@XXXXXX           -----XXXX
XXX@XXXXX           X-----XXX
XXXX@XXXX     >     XX-----XX
XXXXX@XXX           XXX-----X
XXXXXX@XX           XXXX-----
XXXXXXX@X           XXXXX----
XXXXXXXX@           XXXXXX---
```
Test case 6 (*9 steps*):
```
XX@@@XXXX           ------XXX
XXXXXXXXX           ------XXX
~XXXXXXXX           ---XXXXXX
XXXXXXXXX           ---XXXXXX
~XXXXXXXX     >     ---XXXXXX
XXXXXXXXX           ---XXXXXX
~XXXXXXXX           ---XXXXXX
@XXXXXXXX           ---XXXXXX
!XXXXXXXX           ---XXXXXX
```
Test case 7 (*3 steps*):
```
!XXXXXXXX           ---XXXXXX
X@XXXXXXX           ----XXXXX
XX@XXXXXX           ----XXXXX
XXXXXXXXX           X---X----
XXXXXX@@!     >     XXXXX----
XXXXXXXXX           X---X----
XX@XXXXXX           ----XXXXX
X@XXXXXXX           ----XXXXX
!XXXXXXXX           ---XXXXXX
```
  
[Answer]
# Matlab, ~~120~~ 111 bytes
```
function f=c(f);c=@(x,i)conv2(x+0,ones(i),'s');a=c(f<34,3);for k=f;a=c(a&f<65,3)|a;a=c(a&f>99,5)|a;end;f(a)='-'
```
> 
> Convolution is the key to success.
> 
> 
> 
The idea is following: Find the active bomb. Enlarge this area to a 3x3 square. Find new affected bombs, enlarge the correspoding areas to the corresponding size and add those to the previously destroyed area. Repeat this enough times (in my case as many times as we have input characters, just because that is the shortest variant) to be sure that we reached a stationary point (=no more exploding bombs). Then set all the destroyed area to `-` and display the result.
The input is assumed to be a matrix of characters, e.g.
```
['!XXXXXXXX';
'X@XXXXXXX';
'XX@XXXXXX';
'XXX@XXXXX';
'XXXX@XXXX';
'XXXXX@XXX';
'XXXXXX@XX';
'XXXXXXX@X';
'XXXXXXXX@'];
```
[Answer]
## [Retina](https://github.com/mbuettner/retina/), ~~188~~ ~~168~~ ~~154~~ 152 bytes
Bytes counted as ISO 8859-1.
```
+Tm`@~X!:`!:\-`(.)?.?.(.?(?<1>.)?)(?<=(:|(?(1)_)!|^(?(5)_)(?<-5>.)*(:|(?(1)_)!)(?<1>.*¶)?.*¶(.)*.|(?=(.)*¶.*(?<1>¶.*)?(:|(?(1)_)!)(?<-6>.)*(?(6)_)$))\2)
```
[Try it online!](http://retina.tryitonline.net/#code=K1RtYEB-WCE6YCE6XC1gKC4pPy4_LiguPyg_PDE-Lik_KSg_PD0oOnwoPygxKV8pIXxeKD8oNSlfKSg_PC01Pi4pKig6fCg_KDEpXykhKSg_PDE-LirCtik_LirCtiguKSoufCg_PSguKSrCti4qKD88MT7Cti4qKT8oOnwoPygxKV8pISkoPzwtNj4uKSooPyg2KV8pJCkpXDIp&input=WFhAQEBYWFhYClhYWFhYWFhYWAp-WFhYWFhYWFgKWFhYWFhYWFhYCn5YWFhYWFhYWApYWFhYWFhYWFgKflhYWFhYWFhYCkBYWFhYWFhYWAohWFhYWFhYWFg&debug=on)
~~This is more of a proof of concept. There is a horrible amount of duplication between bombs and nukes, which I'll try to get rid of before adding an explanation.~~ Well, I got rid of that duplication but it increased the complexity significantly so it didn't actually result in huge savings...
[Answer]
# [APL (Dyalog)](https://www.dyalog.com/), 56 chars or 62 bytes\*
My colleague [Marshall](http://dyalog.com/meet-team-dyalog.htm#Marshall) came up with an elegant solution, 21 characters shorter than mine:
```
{'-'@(({1∊⍵≥∘.⌈⍨5⍴1+4↑1}⌺5 5×∘(('X'≠⍵)+'~'=⍵))⍣≡'!'∘=)⍵}
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///Pzyx6FHbhGp1XXUHDY3qRx0r9HUe9W591Ln0UccMvUc9HY96V5g@6t1iqG3yqG2iYe2jnl2mCqaHpwNlNTTUI9QfdS4AKtfUVq9TtwUxNB/1Ln7UuVBdUR2owhbI21r73yWzuABsh4L6o95VQCEdDbNHPXtNH3VNs1QwNASaCxRWt1PXBNq8C4gUwLqADlMA6VSwVLAEOkA9AgZ0gQDOcYhAArrYROqgTEUkNWCgzoXTCiRQh7BUF2azIroiB4cIB0UsmkmyAgVQywpdNOW6QJNRxXQR4akbgRVgWqGIJfwpYmHzhYODA4FgwiPigBGQpPoCNfCRg94BjUZYAQA "APL (Dyalog Unicode) – Try It Online")
`{`…`}` anonymous function where the argument is represented by *⍵*
 `'-'@(`…`)⍵` *dash* **at** the positions masked by the following tacit function:
  `'!'∘=` Boolean where exclamation point equals the argument
  `(`…`)⍣≡` apply the following tacit function until nothing more changes:
   `×∘(`…`)` multiply by the following constant:
    `'~'=⍵` Boolean where tilde equals the original argument
    `(`…`)+` to that, add:
     `'X'≠⍵` Boolean where X is different from the original argument
   `{`…`}⌺5 5` for each, apply the following function on the 5×5 area centered on it:
    `4↑1` take the first four elements of one, padding with zeros [1,0,0,0]
    `1+` add one [2,1,1,1]
    `5⍴` reshape cyclically into length five [2,1,1,1,2]
    `∘.⌈⍨` maximum table with itself on both axes
    `⍵≥` Boolean where the corresponding neighbours are greater than or equal to that
    `1∊` Boolean if any is true
---
\* Just replace `⌺` with `⎕U233A`  under Classic for single byte per character.
[Answer]
# Java, ~~574~~ ~~562~~ ~~558~~ ~~549~~ ~~525~~ 523 bytes
```
import java.util.*;interface B{static char[][]g=new char[9][9];static void d(int i,int j,int r){g[i][j]=45;for(int x=Math.max(i-r,0);x<Math.min(i+r+1,9);x++)for(int y=Math.max(j-r,0);y<Math.min(j+r+1,9);y++)if(g[x][y]==64){d(x,y,1);}else if(g[x][y]>99){d(x,y,2);}else g[x][y]=45;}static void main(String[]a){Scanner q=new Scanner(System.in);for(int i=0;i<9;i++){int j=0;for(char c:q.nextLine().toCharArray())g[i][j++]=c;}for(int j=0;j<9;j++)for(int k=0;k<9;k++)if(g[j][k]==33)d(j,k,1);for(char[]z:g)System.out.println(z);}}
```
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), 61 bytes
```
'-'@({i/⍨∨⌿↑(↓⌈/¨|⍵∘.-i)≤3|'X@~-'⍳a[⍵]}⍣≡('!'=,a)/i←,⍳⍴a)⊢a←⎕
```
[Try it online!](https://tio.run/##pVBNS8NAEL3vr3BPk0DHCOKhB2F@xkLxsFQqgUCF9iLWnCRNtRFFBK9@HHLzoJ6F/pT5I@m0mHaTBi30wbIzb2ffG549j/D0wkb9M@xGdjAIuwXfPYV9Tu4PFKfjXgEI5F2GAWc5pzlPfzh58Dh55GkazPIRZ9@cPu9j6PPk/XAEhmIEzj5tR15Orjh748mLBxqOW9YPQtFtyStnX9bnm1crvfgV4qQWdkPV49trYYSffRyJFSxPydlVBbCYL4aqvdcWNTAlULBqyDjAJib@LbUzswSoTW0H8doNS0tdHyIypBs@b6ddwc7aWJtDkaxyuI4OTSMcbd2Q8U5VZW8i@ieRPxjayGzrvasBu/FS7Xa05w "APL (Dyalog Classic) – Try It Online")
`a←⎕` evaluate input and assign to `a`
`i←,⍳⍴a` the indices (pairs of coords) of all cells
`('!'=,a)/` filter only the initially active bombs
`{ }⍣≡` perform a transformation on the list until it stabilizes
* `'X@~-'⍳a[⍵]` substitute 0 for `X`, 1 for `@`, etc, 4 for anything else (`!`)
* `3|` mod 3 to get the "radius" of impact; it must be greater or equal to the...
* `(↓⌈/¨|⍵∘.-i)≤` ...Manhattan distances between cells in the list and all cells
* `i/⍨∨⌿↑` get bitmask of which cells are affected and select those from `i`
`'-'@( )⊢a` put `-` at those positions
]