
separate (gameutils)



-- adjusts Ypos, Barrels, eXit cube:
procedure updategamestate( currenttime : float ) is
	barrelwasmoved, barrelhitko, barrelhitwall : boolean := false;
	dist,
	dfx,dfz, hordist, deltaang,
	deltal, deltaj, nbx,nby,nbz,
	kxl,kxh,kyl,kyh,kzl,kzh : float;
	offset,npass : integer := 0;
	aboveledge, withinledge : boolean := false; --9nov14
	dyp,dxp,dzp: float;
	iwhich: integer;
	closeEnough: constant float := 4.0; --3.0;
	onsomeledge, settling: boolean;

begin

if level>0 then


	nbx:=0.0; nby:=0.0; nbz:=0.0;

	--prep to define vertical pos...

	onsomeledge:=false;
	for i in 1..nko loop
	if (i /= pko ) then

		kyl := yme - (koylo(i)+aheight);
		kyh := (koyhi(i)+aheight) - yme;


		-- 9nov14:  now matches KO definitions elsewhere (margin)
		kxl:=xme-koxlo(i)+margin;
		kxh:=koxhi(i)+margin-xme;
		kzl:=zme-kozlo(i)+margin;
		kzh:=kozhi(i)+margin-zme;

		aboveledge  := (kxl*kxh>=0.0) and (kzl*kzh>=0.0) and (kyh<=0.0); --9nov14
		withinledge := (kxl*kxh>=0.0) and (kzl*kzh>=0.0) and (kyl*kyh>0.0);
		if aboveledge or withinledge then
			onledge(i) := true;
			onSomeLedge:=true;
			if( yme<koyhi(i)+aheight ) then yme:=koyhi(i)+aheight; end if; --9nov14
		else
			if onledge(i) then --just stepped off of ledge
				onledge(i) := false;

				if not jumping then
					pyjump := koyhi(i)+aheight;
					vyjump := 0.0;
					jumptime := currenttime;
					jumping := true;
				end if;

			end if;
		end if;
	end if;
	end loop; -- for i



--------------------------------------------------------------------------

	deltal := currenttime - landingtime; -- give 1 second to settle
	settling := not jumping and deltal>-0.01 and deltal<0.5;

	deltaj := currenttime - jumptime;
	oxme:=xme;
	oyme:=yme;
	ozme:=zme;
	if jumping and not worming then -- camera lags behind somewhat

		yme := ypos(currenttime,pyjump,vyjump,deltaj);


		if abs(oyme-yme)>4.0e-4 then --small eps to respond to jumps
			if thirdperson then updateVert; end if; --27jan18
			updateMVP( float(winwidth), float(winheight) );
		end if;

		testPortals;



	--27jan18
	elsif thirdperson and settling and not worming and not onSomeLedge then 
	-- let camera settle, BUT if on a ledge we need NOT
	-- adjust camera at every seam...

		updateVert;
		updateMVP( float(winwidth), float(winheight) );

	end if;

--------------------------------------------------------------------------






	if lport_stable and rport_stable and portalEnabled then 
		worm_active:=true; 
	end if;



	---------- begin barrel logic -------------------------------

	-- initiate roll when appropriate:
	for i in 1..nbarrels loop
	if not rolling(i) then

		barrl := posbar(i);
		testbarrel( nbx,nby,nbz, barrelwasmoved, barrelhitko, barrelhitwall);

		if barrelwasmoved and anybarrelisat(nbx,nbz) then 
			barrelhitko:=true; 
		end if;

		if barrelhitko or barrelhitwall then
			forwardok := false;
			badhoriang := horiang;
		end if;



		-- barrel i is NOT rolling [see line 117]
		othersrolling:=false;
		for j in 1..nbarrels loop
			--if rolling(j) and (j/=i) then
			if rolling(j) then --updated & simplified 10jun18
				othersrolling:=true; 
			end if;
		end loop;



		if forwardok and barrelwasmoved and not othersrolling then

			if portalEnabled then
				portalEnabled:=false;
				worm_defined:=false;
				worm_active:=false;

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

			end if;

			nubarrl(1):=nbx;
			nubarrl(2):=nby;
			nubarrl(3):=nbz;
			rolling(i):=true;
			timeofroll:=currenttime;
			olbarrl:=barrl;
			incbarrl:=olbarrl;
			if (nubarrl(3)=olbarrl(3)) then
				rolldir := 3 * integer( signum(nubarrl(1)-olbarrl(1)) );
			elsif (nubarrl(1)=olbarrl(1)) then
				rolldir := 1 * integer( signum(nubarrl(3)-olbarrl(3)) );
			end if;
			snd4ada_hpp.playSnd(kick); --kick

		end if;


	end if;
	end loop; --for i



	anyrolling := false;
	for i in 1..nbarrels loop 
		anyrolling:=anyrolling or rolling(i); 
	end loop;

	-- check whether all barrels are on their receptacles:
	if not worming and not portalEnabled and not anyrolling and not xit then

		npass:=0;
		for i in 1..nbarrels loop
			seated(i):=false;
			for j in 1..nbarrels loop
				dist := fmath.sqrt( 
					sqr(posbar(i)(1)-recept(j)(1)) +
					sqr(posbar(i)(3)-recept(j)(3)) );
				if (dist<0.1) then 
					npass:=npass+1; 
					seated(i):=true; -- barrel i is on receptacle
				end if;
			end loop; -- for j
		end loop; -- for i
		if (npass = nbarrels) then
			portalEnabled:=true;
			snd4ada_hpp.playSnd(qport); -- signals empowerment 11nov14
		end if;

	end if;


	---------- end barrel logic -------------------------------

	if lport_stable and rport_stable and portalEnabled and not first_worm_active then

		first_worm_active:=true;

				if level=1 then
					snd4ada_hpp.stopLoop(falls);
				elsif level=2 then
					snd4ada_hpp.stopLoop(dark);
				elsif level=3 then
					snd4ada_hpp.stopLoop(gothic);
				elsif level=4 then
					snd4ada_hpp.stopLoop(neptune);
				end if;


		snd4ada_hpp.playLoop(hum); --Hum;

	end if;


	-- test for exit activation:
	dfx := xboxpos(1) - xme;
	dfz := xboxpos(3) - zme;
	hordist := fmath.sqrt( dfx*dfx + dfz*dfz );

	deltaang := abs(fmath.sin( fmath.arctan(dfx,dfz) - horiang )); -- see exception

	if
		not xit and
		(hordist<closeEnough) and
		(deltaang < fmath.sin(fovrad/3.0)) and
		( not inpool(xme,yme,zme) )
	then --trigger changeover to exit stargate
		xit := true;
		exittime := currenttime;
		snd4ada_hpp.playSnd(stone); --concrete
	end if;



	if atexit then
		pauseatlevelchange:=true;
		solved(level):=true;
	else
		pauseatlevelchange:=false;
	end if;

	lasttime := currenttime;


