# Copyright 2003-2004 Kevin Reid. # This source code and related files are distributed under the MIT License, as described in the document named "License.txt" which should be provided with this source distribution. pragma.enable("explicit-result-guard") pragma.disable("no-dot-call") pragma.disable("easy-return") pragma.enable("accumulator") def := #def := #def := def lazy := def InteriorDelegate := lazy(fn{ }) def JPanel__quasiParser := lazy(fn{ }) #def Name := lazy(fn{ }) def buildIncrementalList := lazy(fn{ }) def description__quasiParser := lazy(fn{ }) def en := lazy(fn{ }) def jbo := lazy(fn{ }) def makeInspectorReference := lazy(fn{ }) def makeInterior := lazy(fn{ }) def makeRecognizer := lazy(fn{ }) def makeThing := lazy(fn{ }) def name__quasiParser := lazy(fn{ }) def promiseAllResolved := lazy(fn{ }) def makeCharacter { to __optUncall() :any { return [, "get", [meta.context().getFQNPrefix().split("$")[0]]] } to run([ => self := (def character; character), "super" => optSuper := null, "inventoryInterior" => charInventory := (def superArgs; def inventoryDelegate; lazy(fn{ makeInterior(inventoryDelegate, superArgs["owner"], superArgs["identityHolder"]) })), => recognizer := lazy(fn{ makeRecognizer("owner" => superArgs["owner"], "selfIdentity" => superArgs["identityHolder"].getIdentity()) }) ] | bind superArgs) :any { def outerSuper := if (optSuper != null) { optSuper } else { makeThing([=> self] | superArgs | ["name" => name`someone`, "description" => description`Looks human.`]) } var outputListeners := [].asSet() def output { match [v ? !v.startsWith("__"), a] { for l in outputListeners { E.send(l, v, a) } } } # FIXME: initialization race recognizer <- putNicknameGetter(def getNickname(id) :any { when (self.getOptTeriorVow(id)) -> done(terior) :any { if (terior != null) { terior <- getNickname() } } catch p { throw <- (p) null } }) bind inventoryDelegate implements InteriorDelegate { to __optSealedDispatch(brand) :any { switch (brand) { match ==((def sealer := self.getOwner().getUncallSealer()).getBrand()) { sealer.seal([E, "send", [character, "getInventoryInteriorDelegate", []]]) } match _ { null } } } to getName() :any { self.getName() } to lookFrom(contentInfo) :any { self.exterior_look() } to hear(extract) :void {} } bind character extends outerSuper { to __optUncall() :any { [makeCharacter, "run", [[=> self, => super, "inventoryInterior" => charInventory, => recognizer]]] } to __conformTo(guard) :any { if (guard.__respondsTo("isDenDetailGuard", 0) && guard.isDenDetailGuard()) { def outerPanel def superDetail := guard.sprout().coerce(super).getComponent() def recognizerIRef := makeInspectorReference.asStatic("recognizer", self.getRecognizer()) def inventoryDetail := charInventory.makeRealInspectorComponent() bind outerPanel := JPanel` $superDetail $recognizerIRef $inventoryDetail ` def detail { to isDenDetail() :any { true } to getComponent() :any { outerPanel } } } else { character } } to getRecognizer() :any { recognizer } to getInventoryInterior() :any { charInventory } to getInventoryInteriorDelegate() :any { inventoryDelegate } to addOutputListener(new) :void { outputListeners with= new } to getOptTeriorVow(searchIdentity) :any { if (character.getInventoryInterior().getContentInfosByIdentity().fetch(searchIdentity, fn{}) =~ contentInfo :notNull) { contentInfo.getExterior() } else if (searchIdentity == character.getExterior().getLocationIdentity()) { character.getExterior().getLocation() } else { def result var done := false def location := character.getExterior().getLocation() var lastBranchDebugId := 0 def formatIdentityList(l) :any { # this WOULD be a language-choice -IXME, but it's just debug info "[" + accum "" for x in l { _ + recognizer.getNameReporter(x, en, [].asMap()).get() + ", " } + "]" } def search(tree, pathSoFar) :any { def debugSerial := (lastBranchDebugId += 1) self.getOwner().trace("getOptTeriorVow", `$debugSerial tree=$tree psf=${formatIdentityList(pathSoFar)}`) when (tree) -> treeResolved(_) :any { self.getOwner().trace("getOptTeriorVow", `$debugSerial resolved`) if (done) { return } promiseAllResolved( accum [] for id => subtreeVow in tree { _.with( def pathMore := pathSoFar + [id] if (id == searchIdentity) { self.getOwner().trace("getOptTeriorVow", `$debugSerial found it ${formatIdentityList(pathMore)}`) bind result := location <- getOptDeepContentExterior(pathMore) done := true return } else { search <- run(subtreeVow, pathMore) } )} ) } catch p { throw(p) } } when ( search <- run(location <- getVisibleContentsTreeReporter() <- get(), []) ) -> searchDone(_) :void { self.getOwner().trace("getOptTeriorVow", `search resolved: result=$result`) if (!done) { bind result := null } } catch p { self.getOwner().trace("getOptTeriorVow", `search broken: $p`) bind result := Ref.broken(p) } result } } to exterior_look() :any { def [_, append, finish] := buildIncrementalList() append.splice(super.exterior_look()) def items := charInventory.getContentsList() if (items !~ []) { append(description`%?(en:Carrying:%|jbo:.i ti ralte ge`) for info in items { append(description` %?(en:%|jbo:gi %)${info.getIdentity()}:i;`) } } finish() } to exterior_getOptCommandImplementation(cmd :List) :any { # FIXME: this is just a quick test case. it is *wrong* because it ties the action (whispering) implementation to a particular human interface (command syntax); NPCs and GUIs would find this less useful. def selfId := self.getIdentityHolder().getIdentity() if (cmd =~ [[`string`, `whisper`], _, [`keyword`, `to`], [`thing`, ==selfId]]) { def whisperImpl(contextBox, from, [[`string`, `whisper`], [`string`, what], [`keyword`, `to`], [`thing`, ==selfId]]) :vow[void] { when (from.getRcvr() <- getCommandContextUnsealer() <- unseal(contextBox)) -> done(context) :void { def msg := description`%?(en:$from:I; %!:(whispers) to $selfId:d;, "$what;"%|jbo:$from:i; smaji bacru cusku ${jbo.quoteText(what, false, null)}; $selfId:i;%)$\n` output(msg) context <- getMsgOutputFunc() <- (msg) } catch p { throw(p) } } } } to exterior_hear(extract) :void { output(extract) super.exterior_hear(extract) if ( extract =~ [ "assertionsMerged" => [ "org.cubik.den.arrival" => [ (self.getExterior().getLocationInfo().getIdentity()) => \ [arrival, sealedAssertions] ] |_ ] |_ ] |_ ) { # if we wanted to verify the assertion: locIdentity.getRcvr() <- getEventAssertionUnsealer() <- unseal(optSealedAssertions) <- get("org.cubik.den.arrival") == optArrival # (fixme: write a util function to verify assertions) # but this is harmless so we don't bother checking recognizer.hintRelevantIdentity(arrival) } } #end to hear to exterior_didChangeLocation() :void { when (self.getExterior().getLocation() <- getContentIdentities()) -> doneNeighbors(ids) :void { for id in ids { recognizer.hintRelevantIdentity(id) } } catch _ {} } to interact_moveInto([[inModes, outModes], optAllegedActor], entrance, options) :vow[void] { throw("not moving") } } #end bind character } #end run(self, params) } ? def makeCharacter := # value: ?# fixme: more updoc