
%%%===================================================%%%
%%% WASP SOCCER GAME CLIENT 1.1, Dec 5, 2003	      %%%
%%%									%%%
%%% Vrije University Amsterdam				%%%
%%%									%%%
%%% (C) Zhisheng Huang						%%%
%%%===================================================%%%


:-object wsclient: [gg_client, bcilib].


	var url='./soccer6.wrl'.


	var client_name = unknown.
	var client_host = unknown.
	var client_addr = unknown.
      var server_host = unknown.
	var remote_data = 0.
	var time_limit = 5000.
	var server_port = 4321, timeout = 10.

	main :-
		text_area(BrowserTextArea),
		set_output(BrowserTextArea),
		wsclient.


wsclient:- 
		format('Load the game ...~n'),
		loadURL(url),
		format('the game will start in 5 seconds,~n'),
		format('the total playing time is ~w seconds,~n', [time_limit]),
		sleep(5000),
		format('joining the game ...~n'),
		set_field(wsclient, clock, time_limit),
      	new(wsclock_pulse_client,_),
		new(ball_client(ball, time_limit), _),
		new(soccerPlayerClientAgent(goalKeeper1, time_limit), _),
		new(soccerPlayerClientAgent(goalKeeper2, time_limit), _),
		new(soccerPlayerClientAgent(blue8, time_limit), _),
		new(soccerPlayerClientAgent(blue7, time_limit), _),
		new(soccerPlayerClientAgent(red2, time_limit), _),
%		new(soccerPlayerClientAgent(red3, time_limit), _),
%		new(soccerPlayerClientAgent(blue9, time_limit), _),
%		new(soccerPlayerClientAgent(blue11, time_limit), _),
%		new(soccerPlayerClientAgent(red11, time_limit), _),

%		local_host(ClientHost, ClientAddress),
		ClientHost = 'a computer',
%		client_addr := ClientAddress,
		client_addr := 'a computer',
		code_base_host(ServerHost),
		server_host := ServerHost,
		wsclient(ClientHost, ServerHost, server_port),
		true.


        wsclient(ClientHost, ServerHost, ServerPort) :-
		client_host := ClientHost,
		gg_client_loop(ClientHost, ServerHost, ServerPort).


	client_request(Request) :-
		client_name = unknown,
		Request = [register, soccer, From],
		From = from(client_host, client_addr).

	client_request(Request) :-
		set_field(client_name, position(0.0, 0.0, 0.0)),
		set_field(client_name, rotation(0.0, 0.0, 0.0, 0.0)),
		local_processing(Request).

	client_request(Request) :-
		Request = [unregister, soccer, [User]],
		client_ident(User).

	client_chat(Recipient, Text) :-
		get_field(wsclient, name, ClientName),
		TellMessage = [tell, text, [user(client_host, ClientName),[Recipient], Text]],
%%		format('tell message: ~w~n',[TellMessage]),
		set_queue(ClientName, TellMessage).

		

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, position, Data],
		Data = [user(_Host,Name), position(X,Y,Z)],
		client_name \= Name,
		!,
		%% format('~nsetSFVec3f NAME = ~w (~k, ~k, ~k)~n', [Name,X,Y,Z]),
		setSFVec3f(Name, set_position, X,Y,Z).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, text, Message],
		Message = [user(_Host, Name), _RecipientList, Text],
