Up to Main Index                            Up to Journal for August, 2021

                     JOURNAL FOR SUNDAY 15TH AUGUST, 2021
______________________________________________________________________________

SUBJECT: Automatic doors update + holding/wearing/wielding progress
   DATE: Sun 15 Aug 20:56:49 BST 2021

Time for another update, this time quite a small one.

I had an interesting time coding yesterday, making doors automatically open or
close depending on whether RESET and/or JITTER attributes were set for a DOOR
field. Not exactly exciting stuff, however…

I started by adding Blocker events, doors are implemented as general direction
blockers. Then I added some code to the OPEN and CLOSE commands to schedule or
cancel the Blocker events depending on whether the door was opened or closed
and what its initial state was. All good so far, and it worked. But, that
looked like a lot of code for a simple task.

I took a look at the Blocker event and tried to work out how to generalise the
event to make it more useful. Also I could see there being a lot of events and
event handlers in the future without some general event handling.

What I came up with is working and generalised, but could still be improved.

My solution was to turn the Blocker event into a Trigger event. An item can
say what type of trigger it is by setting Thing.As[TriggerType]. This does
mean there is only one trigger type per item for now. In the future the
trigger could be made a Thing.Any[TriggerType] or multiple eventKey could be
mapped to the Trigger event. Not sure which was to go yet as it’s not needed
right now, but there are options that can be explored.

Anyway, now the tavern door is work as it was previously:


  [Street between tavern and bakers]
  You are on a well kept cobbled street. Buildings loom up on either side of
  you. To the east the smells of a bakery taunt you. To the west the entrance
  to a tavern. A sign outside the tavern proclaims it to be the "Dragon's
  Breath". The street continues to the north and south.

  You see exits: north, east, south, west
  >examine door
  You examine the tavern door.
  This is a sturdy wooden door with a simple latch. It is closed.
  >open door
  You open the tavern door.
  >exam door
  You examine the tavern door.
  This is a sturdy wooden door with a simple latch. It is open.
  >
  :
  Time passess...
  :
  the tavern door closes.
  >


Thrilling stuff eh? Well no… but there is now a general Trigger event that can
be used to extinguish spent torches and lights, expire poisons and… well other
stuff in the future :P

I spent the rest of yesterday and today implementing bodies and items that can
be held, worn or wielded. So far I can wear and wield items:


  >inv
  You are carrying:
    a longsword
    a dagger
    a cotton shirt
    some cotton trousers
    a plain belt
  1>wear shirt trousers belt
  You wear a cotton shirt.
  You wear some cotton trousers.
  You wear a plain belt.
  >wield sword dagger
  You wield a longsword.
  You wield a dagger.
  >inv
  You are carrying:
    a longsword (wielded)
    a dagger (wielded)
    a cotton shirt (worn)
    some cotton trousers (worn)
    a plain belt (worn)
  >


However the codes is a horrible mess, can panic and is duplicated to handle
holding, wearing and wielding. Holding items panic as some special handling is
required, which is yet unwritten. However it is using and freeing body slots
correctly — as long as I don’t try using something than I’m already using or
removing something that I’m not using.

The code for body slot handling is actually short and sweet:


  func allocSlots(have, want []string) (rem []string) {
    if len(want) == 0 {
      return have
    }
    sort.Strings(have)
    sort.Strings(want)
    x := 0
    for y, had := range have {
      if want[x] == had {
        x++
        if x == len(want) {
          rem = append(rem, have[y+1:]...)
          return rem
        }
      } else {
        rem = append(rem, had)
      }
    }
    return have
  }


Given a string slice of body slots that are available and slice of slots an
item needs to be used it returns the remaining slots. To use an item, in this
case wielding it, we can do:


  rem := allocSlots(s.actor.Any[BodySlots], what.Any[Wield])
  if len(rem) != len(s.actor.Any[BodySlots]) {
    s.actor.Any[BodySlots] = rem
    s.actor.Any[BodyUsed] = append(s.actor.Any[BodyUsed], what.Any[Wield]...)
  }


To stop wielding we just allocate the slots back again:


  rem := allocSlots(s.actor.Any[BodyUsed], what.Any[Wield])
  if len(rem) != len(s.actor.Any[BodyUsed]) {
    s.actor.Any[BodyUsed] = rem
    s.actor.Any[BodySlots] = append(s.actor.Any[BodySlots], what.Any[Wield]...)
  }


Looking at that code now, this as I write, I can probably do away with the
need for having Any[BodyUsed] and just use Any[Wield] which is nice :)

Anyway, the changes for holding/wearing/wielding items is in a mess, causing
panics and still under development. This means only the automatic doors and
Trigger event changes have been pushed out to the public experiment branch
with the rest to follow quite soon, quite soonish…

--
Diddymus


  Up to Main Index                            Up to Journal for August, 2021