bomb
;не портит ix
;взрывает монстра, заодно стирает из списка объектов
        ld a,7
        call remove_sprscript
         ld a,11 ;3 перезвяк, 5 диньк, 7 тормоз, 9 миниприз, 10 приз, 11 бум
         call SFXPLAY
        
;мы сейчас на нижнем бордере
;берём координаты объекта и рассчитываем, в каком атрибуте делать взрыв
        ;ld ix,objects+(7*OBJSIZE) ;hero
;и генерим партиклы
;сейчас партиклов на экране нет, после взрыва будем их как раз рисовать
        ld a,(ix+OBJ_GFX)
        and 0xfc
        cp ID_BOSS
        push af
        ld a,5 ;чтобы ближе к центру объекта
        jr nz,$+2+3+2+2
         call rnd
         and 15
         sub 3
        add a,(ix+OBJ_X) ;x/2
         ;add a,5 ;чтобы ближе к центру объекта
        ld (genparticles0_x),a
        sub bombradius +5
        ld (bomb_killhero_x),a
        ld (bomb_killmonsters0_x),a
        pop af
        ld a,4 ;чтобы ближе к центру объекта
        jr nz,$+2+3+2+2
         call rnd
         and 15
         sub 3
        add a,(ix+OBJ_Y) ;y/2
         ;add a,4 ;чтобы ближе к центру объекта
        add a,a
        ld (genparticles0_y),a
        srl a
        sub bombradius +4
        ld (bomb_killhero_y),a
        ld (bomb_killmonsters0_y),a
        ld a,MAXDOTS;42;12
        ld (ndots),a
        ld hy,a
        ld bc,tdots ;+5 ;yspeed, y, xspeed, x
genparticles0
        call rnd
        and 15
        add a,a ;0,2...30
        sub 23;15
        ld (bc),a ;yspeed
        inc c
genparticles0_y=$+1
        ld a,0
        ld (bc),a ;y
        inc c
        call rnd
        and 15
        sub 8 ;-8..+7
        sbc a,-1 ;-8..+8
        ld (bc),a ;xspeed
        inc c
genparticles0_x=$+1
        ld a,0
        ld (bc),a ;x
        inc c
         inc c
         inc c
        dec hy
        jp nz,genparticles0
        
        ld a,(ix+OBJ_Y) ;y/2 ;h=gfxdescraddrLSB ;на каждую фазу X 3 байта: gfx16, pg, хотя по идее pg должны быть общие
         add a,6 ;чтобы ближе к центру объекта (на глазок)
          and 0xfc
         ld l,a
        ld a,(ix+OBJ_X) ;x/2
         add a,5 ;чтобы ближе к центру объекта
        scf
        rra
        or a
        rra
;a=x/8 + 0x40
;l=y/2
        ld h,tytoscr/256
        add a,(hl)
        inc h
        ld h,(hl)
        ld l,a ;hl=scr
        ;scf
        ;rr h ;hl=attr
         ld a,h
         rrca
         rrca
         rrca ;0x40 -> 0x08; 0x48 -> 0x09
         add a,0x50
         ld h,a

        ;ld hl,0x5910
        ld b,3;2
        ld c,0xff
        push hl
        call bombcross
;мы сейчас на нижнем бордере, крест пока не виден
        call scrollpixeldown
        if NOIM
        ei
        halt ;увидим крест фаза 1
        di
        else
        halt ;увидим крест фаза 1
        endif
;сейчас мы на верхнем бордере
        pop hl
        ld b,9;5
        ld c,0x3f;0xff
        push hl
        call bombcross
        ;call scrollpixelup ;тут не увидим, что верх экрана сдвинулся!
        pop hl
        if NOIM
        ei
        halt ;увидим крест фаза 2
        di
        else
        halt ;увидим крест фаза 2
        endif
        ld b,9
        ld c,0x07;0x3f
        call bombcross

;не ранить, если убил босса (там несколько взрывов):
         ld a,(ix+OBJ_GFX)
         and 0xfc
         cp ID_BOSS
         jr z,bomb_killmonstersq;bomb_killhero_skip

;ранить героя
        ld a,(objects+(7*OBJSIZE)+OBJ_X)
