Initial push

This commit is contained in:
Charles Click 2024-06-16 10:59:55 -04:00
commit b5e14f3f22
Signed by: roryejinn
GPG Key ID: EDECB89DEDB998C0
12 changed files with 437 additions and 0 deletions

10
mfile Normal file
View File

@ -0,0 +1,10 @@
{
"package": "Bashmatic",
"title": "Bashmatic",
"description": "A Generic Mudlet plugin that automates bashing mobs across muds",
"version": "0.1",
"author": "Charles Click",
"icon": "",
"dependencies": "",
"outputFile": false
}

46
readme.md Normal file
View File

@ -0,0 +1,46 @@
# What is this?
Bashmatic is a generic script package for mudlet. Many muds have a character visit areas and attack various denizens to gain experience to level up. This process is colloquially called bashing. Bashmatic is a very generic script package that automates this process.
# What does it support?
Again, it's very generic. Because of that it supports pretty much anywhere that you can bash using a one line command to do so. However, because of the generic nature of the script it also doesn't support more advanced features games might have. It does however support sending commands to the game before and after fights. It also supports grouping bashing targets by areas if you use the mudlet mapper or your game supports gmcp. It also supports finding enemies by gmcp or general input scraping. So overall:
* Supports sending a customized pre-bashing command
* Supports sending a customized bashing command
* Supports sending a customized post-bashing command
* Supports specifying a custom mob death phrase
* Supports grouping bashing targets by area
* Supports detecting areas using the mudlet mapper or by GMCP
* Supports detecting enemies by GMCP or general input scraping
* Provides a function `bmDisable()` that will disable the basher so you can rig a flee/wimpy trigger/alias
# Can I use this on my mud?
I don't know. Many muds have rules against this kind of script. Just as many muds don't care if you use a script like this. Yet more sit somewhere in the middle. It's your responsibility to know where the rules on your mud stand.
# Are there any cavaets?
A few but none that are too bad.
## Switching To Area Group Mode
By default, Bashmatic does not group by areas. This means if you switch the target grouping mode to areas you will erase your target list. This is by necessity. If area grouping is turned off, no area data is stored for targets. When you turn on area grouping, we have no way of finding out what area they should be in. So you'll have to readd them to get them in the right area. This is not true of the other way. If you are grouping by area and turn that off, then we will simply collate all targets into a giant list. You can then clear your target list using `bm clear` if you want.
## GMCP Usage
GMCP requires you to tell the script where the variables are located. This isn't hard. You can type `lua gmcp` into mudlet to get back a listing of the gmcp data your mud sends out. If the list of enemies on your mud was at `Room.Info.Enemies` you could give me that information using `bm config egmcp=Room.Info.Enemies`
## Grouping Targets By Areas
If grouping by GMCP areas, also see above.
We can group targets by areas if you prefer as long as we can tell which area we are in. This can happen by the mud sending the area name by GMCP or by mudlet returning an area through `GetRoomArea(GetPlayerRoom())`. This can be useful for keeping your target lists manageable assuming you want to be able to look at them.
## Auto target switching
Bashmatic doesn't technically support auto-target switching, but we have a jury rigged solution. Upon detecting an enemy's death we will look at the room again.
## Before, During, and After Bashing commands
You should know that the only time we append the target name is bashing start command. Before, During, and After bashing commands do not receive the target name.
# Required Setup
At the very least, you'll need to setup a bashing command. This can be as simply as just `kill` and we'll fill in the target. And you'll need some kind of death trigger. On a lot of muds this could just be the word `died`. A lot of muds just use some variation of the phrase `has died` and this script will match `.*word.*`. Then at least one target added using bm add target. So `bm add bunny` maybe.
* A bash command, Possibly just: `kill`
* A death trigger, Possibly just: `died`
* At least one target, Possibly just: `bm add bunny`
# How does this work?
It depends. Under the hood, it's much more efficient if we can get enemy data from GMCP. Using GMCP, we can simply scan GMCP data for changes to enemy data and react to that. Without GMCP, we create temporary triggers and react to those as they fire.

View File

