Ok this is the actual inital code... need to convert from mongo to sqlite...

This commit is contained in:
Alex Stevenson 2025-07-15 23:00:02 -04:00
parent 8c856ce465
commit 8fa1664bcb
13 changed files with 1168 additions and 0 deletions

91
entities/boss.rb Normal file
View file

@ -0,0 +1,91 @@
class Boss < Entity
@@bossMods = [
"Insanely Violent", "Horiffic and Huge", "Incredibly Monstrous", "World-Threatening",
"Disasterously Unhinged", "Literally God-like", "Absurdly Deranged", "Wildly Disastrous",
"Potentially Universe Ending", "Unhinged Ancient", "Insatiably Hungry", "Malevolently Cruel",
"Practically Omniscient Like Wow You Don't Even Know",
]
@@bossTypes = [
"Space Demon", "Literal Star", "Supervillian", "Kitten", "Bob", "Subatomic Particle",
"Dental Hygenist", "Creature from Beyond the Stars", "Previously Slumbering Elder Being",
"Bag of Snacks that Says it's 20g In Size But Somehow 19g's of it are Just Air???",
"Mysterious Button", "English Teacher", "Corrupted Wizard", "Pit Fiend",
"King Henry VIII's 9th Wife", "Guy Fieri", "Celestial Being", "Balloon-Shaped Horror",
"GREAT Worm", "Planet Smasher", "DragBot Mecha-Queen",
]
@@bossLosses = [
"returned from the dimension from which they came", "slumbers under the sea once more",
"flees to the stars", "gives up and vanishes without a trace", "runs home to devise a new plan",
]
@@bossWins = [
"isn't sure what to do with themselves now, and goes off to plan an easier conflict",
"only partially destroys the planet", "deletes a star out there, probably somewhere over the rainbow",
"summoned several eldritch beings that quickly passed away in their atmosphere", "eats some cake",
]
@@encounterTypes = [
"tangle", "struggle", "wrestle", "argue", "combat", "stare down", "grapple",
]
def get_default_doc()
q = {
'type' => :boss,
'spawned_by' => nil,
'location' => nil,
'exp' => nil,
'last_line' => nil,
'name' => @@bossMods.sample + " " + @@bossTypes.sample
}
return q
end
def resolve(p)
max_player_attack = p.get('exp')
max_xp_gain = (self.get('exp').to_f + 0.25).to_i
encounter_str = "runs into a Boss, spawned by " +
self.get("spawned_by") + " with their wicked incantation of \"" +
self.get("last_line") + "\"! Known by legend as the "
result = p.get("name") + "[" + max_player_attack.to_s + "str] "
result = result + encounter_str
result = result + self.get("name") + "[" + self.get('exp').to_s + "str] "
player_attack = 1+rand(max_player_attack)
foe_attack = 1+rand(self.get('exp'))
result = result + "They " + @@encounterTypes.sample + "! "
result = result + "[" + player_attack.to_s + "dmg vs " + foe_attack.to_s + "dmg]! "
if player_attack > foe_attack then
xp = 1 + rand(max_xp_gain)
result = result + p.get("name") + " wins! "
result = result + "The " + self.get('name') + " " + @@bossLosses.sample + "! "
result = result + p.get('name') + " earns " + xp.to_s + "xp!"
p.gain_exp(xp)
elsif player_attack < foe_attack then
result = result + "The " + self.get("name") + " wins and " + @@bossWins.sample + "! "
if self.get("spawned_by") != p.get("name") then
raw_spawner = @mc.collection().find({"type" => :player, "name" => self.get("spawned_by")}).first
s = Player.new(@mc, raw_spawner)
xp = 1 + rand(1 + (s.get("exp")*0.05).to_i)
result = result + self.get("spawned_by") + "'s nefarious plan succeeded! They gain " + xp.to_s + "xp!"
s.gain_exp(xp)
else
result = result + self.get("spawned_by") + " was betrayed by their creation! "
result = result + "The shame they feel is immeasurable!"
end
else
result = result + "They tied! They begrudgingly back away from each other."
end
return result
end
end

11
entities/entity.rb Normal file
View file

@ -0,0 +1,11 @@
load "mongo_document_wrapper.rb"
class Entity < MongoDocumentWrapper
def initialize(mc, doc=nil)
super(mc, doc)
end
def resolve(target)
return nil
end
end

131
entities/monster.rb Normal file
View file

