diff --git a/_datafiles/world/default/sample-scripts/mobs/item-gold-quest.js b/_datafiles/sample-scripts/mobs/item-gold-quest.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/mobs/item-gold-quest.js
rename to _datafiles/sample-scripts/mobs/item-gold-quest.js
diff --git a/_datafiles/world/default/sample-scripts/spells/harmarea.js b/_datafiles/sample-scripts/spells/harmarea.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/spells/harmarea.js
rename to _datafiles/sample-scripts/spells/harmarea.js
diff --git a/_datafiles/world/default/sample-scripts/spells/harmmulti.js b/_datafiles/sample-scripts/spells/harmmulti.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/spells/harmmulti.js
rename to _datafiles/sample-scripts/spells/harmmulti.js
diff --git a/_datafiles/world/default/sample-scripts/spells/harmsingle.js b/_datafiles/sample-scripts/spells/harmsingle.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/spells/harmsingle.js
rename to _datafiles/sample-scripts/spells/harmsingle.js
diff --git a/_datafiles/world/default/sample-scripts/spells/helparea.js b/_datafiles/sample-scripts/spells/helparea.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/spells/helparea.js
rename to _datafiles/sample-scripts/spells/helparea.js
diff --git a/_datafiles/world/default/sample-scripts/spells/helpmulti.js b/_datafiles/sample-scripts/spells/helpmulti.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/spells/helpmulti.js
rename to _datafiles/sample-scripts/spells/helpmulti.js
diff --git a/_datafiles/world/default/sample-scripts/spells/helpsingle.js b/_datafiles/sample-scripts/spells/helpsingle.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/spells/helpsingle.js
rename to _datafiles/sample-scripts/spells/helpsingle.js
diff --git a/_datafiles/world/default/sample-scripts/spells/neutral.js b/_datafiles/sample-scripts/spells/neutral.js
similarity index 100%
rename from _datafiles/world/default/sample-scripts/spells/neutral.js
rename to _datafiles/sample-scripts/spells/neutral.js
diff --git a/_datafiles/world/empty/pets/cat.yaml b/_datafiles/world/empty/pets/cat.yaml
index 0606b5cd..1d069e4a 100644
--- a/_datafiles/world/empty/pets/cat.yaml
+++ b/_datafiles/world/empty/pets/cat.yaml
@@ -1,5 +1 @@
type: cat
-statmods:
- speed: 5
-buffids:
- - 38 # shadow eyes
\ No newline at end of file
diff --git a/_datafiles/world/empty/pets/dog.yaml b/_datafiles/world/empty/pets/dog.yaml
deleted file mode 100644
index d0c3fc41..00000000
--- a/_datafiles/world/empty/pets/dog.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-type: dog
-statmods:
- strength: 5
-damage:
- diceroll: 1d3
\ No newline at end of file
diff --git a/_datafiles/world/empty/pets/mule.yaml b/_datafiles/world/empty/pets/mule.yaml
deleted file mode 100644
index 2b280639..00000000
--- a/_datafiles/world/empty/pets/mule.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-type: mule
-statmods:
- vitality: 5
-capacity: 5
\ No newline at end of file
diff --git a/_datafiles/world/empty/pets/owl.yaml b/_datafiles/world/empty/pets/owl.yaml
deleted file mode 100644
index d4a074fd..00000000
--- a/_datafiles/world/empty/pets/owl.yaml
+++ /dev/null
@@ -1,5 +0,0 @@
-type: owl
-statmods:
- smarts: 5
-buffids:
- - 39
diff --git a/_datafiles/world/empty/quests/1-find_sophies_locket.yaml b/_datafiles/world/empty/quests/1-find_sophies_locket.yaml
deleted file mode 100644
index 978bbdde..00000000
--- a/_datafiles/world/empty/quests/1-find_sophies_locket.yaml
+++ /dev/null
@@ -1,14 +0,0 @@
-questid: 1
-name: Find Sophie's Locket
-description: In Frostfang, Sophie has lost her locket. She thinks she lost it in the garden hedge.
-steps:
- - id: start #1-start
- description: Sophie has lost her locket. She thinks she lost it in the garden hedge.
- hint: The garden hedge is behind Sophie's house.
- - id: return #1-return
- description: Return Sophie's locket to her.
- hint: Sophie's house is near the center of Frostfang.
- - id: end #1-end
- description: You recovered Sophie's locket for her.
-rewards:
- experience: 5000
diff --git a/_datafiles/world/empty/quests/2-the_kings_shadow.yaml b/_datafiles/world/empty/quests/2-the_kings_shadow.yaml
deleted file mode 100644
index cd930390..00000000
--- a/_datafiles/world/empty/quests/2-the_kings_shadow.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
-questid: 2
-name: The King's Shadow
-description: The King is uneasy. Something stirs.
-steps:
- - id: start
- description: The king suspects something is up at the Sanctuary of the Benevolent Heart. He wants you to investigate.
- hint: The priest in the Sanctuary may have some useful information.
- - id: catacombs
- description: Rumor has it that there is a secret entrance to the ancient catacombs beneath the city at the Sanctuary.
- hint: Try searching around the perimeter of the Sanctuary.
- - id: investigate
- description: Explore and investigate the catacombs.
- hint: Look for an ancient crypt deep within the catacombs.
- - id: inform
- description: Return to the King and show him what you discovered.
- hint: The King is north of the Town Square in Frostfang.
- - id: end
- description: You helped the king stop a malevolent force.
-rewards:
- playermessage: 'The King finally has some peace!'
- roommessage: 'The King seems a little bit more at ease.'
- experience: 15000
- gold: 1000
-
\ No newline at end of file
diff --git a/_datafiles/world/empty/quests/3-frostfang_incantation.yaml b/_datafiles/world/empty/quests/3-frostfang_incantation.yaml
deleted file mode 100644
index 35ac19cd..00000000
--- a/_datafiles/world/empty/quests/3-frostfang_incantation.yaml
+++ /dev/null
@@ -1,8 +0,0 @@
-questid: 3
-name: Frostfang Incantation
-description: You uttered the phrase that lets you pass the western gate safely.
-secret: true
-steps:
- - id: end
- description: You uttered the phrase that lets you pass the western gate safely.
-
\ No newline at end of file
diff --git a/_datafiles/world/empty/quests/4-a_soldiers_lunch.yaml b/_datafiles/world/empty/quests/4-a_soldiers_lunch.yaml
deleted file mode 100644
index 13a18954..00000000
--- a/_datafiles/world/empty/quests/4-a_soldiers_lunch.yaml
+++ /dev/null
@@ -1,16 +0,0 @@
-questid: 4
-name: A Soldier's Lunch
-description: A soldier in Frostfang forgot his lunch.
-steps:
- - id: start
- description: Find a cheese sandwich for the Frostfang Soldier in the barracks.
- hint: They sell some food at the Inn in Frostfang.
- - id: return
- description: Deliver the sandwich to the Frostfang Soldier in the barracks.
- hint: The barracks are just north of the Town Square.
- - id: end
- description: You helped a Frostfang soldier get through his day.
-rewards:
- experience: 1000
- gold: 100
- itemid: 22
diff --git a/_datafiles/world/empty/quests/5-the_frozen_hermit.yaml b/_datafiles/world/empty/quests/5-the_frozen_hermit.yaml
deleted file mode 100644
index d9d49895..00000000
--- a/_datafiles/world/empty/quests/5-the_frozen_hermit.yaml
+++ /dev/null
@@ -1,21 +0,0 @@
-questid: 5
-name: The frozen hermit
-description: The old hermit is freezing to death.
-steps:
- - id: start
- description: The old hermit is waiting for a magic artifact that will keep him warm.
- hint: Ask the hermit a little bit more about the winterfire crystals.
- - id: lookeast
- description: The old hermit's shipment should have come from the eastern city Mystarion.
- hint: A wrecked caravan was seen outside of Frostang on the eastern road.
- - id: usecrowbar
- description: Use the crowbar to open the crate at the caravan.
- hint: Crowbars are hard to come by, but there may be one at the Inn in Frostfang.
- - id: return
- description: Deliver the winterfire crystal to the old hermit in the Whispering Wastes.
- hint: The old hermit is in the Whispering Wastes, just west of Frostfang.
- - id: end
- description: You helped the old hermit find his winterfire crystal.
-rewards:
- experience: 2000
-
diff --git a/_datafiles/world/empty/quests/6-the_history_of_frostfang.yaml b/_datafiles/world/empty/quests/6-the_history_of_frostfang.yaml
deleted file mode 100644
index 61e1f022..00000000
--- a/_datafiles/world/empty/quests/6-the_history_of_frostfang.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-questid: 6
-name: The History of Frostfang
-description: Elara needs help finding the history of Frostfang, a book.
-steps:
- - id: start
- description: The book was borrowed by a resident of Frostfang and never returned.
- hint: The book is probably still in Frostfang, somewhere.
- - id: return
- description: Deliver the book to Elara, in the Frostfang keep library.
- hint: The keep is to the north of Town Square.
- - id: end
- description: You returned an important part of Frostfangs history.
-rewards:
- experience: 1000
-
diff --git a/_datafiles/world/empty/quests/7-rodrics_rats.yaml b/_datafiles/world/empty/quests/7-rodrics_rats.yaml
deleted file mode 100644
index db85d624..00000000
--- a/_datafiles/world/empty/quests/7-rodrics_rats.yaml
+++ /dev/null
@@ -1,29 +0,0 @@
-#
-# This quest reveals the location fo the thieves hideout
-# 1. They must ask rodric about the rat problem
-# ask rodric about rats
-# 2. They must kill 25 rats for rodric (they may have already done this)
-# ask rodric about rats
-# 3. Rodric is impressed, but needs them to retrieve an old rat trap from a customer
-# give trap to rodric
-# 4. When they return the trap, Rodric mentions the thieves guild never returned his traps, costing him a lot of money
-# 5. From then on he can be asked wehre the thieves den is, and will reveal it.
-#
-questid: 7
-name: Rodric's Rats
-description: Rodric could use a hand with the rat situation.
-steps:
- - id: start
- description: Rodric would like you to kill 25 rats for him.
- hint: Rats are abundant south of town square, in the alleyway and near the slums.
- - id: gettrap
- description: Collect an old trap from a resident of Frostfang.
- hint: The residents are just north of town square.
- - id: tradetrap
- description: Give the rat trap you found to Rodric.
- hint: Find Rodric, he needs a rat trap.
- - id: end
- description: You helped Rodric get back to work.
-rewards:
- experience: 1000
-
diff --git a/_datafiles/world/empty/sample-scripts/mobs/item-gold-quest.js b/_datafiles/world/empty/sample-scripts/mobs/item-gold-quest.js
deleted file mode 100644
index bb644b3a..00000000
--- a/_datafiles/world/empty/sample-scripts/mobs/item-gold-quest.js
+++ /dev/null
@@ -1,213 +0,0 @@
-
-
-// Things to ask the mob to initate the quest
-const questStartSubjects = ["quest", "desire", "help"];
-
-// Things to ask the mob once the quest is started, seeking more information
-const questInfoSubjects = ["where", "how"];
-
-// The item this mob wants in order to complete the quest.
-const REQUIRED_ITEM_ID = 10001;
-
-// The gold this mob wants in order to complete the quest
-const REQUIRED_GOLD_AMOUNT = 10;
-
-// This corresponds to the quest defined in the _datafiles/quests/ folder.
-const QUEST_START_ID = "1000000-start" // All quests begin with #-start
-const QUEST_NEXT_STEP_ID = "1000000-givegold" // Quest steps can be called #-anything
-const QUEST_END_ID = "1000000-end" // All quests end with #-end
-
-
-//
-// The onAsk() function handles when players invoke the `ask` command
-//
-function onAsk(mob, room, eventDetails) {
-
- //
- // Get the user, and if the user is invalid, skip the script (something is wrong)
- //
- if ( (user = GetUser(eventDetails.sourceId)) == null ) {
- return false;
- }
-
- //
- // Do they have the quest end id? Then they have already completed the quest.
- //
- if ( user.HasQuest(QUEST_END_ID) ) {
- mob.Command("say Your help is no longer needed.");
- return true;
- }
-
- //
- // Do this part of they have not started the quest yet
- //
- if ( !user.HasQuest(QUEST_START_ID) ) {
-
- //
- // Search the text they inputted for the "ask" command for one of the questStartSubjects
- //
- match = UtilFindMatchIn(eventDetails.askText, questStartSubjects);
-
- if ( match.found ) {
-
- mob.Command("emote smiles.");
- mob.Command("say I would really like a sharp stick!");
- //
- // Give them the start quest id
- //
- user.GiveQuest(QUEST_START_ID);
-
- }
-
- return true;
- }
-
- //
- // By this point in the script we know they've at least started the quest
- // Lets see if they are asking any follow up questions for more info.
- //
- match = UtilFindMatchIn(eventDetails.askText, questInfoSubjects);
- if ( match.found ) {
- mob.Command("emote thinks hard for a moment.");
- mob.Command("say You can get sharp sticks from a shop, and gold from selling objects, or possibly killing bad guys and looting them.");
- return true;
- }
-
- return true;
-}
-
-//
-// The onGive() function is invoked when players give the mob an item or gold.
-//
-function onGive(mob, room, eventDetails) {
-
- //
- // Get the user, and if the user is invalid, skip the script (something is wrong)
- //
- if ( (user = GetUser(eventDetails.sourceId)) == null ) {
- return false;
- }
-
-
- //
- // Did they give an item?
- //
- if ( eventDetails.item.ItemId ) {
-
- //
- // If the item they gave isn't the desired item id, give it back.
- //
- if (eventDetails.item.ItemId != REQUIRED_ITEM_ID) {
-
- mob.Command("say That's very kind, but I don't need this right now.");
-
- // Use special shorthand such as !{item_id} to avoid accidentally dropping the wrong item by name
- // See: internal/scripting/README.md for other shorthand examples.
- // user object actually has a ShorthandId() function to make that easy.
- mob.Command("give !" + String(eventDetails.item.ItemId) + " " + user.ShorthandId()); // Give it to the player using shorthand
-
- return true;
- }
-
-
- //
- // If they've already done this step of the quest (and have the next step quest token), reject the offering.
- //
- if ( user.HasQuest(QUEST_NEXT_STEP_ID) ) {
- mob.Command("say I already have the stick you gave me. I don't need another.");
- mob.Command("give !" + String(eventDetails.item.ItemId) + " " + user.ShorthandId()); // Give it to the player using shorthand
- return true;
- }
-
- //
- // By this point in the script, we know it's the right item id.
- //
-
- mob.Command("say Thank you so much! That's the perfect stick!");
- mob.Command("say Do you think you could spare 10 gold?");
-
- //
- // Give them the next step of the quest
- //
- user.GiveQuest(QUEST_NEXT_STEP_ID)
-
- return true;
- }
-
-
- //
- // Did they give gold?
- //
- if ( eventDetails.gold > 0 ) {
-
- //
- // If they don't have the part of the quest that asks for gold yet
- // Reject their offering for now.
- //
- if ( !user.HasQuest(QUEST_NEXT_STEP_ID) ) {
- mob.Command("say We aren't quite there yet.");
- mob.Command("give "+String(eventDetails.gold)+" gold " + user.ShorthandId()); // Give it to the player using shorthand
- return true;
- }
-
- //
- // If they gave less than REQUIRED_GOLD_AMOUNT, reject it
- //
- if ( eventDetails.gold < REQUIRED_GOLD_AMOUNT ) {
- mob.Command("say We aren't quite there yet.");
- mob.Command("give "+String(eventDetails.gold)+" gold " + user.ShorthandId()); // Give it to the player using shorthand
- return true;
- }
-
-
- //
- // If they gave less than REQUIRED_GOLD_AMOUNT, reject it
- //
- if ( eventDetails.gold >= REQUIRED_GOLD_AMOUNT ) {
-
- mob.Command("say Great thanks!");
-
- //
- // If they gave too much gold, lets give them back the change.
- //
- excessGold = eventDetails.gold - REQUIRED_GOLD_AMOUNT;
- if ( excessGold > 0 ) {
- mob.Command("say Here's your change.")
- mob.Command("give "+String(excessGold)+" gold " + user.ShorthandId()); // Give it to the player using shorthand
- }
-
- //
- // They have now completed the entire quest, all steps are complete.
- //
- user.GiveQuest(QUEST_END_ID)
-
- return true;
- }
-
- return true;
- }
-
- return false;
-}
-
-
-//
-// The onIdle() function is invoked whenver the mob is sitting around bored.
-// The frequency is dictated by the mob's "activitylevel" defined in its flatfile.
-//
-function onIdle(mob, room) {
-
- // 25% chance of saying something in a given round
- if ( UtilGetRoundNumber() % 4 == 0 ) {
-
- mob.Command('say I have a quest for a new adventurer. You can ask me about it.');
-
- // Returning true from this function says we handled the idle, so do not try to do other random idle behaviors.
- return true;
- }
-
- //
- // otherwise return false, allow the mob to perform idlecommands it may have defined.
- //
- return false;
-}
\ No newline at end of file
diff --git a/_datafiles/world/empty/sample-scripts/spells/harmarea.js b/_datafiles/world/empty/sample-scripts/spells/harmarea.js
deleted file mode 100644
index 8a302c3a..00000000
--- a/_datafiles/world/empty/sample-scripts/spells/harmarea.js
+++ /dev/null
@@ -1,62 +0,0 @@
-
-HARM_DICE_QTY = 1
-HARM_DICE_SIDES = 2
-SPELL_DESCRIPTION = 'sample harmful area spell'
-
-// Called when the casting is initialized (cast command)
-// Return false if the casting should be ignored/aborted
-function onCast(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You begin to chant softly.');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' begins to chant softly.', sourceActor.UserId());
- return true
-}
-
-function onWait(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You continue chanting...');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' continues chanting...', sourceActor.UserId());
-}
-
-// Called when the spell succeeds its cast attempt
-function onMagic(sourceActor, targetActors) {
-
- roomId = sourceActor.GetRoomId();
-
- sourceUserId = sourceActor.UserId();
- sourceName = sourceActor.GetCharacterName(true);
-
- for (var i = 0; i < targetActors.length; i++) {
-
- dmgAmt = UtilDiceRoll(HARM_DICE_QTY, HARM_DICE_SIDES);
- dmgAmtStr = String(dmgAmt);
-
- targetUserId = targetActors[i].UserId();
- targetName = targetActors[i].GetCharacterName(true);
-
- if ( sourceActor.UserId() != targetActors[i].UserId() ) {
-
- // Tell the caster about the action
- SendUserMessage(sourceUserId, 'You unleash a '+SPELL_DESCRIPTION+' at '+targetName+', doing '+dmgAmtStr+' damage.');
-
- // Tell the room about the dmg, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and unleashes a '+SPELL_DESCRIPTION+', hitting '+targetName+'.', sourceUserId, targetUserId);
-
- // Tell the target about the dmg
- SendUserMessage(targetUserId, sourceName+' stops chanting and unleashes a '+SPELL_DESCRIPTION+' at you, hitting for '+dmgAmtStr+' damage.');
-
- } else {
-
- // Tell the cast they did it to themselves
- SendUserMessage(sourceUserId, 'You stop chanting and unleash a '+SPELL_DESCRIPTION+' at yourself, doing '+dmgAmtStr+' damage.');
-
- // Tell the room about the dmg, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and unleashes a '+SPELL_DESCRIPTION+' at themselves, hurting themselves.', sourceUserId, targetUserId);
-
- }
-
- // Apply the dmg to the target
- targetActors[i].AddHealth(dmgAmt * -1);
- }
-
-}
diff --git a/_datafiles/world/empty/sample-scripts/spells/harmmulti.js b/_datafiles/world/empty/sample-scripts/spells/harmmulti.js
deleted file mode 100644
index a7c08565..00000000
--- a/_datafiles/world/empty/sample-scripts/spells/harmmulti.js
+++ /dev/null
@@ -1,62 +0,0 @@
-
-HARM_DICE_QTY = 1
-HARM_DICE_SIDES = 2
-SPELL_DESCRIPTION = 'sample harmful group spell'
-
-// Called when the casting is initialized (cast command)
-// Return false if the casting should be ignored/aborted
-function onCast(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You begin to chant softly.');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' begins to chant softly.', sourceActor.UserId());
- return true
-}
-
-function onWait(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You continue chanting...');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' continues chanting...', sourceActor.UserId());
-}
-
-// Called when the spell succeeds its cast attempt
-function onMagic(sourceActor, targetActors) {
-
- roomId = sourceActor.GetRoomId();
-
- sourceUserId = sourceActor.UserId();
- sourceName = sourceActor.GetCharacterName(true);
-
- for (var i = 0; i < targetActors.length; i++) {
-
- dmgAmt = UtilDiceRoll(HARM_DICE_QTY, HARM_DICE_SIDES);
- dmgAmtStr = String(dmgAmt);
-
- targetUserId = targetActors[i].UserId();
- targetName = targetActors[i].GetCharacterName(true);
-
- if ( sourceActor.UserId() != targetActors[i].UserId() ) {
-
- // Tell the caster about the action
- SendUserMessage(sourceUserId, 'You unleash a '+SPELL_DESCRIPTION+' at '+targetName+', doing '+dmgAmtStr+' damage.');
-
- // Tell the room about the dmg, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and unleashes a '+SPELL_DESCRIPTION+', hitting '+targetName+'.', sourceUserId, targetUserId);
-
- // Tell the target about the dmg
- SendUserMessage(targetUserId, sourceName+' stops chanting and unleashes a '+SPELL_DESCRIPTION+' at you, hitting for '+dmgAmtStr+' damage.');
-
- } else {
-
- // Tell the cast they did it to themselves
- SendUserMessage(sourceUserId, 'You stop chanting and unleash a '+SPELL_DESCRIPTION+' at yourself, doing '+dmgAmtStr+' damage.');
-
- // Tell the room about the dmg, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and unleashes a '+SPELL_DESCRIPTION+' at themselves, hurting themselves.', sourceUserId, targetUserId);
-
- }
-
- // Apply the dmg to the target
- targetActors[i].AddHealth(dmgAmt * -1);
- }
-
-}
diff --git a/_datafiles/world/empty/sample-scripts/spells/harmsingle.js b/_datafiles/world/empty/sample-scripts/spells/harmsingle.js
deleted file mode 100644
index 7f623f16..00000000
--- a/_datafiles/world/empty/sample-scripts/spells/harmsingle.js
+++ /dev/null
@@ -1,48 +0,0 @@
-
-HARM_DICE_QTY = 1
-HARM_DICE_SIDES = 2
-SPELL_DESCRIPTION = 'sample harmful single target spell'
-
-// Called when the casting is initialized (cast command)
-// Return false if the casting should be ignored/aborted
-function onCast(sourceActor, targetActor) {
-
- SendUserMessage(sourceActor.UserId(), 'You begin to chant softly.');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' begins to chant softly.', sourceActor.UserId());
- return true
-}
-
-function onWait(sourceActor, targetActor) {
-
- SendUserMessage(sourceActor.UserId(), 'You continue chanting, as a swirling light gathers...');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' continues chanting...', sourceActor.UserId());
-}
-
-// Called when the spell succeeds its cast attempt
-function onMagic(sourceActor, targetActor) {
-
- roomId = sourceActor.GetRoomId();
-
- harmAmt = UtilDiceRoll(HARM_DICE_QTY, HARM_DICE_SIDES);
- harmAmtStr = String(harmAmt);
-
- sourceUserId = sourceActor.UserId();
- sourceName = sourceActor.GetCharacterName(true);
-
- targetUserId = targetActor.UserId();
- targetName = targetActor.GetCharacterName(true);
-
- // Tell the caster about the action
- SendUserMessage(sourceUserId, 'You cast a '+SPELL_DESCRIPTION+' at '+targetName+', doing '+harmAmtStr+' hitpoints of damage!');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' casts a '+SPELL_DESCRIPTION+' at '+targetName+' hurting them!', sourceUserId, targetUserId);
-
- // Tell the target about the heal
- SendUserMessage(targetUserId, sourceName+' casts a '+SPELL_DESCRIPTION+' at you, doing '+harmAmtStr+' hitpoints of damage!');
-
- // Apply the heal to the target
- targetActor.AddHealth(harmAmt * -1);
-
-}
-
diff --git a/_datafiles/world/empty/sample-scripts/spells/helparea.js b/_datafiles/world/empty/sample-scripts/spells/helparea.js
deleted file mode 100644
index 601d2ea0..00000000
--- a/_datafiles/world/empty/sample-scripts/spells/helparea.js
+++ /dev/null
@@ -1,62 +0,0 @@
-
-HEAL_DICE_QTY = 1
-HEAL_DICE_SIDES = 2
-SPELL_DESCRIPTION = 'sample helpful area spell'
-
-
-// Called when the casting is initialized (cast command)
-// Return false if the casting should be ignored/aborted
-function onCast(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You begin to chant softly.');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' begins to chant softly.', sourceActor.UserId());
- return true
-}
-
-function onWait(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You continue chanting...');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' continues chanting...', sourceActor.UserId());
-}
-
-// Called when the spell succeeds its cast attempt
-function onMagic(sourceActor, targetActors) {
-
- roomId = sourceActor.GetRoomId();
-
- sourceUserId = sourceActor.UserId();
- sourceName = sourceActor.GetCharacterName(true);
-
- for (var i = 0; i < targetActors.length; i++) {
- healAmt = UtilDiceRoll(HEAL_DICE_QTY, HEAL_DICE_SIDES);
- healAmtStr = String(healAmt);
-
- targetUserId = targetActors[i].UserId();
- targetName = targetActors[i].GetCharacterName(true);
-
- if ( sourceActor.UserId() != targetActors[i].UserId() ) {
-
- // Tell the caster about the action
- SendUserMessage(sourceUserId, 'You stop chanting cast a '+SPELL_DESCRIPTION+' on '+targetName+', healing '+healAmtStr+' hitpoints.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and casts a '+SPELL_DESCRIPTION+' on '+targetName+', providing health.', sourceUserId, targetUserId);
-
- // Tell the target about the heal
- SendUserMessage(targetUserId, sourceName+' stops chanting and cast a '+SPELL_DESCRIPTION+' on you with glowing hands, healing '+healAmtStr+' hitpoints.');
-
- } else {
-
- // Tell the cast they did it to themselves
- SendUserMessage(sourceUserId, 'You stop chanting and cast a '+SPELL_DESCRIPTION+' on yourself, healing '+healAmtStr+' hitpoints.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and casts a '+SPELL_DESCRIPTION+' on themselves, providing health.', sourceUserId, targetUserId);
-
- }
-
- // Apply the heal to the target
- targetActors[i].AddHealth(healAmt);
- }
-
-}
diff --git a/_datafiles/world/empty/sample-scripts/spells/helpmulti.js b/_datafiles/world/empty/sample-scripts/spells/helpmulti.js
deleted file mode 100644
index 17a216bf..00000000
--- a/_datafiles/world/empty/sample-scripts/spells/helpmulti.js
+++ /dev/null
@@ -1,62 +0,0 @@
-
-HEAL_DICE_QTY = 1
-HEAL_DICE_SIDES = 2
-SPELL_DESCRIPTION = 'sample helpful group spell'
-
-
-// Called when the casting is initialized (cast command)
-// Return false if the casting should be ignored/aborted
-function onCast(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You begin to chant softly.');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' begins to chant softly.', sourceActor.UserId());
- return true
-}
-
-function onWait(sourceActor, targetActors) {
-
- SendUserMessage(sourceActor.UserId(), 'You continue chanting...');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' continues chanting...', sourceActor.UserId());
-}
-
-// Called when the spell succeeds its cast attempt
-function onMagic(sourceActor, targetActors) {
-
- roomId = sourceActor.GetRoomId();
-
- sourceUserId = sourceActor.UserId();
- sourceName = sourceActor.GetCharacterName(true);
-
- for (var i = 0; i < targetActors.length; i++) {
- healAmt = UtilDiceRoll(HEAL_DICE_QTY, HEAL_DICE_SIDES);
- healAmtStr = String(healAmt);
-
- targetUserId = targetActors[i].UserId();
- targetName = targetActors[i].GetCharacterName(true);
-
- if ( sourceActor.UserId() != targetActors[i].UserId() ) {
-
- // Tell the caster about the action
- SendUserMessage(sourceUserId, 'You stop chanting cast a '+SPELL_DESCRIPTION+' on '+targetName+', healing '+healAmtStr+' hitpoints.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and casts a '+SPELL_DESCRIPTION+' on '+targetName+', providing health.', sourceUserId, targetUserId);
-
- // Tell the target about the heal
- SendUserMessage(targetUserId, sourceName+' stops chanting and cast a '+SPELL_DESCRIPTION+' on you with glowing hands, healing '+healAmtStr+' hitpoints.');
-
- } else {
-
- // Tell the cast they did it to themselves
- SendUserMessage(sourceUserId, 'You stop chanting and cast a '+SPELL_DESCRIPTION+' on yourself, healing '+healAmtStr+' hitpoints.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and casts a '+SPELL_DESCRIPTION+' on themselves, providing health.', sourceUserId, targetUserId);
-
- }
-
- // Apply the heal to the target
- targetActors[i].AddHealth(healAmt);
- }
-
-}
diff --git a/_datafiles/world/empty/sample-scripts/spells/helpsingle.js b/_datafiles/world/empty/sample-scripts/spells/helpsingle.js
deleted file mode 100644
index 40c09563..00000000
--- a/_datafiles/world/empty/sample-scripts/spells/helpsingle.js
+++ /dev/null
@@ -1,59 +0,0 @@
-
-HEAL_DICE_QTY = 1
-HEAL_DICE_SIDES = 2
-SPELL_DESCRIPTION = 'sample helpful single target spell'
-
-// Called when the casting is initialized (cast command)
-// Return false if the casting should be ignored/aborted
-function onCast(sourceActor, targetActor) {
-
- SendUserMessage(sourceActor.UserId(), 'You begin to chant softly.');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' begins to chant softly.', sourceActor.UserId());
- return true
-}
-
-function onWait(sourceActor, targetActor) {
-
- SendUserMessage(sourceActor.UserId(), 'You continue chanting...');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' continues chanting...', sourceActor.UserId());
-}
-
-// Called when the spell succeeds its cast attempt
-function onMagic(sourceActor, targetActor) {
-
- roomId = sourceActor.GetRoomId();
-
- healAmt = UtilDiceRoll(HEAL_DICE_QTY, HEAL_DICE_SIDES);
- healAmtStr = String(healAmt);
-
- sourceUserId = sourceActor.UserId();
- sourceName = sourceActor.GetCharacterName(true);
-
- targetUserId = targetActor.UserId();
- targetName = targetActor.GetCharacterName(true);
-
- if ( sourceActor.UserId() != targetActor.UserId() ) {
-
- // Tell the caster about the action
- SendUserMessage(sourceUserId, 'You stop chanting and casts '+SPELL_DESCRIPTION+' on '+targetName+', healing '+healAmtStr+' hitpoints.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and casts '+SPELL_DESCRIPTION+' on '+targetName+', providing health.', sourceUserId, targetUserId);
-
- // Tell the target about the heal
- SendUserMessage(targetUserId, sourceName+' stops chanting and casts '+SPELL_DESCRIPTION+' on you, healing '+healAmtStr+' hitpoints.');
-
- } else {
-
- // Tell the cast they did it to themselves
- SendUserMessage(sourceUserId, 'You stop chanting and cast '+SPELL_DESCRIPTION+' on yourself, healing '+healAmtStr+' hitpoints.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' stops chanting and casts '+SPELL_DESCRIPTION+' on themselves, providing health.', sourceUserId, targetUserId);
-
- }
-
- // Apply the heal to the target
- targetActor.AddHealth(healAmt);
-
-}
diff --git a/_datafiles/world/empty/sample-scripts/spells/neutral.js b/_datafiles/world/empty/sample-scripts/spells/neutral.js
deleted file mode 100644
index e484c606..00000000
--- a/_datafiles/world/empty/sample-scripts/spells/neutral.js
+++ /dev/null
@@ -1,53 +0,0 @@
-
-// Called when the casting is initialized (cast command)
-// Return false if the casting should be ignored/aborted
-function onCast(sourceActor, targetActor) {
-
- SendUserMessage(sourceActor.UserId(), 'You begin to chant softly.');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' begins to chant softly.', sourceActor.UserId());
- return true
-}
-
-function onWait(sourceActor, targetActor) {
-
- SendUserMessage(sourceActor.UserId(), 'You gather threads of light...');
- SendRoomMessage(sourceActor.GetRoomId(), sourceActor.GetCharacterName(true)+' is gathering threads of light...', sourceActor.UserId());
-}
-
-// Called when the spell succeeds its cast attempt
-function onMagic(sourceActor, targetActor) {
-
- roomId = sourceActor.GetRoomId();
-
- sourceUserId = sourceActor.UserId();
- sourceName = sourceActor.GetCharacterName(true);
-
- targetUserId = targetActor.UserId();
- targetName = targetActor.GetCharacterName(true);
-
-
- if ( sourceActor.UserId() != targetActor.UserId() ) {
-
- // Tell the caster about the action
- SendUserMessage(sourceUserId, 'You materialize a glowing orb.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' materializes a glowing orb, which follows '+targetName+' around.', sourceUserId, targetUserId);
-
- // Tell the target about the heal
- SendUserMessage(targetUserId, sourceName+' materializes a glowing orb, which follows you around.');
-
- } else {
-
- // Tell the cast they did it to themselves
- SendUserMessage(sourceUserId, 'You materialize a glowing orb.');
-
- // Tell the room about the heal, except the source and target
- SendRoomMessage(roomId, sourceName+' materializes a glowing orb, which follows them around.', sourceUserId);
-
- }
-
- // Apply the illumination
- targetActor.GiveBuff(1);
-
-}
diff --git a/internal/mobs/newmobfile.go b/internal/mobs/newmobfile.go
index bc30d99a..ba8bfaad 100644
--- a/internal/mobs/newmobfile.go
+++ b/internal/mobs/newmobfile.go
@@ -61,7 +61,7 @@ func CreateNewMobFile(newMobInfo Mob, copyScript string) (MobId, error) {
os.MkdirAll(filepath.Dir(newScriptPath), os.ModePerm)
fileloader.CopyFileContents(
- util.FilePath(string(configs.GetConfig().FolderDataFiles)+`/sample-scripts/mobs/`+copyScript),
+ util.FilePath(`_datafiles/sample-scripts/mobs/`+copyScript),
newMobInfo.GetScriptPath(),
)
}
diff --git a/internal/rooms/roomgraph.go b/internal/rooms/roomgraph.go
index 0e7de50a..b69622dd 100644
--- a/internal/rooms/roomgraph.go
+++ b/internal/rooms/roomgraph.go
@@ -651,7 +651,7 @@ func (r *RoomGraph) Changed() bool {
}
if totalRooms == len(r.trackedRoomIds) {
- slog.Info("RoomGraph::Changed()", "Updated needed, mismatched room counts", "totalRooms", totalRooms, "trackedRoomIds", len(r.trackedRoomIds))
+ slog.Info("RoomGraph::Changed()", "error", "Updated needed, mismatched room counts", "totalRooms", totalRooms, "trackedRoomIds", len(r.trackedRoomIds))
// return true
}
diff --git a/internal/scripting/buff.go b/internal/scripting/buff.go
index 03d724f7..87d6d35b 100644
--- a/internal/scripting/buff.go
+++ b/internal/scripting/buff.go
@@ -186,7 +186,7 @@ func getBuffVM(buffId int) (*VMWrapper, error) {
bSpec := buffs.GetBuffSpec(buffId)
if bSpec == nil {
- return nil, fmt.Errorf("buff spec not found: %d", bSpec)
+ return nil, fmt.Errorf("buff spec not found: %T", bSpec)
}
script := bSpec.GetScript()
diff --git a/internal/spells/newspellfile.go b/internal/spells/newspellfile.go
index 0e7815d9..0544167e 100644
--- a/internal/spells/newspellfile.go
+++ b/internal/spells/newspellfile.go
@@ -37,7 +37,7 @@ func CreateNewSpellFile(newSpellInfo SpellData) (string, error) {
newScriptPath := newSpellInfo.GetScriptPath()
os.MkdirAll(filepath.Dir(newScriptPath), os.ModePerm)
- fileloader.CopyFileContents(util.FilePath(string(configs.GetConfig().FolderDataFiles)+`/sample-scripts/spells/`+string(newSpellInfo.Type)+`.js`),
+ fileloader.CopyFileContents(util.FilePath(`_datafiles/sample-scripts/spells/`+string(newSpellInfo.Type)+`.js`),
newScriptPath)
return newSpellInfo.SpellId, nil
diff --git a/internal/usercommands/biome.go b/internal/usercommands/biome.go
index 92d2b878..21bdbe7e 100644
--- a/internal/usercommands/biome.go
+++ b/internal/usercommands/biome.go
@@ -14,7 +14,7 @@ func Biome(rest string, user *users.UserRecord, room *rooms.Room) (bool, error)
if !ok {
user.SendText(`No biome information found about this area.`)
- return false, fmt.Errorf(`biome %d not found`, room.Biome)
+ return false, fmt.Errorf(`biome %s not found`, room.Biome)
}
biomeTxt, _ := templates.Process("descriptions/biome", biome)
diff --git a/internal/usercommands/macros.go b/internal/usercommands/macros.go
index 018178f3..f1644e0c 100644
--- a/internal/usercommands/macros.go
+++ b/internal/usercommands/macros.go
@@ -41,7 +41,7 @@ func Macros(rest string, user *users.UserRecord, room *rooms.Room) (bool, error)
cmdRest = strings.Join(cmdParts[1:], ` `)
}
- user.SendText(fmt.Sprintf(` %s) %s %s`, string(97+i), cmdAlone, cmdRest))
+ user.SendText(fmt.Sprintf(` %s) %s %s`, string(rune(97+i)), cmdAlone, cmdRest))
}
}
user.SendText(``)
diff --git a/internal/util/util.go b/internal/util/util.go
index fd57efa5..695c2c09 100644
--- a/internal/util/util.go
+++ b/internal/util/util.go
@@ -819,3 +819,36 @@ func StringWildcardMatch(stringToSearch string, patternToSearch string) bool {
return stringToSearch == patternToSearch
}
+
+func ValidateWorldFiles(worldPath string) error {
+
+ exampleWorld := FilePath(`_datafiles/world/default`)
+
+ entries, err := os.ReadDir(exampleWorld)
+ if err != nil {
+ return fmt.Errorf("unable to read directory %s: %v", exampleWorld, err)
+ }
+
+ var subfolders []string
+ // Filter out only directories
+ for _, entry := range entries {
+ if entry.IsDir() {
+ subfolders = append(subfolders, entry.Name())
+ }
+ }
+
+ // Check each source subfolder in the target directory
+ for _, folder := range subfolders {
+ testPath := filepath.Join(worldPath, folder)
+
+ info, err := os.Stat(testPath)
+ if err != nil {
+ return fmt.Errorf("'%s' missing folder '%s': %v", worldPath, folder, err)
+ }
+ if !info.IsDir() {
+ return fmt.Errorf("'%s' exists but is not a directory", testPath)
+ }
+ }
+
+ return nil
+}
diff --git a/internal/web/admin.items.go b/internal/web/admin.items.go
index 8942618d..5632d59a 100644
--- a/internal/web/admin.items.go
+++ b/internal/web/admin.items.go
@@ -73,7 +73,7 @@ func itemsIndex(w http.ResponseWriter, r *http.Request) {
func itemData(w http.ResponseWriter, r *http.Request) {
- tmpl, err := template.New("item.data.html").Funcs(funcMap).ParseFiles(DataFiles() + "/html/admin/items/item.data.html")
+ tmpl, err := template.New("item.data.html").Funcs(funcMap).ParseFiles(configs.GetConfig().FolderHtmlFiles.String() + "/admin/items/item.data.html")
if err != nil {
slog.Error("HTML Template", "error", err)
}
diff --git a/internal/web/admin.mobs.go b/internal/web/admin.mobs.go
index 2db060eb..10d49e65 100644
--- a/internal/web/admin.mobs.go
+++ b/internal/web/admin.mobs.go
@@ -41,7 +41,7 @@ func mobsIndex(w http.ResponseWriter, r *http.Request) {
func mobData(w http.ResponseWriter, r *http.Request) {
- tmpl, err := template.New("mob.data.html").Funcs(funcMap).ParseFiles(DataFiles() + "/html/admin/mobs/mob.data.html")
+ tmpl, err := template.New("mob.data.html").Funcs(funcMap).ParseFiles(configs.GetConfig().FolderHtmlFiles.String() + "/admin/mobs/mob.data.html")
if err != nil {
slog.Error("HTML Template", "error", err)
}
diff --git a/internal/web/admin.mutators.go b/internal/web/admin.mutators.go
index bad55f0f..58027097 100644
--- a/internal/web/admin.mutators.go
+++ b/internal/web/admin.mutators.go
@@ -39,7 +39,7 @@ func mutatorsIndex(w http.ResponseWriter, r *http.Request) {
func mutatorData(w http.ResponseWriter, r *http.Request) {
- tmpl, err := template.New("mutator.data.html").Funcs(funcMap).ParseFiles(DataFiles() + "/html/admin/mutators/mutator.data.html")
+ tmpl, err := template.New("mutator.data.html").Funcs(funcMap).ParseFiles(configs.GetConfig().FolderHtmlFiles.String() + "/admin/mutators/mutator.data.html")
if err != nil {
slog.Error("HTML Template", "error", err)
}
diff --git a/internal/web/admin.races.go b/internal/web/admin.races.go
index bb33dcb4..2f9e11f2 100644
--- a/internal/web/admin.races.go
+++ b/internal/web/admin.races.go
@@ -40,7 +40,7 @@ func racesIndex(w http.ResponseWriter, r *http.Request) {
func raceData(w http.ResponseWriter, r *http.Request) {
- tmpl, err := template.New("race.data.html").Funcs(funcMap).ParseFiles(DataFiles() + "/html/admin/races/race.data.html")
+ tmpl, err := template.New("race.data.html").Funcs(funcMap).ParseFiles(configs.GetConfig().FolderHtmlFiles.String() + "/admin/races/race.data.html")
if err != nil {
slog.Error("HTML Template", "error", err)
}
diff --git a/internal/web/admin.rooms.go b/internal/web/admin.rooms.go
index 89a201c3..24122a67 100644
--- a/internal/web/admin.rooms.go
+++ b/internal/web/admin.rooms.go
@@ -59,7 +59,7 @@ func roomsIndex(w http.ResponseWriter, r *http.Request) {
if rootRoomId, err := rooms.GetZoneRoot(room.Zone); err == nil {
if rootRoom := rooms.LoadRoom(rootRoomId); rootRoom != nil {
- if rootRoom.ZoneConfig.MobAutoScale.Minimum > 0 || rootRoom.ZoneConfig.MobAutoScale.Minimum > 0 {
+ if rootRoom.ZoneConfig.MobAutoScale.Minimum > 0 || rootRoom.ZoneConfig.MobAutoScale.Maximum > 0 {
autoScale = fmt.Sprintf(`%d to %d`, rootRoom.ZoneConfig.MobAutoScale.Minimum, rootRoom.ZoneConfig.MobAutoScale.Maximum)
}
}
@@ -140,7 +140,7 @@ func roomsIndex(w http.ResponseWriter, r *http.Request) {
func roomData(w http.ResponseWriter, r *http.Request) {
- tmpl, err := template.New("room.data.html").Funcs(funcMap).ParseFiles(DataFiles() + "/html/admin/rooms/room.data.html")
+ tmpl, err := template.New("room.data.html").Funcs(funcMap).ParseFiles(configs.GetConfig().FolderHtmlFiles.String() + "/admin/rooms/room.data.html")
if err != nil {
slog.Error("HTML Template", "error", err)
}
diff --git a/internal/web/home.go b/internal/web/home.go
index 854c0f85..9a663753 100644
--- a/internal/web/home.go
+++ b/internal/web/home.go
@@ -18,7 +18,7 @@ func serveHome(w http.ResponseWriter, r *http.Request) {
configs.GetConfig().AllConfigData(`*port`, `seed`, `folder*`, `file*`),
}
- tmpl, err := template.New("index.html").Funcs(funcMap).ParseFiles(DataFiles() + "/html/public/index.html")
+ tmpl, err := template.New("index.html").Funcs(funcMap).ParseFiles(configs.GetConfig().FolderHtmlFiles.String() + "/public/index.html")
if err != nil {
slog.Error("HTML ERROR", "error", err)
}
diff --git a/main.go b/main.go
index ad9f7506..9dcbf462 100644
--- a/main.go
+++ b/main.go
@@ -127,6 +127,12 @@ func main() {
// System Configurations
runtime.GOMAXPROCS(int(c.MaxCPUCores))
+ // Validate chosen world:
+ if err := util.ValidateWorldFiles(c.FolderDataFiles.String()); err != nil {
+ slog.Error("World", "error", err)
+ os.Exit(1)
+ }
+
// Load all the data files up front.
loadAllDataFiles(false)