@ -0,0 +1,17 @@
if not bashmatic.configs.death.event then
cecho("<firebrick>BASHMATIC: You must configure the death trigger first. Please see bm help for more info.")
else
if bashmatic.configs.enemies.detection == "inline" then
-- using trigger detection
local area = nil
if bashmatic.configs.areas.detection == "mapper" then area = GetRoomAreaName(GetRoomArea(GetPlayerRoom())) end
if bashmatic.configs.areas.detection == "gmcp" and bashmatic.configs.areas.data ~= nil then area = bashmatic.configs.areas.data end
inlineAddTarget(matches[2], area)
elseif bashmatic.configs.enemies.detection == "gmcp" then
-- using gmcp detection
cecho("<firebrick>BASHMATIC: GMCP not implemented yet.")
else
-- well this is broken
cecho("<firebrick>BASHMATIC: Invalid enemy detection method.<reset>")
end
end

View File

@ -0,0 +1,10 @@
if table.size(bashmatic.hunting.events) > 0 then
for _, tid in ipairs(bashmatic.hunting.events) do
killTrigger(tid)
end
end
toggleBashing(false)
bmDisable()
bashmatic.hunting.events = {}
bashmatic.hunting.targets = {}
cecho("<firebrick>BASHMATIC: Cleared target list.<reset>")

View File

@ -0,0 +1,24 @@
cecho("<MediumPurple>Bashmatic - Let's Bash Some Mobs!")
cecho("<Slategrey>---------------------------------")
cecho("<DarkSlateBlue>See bm help for information on configuration.")
cecho("<DarkSlateBlue>")
cecho("<MediumPurple>\nBattle Commands:")
cecho("<DarkSlateBlue>-- Start : " .. bashmatic.commands.start or "None")
cecho("<DarkSlateBlue>-- Before: " .. bashmatic.commands.before or "None")
cecho("<DarkSlateBlue>-- During: " .. bashmatic.commands.during or "None" .. "(Every " .. bashmatic.commands.duringTime .. "s)")
cecho("<DarkSlateBlue>-- After : " .. bashmatic.commands.after or "None")
cecho("<MediumPurple>\n\nDeath Trigger:")
cecho("<DarkSlateBlue>-- Phrase : " .. bashmatic.death.phrase or "None")
cecho("<DarkSlateBlue>-- Activated?: " .. bashmatic.death.event or "No")
cecho("<MediumPurple>\n\nDetection:")
cecho("<DarkSlateBlue>-- Detecting enemies using " .. bashmatic.configs.enemies.detection)
if bashmatic.configs.areas.detection == nil then
cecho("<DarkSlateBlue>-- Not currently grouping enemies by areas.")
else
cecho("<DarkSlateBlue>-- Currently grouping enemies by areas using " .. bashmatic.configs.areas.detection)
end
if bashmatic.configs.enemies.detection == "gmcp" or bashmatic.configs.areas.detection == "gmcp" then
cecho("<MediumPurple>\n\nGMCP Detection Settings:")
if bashmatic.configs.enemies.detection == "gmcp" then cecho("<DarkSlateBlue>-- Enemy data located at " .. bashmatic.configs.enemies.location) end
if bashmatic.configs.areas.detection == "gmcp" then cecho("<DarkSlateBlue>-- Area data located at " .. bashmatic.configs.areas.location) end
end

View File

@ -0,0 +1,25 @@
local which = matches[2]:lower()
if which == "phrase" then
-- death phrase
elseif which == "start" then
-- starting battle command
elseif which == "before" then
-- before battle command
elseif which == "during" then
-- during battle command
elseif which == "duringTime" then
-- during battle command time frame
elseif which == "after" then
-- after battle command
elseif which == "enemy" then
-- enemy detection method
elseif which == "egmcp" then
-- enemy gmcp path
elseif which == "area" then
-- area detection method
elseif which == "agmcp" then
-- area gmcp path
else
cecho("<firebrick>BASHMATIC: Unrecognized option " .. matches[2] .. ". See bm help for a list of options.")
end

View File

