-+-+-+-+-+-+-+-+ START OF PART 16 -+-+-+-+-+-+-+-+ X`09default_filespec : `5BCLASS_S`5D PACKED ARRAY `5B$l2..$u2:INTEGER`5D OF C VHAR := %IMMED 0; X`09related_filespec : `5BCLASS_S`5D PACKED ARRAY `5B$l3..$u3:INTEGER`5D OF C VHAR := %IMMED 0; X`09%IMMED `5BUNBOUND, ASYNCHRONOUS`5D PROCEDURE user_success_procedure := %I VMMED 0; X`09%IMMED `5BUNBOUND, ASYNCHRONOUS`5D PROCEDURE user_error_procedure := %IMM VED 0; X`09%IMMED `5BUNBOUND, ASYNCHRONOUS`5D PROCEDURE user_confirm_procedure := %I VMMED 0; X`09%IMMED user_specified_argument : `5BUNSAFE`5D INTEGER := %IMMED 0; X`09VAR resultant_name : `5BCLASS_S,VOLATILE`5D PACKED ARRAY `5B$l8..$u8:INTE VGER`5D OF CHAR := %IMMED 0; X`09VAR file_scan_context : `5BVOLATILE`5D UNSIGNED := %IMMED 0) : INTEGER; E VXTERNAL; X X`5BASYNCHRONOUS`5D FUNCTION smg$begin_pasteboard_update ( X`09pasteboard_id : UNSIGNED) : INTEGER; EXTERNAL; X X`5Basynchronous,hidden,external`5D Xprocedure scatter_objects; Xexternal; X X`5Basynchronous,hidden,external`5D Xprocedure drop_gold(quantity:integer; echo:boolean); Xexternal; X X`5Basynchronous`5D Xfunction good_coordinates(x,y:integer):boolean; Xbegin X good_coordinates := (x > 0) and (y > 0) and X`09`09 (x <= here.size.x) and (y <= here.size.y); Xend; X Xprocedure show_player_status; Xvar X s:string; X i:integer; Xbegin X writev(s,name`5Bna_player`5D.id`5Bplr`5Bnow`5D.log`5D,'''s stats'); X x_label(s); X purge_x; X for i := 1 to ps_max do X if pl`5Bnow`5D.sts`5Bi`5D.on then X begin X writev(s,write_nice(player_status`5Bi`5D,10),':', X`09(pl`5Bnow`5D.sts`5Bi`5D.time - getticks) div 10:0); X add_x(s); X end; X draw_x; Xend; X X`5Basynchronous`5D Xprocedure show_stats; Xvar X s:string; X i:integer; Xbegin X x_label(name`5Bna_player`5D.id`5Bplr`5Bnow`5D.log`5D); X purge_x; X add_x('Race :'+name`5Bna_race`5D.id`5Bpl`5Bnow`5D.attrib_ex`5Bst_race`5D` V5D); X add_x('Class :'+class_name`5Bpl`5Bnow`5D.attrib_ex`5Bst_class`5D`5D); X for i := 1 to at_max do X begin X writev(s,write_nice(attrib_name`5Bi`5D,16),':',pl`5Bnow`5D.attrib`5Bi`5D V:0,'/', X`09pl`5Bnow`5D.attrib_max`5Bi`5D:0); X add_x(s); X end; X add_x('--------Proficiencies-------'); X for i := 1 to el_max do X begin X writev(s,write_nice(element`5Bi`5D,16),':', X show_condition(pl`5Bnow`5D.proficiency`5Bi`5D)); X add_x(s); X end; X add_x('---------Misc Stats---------'); X for i := 1 to st_max do X begin X writev(s,write_nice(attrib_ex_name`5Bi`5D,16),':',pl`5Bnow`5D.attrib_ex` V5Bi`5D:0); X add_x(s); X end; X add_x('-----------Armor-----------'); X for i := 1 to el_max do X begin X writev(s,write_nice(element`5Bi`5D,10),' chance:', X show_condition(plr`5Bnow`5D.armor`5Bi`5D.chance)); X add_x(s); X writev(s,write_nice(element`5Bi`5D,10),' mod :', X show_condition(plr`5Bnow`5D.armor`5Bi`5D.magnitude)); X add_x(s); X end; X draw_x; Xend; X X`5Basynchronous`5D Xfunction find_thought(looking_for:integer; var slot:integer):boolean; Xvar X i:integer := 1; X found:boolean := false; Xbegin X while (i <= maxthoughts) and (not found) do X if plr`5Bnow`5D.target`5Bi`5D.log = looking_for then X begin X found := true; X slot := i; X end X else i := i + 1; X find_thought := found; Xend; X X`5Basynchronous`5D Xprocedure remember_attack(log,damage:integer); Xvar X slot:integer; X X procedure remember_prime; X begin X plr`5Bnow`5D.target`5Bslot`5D.log := log; X plr`5Bnow`5D.target`5Bslot`5D.hits := plr`5Bnow`5D.target`5Bslot`5D.hits V + 1; X plr`5Bnow`5D.target`5Bslot`5D.damage := plr`5Bnow`5D.target`5Bslot`5D.da Vmage + 1; X end; X Xbegin X if plr`5Bnow`5D.log <> log then X begin X if find_thought(log,slot) then remember_prime X else if find_thought(0,slot) then remember_prime; X end; Xend; X X`5Basynchronous`5D Xprocedure forget_attack(log:integer); Xvar X slot:integer; Xbegin X if find_thought(log,slot) then X with plr`5Bnow`5D.target`5Bslot`5D do X begin X log := 0; X damage := 0; X hits := 0; X end; Xend; X X`5Basynchronous`5D Xprocedure do_go(dirnum:integer; move_delay:boolean := true; X`09`09move_modifier:integer := 0); Xforward; X X`5Basynchronous`5D Xprocedure forget_foreground_effect(slot:integer := 0); Xvar X i,j,k:integer; Xbegin X for i := 1 to maxhoriz do X for j := 1 to maxvert do X for k := 1 to fg_layers do X if (fg.map`5Bi,j,k`5D = slot) or (slot = 0) then fg.map`5Bi,j,k`5D := 0; Xend; X X`5Basynchronous`5D Xprocedure forget_foreground_object(slot:integer := 0); Xvar X i,j,k:integer; Xbegin X for i := 1 to maxhoriz do X for j := 1 to maxvert do X for k := 1 to obj_layers do X if (obj_map`5Bi,j,k`5D = slot) or (slot = 0) then obj_map`5Bi,j,k`5D := 0; Xend; X X`5Basynchronous`5D Xprocedure forget_all; Xvar X i,j:integer; Xbegin X for i := 1 to maxplayers do person`5Bi`5D.here := false; X for i := 1 to maxhoriz do X for j := 1 to maxvert do people_map`5Bi,j`5D := 0; Xend; X X`5Basynchronous`5D Xprocedure leave_room(roomto:string := ''); Xbegin X act_out(plr`5Bnow`5D.log,e_walkout,pl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y V,,,,,roomto); X deassign_channel(person`5Bplr`5Bnow`5D.log`5D.channel); X forget_all; X forget_foreground_object; X forget_foreground_effect; X smg$begin_pasteboard_update(pasteboard); Xend; X X`5Basynchronous`5D Xprocedure setup_room_process(roomnum:integer); Xvar X prcnam,out_file_name:string; X baspri:$uword := 4; X pid,len:unsigned := 0; X X procedure spawn_proc(exe_dir:string); X begin X spawned_out := not (lib$spawn('run '+exe_dir+'srgod',,out_file_name,1, X prcnam) = 1); X end; X Xbegin X writev(prcnam,roomnum:0,' Control'); X writev(out_file_name,'sys$scratch:out_',roomnum:0,'.sr'); X sysstatus := lib$delete_file(out_file_name); X syscheck('lib$delete_file'); X spawn_proc(root); X add_acl(out_file_name, X '(identifier=`5Bmas,'+srop+'`5D,access=read+write+execute+delete)'); X if spawned_out then X begin X act_out(plr`5Bnow`5D.log,e_can_spawn,,,roomnum,,,,,,true); X other_lognum := 0; X wl('You feel a strange sensation...'); X wait(3); X if other_lognum <> 0 then X begin X if checkprivs(10) then X wl(name`5Bna_player`5D.id`5Bother_lognum`5D+' is controlling randoms i Vn your room.'); X act_out(plr`5Bnow`5D.log,e_spawn,,,other_lognum,,,,,,, X person`5Bother_lognum`5D.channel); X end; X end; Xend; X X`5Basynchronous`5D Xprocedure enter_room(roomto:loc; ratiox,ratioy:real := 0; X`09`09 sameroom,npc_in:boolean := false); Xvar X i,mask:integer := 0; X `20 X function nobody_here:boolean; X var X ii:integer; X begin X nobody_here := true; X for ii := 1 to indx`5Bi_player`5D.top do X if an_int`5Bn_location`5D.int`5Bii`5D = pl`5Bnow`5D.where.r then`20 X if (ii <> plr`5Bnow`5D.log) and X`09(indx`5Bi_ingame`5D.on`5Bii`5D) and X`09(not indx`5Bi_npc`5D.on`5Bii`5D) then nobody_here := false; X end; X Xbegin X change_stat_ex(st_base,0); X if not sameroom then X begin X pl`5Bnow`5D.where.r := roomto.r; X getint(n_location); X an_int`5Bn_location`5D.int`5Bplr`5Bnow`5D.log`5D := roomto.r; X putint(n_location); X for i := 1 to maxfg do fg_printed`5Bi`5D := false; X getroom(roomto.r); X freeroom; X getfg(roomto.r); X freefg; X if human then X begin X if not assign_channel(here.mbx,person`5Bplr`5Bnow`5D.log`5D.channel) t Vhen X setup_room_process(here.valid) X else X begin X`7BThe way it works is: The person just coming into the game logs an e_assi Vgn X to the process(es) already in the game. When they respond with e_acknowled Vge, X we'll start sending to them.`7D X X`7BThis is so if we dumped out, and the god process thought we were still in V, X we wouldn't try plotting them before they assigned the channel. The point X at which we start sending to it is once we get their X 1) e_assign - for when room_process was just activated X 2) e_ack - for when room_process acknowledges our e_assign`09`7D X`09person`5Bplr`5Bnow`5D.log`5D.here := true; X`09act_out(plr`5Bnow`5D.log,e_assign,,,,,,,mymbx, X`09`09name`5Bna_player`5D.id`5Bplr`5Bnow`5D.log`5D,,person`5Bplr`5Bnow`5D.lo Vg`5D.channel); X`09person`5Bplr`5Bnow`5D.log`5D.here := false; X end; X end; X if (here.kind = rm_dungeon) and human then X if nobody_here then draw_map; X end; X if roomto.x = -1 then X case roomto.y of X 1:begin X`09pl`5Bnow`5D.where.y := 1; X`09pl`5Bnow`5D.where.x := trunc(ratiox * here.size.x); X end; X 2:begin X pl`5Bnow`5D.where.y := here.size.y; X`09pl`5Bnow`5D.where.x := trunc(ratiox * here.size.x); X end; X 3:begin X`09pl`5Bnow`5D.where.x := here.size.x; X`09pl`5Bnow`5D.where.y := trunc(ratioy * here.size.y); X end; X 4:begin X`09pl`5Bnow`5D.where.x := 1; X`09pl`5Bnow`5D.where.y := trunc(ratioy * here.size.y); X end; X end X else X if (roomto.x = 0) or (roomto.y = 0) then X free_space(pl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y) X else X begin X pl`5Bnow`5D.where.x := roomto.x; X pl`5Bnow`5D.where.y := roomto.y; X end; X draw_screen(sameroom); X draw_me; X mask := do_mask(not pl`5Bnow`5D.sts`5Bps_dead`5D.on,m_alive,human,m_human, X pl`5Bnow`5D.sts`5Bps_invisible`5D.on,m_invisible); X with pl`5Bnow`5D do X if (not sameroom) or (npc_in) then X act_out(plr`5Bnow`5D.log,e_walkin,where.x,where.y,attrib_ex`5Bst_base`5D, X`09attrib`5Bat_size`5D,where.r,mask,name`5Bna_player`5D.id`5Bplr`5Bnow`5D.lo Vg`5D,,true) X else act_out(plr`5Bnow`5D.log,e_move,where.x,where.y,attrib_ex`5Bst_base`5 VD, X`09attrib`5Bat_size`5D,where.r,mask,name`5Bna_player`5D.id`5Bplr`5Bnow`5D.lo Vg`5D); Xend; X X`5Basynchronous`5D Xfunction dir_convert(dir:integer):integer; Xbegin X case dir of X 6:dir_convert := 3; X 7:dir_convert := 4; X 8,9:dir_convert := 1; X 1:dir_convert := 2; X otherwise dir_convert := dir; X end; Xend; X X`5Basynchronous`5D Xfunction find_exit(dir:integer; var exitnum:integer):boolean; Xvar X i:integer; Xbegin X exitnum := 0; X find_exit := false; X X if dir <> 5 then X if here.exit`5Bdir_convert(dir)`5D.toroom <> 0 then X begin X exitnum := dir_convert(dir); X find_exit := true; X end; X X if (exitnum = 0) and (dir = 5) then X begin X for i := 1 to fg_layers do X if fg.map`5Bpl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y,i`5D <> 0 then X if (fg.effect`5Bfg.map`5Bpl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y,i`5D`5D V.kind = fg_exit) and X (fg.effect`5Bfg.map`5Bpl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y,i`5D`5D.b Vase = pl`5Bnow`5D.attrib_ex`5Bst_base`5D) X`09then exitnum := fg.map`5Bpl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y,i`5D; X if exitnum > 0 then find_exit := (fg.effect`5Bexitnum`5D.dest.r <> 0) X else find_exit := false; X end; Xend; X X`5Basynchronous`5D Xprocedure dispossess_someone(died:boolean := true); Xvar X i:integer; Xbegin X i := plr`5Bnow`5D.log; X getindex(i_ingame); X indx`5Bi_ingame`5D.on`5Bi`5D := false; X putindex(i_ingame); X if died then X begin X getname(na_player); X name`5Bna_player`5D.id`5Bplr`5Bnow`5D.log`5D := 'Null'; X putname(na_player); X act_out(i,e_walkout,,,,,,,'the halls of the dead'); X end X else act_out(i,e_walkout,,,,,,,'Knox 110'); X pl`5Bnow`5D.sts`5Bps_dead`5D.on := true; X person`5Bi`5D.here := false; X monsters_active := monsters_active - 1; Xend; X X`5Basynchronous`5D Xprocedure do_exit(dirnum:integer); Xvar X exitnum:integer; X ratiox,ratioy:real; X sameroom:boolean := false; X dest:loc; X old_mbx:shortstring; X a_channel:$uword; Xbegin X if find_exit(dirnum,exitnum) then X begin X ratiox := pl`5Bnow`5D.where.x/here.size.x; X ratioy := pl`5Bnow`5D.where.y/here.size.y; X X if dirnum = 5 then dest := fg.effect`5Bexitnum`5D.dest X else with here.exit`5Bexitnum`5D do X begin X dest.r := toroom; X dest.x := -1; X dest.y := face; X end; X sameroom := (dest.r = pl`5Bnow`5D.where.r); X if human then X begin X if not sameroom then X begin X wl('Exiting '+name`5Bna_room`5D.id`5Bpl`5Bnow`5D.where.r`5D+'...'); X leave_room(name`5Bna_room`5D.id`5Bdest.r`5D); X end X else fix_scenery(pl`5Bnow`5D.where.x,pl`5Bnow`5D.where.y); X enter_room(dest,ratiox,ratioy,sameroom); X end X else X begin X if not sameroom then X begin X`09old_mbx := here.mbx; X`09getint(n_location); X`09an_int`5Bn_location`5D.int`5Bplr`5Bnow`5D.log`5D := dest.r; X`09putint(n_location); X`09getroom(dest.r); X`09freeroom; X`09if assign_channel(here.mbx,a_channel) then X`09begin X`09 act_out(0,e_possess,plr`5Bnow`5D.log,,,,,,,old_mbx,,a_channel); X`09 deassign_channel(a_channel); X`09 dispossess_someone(false); X`09end; X`09getroom; X`09freeroom; X end X else X enter_room(dest,ratiox,ratioy,sameroom); X end; X end; Xend; X X`5Basynchronous`5D Xfunction block_background(icon:char):boolean; Xbegin X if icon in `5B'#','`7C','_','/','\'`5D then block_background := true X else block_background := false; Xend; X X`5Basynchronous`5D Xfunction bump_background(x,y:integer; move_delay:boolean := true):boolean; Xvar X s:string; X X procedure delay(d_time:real); X begin X if move_delay then freeze(d_time); X end; X Xbegin X bump_background := false; X if block_background(here.background`5Bx,y`5D) and (not checkprivs(2)) then X begin X bump_background := true; X case here.background`5Bx,y`5D of X '#':s :='Arumph!'; X '`7C':s :='Oomph!'; X '/':s :='Whop!'; X '\':s :='Ooof!'; X '_':s :='Bif!'; X end; X wl(s); X if human then X begin X act_out(plr`5Bnow`5D.log,e_msg,,,,,,,name`5Bna_player`5D.id`5Bplr`5Bno Vw`5D.log`5D+ X`09' slams into a wall with a '+s); X delay(0.75); X end; X end X else if (here.background`5Bx,y`5D in `5B'`7E','`5E','"'`5D) and (not check Vprivs(8)) then X begin X case here.background`5Bx,y`5D of X '`7E':delay(0.5); X '`5E':delay(1); X '"':delay(0.25); X end; X end; Xend; X X`5Basynchronous`5D Xfunction find_enemy(var slot:integer):boolean; Xvar X i,most_damage:integer := 0; Xbegin X find_enemy := false; X for i := 1 to maxthoughts do X if plr`5Bnow`5D.target`5Bi`5D.damage > most_damage then X begin +-+-+-+-+-+-+-+- END OF PART 16 +-+-+-+-+-+-+-+-