	SUBROUTINE HITMILLI(IX,IY)
C Routine called when a bullet hits a millipede segment
C Input is coordinates of millipede segment which was hit
	IMPLICIT REAL*8 (A-Z)
	INCLUDE 'ARRAYS.INC/NOLIST'
	INTEGER*4 IX,IY
	INTEGER*4 PREV_MIL,MIL_PTR,TAIL_PT,PREV_SEG,SE_PTR,I
	INTEGER*4 OLD_HEAD,DELT_X,DELT_Y,PREV_SEG_1
	INTEGER*4 RANDINT
C
C Initialize to traverse the linked list of active millipedes, in
C search of the segment which was hit
C
	PREV_MIL = 0
	MIL_PTR = MI_LISTHEAD
100	CONTINUE
C
C Initialize to traverse the linked list of segments of this millipede
C at the tail end
C
	TAIL_PT = MI_ARY(M_TAILPT,MIL_PTR)
	PREV_SEG_1 = 0
	PREV_SEG = 0
	SE_PTR = TAIL_PT
200	CONTINUE
	IF(SE_ARY(S_XLOC,SE_PTR).EQ.IX) THEN
	  IF(SE_ARY(S_YLOC,SE_PTR).EQ.IY) THEN
C
C This segment is the one that was hit:
C Move the segment off the screen, so it won't be displayed any more
C Put up a barrier where the segment was when hit
C Give player some points for hitting the segment
C
	    SE_ARY(S_YLOC,SE_PTR) = BORDER_MINY
	    BARR_ARY(IX,IY) = RANDINT(RANL_NEWBARR,RANU_NEWBARR)
	    SCREEN_ARY(IX,IY,POINT_NEW) = CHAR_BARR
	    SCORE(POINT_NEW) = SCORE(POINT_NEW) + SCOR_HITSEG
	    IF(SE_ARY(S_FLINK,SE_PTR).EQ.SE_PTR) THEN
C
C A single segment millipede was hit - remove this millipede from the
C linked list of active millipedes
C
	      IF(PREV_MIL.EQ.0) THEN
		MI_LISTHEAD = MI_ARY(M_FLINK,MIL_PTR)
		IF(MI_LISTHEAD.EQ.0) THEN
C
C This was the last millipede - signal to main MILLIPEDE routine
C
		  UNDO_CODE = U_KILLMILLI
		  GOTO 300
		ENDIF
	      ELSE
		MI_ARY(M_FLINK,PREV_MIL) = MI_ARY(M_FLINK,MIL_PTR)
	      ENDIF
	    ELSEIF(PREV_SEG.EQ.0) THEN
C
C A multi segment millipede was hit on the tail - adjust segment links
C
	      SE_ARY(S_FLINK,MI_ARY(M_HEADPT,MIL_PTR)) =
     1			 SE_ARY(S_FLINK,SE_PTR)
	      MI_ARY(M_TAILPT,MIL_PTR) = SE_ARY(S_FLINK,SE_PTR)
	    ELSEIF(SE_PTR.EQ.MI_ARY(M_HEADPT,MIL_PTR)) THEN
C
C A multi segment millipede was hit on the head - adjust segment links
C Give player bonus score for hitting the head
C Change millipede x direction if head (which was hit) was directly
C below the millipede's next segment
C
	      SCORE(POINT_NEW) = SCORE(POINT_NEW) + SCOR_HITHEAD
	      MI_ARY(M_HEADPT,MIL_PTR) = PREV_SEG
	      SE_ARY(S_FLINK,PREV_SEG) = SE_ARY(S_FLINK,SE_PTR)
	      IF(SE_ARY(S_XLOC,SE_PTR).EQ.SE_ARY(S_XLOC,PREV_SEG)) THEN
		MI_ARY(M_XDIR,MIL_PTR) = -MI_ARY(M_XDIR,MIL_PTR)
	      ENDIF
	    ELSE
C
C A multi segment millipede was hit in the middle - split the millipede
C
	      OLD_HEAD = MI_ARY(M_HEADPT,MIL_PTR)
C
C Get an empty slot in the millipede array for the tail half to use
C
	      I = MI_FREEHEAD
 	      MI_FREEHEAD = MI_FREEHEAD + 1
C We need to figure out the X direction for the tail half - look at
C X location of the hit segment and the new head of the new tail half
	      DELT_X = IX - SE_ARY(S_XLOC,PREV_SEG)
	      IF(DELT_X.EQ.0) THEN
C The hit segment was directly below the new head of the new tail half -
C so it's not so simple - try to use new head and next segment to define
C direction - if this fails (see picture below) then give up
C
C Give up if:	****	where it was moving like this >---+
C		  X*	(X is the hit segment)		<-+
C
		DELT_Y = IY - SE_ARY(S_YLOC,PREV_SEG)
		IF(DELT_Y.NE.1) THEN
C Bugcheck if something fishy - rethink this logic if bugcheck ever occurs
		  UNDO_CODE = U_BUGCHECK1
		  GOTO 300
		ELSE
		  IF(PREV_SEG_1.NE.0) THEN
C We can use head and next segment to define direction
		    DELT_X = SE_ARY(S_XLOC,PREV_SEG) -
     1			     SE_ARY(S_XLOC,PREV_SEG_1)
		  ENDIF
		  IF(DELT_X.EQ.0) THEN
C Give up and choose X direction at random - either -1 or +1
		    DELT_X = (2 * RANDINT (0,1)) - 1
		  ENDIF
		ENDIF
	      ENDIF
C MI_ARY( ,I) is the tail half of the split millipede - set it up
	      MI_ARY(M_XDIR,I)   = DELT_X
	      MI_ARY(M_YDIR,I)   = 1
	      MI_ARY(M_HEADPT,I) = PREV_SEG
	      MI_ARY(M_TAILPT,I) = MI_ARY(M_TAILPT,MIL_PTR)
	      MI_ARY(M_FLINK,I)  = MI_LISTHEAD
	      MI_LISTHEAD = I
C MI_ARY( ,MIL_PTR) is the head half of the split millipede - set it up
	      MI_ARY(M_TAILPT,MIL_PTR) = SE_ARY(S_FLINK,SE_PTR)
C Break the segments into two millipedes
	      SE_ARY(S_FLINK,PREV_SEG) = MI_ARY(M_TAILPT,I)
	      SE_ARY(S_FLINK,OLD_HEAD) = MI_ARY(M_TAILPT,MIL_PTR)
	    ENDIF
C Return since the hit segment was found
	    GOTO 300
	  ENDIF
	ENDIF
C Set up to check next segment in this millipede
	PREV_SEG_1 = PREV_SEG
	PREV_SEG = SE_PTR
	SE_PTR = SE_ARY(S_FLINK,SE_PTR)
	IF(SE_PTR.NE.MI_ARY(M_TAILPT,MIL_PTR)) GOTO 200
C Searched all of this millipede - get next one
	PREV_MIL = MIL_PTR
	MIL_PTR = MI_ARY(M_FLINK,MIL_PTR)
	IF(MIL_PTR.NE.0) GOTO 100
C Didn't find the hit segment
	UNDO_CODE = U_BUGCHECK5
300	CONTINUE
	RETURN
	END
