-+-+-+-+-+-+-+-+ START OF PART 14 -+-+-+-+-+-+-+-+ X d_last := line_num; X end; X for i := d_first to d_last do X begin X writev(s1,i:2,') ',write_nice(a_menu`5Bi`5D.choice,24)); X case a_menu`5Bi`5D.kind of X k_int`09:writev(s2,a_menu`5Bi`5D.int_result:0); X k_str, X k_sst, X`09k_ico`09:s2 := a_menu`5Bi`5D.str_result; X`09k_sta`09:s2 := stat`5Ba_menu`5Bi`5D.int_result`5D; X k_boo`09:if a_menu`5Bi`5D.boo_result then s2 := 'True' X`09`09else s2 := 'False'; X`09k_use, X`09k_pla, X`09k_roo, X`09k_rac, X`09k_spe, X`09k_obj`09:if a_menu`5Bi`5D.int_result = 0 then s2 := 'Unknown' X`09`09 else s2 := name`5Ba_menu`5Bi`5D.kind`5D.id`5Ba_menu`5Bi`5D.int_result V`5D; X`09k_dsc`09:s2 := a_menu`5Bi`5D.str_result; X end; X if length(s2) > 24 then s2 := substr(s2,1,24) + '+'; X writev(s3,s1,write_nice(s2,24)); X smg$put_chars(ywind,s3,1+i-m_first,1); X end; X end; X X procedure menu_check; X begin X if m_last > mc then m_last := mc; X end; X X procedure menu_up; X begin X m_first := m_first - m_length; X if m_first < 1 then m_first := 1; X m_last := m_first + m_length; X menu_check; X draw_menu; X end; X X procedure menu_down; X begin X m_last := m_last + m_length; X menu_check; X m_first := m_last - m_length; X if m_first < 1 then m_first := 1; X draw_menu; X end; X Xbegin X mc := mc - 1; X m_first := 1; X m_last := m_length + 1; X smg$begin_pasteboard_update(pasteboard); X smg$create_virtual_display(15,48,ywind,1); X smg$paste_virtual_display(ywind,pasteboard,2,2); X menu_check; X draw_menu; X smg$end_pasteboard_update(pasteboard); X repeat X repeat X grab_line('Menu ',s); X s := lowcase(s); X until length(s) > 0; X case s`5B1`5D of X 'q':done := true; X 'l':do_list; X 'u':menu_up; X 'd':menu_down; X 't':toggle_full_text(not full_text,false); X 'v':if help_file <> '' then X`09 begin X`09 wl('Opening '+help_file+'.'); X`09 typefile(helproot+help_file); X`09 wl('Closing '+help_file+'.'); X`09 end X`09 else wl('There is no help file for this menu.'); X 'h','?':menu_help; X otherwise if isnum(s) then X begin X`09sel := number(s); X`09if sel in `5B1..mc`5D then X`09begin X`09 if a_menu`5Bsel`5D.help_menu <> 0 then do_list(a_menu`5Bsel`5D.help_men Vu); X`09 case a_menu`5Bsel`5D.kind of X k_int:grab_num(a_menu`5Bsel`5D.prompt,a_menu`5Bsel`5D.int_result, X`09a_menu`5Bsel`5D.min_int,a_menu`5Bsel`5D.max_int,a_menu`5Bsel`5D.def_int); X k_dsc:`7Bif a_menu`5Bsel`5D.str_result = '' then`7D X`09 begin X`09 grab_line('`5BFilename`5D '+a_menu`5Bsel`5D.prompt,s); X`09 if s = '' then s := a_menu`5Bsel`5D.str_result; X`09 sysstatus := lib$find_file(root+s,%descr dum_dum,context); X`09 if sysstatus = rms$_suc then X`09 wl('File by that name already exists!') X`09 else if edit(s,a_menu`5Bsel`5D.prompt) then X`09 a_menu`5Bsel`5D.str_result := s; X`09 end; X`7B`09 else if not edit(a_menu`5Bsel`5D.str_result,a_menu`5Bsel`5D.prompt V) then X`09`09a_menu`5Bsel`5D.str_result := '';`7D X k_sst:grab_short(a_menu`5Bsel`5D.prompt,a_menu`5Bsel`5D.str_result); X k_ico:begin X`09 grab_line(a_menu`5Bsel`5D.prompt,s); X`09 if length(s) > 0 then a_menu`5Bsel`5D.str_result := s`5B1`5D X`09 else a_menu`5Bsel`5D.str_result := '?'; X`09 end; X k_sta:begin X`09 grab_line(a_menu`5Bsel`5D.prompt,s); X`09 lookup(attrib_name,s,a_menu`5Bsel`5D.int_result); X`09 end; X k_str:begin X`09 wl('Currently reads :'); X`09 wl(a_menu`5Bsel`5D.str_result); X`09 wl(a_menu`5Bsel`5D.prompt); X`09 grab_line('',a_menu`5Bsel`5D.str_result); X`09 end; X k_boo:a_menu`5Bsel`5D.boo_result := not a_menu`5Bsel`5D.boo_result; X`09`09`09`09 `7Bgrab_yes(a_menu`5Bsel`5D.prompt);`7D X k_pla:get_name(name`5Bna_player`5D.id,a_menu`5Bsel`5D.prompt,a_menu`5B Vsel`5D.int_result, X`09`09a_menu`5Bsel`5D.def_int); X k_obj:get_name(name`5Bna_obj`5D.id,a_menu`5Bsel`5D.prompt,a_menu`5Bsel V`5D.int_result, X`09`09a_menu`5Bsel`5D.def_int); X k_roo:get_name(name`5Bna_room`5D.id,a_menu`5Bsel`5D.prompt,a_menu`5Bse Vl`5D.int_result, X`09`09a_menu`5Bsel`5D.def_int); X k_rac:get_name(name`5Bna_race`5D.id,a_menu`5Bsel`5D.prompt,a_menu`5Bse Vl`5D.int_result, X`09`09a_menu`5Bsel`5D.def_int); X k_spe:get_name(name`5Bna_spell`5D.id,a_menu`5Bsel`5D.prompt,a_menu`5Bs Vel`5D.int_result, X`09`09a_menu`5Bsel`5D.def_int); X k_use:get_name(name`5Bna_user`5D.id,a_menu`5Bsel`5D.prompt,a_menu`5Bse Vl`5D.int_result, X`09`09a_menu`5Bsel`5D.def_int); X`09 end; X`09 draw_menu(sel); X`09end X end X else wl('That is not a valid menu option.'); X end; X until done; X X smg$begin_pasteboard_update(pasteboard); X smg$delete_virtual_display(ywind); X smg$repaste_virtual_display(gwind,pasteboard,2,2); X smg$end_pasteboard_update(pasteboard); X mc := 1; Xend; X Xprocedure set_menu( in_choice:shortstring; X`09`09 in_prompt:string := ''; X`09`09 in_kind:integer := k_int; X`09`09 in_int_result:integer := 0; X`09`09 in_str_result:string := ''; X`09`09 in_boo_result:boolean := false; X`09`09 in_min_int:integer := 0; X`09`09 in_max_int:integer := maxint div 2; X`09`09 in_def_int:integer := 0; X`09`09 in_help_menu:integer := 0); Xbegin X with a_menu`5Bmc`5D do X begin X choice`09:= in_choice; X if in_prompt = '' then prompt := in_choice X else prompt`09:= in_prompt; X kind`09:= in_kind; X max_int`09:= in_max_int; X min_int`09:= in_min_int; X def_int`09:= in_min_int; X str_result`09:= in_str_result; X int_result`09:= in_int_result; X boo_result`09:= in_boo_result; X help_menu`09:= in_help_menu; X end; X mc := mc + 1; Xend; X Xprocedure get_menu_int(var i:integer); Xbegin X i := a_menu`5Bmc`5D.int_result; X mc := mc + 1; Xend; X Xprocedure get_menu_str(var s:string); Xbegin X s := a_menu`5Bmc`5D.str_result; X mc := mc + 1; Xend; X Xprocedure get_menu_sst(var s:shortstring); Xbegin X s := a_menu`5Bmc`5D.str_result; X mc := mc + 1; Xend; X Xprocedure get_menu_ico(var s:char); Xbegin X s := a_menu`5Bmc`5D.str_result`5B1`5D; X mc := mc + 1; Xend; X Xprocedure get_menu_boo(var b:boolean); Xbegin X b := a_menu`5Bmc`5D.boo_result; X mc := mc + 1; Xend; X Xend. $ CALL UNPACK SRMENU.PAS;1 1315792060 $ create 'f' X`5Binherit ('srinit','srsys','srother'),environment('srmisc')`5D X Xmodule srmisc; X X`5BASYNCHRONOUS`5D FUNCTION smg$put_chars ( X`09display_id : UNSIGNED; X`09text : `5BCLASS_S`5D PACKED ARRAY `5B$l2..$u2:INTEGER`5D OF CHAR; X`09start_row : INTEGER := %IMMED 0; X`09start_column : INTEGER := %IMMED 0; X`09flags : UNSIGNED := %IMMED 0; X`09rendition_set : UNSIGNED := %IMMED 0; X`09rendition_complement : UNSIGNED := %IMMED 0; X`09character_set : UNSIGNED := %IMMED 0) : INTEGER; EXTERNAL; X X`5BASYNCHRONOUS`5D FUNCTION smg$begin_display_update ( X`09display_id : UNSIGNED) : INTEGER; EXTERNAL; X X`5BASYNCHRONOUS`5D FUNCTION smg$end_display_update ( X`09display_id : UNSIGNED) : INTEGER; EXTERNAL; X X`5BASYNCHRONOUS`5D FUNCTION smg$change_viewport ( X`09display_id : UNSIGNED; X`09viewport_row_start : INTEGER := %IMMED 0; X`09viewport_column_start : INTEGER := %IMMED 0; X`09viewport_number_rows : INTEGER := %IMMED 0; X`09viewport_number_columns : INTEGER := %IMMED 0) : INTEGER; EXTERNAL; X X`5BASYNCHRONOUS`5D FUNCTION smg$label_border ( X`09display_id : UNSIGNED; X`09text : `5BCLASS_S`5D PACKED ARRAY `5B$l2..$u2:INTEGER`5D OF CHAR := %IMME VD 0; X`09position_code : UNSIGNED := %IMMED 0; X`09units : INTEGER := %IMMED 0; X`09rendition_set : UNSIGNED := %IMMED 0; X`09rendition_complement : UNSIGNED := %IMMED 0; X`09character_set : UNSIGNED := %IMMED 0) : INTEGER; EXTERNAL; X X`5BASYNCHRONOUS`5D FUNCTION smg$repaste_virtual_display ( X`09display_id : UNSIGNED; X`09pasteboard_id : UNSIGNED; X`09pasteboard_row : INTEGER; X`09pasteboard_column : INTEGER; X`09top_display_id : UNSIGNED := %IMMED 0) : INTEGER; EXTERNAL; X X`5BASYNCHRONOUS`5D FUNCTION smg$end_pasteboard_update ( X`09pasteboard_id : UNSIGNED) : INTEGER; EXTERNAL; X`20 X`5Basynchronous`5D Xfunction distance(x1,y1,x2,y2:real):integer; Xbegin X distance := round( ((x2-x1)**2+(y2-y1)**2) **(1/2) ); Xend; X X`5Basynchronous`5D Xprocedure plot_special(x,y:integer); Xvar X i:integer; Xbegin X for i := 1 to 4 do X begin X smg$put_chars(gwind,'-',y,x); X smg$put_chars(gwind,'\',y,x); X smg$put_chars(gwind,'`7C',y,x); X smg$put_chars(gwind,'/',y,x); X end; X smg$put_chars(gwind,' ',y,x); Xend; X X`5Basynchronous`5D Xfunction empty_foreground:integer; Xvar X i:integer := 1; X done:boolean := false; Xbegin X while (i <= maxfg) and (not done) do X if fg.name`5Bi`5D = '' then done := true X else i := i + 1; X empty_foreground := i; Xend; X X`5Basynchronous`5D Xfunction hit_me(geometry,geo1,geo2,x,y:integer):boolean; Xvar X d:integer; Xbegin X hit_me := false; X case geometry of Xg_circle: X begin X d := distance(pl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y,x,y); X if (d >= geo1) and (d <= geo2) then hit_me := true; X end; Xg_rectangle: X if (pl`5Bnow`5D.where.x >= x -geo1/2) and (pl`5Bnow`5D.where.x <= x +geo V1/2) and X (pl`5Bnow`5D.where.y >= y -geo2/2) and (pl`5Bnow`5D.where.y <= y +geo V2/2) then X`09hit_me := true; Xg_point: X if (pl`5Bnow`5D.where.x = x) and (pl`5Bnow`5D.where.y = y) then hit_me : V= true; Xg_line,g_blip: X if (pl`5Bnow`5D.where.x = x) and (pl`5Bnow`5D.where.y = y) then hit_me : V= true; X end; Xend; X X`5Basynchronous`5D Xfunction on_screen(x,y:integer):boolean; Xbegin X if (x < vpoffsetx) or (x > vpoffsetx + vpsizex) or X (y < vpoffsety) or (y > vpoffsety + vpsizey) then on_screen := false X else on_screen := true; Xend; X X`5Basynchronous`5D Xfunction in_range(x,y,r:integer):boolean; Xbegin X if distance(pl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y,x,y) <= r then in_rang Ve := true X else in_range := false; Xend; X X`5Basynchronous`5D Xfunction overlap(a,b,c,d:integer):boolean; X`7Breturns true if c-d somewhere in a-b`7D Xbegin X if ((c >= a) and (c <= a+b)) or X ((c+d >= a) and (c+d <= a+b)) then overlap := true X else overlap := false; Xend; X X`5Basynchronous`5D Xfunction highest_priority(x,y,max_priority:integer; X`09`09`09var slot,map_type:integer):integer; X`7Breturns foreground effect with highest visible base`7D Xvar X i,highest:integer := -999; Xbegin X slot := 0; X map_type := map_background; X X for i := 1 to obj_layers do X if obj_map`5Bx,y,i`5D <> 0 then X begin X slot := obj_map`5Bx,y,i`5D; X map_type := map_object; X with fg.object`5Bobj_map`5Bx,y,i`5D`5D do X highest := base + altitude; X end; X X for i := 1 to fg_layers do X if fg.map`5Bx,y,i`5D <> 0 then X with fg.effect`5Bfg.map`5Bx,y,i`5D`5D do X if `09(kind <> 0) and (on) and X`09(not ((icon = ' ') and (rendition = 0)) ) and X`09((base >= highest) or (base + altitude >= highest)) and X`09((base <= max_priority) or (base + altitude <= max_priority)) then X begin X slot := fg.map`5Bx,y,i`5D; X map_type := map_fg; X highest := base + altitude; X end; X X if people_map`5Bx,y`5D <> 0 then X with person`5Bpeople_map`5Bx,y`5D`5D do X if ((feet >= highest) or (head > highest)) and`20 X ((feet <= max_priority) or (head <= max_priority)) then X begin X slot := people_map`5Bx,y`5D; X map_type := map_player; X highest := head; X end; X if highest = -999 then highest := 0; X highest_priority := highest; Xend; X X`5Basynchronous`5D Xprocedure draw_me; Xvar X dum,dum_dum:integer; X rendition:unsigned; Xbegin X if highest_priority(pl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y,pl`5Bnow`5D.at Vtrib`5Bat_size`5D + myview,dum,dum_dum) <= X pl`5Bnow`5D.attrib_ex`5Bst_base`5D + pl`5Bnow`5D.attrib`5Bat_size`5D then V rendition := reverse X else rendition := bold; X smg$put_chars(gwind,name`5Bna_player`5D.id`5Bplr`5Bnow`5D.log`5D`5B1`5D, X`09pl`5Bnow`5D.where.y,pl`5Bnow`5D.where.x,,rendition); Xend; X X`5Basynchronous`5D Xfunction bg_char(x,y:integer; var rendition:unsigned; X`09`09max_priority:integer := -888; X`09`09slot,map_type:integer := 0):char; Xbegin X rendition := 0; X if max_priority = -888 then max_priority := pl`5Bnow`5D.attrib_ex`5Bst_bas Ve`5D; X if slot = 0 then highest_priority(x,y,max_priority,slot,map_type); X case map_type of X map_object`09:begin X`09`09 bg_char := fg.object`5Bslot`5D.icon; X`09`09 rendition := fg.object`5Bslot`5D.rendition; X`09`09 end; X map_player`09:begin X`09`09 bg_char := name`5Bna_player`5D.id`5Bslot`5D`5B1`5D; X`09`09 if person`5Bslot`5D.alive then rendition := reverse X`09`09 else rendition := bold; X`09`09 end; X map_fg`09:begin X`09`09 bg_char := fg.effect`5Bslot`5D.icon; X`09`09 rendition := fg.effect`5Bslot`5D.rendition; X`09`09 end; X map_background:bg_char := here.background`5Bx,y`5D; X end; Xend; X X`7BLooks at the objects in a location, and puts the top one on the X background. Otherwise, it just plots the background.`7D X`5Basynchronous`5D Xprocedure fix_scenery(x,y,max_priority:integer := -888); Xvar X thechar:char; X rendition:unsigned; Xbegin X if max_priority = -888 then max_priority := pl`5Bnow`5D.attrib_ex`5Bst_bas Ve`5D + myview; X thechar := bg_char(x,y,rendition,max_priority); X smg$put_chars(gwind,thechar,y,x,,rendition); Xend; X X`5Basynchronous`5D Xprocedure fix_room(max_priority:integer; short_range:boolean := false); Xvar X i,j,x1,x2,y1,y2:integer; Xbegin X if human then X begin X if short_range then X begin X x1 := vpoffsetx; X x2 := vpoffsetx + vpsizex; X y1 := vpoffsety; X y2 := vpoffsety + vpsizey; X end X else X begin X x1 := 1; X x2 := here.size.x; X y1 := 1; X y2 := here.size.y; X end; X smg$begin_display_update(gwind); X for j := y1 to y2 do X for i := x1 to x2 do X fix_scenery(i,j,max_priority); X draw_me; X smg$end_display_update(gwind); X end; Xend; X X`5Basynchronous`5D Xprocedure map_objects(f_num:integer := 0); Xvar X f_start,f_end,fg_slot:integer; X X procedure plot_object; X var X n:integer := 1; X done:boolean := false; X begin +-+-+-+-+-+-+-+- END OF PART 14 +-+-+-+-+-+-+-+-