@ -0,0 +1,38 @@
cecho([[<SteelBlue>
Bashmatic Help File
Let's Bash some Mobs!
Basic Setup
-----------
Bare Minimum, you need to setup a death trigger, a starting battle command, and at least one target. Set up the death trigger by doing bm config phrase=your game's death phrase. Then setup a starting command with bm config start=kill. Then go find a target and bm add target. Then type bm and you're all set to auto bash them. Altogether again then that was.
1) bm config phrase=death phrase
2) bm config start=kill command
3) bm add target
4) bm - this will toggle the system on
All config options
------------------
Toggle all of these using bm config option=value
bm config phrase - sets the phrase that should trigger resolution for the death of our target.
bm config start - sets the command used to start combat. The target name is added here.
bm config before - commands to execute before we start combat.
bm config during - commands to execute during combat.
bm config duringTime - time delay between during command execution. Default 2 seconds. Wants a number.
bm config after - commands to execute after the death trigger fires.
bm config enemy - Set to one of inline or gmcp to determine how we grab enemy data.
bm config egmcp - if using gmcp to grab enemy data, use this to set the gmcp path for enemy data.
bm config area - if wanting to group by areas, set this to mapper or gmcp to set how we get area information.
bm config agmcp - if using gmcp for areas, use this to set the gmcp path for area data.
Aliases Available
-----------------
bm add <target> - add a new target to the hunt list
bmc - show the current configuration
bm config option=value - change the configuration
bmt - List all current targets
bm - toggle the bashing system on and off
bm clear - clear all targets
bm help - this screen
<reset>]])

View File

View File

@ -0,0 +1 @@
bashmatic.configs.enabled = not bashmatic.configs.enabled

View File

@ -0,0 +1,51 @@
[
{
"isActive": "yes",
"isFolder": "no",
"name": "BM Addtarget",
"regex": "^bm add (.*)$",
"script": ""
},
{
"isActive": "yes",
"isFolder": "no",
"name": "BM Config",
"regex": "^bmc$",
"script": ""
},
{
"isActive": "yes",
"isFolder": "no",
"name": "BM Configset",
"regex": "^bm config (.*)=(.*)$",
"script": ""
},
{
"isActive": "yes",
"isFolder": "no",
"name": "BM Listtargets",
"regex": "^bmt$",
"script": ""
},
{
"isActive": "yes",
"isFolder": "no",
"name": "BM Toggle",
"regex": "^bm$",
"script": ""
},
{
"isActive": "yes",
"isFolder": "no",
"name": "BM Clear",
"regex": "^bm clear$",
"script": ""
},
{
"isActive": "yes",
"isFolder": "no",
"name": "BM Help",
"regex": "^bm help$",
"script": ""
}
]

View File

