Compare commits

...

450 Commits

Author SHA1 Message Date
Schmappie Eldress c6faa7361f Fix CI builds
Reverts part of 'add noPosUpdate', 8ca63644
2021-09-06 21:42:54 -05:00
Schmappie Eldress be2f7d1736 Remove nonexistent mods from clientmods/mods.conf 2021-09-06 21:40:34 -05:00
Schmappie Eldress 21dd81a3c2 Fix crash in autofly mod
From clean `~/.minetest` directory:
- Start waspsaliva
- Create a waypoint ".wah"
- Cheat menu -> autofly -> waypoints
- Click the new waypoint
- Click SHOW button

2021-08-19 22:24:46: ERROR[Main]: ModError: Runtime error from mod 'autoeat' in callback on_formspec_input(): *builtin*:common/vector.lua:67: attempt to index local 'pos2' (a nil value)
2021-08-19 22:24:46: ERROR[Main]: stack traceback:
2021-08-19 22:24:46: ERROR[Main]: 	*builtin*:common/vector.lua:67: in function 'direction'
2021-08-19 22:24:46: ERROR[Main]: 	*builtin*:client/wasplib.lua:503: in function 'aim'
2021-08-19 22:24:46: ERROR[Main]: 	autofly:init.lua:301: in function 'display_waypoint'
2021-08-19 22:24:46: ERROR[Main]: 	autofly:/wpforms.lua:102: in function <autofly:/wpforms.lua:77>
2021-08-19 22:24:46: ERROR[Main]: 	*builtin*:client/register.lua:26: in function <*builtin*:client/register.lua:14>
2021-08-19 22:24:46: ERROR[Main]: Check debug.txt for details.
2021-09-06 21:40:34 -05:00
Schmappie Eldress 8f119fc63c Fix mod.conf and depends.txt warnings
2021-08-18 22:52:39: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (scaffold at [...]/clientmods/scaffold)
2021-08-18 22:52:39: WARNING[Main]: depends.txt is deprecated, please use mod.conf instead. (scaffold at [...]/clientmods/scaffold)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (kamikaze at [...]/clientmods/kamikaze)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (speedlimit at [...]/clientmods/speedlimit)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (quint at [...]/clientmods/quint)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (invrefill at [...]/clientmods/invrefill)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (haxnotify at [...]/clientmods/haxnotify)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (test at [...]/clientmods/test)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (optimize at [...]/clientmods/optimize)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (bookbot at [...]/clientmods/bookbot)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (dte at [...]/clientmods/dte)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (autoaim at [...]/clientmods/autoaim)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (peek at [...]/clientmods/peek)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (render at [...]/clientmods/dragonfire/render)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (combat at [...]/clientmods/dragonfire/combat)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (list at [...]/clientmods/dragonfire/list)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (muse at [...]/clientmods/muse)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (nlist at [...]/clientmods/nlist)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (automt at [...]/clientmods/automt)
2021-08-18 23:52:38: WARNING[Main]: Mods not having a mod.conf file with the name is deprecated. (waterbot at [...]/clientmods/waterbot)
2021-09-06 21:40:34 -05:00
Schmappie Eldress 4a9e2a4902 Silence various undeclared variable warnings
scaffold:

    2021-08-18 22:42:54: WARNING[Main]: Assignment to undeclared global "sdir" inside a function at scaffold:/railscaffold.lua:151.

incrementaltp:  Fix this by adding `optional_depends` to `mod.conf`

2021-08-18 22:52:39: WARNING[Main]: Undeclared global variable "autofly" accessed at incrementaltp:init.lua:85
2021-08-18 22:52:39: WARNING[Main]: Undeclared global variable "autofly" accessed at incrementaltp:init.lua:87

dte:

2021-08-18 22:59:26: WARNING[Main]: Assignment to undeclared global "_" inside a function at dte:init.lua:375.

tchat:  Use `get_modpath('wisp')` to fix this

2021-08-18 23:21:20: WARNING[Main]: Undeclared global variable "wisp" accessed at tchat:init.lua:537
2021-09-06 21:40:34 -05:00
Schmappie Eldress b56eb97334 scaffold CSM: Fix crash from indexing undefined variable
debug.txt:2021-08-18 02:17:31: WARNING[Main]: Undeclared global variable "storage" accessed at scaffold:/railscaffold.lua:151
    debug.txt:2021-08-18 02:17:31: ERROR[Main]: Access denied. Reason: Client environment_step: Runtime error from mod 'scaffold' in callback environment_step(): scaffold:/railscaffold.lua:151: attempt to index global 'storage' (a nil value)
    debug.txt:2021-08-18 02:17:31: ERROR[Main]: 	scaffold:/railscaffold.lua:151: in function 'func'
2021-09-06 21:40:34 -05:00
Schmappie Eldress 092c43b168 clientmods/mods.conf: Silence client announcement by default
Silence the embarrassing announcement:

    <schmappie>: Hey guys. I'm using a hacked client. https://repo.or.cz/waspsaliva.git.

...and the embarrassing followup:

    BOT — Today at 9:10 PM
    Thingamabobber Joined
    <Thingamabobber>: hey, schmapa
    <Thingamabobber>: I saw that youre using waspsaliva.
    <Thingamabobber>: In contents, in the game's main menu, turn off haxnotify to stop the message from showing up.
    <Thingamabobber>: Also, I can tell you the necessary cmake options to hide the fact that you're using a hacked client from other servers.
    <Thingamabobber>: In the waspsaliva directory, there is a file called cmakelists.txt
    <Thingamabobber>: near the top, there are a few options.

    xay — Today at 9:13 PM
    wow its p nice of u to share this stuff :) (with others ;) ) how are you today?
2021-09-06 21:40:34 -05:00
Schmappie Eldress 0f514735d5 mods.conf: Add `load_mod_preview`
Added automatically; is this module actually bogus?
2021-09-06 21:40:34 -05:00
Schmappie Eldress f2bd219041 Merge branch 'dragonfire/master' into waspsaliva
This merge removes some redundant-looking code that was apparently
included in DFC upstream already.

This merge also reverts some whitespace & reformatting changes in the
`src/` directory so that a `git diff dragonfire/master` contains only
the essential differences.
2021-08-28 23:30:54 -05:00
cora a1c54e5f21 nlist: make selected list accessible globally 2021-08-28 23:26:35 -05:00
cora ef043544c6 wasplib: add get item meta 2021-08-28 23:26:35 -05:00
cora 427cbad41f esp: fix crash when no list is defined 2021-08-28 23:26:35 -05:00
cora affad32aa0 wasplib updates 2021-08-28 23:26:35 -05:00
cora 7739cf39d2 autofly: add axisnames to dirview 2021-08-28 23:26:35 -05:00
cora c380ab95b6 autoaim: fix crash on login 2021-08-28 23:26:35 -05:00
cora 1912e3302e wallbot: fix freeze 2021-08-28 23:26:35 -05:00
cora 30de6b6b88 clientobject: add null checks 2021-08-28 23:26:35 -05:00
cora cce6e768a8 optimize: fix noBurning 2021-08-28 23:26:35 -05:00
cora aab363998d kamikaze: rewrite 2021-08-28 23:26:35 -05:00
cora ef0f05c4d2 optimize: remove noBurning 2021-08-28 23:26:35 -05:00
cora 9991338895 fix autoeat 2021-08-28 23:26:35 -05:00
cora 17f29e7579 update wasplib 2021-08-28 23:26:35 -05:00
cora 8884c81f08 add missing files 2021-08-28 23:26:35 -05:00
cora b2bf5e5b63 switch_item: better target slot selection 2021-08-28 23:26:35 -05:00
cora e73d8faf67 item wield: auto swap to hotbar 7 for now 2021-08-28 23:26:35 -05:00
cora 0d6c7da4eb wasplib: latest 2021-08-28 23:26:35 -05:00
cora 89df993a45 railscaff:updates 2021-08-28 23:26:35 -05:00
cora 8889f0bbff kamikaze stuff 2021-08-28 23:26:35 -05:00
cora 9b27896259 kamikaze: added nobanner policy <3<3<3 emi 2021-08-28 23:26:35 -05:00
cora b031ab6468 kamikaze: cleanup 2021-08-28 23:26:35 -05:00
cora cf2eb29a76 remove ad from mod.conf 2021-08-28 23:26:35 -05:00
cora 21f8e7e7bf cleanup 2021-08-28 23:26:35 -05:00
cora f6b0042989 fix railbot 2021-08-28 23:26:35 -05:00
cora 2550294514 wasplib additions 2021-08-28 23:26:35 -05:00
cora d7b4931778 wasplib: fix bug 2021-08-28 23:26:35 -05:00
cora 43cd5d2e8d autofly: cleanup 2021-08-28 23:26:35 -05:00
cora 1541545758 scaffold: use new globalhack system 2021-08-28 23:26:35 -05:00
cora f497a37bee actually add wasplib 2021-08-28 23:26:35 -05:00
cora 6abde162d9 add wasplib 2021-08-28 23:26:35 -05:00
cora 26dda03846 lua api: add register_on_item_activate 2021-08-28 23:26:35 -05:00
cora 5b427dd5aa autofly: add show local names 2021-08-28 23:26:35 -05:00
cora 4b1330c8c3 autofly: add transport api 2021-08-28 23:26:35 -05:00
cora 45a0a33ba1 autofly: clean up ui a bit 2021-08-28 23:26:35 -05:00
cora 8ca63644e3 add noPosUpdate 2021-08-28 23:26:34 -05:00
cora 34ca75586e autofly: fix autotp under lag 2021-08-28 23:26:34 -05:00
cora fd05f16dd6 scaffold: add constrain 2021-08-28 23:26:34 -05:00
cora c4810bdb71 autoeat: fix .interact incompatibility 2021-08-28 23:26:34 -05:00
cora a2e4672a53 optimize:add noparticles 2021-08-28 23:26:34 -05:00
cora 34da23941e inctp: add optional end func 2021-08-28 23:26:34 -05:00
cora a0bbcece4c autoeat: merge fleckmagic 2021-08-28 23:26:34 -05:00
cron 4f940c2000 bookbot: prepare for local read/write forms 2021-08-28 23:26:34 -05:00
cora 5c00c9ca7f scaffold: fix randomscaff 2021-08-28 23:26:27 -05:00
cora a825bdf8f3 optimize: remove early localplayer ref 2021-08-28 23:26:27 -05:00
cron 0953f112e5 peek: support nested shulkers, display custom descriptions, display shulker name
Next addition is book reading. Needs a bookbot fix first.
2021-08-28 23:26:23 -05:00
cron 195796b162 test: make chained clientmod for private tests 2021-08-28 23:26:23 -05:00
cron c552435c41 haxnotify: use get_bool 2021-08-28 23:26:23 -05:00
cron 0a3e70374e bookbot: add API 2021-08-28 23:26:23 -05:00
cora facc8ad338 add -dragonfire version string for easy detection 2021-08-28 23:26:23 -05:00
cora 7d43cde6f0 why cora WHY ? 2021-08-28 23:26:23 -05:00
cora cc1664e650 add haxnotify 2021-08-28 23:26:23 -05:00
cron 3c4d034e88 incrementaltp: add incremental teleportation 2021-08-28 23:26:23 -05:00
cora bc31d696ef scaff: wallbot updates 2021-08-28 23:26:18 -05:00
cora a9e888aa0c cchat:remove lastlog for now 2021-08-28 23:26:18 -05:00
cron 5f90569029 CheatMenu: fix bottom entry being cut off sometimes
PS: cora <3 <3 <3 <3
2021-08-28 23:26:14 -05:00
cron ce30691aeb invrefill: fix some bugs, get echest pulling functional 2021-08-28 23:26:14 -05:00
cron 7855cac461 CheatMenu: add circular menu mode for large categories
If the items in a category runs off the screen the category will switch into a circular mode where only the items around the cursor are displayed.
This makes the cheat menu usable on smaller screens when large amounts of items are in a category, or if the category is low on the menu.

PS: cora <3 <3
2021-08-28 23:26:14 -05:00
cron c4a075add1 (untested) invrefill: support pulling from echest 2021-08-28 23:26:14 -05:00
cora 77274845fd add wallTool 2021-08-28 23:26:14 -05:00
cron 57f10ad0c1 formspec API: add on_sending_*_fields
(register/ed)_on_sending_(inventory/nodemeta)_fields
Could be useful for translating field values? No clue, sure we'll find a use :]
2021-08-28 23:26:14 -05:00
cron 285b6801a0 hignore: fix patterns, make better for chat bridges 2021-08-28 23:26:14 -05:00
cron 99eec7d996 scaffold: fix to use the ymodified dircoord 2021-08-28 23:26:14 -05:00
cron 6dae48fe85 invrefill: remove debug print 2021-08-28 23:26:14 -05:00
cron 48f3d8d2b9 invrefill: add small CSM for inventory refilling (bots and stuff)
right now it just has .refill which looks for a named shulker with some items and refills the inv with that
2021-08-28 23:26:14 -05:00
cron 135fc77230 autotool: fix (this cheat is always broken) 2021-08-28 23:26:14 -05:00
cora 9bee7db1c3 scaffold: add wallbot 2021-08-28 23:26:14 -05:00
cora 5dbcf42e6e scaff: talltbm hindscaff 2021-08-28 23:26:14 -05:00
cora 2b26787634 goddessmode: add dodge - deactive hacky shit 2021-08-28 23:26:14 -05:00
cora 87b5f71220 killaura: add rate limiting for now 2021-08-28 23:26:14 -05:00
cora ddfc8c8dae goddessmode: add shulker bullet 2021-08-28 23:26:14 -05:00
cora ee5c11894c railscaff: latest updates 2021-08-28 23:26:14 -05:00
cora 4e4d6950cc scaffold: add stop func 2021-08-28 23:26:14 -05:00
cora 7741ad2d7d fat xmas scaffold commit 2021-08-28 23:26:14 -05:00
cora a4ed213a56 clientobject: add get_id() 2021-08-28 23:26:14 -05:00
cora f1fab23f78 railscaff:add tunnelmaker 2021-08-28 23:26:14 -05:00
cora 0dac71797c railscaff:cosmetic changes 2021-08-28 23:26:14 -05:00
cora bcdb33f555 railscaff: fixes 2021-08-28 23:26:14 -05:00
cora b0bad30dc5 scaffold:add TBM; turtle: add getdir() 2021-08-28 23:26:14 -05:00
cora 26c66e89be railscaff:cleanup 2021-08-28 23:26:14 -05:00
cora 4fe607d0cf scaff: fix dig and rail 2021-08-28 23:26:14 -05:00
cora c03ab2f6d9 scaffold: add waterspam 2021-08-28 23:26:14 -05:00
cron ceaa9a2874 bookbot: make more flexible, add randwrite 2021-08-28 23:26:14 -05:00
cron bae0e18c00 scaffold: add waterscaffold
Not strictly optimal, but it is optimal for certain rectangles :]
2021-08-28 23:26:14 -05:00
cron ccefd5d2e7 waterbot: add FreeRefills cheat (refills water buckets) 2021-08-28 23:26:14 -05:00
cron e9c8661feb Fix early minetest.localplayer reference 2021-08-28 23:26:14 -05:00
cron 8f600e0405 bookbot: add automatic book writing bot 2021-08-28 23:26:14 -05:00
cron 30d852cd84 Remove duplicate 'util' CSM 2021-08-28 23:26:14 -05:00
cron 0febd39537 waterbot: add WIP water renewing bot
At the moment it can just give you a list of water sources that can be bucketed without having a net loss of water.
Next is to make an automatic bucket filler hack using that.
2021-08-28 23:26:14 -05:00
cron 6c73180988 Add fastdig to defaultsettings
Not sure if fastdig does anything.
2021-08-28 23:26:14 -05:00
cron f21af5e5a0 dragonfire/world: update to match DF master
Fixes Nuke, adds BlockLava
I need to rewrite this script BAD
Probably will use scaffold
2021-08-28 23:26:14 -05:00
cron b003dd6211 quint: fix simulate_invaction
Before the counts were wrong and it could swap then fill
This fixes an infinite recursion bug with invaction_dump
2021-08-28 23:26:14 -05:00
cron 6a336597a7 turtle: fix tlang state removal
This could remove the wrong position before
2021-08-28 23:26:14 -05:00
cora 557ea94968 killaura: cleanup 2021-08-28 23:26:02 -05:00
cora b2ab01cf2f killaura: better logic, autoswitch to diasword 2021-08-28 23:26:02 -05:00
cora 2d00d16f96 killaura: make it safer 2021-08-28 23:26:02 -05:00
cron da090876a4 turtle/tlang: numerous fixes for .indexing
Lua interface now supports it
The access/assign functions now use indexing by default
Things that deal with indexed stuff now assume its a table rather than a string
2021-08-28 23:25:59 -05:00
cron 5bf454f94e InventoryAction: make to_table 1 indexed 2021-08-28 23:25:59 -05:00
cora 4a40d7daff combat: fix killaura - only attack enemies 2021-08-28 23:25:59 -05:00
cron e05a24b728 turtle/tlang: add numerical dot indexing
[1, 2, 3] now you can do .1 to get the 1st element (Lua style 1-indexed)
2021-08-28 23:25:59 -05:00
cron 42a253cc71 turtle/tlang: add . map indexing
var.key pushes the value indexed by key in var onto the stack
quotes also work for assignment
numerical keys do not work yet
2021-08-28 23:25:59 -05:00
cora a4b2aca647 fix cheat menu design ^^ 2021-08-28 23:25:59 -05:00
cron da00f89ab8 Fix widespread off by one error 2021-08-28 23:25:59 -05:00
cron 96d6104265 hignore: add strip colors 2021-08-28 23:25:59 -05:00
cron f934733623 Merge Dragonfire
Replicate the following commit (with cherry-picked parents on left
side):

    commit be80a15bad
    Merge: be8e8b906 33a69f694
    Author:     cron <example@example.local>
    AuthorDate: Wed Dec 9 20:36:09 2020 +0000
    Commit:     cron <example@example.local>
    CommitDate: Wed Dec 9 20:36:09 2020 +0000

	Merge Dragonfire
	Dragonfire commit: 56d536ea5e
2021-08-28 23:21:04 -05:00
cron 89dbe3dcd6 optimize: add optimization script to remove water drops, improve ClientObjectRefs 2021-08-28 23:13:46 -05:00
cora d8eaf0f8bb scaffol: add headTri 2021-08-28 23:13:46 -05:00
cora aa046ffd13 kamikaze: extinguish fires 2021-08-28 23:13:46 -05:00
cora f62ac54e38 kamikaze: widen search area, add sponges as badnode 2021-08-28 23:13:46 -05:00
cora 5bfa7db146 randomscaff: fix bug 2021-08-28 23:13:46 -05:00
cora b00f4e42e3 cchat: add names of lastlogs - its not ideal this way 2021-08-28 23:13:46 -05:00
cora c86f1718f1 ckam: rename to kamikaze since it finds other stuff too now 2021-08-28 23:13:46 -05:00
cora c5312c9507 automt: fix automt not loading on first try 2021-08-28 23:13:46 -05:00
cora 00dc99516f crystalkamikaze: add tnt removal, cleanup, optimisation 2021-08-28 23:13:46 -05:00
cora 5cb9591bb5 crystalkamikaze: clear arrows too, add waypoint, make it smoother 2021-08-28 23:13:46 -05:00
cora ac8683a777 autotool: reset old wield index (with proper wait) 2021-08-28 23:13:46 -05:00
cora 41c9e86549 scaffold: improve random- and railscaff, add quintscaff 2021-08-28 23:13:46 -05:00
cora d46bf9a1fc autotool: make autotool() public 2021-08-28 23:13:46 -05:00
cron 954161bf94 muse: add automatic noteblock player 2021-08-28 23:13:46 -05:00
cora 6006cebc6b scaffold: add randomscaffold 2021-08-28 23:13:46 -05:00
cora 1405194bac nlist: add mt default nodes (nlist.get_mtnodes) 2021-08-28 23:13:46 -05:00
cora b32586700a crystalclear: renamed to crystalkamikaze :) 2021-08-28 23:13:46 -05:00
cora 1603f86387 add: crystalClear - suicide-clear endcrystals at spawn 2021-08-28 23:13:46 -05:00
cora 8155cf4ebc scaffold: add railscaffold 2021-08-28 23:13:46 -05:00
cora 69ba983410 nlist: some cleanup 2021-08-28 23:13:45 -05:00
cora 46c9b4b5b6 nlist: makin it all smoother 2021-08-28 23:13:45 -05:00
cora 435d82cc57 esp: add nodelist 2021-08-28 23:13:45 -05:00
cora f956ff8566 autominer: add nodelist 2021-08-28 23:13:45 -05:00
cora 4ea52f350b add: nodelists 2021-08-28 23:13:45 -05:00
cora c65b6a7299 undying: huge improvements! 2021-08-28 23:13:45 -05:00
cora aa945ad80c autofly: fix stupid cora grep mistake lol 2021-08-28 23:13:45 -05:00
cora be1aed758f autofly: more tweaks lol 2021-08-28 23:13:45 -05:00
cora ca106b1546 autofly: more tweaks 2021-08-28 23:13:45 -05:00
cora 7b0d792a63 autofly: add all nodes as ground nodes for cruise 2021-08-28 23:13:45 -05:00
cora e6371af7e7 automt: renamed to waspsaliva, linked to automt 2021-08-28 23:13:45 -05:00
cora 4db6bde127 cchat/frens: log last logs 2021-08-28 23:13:45 -05:00
cora 75e85290cb automt: some fixes 2021-08-28 23:13:45 -05:00
cora b4da45df12 cchat: log last-login of frens 2021-08-28 23:13:45 -05:00
cora 0c5403d06e automt: add support for custom ports ( use server:port) 2021-08-28 23:13:33 -05:00
cora ef72107c0a autoeat: delete old df version 2021-08-28 23:13:33 -05:00
cora bfa5bab2a5 randomsc: fix double menu entry 2021-08-28 23:13:33 -05:00
cron fde02131c8 frenemies: fix enemy addition 2021-08-28 23:13:13 -05:00
cora bc5df968fc scaffold: add railscaffold 2021-08-28 23:13:13 -05:00
cora 30a14f5874 automt: add clammt wrapper 2021-08-28 23:13:13 -05:00
cora 773cf760b8 automt: security fix !!1 :) 2021-08-28 23:13:13 -05:00
cora b5ead96d20 automt: add exit to os and exit to menu support 2021-08-28 23:13:13 -05:00
cora 9cf32d9749 automt: add .mtq to quit 2021-08-28 23:13:13 -05:00
cora 7611e734e0 automt: add seperate logfiles for chats and errors 2021-08-28 23:13:01 -05:00
cora dc4bd0218c autofly: cruise small fix 2021-08-28 23:13:01 -05:00
cron 1cf6ad214e scaffold: add TriScaffold (three wide scaffold) 2021-08-28 23:12:53 -05:00
cron 9f1eca494c quint/invaction: fix dump recursion 2021-08-28 23:12:53 -05:00
cora 39cf1f197d autofly: cruisemode - its very nice now - no more set_pos :) 2021-08-28 23:12:53 -05:00
cora e5c91a3a22 movement: add jetpack (working jetpack :) ) 2021-08-28 23:12:53 -05:00
cron 2b80dfaa51 quint/invaction: add bounds to dump 2021-08-28 23:12:53 -05:00
cron 8c5be087f3 quint/invaction: improve state peeking, add refresh 2021-08-28 23:12:53 -05:00
cron 6a5f605fb3 quint: add queued interactions (currently only InventoryActions)
Big things:
Allows a queue of inventory actions to be performed in succession
The queue keeps track of the predicted outcome after the queue finishes
Allows for dumping between inventory
Allows delayed InventoryActions
2021-08-28 23:12:53 -05:00
cron 3d6404566f InventoryAction: add to_table() 2021-08-28 23:12:53 -05:00
cron ff4c79f16d turtle/tlang: improve in_keys()
The function references should probably be replaced with the Lua-y form
2021-08-28 23:12:53 -05:00
cron 961a0d3803 turtle: add WIP nonworking tlang quarry
Will require some tlang changes, including floor division and the .elem accessing syntax
2021-08-28 23:12:53 -05:00
cron ba170c5193 scaffold: improve melon pattern, remove dead settings 2021-08-28 23:12:53 -05:00
cron 1cc7f25afd scaffold: improve organization, add HereScaffold 2021-08-28 23:12:53 -05:00
cron 38629dec56 scaffold: improve autofarm pattern 2021-08-28 23:12:53 -05:00
cron e7f1106b61 scaffold: improve autofarm, add AutoMelon 2021-08-28 23:12:53 -05:00
cron c37a7f5020 scaffold: add AutoFarm 2021-08-28 23:12:53 -05:00
cron f8be6e24e9 autofly: autotp support position and waypoint 2021-08-28 23:12:53 -05:00
cron 016be0eede LuaClient: modify minetest.interact
It now uses strings instead of numbers, and supports being passed a node coordinate as well as raycasting for the target.
2021-08-28 23:12:53 -05:00
cron 929253e84c scaffold: improve API, simplify scaffolds 2021-08-28 23:12:53 -05:00
cron 83840da8f8 scaffold: add registration functions, clean some things up 2021-08-28 23:12:53 -05:00
cora 17ce7c0fa5 autofly: fix regression 2021-08-28 23:12:39 -05:00
cron 0ce3485357 scaffold: move sapscaffold and slowscaffold together, add CheckScaffold 2021-08-28 23:12:30 -05:00
cora ea30789680 automt: fix lol 2021-08-28 23:12:30 -05:00
cora 1cb2279eff speed: add default settings why cora WHY?? lol 2021-08-28 23:12:30 -05:00
cora f985976972 speed: cora did it again lol 2021-08-28 23:12:30 -05:00
cora ddb96e465c speed: change csm to reflect the api change 2021-08-28 23:12:30 -05:00
cora 8a237b4f1b speed: store server sent settings for proper reset 2021-08-28 23:12:30 -05:00
cron 5f92bd9746 autofly: add random flying, some fixes 2021-08-28 23:12:30 -05:00
cron 85422520b4 Client: fix on_nodemeta_form_open 2021-08-28 23:12:30 -05:00
cora 0a95b8b45b autofly:various fixes 2021-08-28 23:12:30 -05:00
cora 263dbeac47 autofly: automatically show death waypoint 2021-08-28 23:12:30 -05:00
cron eeff0d4be0 Client: add form interception
register_on_receiving_inventory_form(function(formname, formspec))
    intercepts forms sent from the server
register_on_open_nodemeta_form(function(pos, formname, formspec))
    intercepts forms that are to be shown locally

nodemeta intecept probably doesn't intercept all ways it can be opened
2021-08-28 23:12:30 -05:00
cron 14b9c0b98f LuaClient: VERY preliminary raw form field sending
Nothing has been tested, do not use :]
2021-08-28 23:12:30 -05:00
cora 2edcfe4992 ignore_server_speed: ignore all speed settings 2021-08-28 23:12:30 -05:00
cora 93984e27de goddessmode: some fixes 2021-08-28 23:12:30 -05:00
cora 23e3c8c903 goddessmode: disable killaura when in range of friends 2021-08-28 23:12:30 -05:00
cora 7a0c8518a3 goddessmode: dont evade friends 2021-08-28 23:12:30 -05:00
cron 6e8996cd94 autocraft: add WIP automatic crafting CSM
Right now it can traverse the craft tree and construct a crafting queue.
2021-08-28 23:12:30 -05:00
cora 16b41bbd3e main menu: add background 2021-08-28 23:12:30 -05:00
cora e2321f82b7 add logo 2021-08-28 23:12:30 -05:00
cora 1d04bd87d5 autosneak: add conditional autosneak only if touching ground 2021-08-28 23:12:30 -05:00
cora bde87dc5a3 prevent fall damage: fix this shit :) 2021-08-28 23:12:30 -05:00
cora a7dcc30ab1 hide huds: fix stupid cora mistake 2021-08-28 23:12:30 -05:00
cora 60b3eeae8b client::makeScreenshot: add ability to screenshot without chatspam 2021-08-28 23:12:30 -05:00
cora c13deff8de gameui: hide cheatmenu on f1 2021-08-28 23:12:30 -05:00
cora 6af8242717 autofly: fix warning 2021-08-28 23:12:30 -05:00
cora e3d3ff720e randomscreenshot: optimized timing 2021-08-28 23:12:30 -05:00
cora 1a6d018ae6 lua.show/hide_huds(): add hide chat 2021-08-28 23:12:30 -05:00
cora daee8c89b2 gameui: fixed hide chat 2021-08-28 23:12:30 -05:00
cora b88f3fd140 randomscreenshot: make it nice :) 2021-08-28 23:12:30 -05:00
cora 96e1367839 randomscreenshot:optiminzin 2021-08-28 23:12:30 -05:00
cora 29ee4e8547 lua-api: add (messageless show/hide huds) 2021-08-28 23:12:30 -05:00
cora 01aeffa8a7 esp: improved autostop 2021-08-28 23:12:30 -05:00
cora 227e487bea randomscreenshot: disable huds while screenshoting 2021-08-28 23:12:30 -05:00
cora 82ef888bbb autofly:optimizin' 2021-08-28 23:12:30 -05:00
cora 8e48383812 autofly: and another one lol .. now it works 2021-08-28 23:12:30 -05:00
cora 58bc30f541 autofly: cruise small fix 2021-08-28 23:12:30 -05:00
cora 26b1d072b0 autofly: add cruise mode 2021-08-28 23:12:30 -05:00
cora e22714aa6c automt: change nc to ping for now (doesnt really help tho) 2021-08-28 23:12:30 -05:00
cron 01decba5de autofly: disable aim on freecam, use autofsprint instead of pressing special1 2021-08-28 23:12:30 -05:00
cron 8724802b02 frenemies: remove debug print, fix placeholders 2021-08-28 23:12:30 -05:00
cron 5c52f0b6ba esp: fix cheat registration
We should merge dragonfire sometime :]
2021-08-28 23:12:30 -05:00
cora e57f62a186 autofly: fix arrive 2021-08-28 23:12:30 -05:00
cora 2ac62c69b7 autofly: fix regression 2021-08-28 23:12:30 -05:00
cron af4d3c1e72 frenemies: add friend and enemy manager
Intended for use by other mods. tchat should use it, as well as killaura and tracers
2021-08-28 23:12:30 -05:00
cora 27fc956af9 lua-api:fix get yaw/pitch .. why, MT, WHY?? 2021-08-28 23:12:30 -05:00
cora b9ed498afb get_pitch/yaw modulo 2021-08-28 23:12:30 -05:00
cora a17def93c3 autofly: small fix 2021-08-28 23:12:30 -05:00
cora 743516e8cf autofly: add autofly.goto + some cleanup 2021-08-28 23:12:30 -05:00
cron b6c34f9d5e autofly: modulo yaw 2021-08-28 23:12:30 -05:00
cora a0fdbcf45b automt: log to ~/.wslog 2021-08-28 23:12:30 -05:00
cora cd4aa1220a autofly: add snap to axis 2021-08-28 23:12:30 -05:00
cora e5ca28f445 autofly: hud improvments 2021-08-28 23:12:30 -05:00
cora 2cda3ac31f speed: fix crash 2021-08-28 23:12:30 -05:00
cron d37b416495 turtle/tlang: make () work
Literally equivalent to {} run
2021-08-28 23:12:30 -05:00
cron d740256b12 turtle/tlang: preliminary .key accessing
VAR.key.key = index var[key][key]
.key.key = index TOS[key][key]

