tkeyangle=$-5
 
              ;LRDU
 
       ;DB -1 ;0000
 
       ;DB 128;0001
 
       ;DB 0  ;0010
 
       ;DB -1 ;0011
 
       ;DB 64 ;0100
 
        DB 96 ;0101
 
        DB 32 ;0110
 
        DB 64 ;0111
 
        DB 192;1000
 
        DB 160;1001
 
        DB 224;1010
 
        DB 192;1011
 
        DB -1 ;1100
 
        DB 128;1101
 
        DB 0  ;1110
 
        DB -1 ;1111
 
tkeyangleend
 
 
 
;в 0x4000 включена pgmap
 
CONTROL
 
        LD HL,(IMcurXx+1)
 
        LD a,(IMcurYy+1)
 
        ld h,a
 
        ;корректировать адрес стены в зависимости от направления
 
        ld a,(IMavision+1)
 
        sub 32
 
        cp 64
 
        jr nc,$+3
 
         inc h       
 
        bit 6,a
 
        jr z,$+4
 
         SET mapdifbit,L        
 
        cp -64
 
        jr c,$+3
 
         inc l
 
        ld (touchedwalladdr),hl
 
 
 
        ld a,0xf7
 
        in a,(0xfe)
 
        and 0x1f
 
oldeditkeys=$+1
 
        ld c,0
 
        ld (oldeditkeys),a
 
        cp c
 
        jr z,noedit
 
        ld c,a
 
        bit 0,c
 
        jr nz,noedit1
 
        ld a,(hl)
 
        or a
 
        ld (hl),0xc0
 
        jr z,edit1q
 
         set 6,a
 
        add a,2
 
        cp 0xc0+(2*12)
 
        jr c,$+4
 
        ld a,0xc0
 
         xor (hl)
 
         and 0x3f
 
         xor (hl)
 
        ld (hl),a
 
edit1q
 
noedit1
 
        bit 1,c
 
        jr nz,noedit2
 
        ld a,(hl)
 
        or a
 
        ld (hl),0xc0
 
        jr z,edit2q
 
         set 6,a
 
        sub 2
 
        cp 0xc0
 
        jr nc,$+4
 
        ld a,0xc0+(2*11)
 
         xor (hl)
 
         and 0x3f
 
         xor (hl)
 
        ld (hl),a
 
edit2q
 
noedit2
 
        bit 2,c
 
        jr nz,noedit3
 
        ld a,(hl)
 
        xor 1 ;mirror
 
        ld (hl),a
 
noedit3
 
        bit 3,c
 
        jr nz,noedit4
 
        ld (hl),0
 
noedit4
 
        bit 4,c
 
        jr nz,noedit5
 
        ld a,(hl)
 
        or a
 
        jr z,noedit5
 
        xor 64 ;page
 
        ld (hl),a
 
noedit5
 
noedit
 
 
 
;режимы двери:
 
;0: дверь закрыта
 
;1: дверь открывается, doortimer увеличивается
 
;2: дверь открыта, dooropentimer уменьшается
 
;3: дверь закрывается, doortimer уменьшается
 
doortimer=$+1
 
        ld a,0
 
doortimermode=$+1
 
        ld b,0
 
        djnz control_door_noopening
 
        add a,2
 
        ld (doortimer),a
 
        jr nz,control_doorq
 
        dec a ;-1
 
        ld (doortimer),a ;stay opened
 
        ld a,50 ;a=door open time
 
        ld (dooropentimer),a
 
        ld a,2
 
        ld (doortimermode),a
 
        jr control_doorq
 
control_door_noopening
 
        djnz control_door_noopened
 
dooropentimer=$+1
 
        ld a,0
 
        dec a
 
        ld (dooropentimer),a
 
        jr nz,control_doorq
 
        ;call closecurrentdoor ;keeps hl
 
        ld a,-2
 
        ld (doortimer),a ;stay opened
 
        ld a,3
 
        ld (doortimermode),a
 
        jr control_doorq
 
control_door_noopened
 
        djnz control_door_noclosing
 
