1% look.pl
    2% June 18, 1996
    3% John Eikenberry
    4%
    5% Dec 13, 2035
    6% Douglas Miles
    7%
    8/* * module *
    9% This file defines the basic look action
   10% Agents will use the predicate:
   11% mudGetPrecepts(Agent,Percepts) = list of lists of objects in agents location plus 2 locations in each direction
   12% mudNearReach(Agent,Percepts) = list of lists of objects in agents atloc plus 1 atloc in each dir
   13% mudNearBody(Agent,Percepts) = list of objects in agents location
   14%
   15
   16%
   17% props(Obj,height(ObjHt))  == svo(Obj,height,ObjHt) == p(height,Obj,ObjHt) == height(Obj,ObjHt)
   18% padd(Obj,height(ObjHt))  == ain(p(height,Obj,ObjHt)) == ain(p(height,Obj,ObjHt)) == ain(height(Obj,ObjHt))
   19*/
   20
   21% :-swi_module(user). 
   22:-swi_module(modLook, []).   23
   24:-export((  mudGetPrecepts/2,  mudNearReach/2, mudNearBody/2,  mudCanSense/5 , cmdLook/2)).   25
   26:- include(prologmud(mud_header)).   27
   28% :- register_module_type (mtCommand).
   29
   30:- dynamic blocks/1.   31
   32
   33% mudCanSense(Agent,Sense,InList,CanDetect,CantDetect).
   34mudCanSense(_Agent,visual,InList,InList,[]).
   35
   36
   37baseKB:action_info(actExamine(tItem), "view details of item (see also @ftListFn)").
   38baseKB:agent_call_command(_Gent,actExamine(SObj)):- xlisting(SObj).
   39
   40visibleTo(Agent,Agent).
   41visibleTo(Agent,Obj):-mudPossess(Agent,Obj).
   42visibleTo(Agent,Obj):-same_regions(Agent,Obj).
   43
   44
   45tCol(txtPrepOf).
   46tCol(txtPrepSpatial).
   47impl_coerce_hook(StrIn,txtPrepSpatial,Str):-member(Prep,[in,on,north_of,inside,onto,ontop]),name_text(Prep,StrIn),name_text(Prep,Str).
   48impl_coerce_hook(Prep,txtPrepSpatial,Inst):-impl_coerce_hook(Prep,txtPrepOf,Inst).
   49impl_coerce_hook([SDir,of],txtPrepOf,vDirFn(Dir)):-impl_coerce_hook(SDir,vtDirection,Dir).
   50
   51==> vtVerb(actLook).
   52
   53baseKB:action_info(actLook, "generalized look in region").
   54baseKB:action_info(actLook(isOptionalStr('in'),isOptionalStr('here')), "generalized look in region").
   55baseKB:action_info(actLook(txtPrepOf,isOptionalStr("self")), "Look in a direction (TODO: look north of vHere)").
   56baseKB:action_info(actLook(isOptional(txtPrepSpatial,"at"),tObj),"look [in|at|on|under|at] somewhere").
   57%baseKB:action_info(look(obj), "Look at a speficific item").
   58%baseKB:action_info(look_at(isOptional(call(visibleTo(vHere,value)),call(visibleTo(vHere,value)))), "Look at a speficific item").
   59
   60baseKB:agent_call_command(Agent,actLook):- look_as(Agent),!.
   61baseKB:agent_call_command(Agent,actLook('here')):- look_as(Agent),!.
   62baseKB:agent_call_command(Agent,actLook(_,'here')):- look_as(Agent),!.
   63baseKB:agent_call_command(Agent,actLook(DirS,'self')):- coerce(DirS,vtDirection,Dir),!,
   64   view_dirs(Agent,[[Dir,vHere],[Dir,Dir],[Dir,Dir,vAdjacent]],Percepts),
   65   forall_member(P,Percepts,baseKB:agent_call_command_now(Agent,actExamine(P))).
   66baseKB:agent_call_command(Agent,actLook(_Dir,SObj)):-
   67   objects_match_for_agent(Agent,SObj,tObj,Percepts),
   68   forall_member(P,Percepts,baseKB:agent_call_command_now(Agent,actExamine(P))).
   69
   70:-export(look_as/1).   71look_as(Agent):- mudAtLoc(Agent,LOC),cmdLook(Agent,LOC),!.
   72
   73:-export(cmdLook/2).   74cmdLook(Agent,LOC):-
   75  ignore(current_agent(Agent)),
   76  garbage_collect_atoms, call_u(call(cmdLook_proc,Agent,LOC)),!.
   77
   78ai_look(Buffer):-
   79 BufferH= b([]),
   80 ignore(current_agent(Agent)),
   81 findall(Show,on_command_show(Agent,actLook,Show),MORELOOK),
   82  % implicit in next command clr(props(Agent,mudNeedsLook(_))),
   83   show_kb_preds_to_buffer(Agent,_LOC,MORELOOK,BufferH),
   84    nop(must(show_inventory(Agent,Agent))),!,arg(1,BufferH,Buffer).
   85
   86 
   87
   88:-export(cmdLook_proc/3).   89cmdLook_proc(Agent,LOC):- 
   90   with_no_modifications(locally(mpred_prop(nameString,2,prologListValued),
   91   cmdLook_proc_0(Agent,LOC))),
   92   ain(props(Agent,mudNeedsLook(vFalse))).
   93
   94cmdLook_proc_0(Agent,LOC):-
   95 findall(Show,on_command_show(Agent,actLook,Show),MORELOOK),
   96  % implicit in next command clr(props(Agent,mudNeedsLook(_))),
   97   show_kb_preds(Agent,LOC,MORELOOK),
   98    must(show_inventory(Agent,Agent)),!.
   99
  100:- multifile(on_command_show/3).  101:- dynamic(on_command_show/3).  102on_command_show(Agent,actLook,Show):- 
  103  ignore((once(mudAtLoc(Agent,LOC);localityOfObject(Agent,LOC)))),
  104  ignore((once(locationToRegion(LOC,Region);localityOfObject(Agent,Region);LOC=Region))),
  105   (on_look_show_region(Region,Show);on_look_show_agent_region(Agent,Show)).
  106
  107on_look_show_region(Here,Show):-
  108  member(Show,
  109       [
  110         location= Here,
  111      % TODO make this work
  112         %  why does this this work on Prolog REPL?
  113         %   with_output_to(string(Str),cmdShowRoomGrid('Area1000'))
  114         %  but yet this doent?
  115       %   cmdShowRoomGrid = once(with_output_to(string(value),cmdShowRoomGrid(region))),
  116         % for now workarround is 
  117
  118         call((cmdShowRoomGrid(Here),!)),
  119         nameStringsList(Here,value),
  120         forEach(mudDescription(Here,Value),fmt(mudDescription(Value))),
  121         events=clause_u(mudDeliverableLocationEvents(isSelfAgent,Here,value),true),
  122         path(D) = pathDirLeadsTo(Here,D,value),
  123         pathName(D) = pathName(Here,D,value),
  124         localityOfObject(value,Here)]).
  125
  126on_look_show_agent_region(Agent,Show):-
  127     member(Show,
  128         [fmt(selfAgent= Agent),
  129         mudAtLoc(Agent,value),
  130         mudHeightOnObj(Agent,value),
  131         mudFacing(Agent,value),
  132         mudStance(Agent,value),
  133         mudNearBody(Agent,value),
  134         mudNearReach(Agent,value),
  135         mudGetPrecepts(Agent,value),                  
  136         mudMoveDist(Agent,value),
  137         mudLastCmdSuccess=wasSuccess(Agent,_What,value)]).
  138
  139
  140cmdLookTest(Agent,LOC):-current_agent(Agent),mudAtLoc(Agent,LOC),
  141     show_kb_preds(Agent,LOC,
  142         [
  143         mudAtLoc(Agent,value),
  144         nameStringsList(vHere,value)]),!.
  145
  146
  147:-export(nameStringsList/2).  148
  149nameStringsList(Region,ValueList):-
  150  findall(Value,nameString(Region,Value),ValueList).
  151
  152tLooking(Agent):- current_agent(Agent),!.
  153tLooking(Agent):- tAgent(Agent),not(tDeleted(Agent)).
  154
  155% ********** TOP LEVEL PREDICATE: this is the predicate agents use to look
  156% Look, reports everything not blocked up to two locations away
  157% plus the agents score, damage, charge, and if they succeeded at their last action.
  158% To make this action take a turn, change the first line to:
  159% Impliment(get_all(Agent,Vit,Dam,Suc,Scr,Percepts,Inv)) :-
  160get_all(Agent,Vit,Dam,What=Suc,Scr,Percepts,Inv) :-
  161  call_u((
  162	tLooking(Agent),
  163	mudEnergy(Agent,Vit),
  164        mudHealth(Agent,Dam),
  165	wasSuccess(Agent,What,Suc),
  166	mudScore(Agent,Scr),
  167	mudPossess(Agent,Inv),
  168	mudGetPrecepts(Agent,Percepts))),!.
  169
  170
  171% Get only the Percepts
  172
  173prologBuitlin(mudGetPrecepts(tAgent,ftListFn(tSpatialThing)),[predicateConventionMt(user)]).
  174mudGetPrecepts(Agent,Percepts) :- mudGetPrecepts0(Agent,Percepts0),!,flatten_set(Percepts0,Percepts).
  175mudGetPrecepts0(Agent,Percepts) :-
  176  call_u((
  177	tLooking(Agent),
  178	view_vectors(Agent,Dirs),
  179	check_for_blocks(Agent),
  180	view_dirs(Agent,Dirs,Tmp_percepts),
  181	alter_view(Agent,Dirs,Tmp_percepts,Percepts))),
  182	!.
  183
  184% Look at locations immediately around argent
  185% prologBuitlin(mudNearReach(tAgent,ftListFn(tSpatialThing)),[predicateConventionMt(user)]).
  186mudNearReach(Agent,PerceptsO):- get_near0(Agent,Percepts0),!,flatten_set(Percepts0,Percepts),delete(Percepts,Agent,PerceptsO).
  187   
  188get_near0(Agent,Percepts) :-
  189  call_u((
  190	tLooking(Agent),
  191	near_vectors(Dirs),
  192	view_dirs(Agent,Dirs,Percepts))),!.
  193
  194% Look only at location tAgent is currently in.
  195% prologBuitlin(mudNearBody(tAgent,ftListFn(tSpatialThing)),[predicateConventionMt(user)]).
  196mudNearBody(Agent,PerceptsO) :-  get_feet0(Agent,Percepts0),!,flatten_set(Percepts0,Percepts),delete(Percepts,Agent,PerceptsO).
  197
  198get_feet0(Agent,Percepts):-
  199  call_u((
  200	tLooking(Agent),
  201	mudAtLoc(Agent,LOC),
  202        mudFacing(Agent,Facing),
  203        reverse_dir(Facing,Rev),
  204	get_mdir_u(Agent,[Facing,Rev],LOC,Percepts))),
  205	!.
  206
  207==>pddlObjects(vtDirection,[vNorth,vSouth,vEast,vWest,vNE,vNW,vSE,vSW]).
  208
  209
  210%View list starting at vac'vSouth position and moving out in a clockwise spiral
  211%old_view_list([[vEast,vWest],[vNorth,vHere],[vNE,vHere],[vEast,vHere],[vSE,vHere],[vSouth,vHere],[vSW,vHere],
  212%	   [vWest,vHere],[vNW,vHere],[vNorth,vNorth],[vNorth,vNE],[vNE,vNE],[vEast,vNE],[vEast,vEast],[vEast,vSE],
  213%	   [vSE,vSE],[vSouth,vSE],[vSouth,vSouth],[vSouth,vSW],[vSW,vSW],[vWest,vSW],[vWest,vWest],[vWest,vNW],
  214%	   [vNW,vNW],[vNorth,vNW]]).
  215
  216%grid of view, upper left (vNW) to lower right (vSE)
  217%This is the order the agents will receive their Percepts returned from get_all(Agent,) in
  218view_vectors(_Agent,[[vNW,vNW],[vNorth,vNW],[vNorth,vNorth],[vNorth,vNE],[vNE,vNE],
  219	    [vWest,vNW],[vNW,vHere],[vNorth,vHere],[vNE,vHere],[vEast,vNE],
  220	    [vWest,vWest],[vWest,vHere],[vDown,vUp],[vEast,vHere],[vEast,vEast],
  221	    [vWest,vSW],[vSW,vHere],[vSouth,vHere],[vSE,vHere],[vEast,vSE],
  222	    [vSW,vSW],[vSouth,vSW],[vSouth,vSouth],[vSouth,vSE],[vSE,vSE]]).
  223
  224% A view list of only the locations immediately surrounding the tAgent.
  225near_vectors([[vNW,vHere],[vNorth,vHere],[vNE,vHere],
  226	[vWest,vHere],[vDown,vUp],[vEast,vHere],
  227	[vSW,vHere],[vSouth,vHere],[vSE,vHere]]).
  228
  229:-dynamic(visually_blocked/2).  230==>prologDynamic(visually_blocked(tAgent,ftListFn(vtDirection))).
  231
  232% :-listing(visually_blocked).
  233
  234% Series of predicates to modify agents vision so return 'dar(k)' for locations
  235% which are blocked from view
  236% check_for_blocks(_Agent) :-!.
  237check_for_blocks(Agent) :-
  238	mudHeightOnObj(Agent,Ht),
  239	clr(visually_blocked(Agent,_)),
  240	Dirs = [[vNorth,vHere],[vSouth,vHere],[vEast,vHere],[vWest,vHere],
  241	[vNE,vHere],[vNW,vHere],[vSE,vHere],[vSW,vHere]],
  242	view_dirs(Agent,Dirs,Percepts),
  243	blocked_percepts(Ht,Dirs,Percepts,[],Blocked_Percepts),
  244	ain(visually_blocked(Agent,Blocked_Percepts)).
  245check_for_blocks(_,[]).
  246
  247==>prologSingleValued(mudSize(tSpatialThing,ftTerm)).
  248==>prologSingleValued(mudShape(tSpatialThing,vtShape)).
  249==>prologSingleValued(mudHeightOnObj(tSpatialThing,ftNumber)).
  250meta_argtypes(mudTexture(tSpatialThing,vtTexture)).
  251
  252prologHybrid(mudHeightOnObj(tSpatialThing,ftNumber)).
  253% High enough to see over obstacles??
  254% Check to see how tall the tAgent is and if they are standing on an item
  255mudHeightOnObj(Agent,Ht) :-
  256	mudAtLoc(Agent,LOC),
  257	mudAtLocList(LOC,Objs),
  258	member(Obj,Objs),
  259	iprops(Obj,mudHeight(ObjHt)),
  260	mudHeight(Agent,AgHt),
  261	Ht = (AgHt + ObjHt) - 1,!.
  262mudHeightOnObj(Agent,Ht) :-
  263	mudHeight(Agent,Ht),!.
  264
  265
  266% Figure out if any obstacles are blocking vision...
  267blocked_percepts(_,[],[],Blocked_Percepts,Blocked_Percepts).
  268blocked_percepts(AgHt,[[D1,_]|Drest],[[P1|_]|Prest],Blocked_sofar,Blocked_Percepts) :-
  269	props(P1,mudHeight(ObjHt)),
  270	ObjHt > AgHt,
  271	block_coverage(D1,D1,Hidden),
  272	append(Hidden,Blocked_sofar,Blocked_sofar_tmp),
  273	!,
  274	blocked_percepts(AgHt,Drest,Prest,Blocked_sofar_tmp,Blocked_Percepts).
  275blocked_percepts(AgHt,[_|Drest],[_|Prest],Blocked_sofar,Blocked_Percepts) :-
  276	!,
  277	blocked_percepts(AgHt,Drest,Prest,Blocked_sofar,Blocked_Percepts).
  278
  279% Blocks view for inbetween locations (eg.[vNorth,vHere] would block [vNorth,vNorth],[vNorth,vNE],[vNorth,vNW]).
  280block_coverage(vNorth,vNorth,[[vNorth,vNorth],[vNorth,vNE],[vNorth,vNW]]).
  281block_coverage(vSouth,vSouth,[[vSouth,vSouth],[vSouth,vSE],[vSouth,vSW]]).
  282block_coverage(vWest,vWest,[[vWest,vWest],[vWest,vNW],[vWest,vSW]]).
  283block_coverage(vEast,vEast,[[vEast,vEast],[vEast,vNE],[vEast,vSE]]).
  284block_coverage(D1,D2,[[D1,D2]]).
  285
  286% These three predicates modifies Percepts so that blocked locations return 'dark'
  287alter_view(_Agent,[],[],[]).
  288alter_view(Agent,[[D1,D2]|Drest],[TP|TPrest],[P|Prest]) :-
  289	mem_test(Agent,D1,D2,YorN),
  290	alter_view(Agent,Drest,TPrest,Prest),
  291	dark_if_yes(YorN,[TP],P).
  292
  293mem_test(Agent,D1,D2,YorN) :-
  294	visually_blocked(Agent,Bdirs),
  295	prop_memb([D1,D2],Bdirs),
  296	YorN = yes.
  297mem_test(_Agent,_,_,no).
  298
  299dark_if_yes(yes,_,[vDark]).
  300%dark_if_yes(no,[[]],[]).
  301dark_if_yes(no,[P],P).
  302
  303% Builds the Percepts ftListFn. (everything located up to 2 locations away from tAgent).
  304view_dirs(_,[],[]).
  305view_dirs(Agent,[[D1|D2]|Rest],Percepts) :-
  306      tLooking(Agent),
  307	view_dirs(Agent,Rest,Psofar),
  308	mudAtLoc(Agent,LOC),
  309	get_mdir_u(Agent,[D1|D2],LOC,What),
  310	append([What],Psofar,Percepts).
  311
  312% The look loop (look at one location)
  313get_mdir(_Gent,[],LOC,What) :-
  314	mudAtLocList(LOC,What).
  315get_mdir(_Gent,[vHere],LOC,What) :-
  316	mudAtLocList(LOC,What).
  317get_mdir(Agent,[Dir|D],LOC,What) :-
  318	from_dir_target(LOC,Dir,XXYY),
  319	get_mdir(Agent,D,XXYY,What).
  320
  321% The look loop (look at one location)
  322get_mdir_u(_Gent,[],LOC,What) :-
  323	mudAtLocList(LOC,What).
  324get_mdir_u(_Gent,[vHere],LOC,What) :-
  325	mudAtLocList(LOC,What).
  326get_mdir_u(Agent,[Dir|D],LOC,What) :-
  327	from_dir_target(LOC,Dir,XXYY),
  328	get_mdir_u(Agent,D,XXYY,What).
  329get_mdir_u(Agent,[_|D],LOC,What) :- 
  330   get_mdir_u(Agent,D,LOC,What).
  331
  332% Reports everything at a location.
  333mudAtLocList(LOC,List) :-
  334	findall(Z,mudAtLoc(Z,LOC),List).
  335
  336% Converts the objects seen... basically to weed out the 0'vSouth the empty locations mudAtLocList
  337mask([],What,What).
  338mask([K|Tail],SoFar,What) :-
  339	(K)=nil,
  340	!,
  341	mask(Tail, SoFar,What).
  342mask([Head|Tail],SoFar,What) :-
  343	mask(Tail,[Head|SoFar],What).
  344
  345:- include(prologmud(mud_footer)).