-+-+-+-+-+-+-+-+ START OF PART 12 -+-+-+-+-+-+-+-+ X +Obj.Name+'.'); X AffectPerson(Obj.GetEffect, EntityId, Where, Entity, PersonBlk, X Dummy1, Dummy2, Dummy3, Print, FALSE); X End Else Begin X PutToken(What, Where, NodeIn.RoomMapId, OldPos, TRUE); X If Print Then PutLine('You can''t hold any more objects. '); X End; X End Else If Print Then PutLine('Someone else got it before you. '); X End Else LogEvent(EntityId, 0, EV_INFORM, Where, X Entity.Name+' fail to get a(n) '+Obj.Name+'.'); XEnd; X XProcedure GetGold(Var Entity, NodeIn : EntityType; X Var PersonBlk, RoomBlk : BlockType; X EntityId, Where : $UWord; Amount : Integer; X Print : Boolean); XBegin X Get_Record(FILE_BLOCK, NodeIn.RoomId, IAddress(RoomBlk)); X If (RoomBlk.Room.Goldhere >= Amount) Then Begin X RoomBlk.Room.Goldhere := RoomBlk.Room.Goldhere - Amount; X Update_Record(FILE_BLOCK, NodeIn.RoomId, IAddress(RoomBlk)); X Get_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X PersonBlk.Person.Gold := PersonBlk.Person.Gold + Amount; X Update_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If Print Then PutLine('got it! '); X LogEvent(EntityId, 0, EV_INFORM, Where, Entity.Name+' took some gold. ') V; X End Else Begin X Free_Record(FILE_BLOCK); X If Print Then PutLine('There isn''t that much gold here. '); X End; XEnd; X XProcedure DropObj(Var Entity, NodeIn : EntityType; X Var PersonBlk : BlockType; X EntityId, Where, What : $UWord; X Print : Boolean := False); XVar Obj : EntityType; X OldPos : $UWord := 0; X Dummy1, Dummy2 : Integer := 0; X Dummy3 : Boolean := False; XBegin X ReadEntity(What, Obj); X If Not HaveEffect(Obj.GetEffect, Entity, PersonBlk, Print, TRUE) Then Begi Vn X If TakeToken(What, Entity.InvenId, OldPos) Then Begin X PutToken(What, Where, NodeIn.RoomMapId, POS_OBJ_HERE, TRUE); X If Print Then PutLine('You dropped a(n) '+Obj.Name+'.'); X LogEvent(EntityId, 0, EV_INFORM, Where, Entity.Name+' dropped a(n) ' X +Obj.Name+'.'); X AffectPerson(Obj.GetEffect, EntityId, Where, Entity, PersonBlk, X Dummy1, Dummy2, Dummy3, Print, TRUE); X End Else If Print Then PutLine('You are not holding '+Obj.Name+'.'); X End Else LogEvent(EntityId, 0, EV_INFORM, Where, X Entity.Name+' fail to drop a(n) '+Obj.Name+'.'); XEnd; X XProcedure DropGold(Var Entity, NodeIn : EntityType; X Var PersonBlk, RoomBlk : BlockType; X EntityId, Where : $UWord; Amount : Integer; X Print : Boolean; X Prived : Boolean := False); XBegin X Get_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If (PersonBlk.Person.Gold >= Amount) Then Begin X PersonBlk.Person.Gold := PersonBlk.Person.Gold - Amount; X Update_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X Get_Record(FILE_BLOCK, NodeIn.RoomId, IAddress(RoomBlk)); X RoomBlk.Room.Goldhere := RoomBlk.Room.Goldhere + Amount; X Update_Record(FILE_BLOCK, NodeIn.RoomId, IAddress(RoomBlk)); X If Print Then PutLine('dropped. '); X LogEvent(EntityId, 0, EV_INFORM, Where, Entity.Name+' dropped some gold. V '); X End Else If Prived Then Begin X Free_Record(FILE_BLOCK); X Get_Record(FILE_BLOCK, NodeIn.RoomId, IAddress(RoomBlk)); X RoomBlk.Room.Goldhere := RoomBlk.Room.Goldhere + Amount; X Update_Record(FILE_BLOCK, NodeIn.RoomId, IAddress(RoomBlk)); X If Print Then PutLine('You create some gold here. '); X LogEvent(EntityId, 0, EV_INFORM, Where, Entity.Name+' create some gold. V '); X End Else Begin X Free_Record(FILE_BLOCK); X If Print Then PutLine('You don''t have that much gold. '); X End; XEnd; X XProcedure TakeObj; XBegin XEnd; X XProcedure AttackPerson(Var Attk, Targ, NodeIn : EntityType; X Var PersonBlk : BlockType; Attker, Target, Loc : $UWord; Print : Boolean); XVar Damage, OldPos : $UWord; XBegin X GetLocation(Attker, Loc, OldPos); (* I only need oldpos *) X If (OldPos = POS_HIDDEN) Then Begin X ChangeMapPos(Attker, Loc, NodeIn.RoomMapId, POS_IN_ROOM); X If Print Then PutLine('You attack '+Targ.Name+' from under the shadow! ' V); X End Else If (OldPos = POS_INVISI) Then Begin X ChangeMapPos(Attker, Loc, NodeIn.RoomMapId, POS_IN_ROOM); X If Print Then PutLine('You attack '+Targ.Name+' from thin air! '); X End Else If Print Then DescAttack('You', Targ.Name); X With PersonBlk.Person Do Begin X Damage := (Attributes`5BATT_STR`5D + Attributes`5BATT_DEX`5D) Div 12; X If (Stats`5BSTAT_DEFEND`5D) Then X Freeze( 600.0 / MaxSpeed, Attker) X Else Freeze( 400.0 / MaxSpeed, Attker); X LogEvent(Attker, Target, EV_ATTACK, Loc, '', (Targ.Driver = 0), X Damage, Weapon); X If (Targ.Driver = 0) Then X UpdateEnemyList(Target, targ); X End; XEnd; X XProcedure WieldWeapon(Var Entity, Obj : EntityType; X Var PersonBlk : BlockType; X EntityId, Where, What : $UWord; X Print : Boolean); XVar Dummy1, Dummy2 : Integer := 0; X Dummy3 : Boolean := False; XBegin X Read_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If (PersonBlk.Person.Weapon = 0) Then Begin X If (Not HaveEffect(Obj.WornEffect, Entity, PersonBlk, Print, FALSE)) The Vn Begin X If ChangeMapPos(What, EntityId, Entity.InvenId, POS_WEAPON) Then Begin X Get_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X PersonBlk.Person.Weapon := What; X Update_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If Print Then PutLine('You are now wielding a(n) '+Obj.Name+'.'); X AffectPerson(Obj.WornEffect, EntityId, Where, Entity, PersonBlk, X Dummy1, Dummy2, Dummy3, Print, FALSE); X End Else If Print Then X PutLine('You are not holding'+Obj.Name+'.'); X End; X End Else PutLine('You are already wielding another weapon. '); XEnd; X X`5BHidden`5D XFunction CanWear(Var PersonBlk : BlockType; X Var Obj: EntityType; X Var Slot : $UWord): Boolean; XBegin X Case Obj.ObjKind Of X OBJ_ARMOR : Slot := STAT_WORN_ARMOR; X Otherwise Slot := 0; X End; X If (Slot > 0) Then X CanWear := Not PersonBlk.Person.Stats`5BSlot`5D X Else CanWear := False; XEnd; X XProcedure WearArmor(Var Entity, Obj : EntityType; X Var PersonBlk : BlockType; X EntityId, Where, What : $UWord; X Print : Boolean); XVar Dummy1, Dummy2 : Integer := 0; X Dummy3 : Boolean := False; X Slot : $UWord := 0; XBegin X Read_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If CanWear(PersonBlk, Obj, Slot) Then Begin X If (Not HaveEffect(Obj.WornEffect, Entity, PersonBlk, Print, FALSE)) The Vn Begin X If ChangeMapPos(What, EntityId, Entity.InvenId, POS_ARMOR) Then Begin X Get_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X PersonBlk.Person.Stats`5BSlot`5D := True; X Update_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If Print Then PutLine('You are now wearing a(n) '+Obj.Name+'.'); X AffectPerson(Obj.WornEffect, EntityId, Where, Entity, PersonBlk, X Dummy1, Dummy2, Dummy3, Print, FALSE); X End Else If Print Then X PutLine('You are not holding'+Obj.Name+'.'); X End; X End Else PutLine('You are wearing something else. '); XEnd; X XProcedure TakeoffObj(Var Entity, Obj : EntityType; X Var PersonBlk : BlockType; X EntityId, Where, What : $UWord; X Print : Boolean); XVar Dummy1, Dummy2 : Integer := 0; X Dummy3 : Boolean := False; X Slot : $UWord := 0; XBegin X If Not HaveEffect(Obj.WornEffect, Entity, PersonBlk, Print, TRUE) Then Beg Vin X If ChangeMapPos(What, EntityId, Entity.InvenId, POS_INVEN) Then Begin X Get_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If (PersonBlk.Person.Weapon <> What) Then Begin X CanWear(PersonBlk, Obj, Slot); X If (Slot > 0) Then X PersonBlk.Person.Stats`5BSlot`5D := FALSE; X End Else PersonBlk.Person.Weapon := 0; X Update_Record(FILE_BLOCK, Entity.PersonId, IAddress(PersonBlk)); X If Print Then PutLine('You take off '+Obj.Name+'.'); X AffectPerson(Obj.WornEffect, EntityId, Where, Entity, PersonBlk, X Dummy1, Dummy2, Dummy3, Print, TRUE); X End Else PutLine('You are not wielding '+Obj.Name+'.'); X End; XEnd; X XFunction GetExitDest(Var NodeIn : EntityType; X From, Dir : $UWord; X Var Dest : $UWord): Boolean; XVar RoomBlk : BlockType; X AnExit : ExitType; XBegin X ReadBlock(NodeIn.RoomId, RoomBlk); X If (RoomBlk.Room.Exits`5BDir`5D > 0) Then Begin X ReadExit(RoomBlk.Room.Exits`5BDir`5D, AnExit); X If (AnExit.Node`5B1`5D = From) Then X Dest := AnExit.Node`5B2`5D X Else Dest := AnExit.Node`5B1`5D; X End Else Dest := 0; X GetExitDest := (Dest > 0); XEnd; X XProcedure CastSpell(Var Entity, NodeIn, Spell : EntityType; X Var PersonBlk : BlockType; X EntityId, Where, SpellId, Target, Dir : $UWord; X Print : Boolean); XVar Dummy1, Dummy2 : Integer := 0; X Dummy3, Done : Boolean := False; X TargEntity, RoomIn : EntityType; X Dest, I : $UWord := 0; X DriveIt : Boolean := False; XBegin X If Print Then Begin X If (Target <> ALL_TARGET) Then Begin X ReadEntity(Target, TargEntity); X If (Dir > 0) And (Spell.Power > 0) Then X PutLine('You cast a '+Spell.Name+' toward '+DirTable`5BDir`5D+' at ' V+ X TargEntity.Name+'! ') X Else PutLine('You cast a '+Spell.Name+' at '+TargEntity.Name+'! '); X If (TargEntity.Driver = 0) Then Begin X DriveIt := True; X UpdateEnemyList(Target, TargEntity); X End; X End Else Begin X If (Dir > 0) And (Spell.Power > 0) Then X PutLine('You cast a '+Spell.Name+' toward the '+DirTable`5BDir`5D+'! V ') X Else PutLine('You cast a '+Spell.Name+'! '); X End; X End; X Freeze(400.0/PersonBlk.Person.MaxSpeed, EntityId); X If (Dir > 0) Then Begin (* remote spell *) X LogEvent(EntityId, Target, EV_CAST, Where, '', False, SpellId, Dir, Wher Ve); X Dest := Where; X RoomIn := NodeIn; X While Not Done Do Begin X If GetExitDest(RoomIn, Dest, Dir, Dest) Then Begin X ReadEntity(Dest, RoomIn); X I := I + 1; X PutLine(Spell.Name+' flew '+DirTable`5BDir`5D+' into '+RoomIn.Name+' V. '); X LogEvent(EntityId, Target, EV_CAST, Dest, '', DriveIt, SpellId, X Dir, Where); X If (Spell.SpellFlags`5BSP_RND_DIR`5D) Then Dir := Rnd(5)+1; X Done := (I = Spell.Power); X End Else Done := True; X End; X End Else X LogEvent(EntityId, Target, EV_CAST, Where, '', DriveIt, SpellId, Dir, Wh Vere); X AffectPerson(Spell.CastEffect, EntityId, Where, Entity, PersonBlk, X Dummy1, Dummy2, Dummy3, Print, FALSE); XEnd; X XEnd. $ CALL UNPACK M9.PAS;1 1484175756 $ create 'f' X`5BInherit('M1','M2','M3','M4','M5','M6','M7','M7_2','M7_3','M9'), X Environment('M9_2')`5D X XModule M9_2; X X X(* NPC customization routines *) X XConst X NPC_ACT_GO_S = 1; X NPC_ACT_GO_N = 2; X NPC_ACT_GO_W = 3; X NPC_ACT_GO_E = 4; X NPC_ACT_GO_D = 5; X NPC_ACT_GO_U = 6;`20 X MaxNpcAct = 6; X XVar X NpcActTable : Array`5B1..MaxNpcAct`5D Of Short_String_Type := ( X 'South', 'North', 'West', 'East', 'Down', 'Up'); X X`5BGlobal`5D XProcedure ChangeMemory(Var S : String_Type; Where : $UWord); XConst X M_Bexp = 1; M_Bgold = 2; M_Ap = 3; M_Saying = 4; X MaxMemOpt = 4; XVar X MemOptTable : Array`5B1..MaxmemOpt`5D Of Short_String_Type := ( X 'Base experience', 'Base gold', 'Action points', 'Saying'); X Opt, EntityId : $UWord := 0; X NodeIn, Entity : EntityType; X Memory : MemoryType; X X Procedure EditSaying; X Begin X PutLine('Not yet implemented. '); X End; X X Procedure AddAp; X Var I, Pos, Act, Act2, Dir : $UWord := 0; X Done, Found : Boolean := False; X Begin X While not Found And Not Done Do Begin X I := I + 1; X Found := (Memory.ActPoints`5BI`5D.Where = 0); X Done := (I = MaxActPoints); X End; X If Found Then With Memory.ActPoints`5BI`5D Do Begin X If GrabEntity('Location? ', S, Where, ENTITY_ROOM) Then Begin X(* X If GrabTable('Likely position? ', PosTable, S, Pos) Then X Position := Pos; X *) X If GrabTable('Primary action? ', NpcActTable, S, Act) Then X Action := Act; X If GrabTable('Running action? ', NpcActTable, S, Act2) Then X RunAct := Act2; X If GrabTable('Forbidden direction? ', DirTable, S, Dir) Then X Outdir := Dir; X End Else PutLine('Not added. '); X End Else PutLine('Memory action points are used up. '); X End; X X Procedure DeleteAp; X Var Index : $UWord; X Begin X Index := GrabNumberW('Which action points? ', S); X If (Index > 0) And (Index < MaxActPoints) Then X Memory.ActPoints`5BIndex`5D.Where := 0 X Else PutLine('Out of range. '); X End; X X Procedure Listap; X Var I : $UWord; X L : String_Type := ''; X Entity : EntityType; X Begin X PutLine(DivLine+DivLine); X for I := 1 To MaxActPoints Do X If (Memory.ActPoints`5BI`5D.Where > 0) Then With Memory.ActPoints`5BI`5 VD Do Begin X WriteV(L, 'Action points ', I:0, ':'); X PutLine(L); X ReadEntity(Where, Entity); X PutLine('Location : '+Entity.Name); X(* X If (Position > 0) Then PutLine('Position : '+PosTable`5BPosition V`5D); X *) X If (Action > 0) Then PutLine('Action : '+NpcActTable`5BActio Vn`5D); X If (RunAct > 0) Then PutLine('Run Action : '+NpcActTable`5BRunac Vt`5D); X If (OutDir > 0) Then PutLine('Out Direction : '+DirTable`5BOutDir`5 VD); X PutLine(DivLine+DivLine); X End; X End; X X Procedure EditActionPoints; X Const X AP_Add = 1; AP_Delete = 2; AP_List = 3; AP_Quit = 4; MaxApOpt = 4; X Var X ApOptTable : Array`5B1..MaxApOpt`5D Of Short_String_Type := ( X 'Add', 'Delete', 'List', 'Quit'); X ApOpt : $UWord := 0; X Done : Boolean := False; X Begin X While Not Done Do Begin X If GrabTable('Edit ActionPoints> ', ApOptTable, S, ApOpt) Then X Case ApOpt Of X AP_Add : AddAp; X AP_Delete : DeleteAp; X AP_List : ListAp; X AP_Quit : Done := True; X End X Else PutLine('Type ? for a list of action points edit command. '); X End; X End; X XBegin X ReadEntity(Where, NodeIn); X If (S.Length = 0) Then GrabLine('Person name? ', S); X If ParsePeopleHere(NodeIn, S, EntityId) Then Begin X ReadEntity(EntityId, Entity); X If (Entity.MemoryId > 0) Then Begin +-+-+-+-+-+-+-+- END OF PART 12 +-+-+-+-+-+-+-+-