Skip to content

Instantly share code, notes, and snippets.

@GreenReaper
Last active January 8, 2025 15:43
Show Gist options
  • Save GreenReaper/fdf48ec09ec295ea9d1c29ea30fcb6b8 to your computer and use it in GitHub Desktop.
Save GreenReaper/fdf48ec09ec295ea9d1c29ea30fcb6b8 to your computer and use it in GitHub Desktop.
A configurable ambient noises script for Wolfery.com
// noises.ts - Configurable activity-based ambiance
// Copyright © 2024 Laurence "GreenReaper" Parry <[email protected]>
// A room script for Mucklet by Accipiter Nisus <[email protected]>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
const FORM_FEED = String.fromCodePoint(0xC)
export function onActivate(): void {
Room.listen()
}
// Required because AS doesn't support closures yet
function reduceList(acc: string, cur: string, index: i32, self: Array<string>) : string {
return acc += '\n' + index.toString() + ': ' + cur
}
export function onRoomEvent(addr: string, ev: string): void {
// We use this later so get it regardless
let noisesString = Store.getString('list')
if (noisesString) {
let chance = getStoredU32('chance')
if (chance > 0 && 0 == u32(Math.floor(Math.random() * chance))) {
let nonetill = getStoredI64('nonetill')
let now = Date.now()
if (nonetill <= now) {
let sleep = getStoredU32('sleep')
let noises = noisesString.split(FORM_FEED)
// Can always post to self
setStoredI64('nonetill', now + getStoredU32('delay') * 1000) // in ms
Script.post("#", noises[u32(Math.floor(Math.random() * noises.length))], null, sleep * 1000)
}
}
}
// Handle commands
const eventType = Event.getType(ev)
if ('ooc' != eventType) return
// Handle the ooc event
const ooc = JSON.parse<Event.OOC>(ev)
const msg = ooc.msg.split(' ', 3)
if ('noises' != msg[0]) return
const puppeteer = ooc.puppeteer
if (Room.canEdit(ooc.char.id) || (puppeteer && Room.canEdit(puppeteer.id))) {
if (1 == msg.length) {
printUsage()
return
}
if ('list' == msg[1]) {
if (noisesString) {
let noises = noisesString.split(FORM_FEED)
let list = 'noises: ' + noises.length.toString() + ' in list:' // + noisesString
// Handle lists > ~2000 char describe limit
let toPrint = noises.reduce<string>(reduceList, list)
for (let len = toPrint.length; len > 2000; len = toPrint.length) {
let cutAt = toPrint.lastIndexOf('\n', 2000)
Room.describe(toPrint.slice(0, cutAt))
toPrint = toPrint.slice(cutAt + 1)
}
Room.describe(toPrint)
} else {
Room.describe('noises: empty list')
}
} else if ('chance' == msg[1] || 'delay' == msg[1] || 'sleep' == msg[1]) {
var value: u32
if (2 == msg.length) {
value = getStoredU32(msg[1])
} else {
value = U32.parseInt(msg[2])
setStoredU32(msg[1], value)
}
Room.describe('noises: ' + msg[1] + ': ' + value.toString())
} else if ('add' == msg[1] && 3 == msg.length) {
let index = <i32>0
// Because split() stops after the last selected group
let noise = ooc.msg.slice(ooc.msg.indexOf('add') + 4)
if (noisesString) {
var noises = noisesString.split(FORM_FEED)
index = noises.length
noisesString += FORM_FEED + noise
} else {
noisesString = noise
}
Store.setString('list', noisesString)
Room.describe(index.toString() + ': ' + noise)
} else if (0 == msg[1].indexOf('del') && 3 == msg.length) { // 'delay' handled first
if (noisesString) {
let index = U32.parseInt(msg[2])
noises = noisesString.split(FORM_FEED)
if (index < <u32>noises.length) {
Room.describe('~~' + index.toString() + ': ' + noises.splice(index, 1)[0] + '~~')
Store.setString('list', noises.join(FORM_FEED))
} else {
Room.describe('noises: out of range (' + index.toString() + ' > ' + (noises.length - 1).toString() + ')')
}
} else {
Room.describe('noises: none to delete')
}
} else {
printUsage()
}
} else {
Room.describe('noises: Character [puppeteer] must be room owner')
}
}
export function onMessage(addr: string, topic: string, data: string): void {
Room.describe(topic)
}
function getStoredU32(key: string) : u32 {
let valueBuffer = Store.getBuffer(key)
if (valueBuffer && sizeof<u32>() == valueBuffer.byteLength) {
return Uint32Array.wrap(valueBuffer)[0]
}
return 0
}
function getStoredI64(key: string) : i64 {
let valueBuffer = Store.getBuffer(key)
if (valueBuffer && sizeof<i64>() == valueBuffer.byteLength) {
return Int64Array.wrap(valueBuffer)[0]
}
return 0
}
function setStoredU32(key: string, value: u32) : void {
let valueArray = new Uint32Array(1)
valueArray[0] = value
Store.setBuffer(key, valueArray.buffer)
}
function setStoredI64(key: string, value: i64) : void {
let valueArray = new Int64Array(1)
valueArray[0] = value
Store.setBuffer(key, valueArray.buffer)
}
function printUsage(): void {
Room.describe(`Usage: \`ooc noises list\` — list current noises
\`ooc noises add <text>\` — add noise to the end of the list
\`ooc noises del[ete] <n>\` — delete noise at index n
\`ooc noises chance [<n>]\` — get/set 1/n chance for message to trigger a noise
\`ooc noises delay [<n>]\` — get/set seconds to delay until allowing a new trigger
\`ooc noises sleep [<n>]\` — get/set seconds from trigger to noise`)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment