
separate (gameutils)

procedure shootright( mbtntime: gldouble ) is

	me21,me12,
	tg1,tg2,olook,ome,d12,d21,nulook12,nulook21: vec4;

	iwhich: integer := 0;
	xaim,yaim,zaim,
	x00,y00,z00, x9,z9,
	dt,x0,y0,z0, x1,y1,z1, tt, fi : float := 0.0;
	xme2,yme2,zme2,xlook2,ylook2,zlook2: float;
	tryx,tryy,tryz, xvertang, dxz,
	xcross,ycross,zcross,xhoriang: float;
	xmaxa: constant float := xmax-0.0;
	ymaxa: constant float := ymax-0.0;
	zmaxa: constant float := zmax-0.0;

	ko_Ok, hitCeil, hitFloor, floorOk,ceilingOk, xOk,yOk,zOk : boolean;

	poolOk, sokOk: boolean := false;
	sxlo,sxhi,szlo,szhi: float;

begin

dt:=float(mbtntime-portalbtn2time);
if dt>0.9 and showCross then

	-- choriang does NOT describe the direction 
	-- from the camera towards the crosshairs!
	-- That is the job of xhoriang:
	if thirdperson then
		aim(xcross,ycross,zcross); -- 15jan18
		xhoriang:=branchnear(horiang,fmath.arctan(xcross-xcam,zcross-zcam));
		dxz:=fmath.sqrt(sqr(xcross-xcam)+sqr(zcross-zcam));
		xvertang:= fmath.arcsin((ycross-ycam)/dxz);

		x00:=xcam;
		y00:=ycam;
		z00:=zcam;

	else
		xhoriang:=horiang;
		xvertang:=vertang;

		x00:=xme;
		y00:=yme;
		z00:=zme;

	end if;

	-- 13apr18 use this as look direction:
	xaim:=fmath.cos(xvertang)*fmath.sin(xhoriang);
	yaim:=fmath.sin(xvertang);
	zaim:=fmath.cos(xvertang)*fmath.cos(xhoriang);


	portalbtn2time:=mbtntime;

	x0:=x00;
	y0:=y00;
	z0:=z00;
	x1:=x0;
	y1:=y0;
	z1:=z0;

	while (abs(x1)<xmaxa) and (abs(y1)<ymaxa) and (abs(z1)<zmaxa) loop
		tt:=tt+1.0;
		x1 := x0 + tt*xaim; --xlook;
		y1 := y0 + tt*yaim; --cylook;
		z1 := z0 + tt*zaim; --zlook;
	end loop;


	if (abs(x1)>=xmaxa) then --hit X-bound

		p2:=1;
		if (x1>0.0) then
			tt := (xmaxa-x0)/(x1-x0);
			pn(1):=-1.0;
			pn(2):= 0.0; --outward normal
			pn(3):= 0.0;
			wal:=we; -- X+
		else
			tt := (-xmaxa-x0)/(x1-x0);
			pn(1):=+1.0;
			pn(2):= 0.0; --outward normal
			pn(3):= 0.0;
			wal:=ea; -- X-
		end if;

	elsif (abs(y1)>=ymaxa) then --hit Y-bound

		p2:=2;
		if (y1>0.0) then
			tt := (ymaxa-y0)/(y1-y0);
			pn(1):= 0.0;
			pn(2):=-1.0; --outward normal
			pn(3):= 0.0;
			wal:=up;
		else
			tt := (-ymaxa-y0)/(y1-y0);
			pn(1):= 0.0;
			pn(2):=+1.0; --outward normal
			pn(3):= 0.0;
			wal:=dn;
		end if;

	else --hit Z-bound

		p2:=3;
		if (z1>0.0) then
			tt := (zmaxa-z0)/(z1-z0);
			pn(1):= 0.0;
			pn(2):= 0.0; --outward normal
			pn(3):=-1.0;
			wal:=no; -- Z+
		else
			tt := (-zmaxa-z0)/(z1-z0);
			pn(1):= 0.0;
			pn(2):= 0.0; --outward normal
			pn(3):=+1.0;
			wal:=so; -- Z-
		end if;

	end if;



	tryx := x0 + tt*(x1-x0);
	tryy := y0 + tt*(y1-y0);
	tryz := z0 + tt*(z1-z0);