@ -0,0 +1,131 @@
class Monster < Entity
@@monsterMods = [
"Crafty", "Stinky", "Spooky", "Surprisingly Stout", "Shockingly Petite",
"Malevolent", "Loud", "Nudist", "Rude", "Aroused", "Depressed",
"Seemingly Friendly but Violent", "Lazy", "Ugly", "Cute Lil'", "Impish", "Ancient",
"Ambiguously Gendered", "Idiotic", "Sticky", "Angery", "Dusty ol'", "Big",
"Mega", "Itty Bitty", "Vibrant Orange", "Yella-Bellied", "Cowardly", "Brave",
"Crusty", "Jankety", "Viral", "Blue-ish", "Moldy", "Musty", "Haunted", "Cursed",
"Buttery", "Sexy", "Drunken", "Foreign", "Extremely Sharp", "Shifty", "Smrat",
"Sharply Dressed", "Irate", "Psychic", "Emphatic", "Unreasonable",
"Dumb as Rocks", "Possessed", "High as Hell", "Annoying", "VERY LOUD",
"Oddly Erotic", "Confused", "Arrogant", "Undead", "Frustrated", "Transparent",
"Thicc", "Holy", "Unholy", "Filthy", "Slimy", "Contagious", "Fartin'", "Eccentric",
"Shartin'", "Eccentric", "Moist", "Ecstatic", "Zooming", "Grim (Up North)",
"Flatulent", "Nefarious", "Rotten", "Sacred", "Handsome", "Purdy", "Howling",
"Weeping", "Real Handsy", "Underachieving", "Playful", "Bubbly", "Offputting",
"Unnerving", "Mysterious", "Creeeepy", "Dirty", "Unfunny", "Inverted", "Inside-Out",
"Bleak", "Near-Sighted", "Uncooked", "Burnt", "Frosty", "Corpulent", "Winged",
"Mastermind", "Lackey", "Scientific", "Tenured", "Illegal", "[redacted]",
"Invisible", "Floating", "Oozing", "smol", "Embarrassing", "Cheeky", "Slanderous",
"Perverted", "Super-Fast", "Boring", "Educated", "Wary", "Ribbed", "Bumpy",
"Smooth", "Cheeked Up", "Insane", "Faaaaast", "Stoned", "Worthless", "Timid",
"Voyeuristic", "Watchful", "Crunchy", "Uncouth", "Brazen", "Regretful", "Practically Dead",
"Obviously Unhinged", "Volatile", "Problematic", "Wary", "Gifted", "Abstract",
"Disgusting", "Amateur", "Expired", "Fading", "Funky", "Bearded", "Feeble", "Frail",
"Crude", "Stringy", "El Fuego", "Paper Crown Wearing", "Majestic", "Beastly", "Number 7",
"Onanistic", "Stained", "Lucky", "Priapic", "Phallic", "Professional", "Wild", "Feral",
"Electric", "Droopy", "Dripping", "Questionable", "Wandering", "Scousey", "Troubled",
"Well-Adjusted", "Innocent", "Creepy", "Clown-Like", "Abrasive", "Arrogant", "1337",
"Tastefully Nude", "Wet", "All-Powerful", "Scandelous", "Remarkedly Stupid",
]
@@monsterTypes = [
"Goblin", "Orc", "Skeleton", "Skelly", "Bob", "Tim", "Witch", "Demon", "Cricket",
"Slime", "Ghost", "Gila Monster", "Sentient Paperclip", "Cthlululu", "Imp",
"BUG?!", "Influencer", "Duck", "Alium", "Hippie", "Druid", "Bean", "Woof", "Sheep",
"Opossum", "Dwarf", "Lizard Fella", "Sailor", "Spy", "Agent", "ChonKee", "Boar",
"Squirrel", "Hobo", "Hairball", "Wizard", "Pupper", "Doggo", "Cat", "Mother",
"Karen", "Magister", "Thief", "Leaky Glass", "Dead Battery", "Cow",
"Disembodied Foot", "Cloud", "Patch of Grass", "Ginger", "Warrior", "Bride",
"Badger", "Parrot", "Mummy", "Raider", "Knight", "Paladin", "Necromancer",
"Pixie", "Sprite", "Stranger", "College Student", "Child", "Foreigner", "Creep",
"Basement Dweller", "Pile of Clothes", "Box of Sand", "Lady", "Dude", "Nerd",
"Luggage", "Spooder", "Pirate", "Scientist", "Professor", "Monkey", "Tree", "Bus",
"[redacted]", "Moth", "Perv", "Sanic", "Wolverine", "Rock", "Eggplant", "Stoner",
"Honeybee", "Wasp", "Gnome", "Tunnel Dweller", "Truck", "Shrimp Appetizer Platter",
"Marine", "Pilot", "Faceless Beard", "Pork Slab", "Denizen", "Archer", "Weirdo Next Door",
"Can of Diet Sprite", "Ferret", "Guttersnipe", "Elf", "Horror", "Terror", "Wanderer",
"Person Who Works in the Cubicle Next to You", "Bunny Rabbit", "Hamster", "Degu",
"Metalhead", "Baking-Soda Volcano", "Canadian", "Moon", "Jazz Musician", "Robot",
"AI Program", "Flat Earther", "Entrepreneur", "Social Media Platform", "Man?", "Beast",
"American", "Brit", "Hippo", "7", "B-List Celebrity", "Bear", "Childs Drawing",
"Anime Character", "Merperson", "Salesperson", "Skellington", "Scallies", "Clown Puppet",
"Clown", "Puppet", "n00b", "Spider Shaped Man", "Bat Shaped Man", "Armadillo", "Unshucked Ear of Corn",
"Dustmite", "Single Follicle of Hair", "Optimal Pride",
]
@@encounter = [
"ran into", "encountered", "crossed paths with", "slammed into", "almost got stepped on by",
"crossed paths with", "almost got eaten by", "got into fisticuffs with", "failed to hide from",
"hunted down", "picked a fight with", "got caught sleeping by", "drunkenly bumped into",
"got bored and starting puching at", "attempted to poach", "tried to collect a trophy from",
"got jealous of and attacked", "got lost then found and got punchy with", "had beef to settle with",
"was inappropriately touched by", "had a misunderstanding with",
"was frustrated and confused by and started fighting",
]
@@getWin = [
"is brutally slaughtered", "straight up dies", "explodes into a million tiny pieces", "has been murdered",
"collapses into a pile of tears before slowly dying", "should probably be buried soon", "DESTROYED!!!",
"is beaten to a bloody pulp", "is permamently damaged", "wonders where things went so wrong and flees",
"dies from embarrassment", "ineffectively begs for forgiveness", "was exsanguinated",
]
@@getLoss = [
"mysteriously disappears", "vanishes in a puff of smoke", "spits at your feet and flips you the bird",
"returns to the dimension from whence they came", "saunters off happily", "gets bored of winning and leaves",
"somehow managed to not completely murder you", "runs away cackling", "is quite embarrassed for you",
"bows, then turns to walk away",
]
def get_default_doc()
return {
'type' => :monster,
'spawned_by' => nil,
'location' => nil,
'exp' => nil,
'line' => "",
'name' => @@monsterMods.sample + " " + @@monsterTypes.sample
}
end
def resolve(p)
max_xp_gain = self.get('exp')
max_player_strength = p.get('last_line').length
name = self.get("name")
article = "a"
if ['A','E','I','O','U', 'a','e','i','o','u'].include?(self.get('name')[0])
article = "an"
end
player_attack = 1+rand(max_player_strength)
foe_attack = 1+rand(self.get('exp'))
result = p.get('name') + "[" + max_player_strength.to_s + "str] "
result = result + @@encounter.sample + " " + article
result = result + " " + name
result = result + "[" + max_xp_gain.to_s + "str]" + "! "
result = result + "[" + player_attack.to_s + "dmg vs " + foe_attack.to_s + "dmg] "
if player_attack > foe_attack then
xp_gain = 1 + rand(max_xp_gain)
result = result + "The " + name + " " + @@getWin.sample + "! "
result = result + p.get("name") + " wins and earns " + xp_gain.to_s + "xp! "
p.gain_exp( xp_gain)
elsif player_attack < foe_attack then
result = result + "The " + self.get("name") + " wins and " + @@getLoss.sample + "! "
else
result = result + "They tied! They shake hands and agree to disagree. "
end
return result
end
end