%		client_name \= Name,
		!,
		show_chat_text(Name, Text),
		true.


	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, rotation, Data],
		Data = [user(_Host,Name), rotation(X,Y,Z,R)],
		client_name \= Name,
		!,
		setRotation(Name, X,Y,Z,R).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, position_and_rotation, Data],
		Data = [user(_Host,Name), position(X,Y,Z), rotation(XR,YR,ZR,RR)],
		client_name \= Name,
		!,
		%% format('~nsetSFVec3f NAME = ~w (~k, ~k, ~k)~n', [Name,X,Y,Z]),
		setSFVec3f(Name, set_position, X,Y,Z),
		setRotation(Name, XR,YR,ZR,RR).

	server_reply(ReplyTerm) :-
		ReplyTerm = [reply, update, [Count, Message]],
		!,
		remote_data := Count,
		%% format('~w : broadcast message, ~w~n', [this, Message]),
		print_server_queue_size(client_name, Count),
		server_reply(Message).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, move_player, Data],
		Data = [user(_Host,Player), _X,_Y,_Z, _X1,_Y1,_Z1, _Dist],
		!,
		set_queue(Player, [move_player, Data]),
		sleep(100).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, run_and_trace, Data],
		Data = [user(_ServerHost,Player), _Ball,_X,_Y,_Z,_KickableDistance,_Dist,_Runstep,_RunSleepTime],
		!,
		set_queue(Player, [run_and_trace, Data]),
		sleep(100).

	server_reply(ReplyTerm) :-
		ReplyTerm = none,
		!,
		%% format('~w : server reply, ~w~n', [this, ReplyTerm]),
		true.

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, kick_ball, Data],
		!,
		set_queue(ball, [kick_ball, Data]).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, move_ball, Data],
		!,
		set_queue(ball, [move_ball, Data]).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, ball_position, Data],
		Data = [Ball, position(_X,_Y,_Z)],
		!,
		set_queue(Ball, [ball_position, Data]).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, game_score, Score],
		!,
		set_score_board(Score).

	server_reply(ReplyTerm) :-
		ReplyTerm = [reply, accept, [UserName, BallPosition, 
GameScore,Others]],
		BallPosition = position(XB,YB,ZB),
		!,
		setPosition(ball, XB,YB,ZB),
		set_score_board(GameScore),
		new(soccerPlayerUser_client(me, time_limit, UserName), _),
		enable_others(Others),
%		format('get the user name ~w from the server~n',[UserName]),
		enable_clientname(UserName),
		client_name := UserName.

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, new_player, [UserName]],
		client_name \= UserName,
		!,
		enable_newplayer(UserName).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, unregister, [UserName]],
		client_name \= UserName,
		!,
		disenable_player(UserName).

	server_reply(ReplyTerm) :-
		ReplyTerm = [tell, browser_exit, [UserName]],
		client_name \= UserName,
		!,
		disenable_player(UserName).


	server_reply(ReplyTerm) :-
		%% Server exit, broken pipe:
		ReplyTerm = shutdown,
		!.

	server_reply(ReplyTerm) :-
		ReplyTerm = getChatMessage,
		!.

	server_reply(ReplyTerm) :-
		format('~n~w : SKIPPING UNKNOWN SERVER REPLY : ~w~n', [this, 
ReplyTerm]).


	enable_others([]) :-
		!.

	enable_others([OtherInfo | List]) :-
		OtherInfo = user(_OtherHost,OtherName),
		enable_newplayer(OtherName),		
		enable_others(List).
	
	enable_clientname(UserName):-
		set_field(wsclient, name, UserName),
		Term = setUserName(UserName),
		set_queue(script, queue, Term),
		true.

	enable_newplayer(Name):-
		setSFInt32(Name, whichChoice, 0),
		Term = addPlayerName(Name),
		set_queue(script, queue, Term).

	disenable_player(Name):-
		setSFInt32(Name, whichChoice, -1),
		Term =removePlayerName(Name),
		set_queue(script, queue, Term).



 
	show_chat_text(Name, Text):-
		format('~w: ~w~n', [Name, Text]),
          Term = showChatText(Name, Text),
		set_queue(script, queue, Term),
		true.



	print_server_queue_size(ClientName, NewQueueSize) :-
		get_field(ClientName, old_queue_size, OldQueueSize),
		NewQueueSize \= OldQueueSize,
		!,
		set_field(ClientName, old_queue_size, NewQueueSize),
		format('~w, ~w : message queue length = ~w~n', [this, client_name, 
NewQueueSize]).
	print_server_queue_size(_ClientName, _NewQueueSize).


	var oldpos=position(0.0,0.0,0.0), oldrot=rotation(0.0,1.0,0.0,0.0).