--============================== begin Portal-In-Portal shot ==============
----------- begin insert 13oct16 ------------------------------------------

	if 
		worm_active and 
		distance(xtgt1,ytgt1,ztgt1, tryx,tryy,tryz)<wormradius 
	then
		-- extend gun trajectory into portal1 view


		tg1:=(xtgt1,ytgt1,ztgt1,0.0);
		tg2:=(xtgt2,ytgt2,ztgt2,0.0);

		-- 13apr18
		ome:=(x00,y00,z00,0.0);
		olook:=(xaim,yaim,zaim,0.0);

		--if thirdPerson then
		--	ome:=(xcam,ycam,zcam,0.0);
		--	olook:=(cxlook,cylook,czlook,0.0);
		--else
		--	ome:=(xme,yme,zme,0.0);
		--	olook:=(xlook,cylook,zlook,0.0);
		--end if;

		matXvec(solmat12, ome-tg1, d12);
		me12:=d12+tg2;
		matXvec(solmat12, olook, nulook12);

		xme2:=me12(1);
		yme2:=me12(2);
		zme2:=me12(3);
		xlook2:=nulook12(1);
		ylook2:=nulook12(2);
		zlook2:=nulook12(3);


		-- [virtual] coords within portal1 view (and out-of-bounds):
		x0:=xme2;
		y0:=yme2;
		z0:=zme2;
		x1:=x0;
		y1:=y0;
		z1:=z0;

		tt:=0.0;
		while (abs(x1)>xmaxa) or (abs(y1)>ymaxa) or (abs(z1)>zmaxa) loop
			tt:=tt+1.0;
			x1 := x0 + tt*xlook2;
			y1 := y0 + tt*ylook2;
			z1 := z0 + tt*zlook2;
		end loop;

		--now (x1,y1,z1) is within bounds
		x0:=x1; y0:=y1; z0:=z1; tt:=0.0;
		while (abs(x1)<xmaxa) and (abs(y1)<ymaxa) and (abs(z1)<zmaxa) loop
			tt:=tt+1.0;
			x1 := x0 + tt*xlook2;
			y1 := y0 + tt*ylook2;
			z1 := z0 + tt*zlook2;
		end loop;


		if (abs(x1)>=xmaxa) then --hit X-bound

			p2:=1;
			if (x1>0.0) then
				tt := (xmaxa-x0)/(x1-x0);
				pn(1):=-1.0;
				pn(2):= 0.0; --outward normal
				pn(3):= 0.0;
				wal:=we; -- X+
			else
				tt := (-xmaxa-x0)/(x1-x0);
				pn(1):=+1.0;
				pn(2):= 0.0; --outward normal
				pn(3):= 0.0;
				wal:=ea; -- X-
			end if;

		elsif (abs(y1)>=ymaxa) then --hit Y-bound

			p2:=2;
			if (y1>0.0) then
				tt := (ymaxa-y0)/(y1-y0);
				pn(1):= 0.0;
				pn(2):=-1.0; --outward normal
				pn(3):= 0.0;
				wal:=up;
			else
				tt := (-ymaxa-y0)/(y1-y0);
				pn(1):= 0.0;
				pn(2):=+1.0; --outward normal
				pn(3):= 0.0;
				wal:=dn;
			end if;

		else --hit Z-bound

			p2:=3;
			if (z1>0.0) then
				tt := (zmaxa-z0)/(z1-z0);
				pn(1):= 0.0;
				pn(2):= 0.0; --outward normal
				pn(3):=-1.0;
				wal:=no; -- Z+
			else
				tt := (-zmaxa-z0)/(z1-z0);
				pn(1):= 0.0;
				pn(2):= 0.0; --outward normal
				pn(3):=+1.0;
				wal:=so; -- Z-
			end if;

		end if;


	elsif 
		worm_active and 
		distance(xtgt2,ytgt2,ztgt2, tryx,tryy,tryz)<wormradius 
	then
		-- extend gun trajectory into portal2 view


		tg1:=(xtgt1,ytgt1,ztgt1,0.0);
		tg2:=(xtgt2,ytgt2,ztgt2,0.0);

		-- 13apr18
		ome:=(x00,y00,z00,0.0);
		olook:=(xaim,yaim,zaim,0.0);

		--if thirdPerson then
		--	ome:=(xcam,ycam,zcam,0.0);
		--	olook:=(cxlook,cylook,czlook,0.0);
		--else
		--	ome:=(xme,yme,zme,0.0);
		--	olook:=(xlook,cylook,zlook,0.0);
		--end if;

		matXvec(solmat21, ome-tg2, d21);
		me21:=d21+tg1;
		matXvec(solmat21, olook, nulook21);

		xme2:=me21(1);
		yme2:=me21(2);
		zme2:=me21(3);
		xlook2:=nulook21(1);
		ylook2:=nulook21(2);
		zlook2:=nulook21(3);



		x0:=xme2;
		y0:=yme2;
		z0:=zme2;
		x1:=x0;
		y1:=y0;
		z1:=z0;

		tt:=0.0;
		while (abs(x1)>xmaxa) or (abs(y1)>ymaxa) or (abs(z1)>zmaxa) loop
			tt:=tt+1.0;
			x1 := x0 + tt*xlook2;
			y1 := y0 + tt*ylook2;
			z1 := z0 + tt*zlook2;
		end loop;

		--now (x1,y1,z1) is within bounds
		x0:=x1; y0:=y1; z0:=z1; tt:=0.0;
		while (abs(x1)<xmaxa) and (abs(y1)<ymaxa) and (abs(z1)<zmaxa) loop
			tt:=tt+1.0;
			x1 := x0 + tt*xlook2;
			y1 := y0 + tt*ylook2;
			z1 := z0 + tt*zlook2;
		end loop;


		if (abs(x1)>=xmaxa) then --hit X-bound

			p2:=1;
			if (x1>0.0) then
				tt := (xmaxa-x0)/(x1-x0);
				pn(1):=-1.0;
				pn(2):= 0.0; --outward normal
				pn(3):= 0.0;
				wal:=we; -- X+
			else
				tt := (-xmaxa-x0)/(x1-x0);
				pn(1):=+1.0;
				pn(2):= 0.0; --outward normal
				pn(3):= 0.0;
				wal:=ea; -- X-
			end if;

		elsif (abs(y1)>=ymaxa) then --hit Y-bound

			p2:=2;
			if (y1>0.0) then
				tt := (ymaxa-y0)/(y1-y0);
				pn(1):= 0.0;
				pn(2):=-1.0; --outward normal
				pn(3):= 0.0;
				wal:=up;
			else
				tt := (-ymaxa-y0)/(y1-y0);
				pn(1):= 0.0;
				pn(2):=+1.0; --outward normal
				pn(3):= 0.0;
				wal:=dn;
			end if;

		else --hit Z-bound

			p2:=3;
			if (z1>0.0) then
				tt := (zmaxa-z0)/(z1-z0);
				pn(1):= 0.0;
				pn(2):= 0.0; --outward normal
				pn(3):=-1.0;
				wal:=no; -- Z+
			else
				tt := (-zmaxa-z0)/(z1-z0);
				pn(1):= 0.0;
				pn(2):= 0.0; --outward normal
				pn(3):=+1.0;
				wal:=so; -- Z-
			end if;

		end if;


	end if;


	-- define final target:
	xpre2 := x0 + tt*(x1-x0);
	ypre2 := y0 + tt*(y1-y0);
	zpre2 := z0 + tt*(z1-z0);

	x9:=x0+0.9*tt*(x1-x0);
	z9:=z0+0.9*tt*(z1-z0);