;если игрок стоит в дверях, то не закрываем, а открываем
 
        LD HL,(IMcurXx+1)
 
        LD a,(IMcurYy+1)
 
        ld h,a
 
        ld a,ID_DOOR
 
        cp (hl)
 
        jr z,control_door_setopened
 
        inc h
 
        cp (hl)
 
        jr z,control_door_setopened
 
        dec h
 
        set mapdifbit,l
 
        cp (hl)
 
        jr z,control_door_setopened
 
        inc l
 
        cp (hl)
 
        jr z,control_door_setopened
 
        ld a,(doortimer)
 
        sub 2
 
        ld (doortimer),a
 
        jr nz,control_doorq
 
        ;xor a
 
        ld (doortimermode),a
 
        call closecurrentdoor ;keeps hl
 
        jr control_doorq
 
control_door_setopened
 
        ld a,1
 
        ld (doortimermode),a
 
control_door_noclosing
 
control_doorq
 
 
 
       IF kempston
 
        LD C,#FF
 
        IN A,(#1F)
 
        LD B,A
 
        AND #E0
 
        jr NZ,nKEMPSTON
 
        LD A,B
 
        RRA 
 
        jr NC,$+4
 
        RES 1,C
 
        RRA 
 
        jr NC,$+4
 
        RES 0,C
 
        RRA 
 
        jr NC,$+4
 
        RES 3,C
 
        RRA 
 
        jr NC,$+4
 
        RES 2,C
 
        RRA 
 
        jr NC,$+4
 
        RES 6,C
 
nKEMPSTON
 
;C=%1f11durl
 
       ENDIF 
 
       IF autostrafe
 
        BIT 3,C ;down
 
        jr NZ,nAUTOSTRAFE
 
        LD A,C
 
        BIT 1,A
 
        jr NZ,$+6
 
        AND %01101111 ;strafe + rotate flag
 
        OR %00001011 ;block down & rotate
 
        BIT 0,A
 
        jr NZ,$+6
 
        AND %01011111 ;strafe + rotate flag
 
        OR %00001011 ;block down & rotate
 
        LD C,A
 
nAUTOSTRAFE
 
       ENDIF 
 
        LD B,#FF
 
        ld a,#fe
 
        in a,(#fe)
 
        rra
 
        rl b ;cs (open)
 
        LD A,#7F
 
        IN A,(#FE)
 
        RRA 
 
        RL B ;space (fire)
 
        LD A,#FD
 
        IN A,(#FE)
 
        RRA 
 
        RL B ;A
 
        RRA 
 
        RRA 
 
        RL B ;D
 
        RLA 
 
        RL B ;S (down)
 
        LD A,#FB
 
        IN A,(#FE)
 
        RRA 
 
        RRA 
 
        RL B ;W (up)
 
        LD A,#DF
 
        IN A,(#FE)
 
        RRA 
 
        RL B ;P (right)
 
        RRA 
 
        LD A,B
 
        RLA ;O (left)
 
       IF kempston
 
        AND C
 
       ENDIF 
 
 
 
;A=%ofADdurl
 
 
 
       IF demoplay
 
demoplayoff=$
 
        OR A
 
        jr C,demoplayQ
 
       BIT 4,A ;"D"
 
       jr NZ,demoplaynOFF
 
        LD A,#37 ;scf
 
        LD (demoplayoff),A
 
        LD A,#91 ;sub c
 
        LD (mouseon),A
 
        LD A,#FF
 
demoplaynOFF
 
democursor=$+1
 
        LD HL,demobegin
 
demokey=$+1
 
        LD A,%00111111
 
demokeytime=$+1
 
        LD C,1
 
        DEC C
 
        jr NZ,CnNEWKEY
 
        LD A,(HL)
 
        LD (demokey),A
 
        INC HL
 
        LD C,(HL)
 
        INC HL
 
        LD (democursor),HL
 
CnNEWKEY
 
        LD HL,demokeytime
 
        LD (HL),C
 
demoplayQ
 
       ELSE 
 
       IF demorec
 
democursor=$+1
 
        LD HL,demobegin
 
demokeytime=$+1
 
        LD C,0
 
        INC C
 
        jr Z,CNEWKEY
 
        CP (HL)
 
        jr Z,CnNEWKEY
 
CNEWKEY
 
        INC HL
 
        LD (HL),C
 
        LD C,0
 
        INC HL
 
CnNEWKEY
 
        LD (HL),A
 
        LD (democursor),HL
 
        LD HL,demokeytime
 
        LD (HL),C
 
       ENDIF 
 
       ENDIF 
 
 
 
;a=%ofADdurl
 
       PUSH AF
 
        bit 7,a
 
        jr nz,noopendoor
 
        ;call closecurrentdoor ;keeps hl
 
 
 
        ;LD HL,(IMcurXx+1)
 
        ;LD a,(IMcurYy+1)
 
        ;ld h,a
 
touchedwalladdr=$+1
 
        ld hl,0
 
        ld c,ID_DOOR*2
 
        ld a,(hl)
 
        add a,a
 
        cp c
 
        jr nz,noopendoor
 
        bit mapdifbit,l
 
        jr z,opendoor_h
 
opendoor_l
 
        push hl
 
        res 7,(hl)
 
        inc l
 
        ld a,(hl)
 
        add a,a
 
        cp c
 
        jr z,opendoorok
 
        dec l
 
        dec l
 
        ;ld a,(hl)
 
        ;add a,a
 
        ;cp c
 
        jr opendoorok
 
opendoor_h
 
        push hl
 
        res 7,(hl)
 
        inc h
 
        ld a,(hl)
 
        add a,a
 
        cp c
 
        jr z,opendoorok
 
        dec h
 
        dec h
 
        ;ld a,(hl)
 
        ;add a,a
 
        ;cp c
 
opendoorok
 
        res 7,(hl)
 
;ничего не делать, если hl==(oldopendooraddr2)
 
       ld de,(oldopendooraddr2)
 
       or a
 
       sbc hl,de
 
       add hl,de
 
        pop de
 
       jr z,noopendoor
 
        call closecurrentdoor ;keeps hl,de
 
        ld (oldopendooraddr2),hl
 
        ld (oldopendooraddr),de
 
        xor a
 
        ld (doortimer),a
 
        inc a
 
        ld (doortimermode),a
 
        ld a,5 ;open sfx
 
        call sfxplay
 
noopendoor
 
 
 
;сколько фреймов прошло с прошлого fire? считать независимо от fire!
 
        ld a,(firedelaycounter)
 
        dec a
 
        ;jp m,fire_timeok
 
        ;ld (firedelaycounter),a
 
        jp p,firedelaycounter_popnofire
 
;fire_timeok
 
 
 
       pop af
 
;a=%ofADdurl
 
       bit 6,a
 
       jp nz,nofire
 
       push af
 
      
 
        ld a,(bullets)
 
        or a
 
        jp z,popnofire
 
        dec a
 
        ld (bullets),a
 
 
 
        push hl
 
        ld a,1 ;shot sfx
 
        call sfxplay
 
        pop hl
 
 
 
       if sprites
 
       
 
        call RAYPREPXY
 
        LD A,SCRWIDPIX/2;0x40;TODO связано с scrwid/2
 
        ld l,a
 
        LD (cura),A
 
        CALL RAYCAST
 
;C=dist(scale#)
 
;B=texx
 
        ld a,c
 
        ld (fire_walldist),a
 
       if 1==0
 
       call getuser_scr_high_cur
 
       SETPG8000
 
       ld a,(fire_walldist)
 
       ld hl,0x8000
 
       ld bc,40
 
       dup 8
 
       ld (hl),7
 
       rla
 
       rr (hl)
 
       add hl,bc
 
       edup
 
       endif
 
       
 
        call SCANMONS       
 
;в cursprites лежат данные о видимых спрайтах (от задних к передним)
 
;ID 8 (0=end)
 
;dist 16
 
;xscr 8
 
;monster index
 
        ld hl,cursprites
 
fire_scan0
 
        ld a,(hl)
 
        or a
 
        jp z,fire_scan0q
 
        inc l
 
        ld c,(hl)
 
        inc l
 
        ld b,(hl) ;bc=dist
 
        ld d,b
 
        ld e,c
 
        inc l
 
        dup 3;4
 
        srl d
 
        rr e
 
        edup
 
        ld a,d
 
        or a
 
        jr z,$+4
 
         ld e,255
 
        or e
 
        jr nz,$+3
 
         inc e
 
        ld d,t1x/256
 
        ld a,(de) ;width*k (for typical sprite width)
 
        ld e,a
 
        ld a,(hl) ;xscr (центр = 0x40)
 
        sub e
 
        jr nc,$+3
 
         xor a ;a=sprite left margin
 
        cp SCRWIDPIX/2;0x40;TODO связано с scrwid/2
 
        jr nc,fire_miss
 
        ld a,(hl) ;xscr
 
        add a,e
 
        jr nc,$+3
 
         sbc a,a ;a=sprite right margin
 
        cp SCRWIDPIX/2;0x40;TODO связано с scrwid/2
 
        jr c,fire_miss
 
        push hl
 
;не убивать, если стена впереди закрывает монстра (т.е. стена ближе)
 
;bc=dist
 
;приводим к 128..255
 
        LD DE,#000
 
        INC B
 
        DEC B
 
        LD A,C
 
        jr Z,fire_MOTOLOGRLQ
 
       DUP 5;6
 
        INC D
 
        SRL B
 
        RRA 
 
        jr Z,fire_MOTOLOGRLE
 
       EDUP 
 
fire_MOTOLOGRLQ ;
 
fire_MOTOLOGRLE ;
 
        LD C,A ;128..255 ;D=0..5
 
        LD B,tlogd/256
 
        LD A,(BC) ;log(dist) = 128..255 for arg>=128
 
       if atm==0
 
       SUB 16;64                 ;0..127 for arg=64..127 ;???
 
       endif
 
        LD C,A                ;0 for arg<64
 
        LD B,tlogd2sca/256
 
         SRA D
 
         RR E ;DE=+0,+#80,..+#300
 
        ex de,hl
 
        ADD HL,BC
 
        LD a,(HL) ;scale#
 
        pop hl
 
fire_walldist=$+1
 
        cp 0
 
        jr c,fire_miss
 
        push hl
 
        
 
;найти этого монстра в таблице монстров
 
        inc l
 
        ld l,(hl) ;monster index
 
        ld h,0
 
        add hl,hl
 
        add hl,hl
 
        add hl,hl ;*8
 
        ld bc,MONSTRS+5 ;Xx,Yy,TYPEphase_dir,TIMEenergy
 
        add hl,bc ;TYPEphase
 
        ld a,(hl)
 
        cp 4*8
 
        jr nc,fire_skip ;not a monster
 
        and 7
 
        cp 6
 
        jr z,fire_skip ;dead monster
 
        dec l
 
        ld (hl),0 ;dir = no move
 
        inc l
 
        ld (hl),3*8+4 ;wounded, go
 
        inc l
 
        ld a,(hl) ;energy
 
        sub 20
 
        ld (hl),a ;energy
 
        jr c,fire_kill
 
        inc l
 
        ld (hl),TIME_WOUNDED ;time
 
        ld a,2 ;wound sfx
 
        jr fire_killq
 
fire_kill
 
        dec l
 
        ld (hl),3*8+6 ;dead
 
        ;ld a,l
 
        ;and 0xf8
 
        ;ld l,a
 
        ;inc l ;X
 
        ;ld (hl),0xc0 ;impossible X
 
        ld a,0 ;kill sfx
 
fire_killq
 
        call sfxplay
 
fire_skip
 
        pop hl
 
fire_miss
 
       if CURSPRITES_RECSZ == 5
 
       inc l
 
       endif
 
        inc l
 
        jp fire_scan0
 
fire_scan0q
 
 
 
       endif
 
        ld a,10
 
firedelaycounter_popnofire
 
        ld (firedelaycounter),a
 
popnofire
 
       pop af
 
nofire
 
       push af
 
 
 
IMavision=$+1
 
        LD HL,32*256
 
IMdavision=$+1
 
        LD DE,100
 
        AND %10110011
 
        CP 0
 
        LD ($-1),A
 
        jr Z,$+4
 
        LD E,50 ;key just pressed/released
 
       IF kempston&autostrafe
 
        BIT 7,A
 
        jr NZ,nAUTOROTATE
 
        BIT 4,A
 
        jr NZ,$+3
 
        ADD HL,DE
 
        BIT 5,A
 
        jr NZ,$+4
 
        SBC HL,DE
 
nAUTOROTATE
 
       ENDIF 
 
       IF doublerotate
 
        RRA 
 
        jr C,$+4
 
        ADD HL,DE
 
        ADD HL,DE
 
        RRA 
 
        jr C,$+6
 
        SBC HL,DE
 
        SBC HL,DE
 
       ELSE 
 
        RRA 
 
        jr C,$+3
 
        ADD HL,DE
 
        RRA 
 
        jr C,$+4
 
        SBC HL,DE
 
       ENDIF 
 
 
 
        LD A,E
 
        ADD A,12;10
 
        jr C,$+3
 
         LD E,A ;key held: increase rotspd
 
        LD (IMdavision),DE
 
       IF mouse
 
        LD BC,#FBDF
 
        IN A,(C)
 
mouseoldx=$+1
 
        LD C,0
 
        LD ($-1),A
 
mouseon=$
 
       IF demoplay
 
        XOR A
 
       ELSE 
 
        SUB C
 
       ENDIF 
 
        NEG 
 
        LD E,A
 
        RLA 
 
        SBC A,A
 
        LD D,A
 
        ex de,hl 
 
        DUP 6
 
        ADD HL,HL
 
        EDUP 
 
        ADD HL,DE
 
       ENDIF 
 
        LD (IMavision),HL
 
 
 
;делим вектор на коэфф замедления
 
IMcurDX=$+1
 
        LD HL,0
 
        LD B,H
 
        ld A,L
 
        SRA B
 
        RRA 
 
       IF doublespeed
 
        SRA B
 
        RRA 
 
       ENDIF 
 
        LD C,A
 
        CP B
 
       jr NZ,$+3
 
       LD C,L
 
        SBC HL,BC
 
        LD B,H
 
        ld C,L
 
CSLOWXQ
 
IMcurDY=$+1
 
        LD HL,0
 
        LD D,H
 
        ld A,L
 
        SRA D
 
        RRA 
 
       IF doublespeed
 
        SRA D
 
        RRA 
 
       ENDIF 
 
        LD E,A
 
        CP D
 
       jr NZ,$+3
 
       LD E,L
 
        SBC HL,DE
 
        LD D,H
 
        ld E,L
 
CSLOWYQ
 
       POP AF ;%00ADSWPO
 
       RRCA 
 
       RRCA 
 
       AND 15
 
        LD HL,tkeyangle
 
        ADD A,L
 
        LD L,A
 
       IF (tkeyangle^tkeyangleend)&256
 
        ADC A,H
 
        SUB L
 
        LD H,A
 
       ENDIF 
 
        LD A,(HL)
 
;прибавляем вектор направления
 
;sin и cos (IMavision+32*N), где N=0..7 в зав. от клавиш
 
;0=forth
 
;64=left
 
       CP -1
 
       JP Z,CTRLnspeed
 
        LD HL,IMavision+1
 
        ADD A,(HL)
 
        LD L,A
 
        LD H,tcos/256 ;-pi/4..+pi/4
 
        LD A,(HL)
 
       ADD A,C
 
       LD C,A
 
       BIT 7,(HL)
 
       jr NZ,$+3
 
       INC B
 
       jr C,$+3
 
       DEC B
 
        LD A,64
 
        SUB L
 
        LD L,A
 
        LD A,(HL)
 
       ADD A,E
 
       LD E,A
 
       BIT 7,(HL)
 
       jr NZ,$+3
 
       INC D
 
       jr C,$+3
 
       DEC D
 
CTRLnspeed
 
        LD (IMcurDX),BC
 
        LD (IMcurDY),DE
 
       DUP 2
 
        SRA D
 
        RR E
 
        SRA B
 
        RR C
 
       EDUP
 
        ld b,e
 
        LD HL,(IMcurXx)
 
        LD de,(IMcurYy)
 
;hl=x
 
;de=y
 
;c=dx/4
 
;b=dy/4
 
        call moveandcollideX
 
        ex de,hl
 
        call moveandcollideY
 
;hl=y
 
;de=x
 
        LD (IMcurYy),HL
 
        LD (IMcurXx),de
 
 
 
        call collideobjects
 
        call movemonsters
 
        ret
 
 
 
collideobjects
 
;collide with objects
 
;все объекты - в центре своей клетки
 
        LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
 
        ld hx,-1 ;monster index
 
       jp logCOLLIDE0 ;цикл скан-я видимых монстров/предметов
 
logCOLLIDENx
 
        LD A,L
 
        ADD A,8
 
        LD L,A
 
        JR C,logCOLLIDExIH
 
logCOLLIDE0
 
       inc hx ;monster index
 
        LD A,(HL) ;X
 
        INC A
 
       RET Z
 
        ld a,(IMcurXx+1)
 
        cp (hl)
 
        jr nz,logCOLLIDENx
 
        inc l
 
        inc l
 
        ld a,(IMcurYy+1)
 
        cp (hl)
 
        jr z,logCOLLIDEY
 
        LD A,L
 
        ADD A,6
 
        LD L,A
 
        JP NC,logCOLLIDE0
 
logCOLLIDExIH
 
        INC H
 
        JP logCOLLIDE0
 
logCOLLIDEY
 
        inc l
 
        ;ld a,(hl) ;dir
 
        inc l
 
        ld a,(hl) ;TYPE*8+phase
 
        cp 4*8
 
        jr c,logCOLLIDEnobj
 
        push hl
 
        ;ld a,l
 
        ;and 0xf8
 
        ;ld l,a
 
        ;inc l ;X
 
        res 1,l
 
        res 2,l
 
        ld (hl),0xc0 ;impossible X
 
        cp 4*8
 
        jr nz,logCOLLIDEnammo
 
        ld hl,bullets
 
        ld bc,40*256+50 ;ADDmax
 
        call addmax
 
logCOLLIDEnammo
 
        cp 5*8
 
        jr nz,logCOLLIDEnhealth
 
        ld hl,health
 
        ld bc,40*256+100 ;ADDmax
 
        call addmax
 
logCOLLIDEnhealth
 
        
 
        ld a,3 ;get obj
 
        call sfxplay
 
        pop hl
 
logCOLLIDEnobj
 
        inc l
 
        ;ld a,(hl) ;energy
 
        inc l
 
        ;ld a,(hl) ;time
 
        inc hl
 
       INC L ;skip x
 
        jp logCOLLIDE0
 
 
 
movemonsters
 
;move monsters
 
        LD A,(IMcurXx+1);d;(curX)
 
        SUB viewrange
 
        LD (logscmonX),A
 
        LD A,(IMcurYy+1);h;(curY)
 
        SUB viewrange
 
        LD (logscmonY),A
 
        LD HL,MONSTRS+1 ;1+начало табл.монстров/предметов
 
        ld hx,-1 ;monster index
 
       jp logSCMONS0 ;цикл скан-я видимых монстров/предметов
 
logSCMONNx
 
        LD A,L
 
        ADD A,8
 
        LD L,A
 
        JR C,logSCMxIH
 
logSCMONS0
 
       inc hx ;monster index
 
        LD A,(HL) ;X
 
        INC A
 
       RET Z
 
logscmonX=$+1
 
        SUB 0
 
        CP viewrange*2+1
 
        JP NC,logSCMONNx
 
        INC L
 
        inc L
 
        LD A,(HL)
 
logscmonY=$+1
 
        SUB 0
 
        CP viewrange*2+1
 
        JR C,logSCMONY
 
        LD A,L
 
        ADD A,6
 
        LD L,A
 
        JP NC,logSCMONS0
 
logSCMxIH
 
        INC H
 
        JP logSCMONS0
 
logSCMONY
 
        DEC L
 
        dec L
 
        dec L
 
       push hl
 
        LD C,(HL)
 
        INC L
 
        LD B,(HL) ;Xx
 
        INC L
 
        LD E,(HL)
 
        INC L
 
        LD D,(HL) ;Yy
 
        INC L
 
        ld a,(hl) ;dir
 
        or a
 
        jr z,logSCMONS_nomove
 
       push af ;dir
 
        push bc ;x
 
        ld l,a
 
        LD H,tcos/256 ;-pi/4..+pi/4
 
        LD c,(HL)
 
        LD A,64
 
        SUB L
 
        LD L,A
 
        LD b,(HL)
 
        pop hl ;x
 
        dup 3
 
        sra b
 
        sra c
 
        edup
 
;hl=x
 
;de=y
 
;c=dx/4
 
;b=dy/4
 
        call moveandcollideX
 
        ex de,hl
 
        call nc,moveandcollideY
 
;hl=y
 
;de=x
 
       pop bc ;b=dir
 
       ld a,b
 
       jr nc,movemons_nochagedir
 
       ld a,r
 
       add a,a
 
       inc a
 
movemons_nochagedir
 
        ld b,d
 
        ld c,e ;x
 
        ex de,hl ;y
 
logSCMONS_nomove
 
       pop hl
 
        ld (hl),c
 
        inc l
 
        ld (hl),b ;Xx
 
        inc l
 
        ld (hl),e
 
        inc l
 
        ld (hl),d ;Yy
 
        inc l
 
        ld (hl),a ;dir
 
        inc l ;skip dir
 
 
 
      if 1
 
      ld a,0xfe
 
      in a,(0xfe)
 
      rra
 
      jr c,logSCMONS_noattack
 
;если (1..3)*8+(0..1) и близко, то wantattack:
 
        ld a,(hl) ;TYPE*8+phase        
 
        and (30*8)+6
 
        cp 0*8+0 ;стоит спиной
 
        ld e,MONSTERBACKviewrange
 
        jr z,logSCMONS_startattack
 
        cp 2*8+0 ;стоит лицом или идёт
 
        ld e,MONSTERviewrange
 
        jr nz,logSCMONS_noattack
 
logSCMONS_startattack
 
        ld a,(IMcurYy+1)
 
        sub d ;Y
 
        jr nc,$+4
 
        neg
 
        cp e;MONSTERviewrange
 
        jr nc,logSCMONS_noattack
 
        ld a,(IMcurXx+1)
 
        sub b ;X
 
        jr nc,$+4
 
        neg
 
        cp e;MONSTERviewrange
 
        jr nc,logSCMONS_noattack
 
        ld (hl),3*8+2 ;wantattack
 
        inc l
 
        inc l
 
        ld (hl),TIME_WANTATTACK
 
        dec l
 
        dec l
 
        push hl
 
        ld a,4 ;shout
 
        call sfxplay
 
        pop hl
 
logSCMONS_noattack
 
      endif
 
        ld c,(hl) ;TYPE*8+phase
 
        INC L ;skip TYPE*8+phase
 
        inc L ;skip energy
 
        dec (hl) ;time
 
        jr nz,logSCMONS_notime
 
        ld (hl),TIME_STEP ;time
 
        dec l
 
        dec l ;hl points to TYPE*8+phase
 
        ld a,c
 
        and 7
 
        jr z,logSCMONS_step
 
        dec a
 
        jr z,logSCMONS_step
 
        dec a
 
        jr z,logSCMONS_wantattack
 
        dec a ;attack
 
        jr z,logSCMONS_attack
 
        dec a
 
        jr z,logSCMONS_wounded
 
        jr logSCMONS_nosetphase
 
logSCMONS_wantattack
 
        inc l
 
        inc l
 
        ld (hl),TIME_ATTACK
 
        dec l
 
        dec l
 
        dec l
 
        ld (hl),0 ;dir (no move)
 
        inc l
 
        ld a,3*8+3 ;moving attack
 
        jr logSCMONS_setphase
 
logSCMONS_attack
 
;todo shot
 
 
 
;дальше продолжаем движение
 
logSCMONS_wounded
 
        ld a,r
 
        add a,a ;dir
 
        dec l
 
        ld (hl),a ;dir
 
        inc l
 
        ld a,3*8+0 ;moving
 
        jr logSCMONS_setphase
 
logSCMONS_step
 
        ld a,c
 
        xor 1
 
logSCMONS_setphase
 
        ld (hl),a
 
logSCMONS_nosetphase
 
        inc l
 
        inc l
 
logSCMONS_notime
 
        inc hl ;skip TIME
 
       INC L ;skip x
 
        jp logSCMONS0
 
 
 
moveandcollideX
 
;hl=x
 
;de=y
 
;c=dx/4
 
;b=dy/4
 
        ;ADD HL,BC
 
       PUSH HL
 
;|..............|
 
;.....<---*--->..       
 
        ;or a:sbc hl,bc;LD HL,(IMcurXx)
 
         ld a,l
 
         sub mindist ;dx<0
 
         ;dec h
 
        BIT 7,c;B
 
        jr nz,$+6
 
         ld a,l
 
         add a,mindist ;dx>0
 
         inc h
 
        jr nc,CTRLXpass ;проходимо (CY=0)
 
        ;LD A,H
 
        ;LD HL,(IMcurYy)
 
        ;LD L,A
 
        ld l,h
 
        ld h,d ;Y
 
        SET mapdifbit,L
 
        LD A,(HL)
 
        RLA ;проходимо?
 
CTRLXpass
 
       POP HL
 
        jr nc,CTRLnXq ;проходимо (CY=0)
 
CTRLnX
 
;непроходимо
 
        ;LD HL,(IMcurXx)
 
        BIT 7,c;B
 
        LD l,256-mindist ;dx>0
 
        ret z ;C
 
        LD l,mindist ;dx<0
 
        ret ;C
 
CTRLnXq
 
        ;add hl,bc
 
        ld a,c
 
        add a,l
 
        ld l,a
 
        adc a,h
 
        sub l
 
        ld h,a
 
         or a ;NC
 
        bit 7,c
 
        ret z ;NC
 
        dec h
 
        ret ;NC
 
moveandcollideY
 
;hl=y
 
;b=dy/4
 
        ;ADD HL,DE
 
       PUSH HL
 
        ;or a:sbc hl,de;LD HL,(IMcurYy)
 
         ld a,l
 
         sub mindist ;dx<0
 
         ;dec h
 
        BIT 7,b;D
 
        jr nz,$+6
 
         ld a,l
 
         add a,mindist ;dx>0
 
         inc h
 
        jr nc,CTRLYpass ;проходимо (CY=0)
 
        ;LD A,H
 
        ;LD HL,(IMcurXx)
 
        ;LD L,H
 
        ;LD H,A
 
        ld l,d ;X
 
        LD A,(HL)
 
        RLA ;проходимо? 
 
CTRLYpass
 
       POP HL
 
       jr nc,CTRLnYq ;проходимо (CY=0)
 
;непроходимо
 
        ;LD HL,(IMcurYy)
 
        BIT 7,b;d
 
        LD l,256-mindist ;dy>0
 
        ret z ;C
 
        LD l,mindist ;dy<0
 
        ret ;C
 
CTRLnYq
 
        ;add hl,de
 
        ld a,b
 
        add a,l
 
        ld l,a
 
        adc a,h
 
        sub l
 
        ld h,a
 
         or a ;NC
 
        bit 7,b
 
        ret z ;NC
 
        dec h
 
        RET ;NC
 
 
 
closecurrentdoor
 
;keeps hl,de
 
        ld a,128+ID_DOOR;(hl)
 
oldopendooraddr=$+1
 
        ld (killablebyte),a
 
oldopendooraddr2=$+1
 
        ld (killablebyte),a
 
       ld bc,killablebyte
 
       ld (oldopendooraddr),bc
 
       ld (oldopendooraddr2),bc
 
        ret
 
killablebyte
 
        db 0
 
 
 
addmax
 
        ld a,(hl)
 
        cp c;100
 
        ret nc
 
        add a,40
 
        ld (hl),a
 
        cp c;100
 
        ret c
 
        ld (hl),c;100
 
        ret