/***
	local_processing(Request) :-
		remote_data > 2,
		Request = [ask, update, [User]],
		client_ident(User).
***/

	local_processing(Request) :-
		Request = [ask, update, [User]],
		client_ident(User).

	local_processing(Request) :-
		queue_length(client_name, Length),
		Length > 0,
		%% format('Local queue processing~n'),
		get_queue(client_name, Message),
		Request = Message.

	local_processing(Request) :-
		%% queue_empty(client_name),
		%% format('Local field processing of ~w~n', [client_name]),
		get_field(client_name, position, Position),
		get_field(client_name, rotation, Rotation),
		%% oldpos \= Position,
		%% oldpos := Position,
		position_resolution(oldpos, Position),
		Request = [tell, position_and_rotation, [User,Position,Rotation]],
		client_ident(User).

	local_processing(Request) :-
		sleep(200),
		local_processing(Request).

	position_resolution(OldPos, NewPos) :-
		OldPos = position(XO,YO,ZO),
		NewPos = position(XN,YN,ZN),
		distance3D(XO,YO,ZO, XN,YN,ZN, Dist),
		Dist > 1.0 ,
%		format('~w *****: position updated : ~w~n', [this, NewPos]),
		oldpos := NewPos .


	client_exit(Message) :-
		%% format('~w : check for unregister answer : ~w~n', [this,Message]),
		Message = [reply, unregister, _],
		!,
		%% format('~w : received unregister answer~n', [this]),
		true.
	client_exit(Message) :-
		Message = shutdown,
		format('~n~w : ~w server shutdown (broken pipe)~n', [this, server_host]).


	client_ident(User) :-
		User = user(client_host, client_name).


	set_score_board(Score) :-
		Score = score(_Team1:_Team2 / Score1:Score2),
		number_chars(Score1, Chars1),
		number_chars(Score2, Chars2),

		%% format('chars1 = ~q~n', [Chars1]),
		%% format('chars2 = ~q~n', [Chars2]),

		%% atom_list_concat(Chars1, Atom1),
		%% atom_list_concat(Chars2, Atom2),	%% or :

		atom_chars(Atom1, Chars1),
		atom_chars(Atom2, Chars2),

		%% format('Atom1 = ~q~n', [Atom1]),
		%% format('Atom2 = ~q~n', [Atom2]),

		atom_list_concat([Atom1, ':', Atom2], TheScore),
		setMFString(scorePlate1, score, [TheScore]),
		setMFString(scorePlate2, score, [TheScore]).


:-end_object wsclient.







:-object ball_client : [common_process_client].	

var steps.
var time_limit = 0.
var ball_name = unknown.
var ballSleepTime = 300.
var stepUnit = 1.5.


ball_client(BallName, TimeLimit) :-
	time_limit := TimeLimit,
	ball_name := BallName,
	format('~w thread active.~n',[BallName]),
	next_activity(BallName).


next_activity(_Name) :-
	repeat,
		get_queue(ball_name, Data),
		ball_activity(Data),
		get_clock(TimeLimit),
%		format('playing time = ~w seconds.~n', [TimeLimit]),
	TimeLimit > time_limit,
	!,
	game_score <- showGameScore.


ball_activity(Mesg) :-
	Mesg = [ball_position, Data],
	Data = [Ball, position(X,Y,Z)],
	!,
%	format('~nBALL_POSITION MESSAGE RECEIVED : ~w~n~n', [position(X,Y,Z)]),
	setPosition(Ball, X, Y, Z).
ball_activity(Mesg) :-
	Mesg = [kick_ball, Data],
	Data = [_Name, BallName, X,Y,Z,R1, KickBallForce, KickBallForceY],
	!,
	%% format('Ball activity = ~w~n', [Mesg]),
	kickedwithStaticStartRF(BallName,translation,X,Y,Z,R1, 
KickBallForce,KickBallForceY).

ball_activity(Mesg) :-
	Mesg = [move_ball, Data],
	Data = [Ball, X,Y,Z, X2,Y2,Z2, Dist],
	!,
	move_to_position(Ball,translation, stepUnit,ballSleepTime, 
X,Y,Z,X2,Y2,Z2,Dist).
	
ball_activity(Data) :-
	format('~nBall ~w activity error : ~w~n', [ball_name, Data]).



%% kickedwithStaticStart(+Ball,+Field,+X,+Y,+Z,+Vx,+Vy,+Vz,+SleepTime).

kickedwithStaticStart(Ball,Field,X,Y,Z,Vx,Vy,Vz,BallSleepTime):-
%%		kickedSound(Ball),
		Time is Vy/4.9,
		BallSleepTimeInSecond is BallSleepTime/1000,
		steps := 1,
		repeat,
			%% format('KICK STEP = ~w~n', [steps]),