76
entities/player.rb Normal file
View file

@ -0,0 +1,76 @@
class Player < Entity
def initialize(mc, doc=nil)
super(mc, doc)
end
def get_default_doc()
q = {
'type' => :player,
'name' => nil,
'location' => nil,
'exp' => 0,
'last_line' => nil
}
return q
end
def gain_exp(amount)
self.set_exp(self.get('exp') + amount)
end
# be careful with this one. very rare use case when you want
# to use this directly from a bot or playground
def set_exp(amount)
self.set({'exp' => amount})
end
# yeah this needs a WHOLE LOT of cleanup and rethinking....
def resolve(foe)
result = nil
# call the resolve method for anything that's not a player.
if foe.get('type') != :player then
result = foe.resolve(self)
# Handle player v player here.... can't exactly recall resolve without
# recursing forever
# most of this should probably be somehow abstracted into Entity...
# I'm ok with this for now.
else
max_player_attack = self.get('exp')
max_foe_attack = foe.get('exp')
player_str = self.get('name')
player_str = player_str + "[" + max_player_attack.to_s + "str] "
result = player_str + "felt the need to fight "
result = result + foe.get('name')
result = result + "[" + max_foe_attack.to_s + "str]" + "! "
player_attack = 1+rand(max_player_attack)
foe_attack = 1+rand(foe.get('exp'))
result = result + "[" + player_attack.to_s + "dmg vs " + foe_attack.to_s + "dmg]! "
if player_attack > foe_attack then
# Max of 25% of foe exp, minimum of 1. Cannot pass a 0 into rand without
# getting a float, so this is a bit cludgy. if rand gets a 1 it always returns
# 0 so the floor is effectively 1 :/
max_xp_gain = (foe.get('exp').to_f * 0.25).to_i + 1
xp = 1 + rand(max_xp_gain)
result = result + foe.get('name') + " lost! "
result = result + self.get('name') + " wins and earns " + xp.to_s + "xp!"
gain_exp(xp)
elsif player_attack < foe_attack then
result = result + foe.get("name") + " wins and saunters away"
else
result = result + "They tied! They shake hands and agree to disagree and part ways."
end
end
return result
end
end

