unit update; interface uses chars, dtypes, area, constants, util, timers, skills; procedure regenerate_chars; procedure update_chars; procedure update_tracks; procedure update_teleports; procedure update_time; procedure gain_condition(ch:GCharacter;iCond,value:integer); procedure battlegroundMessage; procedure startBattleground; procedure update_battleground; procedure update_objects; implementation uses SysUtils, mudsystem, mudthread, fight, progs, conns; procedure regenerate_chars; var hp_gain,mv_gain,mana_gain:integer; ch : GCharacter; node : GListNode; begin node := char_list.head; while (node <> nil) do begin ch := node.element; hp_gain:=0; mv_gain:=0; mana_gain:=0; if (not ch.IS_NPC) then with ch do with point do begin case position of POS_SLEEPING:begin hp_gain:=9; mv_gain:=7; mana_gain:=3; end; POS_RESTING:begin hp_gain:=7; mv_gain:=9; mana_gain:=4; end; POS_MEDITATE:begin hp_gain:=6; mv_gain:=6; mana_gain:=10; end; POS_STANDING:begin hp_gain:=2; mv_gain:=2; mana_gain:=1; end; POS_FIGHTING:begin hp_gain:=0; mv_gain:=1; mana_gain:=0; end; end; if IS_SET(ch.aff_flags,AFF_POISON) then begin hp_gain:=hp_gain div 4; mv_gain:=mv_gain div 3; mana_gain:=mana_gain div 2; end; if IS_SET(ch.room.flags,ROOM_MANAROOM) then mana_gain:=mana_gain*2; hp:=UMax(hp+hp_gain,max_hp); mv:=UMax(mv+mv_gain,max_mv); mana:=UMax(mana+mana_gain,max_mana); end; node := node.next; end; end; procedure update_time; var buf : string; conn : GConnection; node : GListNode; begin inc(time_info.hour); buf := ''; case time_info.hour of 1:begin time_info.sunlight := SUN_DARK; buf := 'The moon sets.'; end; 5:begin time_info.sunlight:=SUN_DAWN; buf := 'The day has begun.'; end; 6:begin time_info.sunlight:=SUN_RISE; buf := 'The sun rises in the east.'; end; 12:begin time_info.sunlight:=SUN_LIGHT; buf := 'It''s noon.'; end; 19:begin time_info.sunlight:=SUN_SET; buf := 'The sun slowly disappears in the west.'; end; 20:begin time_info.sunlight:=SUN_MOON; buf := 'The night has begun, the moon slowly rises.'; end; 24:begin time_info.hour:=0; inc(time_info.day); end; end; if (time_info.day>=30) then begin time_info.day:=1; inc(time_info.month); end; if (time_info.month>=17) then begin time_info.month:=1; { it wouldn't be Grendel without this :) - Grimlord } { sendtoall('The sky lights up with colorful flashes, created by the firework masters.'#13#10); sendtoall('A cheer passes over the lands as a new year starts.'#13#10); } inc(time_info.year); end; if (length(buf) > 0) then begin node := connection_list.head; while (node <> nil) do begin conn := node.element; if (conn.state=CON_PLAYING) and (conn.ch.IS_OUTSIDE) and (conn.ch.IS_AWAKE) then act(AT_REPORT,buf,false,conn.ch,nil,nil,TO_CHAR); node := node.next; end; end; end; procedure better_mental_state(ch:GCharacter; modifier:integer); var c:integer; begin c:=URANGE(0, abs(modifier), 20); if (number_percent < ch.ability.con) then inc(c); if (ch.mental_state < 0) then ch.mental_state:=URANGE(-MAX_COND, ch.mental_state + c, 0) else if (ch.mental_state > 0) then ch.mental_state:=URANGE(0, ch.mental_state-c, MAX_COND); end; procedure worsen_mental_state(ch:GCharacter;modifier:integer); var c:integer; begin c:=URANGE(0, abs(modifier), 20); if (number_percent < ch.ability.con) then dec(c); if (c<1) then exit; if (ch.mental_state < 0) then ch.mental_state:=URANGE(-MAX_COND, ch.mental_state-c, MAX_COND) else if (ch.mental_state > 0) then ch.mental_state:=URANGE(-MAX_COND, ch.mental_state+c, MAX_COND) else dec(ch.mental_state,c); end; procedure gain_condition(ch:GCharacter;iCond,value:integer); var condition,retcode:integer; begin if (value=0) or (ch.IS_NPC) or (ch.IS_IMMORT) then exit; condition:=ch.player^.condition[iCond]; ch.player^.condition[iCond]:=URANGE(0, condition+value, MAX_COND); retcode := RESULT_NONE; if (ch.player^.condition[iCond]=0) then case iCond of COND_FULL:begin act(AT_REPORT,'You are STARVING!',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n is starving and looks awfully weak!',false,ch,nil,nil,TO_ROOM); worsen_mental_state(ch,1); retcode:=damage(ch,ch,1,TYPE_SILENT); end; COND_THIRST:begin act(AT_REPORT,'You are DYING of THIRST!',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n is dying of thirst!',false,ch,nil,nil,TO_ROOM); worsen_mental_state(ch,2); retcode:=damage(ch,ch,2,TYPE_SILENT); end; COND_DRUNK:begin if condition<>0 then act(AT_REPORT,'You are sober again.',false,ch,nil,nil,TO_CHAR); retcode:=RESULT_NONE; end; COND_HIGH:begin if condition<>0 then act(AT_REPORT,'Your mind stops floating and resumes its normal course.',false,ch,nil,nil,TO_CHAR); retcode:=RESULT_NONE; end; COND_CAFFEINE:begin if condition<>0 then act(AT_REPORT,'Your vains are clear of caffeine... you are less tense.',false,ch,nil,nil,TO_CHAR); retcode:=RESULT_NONE; end; else begin bugreport('gain_condition', 'update.pas', 'invalid condition: '+inttostr(icond), 'The condition given is invalid. Please check your settings.'); retcode:=RESULT_NONE; end; end; if (retcode<>RESULT_NONE) then { don't want to continue when ch is dead } exit; if (ch.player^.condition[iCond]=3) then case iCond of COND_FULL:begin act(AT_REPORT,'You are getting really hungry.',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'You can hear $n''s stomach growling, $e must be hungry.',false,ch,nil,nil,TO_ROOM); if random(2)=0 then worsen_mental_state(ch,1); end; COND_THIRST:begin act(AT_REPORT,'You are getting really thirsty.',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n gasps and looks thirsty.',false,ch,nil,nil,TO_ROOM); worsen_mental_state(ch,1); end; COND_DRUNK:if condition<>0 then act(AT_REPORT,'The world is coming back into perspective.',false,ch,nil,nil,TO_CHAR); COND_HIGH:if condition<>0 then act(AT_REPORT,'You are slowly returning from outer space...',false,ch,nil,nil,TO_CHAR); end; if (ch.player^.condition[iCond]=8) then case iCond of COND_FULL:act(AT_REPORT,'You are hungry.',false,ch,nil,nil,TO_CHAR); COND_THIRST:act(AT_REPORT,'You are thirsty.',false,ch,nil,nil,TO_CHAR); COND_DRUNK:if condition<>0 then act(AT_REPORT,'You feel a bit less light headed.',false,ch,nil,nil,TO_CHAR); COND_HIGH:if condition<>0 then act(AT_REPORT,'Slowly but surely, your high is starting to wear off.',false,ch,nil,nil,TO_CHAR); end; if (ch.player^.condition[iCond]=16) then case iCond of COND_FULL:act(AT_REPORT,'You could use a bite of something.',false,ch,nil,nil,TO_CHAR); COND_THIRST:act(AT_REPORT,'A drink would be nice.',false,ch,nil,nil,TO_CHAR); COND_DRUNK:act(AT_REPORT,'You feel as if little pixies feast inside your skull.',false,ch,nil,nil,TO_CHAR); end; end; procedure update_chars; var p:integer; ch,vict:GCharacter; e:GExit; r:GRoom; node : GListNode; begin node := char_list.head; while (node <> nil) do begin ch := node.element; { switched mobs don't wander } if (ch.IS_NPC) and (ch.conn = nil) then begin if not IS_SET(ch.act_flags, ACT_SENTINEL) then if ch.position=POS_STANDING then begin p:=random(6)+1; e := ch.room.findExit(p); if (e <> nil) then begin r := findRoom(e.vnum); if (r <> nil) and not (IS_SET(ch.act_flags, ACT_STAY_AREA) and (r.area <> ch.room.area)) then interpret(ch, headings[p]); end; end; randTrigger(ch); end else if (not ch.IS_NPC) then begin if (ch.player^.condition[COND_DRUNK]>8) then worsen_mental_state(ch,ch.player^.condition[COND_DRUNK] div 8); if (ch.player^.condition[COND_FULL]>1) then case ch.position of POS_SLEEPING:better_mental_state(ch,4); POS_RESTING:better_mental_state(ch,3); POS_SITTING:better_mental_state(ch,2); POS_STANDING:better_mental_state(ch,1); POS_FIGHTING:if random(4)=0 then better_mental_state(ch,1); end; if (ch.player^.condition[COND_THIRST]>1) then case ch.position of POS_SLEEPING:better_mental_state(ch,5); POS_RESTING:better_mental_state(ch,3); POS_SITTING:better_mental_state(ch,2); POS_STANDING:better_mental_state(ch,1); POS_FIGHTING:if random(4)=0 then better_mental_state(ch,1); end; gain_condition(ch,COND_DRUNK,-1); gain_condition(ch,COND_HIGH,-1); gain_condition(ch,COND_FULL,-1); case ch.room.sector of SECT_DESERT:gain_condition(ch,COND_THIRST,-2); SECT_UNDERWATER, SECT_OCEANFLOOR:if random(2)=0 then gain_condition(ch,COND_THIRST,-1); else gain_condition(ch,COND_THIRST,-1); end; if (ch.mental_state>=30) then case (ch.mental_state+5) div 10 of 3:begin act(AT_REPORT,'You feel chilly and not well.',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n doesn''t look $s normal self.',false,ch,nil,nil,TO_ROOM); end; 4:begin act(AT_REPORT,'You don''t feel good at all.',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n doesn''t look too good.',false,ch,nil,nil,TO_ROOM); end; 5:begin act(AT_REPORT,'You need help immediately!',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n looks like $e could use your help.',false,ch,nil,nil,TO_ROOM); end; 6:begin act(AT_REPORT,'You are in BAD shape, get a healer!',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n looks awful and could use assistance.',false,ch,nil,nil,TO_ROOM); end; 7:begin act(AT_REPORT,'You lose your grip on reality... what is happening?',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n seems unaware of the world and $s surroundings.',false,ch,nil,nil,TO_ROOM); end; 8:begin act(AT_REPORT,'Understanding and knowledge flow through your mind.',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n runs about, babbling like an escaped madman!',false,ch,nil,nil,TO_ROOM); end; 9:begin act(AT_REPORT,'You feel like... Thor.',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n stands ranting about $s immortality.',false,ch,nil,nil,TO_ROOM); end; 10:begin act(AT_REPORT,'Your brain is a cloud of fog... you are dying.',false,ch,nil,nil,TO_CHAR); act(AT_REPORT,'$n kneels down, muttering and chanting in tongues...',false,ch,nil,nil,TO_ROOM); end; end; end; node := node.next; end; end; procedure teleportChar(ch : GCharacter;room:GRoom); begin if IS_SET(room.flags,ROOM_PRIVATE) then exit; act(AT_REPORT,'$n disappears suddenly!',false,ch,nil,nil,TO_ROOM); act(AT_REPORT,'You feel dizzy as you are transferred to another place...',false,ch,nil,nil,TO_CHAR); ch.fromRoom; ch.toRoom(room); act(AT_REPORT,'$n appears in a puff of smoke.',false,ch,nil,nil,TO_ROOM); interpret(ch,'look _AUTO'); end; procedure update_tracks; var node_room, node_track, node_tracknext : GListNode; room : GRoom; track : GTrack; begin node_room := room_list.head; while (node_room <> nil) do begin room := node_room.element; node_track := room.tracks.head; while (node_track <> nil) do begin node_tracknext := node_track.next; track := node_track.element; dec(track.life); if (track.life = 0) then begin room.tracks.remove(node_track); track.Free; end; node_track := node_tracknext; end; node_room := node_room.next; end; end; procedure update_teleports; var tele : GTeleport; room,dest : GRoom; node, node_next : GListNode; begin node := teleport_list.head; while (node <> nil) do begin tele := node.element; node_next := node.next; dec(tele.timer); if (tele.timer = 0) then begin room := tele.t_room; dest := findRoom(room.televnum); while (room.chars.getSize > 0) do teleportChar(room.chars.head.element, dest); teleport_list.remove(node); end; node := node_next; end; end; { procedure update_timers; var timer : GTimer; node, node_next : GListNode; begin node := timer_list.head; while (node <> nil) do begin timer := node.element; node_next := node.next; dec(timer.rounds); if (timer.rounds = 0) then begin timers.remove(node); if assigned(timer.spec_func) then timer.spec_func(timer.ch,timer.victim,timer.sn); timer.Free; end; node := node_next; end; end; } procedure battlegroundMessage; begin if (bg_info.prize<>nil) then to_channel(nil,pchar('[$B$7Battleground starting in '+inttostr(bg_info.count)+' seconds$A$7]'#13#10+ 'Allowed levels: '+inttostr(bg_info.lo_range)+ '-'+inttostr(bg_info.hi_range)+' Prize: '+ GObject(bg_info.prize).short^),CHANNEL_ALL,AT_REPORT) else to_channel(nil,pchar('[$B$7Battleground starting in '+inttostr(bg_info.count)+' seconds$A$7]'#13#10+ 'Allowed levels: '+inttostr(bg_info.lo_range)+ '-'+inttostr(bg_info.hi_range)),CHANNEL_ALL,AT_REPORT) end; procedure startBattleground; var conn : GConnection; node : GListNode; s,vnum:integer; begin to_channel(nil,pchar('[$B$7Battleground starting NOW!$A$7]'),CHANNEL_ALL,AT_REPORT); node := connection_list.head; while (node <> nil) do begin conn := node.element; if (conn.state=CON_PLAYING) and (conn.ch.player^.bg_status=BG_JOIN) and (conn.ch.level >= bg_info.lo_range) and (conn.ch.level <= bg_info.hi_range) then begin act(AT_REPORT,'You are transfered into the arena.',false,conn.ch,nil,nil,TO_CHAR); act(AT_GREEN,'Niet mokken, lekker knokken!',false,conn.ch,nil,nil,TO_CHAR); s:=random(ROOM_VNUM_ARENA_END-ROOM_VNUM_ARENA_START+1)+ROOM_VNUM_ARENA_START; vnum:=URange(ROOM_VNUM_ARENA_START,s,ROOM_VNUM_ARENA_END); conn.ch.player^.bg_room:=conn.ch.room; conn.ch.fromRoom; conn.ch.toRoom(findRoom(vnum)); conn.ch.player^.bg_status:=BG_PARTICIPATE; interpret(conn.ch,'look'); end; node := node.next; end; end; procedure update_battleground; var s:integer; last:GCharacter; conn : GConnection; node : GListNode; begin { battleground is running, check to see if we have a winner } if (bg_info.count=0) then begin last:=nil; s:=0; node := connection_list.head; while (node <> nil) do begin conn := node.element; if (conn.state=CON_PLAYING) and (conn.ch.player^.bg_status=BG_PARTICIPATE) then begin inc(s); last:=conn.ch; end; node := node.next; end; if s=0 then begin to_channel(nil,pchar('[$B$7Battleground stopped without a winner.$A$7]'),CHANNEL_ALL,AT_REPORT); bg_info.count:=-1; end else if s=1 then begin to_channel(nil,pchar('[$B$3'+last.name^+'$B$7 has won the battleground!$A$7]'),CHANNEL_ALL,AT_REPORT); act(AT_REPORT,'Congratulations! You have won the battleground!',false,last,nil,nil,TO_CHAR); inc(last.player^.bg_points,3); last.fromRoom; last.toRoom(last.player^.bg_room); if (bg_info.prize<>nil) then begin act(AT_REPORT,'You have won $p.',false,last,bg_info.prize,nil,TO_CHAR); GObject(bg_info.prize).toChar(last); end; interpret(last, 'look'); last.player^.bg_status:=BG_NOJOIN; last.point.hp:=last.point.max_hp; bg_info.winner:=last; bg_info.count:=-1; bg_info.prize:=nil; end; end; end; procedure update_objects; var obj : Gobject; rch : GCharacter; msg : string; at_temp : integer; node, node_prev : GListNode; begin try node := object_list.tail; while (node <> nil) do begin node_prev := node.prev; if (node_prev <> nil) and (node_prev.next <> node) then begin bugreport('update_objects', 'update.pas', 'obj.prev.next <> nil', 'The object list was linked incorrectly and could not be fixed.'); exit; end; obj := node.element; if (IS_SET(obj.flags, OBJ_NODECAY)) then begin node := node_prev; continue; end; if (obj.timer <= 0) then begin node := node_prev; continue; end; dec(obj.timer); if (obj.timer > 0) then begin node := node_prev; continue; end; case obj.item_type of ITEM_CORPSE : begin msg := '$p decays into dust and blows away.'; at_temp := AT_CORPSE; end; ITEM_BLOOD : begin msg := '$p dries up.'; at_temp := AT_RED; end; ITEM_FOOD : begin msg := '$p slowly rots away, leaving a foul stench.'; at_temp := AT_REPORT; end; else begin msg := '$p vanishes in the wink of an eye.'; at_temp := AT_REPORT; end; end; if (obj.carried_by <> nil) then act(at_temp, msg, false, obj.carried_by, obj, nil, TO_CHAR) else if (obj.room <> nil) then begin if (obj.room.chars.head <> nil) then rch := obj.room.chars.head.element else rch := nil; if (rch <> nil) and (not IS_SET(obj.flags, OBJ_HIDDEN)) then begin act(at_temp, msg, false, rch, obj, nil, TO_ROOM); act(at_temp, msg, false, rch, obj, nil, TO_CHAR); end; end; obj.extract; node := node_prev; end; except raise GException.Create('update.pas:update_objects', 'Memory failure'); end; end; end.