%			counter <-incr(kick_ball_step_counter),
			sleep(BallSleepTime),
			CurrentTime is steps*BallSleepTimeInSecond,
			Xnew is X+ Vx*CurrentTime,
			Ynew is Y+ Vy*CurrentTime-4.9*CurrentTime*CurrentTime,
			Znew is Z+ Vz*CurrentTime,
			setSFVec3f(Ball,Field,Xnew,Ynew,Znew),
			++steps,
		steps > Time//BallSleepTimeInSecond,
		!.



kickedwithStaticStart(_,_,_,_,_,_,_,_,_).



%% kickedwithStaticStartRF(Ball,Field,X,Y,Z,R1,ForceXZ,ForceY)

		

kickedwithStaticStartRF(Ball,Field,X,Y,Z,R1,F1,Vy):-
		Vx is F1 * cos(R1),
		Vz is F1 * sin(R1),
		kickedwithStaticStart(Ball,Field,X,Y,Z,Vx,Vy,Vz,ballSleepTime),
		fallToGround(Ball,Field).

%kickedwithStaticStartRF(_,_,_,_,_,_,_,_).		

	

fallToGround(Ball,Field):- 
		getSFVec3f(Ball,Field,X,_Y,Z),
		setSFVec3f(Ball,Field,X,0.25,Z).

:- end_object ball_client.



:-object soccerPlayerClientAgent : [common_process_client].	

var steps.
var time_limit = 0.
var player_name = unknown.
var runSleepTime = 1000.
var runStep = 2.
var xold, zold.


soccerPlayerClientAgent(PlayerName, TimeLimit) :-
	setSFInt32(PlayerName, whichChoice, 0),
	time_limit := TimeLimit,
	player_name := PlayerName,
	format('~w thread active.~n',[PlayerName]),
	setDescription('WASP SOCCER (C)Zhisheng Huang 2000-2004, Vrije University Amsterdam'),
	player_activity(PlayerName, ball).


player_activity(PlayerName, Ball) :-
	repeat,
		get_queue(PlayerName, Data),
		player_activity(Data),
		get_clock(TimeLimit),
		look_at_ball(PlayerName,Ball),
	TimeLimit > time_limit,
	!.


player_activity(Mesg) :-
	Mesg = [move_player, Data],
	Data = [user(_Host,Player), X,Y,Z, X2,Y2,Z2, Dist],
	!,
	move_to_position(Player,set_position, runStep, runSleepTime, 
X,Y,Z,X2,Y2,Z2,Dist).

player_activity(Mesg) :-
	Mesg = [run_and_trace, Data],
	Data = [user(_ServerHost,Player), 
Ball,X,Y,Z,KickableDistance,Dist,Runstep,RunSleepTime],
	!,
	run_and_trace(Player,Ball,X,Y,Z,KickableDistance,Dist,Runstep,RunSleepTime
).
	
player_activity(Data) :-
	format('~nPlayer ~w activity error : ~w~n', [player_name, Data]).


%run_and_trace(+Player,+Ball,+X,+Y,+Z,+kickableDistance,+RunableDist,+runstep,+runSleepTime).

run_and_trace(Player,Ball,X,Y,Z,KickableDistance,Dist,Runstep,RunSleepTime):-
	xold := X,
	zold := Z,
	repeat,
		%% format('RUN_AND_TRACE 1 : ~w~n', [position(xold,zold)]),
%		counter <-incr(run_and_trace_step_counter),
		sleep(RunSleepTime),
		getPosition(Ball,X1,_,Z1),
		look_at_position(Player,X1,Z1),
		getRotation(Player,_,_,_,R),
		R1 is R + 1.5708,
		Xnew is xold-Runstep * cos(R1),
		Znew is zold+Runstep * sin(R1),
		setSFVec3f(Player,set_position, Xnew, Y, Znew),

		%% local_host(Host, _),
		%% Data = [user(Host,Player), position(Xnew,Y,Znew)],
		%% Message = [tell, position, Data],
		%% gg_echo <- broadcast(Host, to_all_clients, Message),
