varkarrus

Dynamic Dungeon 2

Sep 21st, 2020
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 49.20 KB | None | 0 0
  1.  
  2.  
  3. // INPUT MODIFIER
  4.  
  5.  
  6. function findLast(text,substr){
  7. var rtext = text.split("").reverse().join("");
  8. var rsubstr = substr.split("").reverse().join("");
  9. var reg = new RegExp("\\b"+rsubstr+"\\b")
  10. var index = rtext.search(reg);
  11. if(index != -1){index = rtext.length-index-rsubstr.length}
  12. return index;
  13. }
  14.  
  15.  
  16. function collectPreKeywords(text){
  17. if(!history || history.length <=1){return;}
  18. var recentHistory = text;
  19. var keywordList = [];
  20. for(var i =0; i <= Math.min(3,history.length-1);i++){
  21. recentHistory = history[(history.length-1)-i].text+recentHistory;
  22. }
  23.  
  24. recentHistory = recentHistory.toLowerCase();
  25. for(var i =0;i<state.races.length;i++){
  26. //var index = Math.max(recentHistory.lastIndexOf(state.races[i].name),recentHistory.lastIndexOf(state.races[i].plural))
  27. var index = Math.max(findLast(recentHistory,state.races[i].name),findLast(recentHistory,state.races[i].plural))
  28. if(index>=0){
  29. keywordList.push({word:state.races[i].name,index:index});
  30. }
  31. }
  32.  
  33. for(var i =0;i<state.jobs.length;i++){
  34. //var index = Math.max(recentHistory.lastIndexOf(state.jobs[i].name),recentHistory.lastIndexOf(state.jobs[i].plural))
  35. var index = Math.max(findLast(recentHistory,state.jobs[i].name),findLast(recentHistory,state.jobs[i].plural))
  36. if(index>=0){
  37. keywordList.push({word:state.jobs[i].name,index:index});
  38. }
  39. }
  40.  
  41. for(var i =0; i< state.worldEntries.length;i++){
  42. var index = -1;
  43. var splitTags = state.worldEntries[i].keys.split(",")
  44. for(var a =0; a < splitTags.length;a++){
  45. //index = Math.max(recentHistory.lastIndexOf(splitTags[a]),index)
  46. index = Math.max(findLast(recentHistory,splitTags[a]),index)
  47. }
  48. if(index >=0){
  49. keywordList.push({word:splitTags[0],index:index})
  50. }
  51.  
  52. }
  53. if(keywordList.length > 0){
  54. keywordList.sort((a,b)=>(a.index > b.index) ? -1: 1 );
  55. for(i = 0;i<keywordList.length;i++){
  56. addPreKeyword(keywordList[i].word);
  57. }
  58. }
  59. }
  60.  
  61.  
  62. function parseMemory(){
  63. addPreKeyword(state.worldEntries[Math.floor(Math.random()*state.worldEntries.length)].keys.split(',')[0].toLowerCase())
  64. //if(Math.random()*100>50){addPreKeyword(getRandWeight(state.races,1).name)}
  65. //if(Math.random()*100>50){addPreKeyword(getRandWeight(state.jobs,0).name)}
  66.  
  67. var preMemText = "";
  68. var postMemText = "";
  69. if(memory.length > 0){
  70. state.memory.context = memory.split("---")[0]+"\n"
  71.  
  72. var text = memory.split("---")[1];
  73. if(text!= null && text.length>0){
  74. if(text.toLowerCase().includes("[note:")){
  75. state.baseNote = text.split(/\[note:/i)[1].split("]")[0].replace(/(?:\r\n|\r|\n)/g, ']\n[');
  76. }else{
  77. state.baseNote = "";
  78. }
  79.  
  80. if(text.toLowerCase().includes("[encounter:")){
  81. var encounterText = text.split(/\[encounter:/i)[1].split("]")[0]
  82. state.encounter = {text:encounterText,encountered:true,race:{name:encounterText},duration:1,timeout:1}
  83. }
  84.  
  85. state.specialNotes = [];
  86. if(text.includes("[$")){
  87. var notes = text.split("[$");
  88. for(var i =0 ; i < notes.length;i++){
  89. notes[i] = notes[i].split("]")[0]
  90. var tag = notes[i].split(":")[0]
  91. if(notes.length>1){
  92. state.specialNotes.push({tag:tag,desc:notes[i]})
  93. }
  94. }
  95.  
  96. }
  97. }
  98.  
  99. }
  100. else{state.memory.context = ""};
  101. var memLength = state.memory.context.length;
  102.  
  103. for(var i =0; i < state.postKeywords.length;i+=1){
  104. var entry = makeEntry(state.postKeywords[i]);
  105. if(entry.length+postMemText.length+memLength < 1400){
  106. postMemText+=entry;
  107. }
  108. }
  109.  
  110. for(var i =0; i < state.preKeywords.length;i+=1){
  111. var entry = makeEntry(state.preKeywords[i]);
  112. if(entry.length+postMemText.length+preMemText.length+memLength < 1400){
  113. preMemText= entry+preMemText;
  114. }
  115. }
  116.  
  117. state.memory.context = preMemText+state.memory.context+postMemText+"\n---";
  118. }
  119.  
  120. function makeEntry(text){
  121. var lowered = text.toLowerCase();
  122. console.log(text);
  123. for(var i =0;i < state.races.length;i++){
  124. if(text == state.races[i].name.toLowerCase()){return"["+capitalizeFirst(state.races[i].plural)+": "+state.races[i].desc+"]\n";}
  125. }
  126. for(var i =0;i < state.jobs.length;i++){
  127. if(text == state.jobs[i].name.toLowerCase()){return"["+capitalizeFirst(state.jobs[i].plural)+": "+state.jobs[i].desc+"]\n";}
  128. }
  129. for(var i =0; i<state.worldEntries.length;i++){
  130. if(state.worldEntries[i].keys.toLowerCase().indexOf(lowered)!=-1){
  131. return "["+capitalizeFirst(state.worldEntries[i].keys.split(",")[0])+": "+state.worldEntries[i].desc+"]\n";}
  132. }
  133. return "";
  134. }
  135.  
  136.  
  137. function addNoteKeyword(text){
  138. if(!state.noteKeywords.includes(text)){
  139. state.noteKeywords.push(text);
  140. if(state.preKeywords.includes(text)){
  141. state.preKeywords = state.preKeywords.slice(state.preKeywords.indexOf(text),state.preKeywords.indexOf(text))
  142. }
  143. if(state.postKeywords.includes(text)){
  144. state.postKeywords = state.postKeywords.slice(state.postKeywords.indexOf(text),state.postKeywords.indexOf(text))
  145. }
  146. }
  147. }
  148.  
  149. function addPostKeyword(text){
  150. if(!state.postKeywords.includes(text) && !state.noteKeywords.includes(text)){
  151. state.postKeywords.push(text);
  152. if(state.preKeywords.includes(text)){
  153. state.preKeywords = state.preKeywords.slice(state.preKeywords.indexOf(text),state.preKeywords.indexOf(text))
  154. }
  155. }
  156. }
  157.  
  158. function addPreKeyword(text){
  159. if(!state.postKeywords.includes(text) && !state.preKeywords.includes(text) && !state.noteKeywords.includes(text)){
  160. state.preKeywords.push(text);
  161. }
  162. }
  163.  
  164.  
  165. function getRandWeight(list,id){
  166. var totalWeight = 0;
  167. for(var i = 0; i<list.length; i++){
  168. totalWeight += list[i].weight[id];
  169. }
  170. for(var i =0;i<list.length;i++){
  171. if(!list[i].baseChance){list[i].baseChance = [0,0]}
  172. list[i].baseChance[id] = Math.floor((list[i].weight[id]/totalWeight)*10000)/100;
  173. }
  174. var weight = Math.random()*totalWeight;
  175. for(var i =0; i<list.length;i++){
  176. weight -= list[i].weight[id];
  177. if(weight <=0){return list[i];}
  178. }
  179. return null;
  180. }
  181.  
  182. function aOrAn(text){
  183. lowered = text.toLowerCase();
  184. if(lowered.startsWith('a') || lowered.startsWith('e') || lowered.startsWith('i') || lowered.startsWith('o') || lowered.startsWith('u')){
  185. return true;
  186. }else{
  187. return false;
  188. }
  189. }
  190.  
  191. function capitalizeFirst(text){
  192. return text.substring(0,1).toUpperCase()+text.substring(1)
  193. }
  194. function uncapitalizeFirst(text){
  195. return text.substring(0,1).toLowerCase()+text.substring(1)
  196. }
  197.  
  198.  
  199.  
  200.  
  201. if(!memory){memory = "";}
  202. if(!state.preKeywords){state.preKeywords = []};
  203. if(!state.postKeywords){state.postKeywords = []};
  204. if(!state.noteKeywords){state.noteKeywords = []};
  205. if(!state.specialNotes){state.specialNotes = []};
  206.  
  207. const modifier = (text) => {
  208.  
  209. let modifiedText = text
  210. const lowered = text.toLowerCase()
  211.  
  212. if(lowered.includes("/dbupdate")){
  213. state.databaseInit = false;
  214. modifiedText = "";
  215. state.blockOutput=true;
  216. }
  217.  
  218. if(!state.databaseInit || state.databaseInit == false || Math.random()*100>80){
  219. //Declare Databases
  220. state.races = [
  221. {name:"human",plural:"humans",weight:[100,100],desc:"A common race. Their versatility and adaptability makes them prolific.",job:true},
  222. {name:"elf",plural:"elves",weight:[100,70],desc:"Long lived, graceful, and haughty. Elves have sharp teeth and venomous blood.",job:true},
  223. {name:"dwarf",plural:"dwarves",weight:[100,110],desc:"Stout and hardy. Dwarves can sense vibrations with their chitinous beards.",job:true},
  224. {name:"orc",plural:"orcs",weight:[100,150],desc:"Honorable and proud warriors, falsely considered savages.",job:true},
  225. {name:"cyclops",plural:"cyclopses",weight:[25,40],desc:"A fairly civilized lesser giant race, averaging 8 feet tall. Strong, and magically adept.",job:true},
  226. {name:"goblin",plural:"goblins",weight:[50,200],desc:"Small, mischevious, and agile. Goblins are smarter than others give them credit for.",job:true},
  227. {name:"gnome",plural:"gnomes",weight:[65,40],desc:"Culturally proficient at magitek. Gnomes often use magitek weaponry.",job:true},
  228. {name:"dryad",plural:"dryads",weight:[30,60],desc:"Plant-like humanoids. Usually have either prehensile vines, branches, or flowers for hair.",job:true},
  229. {name:"oread",plural:"oreads",weight:[30,60],desc:"Humanoids with stone-like skin and crystalline hair. Associated with Earth, and live in mountains.",job:true},
  230. {name:"naiad",plural:"naiads",weight:[30,60],desc:"Aquatic humanoids with webbed feet and hands, and slick amphibious skin.",job:true},
  231. {name:"devil",plural:"devils",weight:[30,90],desc:"Archetypical demons, with red skin, forked tails, and horns.",job:true},
  232. {name:"kobold",plural:"kobolds",weight:[30,150],desc:"Humanoid synapsids with a mix of mammal and reptile traits. Small and agile.",job:true},
  233. {name:"oni",plural:"onis",weight:[30,60],desc: "Strong, ogre-like demons with red or blue skin and 1-3 eyes. Some use storm magic. Onis love alcohol.",job:true},
  234. {name:"marilith",plural:"mariliths",weight:[10,40],desc:"Six-armed demons with snake tails instead of legs. Often wield many weapons at once.",job:true},
  235. {name:"amazon",plural:"amazons",weight:[40,30],desc: "An all-female race of lesser giants. Average over seven feet tall, and usually live in the jungle.",job:true},
  236. {name:"centaur",plural:"centaurs",weight:[40,30],desc: "A humanoid upper torso atop a horse's body. Centaurs have trouble with stairs.",job:true},
  237. {name:"arachne",plural:"arachnes",weight:[40,40],desc: "A humanoid upper torso atop a giant spider's body. They can climb walls and are at home underground.",job:true},
  238. {name:"harpy",plural:"harpies",weight:[40,30],desc:"Bird-like humanoids with wings for arms. They carry weapons using their feet instead.",job:true},
  239. {name:"naga",plural:"nagas",weight:[40,40],desc:"A humanoid upper torso atop a snake's body. Their slithering gives them versatile movement.",job:true},
  240. {name:"foocubus",plural:"foocubi",weight:[10,50],desc:"Demons who feed off of lust, including power and knowledge. 'Foocubus' is a gender neutral term for succubus or incubus.",job:true},
  241. {name:"succubus",plural:"succubi",weight:[0,0],desc:"A term for a female foocubus.",job:true},
  242. {name:"incubus",plural:"incubi",weight:[0,0],desc:"A term for a male foocubus.",job:true},
  243. {name:"minotaur",plural:"minotaurs",weight:[25,45],desc:"Humanoid bulls who like to show off their strength.",job:true},
  244. {name:"imp",plural:"imps",weight:[20,90],desc:"Small, goblin sized demons with wings. Tricky and mischevious, often use fire magic.",job:true},
  245. {name:"golem",plural:"golems",weight:[5,50],desc:"Automatons made of various materials, such as clay, metal, or even flesh. Golems don't work on Sundays.",job:true},
  246. {name:"tardigrade-kin",plural:"tardigrade-kins",weight:[15,20],desc:"Humanoid tardigrades. They have six arms and are extremely resilient, thanks to their cryptobiosis.",job:true},
  247. {name:"dullahan",plural:"dullahans",weight:[30,50],desc:"Fae with severed heads, and an affinity for mounted combat. Their heads can fly and scout ahead.",job:true},
  248. {name:"gargoyle",plural:"gargoyles",weight:[30,60],desc:"Winged humanoids that turn to statues during the day while they sleep.",job:true},
  249. {name:"angel",plural:"angels",weight:[10,30],desc:"Winged humanoids from the heavens with holy powers. Most angels are good, but some angels are evil.",job:true},
  250. {name:"tanuki",plural:"tanukis",weight:[15,30],desc:"Shapeshifting humanoid raccoons. They are tricky and mischevious, but usually friendly.",job:true},
  251. {name:"kitsune",plural:"kitsunes",weight:[5,25],desc:"Shapeshifting humanoid foxes. They are agile and sneaky.",job:true},
  252. {name:"mind flayer",plural:"mind flayers",weight:[20,40],desc:"Intelligent, psychic humanoids with tentacles on their mouths. They eat minds.",job:true},
  253. {name:"gnoll",plural:"gnolls",weight:[20,90],desc:"A race of humanoid hyenas with a savage love of fighting.",job:true},
  254. {name:"mothman",plural:"mothmen",weight:[25,50],desc:"A race of humanoid moths. They have elegant wings and love bright lights.",job:true},
  255. {name:"living armor",plural:"living armors",weight:[5,80],desc:"An animated suit of armor, with no-one inside. Some living armors are sentient.",job:true},
  256.  
  257. //monster races
  258. {name:"hekatonchire",plural:"hekatoncheires",weight:[0,30],desc:"Massive, formless giants made up of arms and faces. They are powerful creations of the old gods.",job:false},
  259. {name:"slime",plural:"slimes",weight:[0,125],desc:"Common jelly-like monsters that are weak, but hard to kill.",job:false},
  260. {name:"meat man",plural:"meat men",weight:[0,40],desc:"Created through perverse Life magic. Their regenerative abilities make them easy to defeat, but hard to kill.",job:false},
  261. {name:"zombie",plural:"zombies",weight:[0,120],desc:"Common undead. All brawn and no brains, which is why they'd like to eat yours.",job:false},
  262. {name:"skeleton",plural:"skeletons",weight:[0,120],desc:"Common undead. Fragile, and tend to appear in large numbers.",job:false},
  263. {name:"manticore",plural:"manticores",weight:[0,40],desc:"Beasts with a lion's body, bat wings, and a scorpion's tail.",job:false},
  264. {name:"mimic",plural:"mimics",weight:[0,80],desc:"Hermit crab like monsters that inhabit chests or similar objects.",job:false},
  265. {name:"jotunn",plural:"jotunns",weight:[0,35],desc:"A race of giants, three times the height that of a human.",job:true},
  266. {name:"ogre",plural:"ogres",weight:[0,60],desc:"A race of giants, averaging eleven feet tall. They sleep a lot and are herbivores, but are still dangerous if provoked.",job:false},
  267. {name:"troll",plural:"trolls",weight:[0,90],desc:"Vicious and agile lesser giants, with long limbs, big claws, and shaggy bodies. They hate bright light.",job:false},
  268. {name:"poison dart raccoon",plural:"poison dart raccoons",weight:[0,55],desc:"Large poisonous rodents that are often found in dungeons. They are clever beasts.",job:false},
  269. {name:"gremlin",plural:"gremlins",weight:[0,90],desc:"Small monstrous fairies that like to tear through metal (especially machines) with their claws and teeth.",job:false},
  270. {name:"balrog",plural:"balrogs",weight:[0,25],desc:"Giant, powerful demons with horns, hooves, and wings. They are powerful, but not too magically potent.",job:false},
  271. {name:"beholder",plural:"beholders",weight:[0,50],desc:"Flying monsters with one large eye, and many eyestalks. They use magical lasers.",job:false},
  272. {name:"shoggoth",plural:"shoggoths",weight:[0,20],desc:"Formless creations of the old gods. Shoggoths are liquid blobs of flesh, eyes, and tentacles.",job:false},
  273. {name:"behemoth",plural:"behemoths",weight:[0,30],desc:"Large, thick-skinned animals native to the demon realm. They are used as war animals by demons.",job:false},
  274. {name:"domination",plural:"dominations",weight:[0,30],desc:"Bipedal, gorilla-like animals native to the heavenly realm. They are used as war animals by angels.",job:false},
  275. {name:"hydra",plural:"hydras",weight:[0,30],desc:"An ambulatory plant monster that resembles a wingless dragon. It has multiple heads, and if you cut one off, it grows new ones.",job:false},
  276. {name:"grue",plural:"grues",weight:[0,20],desc:"A deadly and ravenous monster that can only be found in pitch darkness. Even a dim light will repel them.",job:false},
  277.  
  278. //elementals
  279. {name:"fire elemental",plural:"fire elementals",weight:[0,25],desc:"A magical entity formed from the destructive element of fire.",job:false},
  280. {name:"ice elemental",plural:"ice elementals",weight:[0,25],desc:"A magical entity formed from the calming element of ice.",job:false},
  281. {name:"earth elemental",plural:"earth elementals",weight:[0,25],desc:"A magical entity formed from the hardy element of earth.",job:false},
  282. {name:"air elemental",plural:"air elementals",weight:[0,25],desc:"A magical entity formed from the swift element of air.",job:false},
  283. {name:"sun elemental",plural:"sun elementals",weight:[0,20],desc:"A magical entity formed from the revealing element of sun.",job:false},
  284. {name:"dream elemental",plural:"dream elementals",weight:[0,20],desc:"A magical entity formed from the mistifying element of dream.",job:false},
  285. {name:"life elemental",plural:"life elementals",weight:[0,20],desc:"A magical entity formed from the growing element of life.",job:false},
  286. {name:"death elemental",plural:"death elementals",weight:[0,20],desc:"A magical entity formed from the decaying element of death.",job:false},
  287. {name:"poutine elemental",plural:"poutine elementals",weight:[0,10],desc:"A magical entity formed from the peaceful element of poutine.",job:false},
  288. {name:"knife elemental",plural:"knife elementals",weight:[0,10],desc:"A magical entity formed from the violent element of knives.",job:false},
  289. {name:"surprise elemental",plural:"surprise elementals",weight:[0,10],desc:"A magical entity formed from the the chaotic element of surprise.",job:false},
  290.  
  291. //dragons
  292. {name:"fire dragon",plural:"fire dragons",weight:[0,15],desc:"A winged synapsid that breaths fire.",job:false},
  293. {name:"ice dragon",plural:"ice dragons",weight:[0,15],desc:"A winged synapsid that breaths ice.",job:false},
  294. {name:"air dragon",plural:"air dragons",weight:[0,15],desc:"A winged synapsid that produces lightning.",job:false},
  295. {name:"earth dragon",plural:"earth dragons",weight:[0,15],desc:"A wingless dragon that induces earthquakes.",job:false},
  296. {name:"sun dragon",plural:"sun dragons",weight:[0,8],desc:"A winged synapsid that emits blinding light.",job:false},
  297. {name:"dream dragon",plural:"dream dragons",weight:[0,8],desc:"A serpentine synapsid that breaths hallucinogenic mist.",job:false},
  298. {name:"knife dragon",plural:"knife dragons",weight:[0,5],desc:"Violent, winged synapsids that fire shards of metal from their mouths.",job:false},
  299. {name:"poutine dragon",plural:"poutine dragons",weight:[0,5],desc:"Gluttonous winged synapsids that blast molten poutine from their mouths.",job:false}
  300. ]
  301.  
  302. state.jobs = [
  303. {name:"warrior",plural:"warriors",weight:[100],desc:"Typical sword & shield types.",elab:"wields [a sword,an axe,a hammer,a spear] and a shield."},
  304. {name:"ranger",plural:"rangers",weight:[100],desc:"Agile bow-wielding combatants.",elab:"wields [a bow,a crossbow], and looks quite agile."},
  305. {name:"monk",plural:"monks",weight:[60],desc:"Martial artists who fight using chi, and without weapons.",elab:"fights using martial arts and the power of chi."},
  306. {name:"berserker",plural:"berserkers",weight:[70],desc:"Fighters who use huge weapons and rage to fight.",elab:"has a huge [sword,axe,hammer,polearm,club] and a menacing gaze."},
  307. {name:"juggernaut",plural:"juggernauts",weight:[60],desc:"Heavily armored, slow-moving fighters.", elab:"is unusually large, and heavily armored."},
  308. {name:"rogue",plural:"rogues",weight:[100],desc:"Sneaky, stabby types. Hard to pin down. Associated with the element of Surprise.", elab:"is lithe and sneaky, and ready to stab."},
  309. {name:"lich",plural:"liches",weight:[50],desc:"Skeletal undead that retain their intelligence. They have enhanced strength and dark magic.", elab:"is a skeletal undead with [unholy strength and weapons,dark magical powers]."},
  310. {name:"vampire",plural:"vampires",weight:[50],desc:"Classic blood-suckers. Not all vampires are formerly human, of course.", elab:"is also a vampire, with a thirst for blood."},
  311. {name:"wizard",plural:"wizards",weight:[100],desc:"Well-rounded but fragile spellcasters.", elab:"is wearing robes, and carrying an ornate staff."},
  312. {name:"ninja",plural:"ninjas",weight:[50],desc:"Masters of stealth, traps, and sword-fighting.", elab:"wields a [ninjatō,katana,wakizashi], carries [shuriken,throwing knives,caltrops,smoke powder], and is lurking out of sight."},
  313. {name:"bard",plural:"bards",weight:[60],desc:"Spellcasters who use music and charisma to control their foes.",elab:"[sings,plays a lute,plays a guitar,plays a keyboard,plays a keytar,plays a flute,plays a trumpet,plays a ukulele,plays a violin,plays a theremin,badly plays a recorder,plays an otamatone] as the source of their magic."},
  314. {name:"dancer",plural:"dancers",weight:[40],desc:"Agile warriors who disorient foes before stabbing them with hidden weapons.",elab:"is adorned with ribbons, carries a knife, and moves hypnotically."},
  315. {name:"paladin",plural:"paladins",weight:[80],desc:"Warrior spellcasters who use divine magic to protect themselves and others.",elab:"is heavily armored, and [shining with holy magic,clouded with unholy magic]."},
  316. {name:"assassin",plural:"assassins",weight:[40],desc:"Masters of stealth who try to kill their foes in a single strike.",elab:"is waiting for the perfect moment to strike."},
  317. {name:"alchemist",plural:"alchemists",weight:[50],desc:"Potion brewers who use explosive flasks and toxic gasses.",elab:"is carrying an assortment of potions on their person."},
  318. {name:"necromancer",plural:"necromancers",weight:[80],desc:"Spellcasters who conjure and control the undead.",elab:"is accompanied by several reanimated servants."},
  319. {name:"demonologist",plural:"demonologists",weight:[70],desc:"Spellcasters who summon and bind demons.",elab:"is accompanied by a powerful demon servant."},
  320. {name:"fencer",plural:"fencers",weight:[40],desc:"Agile sword-fighters who wield a rapier.",elab:"is wielding a rapier, and capable of swift movements."},
  321. {name:"barbarian",plural:"barbarians",weight:[60],desc:"Brutish warriors who dual-wield weapons.",elab:"is ferocious, and wields [a sword,an axe] in each hand."},
  322. {name:"sniper",plural:"snipers",weight:[30],desc:"Ranged warriors who use bows or rifles from very long distances.",elab:"wields [a longbow,a rifle], ready to attack from afar."},
  323. {name:"gunslinger",plural:"gunslingers",weight:[50],desc:"Agile gun-slinging combatants who weave in and out of range.", elab:"wields [a revolver,a revolver in each hand], and is quick to react."},
  324. {name:"druid",plural:"druids",weight:[40],desc:"Martial spellcasters who channel the power of nature.", elab:"is dressed in druidic gear, ready to channel nature's power."},
  325. {name:"spellblade",plural:"spellblades",weight:[50],desc:"Magical warriors who use both weapons and magic.", elab:"is wielding a blade infused with magical energy."},
  326. {name:"psion",plural:"psions",weight:[30],desc:"Magical mentalists who use psychic powers, such as telekinesis and mind control.",elab:"is levitating, ready to unleash psychic powers."},
  327. {name:"magician",plural:"magicians",weight:[30],desc:"More like a rogue than a wizard, these spellcasters use both sleight of hand and magic.", elab:"wears a top-hat, and uses a mix of magic, sleight of hand, and knife-play."},
  328. {name:"skirmisher",plural:"skirmishers",weight:[50],desc:"Agile spear-wielding foes who keep just out of reach of opponents.", elab:"wields a long spear, capable of agile movements."},
  329. {name:"gladiator",plural:"gladiators",weight:[40],desc:"Agile, lightly-armored, and well-rounded fighters.", elab:"wields [a gladius,a trident,a bladed cestus], and wears light armor."},
  330. {name:"oracle",plural:"oracles",weight:[30],desc:"Utilitarian spellcasters who use clairvoyance and future vision.", elab:"carries a staff, and can see what other cannot."},
  331. {name:"biomancer",plural:"biomancers",weight:[30],desc:"Spellcasters who alter and mutate their biology through magic.", elab:"uses magic to mutate and enhance their body for combat."},
  332. {name:"artificer",plural:"artificers",weight:[50],desc:"Spellcasters who use their magic to create and wield enchanted armaments.", elab:"is equipped with self-made magitek equipment."},
  333.  
  334. //mages
  335. {name:"fire mage",plural:"fire mages",weight:[30],desc:"Spellcasters who use the element of Fire, to bring destruction.", elab:"wields the destructive element of Fire, blazing with heat."},
  336. {name:"ice mage",plural:"ice mages",weight:[30],desc:"Spellcasters who use the element of Ice, and require utmost calm.", elab:"wields the calm element of Ice, surrounded by cool air."},
  337. {name:"earth mage",plural:"earth mages",weight:[30],desc:"Spellcasters who use the element of Earth, and have high endurance.", elab:"wields the hardy element of Earth, shaking the ground."},
  338. {name:"air mage",plural:"air mages",weight:[30],desc:"Spellcasters who use the element of Air, and are always in motion.", elab:"wields the swift element of Air, and crackles with lightning."},
  339. {name:"sun mage",plural:"sun mages",weight:[20],desc:"Spellcasters who use the element of Sun, to bring truth.", elab:"wields the revealing element of Sun, and emits a bright light."},
  340. {name:"dream mage",plural:"dream mages",weight:[20],desc:"Spellcasters who use the element of Dream, to create illusions.", elab:"wields the mistifying element of Dream, capable of making illusions."},
  341. {name:"life mage",plural:"life mages",weight:[20],desc:"Spellcasters who use the element of Life, to induce growth and healing.", elab:"wields the verdant element of Life, surrounded by plants."},
  342. {name:"death mage",plural:"death mages",weight:[20],desc:"Spellcasters who use the element of Death, to induce decay and stasis.", elab:"wields the decaying element of Death, with a toxic aura."},
  343. {name:"knife mage",plural:"knife mages",weight:[10],desc:"Spellcasters who use the element of Knives, to shed blood and spread hatred.", elab:"wields the violent element of Knifes, with a scarred body."},
  344. {name:"poutine mage",plural:"poutine mages",weight:[10],desc:"Spellcasters who use the element of Poutine, to promote peace and safety.", elab:"wields the nourishing element of Poutine, and smells delicious."},
  345. {name:"surprise mage",plural:"surprise mages",weight:[5],desc:"Spellcasters who use the element of Surprise, to unpredictable effect.", elab:"wields the chaotic element of Surprise, to unknown effect"},
  346.  
  347. //rare jobs
  348. {name:"luchador",plural:"luchadors",weight:[20],desc:"Tough wrestlers who gain supernatural strength as long as they wear their mask.", elab:"wears a strength-enhancing wrestling mask, following the path of Lucha."},
  349. {name:"bouncer",plural:"bouncers",weight:[20],desc:"Hardy fighters who serve as impassable walls and guard their allies.", elab:"wields brass knuckles, and has an imposing presence."},
  350. {name:"engineer",plural:"engineers",weight:[20],desc:"Experts at mechanical engineering, which they use for a variety of purposes.", elab:"is equipped with strange mechanisms, and smeared with oil."},
  351. {name:"brewmaster",plural:"brewmasters",weight:[20],desc:"Fighters who brew alcoholic beverages, and are stronger when drunk.", elab:"is extremely drunk, but ready to fight nonetheless."},
  352. {name:"clown",plural:"clowns",weight:[10],desc:"Clowns are terrifying and surprisingly hardy masters of mischief and misdirection.", elab:"may be a clown, but is not to be underestimated."},
  353. {name:"nekomancer",plural:"nekomancers",weight:[10],desc:"Spellcasters who summon, control, and channel the power of cats. Yes, seriously.", elab:"is adorned with many cat-themed accessories, including a pair of claws."},
  354. {name:"stand user",plural:"stand users",weight:[5],desc:"Those who can manifest a \"Stand;\" an extension of their willpower that takes the form of a warrior.",elab:"can manifest a warrior known as a 'Stand' that serves as an extension of their will."}
  355. ]
  356.  
  357. state.worldEntries = [
  358. {keys:"fire,flame",desc:"One of the eleven elements. Fire embodies passion and rage, and opposes ice. It is red."},
  359. {keys:"ice",desc:"One of the eleven elements. Ice embodies calm and willpower, and opposes fire. It is blue."},
  360. {keys:"air",desc:"One of the eleven elements. Air embodies motion and wanderlust, and opposes earth. It is white."},
  361. {keys:"earth",desc:"One of the eleven elements. Earth embodies stasis and endurance, and opposes air. It is brown."},
  362. {keys:"sun",desc:"One of the eleven elements. Sun embodies truth and reality, and opposes dream. It is yellow."},
  363. {keys:"dream",desc:"One of the eleven elements. Dream embodies illusion and fantasy, and opposes sun. It is purple."},
  364. {keys:"life",desc:"One of the eleven elements. Life embodies growth and healing, and opposes death. It is green."},
  365. {keys:"death",desc:"One of the eleven elements. Death embodies decay and stasis, and opposes life. It is black."},
  366. {keys:"knives,knife",desc:"One of the eleven elements. Knives embodies violence and hatred, and opposes poutine. It is gray."},
  367. {keys:"poutine",desc:"One of the eleven elements. Poutine embodies peace and safety, and opposes knives. It is beige."},
  368. {keys:"surprise",desc:"One of the eleven elements. Surprise embodies chance and chaos, and is the only element without an opposite. It is rainbow."},
  369. {keys:"elements,element",desc:"The eleven classic elements are fire, ice, air, earth, sun, dream, life, death, knives, poutine, and surprise."},
  370. {keys:"deepmouth dungeon,deepmouth,dungeon",desc:"The dungeon you are exploring. It leads into the abyss, where an evil entity awaits."},
  371. {keys:"demon,devil",desc:"There are many species of demon. Not all demons are evil, though many are."},
  372. {keys:"giant",desc:"There are many species of giants and lesser giants, such as cyclopses, jotunn, amazonians, ogres, and more."}
  373. ]
  374.  
  375. state.modifiers = [
  376. {name:"dead",weight:[50]},
  377. {name:"hostile",weight:[60]},
  378. {name:"friendly",weight:[90]},
  379. {name:"female",weight:[120]},
  380. {name:"male",weight:[120]},
  381. {name:"wounded",weight:[90]},
  382. {name:"unaware",weight:[100]},
  383. {name:"???",weight:[10]},
  384. {name:"undead",weight:[40]},
  385. {name:"elite",weight:[60]}
  386. ]
  387. state.databaseInit = true;
  388. }
  389.  
  390. if(!state.init){
  391. //Character Creation + initial setup
  392. modifiedText = modifiedText.split('[]');
  393. state.name = modifiedText[1];
  394. state.race = modifiedText[3];
  395. state.job = modifiedText[5];
  396. //You are []Name[], a an []random[] []random[].
  397. if(state.race.toLowerCase().includes("random")){state.race = getRandWeight(state.races,0).name;modifiedText[3] = state.race}
  398. if(state.job.toLowerCase().includes("random")){state.job = getRandWeight(state.jobs,0).name;modifiedText[5] = state.job}
  399. getRandWeight(state.races,1) //purely for debugging
  400.  
  401. modifiedText = modifiedText.join('');
  402. if(aOrAn(state.race)){
  403. modifiedText = modifiedText.replace(/a an/g,"an");
  404. }else{
  405. modifiedText = modifiedText.replace(/a an/g,"a");
  406. }
  407. addPostKeyword(state.race);
  408. addPostKeyword(state.job);
  409. state.init = true;
  410. }
  411.  
  412.  
  413. //commands
  414.  
  415. if(lowered.includes("/forceencounter")||lowered.includes("/force encounter")){
  416. state.encounter = null;
  417. state.forceEncounter = true;
  418. modifiedText = "";
  419. state.blockOutput = true;
  420. }
  421.  
  422. if(lowered.includes("/setname")||lowered.includes("/set name")){
  423. if(!lowered.includes("[")){
  424. state.message = "Put your name in square brackets, i.e: \"/setname [name]\""
  425. }else{
  426. var re = /\[((.|\n)*)\]/;
  427. state.name = modifiedText.match(re)[1];
  428. state.message = "Name is now "+state.name;}
  429. state.blockOutput = true;
  430. modifiedText = "";
  431. }
  432. if(lowered.includes("/setclass")||lowered.includes("/set class")){
  433. if(!lowered.includes("[")){
  434. state.message = "Put your class in square brackets, i.e: \"/setclass [random]\""
  435. }else{
  436. var re = /\[((.|\n)*)\]/;
  437. state.job = modifiedText.match(re)[1];
  438. if(state.job.toLowerCase().includes("random")){state.job = getRandWeight(state.jobs,0).name}
  439. state.message = "Class is now "+state.job;}
  440. state.blockOutput = true;
  441. modifiedText = "";
  442. }
  443. if(lowered.includes("/setrace")||lowered.includes("/set race")){
  444. if(!lowered.includes("[")){
  445. state.message = "Put your race in square brackets, i.e: \"/setrace [random]\""
  446. }else{
  447. var re = /\[((.|\n)*)\]/;
  448. state.race = modifiedText.match(re)[1];
  449. if(state.race.toLowerCase().includes("random")){state.race = getRandWeight(state.races,0).name}
  450. state.message = "Race is now "+state.race;}
  451. state.blockOutput = true;
  452. modifiedText = "";
  453. }
  454.  
  455. if(lowered.includes("/setencounter")||lowered.includes("/set encounter")){
  456. if(!lowered.includes("[")){
  457. state.message = "If you want a random encounter, use /forceencounter. To use /setencounter, put your encounter in square brackets, i.e: \"/setencounter [goblins]\""
  458. }
  459. else{
  460. var re = /\[((.|\n)*)\]/;
  461. var text = modifiedText.match(re)[1];
  462. state.encounter = {duration:3,timeout:8,text:text,encountered:false,desc:""};
  463.  
  464. for(var i = 0;i<state.races.length;i++){
  465. if(text.toLowerCase().includes(state.races[i].name) || text.toLowerCase().includes(state.races[i].plural)){
  466. state.encounter.race = state.races[i];
  467. state.encounter.desc = capitalizeFirst(state.races[i].plural)+" are "+uncapitalizeFirst(state.races[i].desc)
  468. }
  469. }
  470. for(var i = 0;i<state.jobs.length;i++){
  471. if(text.toLowerCase().includes(state.jobs[i].name) || text.toLowerCase().includes(state.jobs[i].plural)){
  472. state.encounter.class = state.jobs[i];
  473. state.encounter.desc += " "+capitalizeFirst(state.jobs[i].plural)+" are "+uncapitalizeFirst(state.jobs[i].desc)
  474. }
  475. }
  476. if(state.encounter.race == null){state.encounter.race = {name:text}}
  477. }
  478. modifiedText = "";
  479. state.blockOutput = true;
  480. }
  481.  
  482. if(lowered.includes("/help")){
  483. modifiedText = "Current list of commands and option blocks:\n"+
  484. "/forceEncounter: forces the AI to generate a random encounter\n"+
  485. "/setName [name]: rename the player. \n"+
  486. "/setRace [race]: change your race (can be set to \"random\")\n"+
  487. "/setClass [class]: change your class (can be set to \"random\")\n"+
  488. "[note: text] Insert this in memory below the --- to add an author's note. More option blocks like these will be added later.\n"+
  489. "[$skill name: text] If \"skill name\" is mentioned in input, adds the entry to author's note. You can have as many skills as you'd like in the option area of memory."
  490. state.blockOutput = true;
  491. }
  492.  
  493. if(lowered.includes("/dbprint")){
  494. var string = "races: ";
  495. for(var i =0;i<state.races.length;i++){
  496. string+= state.races[i].name+", ";
  497. }
  498. string+="\n\nclasses: "
  499. for(var i=0;i<state.jobs.length;i++){
  500. string+= state.jobs[i].name+", ";
  501. }
  502. modifiedText = string;
  503. }
  504.  
  505.  
  506. collectPreKeywords(modifiedText);
  507. parseMemory();
  508.  
  509. // You must return an object with the text property defined.
  510. return {text: modifiedText}
  511.  
  512.  
  513.  
  514.  
  515. }
  516.  
  517. // Don't modify this part
  518. modifier(text)
  519.  
  520. // CONTEXT MODIFIER
  521.  
  522. function capitalizeFirst(text){
  523. return text.substring(0,1).toUpperCase()+text.substring(1)
  524. }
  525. function uncapitalizeFirst(text){
  526. return text.substring(0,1).toLowerCase()+text.substring(1)
  527. }
  528. function aOrAn(text){
  529. lowered = text.toLowerCase();
  530. if(lowered.startsWith('a') || lowered.startsWith('e') || lowered.startsWith('i') || lowered.startsWith('o') || lowered.startsWith('u')){
  531. return "an "+text;
  532. }else{
  533. return "a "+text;
  534. }
  535. }
  536. function parseDesc(text){
  537. if(text.includes("[")){
  538. var splits = text.split("[");
  539. for(var i =0 ;i < splits.length;i++){
  540. if(splits[i].includes("]")){
  541. var remainder = splits[i].split("]")[1];
  542. splits[i] = splits[i].split("]")[0].split(",");
  543. splits[i] = splits[i][Math.floor(Math.random()*splits[i].length)]+remainder;
  544. }
  545. }
  546. text = splits.join("");
  547. }
  548. return text;
  549. }
  550.  
  551.  
  552. function generateNote(text){
  553. state.authorsNote="["
  554. state.authorsNote += "You are "+state.name+", the "+state.race+" "+state.job+".";
  555. if(state.baseNote!=""){
  556. state.authorsNote+=" "+state.baseNote
  557. }
  558.  
  559. if(state.noteKeywords.length>0){
  560. for(var i =0 ; i < state.noteKeywords.length;i++){
  561. var string = "]\n"+makeEntry(state.noteKeywords[i]);
  562. string = string.slice(0,-2);
  563. state.authorsNote+=string;
  564. }
  565. }
  566. state.authorsNote+="]";
  567. }
  568.  
  569. function getEncounterNote(hist){
  570. var text = "";
  571. if(state.encounter!=null){
  572. if(state.encounter.encountered == false){
  573. text+="[Approaching Encounter: "+capitalizeFirst(state.encounter.text)+"]"}
  574. else{text+="[Current Encounter: "+capitalizeFirst(state.encounter.text)+"]";}
  575. if(state.encounter.desc!=null && state.encounter.desc.length > 1){
  576. text+= "\n["+state.encounter.desc+"]"
  577. }
  578. }
  579. return text;
  580. }
  581.  
  582. function getSpecialNotes(hist){
  583. var text = "";
  584. for(var i = 0; i < state.specialNotes.length;i++){
  585. if(hist.toLowerCase().includes(state.specialNotes[i].tag.toLowerCase())){
  586. if(text.length>0){text+="\n"}
  587. text+="["+state.specialNotes[i].desc+"]";
  588. }
  589. }
  590. return text;
  591. }
  592.  
  593. const combineLines = (lines)=>{
  594. var finalLines = "";
  595. for(var i = lines.length-1;i >= 0;i--){
  596.  
  597. if(finalLines.length + lines[i].length < state.info.maxChars - state.info.memoryLength){
  598. finalLines = lines[i]+"\n"+finalLines;
  599. }
  600. else{return finalLines;}
  601. }
  602. return finalLines;
  603.  
  604. }
  605.  
  606. if(!info.maxChars){info = {maxChars:2800,memoryLength:0,actionCount:0}}
  607.  
  608. const modifier = (text) => {
  609. const memory = info.memoryLength ? text.slice(0, info.memoryLength) : ''
  610. var context = info.memoryLength ? text.slice(info.memoryLength + 1) : text
  611. state.info = info;
  612.  
  613. generateNote();
  614. context = context.replace(/\n\n/g,"\n")
  615. const lines = context.split("\n")
  616. var actionOffset = 0;
  617.  
  618. for(var i =0; i < 2;i++){
  619. if(i < lines.length-1 && lines[lines.length-1-i].includes(">")){
  620. actionOffset = i;
  621. break;
  622. }
  623. }
  624.  
  625. if (lines.length > 2) {
  626.  
  627. lines.splice(-3-actionOffset, 0, state.authorsNote)
  628.  
  629. var hist = lines.join("\n");
  630.  
  631. encounterNote = getEncounterNote(hist.substring(Math.max(0,hist.length-500)));
  632.  
  633. if(encounterNote!=""){
  634. lines.splice(state.encounter.encountered ? -3-actionOffset : -1-actionOffset,0,encounterNote);
  635. }
  636. var specialNotes = getSpecialNotes(hist)
  637. if(specialNotes!=""){
  638. lines.splice(-1-actionOffset,0,specialNotes);
  639. }
  640.  
  641. }
  642. // Make sure the new context isn't too long, or it will get truncated by the server.
  643. const combinedLines = combineLines(lines);
  644. const finalText = [memory, combinedLines].join("")
  645. return { text: finalText }
  646. }
  647.  
  648. // Don't modify this part
  649. modifier(text)
  650.  
  651.  
  652. // OUTPUT MODIFIER
  653.  
  654.  
  655. // Checkout the repo examples to get an idea of other ways you can use scripting
  656. // https://github.com/AIDungeon/Scripting/blob/master/examples
  657.  
  658.  
  659. function findLast(text,substr){
  660. var rtext = text.split("").reverse().join("");
  661. var rsubstr = substr.split("").reverse().join("");
  662. var reg = new RegExp("\\b"+rsubstr+"\\b")
  663. var index = rtext.search(reg);
  664. if(index != -1){index = rtext.length-index-rsubstr.length}
  665. return index;
  666. }
  667.  
  668.  
  669. function collectPreKeywords(text){
  670.  
  671. if(!history || history.length <=1){return;}
  672. var recentHistory = text;
  673. var keywordList = [];
  674.  
  675. for(var i =0; i < history.length;i++){
  676. if(recentHistory.length + history[(history.length-1)-i].text.length < 800){
  677. recentHistory = history[(history.length-1)-i].text+recentHistory;
  678. }else{
  679. break;
  680. }
  681. }
  682.  
  683.  
  684. recentHistory = recentHistory.toLowerCase();
  685.  
  686. if(state.encounter!=null && state.encounter.encountered == false){
  687. var encounterTags = state.encounter.text.split(" ")
  688.  
  689. for(var i =0; i < encounterTags.length;i++){
  690. if(encounterTags[i].length > 2 && recentHistory.includes(encounterTags[i].toLowerCase())){state.encounter.encountered = true;state.noteKeywords = [];}
  691. }
  692. if(recentHistory.includes(state.encounter.race.name) || recentHistory.includes(state.encounter.race.plural)){state.encounter.encountered = true;state.noteKeywords = [];}
  693. }
  694.  
  695.  
  696. for(var i =0;i<state.races.length;i++){
  697. //var index = Math.max(recentHistory.lastIndexOf(state.races[i].name),recentHistory.lastIndexOf(state.races[i].plural))
  698. var index = Math.max(findLast(recentHistory,state.races[i].name),findLast(recentHistory,state.races[i].plural))
  699. if(index>=0){
  700. keywordList.push({word:state.races[i].name,index:index});
  701. }
  702. }
  703.  
  704. for(var i =0;i<state.jobs.length;i++){
  705. //var index = Math.max(recentHistory.lastIndexOf(state.jobs[i].name),recentHistory.lastIndexOf(state.jobs[i].plural))
  706. var index = Math.max(findLast(recentHistory,state.jobs[i].name),findLast(recentHistory,state.jobs[i].plural))
  707. if(index>=0){
  708. keywordList.push({word:state.jobs[i].name,index:index});
  709. }
  710. }
  711.  
  712. for(var i =0; i< state.worldEntries.length;i++){
  713. var index = -1;
  714. var splitTags = state.worldEntries[i].keys.split(",")
  715. for(var a =0; a < splitTags.length;a++){
  716. //index = Math.max(recentHistory.lastIndexOf(splitTags[a]),index)
  717. index = Math.max(findLast(recentHistory,splitTags[a]),index)
  718. }
  719. if(index >=0){
  720. keywordList.push({word:splitTags[0],index:index})
  721. }
  722.  
  723. }
  724. if(keywordList.length > 0){
  725. keywordList.sort((a,b)=>(a.index > b.index) ? -1: 1 );
  726. for(i = 0;i<keywordList.length;i++){
  727. addPreKeyword(keywordList[i].word);
  728. }
  729. }
  730. }
  731.  
  732. function parseMemory(){
  733. addPreKeyword(state.worldEntries[Math.floor(Math.random()*state.worldEntries.length)].keys.split(',')[0].toLowerCase())
  734. //if(Math.random()*100>50){addPreKeyword(getRandWeight(state.races,1).name)}
  735. //if(Math.random()*100>50){addPreKeyword(getRandWeight(state.jobs,0).name)}
  736.  
  737. var preMemText = "";
  738. var postMemText = "";
  739.  
  740. if(memory.length > 0){
  741. state.memory.context = memory.split("---")[0]+"\n"
  742.  
  743. var text = memory.split("---")[1];
  744. if(text!= null && text.length>0){
  745. if(text.toLowerCase().includes("[note:")){
  746. state.baseNote = text.split(/\[note:/i)[1].split("]")[0].replace(/(?:\r\n|\r|\n)/g, ']\n[');
  747. }else{
  748. state.baseNote = "";
  749. }
  750.  
  751. if(text.toLowerCase().includes("[encounter:")){
  752. var encounterText = text.split(/\[encounter:/i)[1].split("]")[0]
  753. state.encounter = {text:encounterText,encountered:true,race:{name:encounterText},duration:1,timeout:1}
  754. }
  755.  
  756. state.specialNotes = [];
  757. if(text.includes("[$")){
  758. var notes = text.split("[$");
  759. for(var i =0 ; i < notes.length;i++){
  760. notes[i] = notes[i].split("]")[0]
  761. var tag = notes[i].split(":")[0]
  762. if(notes.length>1){
  763. state.specialNotes.push({tag:tag,desc:notes[i]})
  764. }
  765. }
  766. }
  767. }
  768. }
  769.  
  770. else{state.memory.context = ""};
  771. var memLength = state.memory.context.length;
  772.  
  773. for(var i =0; i < state.postKeywords.length;i+=1){
  774. var entry = makeEntry(state.postKeywords[i]);
  775. if(entry.length+postMemText.length+memLength < 1400){
  776. postMemText+=entry;
  777. }
  778. }
  779.  
  780. for(var i =0; i < state.preKeywords.length;i+=1){
  781. var entry = makeEntry(state.preKeywords[i]);
  782. if(entry.length+postMemText.length+preMemText.length+memLength < 1400){
  783. preMemText= entry+preMemText;
  784. }
  785. }
  786.  
  787. state.memory.context = preMemText+state.memory.context+postMemText+"\n---";
  788. }
  789.  
  790. function makeEntry(text){
  791. var lowered = text.toLowerCase();
  792. for(var i =0;i < state.races.length;i++){
  793. if(text == state.races[i].name.toLowerCase()){return"["+capitalizeFirst(state.races[i].plural)+": "+state.races[i].desc+"]\n";}
  794. }
  795. for(var i =0;i < state.jobs.length;i++){
  796. if(text == state.jobs[i].name.toLowerCase()){return"["+capitalizeFirst(state.jobs[i].plural)+": "+state.jobs[i].desc+"]\n";}
  797. }
  798. for(var i =0; i<state.worldEntries.length;i++){
  799. if(state.worldEntries[i].keys.toLowerCase().indexOf(lowered)!=-1){
  800. return "["+capitalizeFirst(state.worldEntries[i].keys.split(",")[0])+": "+state.worldEntries[i].desc+"]\n";}
  801. }
  802. return "";
  803. }
  804.  
  805. function addNoteKeyword(text){
  806. if(!state.noteKeywords.includes(text)){
  807. state.noteKeywords.push(text);
  808. if(state.preKeywords.includes(text)){
  809. state.preKeywords = state.preKeywords.slice(state.preKeywords.indexOf(text),state.preKeywords.indexOf(text))
  810. }
  811. if(state.postKeywords.includes(text)){
  812. state.postKeywords = state.postKeywords.slice(state.postKeywords.indexOf(text),state.postKeywords.indexOf(text))
  813. }
  814. }
  815. }
  816.  
  817. function addPostKeyword(text){
  818. if(!state.postKeywords.includes(text) && !state.noteKeywords.includes(text)){
  819. state.postKeywords.push(text);
  820. if(state.preKeywords.includes(text)){
  821. state.preKeywords = state.preKeywords.slice(state.preKeywords.indexOf(text),state.preKeywords.indexOf(text))
  822. }
  823. }
  824. }
  825.  
  826. function addPreKeyword(text){
  827. if(!state.postKeywords.includes(text) && !state.preKeywords.includes(text) && !state.noteKeywords.includes(text)){
  828. state.preKeywords.push(text);
  829. }
  830. }
  831.  
  832.  
  833.  
  834. function getRandWeight(list,id){
  835. var totalWeight = 0;
  836. for(var i = 0; i<list.length; i++){
  837. totalWeight += list[i].weight[id];
  838. }
  839. var weight = Math.random()*totalWeight;
  840. for(var i =0; i<list.length;i++){
  841. weight -= list[i].weight[id];
  842. if(weight <=0){return list[i];}
  843. }
  844. return null;
  845. }
  846.  
  847.  
  848. function generateEncounter(){
  849. state.encounter = {};
  850. var encounterRace = getRandWeight(state.races,1);
  851. //addNoteKeyword(encounterRace.name);
  852. state.encounter.race = encounterRace;
  853. state.encounter.desc = capitalizeFirst(encounterRace.plural)+" are "+uncapitalizeFirst(encounterRace.desc);
  854. state.encounter.duration = 3;
  855. state.encounter.timeout = 8;
  856. state.encounter.encountered = false;
  857. if (encounterRace.job != false && Math.random()*100>70){
  858. var encounterClass = getRandWeight(state.jobs,0);
  859. //addNoteKeyword(encounterClass.name);
  860. state.encounter.class = encounterClass;
  861. if(Math.random()*100 > 70){
  862. state.encounter.text = encounterRace.name+" "+encounterClass.plural;
  863. state.encounter.desc += " Of this group, each one "+encounterClass.elab;
  864. }
  865. else{
  866. state.encounter.text = aOrAn(encounterRace.name)+" "+encounterClass.name;
  867. state.encounter.desc += " This one "+encounterClass.elab;
  868. }
  869. }
  870. else{
  871. state.encounter.class = null;
  872. if(Math.random()*100 > 70){
  873. state.encounter.text = encounterRace.plural;
  874. }
  875. else{
  876. state.encounter.text = aOrAn(encounterRace.name);
  877. }
  878. }
  879. if(Math.random()*100 > 70){
  880. state.encounter.text += " ("+capitalizeFirst(getRandWeight(state.modifiers,0).name)+")"
  881. }
  882. state.encounter.desc = parseDesc(state.encounter.desc)
  883. }
  884.  
  885. function aOrAn(text){
  886. lowered = text.toLowerCase();
  887. if(lowered.startsWith('a') || lowered.startsWith('e') || lowered.startsWith('i') || lowered.startsWith('o') || lowered.startsWith('u')){
  888. return "an "+text;
  889. }else{
  890. return "a "+text;
  891. }
  892. }
  893.  
  894. function capitalizeFirst(text){
  895. return text.substring(0,1).toUpperCase()+text.substring(1)
  896. }
  897. function uncapitalizeFirst(text){
  898. return text.substring(0,1).toLowerCase()+text.substring(1)
  899. }
  900.  
  901. function parseDesc(text){
  902. if(text.includes("[")){
  903. var splits = text.split("[");
  904. for(var i =0 ;i < splits.length;i++){
  905. if(splits[i].includes("]")){
  906. var remainder = splits[i].split("]")[1];
  907. splits[i] = splits[i].split("]")[0].split(",");
  908. splits[i] = splits[i][Math.floor(Math.random()*splits[i].length)]+remainder;
  909. }
  910. }
  911. text = splits.join("");
  912. }
  913. return text;
  914. }
  915.  
  916.  
  917.  
  918. if(!state.baseNote){state.baseNote = "";}
  919. if(!memory){memory = "";}
  920. if(!state.name){state.name="Player"}
  921. if(!state.race){state.race="Race"}
  922. if(!state.job){state.job = "Job"}
  923. if(!state.encounterCD){state.encounterCD = 0}
  924. if(!state.blockOutput){state.blockOutput = false;}
  925. if(!state.forceEncounter){state.forceEncounter = false;}
  926. if(!history || history.length == 0){history = [{text:"This is some fire mage test text"} , {text:"this is some oni more test text"}]}
  927.  
  928. const modifier = (text) => {
  929. if(!state.blockOutput){ state.message = "";}
  930.  
  931. let modifiedText = text
  932. const lowered = text.toLowerCase()
  933.  
  934. if(state.blockOutput){
  935. state.blockOutput = false;
  936. modifiedText = "";
  937. }else{
  938. state.postKeywords = [];
  939. state.preKeywords = [];
  940. state.noteKeywords = [];
  941. }
  942.  
  943. addPostKeyword(state.race);
  944. addPostKeyword(state.job);
  945.  
  946. if(state.encounter==null){
  947. if((state.encounterCD >=6 && Math.random()*100 > 80) && (history.map(a => a.text).join(" ").length > 800) || state.forceEncounter){
  948. state.forceEncounter = false;
  949. generateEncounter();
  950. }else{
  951. state.encounterCD += 1;
  952. }
  953. }else{
  954. if(state.encounter.duration <=0){state.encounter = null;state.encounterCD=0;}
  955.  
  956. else{
  957. if(state.encounter.encountered == false){
  958. //addNoteKeyword(state.encounter.race.name);
  959. //if(state.encounter.class!=null){addNoteKeyword(state.encounter.class.name);}
  960. state.encounter.timeout -= 1;
  961. if(state.encounter.timeout <= 0){state.encounter = null;state.encounterCD=4;}
  962. }else{
  963. addPostKeyword(state.encounter.race.name);
  964. if(state.encounter.class!=null){addPostKeyword(state.encounter.class.name);}
  965. state.encounter.duration -= 1;
  966. }
  967.  
  968. }
  969. }
  970.  
  971. collectPreKeywords(modifiedText);
  972. parseMemory();
  973.  
  974. // if(modifiedText.startsWith("\n")){modifiedText = modifiedText.substring(1);}
  975.  
  976. // You must return an object with the text property defined.
  977. return {text: modifiedText}
  978. }
  979.  
  980. // Don't modify this part
  981. modifier(text)
  982.  
Add Comment
Please, Sign In to add comment