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