%		format('RUN_AND_TRACE ****** : ~w~n', [position(xold,zold)]),
		xold := Xnew,
		zold := Znew,
		distance2d(Xnew,Znew,X1,Z1,DistBall),
  	end_of_run_and_trace(DistBall, KickableDistance, Dist),
	!.

run_and_trace(_Player,_Ball,_X,_Y,_Z,_KickableDist,_Dist,_Runstep,_RunSleepTime).       


end_of_run_and_trace(BallDist, KickDist, _Dist) :-
        BallDist =< KickDist,
        !.

end_of_run_and_trace(BallDist, _KickDist, Dist) :-
        BallDist > Dist.


:-end_object soccerPlayerClientAgent.




:-object soccerPlayerUser_client : [common_process_client].

var time_limit = 5000.
var client_name = null.
var kickableDistance = 3.0.
var kickBallForce = 10.0.
var kickBallForceY =6.0.


soccerPlayerUser_client(Name, TimeLimit, ClientName) :-
	time_limit := TimeLimit,
	client_name := ClientName,
	format('The user ~w thread is active (name=~w).~n', [Name,ClientName]),
	activity(Name).



activity(Name) :-
	repeat,
		sleep(500),
		get_clock(Time),
		%% format('The player ~w thread ~w seconds ~n', [Name, Time]),

		getViewpointPositionEx(Name, XA,YA,ZA),
		getViewpointOrientationEx(Name, XR,YR,ZR,R1),
		R2 is R1 + 3.1416,
		set_field(client_name, position, position(XA,YA,ZA)),
		set_field(client_name, rotation, rotation(XR,YR,ZR,R2)),
		near_ball_then_kick(Name,ball),
	Time > time_limit,
	!.

var old_ball_pos = unknown.
var old_kick_time = -10.

near_ball_then_kick(Agent, Ball):-
	getViewpointPositionEx(Agent,X,Y,Z),
	%% local_host(Host, _),
	Host = 'a computer',
      TellData = [user(Host,client_name), position(X,Y,Z)],
	TellMessage = [tell, position, TellData],
	getPosition(Ball,X1,Y1,Z1),
	%% X < X1,
	distance2d(X,Z,X1,Z1,Dist),
	%% format('DIST = ~w, KICK DIST = ~w,~n', [Dist,kickableDistance]),
	Dist < kickableDistance,
	ball_time_check(position(X1,Y1,Z1)),
	!,
	getViewpointOrientationEx(Agent,_,_,_,R),
	R1 is sign(X1 - X) * R -1.5708,
	Data = [client_name, Ball, X1,Y1,Z1,R1, kickBallForce, kickBallForceY],
	KickMessage = [tell, kick_ball, Data],
	%% format('KICK MESSAGE = ~w~n', [KickMessage]),
	set_queue(client_name, TellMessage),
	set_queue(client_name, KickMessage).

near_ball_then_kick(_, _).


ball_time_check(_Position) :-
	get_time(NewKickTime),
	NewKickTime > old_kick_time + 3,
	old_kick_time := NewKickTime,
	!.
ball_time_check(Position) :-
	old_ball_pos \= Position,
	old_ball_pos := Position.


:- end_object soccerPlayerUser_client.



:-object game_score_client : [bcilib].

var score1.
var score2.
var team1.
var team2.


setGameScore(Team1, Team2, Score1, Score2):-
		team1:= Team1,
		team2:= Team2,
		score1:= Score1,
		score2:= Score2.


getGameScore(Team1, Team2, Score1, Score2):-
		Team1 := team1,
		Team2 := team2,
		Score1 := score1,
		Score2 := score2.


getTeamScore(Team, Score):-
		Team = team1,
		Score := score1.


getTeamScore(Team, Score):-
		Team = team2,
		Score := score2.


setTeamScore(Team, Score):-
		Team = team1,
		score1:=Score.


setTeamScore(Team, Score):-
		Team = team2,
		score2:=Score.		

showGameScore :-
                getGameScore(Team1, Team2, Score1, Score2),
                format('game score: ~w:~w---~w:~w~n',[Team1,Team2,Score1,Score2]),
                number_chars(Score1,Score1C),
                number_chars(Score2,Score2C),
                atom_chars(Score1A,Score1C),
                atom_chars(Score2A,Score2C),
		atom_list_concat([Score1A, ':', Score2A], TheScore),
                setMFString(scorePlate1,score,[TheScore]),
                setMFString(scorePlate2,score,[TheScore]).

