-+-+-+-+-+-+-+-+ START OF PART 8 -+-+-+-+-+-+-+-+ X MSLoss, ACLoss, DelayTime, NewDest : Integer := 0; X AttriGain, AttriLoss : Array`5B1..MaxPersonAttri`5D Of Integer := (0,0,0 V,0,0,0); X OldClass, NewClass : $UWord := 0; X OldCls, NewCls : EntityType; X Dummy1, Dummy2 : Integer := 0; X Dummy3, IsNpc : Boolean := False; X X Procedure TransEffect; X Begin X With Buffer.Effects`5BI`5D Do Begin X If Not Reverse Then X Case Effect Of X Eff_HURT : Damage := Damage + Parm1; X EFF_HEAL : Heal := Heal + Parm1; X EFF_G_GOLD : GoldGain := GoldGain + Parm1; X EFF_T_GOLD : GoldGain := GoldGain - Parm1; X EFF_G_ATTRI : AttriGain`5BParm1`5D := AttriGain`5BParm1`5D + Pa Vrm2; X EFF_G_MAXHEALTH : MHGain := MHGain + Parm1; X EFF_G_MAXMANA : MMGain := MMGain + Parm1; X EFF_G_MAXSPEED : MSGain := MSGain + Parm1; X EFF_G_AC : ACGain := ACGain + Parm1; X EFF_FREEZE : DelayTime := DelayTime + Parm1; X EFF_TELEPORT : NewDest := Parm1; X EFF_CHNG_CLS : If Parm1<>PersonBlk.Person.Class Then NewClass := V Parm1 X End X Else X Case Effect Of X Eff_HURT : Heal := Heal + Parm1; X EFF_HEAL : Damage := Damage + Parm1; X EFF_G_GOLD : GoldGain := GoldGain - Parm1; X EFF_T_GOLD : GoldGain := GoldGain + Parm1; X EFF_G_ATTRI : AttriLoss`5BParm1`5D := AttriLoss`5BParm1`5D + Pa Vrm2; X EFF_G_MAXHEALTH : MHLoss := MHLoss + Parm1; X EFF_G_MAXMANA : MMLoss := MMLoss + Parm1; X EFF_G_MAXSPEED : MSLoss := MSLoss + Parm1; X EFF_G_AC : ACLoss := ACLoss + Parm1; X End X End; (* with effect *) X End; X X Procedure HandleEffect; X Begin X With PersonBlk.Person Do Begin X If (Damage > 0) Then Begin X Tmp := (Damage - Rnd(ArmorClass)); X If (Stats`5BSTAT_DEFEND`5D) Then X Tmp := Round(Tmp*0.666); X If (Tmp >= Health) Then X Health := 0 X Else Health := Health - Tmp; X End; X If (GoldGain <> 0) Then Begin X Gold := Gold + GoldGain; X End; X If (Heal > 0) Then Begin X Tmp := Heal + Health; X If (Tmp >= Maxhealth) Then X Health := Maxhealth X Else Health := Tmp; X End; X For I := 1 To MaxPersonAttri Do Begin X If AttriGain`5BI`5D > 0 Then X Attributes`5BI`5D := Attributes`5BI`5D + AttriGain`5BI`5D; X If AttriLoss`5BI`5D > 0 Then Begin X If (AttriLoss`5BI`5D >= Attributes`5BI`5D) Then X Attributes`5BI`5D := 0 X Else Attributes`5BI`5D := Attributes`5BI`5D - AttriLoss`5BI`5D; X End; X End; X If MHGain > 0 Then Begin X Maxhealth := Maxhealth + MHGain; X End; X If MHLoss > 0 Then Begin X If MHLoss >= Maxhealth Then X Maxhealth := 0 X Else Maxhealth := Maxhealth - MHLoss; X End; X If MMGain > 0 Then Begin X Maxmana := Maxmana + MMGain; X End; X If MMLoss > 0 Then Begin X If MMLoss >= Maxmana Then X Maxmana := 0 X Else Maxmana := Maxmana - MMLoss; X End; X If MSGain > 0 Then Begin X Maxspeed := Maxspeed + MSGain; X End; X If MSLoss > 0 Then Begin X If MSLoss >= Maxspeed Then X Maxspeed := 0 X Else Maxspeed := Maxspeed - MSLoss; X End; X If ACGain > 0 Then Begin X ArmorClass := ArmorClass + ACGain; X End; X If ACLoss > 0 Then Begin X If ACLoss >= ArmorClass Then X ArmorClass := 0 X Else ArmorClass := ArmorClass - ACLoss; X End; X If (NewClass > 0) Then Begin X OldClass := Class; X Class := NewClass; X Group := NewCls.Group; X Home := NewCls.Homeroom; X End; X End; X End; X X Procedure PrintEffect; X Begin X If Print Then Begin X If (Damage > Heal) Then X PutLine('You feel some pain. ') X Else If (Heal > Damage) Then X PutLine('You feel healthier. '); X If (GoldGain > 0) Then X PutLine('You gained some gold. ') X Else If (GoldGain < 0) Then X PutLine('You''ve lost some gold. '); X If (NewClass > 0) Then PutLine('You are now a '+NewCls.Name+'.'); X For I := 1 To MaxPersonAttri Do Begin X If (AttriGain`5BI`5D > AttriLoss`5BI`5D) Then X PutLine('You gained some '+PersonAttriTable`5BI`5D+'.') X Else If (AttriLoss`5BI`5D > AttriGain`5BI`5D) Then X PutLine('You lost some '+PersonAttriTable`5BI`5D+'.'); X End; X If (MHGain > MHLoss) Then`20 X PutLine('You feel *healthier*.') X Else If (MHLoss > MHGain) Then X PutLine('Your health is damaged. '); X If (MMGain > MMLoss) Then X PutLine('You are magically enchanted. ') X Else If (MMLoss > MMGain) Then X PutLine('You are magically disenchanted. '); X If (MSGain > MSLoss) Then X PutLine('You feel faster. ') X Else If (MSLoss > MSGain) Then X PutLine('You feel slower. '); X If (ACGain > ACLoss) Then X PutLine('You feel more invulnerable. ') X Else If (ACLoss > ACGain) Then X PutLine('You feel more vulnerable. '); X End; X End; X XBegin X Read_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If (PersonBlk.Person.Health > 0) Then Begin X LoadBuffer(Ptr); X While (I < Buffer.Top) Do Begin X I := I + 1; X TransEffect; X End; X If (NewClass > 0) Then ReadEntity(NewClass, NewCls); X Get_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X HandleEffect; X Update_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X PrintEffect; X IsNpc := (Entity.Driver = 0); X If (NewClass > 0) Then Begin (* special case 1 *) X ReadEntity(OldClass, OldCls); X AffectPerson(Oldcls.ClassEffect, EntityId, Location, Entity, PersonBlk V, X Dummy1, Dummy2, Dummy3, Print, TRUE); X Dummy1 := 0; X Dummy2 := 0; X AffectPerson(NewCls.ClassEffect, EntityId, Location, Entity, PersonBlk V, X Dummy1, Dummy2, Dummy3, Print, FALSE); X End; X If (DelayTime > 0) Then Begin (* special case 2 *) X LogEvent(0, EntityId, EV_FREEZE, Location, '', IsNpc, DelayTime); X End; X If (NewDest > 0) Then Begin (* special case 3 *) X LogEvent(0, EntityId, EV_TELEPORT, Location, '', IsNpc, NewDest); X End; X If (PersonBlk.Person.Health = 0) Then Begin X DoDie(Entity, PersonBlk, ExpGained); X If Print Then PutLine('You are dead! '); X End; X WasDead := False; X End Else Begin X ExpGained := 0; X Damage := 0; X WasDead := True; X End; XEnd; X XEnd. $ CALL UNPACK M6.PAS;1 1848459334 $ create 'f' X`5BInherit('M1', 'M2', 'M3', 'M4', 'M5', 'M6'), X Environment('M7')`5D X XModule M7; X XConst X B_ROOM = 1; B_PERSON = 2; B_OBJECT = 3; B_SPELL = 4; B_EXIT = 5; X B_CLASS = 6; B_USER = 7; B_MEMORY = 8; X MaxBuild = 8; X XVar X BuildTable : Array`5B1..MaxBuild`5D Of Short_String_Type := ( X 'Room', 'Person', 'Object', 'Spell', 'Exit', 'Class', 'User', X 'Memory'); X X`5BExternal, Hidden`5D XProcedure ChangeMemory(Var S : String_Type; Where : $UWord); XExternal; X XFunction Short(S : String_Type): Short_String_Type; XBegin X If (S.Length <= 20) Then X Short := S X Else Short := SubStr(S, 1, 20); XEnd; X X`5BHidden`5D XFunction CanLink(Loc, Dir : $UWord): Boolean; XVar Entity : EntityType; Block : BlockType; XBegin X If (Dir > 0) Then Begin X ReadEntity(Loc, Entity); X Read_Record(FILE_BLOCK, Entity.RoomId, IAddress(Block)); X CanLink := (Block.Room.Exits`5BDir`5D = 0); X End Else CanLink := True; XEnd; X X`5BHidden`5D XProcedure LinkRooms(ExitId, FromLoc, ToLoc, FromDir, ToDir : $UWord); XVar Entity : EntityType; Block : BlockType; XBegin X If (FromDir > 0) Then Begin X ReadEntity(FromLoc, Entity); X Get_Record(FILE_BLOCK, Entity.RoomId, IAddress(Block)); X Block.Room.Exits`5BFromDir`5D := ExitId; X Update_Record(FILE_BLOCK, Entity.RoomId, IAddress(Block)); X End; X If (ToDir > 0) Then Begin X ReadEntity(ToLoc, Entity); X Get_Record(FILE_BLOCK, Entity.RoomId, IAddress(Block)); X Block.Room.Exits`5BToDir`5D := ExitId; X Update_Record(FILE_BLOCK, Entity.RoomId, IAddress(Block)); X End; XEnd; X XFunction ParsePeopleHere(Var Room : EntityType; Var S : String_Type; X Var Target : $UWord; SeeHidden, SeeInvisi : Boolean := False): Boolean; XVar Done : Boolean := False; Map : ItemMapType; XBegin X ParseLine(S, Target, TRUE, FALSE); X Read_Record(FILE_ITEMMAP, Room.RoomMapId, IAddress(Map)); X While Not Done Do Begin X ParseMap(Map, 0, POS_IN_ROOM); X ParseMap(Map, 0, POS_GUARD_N); X ParseMap(Map, 0, POS_GUARD_S); X ParseMap(Map, 0, POS_GUARD_E); X ParseMap(Map, 0, POS_GUARD_W); X ParseMap(Map, 0, POS_GUARD_U); X ParseMap(Map, 0, POS_GUARD_D); X If SeeHidden Then Begin X ParseMap(Map, 0, POS_HIDDEN); X End; X If SeeInvisi Then Begin X ParseMap(Map, 0, POS_INVISI); X End; X If (Map.Next > 0) Then X Read_Record(FILE_ITEMMAP, Map.Next, IAddress(Map)) X Else Done := True; X End; X ParsePeopleHere := ParseLine(S, Target, FALSE, TRUE); XEnd; X XFunction ParseObjHere(Var Room : EntityType; Var S : String_Type; X Var ObjId : $UWord; SeeHidden : Boolean := False): Boolean; XVar Done : Boolean := False; Map : ItemMapType; XBegin X ParseLine(S, ObjId, TRUE, FALSE); X Read_Record(FILE_ITEMMAP, Room.RoomMapId, IAddress(Map)); X While Not Done Do Begin X ParseMap(Map, 0, POS_OBJ_HERE); X If SeeHidden Then Begin X ParseMap(Map, 0, POS_OBJ_HIDE); X End; X If (Map.Next > 0) Then X Read_Record(FILE_ITEMMAP, Map.Next, IAddress(Map)) X Else Done := True; X End; X ParseObjHere := ParseLine(S, ObjId, FALSE, TRUE); XEnd; X XProcedure Do_Change(Var S : String_Type; Where, MapId : $UWord); XVar Entity : EntityType; X Block : BlockType; X Cmd, EntityId : $UWord := 0; X X Procedure ChangeRoom; X Const X R_Alias = 1; R_Desc_M = 2; R_Desc_E = 3; R_Desc_Mc = 4; R_Env = 5; X MaxRoomOpt = 5; X Var X RoomOptTable : Array`5B1..MaxRoomOpt`5D Of Short_String_Type := ( X 'exit alias', 'main description', 'exit description', 'magic descriptio Vn', X 'environment'); X Opt : $UWord := 0; X Begin X If GrabEntity('Room name? ', S, EntityId, ENTITY_ROOM) Then Begin X If GrabTable('Room option? ', RoomOptTable, S, Opt) Then Begin X ReadEntity(EntityId, Entity); X Read_Record(FILE_BLOCK, Entity.RoomId, IAddress(Block)); X Case Opt Of X R_Alias : PutLine('Not yet implmented. '); X R_Desc_M : EditDesc(Block.Room.MainDesc, S); X R_Desc_E : EditDesc(Block.Room.ExitDesc, S); X R_Desc_Mc : EditDesc(Block.Room.MagicDesc, S); X R_Env : PutLine('Not yet implmented. '); X End; X Update_Record(FILE_BLOCK, Entity.RoomId, IAddress(Block)); X End Else PutLine('Type ? for a list of room options. '); X End Else PutLine('No such room exist. '); X End; X X Procedure ChangePerson; X Begin X PutLine('Not yet implmented. '); X End; X X Procedure ChangeSpell; X Const X S_Spell_Effect = 1; S_Cast_Effect = 2; S_Flags = 3; S_Power = 4; X S_Kind = 5; MaxSpellOpt = 5; X Var X SpellOptTable : Array`5B1..MaxSpellOpt`5D Of Short_String_Type := ( X 'target effect', 'caster effect', 'flags', 'power', 'kind'); X Opt : $UWord := 0; X X Procedure GrabSpellFlags; X Begin X With Entity Do Begin X If GrabBoolean('Has area effect(T for true)? ', S) Then X SpellFlags`5BSP_AREA_EFF`5D := True X Else Begin X SpellFlags`5BSP_AREA_EFF`5D := False; X If GrabBoolean('Look for personal name(T for true)? ', S) Then X SpellFlags`5BSP_GET_PNAME`5D := True X Else Begin X SpellFlags`5BSP_GET_PNAME`5D := False; X If GrabBoolean('Look for object name(T for true)? ', S) Then X SpellFlags`5BSP_GET_ONAME`5D := True X Else SpellFlags`5BSP_GET_ONAME`5D := False; X End; X End; X If GrabBoolean('Look for direction(T for true)? ', S) Then Begin X SpellFlags`5BSP_GET_DIR`5D := True; X If GrabBoolean('Random direction(T for ture)? ', S) Then X SpellFlags`5BSP_RND_DIR`5D := True X Else SpellFlags`5BSP_RND_DIR`5D := False; X End Else SpellFlags`5BSP_GET_DIR`5D := False; X End; X End; X X Begin X If GrabEntity('Spell name? ', S, EntityId, ENTITY_SPELL) Then Begin X If GrabTable('Spell option? ', SpellOptTable, S, Opt) Then Begin X ReadEntity(EntityId, Entity); X Case Opt Of X S_Spell_Effect : EditEffect(Entity.SpellEffect, S); X S_Cast_Effect : EditEffect(Entity.CastEffect, S); X S_Flags : GrabSpellFlags; X S_Power : Entity.Power := GrabNumberW('Power? ', S); X S_Kind : If Not GrabTable('Kind? ', SpellKindTable, S, X Entity.SpellKind) Then X PutLine('Type ? for a list of spell kind. '); X End; X Update_Record(FILE_ENTITY, EntityId, IAddress(Entity)); X End Else PutLine('Type ? for a list of spell options. '); X End Else PutLine('Error parsing spell name. '); X End; X X Procedure ChangeObject; X Const X O_Kind = 1; O_Get_Effect = 2; O_Worn_Effect = 3; X O_Use_Effect = 4; O_Att_Effect = 5; X MaxObjOpt = 5; X Var X ObjOptTable : Array`5B1..MaxObjOpt`5D Of Short_String_Type := ( X 'kind', 'get effect', 'worn effect', 'use effect', 'attack effect'); X Opt : $UWord := 0; X NodeIn : EntityType; X Begin X While (S.Length = 0) Do GrabLine('Object name? ', S); X ReadEntity(Where, NodeIn); X If ParseObjHere(NodeIn, S, EntityId, TRUE) Then Begin X If GrabTable('Object option? ', ObjOptTable, S, Opt) Then Begin X ReadEntity(EntityId, Entity); X Case Opt Of X O_Kind :`20 X If GrabTable('Object kind? ', ObjKindTable, S, Entity.ObjKind) Th Ven X PutLine('Done. ') X Else PutLine('Type ? for a list of object kind.'); X O_Get_Effect : EditEffect(Entity.GetEffect, S); X O_Worn_Effect : EditEffect(Entity.WornEffect, S); X O_Use_Effect : EditEffect(Entity.UseEffect, S); X O_Att_Effect : EditEffect(Entity.AttEffect, S); X End; X Update_Record(FILE_ENTITY, EntityId, IAddress(Entity)); X End Else PutLine('Type ? for list of object options. '); +-+-+-+-+-+-+-+- END OF PART 8 +-+-+-+-+-+-+-+-