@ -0,0 +1,207 @@
bashmatic = bashmatic or nil
function handleInstall(_, name)
if name:lower() == "bashmatic" then
if bashmatic == nil then
-- it's empty
bashmatic = {}
bashmatic.commands = {
"start" = nil,
"before" = nil,
"during" = nil,
"duringTime" = 2,
"after" = nil
}
bashmatic.death = {
"phrase" = nil,
"event" = nil
}
bashmatic.configs = {
"enemies" = {
"detection" = "inline",
"location" = nil,
"data" = nil
},
"areas" = {
"detection" = nil,
"location" = nil,
"data" = nil
}
}
bashmatic.enabled = false
bashmatic.bashing = false
bashmatic.hunting = {
"targets" = {},
"events" = {}
}
else
-- it's not empty, verify install
local corruptions = 0
if not table.contains(bashmatic, "commands") then
bashmatic.commands = {
"start" = nil,
"before" = nil,
"during" = nil,
"duringTime" = 2,
"after" = nil
}
cecho("<firebrick>BASHMATIC: Potentially corrupt install. Tried to repair bashing commands.<reset>")
corruptions += 1
end
if not table.contains(bashmatic, "death") then
bashmatic.death = {
"phrase" = nil,
"event" = nil
}
cecho("<firebrick>BASHMATIC: Potentially corrupt install. Tried to repair death trigger.<reset>")
corruptions += 1
end
if not table.contains(bashmatic, "configs") then
bashmatic.configs = {
"enemies"{
"detection" = "inline",
"location" = nil,
"data" = nil
},
"areas" = {
"detection" = nil,
"location" = nil,
"data" = nil
}
}
cecho("<firebrick>BASHMATIC: Potentially corrupt install. Tried to repair configuration.<reset>")
corruptions += 1
end
if not table.contains(bashmatic, "enabled") then
bashmatic.enabled = false
cecho("<firebrick>BASHMATIC: Potentially corrupt install. Tried to repair status settings.<reset>")
corruptions += 1
end
if not table.contains(bashmatic, "bashing") then
bashmatic.bashing = false
cecho("<firebrick>BASHMATIC: Potentially corrupt install. Tried to repair status settings.<reset>")
corruptions += 1
end
if not table.contains(bashmatic, "hunting") then
bashmatic.hunting = {
"targets" = {},
"events" = {}
}
cecho("<firebrick>BASHMATIC: Potentially corrupt install. Tried to repair target listings.<reset>")
corruptions += 1
end
if corruptions >= 2 then
cecho("<firebrick>BASHMATIC: Multiple corruptions fixed. You should probably uninstall and reinstall Bashmatic.<reset>")
end
end
end
end
registerAnonymousEventHandler("sysInstallPackage", handleInstall)
function handleShutdown()
if bashmatic.configs.death.event ~= nil then killTrigger(bashmatic.configs.death.event) end
bashmatic.configs.death.event = nil
table.save(getMudletHomeDir() .. "/bashmatic.lua", bashmatic)
end
registerAnonymousEventHandler("sysExitEvent", handleShutdown)
function handleLoadEvent()
if io.exists(getMudletHomeDir() .. "/bashmatic.lua") then
table.load(getMudletHomeDir() .. "/bashmatic.lua", bashmatic)
end
if bashmatic.configs.death.phrase ~= nil then
bashmatic.configs.death.event = tempTrigger(bashmatic.configs.death.phrase,handleMobDeath)
end
cecho("<DarkSlateBlue>BASHMATIC: Loaded settings. Let's bash some mobs.")
end
registerAnonymousEventHandler("sysLoadEvent", handleLoadEvent)
function bmDisable()
bashmatic.enabled = false
end
function toggleBashing(status)
bashmatic.bashing = status
end
function handleMobDeath()
if bashmatic.configs.commands.after then
send(bashmatic.configs.commands.after)
end
toggleBashing(false)
if bashmatic.configs.enabled then
send("look")
end
end
function handleDuringTick()
send(bashmatic.configs.commands.during)
if bashmatic.configs.bashing then tempTimer(bashmatic.configs.commands.duringTime,handleDuringTick) end
end
-- Functions for handling inline matching
function handleBashingMatches(match)
if not bashmatic.configs.enabled then
-- bashing is disabled, so clear the triggers
for _, tid in ipairs(bashmatic.hunting.events) do
killTrigger(tid)
end
bashmatic.hunting.events = {}
else
if bashmatic.configs.bashing then
-- we're currently bashing something, so reup the trigger and wait
bmCreateTrigger(match)
else
if bashmatic.configs.commands.before then send(bashmatic.configs.commands.before) end
send(bashmatic.configs.commands.start .. match)
if bashmatic.configs.commands.during then tempTimer(bashmatic.configs.commands.duringTime,handleDuringTick) end
end
end
end
function bmCreateTrigger(keyword)
table.insert(bashmatic.hunting.events, tempTrigger(keyword, handleBashingMatches(keyword), 1))
end
-- Functions for handling GMCP matching
-- Functions for handling adding targets
function inlineAddTarget(target, area)
if area == nil then
cecho("<DarkSlateBlue>BASHMATIC: Added " .. matches[2] .. " to hunting targets.<reset>")
if not table.contains(bashmatic.hunting.targets, matches[2]) then
table.insert(bashmatic.hunting.targets, matches[2])
end
end
if area ~= nil then
cecho("<DarkSlateBlue>BASHMATIC: Added " .. matches[2] .. " to hunting targets in " .. area .. ".<reset>")
if table.contains(bashmatic.hunting.targets, area) then
table.insert(bashmatic.hunting.targets.area, matches[2])
else
bashmatic.hunting.targets.area = {}
table.insert(bashmatic.hunting.targets.area, matches[2])
end
end
if not bashmatic.configs.bashing then
if bashmatic.configs.enabled then
bmCreateTrigger(matches[2])
end
end
end

View File

@ -0,0 +1,8 @@
[
{
"isActive": "yes",
"isFolder": "no",
"name": "bashmatic init",
"script": ""
}
]