:-end_object game_score_client.





:-object common_process_client : [bcilib].

var steps.


distance2d(X,Z,X1,Z1,Dist):-
	Xdif is X1-X,
	Zdif is Z1-Z,
	Dist is sqrt(Xdif*Xdif + Zdif*Zdif).


distance3d(X,Y,Z,X1,Y1,Z1,Dist):-
	Xdif is X1-X,
	Ydif is Y1-Y,
	Zdif is Z1-Z,
	Dist is sqrt(Xdif*Xdif + Ydif*Ydif + Zdif*Zdif).



distance2dObject(Object1,Field1,Object2,Field2,Dist):-
	getSFVec3f(Object1, Field1, X1, _, Z1),
	getSFVec3f(Object2, Field2, X2, _, Z2),
	distance2d(X1,Z1,X2,Z2,Dist).



distance3dObject(Object1,Field1,Object2,Field2,Dist):-
	getSFVec3f(Object1, Field1, X1, Y1, Z1),
	getSFVec3f(Object2, Field2, X2, Y2, Z2),
	distance3d(X1,Y1,Z1,X2,Y2,Z2,Dist).


distanceBall(Player,Ball, Dist) :-
	distance2dObject(Player,position,Ball,position,Dist).


distancePlayer(Player1,Player2, Dist) :-
	distance2dObject(Player1,position,Player2,position,Dist).



look_at_ball(Player,Ball) :-
	getSFVec3f(Player,position, X,_,Z),
	getPosition(Ball, X1,_,Z1),
	X =\= X1,
	!,	%% RS: added
	Xdif is X-X1,
	Zdif is Z1-Z,
	R is atan(Zdif/Xdif) - sign(X-X1)*1.5708,
	setRotation(Player,0.0, 1.0, 0.0, R).

look_at_ball(_,_).	%% RS: catch ball?



look_at_position(Player,X1,Z1) :-
	getSFVec3f(Player,position, X,_,Z),
	X =\= X1,
	!,	%% RS: added
	Xdif is X-X1,
	Zdif is Z1-Z,
	R is atan(Zdif/Xdif) - sign(X-X1)*1.5708,
	setRotation(Player,0.0, 1.0, 0.0, R).

look_at_position(_,_,_).	



%move_to_position(+Object,+Field,+Steplength,+Sleeptime,+X,+Y,+Z,+X1,+Y1,+Z1,+Dist).

move_to_position(_,_,_,_,X,_,Z,X,_,Z,_) :-
	!.

move_to_position(Object,Field, StepUnit, SleepTime, X,Y,Z,X1,_,Z1,Dist) :-
	Xstep is sign(X-X1)*StepUnit*abs(X-X1)/Dist,
	Zstep is sign(Z-Z1)*StepUnit*abs(Z-Z1)/Dist,
	steps := Dist // StepUnit,
	repeat,
%		counter <-incr(move_position_step_counter),
		sleep(SleepTime),
		Steps is Dist//StepUnit-steps+1,
		Xnew is X - Xstep*Steps,
		Znew is Z - Zstep*Steps,
		setSFVec3f(Object,Field,Xnew,Y,Znew),
		%% format('move_to_position: steps = ~w, pos = ~w~n', [steps, pos(Xnew,Y,Znew)]),
		-- steps,
	steps < 1,
	!.

getViewpointPositionEx(_,X,Y,Z) :- getSFVec3f(proxSensor,position,X,Y,Z).
getViewpointOrientationEx(_,X,Y,Z,R):- 
getSFRotation(proxSensor,orientation,X,Y,Z,R).

	get_clock(Time) :-
		get_field(wsclient, clock, Time).

	set_clock(Time) :-
		set_field(wsclient, clock, Time).

:-end_object common_process_client.



:-object wsclock_pulse_client: [common_process_client].


	wsclock_pulse_client:-
		format('wsclock pulse thread active~n'),
		repeat,
			sleep(5000),
			get_clock(Time),
			Left is Time - 5,
			set_clock(Left),
%%			format('Game Time: ~w seconds left~n',[Left]),
		Left < 1,
		!.

:-end_object wsclock_pulse_client.

