Login

Subversion Repositories NedoOS

Rev

Blame | Last modification | View Log | Download | RSS feed

;интеллект воинов компьютера и играющего (28.05.97)

;BUF512 array[64], где [i = X/8+Y%8], array[i]={ссылка на первого врага
;       в квадранте|#00,если квадрант пуст}
;+256   список врагов (номер врага)(ссылка на следующего|#00}

;----------2D-сортировка наших (обычная)

QH1SRT  LD DE,HBUILD ;сортировка наших зданий
        LD BC,#2088
        LD A,7
        LD (qad__+1),A
        CALL QAD_
        LD A,15
        LD (qad__+1),A
        RET

Q1SORT  LD DE,HUMAN ;сортировка наших воинов --""--
        LD BC,#3000
QAD_    LD HL,BUF512+64
        XOR A
qadC    DEC L ;очистка
        LD (HL),A
        JR NZ,qadC
        PUSH BC
        EXX
        POP BC
        LD HL,BUF512+256
qad1    EXX
        LD A,(DE)
        INC E
        OR A
        JR Z,qad0 ;мёртв
        LD L,A
        ;выч адр
        SRA L
        SRA L
        SRA L
        LD A,(DE)
        CP #80
        JR NC,qad0 ;в здании
        AND %00111000
        OR L
        LD L,A
        LD H,BUF512/256
        LD A,(HL)
        OR A
        JR Z,qad5
        LD H,BUF512/256+1
qad6    LD L,A
        LD A,(HL)
        OR A
        JR NZ,qad6
qad5    EXX
        LD (HL),C
        INC L
        LD (HL),0
        LD A,L
        INC L
        EXX
        LD (HL),A
qad0    LD A,E
qad__   ADD A,15
        LD E,A
        JR NC,qad10
        INC D
qad10   EXX
        INC C
        DJNZ qad1
        RET

;--------------- 2D-cортировка врагов с учётом видимости

QH2SRT  LD DE,KBUILD ;сортировка вражих зданий
        LD BC,#20A8
        LD A,7
        LD (qvd__+1),A
        CALL QVD_
        LD A,15
        LD (qvd__+1),A
        RET

Q2SORT  LD DE,KUNGE ;сортировка врагов по квадратам 8х8
        LD BC,#3030
QVD_    LD HL,BUF512+64
        XOR A
qvdC    DEC L ;очистка
        LD (HL),A
        JR NZ,qvdC
        PUSH BC
        EXX
        POP BC
        LD HL,BUF512+256
qvd1    EXX
        LD A,(DE)
        INC E
        OR A
        JR Z,qvd0 ;мёртв
        LD L,A
        LD A,(DE)
        CP #80
        JR NC,qvd0 ;в здании
        LD H,A
        PUSH HL
        CALL GMAP ;пров видим
        LD A,(HL)
        POP HL
        RLA
        JR C,qvd0
        ;выч адр
        SRA L
        SRA L
        SRA L
        LD A,H
        AND %00111000
        OR L
        LD L,A
        LD H,BUF512/256
        LD A,(HL)
        OR A
        JR Z,qvd5
        LD H,BUF512/256+1
qvd6    LD L,A
        LD A,(HL)
        OR A
        JR NZ,qvd6
qvd5    EXX
        LD (HL),C
        INC L
        LD (HL),0
        LD A,L
        INC L
        EXX
        LD (HL),A
qvd0    LD A,E
qvd__   ADD A,15
        LD E,A
        JR NC,qvd10
        INC D
qvd10   EXX
        INC C
        DJNZ qvd1
        RET

QNUM    LD L,(IX+0) ;найти номер квадрата
        SRA L
        SRA L
        SRA L
        LD A,(IX+1)
        AND %00111000
        OR L
        LD L,A
        LD H,BUF512/256
        RET

;--------- СКАНИРОВАНИЕ ---------------------------

;номера П/П сканирования QSC_N
;12223
;40005
;40005
;67778

SCAN    LD A,(TIC)
        RRCA
;       JP NC,kSCAN

;--------- СКАНИРОВАНИЕ ДЛЯ ЛЮДЕЙ ------------

hSCAN   ;*** наши сканируют врага ***
        CALL Q2SORT ;сканирование воинов
        LD HL,QSCt2
        LD (QSC+1),HL
        CALL loop_H
hww0    LD A,(IX+0)
        OR A
        JR Z,hww1
        LD A,(IX+9)
        CP 28
        JR Z,hww3
        CP 2
        JR NC,hww1
hww3    LD E,#FF ;E=мин дист
        CALL hwwSCA ;cканировать, если тек действия 0 или 1 или 28
        LD A,E
        CP #FF
        JR NC,hww1a ;в поле зрения не было никого
        ;иначе атаковать цель D
        LD A,(IX+9)
        DEC A
        LD A,4 ;норм.атака
        JR NZ,hww4
        LD A,26 ;атака не сходя с места
hww4    LD (IX+9),A
        LD (IX+12),D
        CALL HL_IX0
        CALL IXt_HL
hww1a   LD DE,16
hww1    ADD IX,DE
        DJNZ hww0
        ;;
hwwH    LD A,(TIC) ;50%
        RRCA
        RET C
        CALL QH2SRT;сканирование зданий
        LD HL,QSCt2H
        LD (QSC+1),HL
        CALL loop_H
hww50   LD A,(IX+0)
        OR A
        JR Z,hww51
        LD A,(IX+9)
        CP 2
        JR NC,hww51
        LD E,#FF ;E=мин дист
        CALL hwwSCA ;cканировать, если текущ действия 0 или 1
        LD A,E
        CP #FF
        JR NC,hww51a ;в поле зрения не было никого
        ;иначе атаковать цель D
        LD A,(IX+9)
        OR A
        LD A,28 ;норм.атака (м.быть прервана)
        JR Z,hww54
        LD A,26 ;атака не сходя с места
hww54   LD (IX+9),A
        LD (IX+12),D
        CALL HL_IX0
        CALL IXt_HL
hww51a  LD DE,16
hww51   ADD IX,DE
        DJNZ hww50
        RET

;------------ СКАНИРОВАНИЕ ДЛЯ ВРАГА --------

kSCAN   ;*** сканируet враг ***
        CALL Q1SORT ;сканирование воинов
        CALL loop_K
kww0    LD A,(IX+0)
        OR A
        JR Z,kww1
        LD A,(IX+9) ;сканировать для 0,3,28
        OR A
        JR Z,kww3c
        CP 3
        JR Z,kww3a
        CP 28
        JR NZ,kww1
kww3a   LD HL,QSCt1m ;п/п для атакующих
        LD A,(IX+13)
        CP 6
        JR C,kww3
        CALL kwwMAG
        JR kww1a
kww3c   LD A,(IX+4) ;катапульты - всегда максимальн скан
        CP 7
        JR Z,kww3a
        CP 16
        JR Z,kww3a
        LD HL,QSCt1 ;п/п для охраны
kww3    LD (QSC+1),HL
        LD E,#FF ;E=мин дист
        CALL hwwSCA
        LD A,E
        CP #FF
        JR NC,kww1a ;в поле зрения не было никого
        ;иначе атаковать цель D
        CALL HELPme ;норм.атака + помощь
kww1a   LD DE,16
kww1    ADD IX,DE
        DJNZ kww0
        ;;
kwwH    LD A,(TIC) ;50%
        RRCA
        RET NC
        CALL QH1SRT;сканирование зданий
        LD HL,QSCt1H
        LD (QSC+1),HL
          CALL loop_K
kww50   LD A,(IX+0)
        OR A
        JR Z,kww51
        LD A,(IX+9)
        OR A
        JR NZ,kww51
        LD A,(IX+13)
        CP 6
        JR NC,kww51 ;волшебники/крестьяне не атакуют
        LD E,#FF ;E=мин дист
        CALL hwwSCA ;cканировать, если текущ действия 0
        LD A,E
        CP #FF
        JR NC,kww51a ;в поле зрения не было никого
        ;иначе атаковать цель D
        LD (IX+9),28 ;норм.атака (м.быть прервана)
        LD (IX+12),D
        CALL HL_IX0
        CALL IXt_HL
kww51a  LD DE,16
kww51   ADD IX,DE
        DJNZ kww50
        RET

kwwMAG  CP 10 ;IX+13
        RET C ;крестьяне не сканируют
        LD HL,QSCt1W ;п/п для волшебников
        LD (QSC+1),HL
        LD E,#FF ;E=мин дист
        CALL hwwSCA
        LD A,E
        CP #FF
        JR Z,kwwM1
        CP 10 ;миним. расст. сближения
        JP NC,IX_98 ;близко - никого
        LD A,R
        LD HL,deMRCH ;ск.отступл - зависит от DIFFIC
        AND (HL)
        JP NZ,IX_98
        LD HL,(pntX)
        CALL IXt_HL
        JP IX_93
kwwM1   LD A,R
        AND %11101 ;компенс глюков 8х8 :-(
        RET NZ
        JP IX_98

HELPme  ;позвать на помощь врагов
        LD A,(DIFFIC)
        ADD A,A
        ADD A,A
        ADD A,6
        LD (HLPrng+1),A
        PUSH BC
        PUSH IX
        CALL HL_IX0 ;коор ц
        LD C,D      ;N ц
        CALL loop_K
hme0    LD A,(IX+0)
        OR A
        JR Z,hme1
         LD A,(IX+13) ;не звать волшебников/крестьян
         CP 6
         JR C,hme7
         LD A,(IX+9)
         CP 4
         JR NC,hme1 ;0..3->0, остальные действуют
         CALL IX_98
         JR hme1
hme7    LD A,(IX+9) ;звать на помощь, если тек действия 0,3,28
        OR A
        JR Z,hme2
        CP 3
        JR Z,hme2
        CP 28
        JR NZ,hme1
hme2    PUSH BC
        CALL DIST2
        CALL HLPrng ;дальность
        JR NC,hme10
        LD (IX+12),C
        LD (IX+9),4 ;немедл нападение
        PUSH HL
        CALL HL_IX0
        CALL IXt_HL
        POP HL
        LD A,(IX+13)
        CP 1
        CALL Z,ZAMENA
         LD A,(levTYP) ;на нач уровнях засада переходит в атаку
         OR A
         JR Z,hme10
         LD (IX+13),3
hme10   POP BC
hme1    ADD IX,DE
        DJNZ hme0
        POP IX
        POP BC
        RET

actRUN  ;атакующим убегать?
        LD A,(levTYP)
        OR A
        RET NZ ;только на обычн уровнях
        LD A,(DIFFIC)
        XOR %110111
        LD L,A
        LD A,R
        AND L
        RET NZ
        JR OUTme

isRUN   ;охране убегать?
        LD A,(TIC)
        AND 63
        CP 48
        RET NC
        ADD A,48
        CALL N_IX
        LD A,(IX+0)
        OR A
        RET Z
        LD A,(IX+13)
        CP 1
        RET NZ
        ;охр
        LD L,(IX+14)
        LD H,(IX+15)
        CALL DIST2
        CP 6
        RET C
        LD A,R
        AND %101110
        RET NZ
        ;
OUTme   ;отступаем!!!
        PUSH IX
        CALL HL_IX0 ;коор ц
        CALL loop_K
ome0    LD A,(IX+0)
        OR A
        JR Z,ome1
        LD A,(IX+4)
        CP 18
        JR NC,ome1 ;магические - не отступают
        PUSH BC
        CALL DIST2
        CP 9 ;радиус оповещения об отступлении
        JR NC,ome10
         LD A,(IX+13)
         CP 6
         JR NC,ome10 ;не звать пеонов/волш
        PUSH HL
        CP 1
        JR NZ,ome3
        ;охр. бегут
        LD L,(IX+14)
        LD H,(IX+15)
        JR ome31
ome3    ;атакующ бегут
        LD (IX+13),2
        LD HL,(pntX)
ome31   CALL IXt_HL
        POP HL
        CALL IX_92
ome10   POP BC
ome1    ADD IX,DE
        DJNZ ome0
        POP IX
        RET

ZAMENA  ;по возможности замени охранника
        PUSH IX
        LD L,(IX+14)
        LD H,(IX+15)
        LD C,(IX+4)
        CALL loop_K
zmn0    LD A,(IX+0)
        OR A
        JR Z,zmn1
        LD A,(IX+4) ;такой же?
        CP C
        JR NZ,zmn1
        LD A,(IX+13) ;из нов отряда?
        CP 2
        JR NZ,zmn1
        LD (IX+14),L
        LD (IX+15),H
        DEC (IX+13) ; -> охр
        POP IX
        LD (IX+13),3 ;охр -> атак
        RET
zmn1    ADD IX,DE
        DJNZ zmn0
        POP IX
        RET

;----сканир: вспом.процедуры ----------------

QSCt1H  ;cкан одного квадрата 8Х8 (поиск наших зданий)
        PUSH HL ;\\ в квадрате враг
        PUSH BC
        INC H ;=BUF512/256
qskh10  LD L,A
        PUSH HL ;\\\
        DEC L
        LD A,(HL) ;=номер врага
        LD C,A
        PUSH IX
        AND #7F
        CALL B_IX
        CALL HL_IX0
        LD A,(IX+2)
        POP IX
        CALL DISTsH
        CP E
        JR NC,qskh20
        CP 7 ;радиус сканирования здания!
        JR NC,qskh20 ;вне досягаемости
qskh11  LD E,A
        LD D,C
qskh20  POP HL  ;///
        LD A,(HL)
        OR A
        JR NZ,qskh10
        POP BC
        POP HL ;//
        RET

QSCt1   ;cкан одного квадрата 8Х8 (поиск наших вражеской охраной)
        PUSH HL ;\\ в квадрате враг
        PUSH BC
        INC H ;=BUF512/256
qsk10   LD L,A
        PUSH HL ;\\\
        DEC L
        LD A,(HL) ;=номер врага
        LD C,A
        PUSH IX
        CALL N_IX
        LD HL,ksSCAN
        CALL gPAR
        LD B,A
        CALL HL_IX0
        POP IX
        PUSH BC
        CALL DIST2
        POP BC
        CP B ; Зона досяг врага (зависит от типа обнаруженного воина)
        JR NC,qsk20 ;вне досягаемости
        CP E
        JR NC,qsk20
        LD E,A
        LD D,C
qsk20   POP HL  ;///
        LD A,(HL)
        OR A
        JR NZ,qsk10
        POP BC
        POP HL ;//
        RET

QSCt1W  ;cкан одного квадрата 8Х8 (поиск волшебниками врага)
        PUSH HL ;\\ в квадрате враг
        PUSH BC
        LD B,11 ;величина зоны+1 сканирования
        JR qsk10w
QSCt1m  ;cкан одного квадрата 8Х8 (поиск наших идущими в атаку)
        PUSH HL ;\\ в квадрате враг
        PUSH BC
        LD B,9  ;величина зоны+1 сканирования
qsk10w  INC H ;=BUF512/256
qsk10m  LD L,A
        PUSH HL ;\\\
        DEC L
        LD A,(HL) ;=номер врага
        LD C,A
        PUSH IX
        CALL N_IX
        CALL HL_IX0
        POP IX
        PUSH BC
        CALL DIST2
        POP BC
        CP B ; Зона досяг врага
        JR NC,qsk20m ;вне досягаемости
        CP E
        JR NC,qsk20m
        LD E,A
        LD D,C
qsk20m  POP HL  ;///
        LD A,(HL)
        OR A
        JR NZ,qsk10m
        POP BC
        POP HL ;//
        RET


QSCt2H  ;cкан одного квадрата 8Х8 (поиск вражих зданий)
        PUSH HL ;\\ в квадрате враг
        PUSH BC
        INC H ;=BUF512/256
qsch10  LD L,A
        PUSH HL ;\\\
        DEC L
        LD A,(HL) ;=номер врага
        LD C,A
        PUSH IX
        AND #7F
        CALL B_IX
        CALL HL_IX0
        LD A,(IX+2)
        POP IX
        CALL DISTsH
        CP E
        JR NC,qsch20
        LD B,A
        LD A,(IX+4)
        LD HL,sSCAN
        CALL BA
        CP 8
        JR NC,qschkt
        CP B
        JR C,qsch20 ;вне досягаемости
qsch11  LD E,B
        LD D,C
qsch20  POP HL  ;///
        LD A,(HL)
        OR A
        JR NZ,qsch10
        POP BC
        POP HL ;//
        RET
        ;
qschkt  ;для катап
        LD A,B
        CP 3
        JR C,qsch20 ;слишком близко
        CP 9
        JR NC,qsch20 ;слишком далеко
        JR qsch11


QSCt2   ;cкан одного квадрата 8Х8 (поиск врагов)
        PUSH HL ;\\ в квадрате враг
        PUSH BC
        INC H ;=BUF512/256
qsc10   LD L,A
        PUSH HL ;\\\
        DEC L
        LD A,(HL) ;=номер врага
        LD C,A
        PUSH IX
        CALL N_IX
        CALL HL_IX0
        LD (en_IX),HL
        POP IX
        CALL DIST2
        CP E
        JR NC,qsc20
        LD B,A
        LD A,(IX+4)
        LD HL,sSCAN
        CALL BA
        CP 8
        JR NC,qcs_kt
        CP B
        JR C,qsc20 ;вне досягаемости
qsc11   LD E,B
        LD D,C
qsc20   POP HL  ;///
        LD A,(HL)
        OR A
        JR NZ,qsc10
        POP BC
        POP HL ;//
        RET
        ;
qcs_kt  ;для катап
        LD A,B
        CP 3
        JR C,qsc20 ;слишком близко
        CP 9
        JR NC,qsc20 ;слишком далеко
        PUSH DE
        CALL qscOWN
        POP DE
        JR Z,qsc20 ;наши рядом
        JR NZ,qsc11


DISTsH  ;DIST2 для здания при сканировании (A-тип здания)
        CP 8
        JR Z,dhh1
        CP 18
        JR Z,dhh1
        ;для обычн зданий
dhh0    CALL DIST2
        DEC A
        RET
dhh1    ;для хибар и изб
        LD A,L
        CP (IX+0)
        JP C,DIST2
        LD A,H
        CP (IX+1)
        JP C,DIST2
        JR dhh0

qscOWN  LD HL,(en_IX) ;есть ли рядом наши (NZ/Z-нет/есть)
humOWN  DEC H ;для катапульты
        DEC L
        CALL GMAP2
        CALL qscOW1
        CALL qscOW1
        CALL qscOW1
        LD DE,61
        ADD HL,DE
        CALL qscOW1
        INC L
        CALL qscOW1
        ADD HL,DE
        CALL qscOW1
        CALL qscOW1
        CALL qscOW1
        INC A ;nz
        RET ;!!

qscOW1  LD A,(HL)
        INC L
        CP #80
        RET C
        CP #B0
        RET NC
        POP HL ;!!
        XOR A
        RET ; z- нельзя стрелять


        macro qsKs
        LD A,(HL)
        CP #B0
        RET NC ;nc-нельзя стрелять
        ENDM

qkkOWN  LD HL,(en_IX) ;есть ли рядом враги (С/NC-нет/есть)
kunOWN  DEC H ;для катапульты
        DEC L
        CALL GMAP2
        qsKs
        INC L
        qsKs
        INC L
        qsKs
        LD DE,62
        ADD HL,DE
        qsKs
        INC L
        INC L
        qsKs
        ADD HL,DE
        qsKs
        INC L
        qsKs
        INC L
        LD A,(HL)
        CP #B0
        RET ;nc/C

;-------скан с соблюд граничн условий

        macro QSCs
        LD A,(HL)
        OR A
        CALL NZ,QSC
        ENDM

QSC_0   LD A,L
        SUB 9
        LD L,A
        QSCs
        INC L
        QSCs
        INC L
        QSCs
        LD A,L
        ADD A,6
        LD L,A
        QSCs
        INC L
        QSCs
        INC L
        QSCs
        LD A,L
        ADD A,6
        LD L,A
        QSCs
        INC L
        QSCs
        INC L
        QSCs
        RET
        ;
hwwSCA  CALL QNUM ;выбор П/П сканирования
        CP 8
        JR C,hwwTOP
        CP 56
        JR NC,hwwBOT
        AND 7
        JR Z,QSC_4
        CP 7
        JR NZ,QSC_0
        JR QSC_5
hwwTOP  OR A
        JP Z,QSC_1
        CP 7
        JR NZ,QSC_2
        JR QSC_3
hwwBOT  JR Z,QSC_6
        CP 63
        JR C,QSC_7
        JR QSC_8
        ;
QSC_5   LD A,L
        SUB 9
        JR QSC_4a
QSC_4   LD A,L
        SUB 8
QSC_4a  LD L,A
        QSCs
        INC L
        QSCs
        LD A,L
        ADD A,7
        LD L,A
        QSCs
        INC L
        QSCs
        LD A,L
        ADD A,7
        LD L,A
        QSCs
        INC L
        QSCs
        RET
        ;
QSC_2   DEC L
        JR QSC_7a
QSC_7   SUB 9
        LD L,A
QSC_7a  QSCs
        INC L
        QSCs
        INC L
        QSCs
        LD A,L
        ADD A,6
        LD L,A
        QSCs
        INC L
        QSCs
        INC L
        QSCs
        RET

QSC_8   SUB 9
        LD L,A
        JR QSC_1
QSC_6   SUB 8
        LD L,A
        JR QSC_1
QSC_3   DEC L
QSC_1   QSCs
        INC L
        QSCs
        LD A,L
        ADD A,7
        LD L,A
        QSCs
        INC L
        QSCs
        RET

;-------------------------------------------------
;--------- ВРАЖЕСКИЙ ИНТЕЛЛЕКТ -------------------
;-------------------------------------------------
kPROF   DEFW AI00,AI01,AI02,AI03,AI04,AI05,AI06,AI07,AI08
        DEFW AI09
        DEFW AI10,AI11, AI12,AI13,AI14, AI15,AI16,AI17

kINTEL  LD A,(IX+13) ;занять работой
        LD HL,kPROF
        CALL WT
        JP (HL)

AI00    ;none
        ;\
AI01    ;охранник возвращается на старт-позицию
        LD L,(IX+14)
        LD H,(IX+15)
        CALL DIST2
        OR A
        RET Z
        ;go home
        CALL IXt_HL
        JP IX_93

AI09    ;
AI04    ;
AI05    ;
AI02    ;произведённый воин - идёт к точке сбора
        RET

AI03    ;воин идёт к цели
        CALL AI03_
        RET Z
        JP ZZ3
        ;
AI03_   LD A,(pntTAR)
        CP #FF
        RET Z ;цель не выбрана
        PUSH IX
        CP #80
        JR NC,ai03a
        CALL N_IX ;цель-человек
        JR ai03b
ai03a   AND #7F
        CALL B_IX ;цель-здание
ai03b   CALL HL_IX0
        LD A,L
        OR A
        POP IX
        RET Z; цель погибла
        CALL IXt_HL
        JP IX_93 ;nz


AI08    ;peмонтник
        RET


AI06    ;рубка леса
        LD A,(IX+4)
        CP 9
        JR C,ai06a
        SUB 9
ai06a   OR A
        JP NZ,basTAR ;с дровами _ вали на базу
        ;ищи лес
        LD B,8 ;-к-во попыток поиска
ai060   CALL R_awa_
        CALL HL_IXt
        CALL GMAP
        LD A,(HL)
        AND #7F
        CP 61
        JR C,ai06b
        CP 63
        JR C,ai06C
ai06b   DJNZ ai060
ai06C   LD (IX+9),6
        RET

AI07    ;поход за золотом
        LD A,(IX+4)
        CP 9
        JR C,ai07a
        SUB 9
ai07a   OR A
        JP NZ,basTAR ;c мешком - вали на базу
        ;ищи шахту поближе
        CALL HL_IX0
        LD C,#FF ;миним расст
        PUSH IX
        LD B,8
        LD DE,8
        LD IX,MINE
ai070   LD A,(IX+0)
        OR A
        JR Z,ai071
        ;расст меньше минимального?
        PUSH BC
        CALL DIST2
        POP BC
        CP C
        JR NC,ai071
        LD C,A
        LD (en_IX),IX
ai071   ADD IX,DE
        DJNZ ai070
        LD A,C
        CP #FF
        JR NZ,ai072
        ;некуда идти
        POP IX
        LD (IX+13),6 ;стань лесорубом
        JP IX_98
ai072   ;идти на ближайшую шахту
        LD IX,(en_IX)
        CALL HL_IX0
        POP IX
        CALL IXt_HL
        LD (IX+9),7
        LD (IX+8),#80
        RET