A new candy themed wonderland

I have noticed that there isn’t, (as far as I’ve been able to find at least) a candy or sweet inspired zone. A wonderful world made entirely out of candy. There are plenty of examples of settings like this in other media, and I’ve certainty taken inspiration from several of them in building a new zone.

I would like to have the entry point connect to the train grey line. Or perhaps a new train line if the current one is deemed too full. I have already built the entry point with that in mind, an underground station with a portal taking visitors to the more colorful candy world.

I should likely point out, considering the recent topic that has been ongoing, that while candy and children might go hand and hand… My intent here is not for an ageplay focused zone, but rather one as many people might enjoy as possible. Something with a sticky, sweet, and sensual atmosphere for patrons to enjoy themselves. (But for those ageplayers out there who would also want to enjoy a candy world, I do hear you too, and have set aside an area where that will be allowed, it’s just off to the side.)

I was having trouble coming up with a name for the zone for a while, and despite there being a board game with the same name, I think Candy Land is still the most fitting name for the zone. I even looked into copywrite laws on the subject, and since it is an RP zone and not a board game, and doesn’t contain any of the characters or areas or images used in the game (and honestly, only it being a candy world and the shared name, has nothing to do with the board game Candy Land) It should be fine. But if this is still a concern I can come up with another name instead.

Room ID: #cve7ile9gbrn4oksio50

6 Likes

This zone is now linked to the Sinder Train Station and is available to check out!

4 Likes

I don’t know much about scripting, but would it be possible to switch a room’s profile on specific days of the year automatically?

1 Like

The answer for that is: Yes, it is possible

For inspiration, one may look at the script example that switches between room profiles based on day/night:

Of course, it is not the same as specific dates, but with t.getUTCDate(), t.getUTCMonth(), and t.getUTCFullYear(), you can determine the time and calculate when the next profile switch will take place.

2 Likes

Thank you! I will have my wife look at that later, as she would actually understand it!

2 Likes

Okay. I played with the day-night and managed to get one to do seasonal…

But then Marilu wanted … more. So much more. So more she will have. I present a seasonal profile (and some debugging text to remove once you’re happy with it). Maybe it could help with Sinder Park’s changes or who knows. :slight_smile:

// =====================
// 1️⃣ JSON type definitions
// =====================
@json
class HolidayEntry {
  key!: string;
  value!: string;
}

@json
class HolidayRange {
  name!: string;
  startMonth!: i32;
  startDay!: i32;
  endMonth!: i32;
  endDay!: i32;
}

@json
class Season {
  name!: string;
  startMonth!: i32;
  startDay!: i32;
  endMonth!: i32;
  endDay!: i32;
}

@json
class CalendarData {
  holidays!: HolidayEntry[];
  holidayRanges!: HolidayRange[];
  seasons!: Season[];
}

// =====================
// 2️⃣ Embedded JSON data
// =====================
const calendarDataText = `
{
  "holidays": [
    { "key": "1-1", "value": "new-years-day" },
    { "key": "2-14", "value": "valentines-day" },
    { "key": "10-31", "value": "halloween-day" },
    { "key": "12-25", "value": "christmas-day" }
  ],
  "holidayRanges": [
    { "name": "halloween", "startMonth": 10, "startDay": 1, "endMonth": 10, "endDay": 31 },
    { "name": "wonderland", "startMonth": 12, "startDay": 20, "endMonth": 12, "endDay": 31 }
  ],
  "seasons": [
    { "name": "winter", "startMonth": 12, "startDay": 21, "endMonth": 3, "endDay": 19 },
    { "name": "spring", "startMonth": 3, "startDay": 20, "endMonth": 6, "endDay": 20 },
    { "name": "summer", "startMonth": 6, "startDay": 21, "endMonth": 9, "endDay": 21 },
    { "name": "autumn", "startMonth": 9, "startDay": 22, "endMonth": 12, "endDay": 20 }
  ]
}
`;

// =====================
// 3️⃣ Global state
// =====================
let data: CalendarData | null = null;
let holidayMap: Map<string, string> = new Map();

// =====================
// 4️⃣ Logic helpers
// =====================
function isDateInRange(month: i32, day: i32, startM: i32, startD: i32, endM: i32, endD: i32): bool {
  if (startM == endM) return month == startM && day >= startD && day <= endD;
  if (month > startM && month < endM) return true;
  if (month == startM && day >= startD) return true;
  if (month == endM && day <= endD) return true;
  return false;
}

function getCalendarEvent(month: i32, day: i32): string {
  if (data == null) return "an unknown time";

  const d = changetype<CalendarData>(data);
  const key = `${month}-${day}`;
Room.describe(`Date: ${key}`);
  if (holidayMap.has(key)) {
    const single = holidayMap.get(key);
    if (single) return single;
  }
  for (let i = 0; i < d.holidayRanges.length; i++) {
    const hr = d.holidayRanges[i];
    if (isDateInRange(month, day, hr.startMonth, hr.startDay, hr.endMonth, hr.endDay)) {
      return hr.name;
    }
  }

  for (let i = 0; i < d.seasons.length; i++) {
    const s = d.seasons[i];
    if (isDateInRange(month, day, s.startMonth, s.startDay, s.endMonth, s.endDay)) {
      return s.name;
    }
  }

  return "an ordinary day";
}

// =====================
// 5️⃣ Lifecycle
// =====================
export function onActivate(): void {
  if (data == null) {
    data = changetype<CalendarData>(JSON.parse<CalendarData>(calendarDataText));

    // Build map
    const d = changetype<CalendarData>(data);
    holidayMap = new Map<string, string>();
    for (let i = 0; i < d.holidays.length; i++) {
      const h = d.holidays[i];
      holidayMap.set(h.key, h.value);
    }

    Room.describe(
      `[Calendar] Loaded ${holidayMap.size.toString()} holidays, ` +
      `${d.holidayRanges.length.toString()} holiday ranges, and ` +
      `${d.seasons.length.toString()} seasons.`
    );
  }

  const now = new Date(Date.now());
  const month = now.getUTCMonth() + 1;
  const day = now.getUTCDate();
  const result = getCalendarEvent(month, day);
  Room.describe(`You step into the room on ${result}.`);
  Room.useProfile(result);

  const msUntil = scheduleNextUpdate(now);
  const hours = (msUntil / (1000 * 60 * 60)).toString();
  Room.describe(`[Calendar] Next update scheduled in ${hours} hours.`);
}

export function onMessage(addr: string, topic: string, dataMsg: string | null, sender: string): void {
  if (topic == "change") {
    onActivate();
  }
}

// =====================
// 6️⃣ Scheduler
// =====================
function scheduleNextUpdate(now: Date): i64 {
  const nextMidnight = Date.UTC(
    now.getUTCFullYear(),
    now.getUTCMonth(),
    now.getUTCDate() + 1,
    0, 0, 0
  );
  const msUntil = nextMidnight - now.getTime();
  Script.post("#", "change", null, msUntil);
  return msUntil;
}
6 Likes