bomb_killhero_x=$+1
        sub 0 ;левый край зоны поражения
        cp bombradius*2 +1
        jr nc,bomb_killhero_skip
        ld a,(objects+(7*OBJSIZE)+OBJ_Y)
bomb_killhero_y=$+1
        sub 0
        cp bombradius*2 +1
        jr nc,bomb_killhero_skip
;TODO не ранить, если это наскок на монстра?
        ld hl,energy_malus
        ld (hl),10
bomb_killhero_skip
        
;убить монстров
        ld iy,objects
        ld de,OBJSIZE
        if EDITOR
        ld b,6;7
        else
        ld b,7
        endif
bomb_killmonsters0
;если dx, dy = -bombradius..+bombradius, то убиваем
        ld a,(iy+OBJ_GFX)
        cp ID_SOSULKA;ID_DEAD
        jr nc,bomb_killmonsters0_skip
        ld a,(iy+OBJ_X)
bomb_killmonsters0_x=$+1
        sub 0 ;левый край зоны поражения
        cp bombradius*2 +1
        jr nc,bomb_killmonsters0_skip
        ld a,(iy+OBJ_Y)
bomb_killmonsters0_y=$+1
        sub 0
        cp bombradius*2 +1
        jr nc,bomb_killmonsters0_skip
;убиваем врага
        ;ld a,(iy+OBJ_GFX)
        ;srl a
        ;srl a
        ;add a,ID_CALMARDEAD - (ID_CALMAR/4)
        ;ld (iy+OBJ_GFX),a
        ld (iy+OBJ_PROC_ADDR),moveobj_deadbody&0xff
        ld (iy+OBJ_PROC_ADDR+1),moveobj_deadbody/256
        ld (iy+OBJ_DY),-4
        ld (iy+OBJ_DX),-1
         ld a,(iy+OBJ_GFX)
        push de
        call removemonster ;выключить монстра в killedmonsterslist
        pop de
        or (iy+OBJ_NUMBERMASK)
        ld (hl),a ;это в вызывающей процедуре
bomb_killmonsters0_skip
        add iy,de
        djnz bomb_killmonsters0

bomb_killmonstersq
        
        if NOIM
        ei
        halt
        di
        else
        halt
        endif
        call scrollpixelup
        ;halt ;увидим крест фаза 3
restore_sprscript
        ;call setim
        ld hl,sprscript ;pop hl
        ld (prsprscriptaddr),hl

        if NOIM
        ei
        halt ;затрём спрайты
        di
        else
        halt ;затрём спрайты
        endif
        ret
       

clwindow
        ld hl,tilemap
         xor a
        ld (hl),a
        inc l
        jr nz,$-2
         call clearattr
        call prtilemap
        ld a,0x47
        ;jp clearattr
clearattr
;a=attr
        ld hl,0x5802
        ld de,0x5802+1
        ld b,0
        ld hy,16
bombclearattr0
        ld c,27
        ld (hl),a
        ldir
        ld c,5
        add hl,bc
        ex de,hl
        add hl,bc
        ex de,hl
        dec hy
        jp nz,bombclearattr0
        ret

bombcross
;c=attr
;hl=addr
;b=sz
        push bc
        push hl
        call bombcross_ver
        pop hl
        pop bc
        ;call bombcross_hor
        ;ret
bombcross_hor
;с=attr
;hl=addr
;b=sz
        push bc
        push hl
        ld a,l
        and 0xe0
        or 32-3
bombcross_hor0
        ld (hl),c
         cp l
         jr z,bombcross_hor0q
        inc l
        djnz bombcross_hor0
bombcross_hor0q
        pop hl
        pop bc
        sub 28-1
bombcross_hor1
        ld (hl),c
         cp l
         ret z
        dec l
        djnz bombcross_hor1
        ret
bombcross_ver
;c=attr
;hl=addr
;b=sz
        push bc
        ld de,32
        push hl
bombcross_ver0
        ld (hl),c
        add hl,de
         bit 1,h
         jr nz,bombcross_ver0q
        djnz bombcross_ver0
bombcross_ver0q
        pop hl
        pop bc
        ld de,-32
bombcross_ver1
        ld (hl),c
        add hl,de
         bit 1,h
         ret nz
        djnz bombcross_ver1
        ret


;a=x/8 + 0x40
;l=y/2
        macro DOT mask
        ld h,tytoscr/256
        add a,(hl)
        inc h
        ld h,(hl)
        ld l,a
        ld a,(hl)
         ld (de),a
         inc e
         or mask
        ld (hl),a
        ;xor mask ;иначе можно попортить цвет фона, если в нём только один пиксель
        ;inc h
        ;or (hl)
        ;ret nz ;no attr
        ;rrc h ;attr
        ;ld (hl),c ;color
         inc h
         ld a,(hl)
         ld (de),a
         dec e;inc e
          or mask
         ld (hl),a
        ret
        endm
        
        macro REDOT mask
        ld h,tytoscr/256
        add a,(hl)
        inc h
        ld h,(hl)
        ld l,a
;стирание будет res ..,(hl):ret - а как быть, если пролетело через препятствие или хотя бы лестницу???
;или по xor (с возможностью пролетания через препятствия, но тогда восстановилка спрайта из тайловой карты затрёт партикл и его нельзя будет восстановить тут!)
        ;ld a,(hl)
        ;xor mask
         ld a,(de)
         inc e
        ld (hl),a
         inc h
         ;ld a,(hl)
         ;xor mask
         ld a,(de)
         ;inc e
         ld (hl),a
        ret
        endm
;в идеале ~144 t рисование, 96 t стирание
        
dot
;c=color
;a=x
;l=y/2
        scf
        rra
        jr c,dot_x1_3
        rra ;srl a
        jr c,dot_x2
;dot_x0
        DOT 0xc0
dot_x2
        DOT 0x0c
dot_x1_3
        srl a
        jr c,dot_x3
;dot_x1
        DOT 0x30
dot_x3
        DOT 0x03

redot
;a=x
;l=y/2
        scf
        rra
        jr c,redot_x1_3
        rra ;srl a
        jr c,redot_x2
;redot_x0
        REDOT 0xc0
redot_x2
        REDOT 0x0c
redot_x1_3
        srl a
        jr c,redot_x3
;redot_x1
        REDOT 0x30
redot_x3
        REDOT 0x03

;как двигать эти точки с учётом гравитации (TODO учёт препятствия внизу? вверх можно пролетать?):
;у каждой точки есть x,y,xspeed (можно не хранить xspeed, а просто группировать точки), yspeed, color (можно тоже не хранить, а группировать точки)
;можно двигать сразу при отрисовке, а при стирании читать эти же данные заново (надо гарантию, что не произойдёт прерывание)
move_drawdots
;a=ndots !=0
        ld b,a
        ld de,tdots ;+5
move_drawdots0
        ex de,hl
        ld a,(hl) ;yspeed
        inc (hl) ;yspeed++
        inc l
        add a,(hl) ;y
        ld (hl),a
        ld e,a ;y
        inc hl ;keep p
         jp p,move_drawdots_nokilldoty
         xor a
         ld (hl),a ;dx=0
         inc l
         ld (hl),a ;invisible x
         dec l
move_drawdots_nokilldoty
        ;ld a,b ;xspeed
         ld a,(hl)
         inc l
        add a,(hl) ;x
         jp p,move_drawdots_nokilldot
         xor a
         dec l
         ld (hl),a ;dx=0
         inc l
         ld (hl),a ;invisible x
move_drawdots_nokilldot
        ld (hl),a
        inc l
        ex de,hl
         srl l
;l=y/2
;a=x
        or a ;invisible x
        call nz,dot ;рисование
         inc e
         inc e
;90+144 t + ...
        djnz move_drawdots0
        ret

;...

redots
;стираем в обратном порядке! иначе запомненное не восстановить
;a=ndots !=0
        ld b,a
         sub 2;dec a
         ld (ndots),a
        ld d,tdots/256
redots0
         ld a,b
         add a,a
         add a,b
         add a,a
         ;sub 5
         ld e,a
        ;inc e
        ld a,(de) ;y
         srl a
        ld l,a
        inc e
         inc e
        ld a,(de) ;x
        inc e
;l=y
;a=x
        or a ;invisible x
        call nz,redot ;стирание
;47+96 t
        djnz redots0
        ret

;итого >377 t/dot

        display "$ before dots align =",$
        align 256 ;главное чтобы не пересекало границу сегмента
        ds 5 ;0xXX05
tdots
;yspeed, y, xspeed, x
        ds MAXDOTS*6;256
        