61
entities/random_event.rb Normal file
View file

@ -0,0 +1,61 @@
class RandomEvent < Entity
@@eventTypes = [
"ate a real solid kebab", "discovered the secret of magnets", "managed to do almost seven whole pushups in a row",
"found a giant cache of fresh beans", "got help from a particularly friendly woodling sprite",
"received a kiss from a travelling prince. Or princess. They weren't exactly sure but it felt great",
"somehow managed to wake up rested", "finished a Rubix cube without swapping any of the stickers this time",
"made a bet with an impish gnome and won", "arm wrestled an ogre and won", "discovered a way to impersonate Guy Fieri",
"found an altar adorned with skulls but it turned out that the god being worshiped was just misunderstood and was actually pretty chill",
"paid for insurance at the blackjack table and it actually worked", "boiled a pot of water without screwing it up",
"finally replied to that text they got from a friend like a week ago but kept putting off responding for no good reason",
"made friends with a tree", "got invited to sit at the cool kids table", "found some dusty sacred texts",
"chose to be a better person", "digs up dirt on their political opponents", "was gifted a jar of honey from The True Queen Bee",
"changed a flat tire for a weary traveller", "won at a game of poker with a tribe of wandering mages",
"didn't die, not even a little", "accidentally solved world hunger, at least for a few minutes",
"felt at one with the universe before realizing it was just a bit of indigestion. But still, it felt pretty good",
"took a big refreshing gulp of ocean water", "replaced the batteries in the smoke detector",
"passed the lie detector test (somehow)", "was found innocent on all charges", "brushed their teeth and took a shower",
"stood up to the schoolyard bully", "found a penny. Not a particularly lucky one but hey, it's better than nothing",
"finally remembered the name of that song that they had half stuck in their head for the past several days",
"discovered music", "found the right cable from that big box of cables they keep saved in that one closet for some reason",
"artfully evaded a swarm of angry ducks", "fell into a hole but found a big ol' pile of treasure at the bottom",
"overheard a joke a friend said but no one else in the group did, repeated it and got good big laughs in return",
"found their way out of The Endless Wood", "found a scratch-off lottery ticket and won a couple bucks",
"got a haircut", "felt a fleeting moment of happiness", "went to bed early", "comforted a grieving child",
"deleted those dozen apps from their phone that they hadn't used in years", "planned a party that people actually showed up for",
"caught a lucky fish that whispered eldritch secrets to them", "raised awareness for The Cause", "helped a friend move",
"didn't burn down the house", "crafted a not-haunted puppet", "saw their childhood imaginary friend",
"discovered a cure for sneezing", "saved the world but it wasn't THAT big of a deal", "donated money to charity",
"regretted previous decisions and made amends", "educated the ignorant", "cut loose on the dance floor",
"filed the appropriate paperwork to prevent The Great Disintegration just in time", "made a new friend",
"finished that TV series their friend recommended a good few months back", "took a hot bath", "won the game",
"cracked the code", "found a sheep stuck on its side, and after righting it found a super small secret wishing well",
"raked some leaves for the elderly couple next door", "kissed a toad, hallucinated",
"saved up the pennies over the years and can now afford that downpayment", "lost a foot but found a fresh new one",
"ran into a crowd, who then started chanting and calling them Muad'Dib",
]
def get_default_doc()
q = {
'type' => :random_event,
'location' => nil,
'name' => @@eventTypes.sample
}
return q
end
def resolve(p)
exp = p.get('exp')
max_xp_gain = ((exp.to_f * (0.10)).to_i)+1
actual_xp_gain = rand(max_xp_gain)+1
result = p.get('name') + "[" + exp.to_s + "xp] " + self.get('name') + "!"
result = result + " They gained " + actual_xp_gain.to_s + "xp!"
p.gain_exp(actual_xp_gain)
return result
end
end