----------- end insert 13oct16 --------------------------------------------







	-- if ptwo=1 => hit X bounds first
	-- if ptwo=2 => hit Y boundary...disallow portal on ceiling or floor
	-- if ptwo=3 => hit Z bounds first

	ko_Ok := ( not intersectsko(x0,y0,z0, xpre2,ypre2,zpre2, iwhich) );

	hitCeil:=((p2=2) and (pn(2)<-0.9)); -- hit ceiling
	hitFloor:=((p2=2) and (pn(2)>0.9)); -- hit floor

	ceilingOk:=
		hitCeil
		and
		((-xmax<xpre2-wormradius) and (xmax>xpre2+wormradius))
		and
		((-zmax<zpre2-wormradius) and (zmax>zpre2+wormradius))
		and
		(level=3) --brick room
		and
		(ko_Ok);


	floorOk:=
		hitFloor
		and
		((-xmax<xpre2-wormradius) and (xmax>xpre2+wormradius))
		and
		((-zmax<zpre2-wormradius) and (zmax>zpre2+wormradius))
		and
		(ko_Ok);



	poolOk:=
		((koxlo(pko)>xpre2) or (koxhi(pko)<xpre2))
		or
		((kozlo(pko)>zpre2) or (kozhi(pko)<zpre2));

	sxhi:=xorigin(level)+1.0;
	szhi:=zorigin(level)+1.0;
	sxlo:=sxhi-8.5*rolldist;
	szlo:=szhi-9.5*rolldist;
	sokOk:=
		((sxlo>xpre2) or (sxhi<xpre2))
		or
		((szlo>zpre2) or (szhi<zpre2));




	xOk:= -- either hits an X-wall or is not too close to it
		((p2=1) or ((-xmax<xpre2-wormradius) and (xmax>xpre2+wormradius)));

	yOk:= -- either hits floor/ceil or is not too close to it
		((p2=2) or ((-ymax<ypre2) and (ymax>ypre2+wormradius)));

	zOk:= -- either hits a Z-wall, or is not too close to it
		((p2=3) or ((-zmax<zpre2-wormradius) and (zmax>zpre2+wormradius)));


	--one final Ztest to disallow portal near fireball:
	if level=3 and abs(zpre2-2.0)<1.0 then zOk:=false; end if;
	--19dec18



	if -- not too close to corners, floor, ceiling...
		(ceilingOk and xOk and zOk and ko_Ok)
		or
		(floorOk and xOk and zOk and ko_Ok and poolOk and sokOk)
		or
	(
		( not hitCeil and not hitFloor )
		and xOk and yOk and zOk and ko_Ok
	)
	then -- we aimed at a valid location

		--finalize global variables:
		wall2:=wal;
		p2n(1):=pn(1);
		p2n(2):=pn(2);
		p2n(3):=pn(3);
		ptwo:=p2;
		rport_stable:=false;


		-- First, adjust Ypos upward, if necessary:

		if not hitFloor then

			--if the last 10% of portal gun trajectory is lowered by 
			--wormradius and intersects a KO, then move tgt higher.
			if 
				intersectsko(x9,ypre2,z9, xpre2,ypre2-wormradius,zpre2, iwhich) 
			then
				if (koyhi(iwhich)>ypre2-wormradius) then
					ypre2:=koyhi(iwhich)+wormradius;
				end if;
			end if;

			if (-ymax+wormradius>ypre2) then 
				ypre2:=-ymax+wormradius;  -- -ymax+1=-3+1=-2
			end if; --adjust up slightly from floor

		end if;


		worm_defined:=false;
		worm_active := false;

		first_worm_active := false;  
		snd4ada_hpp.stopLoop(hum); --Hum; --11nov14

		rport_located := true;
		rport_defined := false;
		rshooting:=true;
		for i in 1..100 loop
			fi:=float(i-1)/99.0;
			xpt(i) := x00 + fi*(xpre2-x00);
			ypt(i) := y00 + fi*(ypre2-y00);
			zpt(i) := z00 + fi*(zpre2-z00);
		end loop;

		snd4ada_hpp.playSnd(laser); -- laser-gun


	end if;

end if;
end shootright;