------- revealing stargate begin [changed from 200 to 2000 parts 9mar18]

			elapsed := currenttime - exittime;
			it := -1000 + integer(elapsed*250.0); -- -1000..+1000 in 8 seconds

			dy := -0.002*float( 1000 - abs(it) ); --  0 .. -2 .. 0
			angl := halfpi*dy;

			if it<0 then --no twist to skull on the way down
				exitwait:=true;
				twictobj.setrect2(xbox, 
					xboxpos(1), xboxpos(2)+dy, xboxpos(3),
					xboxrad(1),xboxrad(2),xboxrad(3), 0.0,
					xm,xp,ym,yp,zm,zp);

			elsif it<=1000  then -- no twist to stargate on the way up
				exitwait:=true;
				twictobj.setrect2(xbox, 
					xboxpos(1), xboxpos(2)+dy, xboxpos(3),
					xboxrad(1),xboxrad(2),xboxrad(3), 0.0,
					xm,xp,ym,yp,zm,zp);

			else -- it>100

				if exitwait then
					snd4ada_hpp.playSnd(kwush);
					snd4ada_hpp.playLoop(kbub);
				end if;
				exitwait:=false;
				twictobj.setrect2(xbox, 
					xboxpos(1), xboxpos(2), xboxpos(3), 
					xboxrad(1),xboxrad(2),xboxrad(3), 0.0,
					xm,xp,ym,yp,zm,zp);

			end if;

			if it<0 then showExitFacade:=true;
			else showExitFacade:=false; end if;

------- revealing tardis end ----------------------------------




------- redefine portals begin ---------------------------------
		if not lport_defined and lport_located and lport_stable then
			xr:=wormradius;  yr:=xr; zr:=xr;
			-- one of these is tiny:
			if    pone=1 then xr:=0.01;
			elsif pone=2 then yr:=0.01;
			elsif pone=3 then zr:=0.01;
			end if;
			-- lift portal texture slightly away from wall:
			dxp:=0.0; dzp:=0.0; dyp:=0.0;
			if    wall1=no then dzp:=-0.02; iwhich:=1;
			elsif wall1=we then dxp:=-0.02; iwhich:=2; -- 5feb17
			elsif wall1=so then dzp:=+0.02; iwhich:=3;
			elsif wall1=ea then dxp:=+0.02; iwhich:=4;
			elsif wall1=up then dyp:=-0.02; iwhich:=5;
			elsif wall1=dn then dyp:=+0.02; iwhich:=6;
			end if;
			pict1obj.setrect(lportal,xtgt1+dxp,ytgt1+dyp,ztgt1+dzp,xr,yr,zr,iwhich);
			lport_defined:=true;
		end if;

		if not rport_defined and rport_located and rport_stable then
			xr:=wormradius;  yr:=xr; zr:=xr;
			-- one of these is tiny:
			if    ptwo=1 then xr:=0.01;
			elsif ptwo=2 then yr:=0.01;
			elsif ptwo=3 then zr:=0.01;
			end if;
			-- lift portal texture slightly away from wall:
			dxp:=0.0; dzp:=0.0; dyp:=0.0;
			if    wall2=no then dzp:=-0.02; iwhich:=1;
			elsif wall2=we then dxp:=-0.02; iwhich:=2; -- 5feb17
			elsif wall2=so then dzp:=+0.02; iwhich:=3;
			elsif wall2=ea then dxp:=+0.02; iwhich:=4;
			elsif wall2=up then dyp:=-0.02; iwhich:=5;
			elsif wall2=dn then dyp:=+0.02; iwhich:=6;
			end if;
			pict1obj.setrect(rportal,xtgt2+dxp,ytgt2+dyp,ztgt2+dzp,xr,yr,zr,iwhich);
			rport_defined:=true;
		end if;
------- redefine portals end -----------------------------------


	if portalEnabled then
		showCross:=true; --22jan18

		--18dec18 addendum (disable gun near exit)
		if level=1 and zme<=-16.0 then showCross:=false;
		elsif level=2 and zme>=+16.0 then showCross:=false;
		elsif level=3 and zme>=+16.0 then showCross:=false;
		elsif level=4 and xme<=-3.0 then showCross:=false; end if;

	end if;




end if; -- level>0


exception -- added 8jan18

	when ada.numerics.argument_error =>
		new_line;
		put_line("updategamestate:  arctan(234)");
		new_line;
		raise;

end updategamestate;





