Routines |
Prev: C892 | Up: Map | Next: CA11 |
This handles the various different pursuit modes that vischars can be in (pursuing the hero, a dog moving towards food, etc.) and drives character movement.
Used by the routines at spawn_character and automatics.
|
||||||||
Proceed into the character behaviour handling only when this delay field hits zero. This stops characters navigating around obstacles too quickly.
|
||||||||
character_behaviour | C918 | LD A,(IY+$07) | Fetch vischar.counter_and_flags | |||||
C91B | LD B,A | Copy it to B | ||||||
If the counter field is set then decrement it and return.
|
||||||||
C91C | AND $0F | Isolate the counter field in the bottom nibble | ||||||
C91E | JR Z,cb_proceed | Decrement the counter if it's positive | ||||||
C920 | DEC B | |||||||
C921 | LD (IY+$07),B | |||||||
C924 | RET | Return | ||||||
We arrive here when the counter is zero.
|
||||||||
cb_proceed | C925 | PUSH IY | Copy the vischar pointer into HL | |||||
C927 | POP HL | |||||||
C928 | INC L | Advance HL to vischar.flags | ||||||
C929 | LD A,(HL) | Fetch the flags so we can check the mode field | ||||||
C92A | AND A | Are any flag bits set? | ||||||
C92B | JP Z,cb_check_halt | Jump if not | ||||||
Check for mode 1 ("pursue")
|
||||||||
C92E | CP $01 | Is the mode vischar_PURSUIT_PURSUE? | ||||||
C930 | JR NZ,cb_hassle_check | Jump if not | ||||||
Mode 1: Hero is chased by hostiles and sent to solitary if caught.
|
||||||||
cb_pursue_hero | C932 | PUSH HL | Preserve vischar.flags pointer | |||||
C933 | EXX | Bank | ||||||
C934 | POP DE | Restore vischar.flags pointer | ||||||
C935 | INC E | Advance DE to vischar.position | ||||||
C936 | INC E | |||||||
C937 | INC E | |||||||
C938 | LD HL,$81B8 | Point HL at the global map position (the hero's position) | ||||||
C93B | LDI | Copy hero's (x,y) position to vischar.target | ||||||
C93D | LDI | |||||||
C93F | EXX | Unbank | ||||||
C940 | JP cb_move | Jump to 'move' | ||||||
Check for mode 2 ("hassle")
|
||||||||
cb_hassle_check | C943 | CP $02 | Is the mode vischar_PURSUIT_HASSLE? | |||||
C945 | JR NZ,cb_dog_food_check | Jump if not | ||||||
Mode 2: Hero is chased by hostiles if under player control.
|
||||||||
C947 | LD A,($A139) | Is the automatic_player_counter non-zero? | ||||||
C94A | AND A | |||||||
The hero is under player control: pursue.
|
||||||||
C94B | JR NZ,cb_pursue_hero | Jump into mode 1's pursue handler | ||||||
Otherwise the hero is under automatic control: hostiles lose interest and resume their original route.
|
||||||||
C94D | LD (HL),$00 | Clear vischar.flags | ||||||
C94F | INC L | |||||||
C950 | JP get_target_assign_pos | Exit via get_target_assign_pos | ||||||
Check for mode 3 ("dog food")
|
||||||||
cb_dog_food_check | C953 | CP $03 | Is the mode vischar_PURSUIT_DOG_FOOD? | |||||
C955 | JR NZ,cb_saw_bribe_check | Jump if not | ||||||
Mode 3: The food item is near a guard dog.
|
||||||||
C957 | PUSH HL | Preserve vischar.flags pointer | ||||||
C958 | EX DE,HL | (get it in DE) | ||||||
C959 | LD HL,$76FA | Point HL at item_structs[item_FOOD].room | ||||||
C95C | BIT 7,(HL) | Is itemstruct_ROOM_FLAG_NEARBY_7 set? | ||||||
C95E | JR Z,cb_dog_food_not_nearby | Jump if not | ||||||
Set the dog's target to the poisoned food location.
|
||||||||
C960 | INC HL | Advance HL to item_structs[item_FOOD].pos.x | ||||||
C961 | LD A,E | Point DE at vischar.target.x | ||||||
C962 | ADD A,$03 | |||||||
C964 | LD E,A | |||||||
C965 | LDI | Copy (x,y) | ||||||
C967 | LDI | |||||||
C969 | POP HL | Restore vischar.flags pointer | ||||||
C96A | JR cb_move | Jump to 'move' | ||||||
Nearby flag wasn't set.
|
||||||||
cb_dog_food_not_nearby | C96C | XOR A | Clear vischar.flags | |||||
C96D | LD (DE),A | |||||||
C96E | EX DE,HL | (get vischar.flags pointer in HL) | ||||||
C96F | INC L | Set vischar.route.index to routeindex_255_WANDER ($FF) | ||||||
C970 | LD (HL),$FF | |||||||
C972 | INC L | Set vischar.route.step to zero -- wander from 0..7 | ||||||
C973 | LD (HL),$00 | |||||||
C975 | POP HL | Restore vischar.flags pointer | ||||||
C976 | JP get_target_assign_pos | Exit via get_target_assign_pos | ||||||
Check for mode 4 ("saw bribe")
|
||||||||
cb_saw_bribe_check | C979 | CP $04 | Is the mode vischar_PURSUIT_SAW_BRIBE? | |||||
C97B | JR NZ,cb_check_halt | Jump if not | ||||||
Mode 4: Hostile character witnessed a bribe being given (in accept_bribe).
|
||||||||
C97D | PUSH HL | Preserve vischar.flags pointer | ||||||
C97E | LD A,($AF8E) | Get the global bribed character | ||||||
C981 | CP $FF | Is it character_NONE? ($FF) | ||||||
C983 | JR Z,cb_bribe_not_found | Jump if so | ||||||
C985 | LD C,A | Copy the bribed character to C | ||||||
Iterate over non-player characters.
|
||||||||
C986 | LD B,$07 | Set B for seven iterations | ||||||
C988 | LD HL,$8020 | Point HL at the second visible character | ||||||
Start loop
|
||||||||
cb_bribe_loop | C98B | LD A,C | Copy bribed character to A | |||||
C98C | CP (HL) | Is this vischar the bribed character? | ||||||
C98D | JR Z,cb_bribed_visible | Jump if so | ||||||
C98F | LD A,$20 | Step HL to the next vischar | ||||||
C991 | ADD A,L | |||||||
C992 | LD L,A | |||||||
C993 | DJNZ cb_bribe_loop | ...loop | ||||||
cb_bribe_not_found | C995 | POP HL | Restore vischar.flags pointer | |||||
Bribed character was not visible: hostiles lose interest and resume following their original route.
|
||||||||
C996 | LD (HL),$00 | Clear vischar.flags | ||||||
C998 | INC L | |||||||
C999 | JP get_target_assign_pos | Exit via get_target_assign_pos | ||||||
Found the bribed character in vischars: hostiles target him.
|
||||||||
cb_bribed_visible | C99C | LD A,$0F | Advance HL to vischar.mi.pos | |||||
C99E | ADD A,L | |||||||
C99F | LD L,A | |||||||
C9A0 | POP DE | Get the vischar pointer | ||||||
C9A1 | PUSH DE | |||||||
C9A2 | LD A,E | Point DE at vischar.target | ||||||
C9A3 | ADD A,$03 | |||||||
C9A5 | LD E,A | |||||||
C9A6 | LD A,($68A0) | Get the global current room index | ||||||
C9A9 | AND A | Is it zero? | ||||||
C9AA | JP NZ,cb_bribed_indoors | Jump if not | ||||||
Outdoors
|
||||||||
C9AD | CALL pos_to_tinypos | Scale down the bribed character's position to this vischar's target field | ||||||
C9B0 | JR cb_bribed_done | (else) | ||||||
Indoors
|
||||||||
cb_bribed_indoors | C9B2 | LDI | Scale down the bribed character's position to this vischar's target field | |||||
C9B4 | INC L | |||||||
C9B5 | LDI | |||||||
cb_bribed_done | C9B7 | POP HL | Restore the vischar pointer | |||||
C9B8 | JR cb_move | Jump to 'move' | ||||||
cb_check_halt | C9BA | INC L | Advance HL to vischar.route.index | |||||
C9BB | LD A,(HL) | Fetch it | ||||||
C9BC | DEC L | Step back | ||||||
C9BD | AND A | Is it routeindex_0_HALT? ($00) | ||||||
C9BE | JR Z,cb_set_input | Jump if so (set input) | ||||||
cb_move | C9C0 | LD A,(HL) | Get vischar.flags | |||||
C9C1 | EXX | Bank | ||||||
C9C2 | LD C,A | C = flags | ||||||
Select a scaling routine.
|
||||||||
C9C3 | LD A,($68A0) | Get the global current room index | ||||||
C9C6 | AND A | Is it outdoors? (zero) | ||||||
C9C7 | JR Z,cb_scaling_door | Jump if so | ||||||
cb_scaling_indoors | C9C9 | LD HL,$CB75 | Point HL at multiply_by_1 | |||||
C9CC | JR cb_self_modify | (else) | ||||||
cb_scaling_door | C9CE | BIT 6,C | Is vischar.flags vischar_FLAGS_TARGET_IS_DOOR set? | |||||
C9D0 | JR Z,cb_scaling_outdoors | Jump if not | ||||||
C9D2 | LD HL,$B295 | Point HL at multiply_by_4 | ||||||
C9D5 | JR cb_self_modify | (else) | ||||||
cb_scaling_outdoors | C9D7 | LD HL,$B1C7 | Point HL at multiply_by_8 | |||||
Self modify vischar_move_x/y routines.
|
||||||||
cb_self_modify | C9DA | LD ($CA13),HL | Self-modify vischar_move_x | |||||
C9DD | LD ($CA4B),HL | Self-modify vischar_move_y | ||||||
C9E0 | EXX | Unbank | ||||||
If the vischar_BYTE7_Y_DOMINANT flag is set then cb_move_y_dominant is used instead of the code below, which is x dominant. i.e. It means "try moving y then x, rather than x then y". This is the code which makes characters alternate left/right when navigating.
|
||||||||
C9E1 | BIT 5,(IY+$07) | Does the vischar's counter_and_flags field have flag vischar_BYTE7_Y_DOMINANT set? ($20) | ||||||
C9E5 | JR NZ,cb_move_y_dominant | Jump if so | ||||||
cb_move_x_dominant | C9E7 | INC L | Advance HL to vischar.position.x | |||||
C9E8 | INC L | |||||||
C9E9 | INC L | |||||||
C9EA | CALL vischar_move_x | Call vischar_move_x | ||||||
C9ED | JR NZ,cb_set_input | If it couldn't move call vischar_move_y | ||||||
C9EF | CALL vischar_move_y | |||||||
C9F2 | JP Z,target_reached | If it still couldn't move exit via target_reached | ||||||
This entry point is used by the routine at target_reached.
|
||||||||
cb_set_input | C9F5 | CP (IY+$0D) | Is our new input different from the vischar's existing input? | |||||
C9F8 | RET Z | Return if not | ||||||
C9F9 | OR $80 | Otherwise set the input_KICK flag | ||||||
C9FB | LD (IY+$0D),A | |||||||
C9FE | RET | Return | ||||||
cb_move_y_dominant | C9FF | LD A,$04 | Advance HL to vischar.position.y | |||||
CA01 | ADD A,L | |||||||
CA02 | LD L,A | |||||||
CA03 | CALL vischar_move_y | Call vischar_move_y | ||||||
CA06 | JR NZ,cb_set_input | If it couldn't move call vischar_move_x | ||||||
CA08 | CALL vischar_move_x | |||||||
CA0B | JR NZ,cb_set_input | If it could move, jump to cb_set_input | ||||||
CA0D | DEC L | Rewind HL to vischar.position.x | ||||||
CA0E | JP target_reached | Exit via target_reached |
Prev: C892 | Up: Map | Next: CA11 |