The value after . can be just a number.
2021-08-28 23:12:30 -05:00
cron ce06e2d824 slowscaffold: add slowscaffold
The
clientmod
dir
is
a
fat
mess.
(TODO)
Also clam can handle like 40-50 nodes per second?
2021-08-28 23:12:30 -05:00
cora c76be7b86d autofly: add sounds 2021-08-28 23:12:30 -05:00
cora 12df80075a lol why cora, WHY ? 2021-08-28 23:12:30 -05:00
cora cedbb418d0 minetest.interact: some cleanup + sanity check 2021-08-28 23:12:30 -05:00
cora a4ea9b0400 minetest.interact: allow all interactions 2021-08-28 23:12:30 -05:00
cora 3dd9dfb174 autotp: add to wpform 2021-08-28 23:12:30 -05:00
cora 49fc041161 autotp: fixed typo lol 2021-08-28 23:12:30 -05:00
cora 9408e18089 autotp: works :) 2021-08-28 23:12:30 -05:00
cora bf63f35c10 autotp: add api method interact place, add preliminary autotp test 2021-08-28 23:12:30 -05:00
cora 6439062306 automt: fix to actually make it work lol 2021-08-28 23:12:30 -05:00
cora 2ba91e7814 speed: and supply an arg in the csm lol 2021-08-28 23:12:30 -05:00
cora 54cab72945 speed: localplayer:set_override_speed actually able to set speed 2021-08-28 23:12:30 -05:00
cora 428d3c2ba3 add: toggle clouds lol 2021-08-28 23:12:30 -05:00
cora a1ea16f10f speed: add api methods and preliminary csm 2021-08-28 23:12:30 -05:00
cora 093913be33 clientpackethandler: add ignore server walk speed 2021-08-28 23:12:30 -05:00
cora 37f066bf9c randomsc: increase delay to 15 secs to give time to render 2021-08-28 23:12:30 -05:00
cron 49515ee77b minetest.get_inventory: whitespace fix 2021-08-28 23:12:30 -05:00
cron b3711601ec minetest.get_inventory: fix segfault when location is invalid 2021-08-28 23:12:30 -05:00
cron 394089ee05 hignore: fix logging 2021-08-28 23:12:30 -05:00
cora 265ee16a2d random screenshot: fix 1st sc being the loading screen lol 2021-08-28 23:12:30 -05:00
cron 48d431ffad turtle: fix dircoord swapping right and left on east and west 2021-08-28 23:12:30 -05:00
cron 75435d73f9 turtle: fix pausing 2021-08-28 23:12:30 -05:00
cron 434de43a72 turtle/tlang: add loop variable to forever 2021-08-28 23:12:30 -05:00
cron db4f5fed9a turtle: add tlang pausing 2021-08-28 23:12:30 -05:00
cron 78d66a7125 turtle/tlang: add state pausing 2021-08-28 23:12:29 -05:00
cron b7dcc4299d autofly: fix autosprint preventing normal sprinting 2021-08-28 23:12:29 -05:00
cron e77a5f9e83 turtle/tlang: improve API, add more boolean builtins 2021-08-28 23:12:29 -05:00
cron 76f3138dbe turtle: improve state execution and interaction 2021-08-28 23:12:29 -05:00
cron f1dfe28848 turtle/tlang: fix binary operators being backwards 2021-08-28 23:12:29 -05:00
cron 88c675193a turtle/tlang: add else to if, fix end of scope error 2021-08-28 23:12:29 -05:00
cron 4be2c31314 turtle/tlang: add boolean conversion API, improve automatic conversion 2021-08-28 23:12:29 -05:00
cron b7793dbb9a turtle/tlang: fix nextpop bug, improve value conversion 2021-08-28 23:12:29 -05:00
cron 3f9f50620d turtle: improve coordinate handling and task scheduling 2021-08-28 23:12:29 -05:00
cron 7b3ebdb460 turtle/tlang: add args builtin
Also fixes some bugs regarding exiting code blocks.
2021-08-28 23:12:29 -05:00
cron 627c7d9bcb turtle/tlang: add WIP API
Some things aren't _raw, other things are, its WIP
2021-08-28 23:12:29 -05:00
cron e30c012771 turtle: add public domain dedications 2021-08-28 23:12:29 -05:00
cron 33505596ed turtle: add .tlang, fix print log 2021-08-28 23:12:29 -05:00
cron 6e8c1fb739 turtle/tlang: log prints 2021-08-28 23:12:29 -05:00
cron 632eb7e286 turtle: fix tlang integration 2021-08-28 23:12:29 -05:00
cron 16fafaa193 turtle: remove unneeded code
Other functions need to be replaced with tlang cogs.
2021-08-28 23:12:29 -05:00
cron a0434a7225 turtle: add tlang scheduler 2021-08-28 23:12:29 -05:00
cron 0753b8d94d turtle/tlang: make more modular 2021-08-28 23:12:29 -05:00
cron 2ca6d7ef31 turtle/tlang: remove unecessary dofile replacement 2021-08-28 23:12:29 -05:00
cron 5623c73578 autodupe: add automatic duping harness CSM
Currently nonworking, some promising methods but nothing concrete thus far.
2021-08-28 23:12:29 -05:00
cron 4c816f1071 turtle/tlang: add repeat
{code} count <var> repeat
2021-08-28 23:12:29 -05:00
cron 05da1be543 turtle/tlang: allow unary operators to assign to quotes, add more operators
`var -- is now possible
Added + - / % !
2021-08-28 23:12:29 -05:00
cron e5f28d8469 turtle/tlang: make = assign to nearest defined
If identifier has never been assigned, assign it in current scope
If it has been assigned, reassign it at that scope to value
Needs a global assignment and local assignment, maybe rename = to set or something
2021-08-28 23:12:29 -05:00
cron 5c3df299a6 sapscaffold: allow place_node when buildable_to 2021-08-28 23:12:29 -05:00
cron 1a8f916fa7 clientmods/world: remove duplicate CSM 2021-08-28 23:12:29 -05:00
cron bb55dcad38 df/inventory: remove odx restoration
this would happen too quick, since anticheat would see the wrong tool being used after mine
this would prevent blocks from being broken
2021-08-28 23:12:29 -05:00
cron d4b2b38133 clientmods/inventory: fix duplicate CSMs 2021-08-28 23:12:29 -05:00
cron 5eddb0f02a sapscaffold: add small sapling scaffold CSM 2021-08-28 23:12:29 -05:00
cron 7e23013727 minetest.register_cheat: fix multiple definition 2021-08-28 23:12:29 -05:00
cron 0c0a8236e9 turtle/tlang: force beginning and end of string literals to match 2021-08-28 23:12:29 -05:00
cron 48da01beb5 turtle/tlang: add while 2021-08-28 23:12:29 -05:00
cron 1f0d77b0c4 builtin/client/util: backport from Dragonfire 2021-08-28 23:12:29 -05:00
cron 8e757040bf turtle/tlang: make access() search for newest locals first, globals last 2021-08-28 23:12:29 -05:00
cron ac9f18f6dd turtle/tlang: fix copying error with = builtin 2021-08-28 23:12:29 -05:00
cron 0f8dd9c7f3 turtle/tlang: add forever and some other builtins
With forever, break, and (basic) if for and while can be made.
2021-08-28 23:12:29 -05:00
cron 93881793cf turtle/tlang: add comments, fix strings
Strings support '' syntax now. They can also be started with ' and ended with " or vice versa, and there is no way to put a literal ' in yet.
2021-08-28 23:12:29 -05:00
cron a57a8772fa nodePlacement: add sort of working force_sneak
doesn't work with mcl2 and stuff
i suspect client->interact being annoying
2021-08-28 23:12:29 -05:00
cron 481f71967b lua_localplayer: add get_pitch(), use floats instead of ints for pitch/yaw 2021-08-28 23:12:29 -05:00
cron d791294319 turtle/tlang: add run builtin
This changes how code is executed a bit, code from the stack is popped to an execution stack before.
This makes global executed functions and anonymous ones identical.
Not super well tested as always :]
2021-08-28 23:12:29 -05:00
cron 73d9e30816 turtle/tlang: fix lexer whitespace issues
This fixes the final whitespace issue as well as numbers requiring a final whitespace.
Maps don't need surrounding whitespace anymore.
2021-08-28 23:12:29 -05:00
cron d6abb183b6 Merge branch 'master' of repo.or.cz:waspsaliva
Replicate the following commit (with cherry-picked parents on both
sides):

    commit a7e6ce6493
    Merge: 8f5dbbb1b 7ad3089d3
    Author:     cron <example@example.local>
    AuthorDate: Sun Nov 1 17:38:38 2020 +0000
    Commit:     cron <example@example.local>
    CommitDate: Sun Nov 1 17:38:38 2020 +0000

	Merge branch 'master' of repo.or.cz:waspsaliva
2021-08-28 23:10:43 -05:00
cora 37efa169d1 removed df chatcommand fuckery 2021-08-28 23:03:45 -05:00
cora f8d8947818 lol 2021-08-28 23:03:45 -05:00
cora 287de74e55 added missing ws cheats ... time spent meaningful ... ^ 2021-08-28 23:03:45 -05:00
cora d2c4108607 autoeat: fixed stupid mistake 2021-08-28 23:03:45 -05:00
cora 6def65f31d autofly: fixed autoSprint to reset correctly 2021-08-28 23:03:45 -05:00
cora 7a757a8c6a autofly: removed image test 2021-08-28 23:03:45 -05:00
cora 1f1e7558b0 autoeat: added seperate setting for timed autoeat 2021-08-28 23:03:45 -05:00
cora 4ff2b8bdbb autoeat: set conditional eating interval to 5 mins 2021-08-28 23:03:45 -05:00
cora aec3fb38f5 autoeat: timed eat when certain things are happening 2021-08-28 23:03:45 -05:00
cron 836e29e653 chatcommands: fix duplicate definition functions 2021-08-28 23:01:50 -05:00
cron 7f09824e89 turtle: add working tlang
Not very well tested, needs a better public API, not integrated with Minetest, ...
This is WAY bigger than a commit should be.
The next stages will be:
- unit tests
- API (allows it to be more than just a language for this project)
- integration with Minetest
2021-08-28 23:01:49 -05:00
cora c9b11b7c73 add ws cheats to cheat.lua ... why, fleck, why ? :D 2021-08-28 23:01:49 -05:00
cora aaffe05463 remove weird cheat def thingy 2021-08-28 23:01:49 -05:00
cron 2fc69991b0 turtle: some weird ideas before the turtle language is added 2021-08-28 23:01:49 -05:00
cora 472f99d81e invA: add more missing lua 2021-08-28 23:01:49 -05:00
cora a452285e03 inventoryAction: add missing lua function 2021-08-28 23:01:49 -05:00
cora aa693c1fbd merge dragonfire inventoryAction 2021-08-28 23:01:49 -05:00
cora eaa39a0987 add autoreconnect script ( ./automt server user pass ) 2021-08-28 23:01:49 -05:00
cora 068252a8dd add random screenshot csm 2021-08-28 23:01:49 -05:00
cora 0e6e73ad43 csm-api: add take_screenshot() 2021-08-28 23:01:49 -05:00
cora 480789b6e6 removed autowarp from mods.conf 2021-08-28 23:01:49 -05:00
cora b1b9f89be3 autotool: actually fix reset wield index lol 2021-08-28 23:01:49 -05:00
cora a28240deb0 autotool: little fix 2021-08-28 23:01:49 -05:00
cora 10c6294fa8 autotool: reset old wield index when node dug 2021-08-28 23:01:49 -05:00
cora 7e082da0f7 autoeat: reset old wield idx after eating 2021-08-28 23:01:49 -05:00
cora 5d9d147444 autofly: more fixes 2021-08-28 23:01:49 -05:00
cora d58ff5d50e cleak: real fix 2021-08-28 23:01:49 -05:00
cora d6f3724f47 cleak: fix 2021-08-28 23:01:49 -05:00
cora 335b710a83 removed dupe csms, changed "Leak" to be a chatcommand 2021-08-28 23:01:49 -05:00
cora b561de16b5 autofly: some fixes 2021-08-28 23:01:49 -05:00
cron 1e33e1bb5e hignore: add settings and logging 2021-08-28 23:01:49 -05:00
cron b5d311f3e5 peek: remove debug log prints 2021-08-28 23:01:49 -05:00
cora bee4d3d326 autofly: add normal autosprint; some gui fixes 2021-08-28 23:01:34 -05:00
cora 510f8da63f autofly: add AutoSprint 2021-08-28 23:01:34 -05:00
cora 5415d2309b goddessmode: fixed stupid error 2021-08-28 23:01:34 -05:00
cora 30db8c2995 undying: optimisation; remove old csns 2021-08-28 23:01:34 -05:00
cora 860f40dbd0 esp: quick optimisation 2021-08-28 23:01:34 -05:00
cron 050e2d820e peek: fix cpeek number parsing error 2021-08-28 23:01:25 -05:00
cron 51c5cfa22d hignore: fix nil issue for DMs from stripped players 2021-08-28 23:01:25 -05:00
cron cd81ac60d8 gameui.cpp: add pointed block position to debug menu 2021-08-28 23:01:25 -05:00
cora 40b62ac32c goddess mode: only evade projectiles if they are moving 2021-08-28 23:01:16 -05:00
cron ef10d26129 peek: add experimental chest peeking 2021-08-28 23:01:08 -05:00
cron 1abd79b524 turtle: add preliminary scheduling system 2021-08-28 23:01:08 -05:00
cron 96861cbe4f turtle: initial turtle mod
Don't use turtle.quarry or the mining features, they are experimental
2021-08-28 23:01:08 -05:00
cora d201dcca1b goddess mode: detect splash potions, core: new font test 2021-08-28 23:01:08 -05:00
cora 056d3d48de goddess mode: detect all arrows 2021-08-28 23:01:08 -05:00
cora c995b35346 gooddess mode: added harming arrows and more bad blocks 2021-08-28 23:01:08 -05:00
cora 31fb77cb9f goddess mode: bugfix 2021-08-28 23:01:08 -05:00
cora 4803341750 goddess mode: some cleanup, 3d coords 2021-08-28 23:01:08 -05:00
cora 2c3f917aba goddess mode: add evade arrows 2021-08-28 23:01:08 -05:00
cora 4e5fbf9d33 goddess mode: safety kinda works 2021-08-28 23:01:08 -05:00
cora 176500adbb goddess mode: some safety 2021-08-28 23:01:08 -05:00
cron f99525f9af Merge branch 'master' of repo.or.cz:waspsaliva
Replicate the following commit (with cherry-picked parents on both
sides):

    commit e4f986e99d
    Merge: de4da91f2 fff6a37e7
    Author:     cron <example@example.local>
    AuthorDate: Mon Oct 12 02:29:26 2020 +0000
    Commit:     cron <example@example.local>
    CommitDate: Mon Oct 12 02:29:26 2020 +0000

	Merge branch 'master' of repo.or.cz:waspsaliva
2021-08-28 22:58:21 -05:00
cora 24fcdc628e goddess mode: tweak the constants 2021-08-28 22:49:04 -05:00
cora 193c5c2753 actually add goddessmode .. 2021-08-28 22:49:04 -05:00
cora c2145684bd add: goddessmode alpha 2021-08-28 22:49:04 -05:00
cron e3a0458c3f peek: add shulker box peek command 2021-08-28 22:48:09 -05:00
cron 2aefaaee92 tchat: prevent /commands from being sent unintentionally 2021-08-28 22:48:09 -05:00
cron 7613a0d6f9 LuaLocalPlayer: add CAO getter 2021-08-28 22:48:09 -05:00
cron 70dcd75369 ClientObjectRef: add more getters 2021-08-28 22:48:09 -05:00
cron b1089317d9 ClientObjectRef: add some more functions 2021-08-28 22:48:09 -05:00
cron 8d8d778fa5 devtest: weird texture additions? 2021-08-28 22:48:09 -05:00
cron 62e123db2b autoaim: add basic autoaim 2021-08-28 22:48:09 -05:00
cron b386220ffb supernotes: create local wiki clientmod 2021-08-28 22:48:09 -05:00
cron b7df47c00a hignore: fix 'higlight' typo 2021-08-28 22:48:09 -05:00
cron 2879ea58a1 ClientObjectRef: fix get_pos() being off by an order of magnitude 2021-08-28 22:48:09 -05:00
cron 1f53b639a5 tracers: fix typo in the merged code 2021-08-28 22:48:09 -05:00
cron 6807c46a27 Merge October 5th Dragonfire changes
Replicate the following commit (with cherry-picked parents on left
side):

    Author:     cron <example@example.local>
    AuthorDate: Wed Oct 7 22:15:33 2020 +0000
    Commit:     cron <example@example.local>
    CommitDate: Wed Oct 7 22:15:33 2020 +0000

    Merge October 5th Dragonfire changes

    44 files changed, 295 insertions(+), 174 deletions(-)
    builtin/client/cheats.lua                        |  1 +
    builtin/mainmenu/tab_credits.lua                 |  9 ++--
    builtin/settingtypes.txt                         |  2 +
    clientmods/dragonfire/autosneak/init.lua         | 13 +++++
    clientmods/dragonfire/autosneak/mod.conf         |  3 ++
    clientmods/dragonfire/autosneak/settingtypes.txt |  1 +
    clientmods/dragonfire/chat/leak.lua              |  2 +
    clientmods/dragonfire/chat/status.lua            |  2 +
    clientmods/dragonfire/inventory/autoeject.lua    | 19 +++++++
    clientmods/dragonfire/inventory/init.lua         |  9 ++--
    clientmods/dragonfire/inventory/mod.conf         |  1 +
    clientmods/dragonfire/inventory/settingtypes.txt |  2 +
    clientmods/dragonfire/list/init.lua              | 47 +++++++++++++++++
    clientmods/mods.conf                             |  2 +
    doc/client_lua_api.txt                           |  2 +
    src/activeobjectmgr.h                            |  7 ++-
    src/client/client.cpp                            | 21 +++++---
    src/client/clientenvironment.h                   |  5 ++
    src/client/game.cpp                              | 19 ++-----
    src/client/game.h                                |  2 -
    src/client/localplayer.cpp                       |  6 +--
    src/client/mapblock_mesh.cpp                     | 65 ++++++++++++++++++------
    src/client/render/core.cpp                       | 57 ++++++++++++++++++---
    src/client/render/core.h                         | 10 ++--
    src/client/render/factory.cpp                    | 16 +++---
    src/client/render/factory.h                      |  2 +-
    src/client/render/interlaced.cpp                 |  4 +-
    src/client/render/interlaced.h                   |  2 +-
    src/client/render/plain.cpp                      |  4 +-
    src/client/render/plain.h                        |  2 +-
    src/client/render/sidebyside.cpp                 |  4 +-
    src/client/render/sidebyside.h                   |  2 +-
    src/client/render/stereo.cpp                     |  4 +-
    src/client/render/stereo.h                       |  2 +-
    src/client/renderingengine.cpp                   |  8 +--
    src/client/renderingengine.h                     | 12 ++---
    src/collision.cpp                                |  5 +-
    src/collision.h                                  |  2 +-
    src/defaultsettings.cpp                          |  3 +-
    src/gui/CMakeLists.txt                           |  1 -
    src/gui/tracers.cpp                              | 46 -----------------
    src/gui/tracers.h                                | 28 ----------
    src/script/lua_api/l_client.cpp                  |  8 +++
    src/script/lua_api/l_client.h                    |  7 ++-
2021-08-28 22:43:14 -05:00
cron 3af4dacd60 clientmod API: add API to get nearby entities 2021-08-28 22:39:39 -05:00
cron 7fde73b8ec tracers: remove include iostream 2021-08-28 22:39:39 -05:00
cron 7383dc7853 tracers: add option to only trace to players 2021-08-28 22:39:39 -05:00
cron 88d1149d7e hignore: fix server names and duplicate messages 2021-08-28 22:39:39 -05:00
cron e293e1edcc quotebot: fix typo 2021-08-28 22:39:39 -05:00
flyc0r 8d947351e3 autfly: add wp-gui menu entry 2021-08-28 22:39:31 -05:00
cron abaa0d78d6 quotebot: create quote saying bot (includes import/exporting quotesets) 2021-08-28 22:39:23 -05:00
cron 3fa305c42b hignore: add mode to strip user titles 2021-08-28 22:39:23 -05:00
cron d499503213 hignore: remove debug prints 2021-08-28 22:39:23 -05:00
cron 15d7d69ca1 Merge branch 'master' of repo.or.cz:waspsaliva
Replicate the following commit (with cherry-picked parents on both
sides):

    Author:     cron <example@example.local>
    AuthorDate: Tue Oct 6 02:49:17 2020 +0000
    Commit:     cron <example@example.local>
    CommitDate: Tue Oct 6 02:49:17 2020 +0000

    Merge branch 'master' of repo.or.cz:waspsaliva

    1 file changed, 8 insertions(+), 81 deletions(-)
    clientmods/autominer/init.lua | 89 ++++---------------------------------------
2021-08-28 22:37:18 -05:00
flyc0r 007f5f0047 autominer: cleanup 2021-08-28 22:33:45 -05:00
cron 41bc1562ff hignore: create highlight/ignore player messages clientmod 2021-08-28 22:32:39 -05:00
cron 6697a9e235 tchat: add team clear and chat clear 2021-08-28 22:32:39 -05:00
cron 4a12c4b818 tchat: fix duplicate player online bug 2021-08-28 22:32:39 -05:00
cron 2454a8f496 Merge dragonfire changes
Replicate the following commit (with cherry-picked parents on left
side):

    commit 106fab9762
    Merge: 7652a30c7 0a2c90f4c
    Author:     cron <example@example.local>
    AuthorDate: Mon Oct 5 22:43:01 2020 +0000
    Commit:     cron <example@example.local>
    CommitDate: Mon Oct 5 22:43:01 2020 +0000

	Merge dragonfire changes
2021-08-28 22:30:52 -05:00
cron 871c36f2f1 Merge branch 'master' of repo.or.cz:waspsaliva
Replicate the following commit (with cherry-picked parents on both
sides):

    commit 7652a30c72
    Merge: 4a1b7bd37 096ce84ab
    Author:     cron <example@example.local>
    AuthorDate: Mon Oct 5 19:33:14 2020 +0000
    Commit:     cron <example@example.local>
    CommitDate: Mon Oct 5 19:33:14 2020 +0000

	Merge branch 'master' of repo.or.cz:waspsaliva
2021-08-28 22:25:07 -05:00
flyc0r 54ee9d32aa hpchange: actually set dmg %) 2021-08-28 22:23:42 -05:00
cron 13f34556d8 itemcount: initial semiworking prototype 2021-08-28 22:22:02 -05:00
flyc0r eb3149b0b4 autominer: more optimisation 2021-08-28 22:22:02 -05:00
flyc0r dc9799e082 Merge https://repo.or.cz/waspsaliva into master
Replicate the following commit (with cherry-picked parents on both
sides):

    commit a269b0d5dc
    Merge: 9363aaa25 86e96f5dc
    Author:     flyc0r <flyc0r@localhost.localdomain>
    AuthorDate: Mon Oct 5 05:11:10 2020 +0200
    Commit:     flyc0r <flyc0r@localhost.localdomain>
    CommitDate: Mon Oct 5 05:11:10 2020 +0200

	m
	Merge https://repo.or.cz/waspsaliva into master

     clientmods/inventory/autotool.lua | 1 -
     1 file changed, 1 deletion(-)
2021-08-28 22:17:02 -05:00
cron 76b1095268 autotool: fix broken reference (now works on non mcl2 servers) 2021-08-28 22:15:49 -05:00
flyc0r f486ff7052 autominer: smaller search radius -> more efficient mining 2021-08-28 22:12:31 -05:00
flyc0r 0b130460fe autominer: further optimization. almost 0 damage now 2021-08-28 22:12:31 -05:00
flyc0r e764cd0114 autominer: functional autotool 2021-08-28 22:12:31 -05:00
flyc0r 2ef1f3e7e9 autominer: optimizing 2021-08-28 22:12:31 -05:00
flyc0r 437c1e26d9 autominer: avoid not only lava but gravel too 2021-08-28 22:12:31 -05:00
flyc0r b138b4f84c autominer: even better positioning 2021-08-28 22:12:31 -05:00
flyc0r 61d7366361 autominer:better positioning->less damage 2021-08-28 22:12:31 -05:00
flyc0r 948c7a6096 added autominer to mods.conf 2021-08-28 22:12:31 -05:00
flyc0r 8f6c90e456 add: autominer ALPHA 2021-08-28 22:12:31 -05:00
cron 2668e20f48 core: change cmake project name
I think Windows buildbot still uses Dragonfire
2021-08-28 22:12:31 -05:00
cron 1b45fab4c3 hpchange: add (nonworking) potential change marker 2021-08-28 22:12:31 -05:00
cron aa40a8747a wisp: add message timeout 2021-08-28 22:12:31 -05:00
cron d4b199f3be panicm: remove hp change diagnostic messages (superseded by hpchange) 2021-08-28 22:12:31 -05:00
cron da884b463b hpchange: create hpchange clientmod 2021-08-28 22:12:31 -05:00
cron 3efe147d8d wisp: add diagnostic error messages when installation is broken 2021-08-28 22:12:31 -05:00
cron 519575a9b3 tchat: make message prefixes consistent 2021-08-28 22:12:31 -05:00
cron c5fef6cdc4 Update README 2021-08-28 22:12:31 -05:00
flyc0r 51408076dc updated wisp and tchat 2021-08-28 22:12:31 -05:00
flyc0r 2551ddbf1d Add changes from waspsaliva initial commit
This commit contains changes best credited to flyc0r
<flyc0r@localhost.localdomain>, although the changes were separated
out from waspsaliva's original initial commit rev. 0e9e1f352, which
added the files from DFC work tree, and squashed in numerous additions
by flyc0r and collaborators.  That commit log:

    commit 0e9e1f3528
    Author: flyc0r <flyc0r@localhost.localdomain>
    Date:   Sun Oct 4 03:37:08 2020 +0200

        init

This rebase had the effect of griefing the git history xD, so
for example `git blame` of DFC and even upstream Minetest sources
appear to be originally authored by `flyc0r` in that commit.

To fix this, I will recommit only the changes onto the appropriate
commit in DFC, and recreate the following git history (incl. merges).
After this, the git history will be at least visually the same as the
original Waspsaliva, even if commit sha1sums have changed.

AFAICT, the closest commit from DFC was af085acbd.  That commit was
found simply by running `git diff wsc-master <some_DFC_rev>`, and
locating the commit with the smallest number of differences.

This commit was then created as follows:

    # Check out the DFC base commit
    git checkout af085acbd
    # Check out the *files* from WSC's initial commit
    git checkout 0e9e1f352 -- .
    # Make sure everything is added and commit the changes
    git add -A
    git commit
2021-08-28 21:58:59 -05:00
cron 33a69f694a Prepare for merge
Move builtin cheats to Dragonfire modpack
2020-12-09 07:06:09 +00:00
cron 8f3061cd89 README: minor grammar change
test change
2020-12-09 06:42:39 +00:00
cron 2530004afb Merge October 5th Dragonfire changes 2020-10-07 22:15:33 +00:00
cron a5245322c0 clientmod API: add API to get nearby entities 2020-10-07 19:43:03 +00:00
cron 01eb35645c tracers: remove include iostream 2020-10-07 00:20:54 +00:00
cron e7bb8d8cee tracers: add option to only trace to players 2020-10-07 00:16:08 +00:00
cron fde77217cb hignore: fix server names and duplicate messages 2020-10-07 00:13:40 +00:00
cron 69da194461 quotebot: fix typo 2020-10-06 18:24:54 +00:00
cron 887b18936e Merge remote-tracking branch 'origin/master' 2020-10-06 18:13:30 +00:00
cron dd1e75bd82 quotebot: create quote saying bot (includes import/exporting quotesets) 2020-10-06 18:09:45 +00:00
cron 9afa61a55d hignore: add mode to strip user titles 2020-10-06 18:08:19 +00:00
flyc0r be40b3da54 autfly: add wp-gui menu entry 2020-10-06 12:42:27 +02:00
cron 750120c494 hignore: remove debug prints 2020-10-06 03:16:03 +00:00
cron e5f220693a Merge branch 'master' of repo.or.cz:waspsaliva 2020-10-06 02:49:17 +00:00
cron 57a1f944c9 hignore: create highlight/ignore player messages clientmod 2020-10-06 02:48:02 +00:00
flyc0r 5bc3b727af Merge https://repo.or.cz/waspsaliva into master 2020-10-06 03:13:59 +02:00
flyc0r c8d90d5f85 autominer: cleanup 2020-10-06 03:13:11 +02:00
cron 51e32ac5ba tchat: add team clear and chat clear 2020-10-05 23:27:30 +00:00
cron 95c10965d5 tchat: fix duplicate player online bug 2020-10-05 23:22:14 +00:00
cron 106fab9762 Merge dragonfire changes 2020-10-05 22:43:01 +00:00
cron 7652a30c72 Merge branch 'master' of repo.or.cz:waspsaliva 2020-10-05 19:33:14 +00:00
cron 4a1b7bd37a itemcount: initial semiworking prototype 2020-10-05 19:32:34 +00:00
flyc0r 096ce84ab6 hpchange: actually set dmg %) 2020-10-05 12:30:30 +02:00
flyc0r cc4736d025 autominer: more optimisation 2020-10-05 06:26:59 +02:00
flyc0r a269b0d5dc m
Merge https://repo.or.cz/waspsaliva into master
2020-10-05 05:11:10 +02:00
flyc0r 9363aaa25d autominer: smaller search radius -> more efficient mining 2020-10-05 05:09:02 +02:00
cron 86e96f5dcb autotool: fix broken reference (now works on non mcl2 servers) 2020-10-05 02:55:48 +00:00
flyc0r 217fd70ee5 autominer: further optimization. almost 0 damage now 2020-10-05 04:21:29 +02:00
flyc0r 0b832d4f48 autominer: functional autotool 2020-10-05 04:05:23 +02:00
flyc0r 56f8c97fa7 autominer: optimizing 2020-10-05 03:30:03 +02:00
flyc0r 9e2805235c autominer: avoid not only lava but gravel too 2020-10-05 02:47:18 +02:00
flyc0r 7ff2a35474 autominer: even better positioning 2020-10-05 02:40:10 +02:00
flyc0r f24040219a autominer:better positioning->less damage 2020-10-05 02:34:51 +02:00
flyc0r 5c274bbafe added autominer to mods.conf 2020-10-05 02:20:33 +02:00
flyc0r 70c925f4ff add: autominer ALPHA 2020-10-05 02:18:38 +02:00
cron cf97c5c246 core: change cmake project name
I think Windows buildbot still uses Dragonfire
2020-10-04 15:42:23 +00:00
cron bce8e36fc3 hpchange: add (nonworking) potential change marker 2020-10-04 15:19:56 +00:00
cron 1ff64b4fa1 wisp: add message timeout 2020-10-04 15:08:50 +00:00
cron 7e3e609825 panicm: remove hp change diagnostic messages (superseded by hpchange) 2020-10-04 05:32:55 +00:00
cron 7e3c6b9cdd hpchange: create hpchange clientmod 2020-10-04 05:32:38 +00:00
cron 9ab726e1ed wisp: add diagnostic error messages when installation is broken 2020-10-04 05:31:51 +00:00
cron d50e632803 tchat: make message prefixes consistent 2020-10-04 05:31:21 +00:00
cron 28371feb4f Update README 2020-10-04 05:30:44 +00:00
flyc0r f3b66c82c5 updated wisp and tchat 2020-10-04 04:32:19 +02:00
flyc0r 0e9e1f3528 init 2020-10-04 03:37:08 +02:00
192 changed files with 20208 additions and 201 deletions

1
.gitignore vendored
View File

@ -53,7 +53,6 @@ build/.cmake/
/worlds
/world/
/client/mod_storage/
/clientmods/*
!/clientmods/mods_here.txt
## Configuration/log files

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.5)
# This can be read from ${PROJECT_NAME} after project() is called
project(minetest)
set(PROJECT_NAME_CAPITALIZED "Dragonfire")
set(PROJECT_NAME_CAPITALIZED "waspsaliva")
set(CMAKE_CXX_STANDARD 11)
set(GCC_MINIMUM_VERSION "4.8")

View File

@ -1,3 +1,10 @@
waspsaliva
=========
This is a hacked client forked from [Dragonfireclient](https://github.com/EliasFleckenstein03/dragonfireclient), itself a fork of Minetest. Build instructions are the same as regular Minetest.
Minetest
========
@ -95,11 +102,11 @@ Where each location is on each platform:
* `bin` = `bin`
* `share` = `.`
* `user` = `.`
* Windows installed:
* Windows installation:
* `bin` = `C:\Program Files\Minetest\bin (Depends on the install location)`
* `share` = `C:\Program Files\Minetest (Depends on the install location)`
* `user` = `%APPDATA%\Minetest`
* Linux installed:
* Linux installation:
* `bin` = `/usr/bin`
* `share` = `/usr/share/minetest`
* `user` = `~/.minetest`

1
automt Symbolic link
View File

@ -0,0 +1 @@
waspsaliva

View File

@ -2,6 +2,8 @@ core.cheats = {
["Combat"] = {
["AntiKnockback"] = "antiknockback",
["AttachmentFloat"] = "float_above_parent",
["ThroughWalls"] = "dont_point_nodes",
["AutoHit"] = "autohit",
},
["Movement"] = {
["Freecam"] = "freecam",
@ -10,8 +12,13 @@ core.cheats = {
["AutoJump"] = "autojump",
["Jesus"] = "jesus",
["NoSlow"] = "no_slow",
["JetPack"] = "jetpack",
["AntiSlip"] = "antislip",
["AutoForwSprint"] = 'autofsprint',
["Jetpack"] = 'jetpack',
["SpeedOverride"] = "override_speed",
["JumpOverride"] = "override_jump",
["GravityOverride"] = "override_gravity",
["AntiSlip"] = "antislip",
["NoPosUpdate"] = "noposupdate",
},
["Render"] = {
["Xray"] = "xray",
@ -20,6 +27,7 @@ core.cheats = {
["NoHurtCam"] = "no_hurt_cam",
["BrightNight"] = "no_night",
["Coords"] = "coords",
["Clouds"] = "enable_clouds",
["CheatHUD"] = "cheat_hud",
["EntityESP"] = "enable_entity_esp",
["EntityTracers"] = "enable_entity_tracers",
@ -35,11 +43,14 @@ core.cheats = {
["AutoPlace"] = "autoplace",
["InstantBreak"] = "instant_break",
["FastHit"] = "spamclick",
["AutoHit"] = "autohit",
},
["Exploit"] = {
["EntitySpeed"] = "entity_speed",
},
["Chat"] = {
["IgnoreStatus"] = "ignore_status_messages",
["Deathmessages"] = "mark_deathmessages",
},
["Player"] = {
["NoFallDamage"] = "prevent_natural_damage",
["NoForceRotate"] = "no_force_rotate",
@ -47,8 +58,8 @@ core.cheats = {
["PointLiquids"] = "point_liquids",
["PrivBypass"] = "priv_bypass",
["AutoRespawn"] = "autorespawn",
["ThroughWalls"] = "dont_point_nodes",
},
["Inventory"] = {}
}
function core.register_cheat(cheatname, category, func)

View File

@ -9,6 +9,6 @@ dofile(commonpath .. "chatcommands.lua")
dofile(commonpath .. "vector.lua")
dofile(clientpath .. "util.lua")
dofile(clientpath .. "chatcommands.lua")
dofile(clientpath .. "death_formspec.lua")
dofile(clientpath .. "cheats.lua")
dofile(clientpath .. "wasplib.lua")
dofile(clientpath .. "death_formspec.lua")

View File

@ -99,12 +99,17 @@ core.registered_on_dignode, core.register_on_dignode = make_registration()
core.registered_on_punchnode, core.register_on_punchnode = make_registration()
core.registered_on_placenode, core.register_on_placenode = make_registration()
core.registered_on_item_use, core.register_on_item_use = make_registration()
core.registered_on_item_activate, core.register_on_item_activate = make_registration()
core.registered_on_modchannel_message, core.register_on_modchannel_message = make_registration()
core.registered_on_modchannel_signal, core.register_on_modchannel_signal = make_registration()
core.registered_on_inventory_open, core.register_on_inventory_open = make_registration()
core.registered_on_receiving_inventory_form, core.register_on_receiving_inventory_form = make_registration()
core.registered_on_nodemeta_form_open, core.register_on_nodemeta_form_open = make_registration()
core.registered_on_recieve_physics_override, core.register_on_recieve_physics_override = make_registration()
core.registered_on_play_sound, core.register_on_play_sound = make_registration()
core.registered_on_spawn_particle, core.register_on_spawn_particle = make_registration()
core.registered_on_sending_inventory_fields, core.register_on_sending_inventory_fields = make_registration()
core.registered_on_sending_nodemeta_fields, core.register_on_sending_nodemeta_fields = make_registration()
core.registered_on_object_properties_change, core.register_on_object_properties_change = make_registration()
core.registered_on_object_hp_change, core.register_on_object_hp_change = make_registration()
core.registered_on_object_add, core.register_on_object_add = make_registration()

View File

@ -29,16 +29,6 @@ function core.find_item(item, mini, maxi)
end
end
function core.switch_to_item(item)
local i = core.find_item(item)
if i then
core.localplayer:set_wield_index(i)
return true
else
return false
end
end
function core.get_pointed_thing()
local pos = core.camera:get_pos()
local pos2 = vector.add(pos, vector.multiply(core.camera:get_look_dir(), 7))

771
builtin/client/wasplib.lua Normal file
View File

@ -0,0 +1,771 @@
ws = {}
ws.registered_globalhacks = {}
ws.displayed_wps={}
ws.c = core
local nextact = {}
local ghwason={}
local nodes_this_tick=0
function ws.s(name,value)
if value == nil then
return ws.c.settings:get(name)
else
ws.c.settings:set(name,value)
return ws.c.settings:get(name)
end
end
function ws.sb(name,value)
if value == nil then
return ws.c.settings:get_bool(name)
else
ws.c.settings:set_bool(name,value)
return ws.c.settings:get_bool(name)
end
end
function ws.dcm(msg)
return minetest.display_chat_message(msg)
end
function ws.set_bool_bulk(settings,value)
if type(settings) ~= 'table' then return false end
for k,v in pairs(settings) do
minetest.settings:set_bool(v,value)
end
return true
end
function ws.shuffle(tbl)
for i = #tbl, 2, -1 do
local j = math.random(i)
tbl[i], tbl[j] = tbl[j], tbl[i]
end
return tbl
end
function ws.in_list(val, list)
if type(list) ~= "table" then return false end
for i, v in ipairs(list) do
if v == val then
return true
end
end
return false
end
function ws.random_table_element(tbl)
local ks = {}
for k in pairs(tbl) do
table.insert(ks, k)
end
return tbl[ks[math.random(#ks)]]
end
function ws.center()
--local lp=ws.dircoord(0,0,0)
--minetest.localplayer:set_pos(lp)
end
function ws.globalhacktemplate(setting,func,funcstart,funcstop,daughters,delay)
funcstart = funcstart or function() end
funcstop = funcstop or function() end
delay = delay or 0.5
return function()
if not minetest.localplayer then return end
if minetest.settings:get_bool(setting) then
if tps_client and tps_client.ping and tps_client.ping > 1000 then return end
nodes_this_tick = 0
if nextact[setting] and nextact[setting] > os.clock() then return end
nextact[setting] = os.clock() + delay
if not ghwason[setting] then
if not funcstart() then
ws.set_bool_bulk(daughters,true)
ghwason[setting] = true
--ws.dcm(setting.. " activated")
ws.center()
minetest.settings:set('last-dir',ws.getdir())
minetest.settings:set('last-y',ws.dircoord(0,0,0).y)
else minetest.settings:set_bool(setting,false)
end
else
func()
end
elseif ghwason[setting] then
ghwason[setting] = false
ws.set_bool_bulk(daughters,false)
funcstop()
--ws.dcm(setting.. " deactivated")
end
end
end
function ws.register_globalhack(func)
table.insert(ws.registered_globalhacks,func)
end
function ws.register_globalhacktemplate(name,category,setting,func,funcstart,funcstop,daughters)
ws.register_globalhack(ws.globalhacktemplate(setting,func,funcstart,funcstop,daughters))
minetest.register_cheat(name,category,setting)
end
ws.rg=ws.register_globalhacktemplate
function ws.step_globalhacks(dtime)
for i, v in ipairs(ws.registered_globalhacks) do
v(dtime)
end
end
minetest.register_globalstep(function(dtime) ws.step_globalhacks(dtime) end)
minetest.settings:set_bool('continuous_forward',false)
function ws.on_connect(func)
if not minetest.localplayer then minetest.after(0,function() ws.on_connect(func) end) return end
if func then func() end
end
ws.on_connect(function()
local ldir =minetest.settings:get('last-dir')
if ldir then ws.setdir(ldir) end
end)
-- COORD MAGIC
function ws.is_same_pos(pos1,pos2)
return vector.distance(vector.round(pos1),vector.round(pos2)) == 0
end
function ws.get_reachable_positions(range,under)
under=under or false
range=range or 2
local rt={}
local lp=minetest.localplayer:get_pos()
local ylim=range
if under then ylim=-1 end
for x = -range,range,1 do
for y = -range,ylim,1 do
for z = -range,range,1 do
table.insert(rt,vector.add(lp,vector.new(x,y,z)))
end
end
end
return rt
end
function ws.do_area(radius,func,plane)
for k,v in pairs(ws.get_reachable_positions(range)) do
if not plane or v.y == minetest.localplayer:get_pos().y -1 then
func(v)
end
end
end
function ws.display_wp(pos,name)
local ix = #ws.displayed_wps + 1
ws.displayed_wps[ix] = minetest.localplayer:hud_add({
hud_elem_type = 'waypoint',
name = name,
text = name,
number = 0x00ff00,
world_pos = pos
})
return ix
end
function ws.clear_wp(ix)
table.remove(ws.displayed_wps,ix)
end
function ws.clear_wps()
for k,v in ipairs(ws.displayed_wps) do
minetest.localplayer:hud_remove(v)
table.remove(ws.displayed_wps,k)
end
end
function ws.register_chatcommand_alias(old, ...)
local def = assert(minetest.registered_chatcommands[old])
def.name = nil
for i = 1, select('#', ...) do
minetest.register_chatcommand(select(i, ...), table.copy(def))
end
end
function ws.round2(num, numDecimalPlaces)
return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
end
function ws.pos_to_string(pos)
if type(pos) == 'table' then
pos = minetest.pos_to_string(vector.round(pos))
end
if type(pos) == 'string' then
return pos
end
return pos
end
function ws.string_to_pos(pos)
if type(pos) == 'string' then
pos = minetest.string_to_pos(pos)
end
if type(pos) == 'table' then
return vector.round(pos)
end
return pos
end
--ITEMS
function ws.find_item_in_table(items,rnd)
if type(items) == 'string' then
return minetest.find_item(items)
end
if type(items) ~= 'table' then return end
if rnd then items=ws.shuffle(items) end
for i, v in pairs(items) do
local n = minetest.find_item(v)
if n then
return n
end
end
return false
end
function ws.find_named(inv, name)
if not inv then return -1 end
if not name then return end
for i, v in ipairs(inv) do
if v:get_name():find(name) then
return i
end
end
end
local hotbar_slot=8
function ws.to_hotbar(it,hslot)
local tpos=nil
local plinv = minetest.get_inventory("current_player")
if hslot and hslot < 10 then
tpos=hslot
else
for i, v in ipairs(plinv.main) do
if i<10 and v:is_empty() then
tpos = i
break
end
end
end
if tpos == nil then tpos=hotbar_slot end
local mv = InventoryAction("move")
mv:from("current_player", "main", it)
mv:to("current_player", "main", tpos)
mv:apply()
return tpos
end
function ws.switch_to_item(itname,hslot)
if not minetest.localplayer then return false end
local plinv = minetest.get_inventory("current_player")
for i, v in ipairs(plinv.main) do
if i<10 and v:get_name() == itname then
minetest.localplayer:set_wield_index(i)
return true
end
end
local pos = ws.find_named(plinv.main, itname)
if pos then
minetest.localplayer:set_wield_index(ws.to_hotbar(pos,hslot))
return true
end
return false
end
function core.switch_to_item(item) return ws.switch_to_item(item) end
function ws.switch_inv_or_echest(name,max_count,hslot)
if not minetest.localplayer then return false end
local plinv = minetest.get_inventory("current_player")
if ws.switch_to_item(name) then return true end
local epos = ws.find_named(plinv.enderchest, name)
if epos then
local tpos
for i, v in ipairs(plinv.main) do
if i < 9 and v:is_empty() then
tpos = i
break
end
end
if not tpos then tpos=hotbar_slot end
if tpos then
local mv = InventoryAction("move")
mv:from("current_player", "enderchest", epos)
mv:to("current_player", "main", tpos)
if max_count then
mv:set_count(max_count)
end
mv:apply()
minetest.localplayer:set_wield_index(tpos)
return true
end
end
return false
end
local function posround(n)
return math.floor(n + 0.5)
end
local function fmt(c)
return tostring(posround(c.x))..","..tostring(posround(c.y))..","..tostring(posround(c.z))
end
local function map_pos(value)
if value.x then
return value
else
return {x = value[1], y = value[2], z = value[3]}
end
end
function ws.invparse(location)
if type(location) == "string" then
if string.match(location, "^[-]?[0-9]+,[-]?[0-9]+,[-]?[0-9]+$") then
return "nodemeta:" .. location
else
return location
end
elseif type(location) == "table" then
return "nodemeta:" .. fmt(map_pos(location))
end
end
-- TOOLS
local function check_tool(stack, node_groups, old_best_time)
local toolcaps = stack:get_tool_capabilities()
if not toolcaps then return end
local best_time = old_best_time
for group, groupdef in pairs(toolcaps.groupcaps) do
local level = node_groups[group]
if level then
local this_time = groupdef.times[level]
if this_time and this_time < best_time then
best_time = this_time
end
end
end
return best_time < old_best_time, best_time
end
local function find_best_tool(nodename, switch)
local player = minetest.localplayer
local inventory = minetest.get_inventory("current_player")
local node_groups = minetest.get_node_def(nodename).groups
local new_index = player:get_wield_index()
local is_better, best_time = false, math.huge
is_better, best_time = check_tool(player:get_wielded_item(), node_groups, best_time)
if inventory.hand then
is_better, best_time = check_tool(inventory.hand[1], node_groups, best_time)
end
for index, stack in ipairs(inventory.main) do
is_better, best_time = check_tool(stack, node_groups, best_time)
if is_better then
new_index = index
end
end
return new_index,best_time
end
function ws.get_digtime(nodename)
local idx,tm=find_best_tool(nodename)
return tm
end
function ws.select_best_tool(pos)
local nd=minetest.get_node_or_nil(pos)
local nodename='air'
if nd then nodename=nd.name end
local t=find_best_tool(nodename)
minetest.localplayer:set_wield_index(ws.to_hotbar(t,hotbar_slot))
--minetest.localplayer:set_wield_index(find_best_tool(nodename))
end
--- COORDS
function ws.coord(x, y, z)
return vector.new(x,y,z)
end
function ws.ordercoord(c)
if c.x == nil then
return {x = c[1], y = c[2], z = c[3]}
else
return c
end
end
-- x or {x,y,z} or {x=x,y=y,z=z}
function ws.optcoord(x, y, z)
if y and z then
return ws.coord(x, y, z)
else
return ws.ordercoord(x)
end
end
function ws.cadd(c1, c2)
return vector.add(c1,c2)
--return ws.coord(c1.x + c2.x, c1.y + c2.y, c1.z + c2.z)
end
function ws.relcoord(x, y, z, rpos)
local pos = rpos or minetest.localplayer:get_pos()
pos.y=math.ceil(pos.y)
--math.floor(pos.y) + 0.5
return ws.cadd(pos, ws.optcoord(x, y, z))
end
local function between(x, y, z) -- x is between y and z (inclusive)
return y <= x and x <= z
end
function ws.getdir(yaw) --
local rot = yaw or minetest.localplayer:get_yaw() % 360
if between(rot, 315, 360) or between(rot, 0, 45) then
return "north"
elseif between(rot, 135, 225) then
return "south"
elseif between(rot, 225, 315) then
return "east"
elseif between(rot, 45, 135) then
return "west"
end
end
function ws.getaxis()
local dir=ws.getdir()
if dir == "north" or dir == "south" then return "z" end
return "x"
end
function ws.setdir(dir) --
if dir == "north" then
minetest.localplayer:set_yaw(0)
elseif dir == "south" then
minetest.localplayer:set_yaw(180)
elseif dir == "east" then
minetest.localplayer:set_yaw(270)
elseif dir == "west" then
minetest.localplayer:set_yaw(90)
end
end
function ws.dircoord(f, y, r ,rpos, rdir)
local dir= ws.getdir(rdir)
local coord = ws.optcoord(f, y, r)
local f = coord.x
local y = coord.y
local r = coord.z
local lp= rpos or minetest.localplayer:get_pos()
if dir == "north" then
return ws.relcoord(r, y, f,rpos)
elseif dir == "south" then
return ws.relcoord(-r, y, -f,rpos)
elseif dir == "east" then
return ws.relcoord(f, y, -r,rpos)
elseif dir== "west" then
return ws.relcoord(-f, y, r,rpos)
end
return ws.relcoord(0, 0, 0,rpos)
end
function ws.get_dimension(pos)
if pos.y > -65 then return "overworld"
elseif pos.y > -8000 then return "void"
elseif pos.y > -27000 then return "end"
elseif pos.y > -28930 then return "void"
elseif pos.y > -31000 then return "nether"
else return "void"
end
end
function ws.aim(tpos)
local ppos=minetest.localplayer:get_pos()
local dir=vector.direction(ppos,tpos)
local yyaw=0;
local pitch=0;
if dir.x < 0 then
yyaw = math.atan2(-dir.x, dir.z) + (math.pi * 2)
else
yyaw = math.atan2(-dir.x, dir.z)
end
yyaw = ws.round2(math.deg(yyaw),2)
pitch = ws.round2(math.deg(math.asin(-dir.y) * 1),2);
minetest.localplayer:set_yaw(yyaw)
minetest.localplayer:set_pitch(pitch)
end
function ws.gaim(tpos,v,g)
local v = v or 40
local g = g or 9.81
local ppos=minetest.localplayer:get_pos()
local dir=vector.direction(ppos,tpos)
local yyaw=0;
local pitch=0;
if dir.x < 0 then
yyaw = math.atan2(-dir.x, dir.z) + (math.pi * 2)
else
yyaw = math.atan2(-dir.x, dir.z)
end
yyaw = ws.round2(math.deg(yyaw),2)
local y = dir.y
dir.y = 0
local x = vector.length(dir)
pitch=math.atan(math.pow(v, 2) / (g * x) + math.sqrt(math.pow(v, 4)/(math.pow(g, 2) * math.pow(x, 2)) - 2 * math.pow(v, 2) * y/(g * math.pow(x, 2)) - 1))
--pitch = ws.round2(math.deg(math.asin(-dir.y) * 1),2);
minetest.localplayer:set_yaw(yyaw)
minetest.localplayer:set_pitch(math.deg(pitch))
end
local function tablearg(arg)
local tb={}
if type(arg) == 'string' then
tb={arg}
elseif type(arg) == 'table' then
tb=arg
elseif type(arg) == 'function' then
tb=arg()
end
return tb
end
function ws.isnode(pos,arg)--arg is either an itemstring, a table of itemstrings or a function returning an itemstring
local nodename=tablearg(arg)
local nd=minetest.get_node_or_nil(pos)
if nd and nodename and ws.in_list(nd.name,nodename) then
return true
end
end
function ws.can_place_at(pos)
local node = minetest.get_node_or_nil(pos)
return (node and (node.name == "air" or node.name=="mcl_core:water_source" or node.name=="mcl_core:water_flowing" or node.name=="mcl_core:lava_source" or node.name=="mcl_core:lava_flowing" or minetest.get_node_def(node.name).buildable_to))
end
-- should check if wield is placeable
-- minetest.get_node(wielded:get_name()) ~= nil should probably work
-- otherwise it equips armor and eats food
function ws.can_place_wielded_at(pos)
local wield_empty = minetest.localplayer:get_wielded_item():is_empty()
return not wield_empty and ws.can_place_at(pos)
end
function ws.find_any_swap(items,hslot)
hslot=hslot or 8
for i, v in ipairs(items) do
local n = minetest.find_item(v)
if n then
ws.switch_to_item(v,hslot)
return true
end
end
return false
end
-- swaps to any of the items and places if need be
-- returns true if placed and in inventory or already there, false otherwise
local lastact=0
local lastplc=0
local lastdig=0
local actint=10
function ws.place(pos,items,hslot, place)
--if nodes_this_tick > 8 then return end
--nodes_this_tick = nodes_this_tick + 1
--if not inside_constraints(pos) then return end
if not pos then return end
items=tablearg(items)
place = place or minetest.place_node
local node = minetest.get_node_or_nil(pos)
if not node then return end
-- already there
if ws.isnode(pos,items) then
return true
else
local swapped = ws.find_any_swap(items,hslot)
-- need to place
if swapped and ws.can_place_at(pos) then
--minetest.after("0.05",place,pos)
place(pos)
return true
-- can't place
else
return false
end
end
end
function ws.place_if_able(pos)
if not pos then return end
if not inside_constraints(pos) then return end
if ws.can_place_wielded_at(pos) then
minetest.place_node(pos)
end
end
function ws.is_diggable(pos)
if not pos then return false end
local nd=minetest.get_node_or_nil(pos)
if not nd then return false end
local n = minetest.get_node_def(nd.name)
if n and n.diggable then return true end
return false
end
function ws.dig(pos,condition,autotool)
--if not inside_constraints(pos) then return end
if autotool == nil then autotool = true end
if condition and not condition(pos) then return false end
if not ws.is_diggable(pos) then return end
local nd=minetest.get_node_or_nil(pos)
if nd and minetest.get_node_def(nd.name).diggable then
if autotool then ws.select_best_tool(pos) end
minetest.dig_node(pos)
end
return true
end
function ws.chunk_loaded()
local ign=minetest.find_nodes_near(ws.dircoord(0,0,0),10,{'ignore'},true)
if #ign == 0 then return true end
return false
end
function ws.get_near(nodes,range)
range=range or 5
local nds=minetest.find_nodes_near(ws.dircoord(0,0,0),rang,nodes,true)
if #nds > 0 then return nds end
return false
end
function ws.is_laggy()
if tps_client and tps_client.ping and tps_client.ping > 1000 then return true end
end
function ws.donodes(poss,func,condition)
if ws.is_laggy() then return end
local dn_i=0
for k,v in pairs(poss) do
local nd=minetest.get_node_or_nil(v)
if nd and nd.name ~= 'air' then
if k > 8 then
return
end
if condition == nil or condition(v) then
func(v)
dn_i = dn_i + 1
end
end
end
end
function ws.dignodes(poss,condition)
local func=function(p) ws.dig(p) end
ws.donodes(poss,func,condition)
end
function ws.replace(pos,arg)
arg=tablearg(arg)
local nd=minetest.get_node_or_nil(pos)
if nd and not ws.in_list(nd.name,arg) and nd.name ~= 'air' then
local tm=ws.get_digtime(nd.name) or 0
ws.dig(pos)
minetest.after(tm + 0.1,function()
ws.place(pos,arg)
end)
else
ws.place(pos,arg)
end
end
function ws.playeron(p)
local pls=minetest.get_player_names()
for k,v in pairs(pls) do
if v == p then return true end
end
return false
end
function ws.between(x, y, z) -- x is between y and z (inclusive)
return y <= x and x <= z
end
local wall_pos1={x=-1255,y=6,z=792}
local wall_pos2={x=-1452,y=80,z=981}
local iwall_pos1={x=-1266,y=6,z=802}
local iwall_pos2={x=-1442,y=80,z=971}
function ws.in_cube(tpos,wpos1,wpos2)
local xmax=wpos2.x
local xmin=wpos1.x
local ymax=wpos2.y
local ymin=wpos1.y
local zmax=wpos2.z
local zmin=wpos1.z
if wpos1.x > wpos2.x then
xmax=wpos1.x
xmin=wpos2.x
end
if wpos1.y > wpos2.y then
ymax=wpos1.y
ymin=wpos2.y
end
if wpos1.z > wpos2.z then
zmax=wpos1.z
zmin=wpos2.z
end
if ws.between(tpos.x,xmin,xmax) and ws.between(tpos.y,ymin,ymax) and ws.between(tpos.z,zmin,zmax) then
return true
end
return false
end
function ws.in_wall(pos)
if ws.in_cube(pos,wall_pos1,wall_pos2) and not in_cube(pos,iwall_pos1,iwall_pos2) then
return true end
return false
end
function ws.inside_wall(pos)
local p1=iwall_pos1
local p2=iwall_pos2
if ws.in_cube(pos,p1,p2) then return true end
return false
end
-- DEBUG
local function printwieldedmeta()
ws.dcm(dump(minetest.localplayer:get_wielded_item():get_meta():to_table()))
end
minetest.register_cheat('ItemMeta','Test',printwieldedmeta)

View File

@ -163,6 +163,49 @@ if INIT == "client" then
return do_help_cmd(nil, param)
end,
})
function core.register_list_command(command, desc, setting)
local def = {}
def.description = desc
def.params = "del <item> | add <item> | list"
function def.func(param)
local list = (minetest.settings:get(setting) or ""):split(",")
if param == "list" then
return true, table.concat(list, ", ")
else
local sparam = param:split(" ")
local cmd = sparam[1]
local item = sparam[2]
if cmd == "del" then
if not item then
return false, "Missing item."
end
local i = table.indexof(list, item)
if i == -1 then
return false, item .. " is not on the list."
else
table.remove(list, i)
core.settings:set(setting, table.concat(list, ","))
return true, "Removed " .. item .. " from the list."
end
elseif cmd == "add" then
if not item then
return false, "Missing item."
end
local i = table.indexof(list, item)
if i ~= -1 then
return false, item .. " is already on the list."
else
table.insert(list, item)
core.settings:set(setting, table.concat(list, ","))
return true, "Added " .. item .. " to the list."
end
end
end
return false, "Invalid usage. (See /help " .. command .. ")"
end
core.register_chatcommand(command, def)
end
else
core.register_chatcommand("help", {
params = S("[all | privs | <cmd>]"),

View File

@ -47,22 +47,28 @@ end
function mm_texture.reset()
mm_texture.gameid = nil
local have_bg = false
local have_overlay = mm_texture.set_generic("overlay")
--local have_overlay = mm_texture.set_generic("overlay")
core.set_clouds(false)
mm_texture.clear("header")
mm_texture.clear("footer")
core.set_clouds(false)
mm_texture.set_generic("footer")
mm_texture.set_generic("header")
local minimalpath = defaulttexturedir .. "menu_bg.png"
core.set_background("background", minimalpath, false, 128)
if true then return end
if not have_overlay then
have_bg = mm_texture.set_generic("background")
end
mm_texture.clear("header")
mm_texture.clear("footer")
core.set_clouds(false)
mm_texture.set_generic("footer")
mm_texture.set_generic("header")
if not have_bg then
if core.settings:get_bool("menu_clouds") then
core.set_clouds(true)
core.set_clouds(false)
else
mm_texture.set_dirt_bg()
end
@ -172,12 +178,12 @@ function mm_texture.set_game(identifier, gamedetails)
end
function mm_texture.set_dirt_bg()
if mm_texture.texturepack ~= nil then
local path = mm_texture.texturepack .. DIR_DELIM .."default_dirt.png"
if core.set_background("background", path, true, 128) then
return true
end
end
--if mm_texture.texturepack ~= nil then
--local path = mm_texture.texturepack .. DIR_DELIM .."default_dirt.png"
--if core.set_background("background", path, true, 128) then
-- return true
-- end
-- end
-- Use universal fallback texture in textures/base/pack
local minimalpath = defaulttexturedir .. "menu_bg.png"

View File

@ -1209,6 +1209,9 @@ movement_acceleration_air (Acceleration in air) float 2
# in nodes per second per second.
movement_acceleration_fast (Fast mode acceleration) float 10
# Ignore server sent walk speed
movement_ignore_server_speed (Ignore Server Sent Speed) bool false
# Walking and flying speed, in nodes per second.
movement_speed_walk (Walking speed) float 4

7
clammt Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh
pwf=$HOME/.mtpw
if [ -z $1 ]; then echo "usage: clammt altname - (common) password must be in $pwf"; exit 1; fi
mt=$(dirname $0)/automt
pw=$(cat $pwf)
$mt clam-ity.minecity.online $1 $pw

View File

@ -0,0 +1,19 @@
local function look_nearest()
if not minetest.localplayer then return end
for k, v in ipairs(minetest.localplayer.get_nearby_objects(10)) do
if (v:is_player() and v:get_name() ~= minetest.localplayer:get_name()) then
local pos = v:get_pos()
pos.y = pos.y - 1
autofly.aim(pos)
return
end
end
end
minetest.register_globalstep(function()
if minetest.settings:get_bool("autoaim") then
look_nearest()
end
end)
minetest.register_cheat("Autoaim", "Combat", "autoaim")

View File

@ -0,0 +1,3 @@
name = autoaim
author = cora
description = Automatically aim at nearby player

View File

@ -0,0 +1,264 @@
-- TODO
--[[
free space could be a concern
traverse_recurse should replace groups with the concrete item
maybe recursions yield an item name?
that way has_sub could indicate the item which would be yielded in traverse_recurse and replaced in the recipe before being queued
autocraft.recipes should be loaded and custom per modset
it might choke on empty items in the recipe
this needs to handle groups a bit better, i dont think it will mix woods/etc
--]]
autocraft = {}
autocraft.recipes = {
["mcl_core:crafting_table"] = {
recipes = {
{
recipe = {
{"group:planks", "group:planks"},
{"group:planks", "group:planks"}}
}
}
},
["mcl_core:wood"] = {
groups = {"planks"},
recipes = {
{
count = 4,
recipe = {
"mcl_core:tree"
},
shapeless = true -- redundant, can detect from the lack of subtables
}
}
}
}
autocraft.groups = {}
-- extract groups from autocraft.recipes
local function group_arrange()
for k, v in pairs(autocraft.recipes) do
if v.groups then
for gi, gv in ipairs(v.groups) do
if not autocraft.groups[gv] then
autocraft.groups[gv] = {}
end
table.insert(autocraft.groups[gv], k)
end
end
end
end
group_arrange()
local function startswith(str, start)
return string.sub(str, 1, #start) == start
end
local function combine(t1, t2)
local t1l = #t1
local o = {}
for i, v in ipairs(t1) do
o[i] = v
end
for i, v in ipairs(t2) do
o[t1l + i] = v
end
return o
end
local function parse_group(str)
if startswith(str, "group:") then
return str:match("group:(.+)")
end
end
-- get recipes for an item/group
local function get_recipes(str)
local group = parse_group(str)
if group then
local o = {}
if autocraft.groups[group] then
for i, v in ipairs(autocraft.groups[group]) do
o = combine(o, get_recipes(v))
end
return o
end
else
local idef = autocraft.recipes[str]
if idef then
local o = idef.recipes
for i, v in ipairs(o) do
v.name = str
end
return o
end
end
return {}
end
-- count up all the items in the player's inventory
-- output:
-- {
-- item = n,
-- item = n
-- }
local function count_inv()
local o = {}
local lpim = minetest.get_inventory("current_player").main
for i, v in ipairs(lpim) do
if not v:is_empty() then
o[v:get_name()] = (o[v:get_name()] or 0) + v:get_count()
end
end
return o
end
-- effectively turn a recipe shapeless
local function flatten_recipe(recipe)
if type(recipe[1]) == "table" then
local o = {}
for i, v in ipairs(recipe) do
o = combine(o, v)
end
return o
else
return recipe
end
end
-- count the requirements for a recipe, uses count_inv format
local function count_recipe(recipe)
local o = {}
for i, v in ipairs(flatten_recipe(recipe)) do
local item = ItemStack(v)
o[item:get_name()] = (o[item:get_name()] or 0) + item:get_count()
end
return o
end
-- get all item strings for an item or group string
local function get_items_of(str)
local group = parse_group(str)
if group then
return autocraft.groups[group]
else
return {str}
end
end
-- check if the recipe can be crafted with current resources
local function can_craft(resources, recipe)
for k, count in pairs(count_recipe(recipe)) do
for i, vv in ipairs(get_items_of(k)) do
local item = ItemStack(vv)
if (resources[item:get_name()] or 0) >= count then
break
end
end
end
return true
end
-- traverse all items in a recipe
local function recurse_recipe(resources, queue, recipe)
for i, v in ipairs(flatten_recipe(recipe)) do
if not autocraft.traverse_recurse(resources, queue, ItemStack(v)) then
return false
end
end
return true
end
-- checks if the item/group is in the resource list and subtracts it
-- is the base case for traverse_recurse
local function has_sub(resources, item)
for i, v in ipairs(get_items_of(item:get_name())) do
if resources[v] and resources[v] >= item:get_count() then
resources[v] = resources[v] - item:get_count()
return true
end
end
return false
end
-- enqueues a recipe for an item and its needed sub items
function autocraft.traverse_recurse(resources, queue, item)
if type(item) == "string" then
item = ItemStack(item)
end
-- base case, uncraftibles/already in inventory
if has_sub(resources, item) then
return true
else
for i, v in ipairs(get_recipes(item:get_name())) do
if can_craft(resources, v.recipe) then
if recurse_recipe(resources, queue, v.recipe) then
table.insert(queue, v.recipe)
local tgt = item:get_count()
local result = v.count or 1
local delta = tgt - result
resources[v.name] = (resources[v.name] or 0) + result
if delta > 0 then
item:set_count(delta)
traverse_recurse(resources, queue, item)
end
return true
end
end
end
end
-- not enough resources
return false
end
-- create a crafting queue for an item
-- return queue if enough resources, nil if not
function autocraft.traverse(item)
local queue = {}
local resources = count_inv()
if autocraft.traverse_recurse(resources, queue, item) then
return queue
end
end
-- craft a traversed craft tree
local function queuecraft(tree)
end
-- make a queue and craft it
function autocraft.craft(item)
end

View File

@ -0,0 +1,3 @@
name = autocraft
author = emilia
description = Automatic crafting. Supports crafting blocks (Mineclone) and custom crafting trees.

674
clientmods/autoeat/LICENSE Normal file
View File

@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.

View File

@ -0,0 +1,2 @@
# autoeat
A dragonfire CSM to automatically eat when a certain hunger is reached (MineClone2).

View File

@ -0,0 +1,76 @@
autoeat = {}
autoeat.lock = false
local autodupe = false --rawget(_G, "autodupe")
local hud_id = nil
local function get_float(name, default)
return tonumber(minetest.settings:get("autoeat_" .. name) or "") or default
end
local etime = 0
function autoeat.eat()
local food_index
local food_count = 0
for index, stack in pairs(minetest.get_inventory("current_player").main) do
local stackname = stack:get_name()
if stackname ~= "" then
local def = minetest.get_item_def(stackname)
if def and def.groups.food then
food_count = food_count + 1
if food_index then
break
end
food_index = index
end
end
end
if food_index then
if food_count == 1 and autodupe then
--autodupe.needed(food_index)
autoeat.lock = true
else
local player = minetest.localplayer
local old_index = player:get_wield_index()
player:set_wield_index(food_index)
--minetest.interact("activate", {type = "nothing"})
minetest.place_node(minetest.localplayer:get_pos())
player:set_wield_index(old_index)
autoeat.lock = false
end
end
end
function autoeat.get_hunger()
if hud_id then
return minetest.localplayer:hud_get(hud_id).number
else
return 20
end
end
minetest.register_globalstep(function(dtime)
if not minetest.localplayer then return end
etime = etime + dtime
if autoeat.lock or minetest.settings:get_bool("autoeat") and etime >= get_float("cooldown", 0.5) and autoeat.get_hunger() < get_float("hunger", 9) then
etime = 0
autoeat.eat()
end
end)
local function get_hud()
local player = minetest.localplayer
local def
local i = -1
if not player then minetest.after(5,get_hud) return end
repeat
i = i + 1
def = player:hud_get(i)
until not def or def.text == "hbhunger_icon.png"
if def then
hud_id = i
end
end
minetest.after(15,get_hud )
minetest.register_cheat("AutoEat", "Player", "autoeat")

View File

@ -0,0 +1,4 @@
name = autoeat
author = Fleckenstein
description = Automatically eat when a certain hunger is reached (MineClone2).
optional_depends = autodupe

View File

@ -0,0 +1,3 @@
autoeat (AutoEat) bool false
autoeat_cooldown (AutoEat cooldown) float 0.5
autoeat_hunger (AutoEat hunger) float 9.0

732
clientmods/autofly/init.lua Normal file
View File

@ -0,0 +1,732 @@
-- autofly by cora
-- gui shit shamelessly stolen from advmarkers
-- https://git.minetest.land/luk3yx/advmarkers-csm
--[[
PATCHING MINETEST: (for autoaim)
in l_localplayer.h add:
static int l_set_yaw(lua_State *L);
static int l_set_pitch(lua_State *L);
in l_localplayer.cpp add:
int LuaLocalPlayer::l_set_yaw(lua_State *L)
{
LocalPlayer *player = getobject(L, 1);
f32 p = (float) luaL_checkinteger(L, 2);
player->setYaw(p);
g_game->cam_view.camera_yaw = p;
g_game->cam_view_target.camera_yaw = p;
player->setYaw(p);
return 0;
}
int LuaLocalPlayer::l_set_pitch(lua_State *L)
{
LocalPlayer *player = getobject(L, 1);
f32 p = (float) luaL_checkinteger(L, 2);
player->setPitch(p);
g_game->cam_view.camera_pitch = p;
g_game->cam_view_target.camera_pitch = p;
player->setPitch(p);
return 0;
}
in src/client/game.h, below class Game { public: add:
CameraOrientation cam_view = {0};
CameraOrientation cam_view_target = { 0 };
from src/client/game.cpp remove
CameraOrientation cam_view = {0};
CameraOrientation cam_view_target = { 0 };
--]]
-- Chat commands:
-- .wa x,y,z name - add waypoint with coords and name
-- .wah - quickadd this location (name will be time and date)
-- .wp - open the selection menu
-- .cls - remove hud
autofly = {}
wps={}
local landing_distance=5
local speed=0;
local ltime=0
local storage = minetest.get_mod_storage()
local oldpm=false
local lpos={x=0,y=0,z=0}
local info=minetest.get_server_info()
local stprefix="autofly-".. info['address'] .. '-'
--local stprefix="autofly-"
local hud_wps={}
autofly.flying=false
autofly.cruiseheight = 30
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
dofile(modpath .. "/wpforms.lua")
dofile(modpath .. "/pathfly.lua")
local hud_wp
local hud_info
-- /COMMON
local pos_to_string = ws.pos_to_string
local string_to_pos = ws.string_to_pos
function autofly.get2ddst(pos1,pos2)
return vector.distance({x=pos1.x,y=0,z=pos1.z},{x=pos2.x,y=0,z=pos2.z})
end
local last_sprint = false
local hud_ah=nil
function autofly.update_ah()
local pos=vector.new(0,0,0)
local ppos=minetest.localplayer:get_pos()
local yaw=math.floor(minetest.localplayer:get_yaw())
local theta =(yaw * math.pi / 180)
pos.x= math.floor( 100 * math.cos(theta) )
pos.z= math.floor( 100 * math.sin(theta) )
pos=vector.add(ppos,pos)
pos.y=ppos.y
local nname=pos_to_string(pos).."\n"..yaw.."\n"..'__________________________________________________________________________________________________________________________________________________'
if hud_ah then
minetest.display_chat_message(pos.x..","..pos.z)
minetest.localplayer:hud_change(hud_ah, 'world_pos', pos)
minetest.localplayer:hud_change(hud_ah, 'name', nname)
else
hud_ah = minetest.localplayer:hud_add({
hud_elem_type = 'waypoint',
name = nname,
title = pos_to_string(pos),
text = '',
number = 0x00ff00,
world_pos = pos,
precision = 0,
width = 1000
})
end
end
minetest.register_globalstep(function()
if not minetest.localplayer then return end
-- autofly.update_ah()
end)
minetest.register_globalstep(function()
if not minetest.localplayer then return end
autofly.axissnap()
if minetest.settings:get_bool("autosprint") or (minetest.settings:get_bool("continuous_forward") and minetest.settings:get_bool("autofsprint")) then
core.set_keypress("special1", true)
last_sprint = true
elseif last_sprint then
core.set_keypress("special1", false)
last_sprint = false
end
if not autofly.flying then autofly.set_hud_info("")
else
autofly.set_hud_info("")
local pos = autofly.last_coords
if pos then
local dst = vector.distance(pos,minetest.localplayer:get_pos())
local etatime=-1
if not (speed == 0) then etatime = ws.round2(dst / speed / 60,2) end
autofly.etatime=etatime
autofly.set_hud_info(autofly.last_name .. "\n" .. pos_to_string(pos) .. "\n" .. "ETA" .. etatime .. " mins")
local pm=minetest.settings:get_bool('pitch_move')
local hdst=autofly.get2ddst(pos,minetest.localplayer:get_pos())
if pm then hdst=vector.distance(pos,ws.dircoord(0,0,0)) end
if autofly.flying and hdst < landing_distance then
autofly.arrived()
end
end
end
if not minetest.settings:get_bool("freecam") and autofly.flying and (minetest.settings:get_bool('afly_autoaim')) then
autofly.aim(autofly.last_coords)
end
if ( os.time() < ltime + 1 ) then return end
ltime=os.time()
if lpos then
local dst=vector.distance(minetest.localplayer:get_pos(),lpos)
speed=ws.round2(dst,1)
autofly.speed=speed
end
lpos=minetest.localplayer:get_pos()
autofly.cruise()
end)
function autofly.get_speed()
return speed
end
function autofly.set_hud_wp(pos, title)
if hud_wp then
minetest.localplayer:hud_remove(hud_wp)
end
pos = string_to_pos(pos)
hud_wp=nil
if not pos then return end
if not title then
title = pos.x .. ', ' .. pos.y .. ', ' .. pos.z
end
autofly.last_name=title
if hud_wp then
minetest.localplayer:hud_change(hud_wp, 'name', title)
minetest.localplayer:hud_change(hud_wp, 'world_pos', pos)
else
hud_wp = minetest.localplayer:hud_add({
hud_elem_type = 'waypoint',
name = title,
text = 'm',
number = 0x00ff00,
world_pos = pos
})
end
return true
end
local hud_info
function autofly.get_quad()
local lp=minetest.localplayer:get_pos()
local quad=""
if lp.z < 0 then quad="South"
else quad="North" end
if lp.x < 0 then quad=quad.."-west"
else quad=quad.."-east" end
return quad
end
function autofly.get_wdir()
local qd=autofly.get_quad()
end
function autofly.get_local_name()
local ww=autofly.getwps()
local lp=minetest.localplayer:get_pos()
local odst=500;
local rt=false
for k,v in pairs(ww) do
local lwp=autofly.get_waypoint(v)
if type(lwp) == 'table' then
local dst=vector.distance(lp,lwp)
if dst < 500 then
if dst < odst then
odst=dst
rt=v
end
end
end
end
if not rt then rt=autofly.get_quad() end
return rt
end
local function countents()
local obj = minetest.localplayer.get_nearby_objects(10000)
return #obj
end
function autofly.set_hud_info(text)
if not minetest.localplayer then return end
if type(text) ~= "string" then return end
local dir=ws.getdir()
local ddir=""
if dir == "north" then
ddir="north(+z)"
elseif dir == "east" then
ddir="east(+x)"
elseif dir == "south" then
ddir="south(-z)"
elseif dir == "west" then
ddir="west(-x)"
end
local lp=minetest.localplayer
local vspeed=lp:get_velocity()
local ttext=text.."\nSpeed: "..speed.."n/s\n"
..ws.round2(vspeed.x,2) ..','
..ws.round2(vspeed.y,2) ..','
..ws.round2(vspeed.z,2) .."\n"
.."Yaw:"..ws.round2(lp:get_yaw(),2).."° Pitch:" ..ws.round2(lp:get_pitch(),2).."° "
if turtle then ttext=ttext..ddir end
if minetest.settings:get_bool('afly_shownames') then
ttext=ttext.."\n"..autofly.get_local_name() .."\nEntities: " .. countents()
end
if hud_info then
minetest.localplayer:hud_change(hud_info,'text',ttext)
else
hud_info = minetest.localplayer:hud_add({
hud_elem_type = 'text',
name = "Flight Info",
text = ttext,
number = 0x00ff00,
direction = 0,
position = {x=0,y=0.8},
alignment ={x=1,y=1},
offset = {x=0, y=0}
})
end
return true
end
function autofly.display(pos,name)
if name == nil then name=pos_to_string(pos) end
local pos=string_to_pos(pos)
autofly.set_hud_wp(pos, name)
return true
end
function autofly.display_waypoint(name)
local pos=name
if type(name) ~= 'table' then pos=autofly.get_waypoint(name) end
autofly.last_name = name
autofly.last_coords = pos
autofly.set_hud_info(name)
autofly.aim(autofly.last_coords)
autofly.display(pos,name)
return true
end
function autofly.goto_waypoint(name)
local wp=autofly.get_waypoint(name)
autofly.goto(wp)
autofly.last_name=name
autofly.display_waypoint(autofly.last_name)
return true
end
function autofly.goto(pos)
minetest.settings:set_bool("free_move",true)
minetest.settings:set_bool("continuous_forward",true)
if minetest.settings:get_bool("afly_sprint") then
minetest.settings:set_bool("autofsprint",true)
minetest.settings:set_bool("autoeat_timed",true)
end
minetest.settings:set_bool("afly_autoaim",true)
autofly.last_coords = pos
autofly.last_name = minetest.pos_to_string(pos)
autofly.aim(autofly.last_coords)
autofly.flying=true
autofly.set_hud_wp(autofly.last_coords, autofly.last_name)
return true
end
function autofly.fly3d(pos)
minetest.settings:set_bool("pitch_move",true)
autofly.goto(pos)
end
function autofly.fly2d(pos)
minetest.settings:set_bool("pitch_move",false)
autofly.goto(pos)
end
function autofly.arrived()
if not autofly.flying then return end
minetest.settings:set("continuous_forward", "false")
minetest.settings:set_bool("autofsprint",false)
minetest.settings:set_bool("pitch_move",oldpm)
minetest.settings:set_bool("afly_autoaim",false)
minetest.settings:set_bool("autoeat_timed",false)
autofly.set_hud_info("Arrived!")
autofly.flying = false
minetest.sound_play({name = "default_alert", gain = 1.0})
end
local cruise_wason=false
local nfctr=0
function autofly.cruise()
if not minetest.settings:get_bool('afly_cruise') then
if cruise_wason then
cruise_wason=false
core.set_keypress("jump",false)
core.set_keypress("sneak",false)
end
return end
local lp=minetest.localplayer:get_pos()
local pos1 = vector.add(lp,{x=16,y=100,z=16})
local pos2 = vector.add(lp,{x=-16,y=-100,z=-16})
local nds=minetest.find_nodes_in_area_under_air(pos1, pos2, nlist.get_mclnodes())
local y=0
local found=false
for k,v in ipairs(nds) do
local nd = minetest.get_node_or_nil(v)
if nd ~= nil and nd.name ~= "air" then
if v.y > y then
y=v.y
found=true
end
end
end
if (autofly.cruiseheight ~= nil) then y=y+autofly.cruiseheight end
local diff = math.ceil(lp.y - y)
if not cruise_wason then --initially set the cruiseheight to the current value above ground
-- if not found then return end --wait with activation til a ground node has been found.
local clr,nnd=minetest.line_of_sight(lp,vector.add(lp,{x=1,y=-200,z=1}))
if not clr then diff = math.ceil(lp.y - nnd.y)
elseif not found then return end
if diff < 1 then autofly.cruiseheight = 20
else autofly.cruiseheight = diff end
cruise_wason=true
minetest.display_chat_message("cruise mode activated. target height set to " .. diff .. " nodes above ground.")
end
if not found then
if nfctr<20 then nfctr = nfctr + 1 return end
--minetest.display_chat_message("no nodes found for 20 iterations. lowering altitude.")
nfctr=0
minetest.settings:set_bool("free_move",false)
core.set_keypress("jump",false)
core.set_keypress("sneak",false)
return
end
local tolerance = 1
if diff < -tolerance then
minetest.settings:set_bool("free_move",true)
core.set_keypress("jump",true)
core.set_keypress("sneak",false)
--minetest.display_chat_message("too low: " .. y)
elseif diff > tolerance * 10 then
core.set_keypress("jump",false)
core.set_keypress("sneak",true)
minetest.settings:set_bool("free_move",false)
--minetest.display_chat_message("too high: " .. y)
elseif diff > tolerance then
core.set_keypress("jump",false)
core.set_keypress("sneak",true)
else
minetest.settings:set_bool("free_move",true)
core.set_keypress("jump",false)
core.set_keypress("sneak",false)
--minetest.display_chat_message("target height reached: " .. y)
end
end
function autofly.aim(tpos)
return ws.aim(tpos)
end
function autofly.autotp(tpname)
if minetest.localplayer == nil then autofly.autotp(tpname) end
local tpos=nil
if tpname == nil then
tpos = autofly.get_waypoint('AUTOTP')
elseif type(tpname) == "table" then
tpos = tpname
else
tpos=autofly.get_waypoint(tpname)
end
if tpos == nil then return end
local lp=minetest.localplayer
local dst=vector.distance(lp:get_pos(),tpos)
if (dst < 300) then
minetest.sound_play({name = "default_alert", gain = 3.0})
autofly.delete_waypoint('AUTOTP')
return true
end
autofly.set_waypoint(tpos,'AUTOTP')
local boat_found=false
for k, v in ipairs(lp.get_nearby_objects(4)) do
local txt = v:get_item_textures()
if ( txt:find('mcl_boats_texture')) then
boat_found=true
minetest.display_chat_message("boat found. entering and tping to "..minetest.pos_to_string(autofly.get_waypoint('AUTOTP')))
autofly.aim(vector.add(v:get_pos(),{x=0,y=-1.5,z=0}))
minetest.after("0.2",function()
minetest.interact("place") end)
minetest.after("1.5",function()
autofly.warpae('AUTOTP')
end)
return true
end
end
if not boat_found then
minetest.display_chat_message("no boat found. trying again in 5.")
minetest.after("5.0",function() autofly.autotp(tpname) end)
return end
end
autofly.register_transport('Fly3D',function(pos,name) autofly.fly3d(pos,name) end)
autofly.register_transport('Fly2D',function(pos,name) autofly.fly2d(pos,name) end)
autofly.register_transport('wrp',function(pos,name) autofly.warp(name) end)
--autofly.register_transport('atp',function(pos,name) autofly.autotp(name) end)
function autofly.axissnap()
if not minetest.settings:get_bool('afly_snap') then return end
if minetest.settings:get_bool("freecam") then return end
local y=minetest.localplayer:get_yaw()
local yy=nil
if ( y < 45 or y > 315 ) then
yy=0
elseif (y < 135) then
yy=90
elseif (y < 225 ) then
yy=180
elseif ( y < 315 ) then
yy=270
end
if yy ~= nil then
minetest.localplayer:set_yaw(yy)
end
end
minetest.register_on_death(function()
if minetest.localplayer then
local name = 'Death waypoint'
local pos = minetest.localplayer:get_pos()
autofly.last_coords = pos
autofly.last_name = name
autofly.set_waypoint(pos,name)
autofly.display(pos,name)
end
end)
local function get_dimension(pos)
if pos.y > -65 then return "overworld"
elseif pos.y > -8000 then return "void"
elseif pos.y > -27000 then return "end"
elseif pos.y >29000 then return "void"
elseif pos.y >31000 then return "nether"
else return "void"
end
end
function autofly.warp(name)
local pos=autofly.get_waypoint(name)
if pos then
if get_dimension(pos) == "void" then return false end
minetest.localplayer:set_pos(pos)
return true
end
end
function autofly.warpae(name)
local s, m = autofly.warp(name)
if s then
minetest.disconnect()
end
return true
end
function autofly.getwps()
local wp={}
for name, _ in pairs(storage:to_table().fields) do
if name:sub(1, string.len(stprefix)) == stprefix then
table.insert(wp, name:sub(string.len(stprefix)+1))
end
end
table.sort(wp)
return wp
end
function autofly.impfromsrv(srv,sel)
local srvstr="autofly-".. srv .. '-'
for name, _ in pairs(storage:to_table().fields) do
if name:sub(1, string.len(srvstr)) == srvstr then
local name=name:sub(string.len(srvstr)+1)
if not sel or ( sel and name:sub(1, string.len(sel)) == sel ) then
local pos=string_to_pos(storage:get_string(srvstr .. tostring(name)))
autofly.set_waypoint(pos,name)
end
end
end
return wp
end
function autofly.set_waypoint(pos, name)
pos = pos_to_string(pos)
if not pos then return end
storage:set_string(stprefix .. tostring(name), pos)
return true
end
function autofly.delete_waypoint(name)
storage:set_string(stprefix .. tostring(name), '')
end
function autofly.get_waypoint(name)
return string_to_pos(storage:get_string(stprefix .. tostring(name)))
end
function autofly.rename_waypoint(oldname, newname)
oldname, newname = tostring(oldname), tostring(newname)
local pos = autofly.get_waypoint(oldname)
if not pos or not autofly.set_waypoint(pos, newname) then return end
if oldname ~= newname then
autofly.delete_waypoint(oldname)
end
return true
end
local function log(level, message)
minetest.log(level, ('[%s] %s'):format(mod_name, message))
end
function autofly.dumptolog()
local wp=autofly.getwps()
for name, _ in pairs(wp) do
--local lname=name:sub(string.len(stprefix)+1)
-- local ppos=string_to_pos(storage:get_string(tostring(name)))
if ppos then
log('action',name .. ' :: ')
end
end
end
minetest.after("5.0",function()
if autofly.get_waypoint('AUTOTP') ~= nil then autofly.autotp(nil) end
end)
math.randomseed(os.time())
local randflying = false
minetest.register_globalstep(function()
if randflying and not autofly.flying then
local x = math.random(-31000, 31000)
local y = math.random(2000, 31000)
local z = math.random(-31000, 31000)
autofly.goto({x = x, y = y, z = z})
end
end)
local function randfly()
if not randflying then
randflying = true
local lp = minetest.localplayer:get_pos()
autofly.goto(turtle.coord(lp.x, 6000, lp.z))
else
randflying = false
autofly.arrived()
end
end
minetest.register_chatcommand('waypoints', {
params = '',
description = 'Open the autofly GUI',
func = function(param) autofly.display_formspec() end
})
ws.register_chatcommand_alias('waypoints','wp', 'wps', 'waypoint')
-- Add a waypoint
minetest.register_chatcommand('add_waypoint', {
params = '<pos / "here" / "there"> <name>',
description = 'Adds a waypoint.',
func = function(param)
local s, e = param:find(' ')
if not s or not e then
return false, 'Invalid syntax! See .help add_mrkr for more info.'
end
local pos = param:sub(1, s - 1)
local name = param:sub(e + 1)
if not pos then
return false, err
end
if not name or #name < 1 then
return false, 'Invalid name!'
end
return autofly.set_waypoint(pos, name), 'Done!'
end
})
ws.register_chatcommand_alias('add_waypoint','wa', 'add_wp')
minetest.register_chatcommand('add_waypoint_here', {
params = 'name',
description = 'marks the current position',
func = function(param)
local name = os.date("%Y-%m-%d %H:%M:%S")
local pos = minetest.localplayer:get_pos()
return autofly.set_waypoint(pos, name), 'Done!'
end
})
ws.register_chatcommand_alias('add_waypoint_here', 'wah', 'add_wph')
minetest.register_chatcommand('clear_waypoint', {
params = '',
description = 'Hides the displayed waypoint.',
func = function(param)
if autofly.flying then autofly.flying=false end
if hud_wp then
minetest.localplayer:hud_remove(hud_wp)
hud_wp = nil
return true, 'Hidden the currently displayed waypoint.'
elseif not minetest.localplayer.hud_add then
minetest.run_server_chatcommand('clrmrkr')
return
elseif not hud_wp then
return false, 'No waypoint is currently being displayed!'
end
for k,v in wps do
minetest.localplayer:hud_remove(v)
table.remove(k)
end
end,
})
ws.register_chatcommand_alias('clear_waypoint', 'cwp','cls')
minetest.register_chatcommand('autotp', {
params = 'position',
description = 'autotp',
func = function(param)
autofly.autotp(minetest.string_to_pos(param))
end
})
ws.register_chatcommand_alias('autotp', 'atp')
minetest.register_chatcommand('wpdisplay', {
params = 'position name',
description = 'display waypoint',
func = function(pos,name)
autofly.display(pos,name)
end
})
ws.register_chatcommand_alias('wpdisplay', 'wpd')
minetest.register_chatcommand("randfly", {
description = "Randomly fly up high (toggle).",
func = randfly
})
minetest.register_cheat("Aim", "Autofly", "afly_autoaim")
minetest.register_cheat("AxisSnap", "Autofly", "afly_snap")
minetest.register_cheat("Cruise", "Autofly", "afly_cruise")
minetest.register_cheat("Sprint", "Autofly", "afly_sprint")
minetest.register_cheat("ShowNames", "Autofly", "afly_shownames")
minetest.register_cheat("Waypoints", "Autofly", autofly.display_formspec)

View File

@ -0,0 +1,3 @@
name = autofly
author = cora
description = autonomous flight

View File

@ -0,0 +1,35 @@
local function get_3dpos_from_yaw_and_pitch(r,yaw,pitch)
local tg=vector.new(0,0,0)
tg.x= r * math.sin(yaw)
tg.y= r * math.sin(pitch)
tg.z= r * math.cos(yaw)
return tg
end
local nexttarget=vector.new(0,0,0)
local sdst=40
function autofly.pathfind(coords)
local lp=minetest.localplayer
autofly.aim(coords)
local yaw=lp:get_yaw()
local pitch=lp:get_pitch()
local ltgt=vector.add(lp:get_pos(),get_3dpos_from_yaw_and_pitch(sdst,yaw,pitch))
local tgt=vector.new(0,0,0)
if not minetest.line_of_sight(lp:get_pos(), ltgt) then
local path=minetest.find_path(lp:get_pos(),ltgt,sdst*2,100,100,'Dijkstra')
if not path then
minetest.display_chat_message("no path found.")
return
end
tgt=vector.add(path[1],vector.new(0,2,0))
if vector.distance(lp:get_pos(),tgt) < 6 then
tgt=vector.add(path[2],vector.new(0,2,0))
end
else
tgt=ltgt
end
autofly.aim(tgt)
autofly.goto(tgt)
end

View File

@ -0,0 +1,3 @@
afly_autoaim (Autoaim) bool false
afly_softlanding (Soft Landing) bool true
afly_sprint (Sprint while flying) bool true

View File

@ -0,0 +1,251 @@
-- ADVMARKERS Stuff
-- Get the waypoints formspec
local formspec_list = {}
local selected_name = false
local storage = minetest.get_mod_storage()
local wpr=false;
local twpname=nil
local info=minetest.get_server_info()
local stprefix="autofly-".. info['address'] .. '-'
autofly = {}
wps={}
autofly.registered_transports={}
local tspeed = 20 -- speed in blocks per second
local speed=0;
local ltime=0
function autofly.register_transport(name,func)
table.insert(autofly.registered_transports,{name=name,func=func})
end
function autofly.display_formspec()
local formspec = 'size[6.25,9]' ..
'label[0,0;Waypoint list]' ..
'button_exit[0,7.5;1,0.5;display;Show]' ..
'button[3.625,7.5;1.3,0.5;rename;Rename]' ..
'button[4.9375,7.5;1.3,0.5;delete;Delete]'
local sp=0
for k,v in pairs(autofly.registered_transports) do
formspec=formspec..'button_exit['..sp..',8.5;1,0.5;'..v.name..';'..v.name..']'
sp=sp+0.8
end
formspec=formspec..'textlist[0,0.75;6,6;marker;'
local selected = 1
formspec_list = {}
local waypoints = autofly.getwps()
for id, name in ipairs(waypoints) do
if id > 1 then
formspec = formspec .. ','
end
if not selected_name then
selected_name = name
end
if name == selected_name then
selected = id
end
formspec_list[#formspec_list + 1] = name
formspec = formspec .. '##' .. minetest.formspec_escape(name)
end
formspec = formspec .. ';' .. tostring(selected) .. ']'
if selected_name then
local pos = autofly.get_waypoint(selected_name)
if pos then
pos = minetest.formspec_escape(tostring(pos.x) .. ', ' ..
tostring(pos.y) .. ', ' .. tostring(pos.z))
pos = 'Waypoint position: ' .. pos
formspec = formspec .. 'label[0,6.75;' .. pos .. ']'
end
else
-- Draw over the buttons
formspec = formspec .. 'button_exit[0,7.5;5.25,0.5;quit;Close dialog]' ..
'label[0,6.75;No waypoints. Add one with ".wa".]'
end
-- Display the formspec
return minetest.show_formspec('autofly-csm', formspec)
end
minetest.register_on_formspec_input(function(formname, fields)
if formname == 'autofly-ignore' then
return true
elseif formname ~= 'autofly-csm' then
return
end
local name = false
if fields.marker then
local event = minetest.explode_textlist_event(fields.marker)
if event.index then
name = formspec_list[event.index]
end
else
name = selected_name
end
if name then
for k,v in pairs(autofly.registered_transports) do
if fields[v.name] then
if not v.func(autofly.get_waypoint(name),name) then
minetest.display_chat_message('Error with '..v.name)
end
end
end
if fields.display then
if not autofly.display_waypoint(name) then
minetest.display_chat_message('Error displaying waypoint!')
end
elseif fields.goto then
if not autofly.goto_waypoint(name) then
minetest.display_chat_message('Error flying to waypoint!')
end
elseif fields.warp then
if not autofly.warp(name) then
minetest.display_chat_message('warp error')
end
elseif fields.autotp then
if not autofly.autotp(name) then
minetest.display_chat_message('warpandexit error')
end
elseif fields.itp then
if incremental_tp then
incremental_tp.tp(autofly.get_waypoint(name),1)
end
elseif fields.jitp then
if incremental_tp then
incremental_tp.tp(autofly.get_waypoint(name),0.5,0.4)
end
elseif fields.rename then
minetest.show_formspec('autofly-csm', 'size[6,3]' ..
'label[0.35,0.2;Rename waypoint]' ..
'field[0.3,1.3;6,1;new_name;New name;' ..
minetest.formspec_escape(name) .. ']' ..
'button[0,2;3,1;cancel;Cancel]' ..
'button[3,2;3,1;rename_confirm;Rename]')
elseif fields.rename_confirm then
if fields.new_name and #fields.new_name > 0 then
if autofly.rename_waypoint(name, fields.new_name) then
selected_name = fields.new_name
else
minetest.display_chat_message('Error renaming waypoint!')
end
autofly.display_formspec()
else
minetest.display_chat_message(
'Please enter a new name for the marker.'
)
end
elseif fields.delete then
minetest.show_formspec('autofly-csm', 'size[6,2]' ..
'label[0.35,0.25;Are you sure you want to delete this waypoint?]' ..
'button[0,1;3,1;cancel;Cancel]' ..
'button[3,1;3,1;delete_confirm;Delete]')
elseif fields.delete_confirm then
autofly.delete_waypoint(name)
selected_name = false
autofly.display_formspec()
elseif fields.cancel then
autofly.display_formspec()
elseif name ~= selected_name then
selected_name = name
autofly.display_formspec()
end
elseif fields.display or fields.delete then
minetest.display_chat_message('Please select a waypoint.')
end
return true
end)
-- Export waypoints
function autofly.export(raw)
local s = storage:to_table().fields
if raw == 'M' then
s = minetest.compress(minetest.serialize(s))
s = 'M' .. minetest.encode_base64(s)
elseif not raw then
s = minetest.compress(minetest.write_json(s))
s = 'J' .. minetest.encode_base64(s)
end
return s
end
-- Allow string exporting
minetest.register_chatcommand('wpexp', {
params = '[old]',
description = 'Exports an autofly string containing all your pois.',
func = function(param)
local export
if param == 'old' then
export = autofly.export('M')
else
export = autofly.export()
end
minetest.show_formspec('autofly-ignore',
'field[_;Your waypoint export string;' ..
minetest.formspec_escape(export) .. ']')
end
})
--register_chatcommand_alias('wpexp', 'wp_export', 'waypoint_export')
-- String importing
minetest.register_chatcommand('wpimp', {
params = '<autofly string>',
description = 'Imports an autofly string. This will not overwrite ' ..
'existing pois that have the same name.',
func = function(param)
if autofly.import(param) then
return true, 'Waypoints imported!'
else
return false, 'Invalid autofly string!'
end
end
})
--register_chatcommand_alias('wpimp', 'wp_import', 'waypoint_import')
-- Import waypoints
function autofly.import(s)
if type(s) ~= 'table' then
local ver = s:sub(1, 1)
if ver ~= 'M' and ver ~= 'J' then return end
s = minetest.decode_base64(s:sub(2))
local success, msg = pcall(minetest.decompress, s)
if not success then return end
if ver == 'M' then
s = minetest.deserialize(msg, true)
else
s = minetest.parse_json(msg)
end
end
-- Iterate over waypoints to preserve existing ones and check for errors.
if type(s) == 'table' then
for name, pos in pairs(s) do
if type(name) == 'string' and type(pos) == 'string' and
name:sub(1, 7) == 'marker-' and minetest.string_to_pos(pos) and
storage:get_string(name) ~= pos then
-- Prevent collisions
local c = 0
while #storage:get_string(name) > 0 and c < 50 do
name = name .. '_'
c = c + 1
end
-- Sanity check
if c < 50 then
storage:set_string(name, pos)
end
end
end
return true
end
end

View File

@ -0,0 +1,187 @@
---
-- autominer
autominer = {}
local dmg=false
local digging=false
local radius=6
local nodes=nlist.get("autominer")
local function sleep(n) -- seconds
local t0 = os.clock()
while os.clock() - t0 <= n do end
end
local function shuffle(tbl)
for i = #tbl, 2, -1 do
local j = math.random(i)
tbl[i], tbl[j] = tbl[j], tbl[i]
end
return tbl
end
local function checklava(pos)
local n=minetest.find_node_near(pos, 2, {'mcl_core:lava_source','mcl_core:lava_flowing'}, true)
if n == nil then return false end
return true
end
local function checkgravel(pos)
local n=minetest.find_node_near(pos, 1, {'mcl_core:gravel','mcl_core:sand'}, true)
if n == nil then return false end
return true
end
-- shamelessly stolen from dragonfire autotool
local function check_tool(stack, node_groups, old_best_time)
local toolcaps = stack:get_tool_capabilities()
if not toolcaps then return end
local best_time = old_best_time
for group, groupdef in pairs(toolcaps.groupcaps) do
local level = node_groups[group]
if level then
local this_time = groupdef.times[level]
if this_time < best_time then
best_time = this_time
end
end
end
return best_time < old_best_time, best_time
end
local function amautotool(pos)
local player = minetest.localplayer
local inventory = minetest.get_inventory("current_player")
local node=minetest.get_node_or_nil(pos)
local node_groups = minetest.get_node_def(node.name).groups
local new_index = player:get_wield_index()
local is_better, best_time = false, math.huge
is_better, best_time = check_tool(player:get_wielded_item(), node_groups, best_time)
is_better, best_time = check_tool(inventory.hand[1], node_groups, best_time)
for index, stack in pairs(inventory.main) do
is_better, best_time = check_tool(stack, node_groups, best_time)
if is_better then
new_index = index
end
end
player:set_wield_index(new_index)
end
local function find_tnod()
local pos = minetest.localplayer:get_pos()
local rr = vector.add(pos,{x=0,y=0,z=radius})
local pos1 = vector.add(pos,{x=radius,y=radius,z=radius})
local pos2 = vector.add(pos,{x=-radius,y=-radius,z=-radius})
local rt=shuffle(minetest.find_nodes_in_area(pos1, pos2, shuffle(nodes), true))
for k,v in pairs(rt) do
for kk,vv in pairs(shuffle(v)) do
-- minetest.display_chat_message("Found nodes:" ..dump(rt))
if ( vv.y > -57 ) and not checkgravel(vv) and not checklava(vv) then
rr=vv
break
end
end
end
if (checkgravel(rr) or checklava(rr)) then return minetest.after(0.2,find_tnod) end
return rr
-- return rt
end
local function get_hnode()
local ppos=minetest.localplayer:get_pos()
local n=minetest.get_node_or_nil(vector.add(ppos,{x=0,y=1,z=0}))
return n
end
local function dighead()
if not minetest.localplayer then return end
local ppos=vector.add(minetest.localplayer:get_pos(),{x=0,y=1,z=0})
local n=get_hnode()
if n==nil or n['name'] == 'air' then return end
--amautotool(ppos)
minetest.localplayer:set_wield_index(1)
minetest.dig_node(ppos)
minetest.dig_node(vector.add(ppos,{x=0,y=1,z=0}))
digging=false
if (minetest.settings:get_bool('aminer_active')) then
local hp=minetest.localplayer:get_hp()
local hn=get_hnode()
if (hp > 17) then
minetest.after(0.2,autominer.aminer )
else
minetest.display_chat_message("taken too much damage. wait.")
local ppos=vector.add(minetest.localplayer:get_pos(),{x=0,y=1,z=0})
minetest.dig_node(ppos)
minetest.dig_node(vector.add(ppos,{x=0,y=1,z=0}))
minetest.after(1.0,function() minetest.dig_node(vector.add(ppos,{x=0,y=0,z=0})) end )
minetest.after(1.4,function() minetest.dig_node(vector.add(ppos,{x=0,y=1,z=0})) end )
minetest.after(1.8,function() minetest.dig_node(vector.add(ppos,{x=0,y=0,z=0})) end )
minetest.after(2.5,function() minetest.dig_node(vector.add(ppos,{x=0,y=1,z=0})) end )
-- minetest.settings:set_bool("aminer_active",false)
end
end
end
local function rwarp()
if not (minetest.settings:get_bool("aminer_active")) then return end
digging=true
local nod=find_tnod()
if not nod then
minetest.display_chat_message('lava detected. stop.')
return
end
minetest.localplayer:set_pos(vector.add(nod,{x=0.3,y=-1.2,z=0.3}))
dighead()
minetest.after(0.2, dighead)
end
local function amine()
minetest.after(1.0,rwarp)
end
function autominer.aminer()
if not digging then
digging=true
dmg=hpchange.get_status()
if dmg then
minetest.after(3.0,rwarp)
else
minetest.after(0.5,rwarp)
end
end
end
local lastch=0
minetest.register_globalstep(function()
if os.time() < lastch + 5 then return end
lastch=os.time()
if ( minetest.settings:get_bool('aminer_active') ) then
dmg=true
digging=false
autominer.aminer()
end
end)
minetest.register_chatcommand("aminer", {
description = "",
func = function()
dmg=true
digging=false
minetest.settings:set_bool("aminer_active",true)
autominer.aminer()
end,
})
minetest.register_chatcommand("amine", {
description = "",
func = amine
})
minetest.register_chatcommand("dhe", {
description = "",
func = dighead
})
minetest.register_on_damage_taken(function(hp)
dmg=true
end)
if (_G["minetest"]["register_cheat"] ~= nil) then
minetest.register_cheat("Autominer (!!! ALPHA!! this will lead to you dying!!!)", "Player", "aminer_active")
else
minetest.settings:set_bool('aminer_active',true)
end

View File

@ -0,0 +1,3 @@
name = autominer
author = cora
description = Mining bot

View File

@ -0,0 +1 @@
aminer_active (Enable Autominer) bool false

View File

@ -0,0 +1,7 @@
minetest.register_chatcommand('mtq', {
description = 'automt-quit',
func = function(param)
minetest.log("AUTOMT Actually Quit")
minetest.disconnect()
end
})

View File

@ -0,0 +1,3 @@
name = automt
author = cora
description = automt

232
clientmods/bookbot/init.lua Normal file
View File

@ -0,0 +1,232 @@
-- CC0/Unlicense Emilia 2020
-- TODO: API
-- TODO: all count should be changed to support using a bookbot as a rolling writer
-- an alternate solution is to just have an inventory manager bot that intermittently swaps the inventory and activates bookbot
-- TODO: local formspec stuff
--[[
COMMANDS
write <book> <times> Writes the book named <book>, <times> times
randwrite <times> Writes randomized books
bookadd_form Opens a book formspec for adding a book to the library
bookadd_this <shortname> Adds the currently selected book to the library
bookdel <shortname> Removes a book from the library
bookpeek <book> Peeks at a book in the library
booklist Lists all books
--]]
bookbot = {}
local book_length_max = 4500
local write = 0
local books = {
example = {
title = "Autobook",
author = "Emilia",
text = "This is an automatically written book."
}
}
local book
local book_iterator
local read_form = [[
size[9,8]
label[0,0;N]
label[0,1;A]
textlist[0,2;9,5;;T]
]]
local edit_form = [[
size[9,8]
field[0,0;9,1;title;;N]
field[0,1;9,1;author;;A]
textarea[0,2;9,5;text;;T]
]]
local storage = minetest.get_mod_storage()
local function storage_save()
storage:set_string("books", minetest.write_json(books))
end
local function storage_load()
local sbooks = storage:get("books")
if sbooks then
books = minetest.parse_json(sbooks)
end
end
storage_load()
local function open_book()
if minetest.switch_to_item("mcl_books:writable_book") then
minetest.interact("place")
book = book_iterator()
else
write = 0
book = nil
book_iterator = nil
end
end
local function count_books()
local lpmain = minetest.get_inventory("current_player").main
local count = 0
for i, v in ipairs(lpmain) do
if v:get_name() == "mcl_books:writable_book" then
count = count + 1
end
end
return count
end
minetest.register_on_receiving_inventory_form(function(formname, formspec)
if formname == "mcl_books:writable_book" and write ~= 0 then
minetest.send_inventory_fields("mcl_books:writable_book", {
text = book.text,
sign = "true",
})
minetest.close_formspec("")
elseif formname == "mcl_books:signing" and write ~= 0 then
minetest.send_inventory_fields("mcl_books:signing", {
title = book.title,
sign = "true"
})
minetest.close_formspec("")
write = write - 1
if write > 0 then
-- this should take lag into consideration
minetest.after(0.5, open_book)
end
end
end)
local function timesparse(times)
local count = 1
if times then
if times == "all" then
count = count_books()
elseif type(times) == "number" or times:match("^[0-9]+$") then
count = tonumber(times)
end
end
return count
end
function bookbot.write_iterator(iterator, write_no)
book_iterator = iterator
write = timesparse(write_no)
open_book()
end
function bookbot.write_simple(book, write_no)
local book_iterator = function()
return book
end
bookbot.write_iterator(book_iterator, write_no)
end
function bookbot.write(bookname, write_no)
local book = "example"
if bookname and books[bookname] then
book = books[bookname]
end
bookbot.write_simple(book, write_no)
end
function bookbot.add(bookname, title, author, text)
books[bookname] = {
title = title,
author = author,
text = text
}
storage_save()
end
minetest.register_chatcommand("write", {
description = "Write a book.",
params = "<book> <?ntimes/all>",
func = function(params)
local p = string.split(params, " ")
if #p == 0 then
minetest.display_chat_message("Error: book short name required")
return
end
bookbot.write(p[1], p[2])
end
})
minetest.register_chatcommand("bookadd_this", {
description = "Add the currently wielded book to the library, <name> is for the name in the library.",
params = "<name>",
func = function(params)
if params == "" then
minetest.display_chat_message("Error: no short name given")
return
end
local wielded = minetest.localplayer:get_wielded_item()
if wielded:get_name() == "mcl_books:written_book" then
local meta = wielded:get_meta():to_table()
bookbot.add(params,
meta.fields.title,
meta.fields.author,
meta.fields.text)
end
end
})
minetest.register_chatcommand("booklist", {
description = "List all saved books.",
func = function()
local out = ""
local first = true
for k, v in pairs(books) do
if not first then
out = out .. ", "
end
out = out .. k
first = false
end
minetest.display_chat_message("Saved books:")
minetest.display_chat_message(out)
end
})
minetest.register_chatcommand("randwrite", {
description = "Write random books.",
params = "<?times/all>",
func = function(params)
local p = string.split(params, " ")
book_iterator = function()
local out = {}
for i = 1, book_length_max do
table.insert(out, string.char(math.random(0x20, 0xFF)))
end
return {
title = "Random book",
author = "The computer",
text = table.concat(out)
}
end
bookbot.write_iterator(book_iterator, p[1])
end
})

View File

@ -0,0 +1,3 @@
name = bookbot
author = Emilia
description = Manage book writing and library

113
clientmods/cchat/init.lua Normal file
View File

@ -0,0 +1,113 @@
--
-- coras Chat hacks
-- * verify death messages
-- * log chat to stdout
cchat = {}
-- verify death
table.insert(minetest.registered_on_receiving_chat_message, 1, function(msg)
local d = msg:find('\1b@mcl_death_messages\1b') --mineclone specific
if d then
-- minetest.send_chat_message("real.") --uncomment to publish approval
minetest.display_chat_message("real.")
end
end)
-- chat logging
local mod_name = minetest.get_current_modname()
local function log(level, message)
minetest.log(level, ('[%s] %s'):format(mod_name, message))
end
log('action', 'Chatlog loading...')
local LOG_LEVEL = 'action'
local server_info = minetest.get_server_info()
local server_id = server_info.address .. ':' .. server_info.port
local my_name = ''
local register_on_send = minetest.register_on_sending_chat_message or minetest.register_on_sending_chat_messages
local register_on_receive = minetest.register_on_receiving_chat_message or minetest.register_on_receiving_chat_messages
local function safe(func)
-- wrap a function w/ logic to avoid crashing the game
local f = function(...)
local status, out = pcall(func, ...)
if status then
return out
else
log('warning', 'Error (func): ' .. out)
return nil
end
end
return f
end
local set_my_name_tries = 0
local function set_my_name()
if minetest.localplayer then
my_name = minetest.localplayer:get_name()
elseif set_my_name_tries < 20 then
set_my_name_tries = set_my_name_tries + 1
minetest.after(1, set_my_name)
else
my_name = ''
end
end
local function loglastlogs()
if not fren then return end
for k,v in pairs(fren.friends) do
if fren.on_server(fren.name_of(k)) then
log("LASTLOGLOG START")
--minetest.display_chat_message('Last login of friend ' .. fren.name_of(k))
log("Last login of friend "..fren.name_of(k))
minetest.send_chat_message("/last-login "..fren.name_of(k))
end
end
for k,v in pairs(fren.enemies) do
if fren.on_server(fren.name_of(k)) then
log("Last login of enemy "..fren.name_of(k))
--minetest.display_chat_message('Last login of friend ' .. fren.name_of(k))
minetest.send_chat_message("/last-login "..fren.name_of(k))
minetest.after("5.0",function() log("LASTLOGLOG END") end)
end
end
end
--minetest.after("5.0",function() loglastlogs() end)
if minetest.register_on_connect then
minetest.register_on_connect(set_my_name)
elseif minetest.register_on_mods_loaded then
minetest.register_on_mods_loaded(set_my_name)
else
minetest.after(1, set_my_name)
end
if register_on_send then
register_on_send(safe(function(message)
local msg = minetest.strip_colors(message)
if msg ~= '' then
log(LOG_LEVEL, ('%s@%s [sent] %s'):format(my_name, server_id, msg))
end
end))
end
if register_on_receive then
register_on_receive(safe(function(message)
local msg = minetest.strip_colors(message)
if msg ~= '' then
log(LOG_LEVEL, ('%s@%s %s'):format(my_name, server_id, msg))
end
end))
end

View File

@ -0,0 +1,3 @@
name = cchat
author = cora
description = cora's chat extensions, primarily log to stdout

View File

@ -0,0 +1,91 @@
if INIT == "client" then
core.register_chatcommand("say", {
description = "Send raw text",
func = function(text)
minetest.send_chat_message(text)
return true
end,
})
core.register_chatcommand("teleport", {
params = "<X>,<Y>,<Z>",
description = "Teleport to relative coordinates.",
func = function(param)
local success, pos = minetest.parse_relative_pos(param)
if success then
minetest.localplayer:set_pos(pos)
return true, "Teleporting to " .. minetest.pos_to_string(pos)
end
return false, pos
end,
})
core.register_chatcommand("wielded", {
description = "Print itemstring of wieleded item",
func = function()
return true, minetest.localplayer:get_wielded_item():get_name()
end
})
core.register_chatcommand("disconnect", {
description = "Exit to main menu",
func = function(param)
minetest.disconnect()
end,
})
core.register_chatcommand("players", {
description = "List online players",
func = function(param)
return true, "Online players: " .. table.concat(minetest.get_player_names(), ", ")
end
})
core.register_chatcommand("kill", {
description = "Kill yourself",
func = function()
minetest.send_damage(minetest.localplayer:get_hp())
end,
})
core.register_chatcommand("hop", {
description = "Hop",
func = function()
minetest.set_keypress("jump", true)
end,
})
core.register_chatcommand("set", {
params = "([-n] <name> <value>) | <name>",
description = "Set or read client configuration setting",
func = function(param)
local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
if arg and arg == "-n" and setname and setvalue then
minetest.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
setname, setvalue = string.match(param, "([^ ]+) (.+)")
if setname and setvalue then
if not minetest.settings:get(setname) then
return false, "Failed. Use '.set -n <name> <value>' to create a new setting."
end
minetest.settings:set(setname, setvalue)
return true, setname .. " = " .. setvalue
end
setname = string.match(param, "([^ ]+)")
if setname then
setvalue = minetest.settings:get(setname)
if not setvalue then
setvalue = "<not set>"
end
return true, setname .. " = " .. setvalue
end
return false, "Invalid parameters (see .help set)."
end,
})
end

View File

@ -0,0 +1,3 @@
name = commands
author = Fleckenstein
description = Misc cheat commands

View File

@ -0,0 +1,48 @@
minetest.register_on_receiving_chat_message(function(message)
if message:sub(1, 1) == "#" and minetest.settings:get_bool("ignore_status_messages") ~= false then
return true
elseif message:find('\1b@mcl_death_messages\1b') and minetest.settings:get_bool("mark_deathmessages") ~= false then
minetest.display_chat_message(minetest.colorize("#F25819", "[Deathmessage] ") .. message)
return true
end
end)
function minetest.send_colorized(message)
local starts_with = message:sub(1, 1)
if starts_with == "/" or starts_with == "." then return end
local reverse = minetest.settings:get_bool("chat_reverse")
if reverse then
local msg = ""
for i = 1, #message do
msg = message:sub(i, i) .. msg
end
message = msg
end
local use_chat_color = minetest.settings:get_bool("use_chat_color")
local color = minetest.settings:get("chat_color")
if use_chat_color and color then
local msg
if color == "rainbow" then
msg = minetest.rainbow(message)
else
msg = minetest.colorize(color, message)
end
message = msg
end
minetest.send_chat_message(message)
return true
end
minetest.register_on_sending_chat_message(minetest.send_colorized)
minetest.register_cheat("IgnoreStatus", "Chat", "ignore_status_messages")
minetest.register_cheat("DeathMessages", "Chat", "mark_deathmessages")
minetest.register_cheat("ColoredChat", "Chat", "use_chat_color")
minetest.register_cheat("ReversedChat", "Chat", "chat_reverse")

View File

@ -0,0 +1,3 @@
name = chat
author = Fleckenstein
description = The chat modifications of Dragonfireclient

View File

@ -0,0 +1,3 @@
chat_color (Chat Color) string white
chat_reverse (Reverse Chat messages) bool false
ignore_status_messages (Ignore status messages from server) bool false

View File

@ -0,0 +1,193 @@
local placed_crystal
local switched_to_totem = 0
local used_sneak = true
local totem_move_action = InventoryAction("move")
totem_move_action:to("current_player", "main", 9)
local mobs_friends = {
'mobs_mc_bat.png',
'mobs_mc_cat_black.png',
'mobs_mc_cat_ocelot.png',
'mobs_mc_cat_red.png',
'mobs_mc_cat_siamese.png',
'mobs_mc_diamond_horse_armor.png',
'mobs_mc_donkey.png',
'mobs_mc_wolf_collar.png',
'mobs_mc_wolf.png',
'mobs_mc_wolf_tame.png',
'mobs_mc_villager_butcher.png',
'mobs_mc_villager_farmer.png',
'mobs_mc_villager_librarian.png',
'mobs_mc_villager.png',
'mobs_mc_villager_priest.png',
'mobs_mc_villager_smith.png',
'mobs_mc_iron_golem.png',
'mobs_mc_iron_horse_armor.png',
'mobs_mc_mooshroom.png',
'mobs_mc_mule.png',
'mobs_mc_pig.png',
'mobs_mc_pig_saddle.png',
'mobs_mc_polarbear.png',
'mobs_mc_rabbit_black.png',
'mobs_mc_rabbit_brown.png',
'mobs_mc_rabbit_caerbannog.png',
'mobs_mc_rabbit_gold.png',
'mobs_mc_rabbit_salt.png',
'mobs_mc_rabbit_toast.png',
'mobs_mc_rabbit_white.png',
'mobs_mc_rabbit_white_splotched.png',
'mobs_mc_sheep_fur.png',
'mobs_mc_sheep.png',
'mobs_mc_horse_armor_diamond.png',
'mobs_mc_horse_armor_gold.png',
'mobs_mc_horse_armor_iron.png',
'mobs_mc_horse_black.png',
'mobs_mc_horse_brown.png',
'mobs_mc_horse_chestnut.png',
'mobs_mc_horse_darkbrown.png',
'mobs_mc_horse_gray.png',
'mobs_mc_horse_creamy.png',
'mobs_mc_horse_markings_blackdots.png',
'mobs_mc_horse_markings_whitedots.png',
'mobs_mc_horse_markings_whitefield.png',
'mobs_mc_horse_markings_white.png',
'mobs_mc_horse_white.png',
'mobs_mc_snowman',
'mobs_mc_chicken.png',
'mobs_mc_enderman.png',
'mobs_mc_cow.png'
}
local mobs_bad = {
'mcl_totems_totem.png',
'mobs_mc_blaze.png',
'mobs_mc_cave_spider.png',
'mobs_mc_creeper.png',
'mobs_mc_dragon.png',
'mobs_mc_endergolem.png',
'mobs_mc_magmacube.png',
'mobs_mc_enderman_eyes.png',
'mobs_mc_endermite.png',
'mobs_mc_ghast.png',
'mobs_mc_gold_horse_armor.png',
'mobs_mc_guardian_elder.png',
'mobs_mc_guardian.png',
'mobs_mc_husk.png',
'mobs_mc_shulker_black.png',
'mobs_mc_shulker_blue.png',
'mobs_mc_shulker_brown.png',
'mobs_mc_shulker_cyan.png',
'mobs_mc_shulker_gray.png',
'mobs_mc_shulker_green.png',
'mobs_mc_shulker_light_blue.png',
'mobs_mc_shulker_lime.png',
'mobs_mc_shulker_magenta.png',
'mobs_mc_shulker_orange.png',
'mobs_mc_shulker_pink.png',
'mobs_mc_shulker_purple.png',
'mobs_mc_shulker_red.png',
'mobs_mc_shulker_silver.png',
'mobs_mc_shulker_white.png',
'mobs_mc_shulker_yellow.png',
'mobs_mc_silverfish.png',
'mobs_mc_skeleton.png',
'mobs_mc_slime.png',
'mobs_mc_spider_eyes.png',
'mobs_mc_spider.png',
'mobs_mc_squid.png',
'mobs_mc_stray.png',
'mobs_mc_stray_overlay.png',
'mobs_mc_vex.png',
'mobs_mc_vex_charging.png',
'mobs_mc_vindicator.png',
'mobs_mc_evoker.png',
'mobs_mc_illusionist.png',
'mobs_mc_witch.png',
'mobs_mc_wither.png',
'mobs_mc_wither_skeleton.png',
'mobs_mc_wolf_angry.png',
'mobs_mc_zombie_butcher.png',
'mobs_mc_zombie_farmer.png',
'mobs_mc_zombie_librarian.png',
'mobs_mc_zombie_priest.png',
'mobs_mc_zombie_smith.png',
'mobs_mc_zombie_villager.png',
'mobs_mc_zombie_pigman.png',
'mobs_mc_zombie.png',
'mobs_mc_horse_zombie.png'
}
--minetest.register_list_command("friend", "Configure Friend List (friends dont get attacked by Killaura or Forcefield)", "friendlist")
local nexthit=0
minetest.register_globalstep(function(dtime)
local player = minetest.localplayer
if not player then return end
local control = player:get_control()
local pointed = minetest.get_pointed_thing()
local item = player:get_wielded_item():get_name()
if minetest.settings:get_bool("killaura") or minetest.settings:get_bool("forcefield") and control.dig then
if nexthit > os.clock() then return end
nexthit=os.clock() + 0.01
for _, obj in pairs(minetest.get_objects_inside_radius(player:get_pos(), 5)) do
local do_attack = false
local txt=obj:get_item_textures()
if(obj:is_player() and fren.is_enemy(obj:get_name())) then do_attack=true end
for k,v in pairs(mobs_bad) do if txt:find(v) then do_attack=true end end
if do_attack then
local owx=core.localplayer:get_wield_index()
minetest.switch_to_item('mcl_tools:sword_diamond')
obj:punch()
core.localplayer:set_wield_index(owx)
end
end
elseif minetest.settings:get_bool("crystal_pvp") then
if placed_crystal then
if minetest.switch_to_item("mobs_mc:totem") then
switched_to_totem = 5
end
placed_crystal = false
elseif switched_to_totem > 0 then
if item ~= "mobs_mc:totem" then
switched_to_totem = 0
elseif pointed and pointed.type == "object" then
pointed.ref:punch()
switched_to_totem = 0
else
switched_to_totem = switched_to_totem
end
elseif control.place and item == "mcl_end:crystal" then
placed_crystal = true
elseif control.sneak then
if pointed and pointed.type == "node" and not used_sneak then
local pos = minetest.get_pointed_thing_position(pointed)
local node = minetest.get_node_or_nil(pos)
if node and (node.name == "mcl_core:obsidian" or node.name == "mcl_core:bedrock") then
minetest.switch_to_item("mcl_end:crystal")
minetest.place_node(pos)
placed_crystal = true
end
end
used_sneak = true
else
used_sneak = false
end
end
if minetest.settings:get_bool("autototem") then
local totem_stack = minetest.get_inventory("current_player").main[9]
if totem_stack and totem_stack:get_name() ~= "mobs_mc:totem" then
local totem_index = minetest.find_item("mobs_mc:totem")
if totem_index then
totem_move_action:from("current_player", "main", totem_index)
totem_move_action:apply()
player:set_wield_index(9)
end
end
end
end)
minetest.register_cheat("Killaura", "Combat", "killaura")
minetest.register_cheat("Forcefield", "Combat", "forcefield")
minetest.register_cheat("CrystalPvP", "Combat", "crystal_pvp")
minetest.register_cheat("AutoTotem", "Combat", "autototem")

View File

@ -0,0 +1,3 @@
name = combat
author = cora
description = killaura, forcefield, crystal_pvp, autototem

View File

@ -0,0 +1,179 @@
local drop_action = InventoryAction("drop")
local strip_move_act = InventoryAction("move")
strip_move_act:to("current_player", "craft", 1)
local strip_craft_act = InventoryAction("craft")
strip_craft_act:craft("current_player")
local strip_move_back_act = InventoryAction("move")
strip_move_back_act:from("current_player", "craftresult", 1)
minetest.register_globalstep(function(dtime)
local player = minetest.localplayer
if not player then return end
local item = player:get_wielded_item()
local itemdef = minetest.get_item_def(item:get_name())
local wieldindex = player:get_wield_index()
-- AutoRefill
if minetest.settings:get_bool("autorefill") and itemdef then
local space = item:get_free_space()
local i = minetest.find_item(item:get_name(), wieldindex + 1)
if i and space > 0 then
local move_act = InventoryAction("move")
move_act:to("current_player", "main", wieldindex)
move_act:from("current_player", "main", i)
move_act:set_count(space)
move_act:apply()
end
end
-- AutoPlanks (Strip in DF)
if minetest.settings:get_bool("autoplanks") then
if itemdef and itemdef.groups.tree and player:get_control().place then
strip_move_act:from("current_player", "main", wieldindex)
strip_move_back_act:to("current_player", "main", wieldindex)
strip_move_act:apply()
strip_craft_act:apply()
strip_move_back_act:apply()
end
end
-- AutoEject
if minetest.settings:get_bool("autoeject") then
local list = (minetest.settings:get("eject_items") or ""):split(",")
local inventory = minetest.get_inventory("current_player")
for index, stack in pairs(inventory.main) do
if table.indexof(list, stack:get_name()) ~= -1 then
drop_action:from("current_player", "main", index)
drop_action:apply()
end
end
end
end)
minetest.register_list_command("eject", "Configure AutoEject", "eject_items")
-- AutoTool
local function check_tool(stack, node_groups, old_best_time)
local toolcaps = stack:get_tool_capabilities()
if not toolcaps then return end
local best_time = old_best_time
for group, groupdef in pairs(toolcaps.groupcaps) do
local level = node_groups[group]
if level then
local this_time = groupdef.times[level]
if this_time and this_time < best_time then
best_time = this_time
end
end
end
return best_time < old_best_time, best_time
end
local function find_best_tool(nodename, switch)
local player = minetest.localplayer
local inventory = minetest.get_inventory("current_player")
local node_groups = minetest.get_node_def(nodename).groups
local new_index = player:get_wield_index()
local is_better, best_time = false, math.huge
is_better, best_time = check_tool(player:get_wielded_item(), node_groups, best_time)
if inventory.hand then
is_better, best_time = check_tool(inventory.hand[1], node_groups, best_time)
end
for index, stack in ipairs(inventory.main) do
is_better, best_time = check_tool(stack, node_groups, best_time)
if is_better then
new_index = index
end
end
return new_index
end
function minetest.select_best_tool(nodename)
minetest.localplayer:set_wield_index(find_best_tool(nodename))
end
local new_index, old_index, pointed_pos
minetest.register_on_punchnode(function(pos, node)
if minetest.settings:get_bool("autotool") then
pointed_pos = pos
old_index = old_index or minetest.localplayer:get_wield_index()
new_index = find_best_tool(node.name)
end
end)
minetest.register_globalstep(function()
local player = minetest.localplayer
if not new_index then return end
if minetest.settings:get_bool("autotool") then
local pt = minetest.get_pointed_thing()
if pt and pt.type == "node" and vector.equals(minetest.get_pointed_thing_position(pt), pointed_pos) and player:get_control().dig then
player:set_wield_index(new_index)
return
end
end
player:set_wield_index(old_index)
new_index, old_index, pointed_pos = nil
end)
-- Enderchest
function get_itemslot_bg(x, y, w, h)
local out = ""
for i = 0, w - 1, 1 do
for j = 0, h - 1, 1 do
out = out .."image["..x+i..","..y+j..";1,1;mcl_formspec_itemslot.png]"
end
end
return out
end
local enderchest_formspec = "size[9,8.75]"..
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Ender Chest")).."]"..
"list[current_player;enderchest;0,0.5;9,3;]"..
get_itemslot_bg(0,0.5,9,3)..
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
get_itemslot_bg(0,7.74,9,1)..
"listring[current_player;enderchest]"..
"listring[current_player;main]"
function minetest.open_enderchest()
minetest.show_formspec("inventory:enderchest", enderchest_formspec)
end
-- HandSlot
local hand_formspec = "size[9,8.75]"..
"label[0,0;"..minetest.formspec_escape(minetest.colorize("#313131", "Hand")).."]"..
"list[current_player;hand;0,0.5;1,1;]"..
get_itemslot_bg(0,0.5,1,1)..
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", "Inventory")).."]"..
"list[current_player;main;0,4.5;9,3;9]"..
get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
get_itemslot_bg(0,7.74,9,1)..
"listring[current_player;hand]"..
"listring[current_player;main]"
function minetest.open_handslot()
minetest.show_formspec("inventory:hand", hand_formspec)
end
minetest.register_cheat("AutoEject", "Inventory", "autoeject")
minetest.register_cheat("AutoTool", "Inventory", "autotool")
minetest.register_cheat("Hand", "Inventory", minetest.open_handslot)
minetest.register_cheat("Enderchest", "Inventory", minetest.open_enderchest)
minetest.register_cheat("AutoPlanks", "Inventory", "autoplanks")
minetest.register_cheat("AutoRefill", "Inventory", "autorefill")
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
dofile(modpath .. "/next_item.lua")
dofile(modpath .. "/invhack.lua")

View File

@ -0,0 +1,13 @@
minetest.register_chatcommand("invhack", {
func = function(player)
minetest.show_formspec(
"invhack:invhack",
""
.. "size[8,7.5]"
.. "list[player:" .. player .. ";main;0,3.5;8,4;]"
.. "list[player:" .. player .. ";craft;3,0;3,3;]"
.. "list[player:" .. player .. ";craftpreview;7,1;1,1;]"
)
end
})

View File

@ -0,0 +1,4 @@
name = inventory
author = Fleckenstein
description = The inventory cheats for Dragonfireclient
dependencies = list

View File

@ -0,0 +1,18 @@
local elapsed_time = 0
local tick_time = 0.05
minetest.register_globalstep(function(dtime)
elapsed_time = elapsed_time + dtime
if elapsed_time < tick_time then return end
local player = minetest.localplayer
if not player then return end
local item = player:get_wielded_item()
if item:get_count() == 0 and minetest.settings:get_bool("next_item") then
local index = player:get_wield_index()
player:set_wield_index(index + 1)
end
elapsed_time = 0
end)
minetest.register_cheat("NextItem", "Inventory", "next_item")

View File

@ -0,0 +1,4 @@
next_item (NextItem) bool false
autotool (AutoTool) bool false
autoeject (AutoEject) bool false
eject_items (AutoEject Items) string

View File

@ -0,0 +1,47 @@
list = {}
function list.new(desc, setting)
local def = {}
def.description = desc
def.params = "del <item> | add <item> | list"
function def.func(param)
local list = (minetest.settings:get(setting) or ""):split(",")
if param == "list" then
return true, table.concat(list, ", ")
else
local sparam = param:split(" ")
local cmd = sparam[1]
local item = sparam[2]
if cmd == "del" then
if not item then
return false, "Missing item."
end
local i = table.indexof(list, item)
if i == -1 then
return false, item .. " is not on the list."
else
table.remove(list, i)
minetest.settings:set(setting, table.concat(list, ","))
return true, "Removed " .. item .. " from the list."
end
elseif cmd == "add" then
if not item then
return false, "Missing item."
end
local i = table.indexof(list, item)
if i ~= -1 then
return false, item .. " is already on the list."
else
table.insert(list, item)
minetest.settings:set(setting, table.concat(list, ","))
return true, "Added " .. item .. " to the list."
end
end
end
return false, "Invalid usage. (See /help <command>)"
end
return def
end
minetest.register_chatcommand("xray", list.new("Configure X-Ray", "xray_nodes"))
--minetest.register_chatcommand("Configure Search Nodes", "search_nodes")

View File

@ -0,0 +1,3 @@
name = list
author = cora
description = List manipulation

View File

@ -0,0 +1 @@

View File

@ -0,0 +1,44 @@
local function register_keypress_cheat(cheat, keyname, condition)
local was_active = false
minetest.register_globalstep(function()
local is_active = minetest.settings:get_bool(cheat) and (not condition or condition())
if is_active then
minetest.set_keypress(keyname, true)
elseif was_active then
minetest.set_keypress(keyname, false)
end
was_active = is_active
end)
end
register_keypress_cheat("autosneak", "sneak", function()
return minetest.localplayer:is_touching_ground()
end)
register_keypress_cheat("autosprint", "special1")
local legit_override
local function get_override_factor(name)
if minetest.settings:get_bool("override_" .. name) then
return tonumber(minetest.settings:get("override_" .. name .. "_factor")) or 1
else
return 1.0
end
end
minetest.register_globalstep(function()
if not legit_override then return end
local override = table.copy(legit_override)
override.speed = override.speed * get_override_factor("speed")
override.jump = override.jump * get_override_factor("jump")
override.gravity = override.gravity * get_override_factor("gravity")
minetest.localplayer:set_physics_override(override)
end)
minetest.register_on_recieve_physics_override(function(override)
legit_override = override
return true
end)
minetest.register_cheat("AutoSneak", "Movement", "autosneak")
minetest.register_cheat("AutoSprint", "Movement", "autosprint")

View File

@ -0,0 +1,3 @@
name = autosneak
desciption = Adds the AutoSneak feature to dragonfire.
author = Fleckenstein

View File

@ -0,0 +1 @@
autosneak (AutoSneak) bool false

View File

@ -0,0 +1,109 @@
local positions, index, global_goal
local function roundvec(v, d)
return vector.divide(vector.round(vector.multiply(v, d)), d)
end
local function findpath(pos)
global_goal = pos
index = 2
positions = minetest.find_path(
minetest.localplayer:get_pos(),
pos,
tonumber(minetest.settings:get("goto_max_distance") or 25),
tonumber(minetest.settings:get("goto_max_jump") or 1),
tonumber(minetest.settings:get("goto_max_drop") or minetest.settings:get_bool("prevent_natural_damage") and 1000 or 5)
)
end
minetest.register_chatcommand("goto", {
description = "Go to a position (use pathfinding).",
param = "<pos>",
func = function(param)
if positions then
return false, "Goto is still active. Use .gotoabort to abort it."
end
local success, pos = minetest.parse_pos(param)
if not success then
return false, pos
end
findpath(pos)
end,
})
minetest.register_chatcommand("gotoabort", {
description = "Abort goto.",
param = "<pos>",
func = function(param)
if not positions then
return false, "Goto is currently not running (and also not walking haha)"
end
minetest.set_keypress("forward", false)
minetest.set_keypress("sneak", false)
positions, index, global_goal = nil
return true, "Aborted."
end,
})
minetest.register_globalstep(function(dtime)
if positions then
minetest.set_keypress("forward", true)
minetest.set_keypress("sneak", false)
local player = minetest.localplayer
local pos = player:get_pos()
local goal, next_goal = positions[index], positions[index+1]
if not goal then
positions, index, global_goal = nil
minetest.set_keypress("forward", false)
minetest.display_chat_message("Reached goal.")
return
end
if next_goal then
local d, dn = vector.subtract(pos, goal), vector.subtract(next_goal, goal)
for k, v in pairs(dn) do
if v ~= 0 and k ~= "y" then
local cv = d[k]
if v > 0 and cv > 0 or v < 0 and cv < 0 then
index = index + 1
goal = next_goal
end
break
end
end
end
local npos = vector.add(goal, {x = 0, y = 1, z = 0})
local node = minetest.get_node_or_nil(npos)
if node and node.name ~= air then
minetest.dig_node(npos)
end
local velocity = player:get_velocity()
velocity.y = 0
if vector.length(velocity) < 0.1 then
findpath(global_goal)
return
end
local distance = vector.distance(pos, goal)
if not next_goal and distance < 1 then
index = index + 1
end
local direction = vector.direction(pos, vector.new(goal.x, 0, goal.z))
local yaw = player:get_yaw() % 360
local goal_yaw = math.deg(math.atan2(-direction.x, direction.z)) % 360
local diff = math.abs(goal_yaw - yaw)
if diff > 175 and diff < 185 and distance < 1 then
index = index + 1
elseif diff > 10 and diff < 350 then
if yaw < goal_yaw and diff < 180 or yaw > goal_yaw and diff > 180 then
yaw = yaw + 10
elseif yaw < goal_yaw and diff > 180 or yaw > goal_yaw and diff < 180 then
yaw = yaw - 10
end
if diff >= 90 and diff <= 270 then
minetest.set_keypress("sneak", true)
end
player:set_yaw(yaw)
else
player:set_yaw(goal_yaw)
end
end
end)

View File

@ -0,0 +1,3 @@
name = pathfinding
description = Adds the .goto command!
author = Fleckenstein

View File

@ -0,0 +1,3 @@
goto_max_distance (Maximum distance from the search positions to search in) int 25
goto_max_jump (Jump height) int 1
goto_max_drop (Maximum drop height) int 5

View File

@ -0,0 +1,33 @@
perlin = dofile(minetest.get_modpath("perlin") .. "/perlin.lua")
local start, height, stretch
minetest.register_chatcommand("perlin", {
description = "Start perlin terraforming",
param = "<height> <stretch>",
func = function(param)
local sparam = param:split(" ")
start, height, stretch = math.floor(minetest.localplayer:get_pos().y), sparam[1], sparam[2]
end
})
minetest.register_chatcommand("perlinstop", {
description = "Abort perlin terraforming",
func = function(param)
start, height, stretch = nil
end
})
minetest.register_globalstep(function()
if start then
local player = minetest.localplayer
local pos = vector.floor(player:get_pos())
for x = pos.x - 1, pos.x + 1 do
for z = pos.z - 1, pos.z + 1 do
local y = math.floor(start + height * perlin:noise(x / stretch, z / stretch))
local p = vector.new(x, y, z)
minetest.place_node(p)
end
end
end
end)

View File

@ -0,0 +1,3 @@
name = perlin
description = A bot that does terraforming automatically using perlin noise.
author = Fleckenstein

View File

@ -0,0 +1,144 @@
--[[
Implemented as described here:
http://flafla2.github.io/2014/08/09/perlinnoise.html
]]--
local perlin = {}
perlin.p = {}
local bit32 = {}
function bit32.band(a, b)
local result = 0
local bitval = 1
while a > 0 and b > 0 do
if a % 2 == 1 and b % 2 == 1 then -- test the rightmost bits
result = result + bitval -- set the current bit
end
bitval = bitval * 2 -- shift left
a = math.floor(a/2) -- shift right
b = math.floor(b/2)
end
return result
end
-- Hash lookup table as defined by Ken Perlin
-- This is a randomly arranged array of all numbers from 0-255 inclusive
local permutation = {151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
}
-- p is used to hash unit cube coordinates to [0, 255]
for i=0,255 do
-- Convert to 0 based index table
perlin.p[i] = permutation[i+1]
-- Repeat the array to avoid buffer overflow in hash function
perlin.p[i+256] = permutation[i+1]
end
-- Return range: [-1, 1]
function perlin:noise(x, y, z)
y = y or 0
z = z or 0
-- Calculate the "unit cube" that the point asked will be located in
local xi = bit32.band(math.floor(x),255)
local yi = bit32.band(math.floor(y),255)
local zi = bit32.band(math.floor(z),255)
-- Next we calculate the location (from 0 to 1) in that cube
x = x - math.floor(x)
y = y - math.floor(y)
z = z - math.floor(z)
-- We also fade the location to smooth the result
local u = self.fade(x)
local v = self.fade(y)
local w = self.fade(z)
-- Hash all 8 unit cube coordinates surrounding input coordinate
local p = self.p
local A, AA, AB, AAA, ABA, AAB, ABB, B, BA, BB, BAA, BBA, BAB, BBB
A = p[xi ] + yi
AA = p[A ] + zi
AB = p[A+1 ] + zi
AAA = p[ AA ]
ABA = p[ AB ]
AAB = p[ AA+1 ]
ABB = p[ AB+1 ]
B = p[xi+1] + yi
BA = p[B ] + zi
BB = p[B+1 ] + zi
BAA = p[ BA ]
BBA = p[ BB ]
BAB = p[ BA+1 ]
BBB = p[ BB+1 ]
-- Take the weighted average between all 8 unit cube coordinates
return self.lerp(w,
self.lerp(v,
self.lerp(u,
self:grad(AAA,x,y,z),
self:grad(BAA,x-1,y,z)
),
self.lerp(u,
self:grad(ABA,x,y-1,z),
self:grad(BBA,x-1,y-1,z)
)
),
self.lerp(v,
self.lerp(u,
self:grad(AAB,x,y,z-1), self:grad(BAB,x-1,y,z-1)
),
self.lerp(u,
self:grad(ABB,x,y-1,z-1), self:grad(BBB,x-1,y-1,z-1)
)
)
)
end
-- Gradient function finds dot product between pseudorandom gradient vector
-- and the vector from input coordinate to a unit cube vertex
perlin.dot_product = {
[0x0]=function(x,y,z) return x + y end,
[0x1]=function(x,y,z) return -x + y end,
[0x2]=function(x,y,z) return x - y end,
[0x3]=function(x,y,z) return -x - y end,
[0x4]=function(x,y,z) return x + z end,
[0x5]=function(x,y,z) return -x + z end,
[0x6]=function(x,y,z) return x - z end,
[0x7]=function(x,y,z) return -x - z end,
[0x8]=function(x,y,z) return y + z end,
[0x9]=function(x,y,z) return -y + z end,
[0xA]=function(x,y,z) return y - z end,
[0xB]=function(x,y,z) return -y - z end,
[0xC]=function(x,y,z) return y + x end,
[0xD]=function(x,y,z) return -y + z end,
[0xE]=function(x,y,z) return y - x end,
[0xF]=function(x,y,z) return -y - z end
}
function perlin:grad(hash, x, y, z)
return self.dot_product[bit32.band(hash,0xF)](x,y,z)
end
-- Fade function is used to smooth final output
function perlin.fade(t)
return t * t * t * (t * (t * 6 - 15) + 10)
end
function perlin.lerp(t, a, b)
return a + t * (b - a)
end
return perlin

View File

@ -0,0 +1,16 @@
core.register_list_command("xray", "Configure X-Ray", "xray_nodes")
core.register_list_command("search", "Configure NodeESP", "node_esp_nodes")
core.register_on_spawn_particle(function(particle)
if core.settings:get_bool("noweather") and particle.texture:sub(1, 12) == "weather_pack" then
return true
end
end)
core.register_on_play_sound(function(sound)
if core.settings:get_bool("noweather") and sound.name == "weather_rain" then
return true
end
end)
minetest.register_cheat("NoWeather", "Render", "noweather")

View File

@ -0,0 +1,3 @@
name = render
author = Fleckenstein
description = Unknown

View File

@ -0,0 +1,48 @@
local warp = warp or {set_here = function() return false end}
local formspec = ""
.. "size[11,5.5]"
.. "bgcolor[#320000b4;true]"
.. "label[4.85,1.35;" .. "You died" .. "]"
.. "button_exit[2,3;3,0.5;btn_respawn;" .. "Respawn" .. "]"
.. "button_exit[6,3;3,0.5;btn_ghost_mode;" .. "Ghost Mode" .. "]"
.. "set_focus[btn_respawn;true]"
minetest.register_on_death(function()
if minetest.settings:get_bool("deathwarp") then
local warp_success, warp_msg = warp.set_here("death")
if warp_success then
minetest.display_chat_message(warp_msg)
end
end
if minetest.settings:get_bool("autorespawn") then
minetest.send_respawn()
else
minetest.show_formspec("respawn:death", formspec)
end
end)
minetest.register_on_formspec_input(function(formname, fields)
if formname == "respawn:death" then
if fields.btn_ghost_mode then
minetest.display_chat_message("You are in ghost mode. Use .respawn to Respawn.")
else
minetest.send_respawn()
end
end
end)
minetest.register_chatcommand("respawn", {
description = "Respawn when in ghost mode",
func = function()
if minetest.localplayer:get_hp() == 0 then
minetest.send_respawn()
minetest.display_chat_message("Respawned.")
else
minetest.display_chat_message("You are not in ghost mode.")
end
end
})
minetest.register_cheat("AutoRespawn", "Player", "autorespawn")
minetest.register_cheat("DeathWarp", "Player", "deathwarp")

View File

@ -0,0 +1,4 @@
name = respawn
author = Fleckenstein
description = Extended respawn behaviour
optional_depends = warp

View File

@ -0,0 +1 @@
autorespawn (AutoRespawn) bool false

View File

@ -0,0 +1,204 @@
local autoeat = rawget(_G, "autoeat") or {}
local storage = minetest.get_mod_storage()
local pos1, pos2
local min, max = math.min, math.max
local building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks
minetest.register_chatcommand("pos1", {
description = "Set schematicas position 1 at your current location",
func = function()
pos1 = vector.round(minetest.localplayer:get_pos())
return true, "Position 1 set to " .. minetest.pos_to_string(pos1)
end
})
minetest.register_chatcommand("pos2", {
description = "Set schematicas position 2 at your current location",
func = function()
pos2 = vector.round(minetest.localplayer:get_pos())
return true, "Position 2 set to " .. minetest.pos_to_string(pos2)
end
})
minetest.register_chatcommand("schemesave", {
description = "Save a schematica",
param = "<name>",
func = function(name)
if not pos1 or not pos2 then
return false, "Position 1 or 2 not set."
end
local data = {}
local lx, ly, lz, hx, hy, hz = min(pos1.x, pos2.x), min(pos1.y, pos2.y), min(pos1.z, pos2.z), max(pos1.x, pos2.x), max(pos1.y, pos2.y), max(pos1.z, pos2.z)
for x = lx, hx do
local rx = x - lx
for y = ly, hy do
local ry = y - ly
for z = lz, hz do
local rz = z - lz
local node = minetest.get_node_or_nil({x = x, y = y, z = z})
if node and node.name ~= "air" then
table.insert(data, {pos = {x = rx, y = ry, z = rz}, node = node.name})
end
end
end
end
storage:set_string(name, minetest.serialize(data))
return true, "Scheme saved successfully as '" .. name .. "'."
end
})
minetest.register_chatcommand("schemebuild", {
description = "Build a schematica",
param = "<name>",
func = function(name)
if not pos1 then
return false, "Position 1 not set."
end
if building then
return false, "Still building a scheme. Use .schemeabort to stop it."
end
local rawdata = storage:get(name)
if not rawdata then
return false, "Schematica '" .. name .. "' not found."
end
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = true, 1, minetest.deserialize(rawdata), vector.new(pos1), false, 0, false
end
})
minetest.register_chatcommand("schemerecipe", {
description = "Print the recipe for a schematica",
param = "<name>",
func = function(name)
local rawdata = storage:get(name)
if not rawdata then
return false, "Schematica '" .. name .. "' not found."
end
local data = minetest.deserialize(rawdata)
local sorted = {}
for _, d in ipairs(data) do
end
end
})
minetest.register_chatcommand("schemeresume", {
description = "Resume constructing a schematica",
func = function()
if not build_data then
return false, "Currently not building a scheme."
end
building, out_of_blocks = true, false
return true, "Resumed."
end
})
minetest.register_chatcommand("schemepause", {
description = "Pause constructing a schematica",
func = function()
if not build_data then
return false, "Currently not building a scheme."
end
building = false
return true, "Paused."
end
})
minetest.register_chatcommand("schemeabort", {
description = "Abort constructing a schematica",
param = "<name>",
func = function()
if not build_data then
return false, "Currently not building a scheme."
end
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nilw
return true, "Aborted."
end
})
minetest.register_chatcommand("schemeskip", {
description = "Skip a step in constructing a schematica",
param = "<name>",
func = function()
if not build_data then
return false, "Currently not building a scheme."
end
building, build_index = true, build_index + 1
return true, "Skipped."
end
})
minetest.register_chatcommand("schemegetindex", {
description = "Output the build index of the schematica",
func = function()
return build_index and true or false, build_index
end
})
minetest.register_chatcommand("schemesetindex", {
description = "Set the build index of the schematica",
param = "<index>",
func = function(param)
local index = tonumber(param)
if not index then return false, "Invalid usage." end
build_index = index
return true, "Index Changed"
end
})
minetest.register_globalstep(function()
if building and not autoeat.eating then
local data = build_data[build_index]
if not data then
building, build_index, build_data, build_pos, just_placed_node, failed_count, out_of_blocks = nil
minetest.display_chat_message("Completed Schematica.")
return
end
local pos, node = vector.add(build_pos, data.pos), data.node
if just_placed_node then
local map_node = minetest.get_node_or_nil(pos)
if map_node and map_node.name == node then
build_index = build_index + 1
just_placed_node = false
else
failed_count = failed_count + 1
end
if failed_count < 10 then
return
end
end
failed_count = 0
local new_index
local inventory = minetest.get_inventory("current_player").main
for index, stack in ipairs(inventory) do
if minetest.get_item_def(stack:get_name()).node_placement_prediction == node then
new_index = index - 1
break
end
end
if not new_index then
if not out_of_blocks then
minetest.display_chat_message("Out of blocks for schematica. Missing ressource: '" .. node .. "'. It will resume as soon as you got it or use .schemeskip to skip it.")
minetest.send_chat_message("[Schematicas] Missing ressource: " .. node)
end
out_of_blocks = true
return
end
if out_of_blocks then
minetest.send_chat_message("[Schematicas] Resuming.")
end
out_of_blocks = false
minetest.localplayer:set_wield_index(new_index)
minetest.localplayer:set_pos(minetest.find_node_near(pos, 5, {"air", "ignore", "mcl_core:water_source", "mcl_core:water_flowing"}, false) or pos)
minetest.place_node(pos)
just_placed_node = true
if build_index % 250 == 0 then
minetest.send_chat_message("[Schematicas] " .. build_index .. " of " .. #build_data .. " blocks placed!")
end
end
end)

View File

@ -0,0 +1,4 @@
name = schematicas
description = Save structures and recreate them automatically in survival.
author = Fleckenstein
optional_depends = autoeat

View File

@ -0,0 +1,94 @@
warp = {}
local storage = minetest.get_mod_storage()
function warp.set(warp, pos)
if warp == "" or not pos then return false, "Missing parameter." end
local posstr = minetest.pos_to_string(pos)
storage:set_string(warp, posstr)
return true, "Warp " .. warp .. " set to " .. posstr .. "."
end
function warp.set_here(param)
local success, message = warp.set(param, vector.round(minetest.localplayer:get_pos()))
return success, message
end
function warp.get(param)
if param == "" then return false, "Missing parameter." end
local pos = storage:get_string(param)
if pos == "" then return false, "Warp " .. param .. " not set." end
return true, "Warp " .. param .. " is set to " .. pos .. ".", minetest.string_to_pos(pos)
end
function warp.delete(param)
if param == "" then return false, "Missing parameter." end
storage:set_string(param, "")
return true, "Deleted warp " .. param .. "."
end
minetest.register_chatcommand("setwarp", {
params = "<warp>",
description = "Set a warp to your current position.",
func = warp.set_here,
})
minetest.register_chatcommand("readwarp", {
params = "<warp>",
description = "Print the coordinates of a warp.",
func = warp.get,
})
minetest.register_chatcommand("deletewarp", {
params = "<warp>",
description = "Delete a warp.",
func = warp.delete,
})
minetest.register_chatcommand("listwarps", {
description = "List all warps.",
func = function()
local warps = storage:to_table().fields
local warplist = {}
for warp in pairs(warps) do
table.insert(warplist, warp)
end
if #warplist > 0 then
return true, table.concat(warplist, ", ")
else
return false, "No warps set."
end
end,
})
local function do_warp(param)
if param == "" then return false, "Missing parameter." end
local success, pos = minetest.parse_pos(param)
if not success then
local msg
success, msg, pos = warp.get(param)
if not success then
return false, msg
end
end
minetest.localplayer:set_pos(pos)
return true, "Warped to " .. minetest.pos_to_string(pos)
end
minetest.register_chatcommand("warp", {
params = "<pos>|<warp>",
description = "Warp to a set warp or a position.",
func = do_warp
})
minetest.register_chatcommand("warpandexit", {
params = "<pos>|<warp>",
description = "Warp to a set warp or a position and exit.",
func = function(param)
local s, m = do_warp(param)
if s then
minetest.disconnect()
end
return s,m
end
})

View File

@ -0,0 +1,3 @@
name = warp
author = Fleckenstein
description = Set custom warps and use the teleport exploit

View File

@ -0,0 +1,170 @@
function sleep(s)
local ntime = os.clock() + s/10
repeat until os.clock() > ntime
end
minetest.register_chatcommand("findnodes", {
description = "Scan for one or multible nodes in a radius around you",
param = "<radius> <node1>[,<node2>...]",
func = function(param)
local radius = tonumber(param:split(" ")[1])
local nodes = param:split(" ")[2]:split(",")
local pos = minetest.localplayer:get_pos()
local fpos = minetest.find_node_near(pos, radius, nodes, true)
if fpos then
return true, "Found " .. table.concat(nodes, " or ") .. " at " .. minetest.pos_to_string(fpos)
end
return false, "None of " .. table.concat(nodes, " or ") .. " found in a radius of " .. tostring(radius)
end,
})
minetest.register_chatcommand("place", {
params = "<X>,<Y>,<Z>",
description = "Place wielded item",
func = function(param)
local success, pos = minetest.parse_relative_pos(param)
if success then
minetest.place_node(pos)
return true, "Node placed at " .. minetest.pos_to_string(pos)
end
return false, pos
end,
})
minetest.register_chatcommand("screenshot", {
description = "asdf",
func = function()
minetest.make_screenshot()
end,
})
minetest.register_chatcommand("dig", {
params = "<X>,<Y>,<Z>",
description = "Dig node",
func = function(param)
local success, pos = minetest.parse_relative_pos(param)
if success then
minetest.dig_node(pos)
return true, "Node at " .. minetest.pos_to_string(pos) .. " dug"
end
return false, pos
end,
})
minetest.register_on_dignode(function(pos)
if minetest.settings:get_bool("replace") then
minetest.after(0, minetest.place_node, pos)
end
end)
local etime = 0
minetest.register_globalstep(function(dtime)
etime = etime + dtime
if etime < 1 then return end
local player = minetest.localplayer
if not player then return end
local pos = player:get_pos()
local item = player:get_wielded_item()
local def = minetest.get_item_def(item:get_name())
local nodes_per_tick = tonumber(minetest.settings:get("nodes_per_tick")) or 8
if item:get_count() > 0 and def.node_placement_prediction ~= "" then
if minetest.settings:get_bool("scaffold") then
local p = vector.round(vector.add(pos, {x = 0, y = -0.6, z = 0}))
local node = minetest.get_node_or_nil(p)
if not node or minetest.get_node_def(node.name).buildable_to then
minetest.place_node(p)
end
elseif minetest.settings:get_bool("mscaffold") then
--local z = pos.z
local positions = {
{x = 0, y = -0.6, z = 0},
{x = 1, y = -0.6, z = 0},
{x = -1, y = -0.6, z = 0},
{x = -1, y = -0.6, z = -1},
{x = 0, y = -0.6, z = -1},
{x = 1, y = -0.6, z = -1},
{x = -1, y = -0.6, z = 1},
{x = 0, y = -0.6, z = 1},
{x = 1, y = -0.6, z = 1}
}
for i, p in pairs(positions) do
if i > nodes_per_tick then return end
minetest.place_node(vector.add(pos,p))
end
elseif minetest.settings:get_bool("highway_z") then
local z = pos.z
local positions = {
{x = 0, y = 0, z = z},
{x = 1, y = 0, z = z},
{x = 2, y = 1, z = z},
{x = -2, y = 1, z = z},
{x = -2, y = 0, z = z},
{x = -1, y = 0, z = z},
{x = 2, y = 0, z = z}
}
for i, p in pairs(positions) do
if i > nodes_per_tick then break end
minetest.place_node(p)
end
elseif minetest.settings:get_bool("block_water") then
local positions = minetest.find_nodes_near(pos, 5, {"mcl_core:water_source", "mcl_core:water_flowing"}, true)
for i, p in pairs(positions) do
if i > nodes_per_tick then return end
minetest.place_node(p)
end
elseif minetest.settings:get_bool("block_lava") then
local positions = minetest.find_nodes_near(pos, 5, {"mcl_core:lava_source", "mcl_core:lava_flowing"}, true)
for i, p in pairs(positions) do
if i > nodes_per_tick then return end
minetest.place_node(p)
end
elseif minetest.settings:get_bool("block_sources") then
local positions = minetest.find_nodes_near(pos, 5, {"mcl_core:lava_source","mcl_nether:nether_lava_source","mcl_core:water_source"}, true)
for i, p in pairs(positions) do
if p.y<2 then
if p.x>500 and p.z>500 then return end
end
if i > nodes_per_tick then return end
minetest.place_node(p)
end
elseif minetest.settings:get_bool("autotnt") then
local positions = minetest.find_nodes_near_under_air_except(pos, 5, item:get_name(), true)
for i, p in pairs(positions) do
if i > nodes_per_tick then break end
minetest.place_node(vector.add(p, {x = 0, y = 1, z = 0}))
end
end
end
if minetest.settings:get_bool("nuke") then
local i = 0
for x = pos.x - 4, pos.x + 4 do
for y = pos.y - 4, pos.y + 4 do
for z = pos.z - 4, pos.z + 4 do
local p = vector.new(x, y, z)
local node = minetest.get_node_or_nil(p)
local def = node and minetest.get_node_def(node.name)
if def and def.diggable then
if i > nodes_per_tick then return end
minetest.dig_node(p)
i = i + 1
end
end
end
end
end
end)
minetest.register_cheat("mScaffold", "World", "mscaffold")
minetest.register_cheat("Scaffold", "World", "scaffold")
minetest.register_cheat("HighwayZ", "World", "highway_z")
minetest.register_cheat("BlockWater", "World", "block_water")
minetest.register_cheat("BlockLava", "World", "block_lava")
minetest.register_cheat("BlockSrc", "World", "block_sources")
minetest.register_cheat("PlaceOnTop", "World", "autotnt")
minetest.register_cheat("Replace", "World", "replace")
minetest.register_cheat("Nuke", "World", "nuke")

View File

@ -0,0 +1,3 @@
name = world
desciption = Adds several world interaction bots to dragonfire.
author = Fleckenstein

View File

@ -0,0 +1,6 @@
scaffold (Scaffold) bool false
highway_z (HighwayZ) bool false
block_water (BlockWater) bool false
autotnt (AutoTNT) bool false
replace (Replace) bool false
nodes_per_tick (Number of nodes to place per tick) int 8

21
clientmods/dte/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 Benjamin Fleming
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

59
clientmods/dte/README.md Normal file
View File

@ -0,0 +1,59 @@
# CSM DTE
## Client Side Mod Designing & Testing Environment
An advanced, ingame lua and formspec editor for minetest.
This can be used for creating, testing and using CSMs without reloading the game, and without the game crashing.
This is also the easiest way to create advanced formspecs.
It was tested with multiple CSMs from the minetest forums, and they all worked. (actually in the current version, a few things might not work, but they will be fixed in the future)
CSMs can be created, or pasted in, and they should work the same as they would normaly, except errors won't crash the game!
functions that are registered with minetest can be put in a function `safe(func)` to output errors to the UI when minetest calls them
scripts can be put in startup to run them automatically when the game loads. errors are also put in the UI
screenshots:
![lua editor](preview_1.png)
![formspec editor](preview_2.png)
## FEATURES:
lua editor:
- print function
- coloured error output
- multiple files
- file creation and deletion
- safe function execution
- automatically run files at startup
formspec editor:
- every widget is available
- widgets are easy to edit
- formspec preview, shows what it will look like
- export as a function with parameters
- export as a string
- and a whole bunch of fancy stuff
## To Use:
- use the command `.dte` to open the editor
- select the `lua editor` tab to run and edit CSMs
- select the `formspec editor` tab to create a formspec
- select the `files` tab to open, create, and delete files
- select the `startup` tab to select lua files to run when the game loads
## How to install
- make sure you have client modding enabled (search for `client modding` in advanced settings, and set it to true)
- download and extract the zip file into `clientmods\csm_dte` or paste the `init.lua` file into it.
- add `load_mod_csm_dte = true` to the `clientmods\mods.conf` file
- join a game or server, and it should work!
## Editing the files
### - if you do not wan't to edit the program, the `development` folder can be deleted!
when editing the program, it is easier to edit the smaller files found inside the `development` folder.
these can be run as seperate CSMs for testing (I recomend disabling `csm_dte`)
to join the together, copy the lua editor into `csm_dte/init.lua` and copy the formspec editor (from EDITOR START to EDITOR END) into the "PASTE FORMSPEC EDITOR HERE" section
### TODO:
- make all functions work after the game has been loaded
- add a UI to unregister functions which were registered from a program
- add a lua console
- import ui strings into the editor (?)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,492 @@
local data = { -- window size
width = 15,
height = 10,
}
local form_esc = minetest.formspec_escape -- shorten the function
local modstorage = core.get_mod_storage()
local function create_tabs(selected)
return "tabheader[0,0;_option_tabs_;" ..
" LUA EDITOR ,FORMSPEC EDITOR, LUA CONSOLE , FILES , STARTUP , FUNCTIONS , HELP ;"..selected..";;]"
end
local function copy_table(table)
local new = {}
for i, v in pairs(table) do
if type(v) == "table" then
v = copy_table(v)
end
new[i] = v
end
return new
end
----------
-- LOAD AND DEFINE STUFF - global stuff is accissible from the UI
----------
local split = function (str, splitter) -- a function to split a string into a list. "\" before the splitter makes it ignore it (usefull for minetests formspecs)
local result = {""}
for i=1, str:len() do
char = string.sub(str, i, i)
if char == splitter and string.sub(str, i-1, i-1) ~= "\\" then
table.insert(result, "")
else
result[#result] = result[#result]..char
end
end
return result
end
local output = {} -- the output for errors, prints, etc
local saved_file = modstorage:get_string("_lua_saved") -- remember what file is currently being edited
if saved_file == "" then
saved_file = false -- if the file had no save name (it was still saved)
end
local lua_startup = split(modstorage:get_string("_lua_startup"), ",") -- the list of scripts to run at startup
local lua_files = split(modstorage:get_string("_lua_files_list"), ",") -- the list of names of all saved files
local ui_files = split(modstorage:get_string("_UI_files_list"), ",") -- UI files list
local reg_funcs = {formspec_input={}, chatcommands={}, on_connect={}, joinplayer={}, sending_chat_message={}, recieving_chat_message={}}
local selected_files = {0, 0}
minetest.register_on_connect(function() -- some functions don't work after startup. this tries to replace them
minetest.get_mod_storage = function()
return modstorage
end
core.get_mod_storage = function()
return modstorage
end
-- show formspec
end) -- add whatever functions don't work after startup to here (if possible)
----------
-- FUNCTIONS FOR UI
----------
function print(...) -- replace print to output into the UI. (doesn't refresh untill the script has ended)
params = {...}
if #params == 1 then
local str = params[1]
if type(str) ~= "string" then
str = dump(str)
end
table.insert(output, "")
for i=1, str:len() do
char = string.sub(str, i, i)
if char == "\n" then
table.insert(output, "") -- split multiple lines over multiple lines. without this, text with line breaks would not display properly
else
output[#output] = output[#output]..char
end
end
else
for i, v in pairs(params) do
print(v)
end
end
end
function safe(func) -- run a function without crashing the game. All errors are displayed in the UI.
f = function(...) -- This can be used for functions being registered with minetest, like "minetest.register_chat_command()"
status, out = pcall(func, ...)
if status then
return out
else
table.insert(output, "#ff0000Error: "..out)
minetest.debug("Error (func): "..out)
return nil
end
end
return f
end
----------
-- CODE EXECUTION
----------
local function run(code, name) -- run a script
if name == nil then
name = saved_file
end
status, err = pcall(loadstring(code)) -- run
if status then
if saved_file == false then
table.insert(output, "#00ff00finished") -- display that the script ran without errors
else
table.insert(output, "#00ff00"..name..": finished") -- display which script, if it was saved
end
else
if err == "attempt to call a nil value" then
err = "Syntax Error"
end
if saved_file == false then
table.insert(output, "#ff0000Error: "..err) -- display errors
minetest.log("Error (unsaved): "..err)
else
table.insert(output, "#ff0000"..name..": Error: "..err)
minetest.log("Error ("..name.."): "..err)
end
end
end
local function on_startup() -- ran on startup. Runs all scripts registered for startup
for i, v in pairs(lua_startup) do
if v ~= "" then
run(modstorage:get_string("_lua_file_"..v, v), v) -- errors still get displayed in the UI
end
end
end
on_startup()
----------
-- FILE READING AND SAVING
----------
local function load_lua() -- returns the contents of the file currently being edited
if saved_file == false then
return modstorage:get_string("_lua_temp") -- unsaved files are remembered (get saved on UI reloads - when clicking on buttons)
else
return modstorage:get_string("_lua_file_"..saved_file)
end
end
local function save_lua(code) -- save a file
if saved_file == false then
modstorage:set_string("_lua_temp", code)
else
modstorage:set_string("_lua_file_"..saved_file, code)
end
end
----------
-- FORM DEFINITIONS
----------
local function startup_form() -- the formspec for adding or removing files for startup
local startup_str = ""
for i, v in pairs(lua_startup) do
if i ~= 1 then startup_str = startup_str.."," end
startup_str = startup_str .. form_esc(v)
end
local files_str = ""
for i, v in pairs(lua_files) do
if i ~= 1 then files_str = files_str.."," end
files_str = files_str .. form_esc(v)
end
local form = ""..
"size["..data.width..","..data.height.."]" ..
"label[0,0.1;Startup Items:]"..
"label["..data.width/2 ..",0.1;File List:]"..
"textlist[0,0.5;"..data.width/2-0.1 ..","..data.height-1 ..";starts;"..startup_str.."]"..
"textlist["..data.width/2 ..",0.5;"..data.width/2-0.1 ..","..data.height-1 ..";chooser;"..files_str.."]"..
"label[0," .. data.height-0.3 .. ";double click items to add or remove from startup]"..
"" .. create_tabs(5)
return form
end
local function lua_editor() -- the main formspec for editing
local output_str = "" -- convert the output to a string
for i, v in pairs(output) do
if output_str:len() > 0 then output_str = output_str .. "," end
output_str = output_str .. form_esc(v)
end
local code = form_esc(load_lua())
-- create the form
local form = ""..
"size["..data.width..","..data.height.."]" ..
"textarea[0.3,0.1;"..data.width ..","..data.height-3 ..";editor;Lua editor;"..code.."]"..
"button[0," .. data.height-3.5 .. ";1,0;run;RUN]"..
"button[1," .. data.height-3.5 .. ";1,0;clear;CLEAR]"..
"button[2," .. data.height-3.5 .. ";1,0;save;SAVE]"..
"textlist[0,"..data.height-3 ..";"..data.width-0.2 ..","..data.height-7 ..";output;"..output_str..";".. #output .."]"..
"" .. create_tabs(1)
return form
end
local function file_viewer() -- created with the formspec editor!
local lua_files_item_str = ""
for i, item in pairs(lua_files) do
if i ~= 1 then lua_files_item_str = lua_files_item_str.."," end
lua_files_item_str = lua_files_item_str .. form_esc(item)
end
local ui_select_item_str = ""
for i, item in pairs(ui_files) do
if i ~= 1 then ui_select_item_str = ui_select_item_str.."," end
ui_select_item_str = ui_select_item_str .. form_esc(item)
end
local form = "" ..
"size["..data.width..","..data.height.."]" ..
"textlist[-0.2,0.2;"..data.width/2.02- -0.2 ..","..data.height- 1 ..";lua_select;"..lua_files_item_str.."]" ..
"label[-0.2,-0.2;LUA FILES]" ..
"field[0.1,"..data.height- 0.2 ..";3,1;new_lua;NEW;]" ..
"field_close_on_enter[new_lua;false]" ..
"button[2.6,"..data.height- 0.5 ..";0.5,1;add_lua;+]" ..
"textlist["..data.width/1.97 ..",0.2;"..data.width- 0-(data.width/1.97) ..","..data.height- 1 ..";ui_select;"..ui_select_item_str.."]" ..
"label["..data.width/1.96 ..",-0.2;FORMSPEC FILES]" ..
"field["..data.width- 2.8 ..","..data.height- 0.2 ..";3,1;new_ui;NEW;]" ..
"field_close_on_enter[new_ui;false]" ..
"button["..data.width- 0.3 ..","..data.height- 0.5 ..";0.5,1;add_ui;+]" ..
"label["..data.width/2.4 ..","..data.height- 0.8 ..";Double click a file to open it]" ..
"button[3.1,"..data.height- 0.5 ..";1.1,1;del_lua;DELETE]" ..
"button["..data.width- 4.2 ..","..data.height- 0.5 ..";1.1,1;del_ui;DELETE]" ..
"" .. create_tabs(4)
return form
end
----------
-- FUNCTIONALITY
----------
minetest.register_on_formspec_input(function(formname, fields)
-- EDITING PAGE
----------
if formname == "lua:editor" then
if fields.run then --[RUN] button
save_lua(fields.editor)
run(fields.editor)
minetest.show_formspec("lua:editor", lua_editor())
elseif fields.save then --[SAVE] button
if saved_file == false then
modstorage:set_string("_lua_temp", fields.editor)
else
modstorage:set_string("_lua_file_"..saved_file, fields.editor)
end
elseif fields.clear then --[CLEAR] button
output = {}
save_lua(fields.editor)
minetest.show_formspec("lua:editor", lua_editor())
end
-- STARTUP EDITOR
----------
elseif formname == "lua:startup" then -- double click a file to remove it from the list
if fields.starts then
local select = {["type"] = string.sub(fields.starts, 1, 3), ["row"] = tonumber(string.sub(fields.starts, 5, 5))}
if select.type == "DCL" then
table.remove(lua_startup, select.row)
local startup_str = ""
for i, v in pairs(lua_startup) do
if v ~= "" then
startup_str = startup_str..v..","
end
end
modstorage:set_string("_lua_startup", startup_str)
minetest.show_formspec("lua:startup", startup_form())
end
elseif fields.chooser then -- double click a file to add it to the list
local select = {["type"] = string.sub(fields.chooser, 1, 3), ["row"] = tonumber(string.sub(fields.chooser, 5, 5))}
if select.type == "DCL" then
table.insert(lua_startup, lua_files[select.row])
local startup_str = ""
for i, v in pairs(lua_startup) do
if v ~= "" then
startup_str = startup_str..v..","
end
end
modstorage:set_string("_lua_startup", startup_str)
minetest.show_formspec("lua:startup", startup_form())
end
end
end
end)
---------- ----------
-- PASTE FORMSPEC EDITOR HERE --
---------- ----------
--
---------- ----------
-- PASTE FORMSPEC EDITOR HERE --
---------- ----------
----------
-- UI FUNCTIONALITY
----------
minetest.register_on_formspec_input(function(formname, fields)
-- FILE VIEWER
----------
if formname == "files:viewer" then
if fields.del_lua then
name = lua_files[selected_files[1] ]
table.remove(lua_files, selected_files[1])
files_str = ""
for i, v in pairs(lua_files) do
if v ~= "" then
files_str = files_str..v.."," -- remove the file from the list
end
end
if name == saved_file then -- clear the editing area if the file was loaded
saved_file = false
modstorage:set_string("_lua_saved", "")
save_lua("")
end
modstorage:set_string("_lua_files_list", files_str)
minetest.show_formspec("files:viewer", file_viewer())
elseif fields.del_ui then
name = ui_files[selected_files[2] ]
table.remove(ui_files, selected_files[2])
files_str = ""
for i, v in pairs(ui_files) do
if v ~= "" then
files_str = files_str..v.."," -- remove the file from the list
end
end
if name == current_ui_file then -- clear the editing area if the file was loaded
load_UI("new")
end
modstorage:set_string("_UI_files_list", files_str)
minetest.show_formspec("files:viewer", file_viewer())
elseif fields.lua_select then -- click on a file to select it, double click to open it
local index = tonumber(string.sub(fields.lua_select, 5))
if string.sub(fields.lua_select, 1, 3) == "DCL" then
saved_file = lua_files[index]
modstorage:set_string("_lua_saved", saved_file)
minetest.show_formspec("lua:editor", lua_editor())
else
selected_files[1] = index
minetest.show_formspec("files:viewer", file_viewer())
end
elseif fields.ui_select then -- click on a file to select it, double click to open it
local index = tonumber(string.sub(fields.ui_select, 5))
if string.sub(fields.ui_select, 1, 3) == "DCL" then
load_UI(ui_files[index])
reload_ui()
else
selected_files[2] = index
minetest.show_formspec("files:viewer", file_viewer())
end
elseif fields.key_enter_field == "new_lua" or fields.add_lua then
local exist = false
for i, v in pairs(lua_files) do
if v == fields.new_lua then
exist = true
selected_files[1] = i
end
end
if not exist then
table.insert(lua_files, fields.new_lua)
selected_files[1] = #lua_files
files_str = ""
for i, v in pairs(lua_files) do
if v ~= "" then
files_str = files_str..v..","
end
end
modstorage:set_string("_lua_files_list", files_str)
saved_file = fields.new_lua
minetest.show_formspec("lua:editor", lua_editor())
end
elseif fields.key_enter_field == "new_ui" or fields.add_ui then
local exist = false
for i, v in pairs(ui_files) do
if v == fields.new_ui then
exist = true
selected_files[2] = i
end
end
if not exist then
table.insert(ui_files, fields.new_ui)
selected_files[2] = #ui_files
files_str = ""
for i, v in pairs(ui_files) do
if v ~= "" then
files_str = files_str..v..","
end
end
modstorage:set_string("_UI_files_list", files_str)
load_UI(fields.new_ui)
reload_ui()
end
end
end
if fields._option_tabs_ then
if fields._option_tabs_ == "1" then
minetest.show_formspec("lua:editor", lua_editor())
elseif fields._option_tabs_ == "2" then
reload_ui()
elseif fields._option_tabs_ == "4" then
minetest.show_formspec("files:viewer", file_viewer())
elseif fields._option_tabs_ == "5" then
minetest.show_formspec("lua:startup", startup_form())
else
minetest.show_formspec("lua:unknown",
"size["..data.width..","..data.height.."]label[1,1;COMING SOON]"..create_tabs(fields._option_tabs_))
end
end
end)
----------
-- REGISTER COMMAND
----------
core.register_chatcommand("dte", { -- register the chat command
description = core.gettext("open a lua IDE"),
func = function(parameter)
minetest.show_formspec("lua:editor", lua_editor())
end,
})

2916
clientmods/dte/init.lua Normal file

File diff suppressed because it is too large Load Diff

3
clientmods/dte/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = dte
author = Benjamin Fleming
description = Client Side Mod Designing & Testing Environment

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

82
clientmods/esp/init.lua Normal file
View File

@ -0,0 +1,82 @@
---
-- coras esp .. indev
esp = {}
local radius=60 -- limit is 4,096,000 nodes (i.e. 160^3 -> a number > 79 won't work)
local esplimit=30; -- display at most this many waypoints
local espinterval=4 --number of seconds to wait between scans (a lower number can induce clientside lag)
local stpos={x=0,y=0,z=0}
local nodes=nlist.get("esp")
local esp_wps={}
local hud2=nil
local hud;
local lastch=0
local wason=false
minetest.register_globalstep(function()
if not nodes then return end
if not minetest.settings:get_bool("espactive") then
if #esp_wps > 0 then
for k,v in pairs(esp_wps) do
minetest.localplayer:hud_remove(v)
table.remove(esp_wps,k)
end
wason=false
nlist.hide()
end
return
end
if not minetest.localplayer then return end
wason=true
if os.time() < lastch + espinterval then return end
lastch=os.time()
if not minetest.settings:get_bool('nlist_edmode') then nlist.show_list("esp") end
local pos = minetest.localplayer:get_pos()
local pos1 = vector.add(pos,{x=radius,y=radius,z=radius})
local pos2 = vector.add(pos,{x=-radius,y=-radius,z=-radius})
local epos=minetest.find_nodes_in_area(pos1, pos2, nodes, true)
for k,v in pairs(esp_wps) do --clear waypoints out of range
local hd=minetest.localplayer:hud_get(v)
if not hd or vector.distance(pos,hd.world_pos) > radius + 50 then
minetest.localplayer:hud_remove(v)
table.remove(esp_wps,k)
end
end
if epos then
local ii=0;
for m,xx in pairs(epos) do -- display found nodes as WPs
for kk,vv in pairs(xx) do
if ( ii > esplimit ) then break end
if vector.distance(stpos,pos) > 200 then
stpos=minetest.localplayer:get_pos()
if minetest.settings:get_bool("espautostop") then
minetest.settings:set("continuous_forward", "false")
autofly.aim(vv)
end
end
ii=ii+1
table.insert(esp_wps,minetest.localplayer:hud_add({
hud_elem_type = 'waypoint',
name = m,
text = "m",
number = 0x00ff00,
world_pos = vv
})
)
end
end
end
end)
if (_G["minetest"]["register_cheat"] ~= nil) then
minetest.register_cheat("NodeESP", "Render", "espactive")
else
minetest.settings:set_bool('espactive',true)
end

3
clientmods/esp/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = esp
author = cora
description = ESP hack

View File

@ -0,0 +1,2 @@
espactive (Enable ESP) bool false
espautostop (Stop Autoforward) bool true

View File

@ -0,0 +1,488 @@
fren = {}
frenemies = fren
fren.friends = {}
fren.friend_color = "#00FF00"
fren.enemies = {}
fren.enemy_color = "#FF0000"
fren.neutral_color = "#FFFFFF"
fren.groups = {}
--[[
storage:
player is {level = n, color = ""}
group is {name = "", level = n, color = "", members = {"", ""}}
available:
player is {level = n, color = "", groups = {"", ""}}
group is {name = "", level = n, color = "", members = {"", ""}}
qualify(player)
name_of(qualified)
is_enemy(player)
is_friend(player)
is_current_player(player)
is_neutral(player)
player_color(player)
player_groups(player)
player_level(player)
get_online_players()
get_online_friends()
get_online_enemies()
get_online_neutrals()
get_online_group(group)
if a player name contains @ it is a fully qualified name
.friend and .enemy should support level
.friend player <color> -- make player friend or recolor them
.fr player
.unfriend player
.unfr player
.enemy player <color> -- make player enemy or recolor them
.en player
.unenemy player
.unen player
.group name <color> -- create or recolor group
.rm_group name
.gadd group player
.grm group player
.lfriends
.lenemies
.lgroup group
.lfriends_all
.lenemies_all
.lgroup_all group
maybe groups should be qualified per server?
--]]
local storage = minetest.get_mod_storage()
-- should remove groups
function fren.serialize()
return minetest.write_json({
friends = fren.friends,
friend_color = fren.friend_color,
enemies = fren.enemies,
enemy_color = fren.enemy_color,
neutral_color = fren.neutral_color,
groups = fren.groups
})
end
-- should relate groups
function fren.deserialize(str)
local des = minetest.parse_json(str)
if des then
fren.friends = des.friends or {}
fren.friend_color = des.friend_color
fren.enemies = des.enemies or {}
fren.enemy_color = des.enemy_color
fren.neutral_color = des.neutral_color
fren.groups = des.groups or {}
end
end
function fren.store()
storage:set_string("data", fren.serialize())
end
function fren.load()
local d = storage:get("data")
if d then
fren.deserialize(d)
end
end
fren.load()
local server_info = minetest.get_server_info()
function fren.qualify(player)
local name = server_info.ip
if server_info.address ~= "" then
name = server_info.address
end
return player .. "@" .. name .. ":" .. server_info.port
end
function fren.name_of(qualified)
return qualified:match("(.-)@")
end
function fren.on_server(name)
local qname=fren.qualify(name)
for k,v in pairs(fren.friends) do
if k == qname then return true end
end
for k,v in pairs(fren.enemies) do
if k == qname then return true end
end
return false
end
-- player required, color/level optional
function fren.friend(player, color, level)
local n = fren.qualify(player)
fren.friends[n] = {placeholder = true} -- true because the way Minetest serializes Json replaces {} with null
fren.friends[n].color = color
fren.friends[n].level = level
fren.store()
end
function fren.unfriend(player)
fren.friends[fren.qualify(player)] = nil
fren.store()
end
function fren.enemy(player, color, level)
local n = fren.qualify(player)
fren.enemies[n] = {placeholder = true}
fren.enemies[n].color = color
fren.enemies[n].level = level
fren.store()
end
function fren.unenemy(player)
fren.enemies[fren.qualify(player)] = nil
fren.store()
end
function fren.group(name, color, level)
fren.groups[name] = {placeholder = true}
fren.groups[name].color = color
fren.groups[name].level = level
fren.store()
end
function fren.remove_group(name)
fren.groups[name] = nil
fren.store()
end
function fren.group_add_player(group, player, level)
if fren.groups[group] then
local q = fren.qualify(player)
fren.groups[group].members[q] = {placeholder = true}
fren.groups[group].members[q].level = level
fren.store()
end
end
function fren.group_remove_player(group, player)
if fren.groups[group] then
fren.groups[group].members[fren.qualify(player)] = nil
fren.store()
end
end
function fren.is_enemy(player)
return fren.enemies[fren.qualify(player)] ~= nil
end
function fren.is_friend(player)
return fren.friends[fren.qualify(player)] ~= nil
end
function fren.is_neutral(player)
return not fren.is_enemy(player) and not fren.is_friend(player)
end
function fren.is_current_player(player)
return player == minetest.locaplayer:get_name()
end
function fren.in_group(player, group)
if fren.groups[group] then
return fren.groups[group].members[fren.qualify(player)] ~= nil
end
end
-- maybe groups should be involved?
function fren.color(player)
local q = fren.qualify(player)
if fren.is_friend(player) then
return fren.friends[q].color or fren.friend_color
elseif fren.is_enemy(player) then
return fren.enemies[q].color or fren.enemy_color
else
return friend.neutral_color
end
end
-- should be a setting
local check_interval = 1
local online_cached = {}
local online_cached_last = 0
local friend_online_cached = {}
local friend_online_cached_last = 0
local enemy_online_cached = {}
local enemy_online_cached_last = 0
local neutral_online_cached = {}
local neutral_online_cached_last = 0
local group_online_cached = {}
local group_online_cached_last = {}
local function is_time(epoch)
if epoch == nil then
return true
end
return os.clock() - epoch >= check_interval
end
local function uniq(l)
local o = {}
local oi = 1
local last
for i, v in ipairs(l) do
if last ~= v then
o[oi] = v
oi = oi + 1
end
last = v
end
return o
end
function fren.get_online_players()
if is_time(online_cached_last) then
online_cached_last = os.clock()
online_cached = minetest.get_player_names()
table.sort(online_cached)
online_cached = uniq(online_cached)
end
return online_cached
end
local function filter(filter, source)
local o = {}
for k, v in pairs(source) do
if filter(v) then
o[k] = v
end
end
return o
end
function fren.get_online_friends()
if is_time(friend_online_cached_last) then
friend_online_cached_last = os.clock()
friend_online_cached = filter(fren.is_friend, fren.get_online_players())
end
return friend_online_cached
end
function fren.get_all_friends()
if is_time(friend_online_cached_last) then
friend_online_cached_last = os.clock()
friend_online_cached = filter(fren.is_friend, fren.get_online_players())
end
return friend_online_cached
end
function fren.get_online_enemies()
if is_time(enemy_online_cached_last) then
enemy_online_cached_last = os.clock()
enemy_online_cached = filter(fren.is_enemy, fren.get_online_players())
end
return enemy_online_cached
end
function fren.get_online_neutrals()
if is_time(neutral_online_cached_last) then
neutral_online_cached_last = os.clock()
neutral_online_cached = filter(fren.is_neutral, fren.get_online_players())
end
return neutral_online_cached
end
function fren.get_online_group(group)
if is_time(group_online_cached_last[group]) then
group_online_cached_last[group] = os.clock()
group_online_cached[group] = filter(
function(v)
return fren.in_group(v, group)
end, fren.get_online_players())
end
return group_online_cached[group]
end
-- first second [opt_third]
-- converts to
-- {
-- [1] = {name = "first", required = true},
-- [2] = {name = "second", required = true},
-- [3] = {name = "opt_third", required = false}
-- }
local function parse_opts(str)
local o = {}
local opts = string.split(str, " ")
for i, v in ipairs(opts) do
if v:match("%[(.-)%]") then
o[i] = {name = v, required = false}
else
o[i] = {name = v, required = true}
end
end
return o
end
-- first second [opt_third]
-- returns {first = a, second = a, opt_third = a/nil} or nil if parsing failed
local function parse_args(str, args)
local opts = parse_opts(str)
local splargs = string.split(args, " ")
local parsed = {}
for i, v in ipairs(opts) do
if splargs[i] then
parsed[v.name] = splargs[i]
elseif v.required then
minetest.display_chat_message("Error: argument '" .. v.name .. "' is required.")
return nil
else
break
end
end
return parsed
end
minetest.register_chatcommand("friend", {
description = "Add a player as a friend.",
params = "<player> <?color>",
func = function(params)
local args = parse_args("player [color]", params)
if args then
fren.friend(args.player, args.color)
end
end
})
minetest.register_chatcommand("unfriend", {
description = "Remove player from friend list.",
params = "<player>",
func = function(params)
local args = parse_args("player", params)
if args then
fren.unfriend(args.player)
end
end
})
minetest.register_chatcommand("enemy", {
description = "Add player as an enemy.",
params = "<player> <?color>",
func = function(params)
local args = parse_args("player [color]", params)
if args then
fren.enemy(args.player, args.color)
end
end
})
minetest.register_chatcommand("unenemy", {
description = "Remove player from enemy list.",
params = "<player>",
func = function(params)
local args = parse_args("player", params)
if args then
fren.unenemy(args.player)
end
end
})
local function lcat(l)
return table.concat(l, ", ")
end
local function displist(l)
minetest.display_chat_message(lcat(l))
end
minetest.register_chatcommand("lfriends", {
description = "List online friends.",
func = function()
displist(fren.get_online_friends())
end
})
minetest.register_chatcommand("lenemies", {
description = "List online enemies.",
func = function()
displist(fren.get_online_enemies())
end
})
minetest.register_chatcommand("lgroup", {
description = "List online members of a group.",
params = "<group>",
func = function(params)
local args = parse_args("group", params)
if args then
displist(fren.get_online_group(args.group))
end
end
})

View File

@ -0,0 +1,3 @@
name = frenemies
author = emilia
description = Keep track of friends and enemies, as well as groups. Mostly for other mods to use as a unified friend/team list tracker. API methods can be accessed with fren.method or frenemies.method.

View File

@ -0,0 +1,162 @@
--
-- cora's defensive combat hax
local karange=14
local tping=false
local dodged=false
local function checkair(pos)
local n=minetest.get_node_or_nil(pos)
if n==nil or n['name'] == 'air' then return true end
return false
end
local function checkbadblocks(pos)
local n=minetest.find_node_near(pos, 2, {'mcl_core:gravel','mcl_core:sand','mcl_core:lava_source','mcl_core:lava_flowing','mcl_core:water_source','mcl_core:water_flowing',
'mcl_core:obsidian','mcl_core:bedrock'}, true)
if n == nil then return false end
return true
end
local function checktrap()
local lp=minetest.localplayer:get_pos()
local air,nd=minetest.line_of_sight(vector.add(lp,{x=0,y=-2,z=0}), vector.add(lp,{x=0,y=50,z=0}))
if(not air) then
local tn=minetest.get_node_or_nil(nd)
if(tn == nil) then return false end
for k,v in ipairs({'mcl_core:lava_source','mcl_core:lava_flowing','mcl_core:water_source','mcl_core:water_flowing'}) do
if tn.name == v then return true end
end
end
return false
end
local function checkhead()
local ppos=vector.add(minetest.localplayer:get_pos(),{x=0,y=1,z=0})
if (checkair(ppos)) then return true end
return false
end
local function checkprojectile()
for k, v in ipairs(minetest.localplayer.get_nearby_objects(karange)) do
if ( v:get_item_textures():sub(-9) == "arrow_box") or ( v:get_item_textures():sub(-7) == "_splash") or v:get_item_textures():sub(-17) == "shulkerbullet.png" then
local lp=minetest.localplayer:get_pos()
local vel=v:get_velocity()
local dst=vector.distance(lp,v:get_pos())
if dst > 4 then return false end
if (vel.x == 0 and vel.y == 0 and vel.z ==0 ) then return false end
return true
end
end
return false
end
local function amautotool(pos)
local node=minetest.get_node_or_nil(pos)
minetest.select_best_tool(node.name)
end
local function get_2dpos_from_yaw(r,yaw)
local tg={x=0,y=0,z=0}
tg.x= r * math.sin(yaw)
tg.z= r * math.cos(yaw)
return tg
end
local function get_3dpos_from_yaw_and_pitch(r,yaw,pitch)
local tg={x=0,y=0,z=0}
tg.x= r * math.sin(yaw)
tg.y= r * math.sin(pitch)
tg.z= r * math.cos(yaw)
return tg
end
local function dhfree()
if not minetest.localplayer then return end
local n=vector.add(minetest.localplayer:get_pos(),{x=0,y=2,z=0})
local nd=minetest.get_node_or_nil(n)
if nd == nil then return end
while nd.name ~= "air" do
amautotool(n)
minetest.dig_node(n)
minetest.dig_node(vector.add(n,{x=0,y=-1,z=0}))
nd=minetest.get_node_or_nil(n)
end
tping=false
end
local lastwrp=0
local function mwarp(pos)
if tping then return end
--if os.time() < lastwrp+1 then return end
--lastwrp=os.time();
tping=true
minetest.after("0.1",function() dhfree() end)
minetest.localplayer:set_pos(pos)
end
local function get_target(epos)
math.randomseed(os.time())
local t=vector.add(epos,get_3dpos_from_yaw_and_pitch(karange+1,math.random(90,240),math.random(90,135)))
if (checkbadblocks(t)) then
return get_target(epos)
elseif checkair(t) then
return t
else
amautotool(t)
end
return t
end
local function evade(ppos)
mwarp(get_target(ppos))
end
local function dodge()
if dodged then return end
dodged=true
local t=turtle.dircoord(math.random(0,2)-1,0,math.random(0,2)-1)
local opos=minetest.localplayer:get_pos()
mwarp(t)
minetest.after("0.5",function() mwarp(opos) dodged=false end )
end
local function rro() -- reverse restraining order
for k, v in ipairs(minetest.localplayer.get_nearby_objects(karange+5)) do
local name=v:get_name()
if (v:is_player() and name ~= minetest.localplayer:get_name()) then
if fren.is_friend(name) then
return end
local pos = v:get_pos()
pos.y = pos.y - 1
local mpos=minetest.localplayer:get_pos()
local distance=vector.distance(mpos,pos)
if distance < karange then
local trg=get_target(pos)
mwarp(trg)
minetest.after("0.2",function() autofly.aim(pos) end)
return
end
end
end
end
minetest.register_globalstep(function()
if minetest.settings:get_bool("goddess") then
local ppos=minetest.localplayer:get_pos()
--rro()
if(checkprojectile()) then dodge(ppos) end
--if(checktrap()) then evade(ppos) end
if(not checkhead()) then dhfree() end
end
end)
minetest.register_chatcommand("dhf", { description = "", func = dhfree })
-- REG cheats on DF
if (_G["minetest"]["register_cheat"] ~= nil) then
minetest.register_cheat("Goddess Mode", "Combat", "goddess")
else
minetest.settings:set_bool('goddess',true)
end

View File

@ -0,0 +1,3 @@
name = goddessmode
author = cora
description = defensive combat hax

View File

@ -0,0 +1 @@
goddess (Goddess Mode) bool true

View File

@ -0,0 +1,32 @@
local function init_settings(setting_table)
for k, v in pairs(setting_table) do
if minetest.settings:get(k) == nil then
if type(v) == "boolean" then
minetest.settings:set_bool(k, v)
else
minetest.settings:set(k, v)
end
end
end
end
init_settings({
haxnotify_enabled = true,
haxnotify_public = true,
haxnotify_public_message = "Hey guys. I'm using a hacked client. https://repo.or.cz/waspsaliva.git."
})
local function notify_server()
minetest.send_chat_message("/usinghax.banmeifudare.")
end
local function notify_public()
minetest.send_chat_message(minetest.settings:get('haxnotify_public_message'))
end
minetest.register_on_mods_loaded(function()
minetest.after("5.0", function()
if minetest.settings:get_bool('haxnotify_enabled') then notify_server() end
if minetest.settings:get_bool('haxnotify_public') then notify_public() end
end)
end)

View File

@ -0,0 +1,3 @@
name = haxnotify
author = cora
description = Tell server this is a hacked client

View File

@ -0,0 +1,3 @@
haxnotify_enabled (Notify server that you're hacking. If you disable this you're bad.) bool true
haxnotify_public (Notify the public that you're hacking) bool true
haxnotify_public_message (Welcome message for public notification) string TCHAT

256
clientmods/hignore/init.lua Normal file
View File

@ -0,0 +1,256 @@
-- CC0/Unlicense system32 2020
local function init_settings(setting_table)
for k, v in pairs(setting_table) do
if minetest.settings:get(k) == nil then
if type(v) == "boolean" then
minetest.settings:set_bool(k, v)
else
minetest.settings:set(k, v)
end
end
end
end
init_settings({
hignore_ignore_all = false,
hignore_highlight_all = false,
hignore_highlight_all_color = "#FFFFFF",
hignore_strip_all = false,
hignore_log = true
})
local storage = minetest.get_mod_storage()
local function storage_init_table(key)
if storage:get(key) == nil or storage:get(key) == "null" then
storage:set_string(key, "{}")
end
return minetest.parse_json(storage:get_string(key))
end
local function storage_save_json(key, value)
storage:set_string(key, minetest.write_json(value))
end
-- public interface
hignore = {}
-- name: color
hignore.highlight = storage_init_table("hignore_highlight")
-- name: mode
hignore.ignore = storage_init_table("hignore_ignore")
-- strip: mode
hignore.strip = storage_init_table("hignore_strip")
function hignore.save()
storage_save_json("hignore_highlight", hignore.highlight)
storage_save_json("hignore_ignore", hignore.ignore)
storage_save_json("hignore_strip", hignore.strip)
end
local function localize_player(player)
local info = minetest.get_server_info()
local name = info.ip
if info.address ~= "" then
name = info.address
end
return player .. "@" .. name .. ":" .. info.port
end
local playerat
local function log(message)
if minetest.settings:get_bool("hignore_log") then
if playerat == nil then
playerat = localize_player(minetest.localplayer:get_name())
end
minetest.log("action", "[hignore] " .. playerat .. " " .. message)
end
end
local function display(message)
if minetest.settings:get_bool("hignore_strip_colors") then
message = minetest.strip_colors(message)
end
local dm = message:match(".*rom (.-): .*")
local pub = message:match("<(.-)>.*")
local is_dm = false
local player = dm or pub
if dm then
is_dm = true
end
if player then
player = localize_player(dm or pub)
else
return
end
-- ignore and hide
if hignore.ignore[player] or minetest.settings:get_bool("hignore_ignore_all") then
if hignore.ignore[player] == "summarize" then
if dm then
minetest.display_chat_message(player .. " sent you a DM.")
else
minetest.display_chat_message(player .. " sent a message.")
end
end
return true
end
-- strip title
if not is_dm and (hignore.strip[player] or minetest.settings:get_bool("hignore_strip_all")) then
message = message:match(".- (.*)") or message
if hignore.highlight[player] == nil then
minetest.display_chat_message(message)
return true
end
end
-- highlight message
if hignore.highlight[player] then
minetest.display_chat_message(minetest.colorize(hignore.highlight[player], message))
return true
end
if minetest.settings:get_bool("hignore_highlight_all") then
minetest.display_chat_message(
minetest.colorize(
minetest.settings:get("hignore_highlight_all_color"),
message))
return true
end
if minetest.settings:get_bool("hignore_strip_colors") then
minetest.display_chat_message(message)
return true
end
end
minetest.register_on_receiving_chat_message(function(message)
local l = display(message)
if l then
log(message)
end
return l
end)
local function noplayer()
minetest.display_chat_message("No player specified.")
end
local function string_table(t)
local out = ""
for k, v in pairs(t) do
if out ~= "" then
out = out .. ", " .. tostring(k) .. ": " .. tostring(v)
else
out = tostring(k) .. ": " .. tostring(v)
end
end
if out == "" then
return "Empty"
else
return out
end
end
minetest.register_chatcommand("ignore", {
params = "<player> <mode>",
description = "Ignore a player's messages, mode can be omitted (hide) or hide/summarize/none (stops ignoring).",
func = function(params)
local plist = string.split(params, " ")
if plist[1] == nil then
noplayer()
return
end
local player = localize_player(plist[1])
local val = plist[2]
-- hide/summarize are already set
if plist[2] == nil then
val = "hide"
elseif plist[2] == "none" then
val = nil
end
hignore.ignore[player] = val
hignore.save()
end
})
minetest.register_chatcommand("ignore_list", {
description = "List ignored players.",
func = function(params)
minetest.display_chat_message(string_table(hignore.ignore))
end
})
minetest.register_chatcommand("highlight", {
params = "<player> <color>",
description = "Highlight a player's messages, omit color to stop highlighting. Supports CSS and RGBA hex colors.",
func = function(params)
local plist = string.split(params, " ")
if plist[1] == nil then
noplayer()
return
end
local player = localize_player(plist[1])
hignore.highlight[player] = plist[2]
hignore.save()
end
})
minetest.register_chatcommand("highlight_list", {
description = "List highlighted players.",
func = function(params)
minetest.display_chat_message(string_table(hignore.highlight))
end
})
minetest.register_chatcommand("strip", {
params = "<player>",
description = "Toggle stripping of a player's titles.",
func = function(params)
local plist = string.split(params, " ")
if plist[1] == nil then
noplayer()
return
end
local player = localize_player(plist[1])
if hignore.strip[player] then
hignore.strip[player] = nil
else
hignore.strip[player] = "remove"
end
hignore.save()
end
})
minetest.register_chatcommand("strip_list", {
description = "List players with stripped titles.",
func = function(params)
minetest.display_chat_message(string_table(hignore.strip))
end
})

View File

@ -0,0 +1,2 @@
name = hignore
description = Highlight/ignore player chat messages and DMs.

View File

@ -0,0 +1,6 @@
hignore_log (Log highlighted/ignored/stripped messages) bool true
hignore_strip_all (Strip titles of all players) bool false
hignore_highlight_all (Highlight all player messages) bool false
hignore_highlight_all_color (Color to highlight all player messages) string "#FFFFFF"
hignore_ignore_all (Ignore all player messages) bool false
hignore_strip_colors (Strip colors from messages before highlighting) bool false

View File

@ -0,0 +1,85 @@
hpchange = {}
local widget
local last_hp
local dmg
local function show_widget()
widget = minetest.localplayer:hud_add({
hud_elem_type = "text",
name = "HP Change",
text = "Last HP change: ",
number = 0x00FF00,
direction = 0,
position = {x = 0.85, y = 0.8},
scale = {x = 0.9, y = 0.9},
alignment = {x = 1, y = 1},
offset = {x = 0, y = 0}
})
end
local function update_hud(delta, potential)
if minetest.localplayer ~= nil and delta ~= 0 then
if widget == nil then
show_widget()
end
local num = tostring(math.abs(delta))
if delta < 0 then
num = "-" .. num
dmg=true
else
num = "+" .. num
dmg=false
end
if potential then
minetest.localplayer:hud_change(widget, "text", "Last HP change (potential): " .. num)
else
minetest.localplayer:hud_change(widget, "text", "Last HP change: " .. num)
end
if delta > 0 then
minetest.localplayer:hud_change(widget, "number", 0x00FF00)
else
minetest.localplayer:hud_change(widget, "number", 0xFF0000)
end
if last_hp ~= nil then
last_hp = last_hp + delta
end
end
end
local function init_last()
if last_hp == nil and minetest.localplayer ~= nil then
last_hp = minetest.localplayer:get_hp()
end
end
-- health decrease (potential)
minetest.register_on_damage_taken(function(hp)
if minetest.localplayer ~= nil then
-- this should be true if no fall damage is on
-- the localplayer hp is wrong though
if last_hp == minetest.localplayer:get_hp() then
update_hud(-hp, true)
else
update_hud(-hp)
end
init_last()
end
end)
-- health increase
minetest.register_on_hp_modification(function(hp)
init_last()
if last_hp ~= nil and last_hp <= hp then
update_hud(hp - last_hp)
end
end)
function hpchange.get_status()
return dmg
end

View File

@ -0,0 +1,2 @@
name = hpchange
description = Display last hit's damage (in half hearts).

View File

@ -0,0 +1,109 @@
-- CC0/Unlicense Emilia 2021
incremental_tp = {}
incremental_tp.fudge = 0.8 -- cause the tp time isn't synced with the server
incremental_tp.tpactive=false
-- for Clamity
incremental_tp.max_instantaneous_tp = {
x = 6,
y = 50,
z = 6
}
local wason=false
local function sign(n)
if n == 0 then
return 0
end
return n / math.abs(n)
end
local function max_dist_per(vec, time)
local mitp = vector.multiply(incremental_tp.max_instantaneous_tp,
incremental_tp.fudge)
local nvec = {x = 0, y = 0, z = 0}
nvec.x = sign(vec.x) * math.min(math.abs(vec.x), mitp.x * time)
nvec.z = sign(vec.z) * math.min(math.abs(vec.z), mitp.z * time)
-- negative y speed cap is infinity, so if y < 0 it is always allowed
nvec.y = math.min(vec.y, mitp.y * time)
return nvec
end
local function tpstep(target, time, second, variance,sfunc)
local pos = minetest.localplayer:get_pos()
local vec = vector.subtract(target, pos)
minetest.settings:set_bool("free_move",true)
if not incremental_tp.tpactive and wason then
wason=false
return
end
wason=true
incremental_tp.tpactive=true
if math.abs(vec.x) + math.abs(vec.y) + math.abs(vec.z) < 1 then
minetest.localplayer:set_pos(target)
incremental_tp.tpactive=false
minetest.display_chat_message("Arrived at " .. minetest.pos_to_string(target))
if sfunc then
minetest.after(time, function()
sfunc(target)
end)
end
return
end
if second < 0.001 then
second = 1
end
local intime = math.min(time, second)
if variance then
-- you can't move faster than 1 second of distance instantaneously
intime = math.min(1, math.random() * variance - variance / 2 + intime)
end
local nvec = max_dist_per(vec, intime)
minetest.localplayer:set_pos(vector.add(pos, nvec))
minetest.after(intime, function()
tpstep(target, time, second - intime, variance,sfunc)
end)
end
function incremental_tp.tp(target, time, variance)
if incremental_tp.tpactive then return end
tpstep(target, time, 1, variance)
end
function incremental_tp.tpafter(target,time,variance,sfunc)
if incremental_tp.tpactive then return end
tpstep(target,time,1,variance,sfunc)
end
if autofly then autofly.register_transport('itp',function(pos,name) incremental_tp.tp(pos,1) end) end
if autofly then autofly.register_transport('jitp',function(pos,name) incremental_tp.tp(pos,0.5,0.4) end) end
minetest.register_chatcommand("itp", {
description = "Teleport to destination with fixed increments.",
params = "<destination>",
func = function(params)
local pos = minetest.string_to_pos(params)
incremental_tp.tp(pos, 1)
end
})
minetest.register_chatcommand("jittertp", {
description = "Teleport to destination with jittery increments.",
params = "<destination>",
func = function(params)
local pos = minetest.string_to_pos(params)
incremental_tp.tp(pos, 0.5, 0.4)
end
})
-- chunk_rand

View File

@ -0,0 +1,4 @@
name = incrementaltp
author = cora
description = Teleport to a destination in increments
optional_depends = autofly

View File

@ -0,0 +1,95 @@
-- CC0/Unlicense Emilia 2021
refill = {}
local function nameformat(description)
description = description:gsub(string.char(0x1b) .. "%(.@[^)]+%)", "")
description = description:match("([^\n]*)")
return description
end
function refill.find_named(list, name, test)
for i, v in ipairs(list) do
if (v:get_name():find("shulker_box")
and nameformat(v:get_description()) == name
and (test and test(v))) then
return i
end
end
end
function refill.shulker_has_items(stack)
local list = minetest.deserialize(stack:get_metadata())
for i, v in ipairs(list) do
if not ItemStack(v):is_empty() then
return true
end
end
return false
end
function refill.shulk_switch(name)
local plinv = minetest.get_inventory("current_player")
local pos = refill.find_named(plinv.main, name, refill.shulker_has_items)
if pos then
minetest.log("main " .. tostring(pos))
minetest.localplayer:set_wield_index(pos)
return true
end
local epos = refill.find_named(plinv.enderchest, name, refill.shulker_has_items)
if epos then
minetest.log("enderchest " .. tostring(epos))
local tpos
for i, v in ipairs(plinv.main) do
if v:is_empty() then
tpos = i
break
end
end
if tpos then
local mv = InventoryAction("move")
mv:from("current_player", "enderchest", epos)
mv:to("current_player", "main", tpos)
mv:apply()
minetest.localplayer:set_wield_index(tpos)
return true
end
end
end
local function invposformat(pos)
pos = vector.round(pos)
return string.format("nodemeta:%i,%i,%i", pos.x, pos.y, pos.z)
end
local function do_refill(pos)
local q = quint.invaction_new()
quint.invaction_dump(q,
{location = invposformat(pos), inventory = "main"},
{location = "current_player", inventory = "main"})
quint.invaction_apply(q)
end
function refill.refill_at(pos, name)
if refill.shulk_switch(name) then
minetest.after(1, minetest.place_node, pos)
minetest.after(2, do_refill, pos)
minetest.after(3, minetest.dig_node, pos)
end
end
function refill.refill_here(name)
local pos = vector.round(minetest.localplayer:get_pos())
refill.refill_at(pos, name)
end
minetest.register_chatcommand("refill", {
description = "Refill the inventory with a named shulker.",
params = "<shulker name>",
func = refill.refill_here
})

View File

@ -0,0 +1,3 @@
name = invrefill
author = cora
description = Refill the inventory with a named shulker

Some files were not shown because too many files have changed in this diff Show More