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 0e9e1f3528c3d2fa1f1e9a79d4a00576be8552f5 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
This commit is contained in:
parent
af085acbd3
commit
2551ddbf1d
120
clientmods/antigone/init.lua
Normal file
120
clientmods/antigone/init.lua
Normal file
@ -0,0 +1,120 @@
|
||||
antigone={}
|
||||
|
||||
local antm = false
|
||||
|
||||
local chance = 10
|
||||
|
||||
local lastutter=0
|
||||
|
||||
local qmsg = "Go then if you must, but remember, no matter how foolish your deeds, those who love you will love you still."
|
||||
|
||||
local prlv = "Goodbye to the sun that shines for me no longer!"
|
||||
|
||||
local smsg = "Unnatural silence signifies no good."
|
||||
|
||||
local qdb = {
|
||||
"All men make mistakes, but a good man yields when he knows his course is wrong, and repairs the evil. The only crime is pride.",
|
||||
"A man, though wise, should never be ashamed of learning more, and must unbend his mind.",
|
||||
"I was born to join in love, not hate - that is my nature.",
|
||||
"Grief teaches the steadiest minds to waver.",
|
||||
"We have only a little time to please the living. But all eternity to love the dead.",
|
||||
"When I have tried and failed, I shall have failed.",
|
||||
"Leave me to my own absurdity.",
|
||||
"No one loves the messenger who brings bad news.",
|
||||
"A state which belongs to just one man is no true state.",
|
||||
"It is not right if I am wrong. But if I am young, and right, what does my age matter?",
|
||||
"There is no greater evil than men's failure to consult and to consider.",
|
||||
"Nobody has a more sacred obligation to obey the law than those who make the law.",
|
||||
"Do not fear for me. Make straight your own path to destiny.",
|
||||
"Do not believe that you alone can be right. The man who thinks that,The man who maintains that only he has the power. To reason correctly, the gift to speak, the soul. A man like that, when you know him, turns out empty.",
|
||||
"I have no love for a friend who loves in words alone.",
|
||||
"There is no happiness where there is no wisdom",
|
||||
"Numberless are the world's wonders, but none more wonderful than man.",
|
||||
"Oh it's terrible when the one who does the judging judges things all wrong.",
|
||||
"I have nothing but contempt for the kind of governor who is afraid, for whatever reason, to follow the course that he knows is best for the State.",
|
||||
"Reason is God's crowning gift to a man.",
|
||||
"Tell me the news, again, whatever it is… sorrow and I are hardly strangers. I can bear the worst.",
|
||||
"What do I care for life when you are dead?",
|
||||
"It is the dead, not the living, who make the longest demands.",
|
||||
"A friend in word is never friend of mine.",
|
||||
"There let her pray to the one god she worships: Death--who knows?--may just reprieve her from death. Or she may learn a last, better late than never, what a waste of breath it is to worship Death.",
|
||||
"No yield to the dead! Never stab the fighter when he's down. Where's the glory, killing the dead twice over?",
|
||||
"I know not, but strained silence, so I deem, is no less ominous than excessive grief.",
|
||||
"What a splendid king you'd make of a desert island - you and you alone.",
|
||||
"I don't even exist—I'm no one. Nothing.",
|
||||
"No man, my lord, should make a vow, for if he ever swears he will not do a thing.",
|
||||
"When misfortune comes, The wisest even lose their mother wit",
|
||||
"I didn't say yes. I can say no to anything I say vile, and I don't have to count the cost. But because you said yes, all that you can do, for all your crown and your trappings, and your guards—all that your can do is to have me killed.",
|
||||
"One must wait until evening to see how splendid the day has been.",
|
||||
"Every way leads but astray.",
|
||||
"Know'st not whate'er we do is done in love?",
|
||||
"Love resistless in fight, all yield at a glance of thine eye, Love who pillowed all night on a maiden's cheek dost lie, Over the upland holds. Shall mortals not yield to thee",
|
||||
"True, as unwisdom is the worst of ills",
|
||||
"Good advice, if there's any good in suffering. Quickest is best when trouble blocks the way.",
|
||||
"Chastisement for errors past – Wisdom brings to age at last.",
|
||||
"But if I am young, thou shouldest look to my merits, not to my years.",
|
||||
"Alas! How sad when reasoners reason wrong",
|
||||
"To guild refined gold, to paint the lily, to throw perfume on the violet is just fuckin' silly.",
|
||||
"Each lie we tell incurs a debt to the truth. Sooner or later the debt is paid. That is how an RBMK rector core explodes – lies!",
|
||||
"I know who I am, and I know whatI've done. In a just world, I would be shot for my lies. But not for this. Not for the truth.",
|
||||
"This death of mine Is of no importance; but if I had left my brother. Lying in death unburied, I should have suffered. Now I do not.",
|
||||
"Your edict, King, was strong! But all your strength is weakness itself against the immortal unrecorded laws of the Gods.",
|
||||
"'Why worry about something thatisn't going to happen.' That'sperfect. They should put that on our money",
|
||||
"This talking is a great weariness: your words are distasteful to me, and I am sure that mine seem so to you. And yet they should not seem so: I should have praise and honor for what I have done. All these men here would praise me were their lips not frozen shut with fear of you.",
|
||||
"The dead man and the gods who rule the dead know whose act this was. Words are not friends.",
|
||||
"You shall not lessen my death by sharing it.",
|
||||
"Out there in the wilderness, and lock her living in a vault of stone. She shall have food, As the custom is, to absolve the State of her death. And there let her pray to the gods of hell. They are her only gods: Perhaps they will show her an escape from death, or she may learn, though late, that piety shown the dead is pity in vain."
|
||||
}
|
||||
|
||||
|
||||
function cchat.getquote()
|
||||
if not antm then return end
|
||||
chance = chance - 1
|
||||
if math.random(chance) > 1 then return end
|
||||
chance=10
|
||||
if os.time() < lastutter + 15 then return end
|
||||
lastutter=os.time()
|
||||
local keyset = {}
|
||||
local qt = 1
|
||||
for k in pairs(qdb) do
|
||||
table.insert(keyset, k)
|
||||
end
|
||||
-- now you can reliably return a random key
|
||||
qt = qdb[keyset[math.random(#keyset)]]
|
||||
minetest.send_chat_message(qt)
|
||||
end
|
||||
|
||||
minetest.register_chatcommand('aqt',{
|
||||
params='',
|
||||
description='get a random antigone quote',
|
||||
func=function(param)
|
||||
cchat.getquote()
|
||||
end
|
||||
})
|
||||
|
||||
table.insert(minetest.registered_on_receiving_chat_message, 1, function(msg)
|
||||
if not antm and minetest.localplayer:get_name() == "antigone" then
|
||||
antm=true
|
||||
minetest.display_chat_message("-----antig detected. quote funcs activated.")
|
||||
end
|
||||
if not antm then return end
|
||||
local s = msg:find('^<Berastone>')
|
||||
local t = msg:find('^<oneplustwo>')
|
||||
local t = msg:find('^<oneminustwo>')
|
||||
local u = msg:find('^<mobilec>')
|
||||
local v = msg:find('^<creon>')
|
||||
local v = msg:find('^Herpera')
|
||||
local v = msg:find('^Kant')
|
||||
local v = msg:find('^Demotivator')
|
||||
local v = msg:find('^dupp')
|
||||
local zz = msg:find("^<cora>")
|
||||
local zzz = msg:find("antigone ")
|
||||
local zzzz = msg:find(" antigone")
|
||||
local zzzzz = msg:find("antigone:")
|
||||
local cc = msg:find("From cora: say")
|
||||
if cc then chance = 1 end
|
||||
if s or t or u or v or zz or zzz or zzzz or zzzzz or cc then
|
||||
cchat.getquote()
|
||||
--minetest.display_chat_message(msg)
|
||||
end
|
||||
end)
|
3
clientmods/antigone/mod.conf
Normal file
3
clientmods/antigone/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = antigone
|
||||
author = cora
|
||||
description = antigone chatbot
|
432
clientmods/autofly/init.lua
Normal file
432
clientmods/autofly/init.lua
Normal file
@ -0,0 +1,432 @@
|
||||
-- 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=100
|
||||
local speed=0;
|
||||
local ltime=0
|
||||
|
||||
local storage = minetest.get_mod_storage()
|
||||
local wpr=false;
|
||||
local twpname=nil
|
||||
local info=minetest.get_server_info()
|
||||
local stprefix="autofly-".. info['address'] .. '-'
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
dofile(modpath .. "/wpforms.lua")
|
||||
|
||||
local hud_wp
|
||||
local hud_info
|
||||
-- /COMMON
|
||||
local function 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
|
||||
end
|
||||
|
||||
local function 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
|
||||
end
|
||||
function round2(num, numDecimalPlaces)
|
||||
return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
autofly.checkfall()
|
||||
if not minetest.localplayer then return end
|
||||
if not twpname then
|
||||
autofly.set_hud_info("")
|
||||
else
|
||||
local pos = string_to_pos(autofly.get_waypoint(twpname))
|
||||
if pos then
|
||||
local dst = vector.distance(pos,minetest.localplayer:get_pos())
|
||||
local etatime=-1
|
||||
if not (speed == 0) then etatime = round2(dst / speed / 60,2) end
|
||||
autofly.set_hud_info(twpname .. "\n" .. pos_to_string(pos) .. "\n" .. "ETA" .. etatime .. " mins")
|
||||
if twpname and dst < landing_distance then
|
||||
autofly.arrived()
|
||||
end
|
||||
end
|
||||
end
|
||||
if twpname and (minetest.settings:get_bool('afly_autoaim')) then
|
||||
autofly.aim(autofly.get_waypoint(twpname))
|
||||
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=round2(dst,1)
|
||||
end
|
||||
lpos=minetest.localplayer:get_pos()
|
||||
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.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
|
||||
twpname=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
|
||||
minetest.display_chat_message('Waypoint set to ' .. title)
|
||||
-- minetest.colorize('#00ffff', title))
|
||||
return true
|
||||
end
|
||||
|
||||
local hud_info
|
||||
function autofly.set_hud_info(text)
|
||||
if not minetest.localplayer then return end
|
||||
local vspeed=minetest.localplayer:get_last_velocity()
|
||||
local ttext=text.."\nSpeed: "..speed.."n/s\n"..round2(vspeed.x / 10,1)..','..round2(vspeed.y / 10,1)..','..round2(vspeed.z / 10,1)
|
||||
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.75,y=0.9},
|
||||
alignment ={x=1,y=1},
|
||||
offset = {x=0, y=0}
|
||||
})
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function autofly.arrived()
|
||||
minetest.settings:set("continuous_forward", "false")
|
||||
minetest.settings:set("afly_autoaim", "false")
|
||||
autofly.set_hud_info("Arrived at destination")
|
||||
minetest.sound_play({name = "sounds/autofly_arrived", gain = 1.0})
|
||||
wpr=false
|
||||
twpname=nil
|
||||
end
|
||||
|
||||
function autofly.checkfall()
|
||||
if(speed > 30) then
|
||||
local nod=minetest.get_node_or_nil(vector.add(minetest.localplayer:get_pos(),{x=0,y=-100,z=0}))
|
||||
if nod and not ( nod['name'] == "air" ) then
|
||||
minetest.settings:set("free_move", "true")
|
||||
minetest.settings:set("noclip", "false")
|
||||
minetest.display_chat_message("fall detected")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function autofly.display_waypoint(name)
|
||||
autofly.last_coords = autofly.get_waypoint(name)
|
||||
autofly.last_name = name
|
||||
minetest.display_chat_message(name)
|
||||
autofly.set_hud_info(name)
|
||||
minetest.settings:set("movement_speed_walk", "5")
|
||||
if (minetest.settings:get_bool("afly_autoaim")) then autofly.aim(autofly.last_coords) end
|
||||
minetest.settings:set_bool("pitch_move",true)
|
||||
minetest.settings:set_bool("continuous_forward",true)
|
||||
return autofly.set_hud_wp(autofly.get_waypoint(name), name)
|
||||
end
|
||||
|
||||
function autofly.arrived()
|
||||
minetest.settings:set("continuous_forward", "false")
|
||||
autofly.set_hud_info("Arrived at destination")
|
||||
minetest.localplayer:hud_change(hud_info,'text',twpname .. "\n" .. "Arrived at destination.")
|
||||
minetest.sound_play({name = "sounds/autofly_arrived", gain = 1.0})
|
||||
wpr=false
|
||||
twpname=nil
|
||||
end
|
||||
|
||||
function autofly.checkfall()
|
||||
if(speed > 30) then
|
||||
local nod=minetest.get_node_or_nil(vector.add(minetest.localplayer:get_pos(),{x=0,y=-100,z=0}))
|
||||
if nod and not ( nod['name'] == "air" ) then
|
||||
minetest.display_chat_message("Autofly: Fall to ground detected!")
|
||||
minetest.display_chat_message("Deactivating noclip.")
|
||||
minetest.settings:set("noclip", "false")
|
||||
if(minetest.settings:get_bool("afly_softlanding")) then
|
||||
minetest.display_chat_message("Soft landing engaged.")
|
||||
minetest.settings:set("free_move", "true")
|
||||
else
|
||||
minetest.display_chat_message("Lithobreak imminent – maybe turn on soft landing next time")
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
function autofly.warp(name)
|
||||
local pos=vector.add(autofly.get_waypoint(name),{x=0,y=150,z=0})
|
||||
if pos then
|
||||
minetest.localplayer:set_pos(pos)
|
||||
return true, "Warped to " .. minetest.pos_to_string(pos)
|
||||
end
|
||||
end
|
||||
function autofly.warpae(name)
|
||||
local s, m = autofly.warp(name)
|
||||
if s then
|
||||
minetest.disconnect()
|
||||
end
|
||||
return s,m
|
||||
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)
|
||||
wpr=true
|
||||
return true
|
||||
end
|
||||
|
||||
-- Delete a waypoint
|
||||
function autofly.delete_waypoint(name)
|
||||
storage:set_string(stprefix .. tostring(name), '')
|
||||
end
|
||||
|
||||
-- Get a waypoint
|
||||
function autofly.get_waypoint(name)
|
||||
return string_to_pos(storage:get_string(stprefix .. tostring(name)))
|
||||
end
|
||||
|
||||
-- Rename a waypoint and re-interpret the position.
|
||||
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
|
||||
|
||||
|
||||
function autofly.get_chatcommand_pos(pos)
|
||||
if pos == 'h' or pos == 'here' then
|
||||
pos = minetest.localplayer:get_pos()
|
||||
elseif pos == 't' or pos == 'there' then
|
||||
if not autofly.last_coords then
|
||||
return false, 'No-one has used ".coords" and you have not died!'
|
||||
end
|
||||
pos = autofly.last_coords
|
||||
else
|
||||
pos = string_to_pos(pos)
|
||||
if not pos then
|
||||
return false, 'Invalid position!'
|
||||
end
|
||||
end
|
||||
return pos
|
||||
end
|
||||
|
||||
local function 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
|
||||
|
||||
minetest.register_chatcommand('waypoints', {
|
||||
params = '',
|
||||
description = 'Open the autofly GUI',
|
||||
func = function(param)
|
||||
if param == '' then
|
||||
autofly.display_formspec()
|
||||
else
|
||||
local pos, err = autofly.get_chatcommand_pos(param)
|
||||
if not pos then
|
||||
return false, err
|
||||
end
|
||||
if not autofly.set_hud_wp(pos) then
|
||||
return false, 'Error setting the waypoint!'
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
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)
|
||||
|
||||
-- Validate the position
|
||||
local pos, err = autofly.get_chatcommand_pos(pos)
|
||||
if not pos then
|
||||
return false, err
|
||||
end
|
||||
|
||||
-- Validate the name
|
||||
if not name or #name < 1 then
|
||||
return false, 'Invalid name!'
|
||||
end
|
||||
|
||||
-- Set the waypoint
|
||||
return autofly.set_waypoint(pos, name), 'Done!'
|
||||
end
|
||||
})
|
||||
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
|
||||
})
|
||||
register_chatcommand_alias('add_waypoint_here', 'wah', 'add_wph')
|
||||
minetest.register_chatcommand('clear_waypoint', {
|
||||
params = '',
|
||||
description = 'Hides the displayed waypoint.',
|
||||
func = function(param)
|
||||
if twpname then twpname = nil end
|
||||
if hud_wp then
|
||||
minetest.localplayer:hud_remove(hud_wp)
|
||||
hud_wp = nil
|
||||
twpname=nil
|
||||
wpr=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,
|
||||
})
|
||||
|
||||
minetest.register_on_death(function()
|
||||
if minetest.localplayer then
|
||||
local name = 'Death waypoint'
|
||||
local pos = minetest.localplayer:get_pos()
|
||||
autofly.last_coords = pos
|
||||
autofly.set_waypoint(pos, name)
|
||||
minetest.display_chat_message('Added waypoint "' .. name .. '".')
|
||||
end
|
||||
end)
|
||||
|
||||
function autofly.aim(tpos)
|
||||
local ppos=minetest.localplayer:get_pos()
|
||||
--local dir=tpos
|
||||
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 = round2(math.deg(yyaw),0)
|
||||
pitch = round2(math.deg(math.asin(-dir.y) * 1),0);
|
||||
minetest.localplayer:set_yaw(yyaw)
|
||||
minetest.localplayer:set_pitch(pitch)
|
||||
|
||||
end
|
||||
|
||||
|
||||
register_chatcommand_alias('clear_waypoint', 'cwp','cls')
|
||||
|
||||
if (_G["minetest"]["register_cheat"] ~= nil) then
|
||||
minetest.register_cheat("AutoAim", "Autofly", "afly_autoaim")
|
||||
minetest.register_cheat("SoftLanding", "Autofly", "afly_softlanding")
|
||||
else
|
||||
minetest.settings:set_bool("afly_autoaim",false)
|
||||
minetest.settings:set_bool("afly_softlanding",true)
|
||||
end
|
3
clientmods/autofly/mod.conf
Normal file
3
clientmods/autofly/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = autofly
|
||||
author = cora
|
||||
description = autonomous flight
|
2
clientmods/autofly/settingtypes.txt
Normal file
2
clientmods/autofly/settingtypes.txt
Normal file
@ -0,0 +1,2 @@
|
||||
afly_autoaim (Autoaim) bool false
|
||||
afly_softlanding (Soft Landing) bool true
|
225
clientmods/autofly/wpforms.lua
Normal file
225
clientmods/autofly/wpforms.lua
Normal file
@ -0,0 +1,225 @@
|
||||
|
||||
|
||||
|
||||
-- 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={}
|
||||
local tspeed = 20 -- speed in blocks per second
|
||||
local speed=0;
|
||||
local ltime=0
|
||||
function autofly.display_formspec()
|
||||
local formspec = 'size[5.25,8]' ..
|
||||
'label[0,0;Waypoint list]' ..
|
||||
'button_exit[0,7.5;1.3125,0.5;display;GO]' ..
|
||||
'button[1.1125,7.5;0.9,0.5;warp;wrp]' ..
|
||||
'button[1.6125,7.5;1.2,0.5;warpae;w+e]' ..
|
||||
'button[2.625,7.5;1.3,0.5;rename;Rename]' ..
|
||||
'button[3.9375,7.5;1.3,0.5;delete;Delete]' ..
|
||||
'textlist[0,0.75;5,6;marker;'
|
||||
|
||||
-- Iterate over all the waypoints
|
||||
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
|
||||
|
||||
-- Close the text list and display the selected waypoint position
|
||||
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 ".add_mrkr".]'
|
||||
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
|
||||
if fields.display then
|
||||
if not autofly.display_waypoint(name) then
|
||||
minetest.display_chat_message('Error displaying waypoint!')
|
||||
end
|
||||
elseif fields.warp then
|
||||
if not autofly.warp(name) then
|
||||
minetest.display_chat_message('warp error')
|
||||
end
|
||||
elseif fields.warpae then
|
||||
if not autofly.warpae(name) then
|
||||
minetest.display_chat_message('warpandexit error')
|
||||
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 markers.',
|
||||
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 markers 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
|
26
clientmods/autowarp/init.lua
Normal file
26
clientmods/autowarp/init.lua
Normal file
@ -0,0 +1,26 @@
|
||||
autowarp = {}
|
||||
|
||||
local storage = minetest.get_mod_storage()
|
||||
|
||||
local cond=true;
|
||||
local function isleep(s)
|
||||
local ntime = os.time() + s
|
||||
repeat until os.time() > ntime
|
||||
end
|
||||
|
||||
|
||||
minetest.register_chatcommand("awarp", {
|
||||
params = "",
|
||||
description = "Warp to a set warp or a position.",
|
||||
func = function(param)
|
||||
local xx=4000
|
||||
--for o,p in poss do
|
||||
--local pos = minetest.parse_pos("4000,20,4000")
|
||||
while cond do
|
||||
minetest.localplayer:set_pos({x=xx,y=20,z=4000})
|
||||
isleep(5)
|
||||
xx=xx-100
|
||||
if xx < -4000 then break end
|
||||
end
|
||||
end
|
||||
})
|
3
clientmods/autowarp/mod.conf
Normal file
3
clientmods/autowarp/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = autowarp
|
||||
author = cora
|
||||
description = dl a section of the map
|
90
clientmods/cchat/init.lua
Normal file
90
clientmods/cchat/init.lua
Normal file
@ -0,0 +1,90 @@
|
||||
--
|
||||
-- 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
|
||||
|
||||
|
||||
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
|
3
clientmods/cchat/mod.conf
Normal file
3
clientmods/cchat/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = cchat
|
||||
author = cora
|
||||
description = cora's chat extensions, primarily log to stdout
|
@ -78,4 +78,3 @@ minetest.register_chatcommand("set", {
|
||||
return false, "Invalid parameters (see .help set)."
|
||||
end,
|
||||
})
|
||||
|
||||
|
21
clientmods/dte/LICENSE
Normal file
21
clientmods/dte/LICENSE
Normal 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
59
clientmods/dte/README.md
Normal 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 (?)
|
2466
clientmods/dte/development/formspec editor.lua
Normal file
2466
clientmods/dte/development/formspec editor.lua
Normal file
File diff suppressed because it is too large
Load Diff
492
clientmods/dte/development/lua editor.lua
Normal file
492
clientmods/dte/development/lua editor.lua
Normal 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,
|
||||
})
|
||||
|
2915
clientmods/dte/init.lua
Normal file
2915
clientmods/dte/init.lua
Normal file
File diff suppressed because it is too large
Load Diff
BIN
clientmods/dte/preview_1.png
Normal file
BIN
clientmods/dte/preview_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
clientmods/dte/preview_2.png
Normal file
BIN
clientmods/dte/preview_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 67 KiB |
92
clientmods/esp/init.lua
Normal file
92
clientmods/esp/init.lua
Normal file
@ -0,0 +1,92 @@
|
||||
---
|
||||
-- coras esp .. indev
|
||||
|
||||
|
||||
esp = {}
|
||||
|
||||
local radius=79 -- 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=1 --number of seconds to wait between scans (a lower number can induce clientside lag)
|
||||
|
||||
--nodes={"group:chest",'mcl_chests:chest','mcl_chests:chest_left','mcl_chests:ender_chest','group:shulker_box','mcl_crafting_table:crafting_table','mcl_furnaces:furnace'}
|
||||
nodes={'mcl_chests:chest','mcl_chests:chest_left','mcl_chests:ender_chest','group:shulker_box','mcl_furnaces:furnace','mcl_chests:violet_shulker_box'}
|
||||
|
||||
local wps={}
|
||||
local hud2=nil
|
||||
local hud;
|
||||
local lastch=0
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
if not minetest.settings:get_bool("espactive") then
|
||||
if hud2 then minetest.localplayer:hud_remove(hud2) hud2=nil end
|
||||
for k,v in pairs(wps) do
|
||||
minetest.localplayer:hud_remove(v)
|
||||
table.remove(wps,k)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if os.time() < lastch + espinterval then return end
|
||||
lastch=os.time()
|
||||
|
||||
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 fpos,cnt=minetest.find_nodes_in_area(pos1, pos2, nodes, false)
|
||||
local epos=minetest.find_nodes_in_area(pos1, pos2, nodes, true)
|
||||
|
||||
for k,v in pairs(wps) do --clear waypoints out of range
|
||||
local hd=minetest.localplayer:hud_get(v)
|
||||
local dst=vector.distance(pos,hd.world_pos)
|
||||
if (dst > radius + 50 ) then
|
||||
minetest.localplayer:hud_remove(v)
|
||||
table.remove(wps,k)
|
||||
end
|
||||
end
|
||||
|
||||
if epos then
|
||||
if(hud2) then minetest.localplayer:hud_remove(hud2) end
|
||||
local infotxt=""
|
||||
for k,v in pairs(cnt) do -- display a summary
|
||||
if not ( v == 0 ) then
|
||||
if minetest.settings:get_bool("espautostop") then minetest.settings:set("continuous_forward", "false") end
|
||||
infotxt=infotxt.."\n"..k..":"..v
|
||||
end
|
||||
end
|
||||
if infotxt ~= "" then
|
||||
hud2=minetest.localplayer:hud_add({
|
||||
hud_elem_type = 'text',
|
||||
name = "ESP info",
|
||||
text = "NOIs in range ("..radius..")\n"..infotxt,
|
||||
number = 0x00ff00,
|
||||
direction = 0,
|
||||
position = {x=0.75,y=0.4},
|
||||
alignment ={x=1,y=1},
|
||||
offset = {x=0, y=0}
|
||||
})
|
||||
end
|
||||
|
||||
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
|
||||
ii=ii+1
|
||||
table.insert(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("ESP active", "ESP", "espactive")
|
||||
minetest.register_cheat("autostop", "ESP", "espautostop")
|
||||
else
|
||||
minetest.settings:set_bool('espactive',true)
|
||||
end
|
3
clientmods/esp/mod.conf
Normal file
3
clientmods/esp/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = esp
|
||||
author = cora
|
||||
description = ESP hack
|
2
clientmods/esp/settingtypes.txt
Normal file
2
clientmods/esp/settingtypes.txt
Normal file
@ -0,0 +1,2 @@
|
||||
espactive (Enable ESP) bool false
|
||||
espautostop (Stop Autoforward) bool true
|
130
clientmods/flightaura/init.lua
Normal file
130
clientmods/flightaura/init.lua
Normal file
@ -0,0 +1,130 @@
|
||||
--
|
||||
-- cora's defensive combat hax
|
||||
-- * undying
|
||||
-- * damagepanic
|
||||
|
||||
flightaura = {}
|
||||
local undying = true --will automatically /sethome when taking damage below 3 hp, tp you back when you die and dig the bones undying needs autorespawn enabled in dragonfire (might steal the code at some point to enable it for vanilla / other clients)
|
||||
local damagepanic = true --will tp you 50 nodes up on damage taken when hp is < paniclimit
|
||||
|
||||
local check_target = true
|
||||
|
||||
local paniclimit=17
|
||||
|
||||
local tprange=50;
|
||||
|
||||
|
||||
local function sleep(n) -- seconds
|
||||
local t0 = os.clock()
|
||||
while os.clock() - t0 <= n do end
|
||||
end
|
||||
|
||||
|
||||
local function mwarp(pos)
|
||||
if not pos then return end
|
||||
--minetest.display_chat_message("Flightaura: Damage taken, target clear. Tping up to "..pos['y'])
|
||||
minetest.localplayer:set_pos(pos)
|
||||
|
||||
end
|
||||
|
||||
minetest.register_on_death(function()
|
||||
if not minetest.settings:get_bool("undying") then return end
|
||||
minetest.send_chat_message("/home")
|
||||
sleep(2)
|
||||
local bn=minetest.find_node_near(minetest.localplayer:get_pos(), 4, {"bones:bones"},true)
|
||||
if not bn then return end
|
||||
minetest.dig_node(bn)
|
||||
end)
|
||||
|
||||
local tprangeh=20
|
||||
local tprangepy=50
|
||||
local tprangeny=60
|
||||
|
||||
|
||||
local function get_rnd_pos()
|
||||
local ppos=minetest.localplayer:get_pos()
|
||||
local xx=1
|
||||
local yy=40
|
||||
local zz=1
|
||||
local pos=vector.add(ppos,{x=xx,y=yy,z=zz})
|
||||
return pos
|
||||
end
|
||||
|
||||
function flightaura.find_target()
|
||||
if not minetest.settings:get_bool("damagepanic") then return end
|
||||
|
||||
local nod=minetest.get_node_or_nil(get_rnd_pos())
|
||||
if not nod then return end
|
||||
while (nod["name"] ~= "air") do
|
||||
local rpos=get_rnd_pos()
|
||||
local tpos=vector.add(ppos,rpos)
|
||||
nod=minetest.get_node_or_nil(tpos)
|
||||
fnd=true
|
||||
end
|
||||
--minetest.display_chat_message(dump(rpos))
|
||||
if not fnd then
|
||||
--minetest.display_chat_message("no clear node to flee. turning on Killaura.")
|
||||
minetest.settings:set_bool("killaura",true)
|
||||
return false
|
||||
end
|
||||
return tpos
|
||||
end
|
||||
|
||||
minetest.register_on_damage_taken(function(hp)
|
||||
local hhp=minetest.localplayer:get_hp()
|
||||
--minetest.display_chat_message("hp:"..hp)
|
||||
--minetest.display_chat_message("hhp:"..hhp)
|
||||
if (hp==0 ) then return end
|
||||
if ( hhp < paniclimit ) and (hhp >= 3 ) then
|
||||
cpos=flightaura.find_target()
|
||||
if minetest.settings:get_bool("damagepanic") then
|
||||
minetest.settings:set("free_move", "true")
|
||||
mwarp(vector.add(cpos,{x=0,y=-1,z=0}))
|
||||
end
|
||||
elseif (hp < 3 ) then
|
||||
if minetest.settings:get_bool("undying") then
|
||||
minetest.settings:set_bool("autorespawn",true)
|
||||
minetest.send_chat_message("/sethome") end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
minetest.register_chatcommand("eat", {
|
||||
params = "",
|
||||
description = "",
|
||||
func = function()
|
||||
local pl = minetest.localplayer
|
||||
local inv = minetest.get_inventory("current_player")
|
||||
for index, stack in pairs(inv.main) do
|
||||
minetest.display_chat_message(stack)
|
||||
if (stack == "mcl_farming:carrot_item_gold") then pl.set_wield_index(index) break end
|
||||
end
|
||||
return
|
||||
end})
|
||||
minetest.register_chatcommand("dhead", {
|
||||
params = "",
|
||||
description = "",
|
||||
func = function()
|
||||
--eat()
|
||||
-- minetest.display_chat_message("head")
|
||||
-- minetest.display_chat_message(dump(minetest.get_inventory("current_player").main))
|
||||
minetest.settings:set_bool("autotool",true)
|
||||
sleep(1)
|
||||
local ppos=vector.add(minetest.localplayer:get_pos(),{x=0,y=1,z=0})
|
||||
if ppos then minetest.dig_node(ppos) end
|
||||
return
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
-- REG cheats on DF
|
||||
if (_G["minetest"]["register_cheat"] ~= nil) then
|
||||
minetest.register_cheat("Flightaura", "Combat", "damagepanic")
|
||||
minetest.register_cheat("Undying", "Combat", "undying")
|
||||
else
|
||||
minetest.settings:set_bool('undying',true)
|
||||
minetest.settings:set_bool('damagepanic',false)
|
||||
end
|
3
clientmods/flightaura/mod.conf
Normal file
3
clientmods/flightaura/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = flightaura
|
||||
author = cora
|
||||
description = defensive combat hax
|
3
clientmods/flightaura/settingtypes.txt
Normal file
3
clientmods/flightaura/settingtypes.txt
Normal file
@ -0,0 +1,3 @@
|
||||
undying (Undying) bool false
|
||||
panicmode (Flightaura) bool false
|
||||
tprange (Teleport Range) int 50
|
@ -15,6 +15,7 @@ local function check_tool(stack, node_groups, old_best_time)
|
||||
end
|
||||
|
||||
minetest.register_on_punchnode(function(pos, node)
|
||||
--minetest.display_chat_message(dump(node))
|
||||
if not minetest.settings:get_bool("autotool") then return end
|
||||
local player = minetest.localplayer
|
||||
local inventory = minetest.get_inventory("current_player")
|
||||
@ -33,4 +34,3 @@ minetest.register_on_punchnode(function(pos, node)
|
||||
end)
|
||||
|
||||
minetest.register_cheat("AutoTool", "Inventory", "autotool")
|
||||
|
||||
|
@ -1,7 +1,19 @@
|
||||
load_mod_warp = true
|
||||
load_mod_world = true
|
||||
load_mod_respawn = true
|
||||
load_mod_inventory = true
|
||||
load_mod_commands = true
|
||||
load_mod_chat = true
|
||||
load_mod_schematicas = true
|
||||
load_mod_warp = true
|
||||
load_mod_cchat = true
|
||||
load_mod_autofly = true
|
||||
load_mod_aflight = false
|
||||
load_mod_geass = false
|
||||
load_mod_autowarp = true
|
||||
load_mod_panicm = true
|
||||
load_mod_tchat = true
|
||||
load_mod_esp = true
|
||||
load_mod_antigone = false
|
||||
load_mod_dte = true
|
||||
load_mod_wisp = true
|
||||
load_mod_flightaura = false
|
||||
|
132
clientmods/panicm/init.lua
Normal file
132
clientmods/panicm/init.lua
Normal file
@ -0,0 +1,132 @@
|
||||
--
|
||||
-- cora's defensive combat hax
|
||||
-- * undying
|
||||
-- * damagepanic
|
||||
|
||||
panicm = {}
|
||||
local undying = true --will automatically /sethome when taking damage below 3 hp, tp you back when you die and dig the bones undying needs autorespawn enabled in dragonfire (might steal the code at some point to enable it for vanilla / other clients)
|
||||
local damagepanic = true --will tp you 50 nodes up on damage taken when hp is < paniclimit
|
||||
|
||||
local check_target = true
|
||||
|
||||
local paniclimit=17
|
||||
|
||||
local tprange=50;
|
||||
|
||||
|
||||
local function sleep(n) -- seconds
|
||||
local t0 = os.clock()
|
||||
while os.clock() - t0 <= n do end
|
||||
end
|
||||
|
||||
|
||||
local function mwarp(pos)
|
||||
if not pos then return end
|
||||
--minetest.display_chat_message("Flightaura: Damage taken, target clear. Tping up to "..pos['y'])
|
||||
minetest.localplayer:set_pos(pos)
|
||||
|
||||
end
|
||||
|
||||
minetest.register_on_death(function()
|
||||
if not minetest.settings:get_bool("undying") then return end
|
||||
minetest.send_chat_message("/home")
|
||||
sleep(2)
|
||||
local bn=minetest.find_node_near(minetest.localplayer:get_pos(), 4, {"bones:bones"},true)
|
||||
if not bn then return end
|
||||
minetest.dig_node(bn)
|
||||
end)
|
||||
|
||||
local tprangeh=20
|
||||
local tprangepy=50
|
||||
local tprangeny=60
|
||||
|
||||
function panicm.find_target(check_target)
|
||||
if not minetest.settings:get_bool("damagepanic") then return end
|
||||
local ppos=minetest.localplayer:get_pos()
|
||||
local tpos=vector.add(ppos,{x=0,y=tprange,z=0})
|
||||
if check_target then return tpos end
|
||||
local pos=false
|
||||
for i = 0,tprangepy,1 do
|
||||
local nod=minetest.get_node_or_nil(vector.add(tpos,{x=0,y=-i,z=0}))
|
||||
if nod and (nod["name"] == "air") then fnd=true break end
|
||||
end
|
||||
if not fnd then
|
||||
for i = -tprangeh,tprangeh,1 do
|
||||
local nod=minetest.get_node_or_nil(vector.add(tpos,{x=i,y=0,z=0}))
|
||||
if nod and (nod["name"] == "air") then fnd=true break end
|
||||
local nod=minetest.get_node_or_nil(vector.add(tpos,{x=0,y=0,z=i}))
|
||||
if nod and (nod["name"] == "air") then fnd=true break end
|
||||
end
|
||||
end
|
||||
if not fnd then
|
||||
for i = -tprangeny,0,1 do
|
||||
local nod=minetest.get_node_or_nil(vector.add(tpos,{x=0,y=i,z=0}))
|
||||
if nod and (nod["name"] == "air") then fnd=true break end
|
||||
end
|
||||
end
|
||||
if not fnd then
|
||||
minetest.display_chat_message("no clear node to flee. turning on Killaura.")
|
||||
minetest.settings:set_bool("killaura",true)
|
||||
return false
|
||||
end
|
||||
return pos
|
||||
end
|
||||
|
||||
minetest.register_on_damage_taken(function(hp)
|
||||
local hhp=minetest.localplayer:get_hp()
|
||||
minetest.display_chat_message("hp:"..hp)
|
||||
minetest.display_chat_message("hhp:"..hhp)
|
||||
if (hp==0 ) then return end
|
||||
if ( hhp < paniclimit ) and (hhp >= 3 ) then
|
||||
cpos=panicm.find_target(check_target)
|
||||
if minetest.settings:get_bool("damagepanic") then
|
||||
minetest.settings:set("free_move", "true")
|
||||
mwarp(vector.add(cpos,{x=0,y=-1,z=0}))
|
||||
--sleep(2)
|
||||
end
|
||||
elseif (hp < 3 ) then
|
||||
if minetest.settings:get_bool("undying") then
|
||||
minetest.settings:set_bool("autorespawn",true)
|
||||
minetest.send_chat_message("/sethome") end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
minetest.register_chatcommand("eat", {
|
||||
params = "",
|
||||
description = "",
|
||||
func = function()
|
||||
local pl = minetest.localplayer
|
||||
local inv = minetest.get_inventory("current_player")
|
||||
for index, stack in pairs(inv.main) do
|
||||
minetest.display_chat_message(stack)
|
||||
if (stack == "mcl_farming:carrot_item_gold") then pl.set_wield_index(index) break end
|
||||
break
|
||||
end
|
||||
return
|
||||
end})
|
||||
minetest.register_chatcommand("dhead", {
|
||||
params = "",
|
||||
description = "",
|
||||
func = function()
|
||||
--eat()
|
||||
-- minetest.display_chat_message("head")
|
||||
-- minetest.display_chat_message(dump(minetest.get_inventory("current_player").main))
|
||||
minetest.settings:set_bool("autotool",true)
|
||||
sleep(1)
|
||||
local ppos=vector.add(minetest.localplayer:get_pos(),{x=0,y=1,z=0})
|
||||
if ppos then minetest.dig_node(ppos) end
|
||||
return
|
||||
end
|
||||
})
|
||||
|
||||
|
||||
-- REG cheats on DF
|
||||
if (_G["minetest"]["register_cheat"] ~= nil) then
|
||||
minetest.register_cheat("Flightaura", "Combat", "damagepanic")
|
||||
minetest.register_cheat("Undying", "Combat", "undying")
|
||||
else
|
||||
minetest.settings:set_bool('undying',true)
|
||||
minetest.settings:set_bool('damagepanic',true)
|
||||
end
|
3
clientmods/panicm/mod.conf
Normal file
3
clientmods/panicm/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = panicm
|
||||
author = cora
|
||||
description = defensive combat hax
|
3
clientmods/panicm/settingtypes.txt
Normal file
3
clientmods/panicm/settingtypes.txt
Normal file
@ -0,0 +1,3 @@
|
||||
undying (Undying) bool false
|
||||
panicmode (Flightaura) bool false
|
||||
tprange (Teleport Range) int 50
|
591
clientmods/tchat/init.lua
Normal file
591
clientmods/tchat/init.lua
Normal file
@ -0,0 +1,591 @@
|
||||
---
|
||||
-- coras teamchat .. indev v0.5
|
||||
--
|
||||
-- adds a team chat for you and a couple friends, also prevents accidental sending of coordinates
|
||||
-- to say something in teamchat either activate teammode in the dragonfire menu or use .t message
|
||||
--
|
||||
-- supports the Wisp encrypted whisper mod
|
||||
--
|
||||
-- .t to say something in team chat (or regular chat if team mode is on)
|
||||
-- .tadd to add a team member
|
||||
-- .tdel to remove
|
||||
-- .tlist to list team
|
||||
--
|
||||
-- .coords to send a message containing coordinates
|
||||
-- .mcoord to send a player your current coordinates
|
||||
|
||||
|
||||
--[[
|
||||
Public methods
|
||||
|
||||
tchat.contains_coords(message) - returns true if the message contains coordinates (2d or 3d)
|
||||
|
||||
tchat.send(message) - send a message to teamchat, returns true if sent, nil if not
|
||||
tchat.send_conditional(message, inverse?) - send a message to teamchat or regular chat, returns true if sent to teamchat, false if main chat, nil if not sent
|
||||
tchat.send_coords(message) - send a message containing coordinates, true if sent, nil if not
|
||||
|
||||
tchat.whisper_coords(player) - DM current coords to a player
|
||||
|
||||
tchat.chat_clear() - clear chat widget
|
||||
tchat.chat_set([]) - set chat widget
|
||||
tchat.chat_append([] or message) - append to chat widget
|
||||
|
||||
tchat.team_add_player(player) - add player to team list
|
||||
tchat.team_remove_player(player) - remove player from team list
|
||||
tchat.team_clear() - clear team list
|
||||
tchat.team_set([]) - set team list
|
||||
|
||||
|
||||
Public properties
|
||||
|
||||
tchat.chat: last few chat messages
|
||||
tchat.team: team list
|
||||
tchat.team_online: online team list
|
||||
tchat.players: currently online players
|
||||
|
||||
|
||||
Settings
|
||||
|
||||
bool tchat_view_chat - if the team chat is shown
|
||||
bool tchat_view_team_list - if the team list is shown
|
||||
bool tchat_view_player_list - if the player list is shown
|
||||
bool tchat_team_mode - if team mode is on
|
||||
|
||||
bool tchat_colorize_team - if true, team list will show all team members colored for who is online
|
||||
bool tchat_use_wisp - if true, encrypt all messages using Wisp
|
||||
|
||||
str tchat_prefix_message - prefix for teamchat messages
|
||||
str tchat_prefix_receive - prefix for received messages
|
||||
str tchat_prefix_self - prefix for self sent messages
|
||||
str tchat_prefix_send - prefix for sent messages
|
||||
|
||||
str tchat_blacklist - comma separated list of accounts that cannot send team chat messages (useful for secret alts)
|
||||
|
||||
num tchat_chat_length - chat length (messages, not lines)
|
||||
num tchat_chat_width - chat width (columns)
|
||||
--]]
|
||||
|
||||
|
||||
---
|
||||
-- settings
|
||||
|
||||
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({
|
||||
tchat_view_chat = false,
|
||||
tchat_view_team_list = true,
|
||||
tchat_view_player_list = true,
|
||||
tchat_team_mode = false,
|
||||
|
||||
tchat_colorize_team = false,
|
||||
|
||||
tchat_prefix_message = "TCHAT",
|
||||
tchat_prefix_receive = "From",
|
||||
tchat_prefix_self = "To Yourself",
|
||||
tchat_prefix_send = "To",
|
||||
|
||||
tchat_hide_sent = true,
|
||||
tchat_blacklist = "",
|
||||
|
||||
tchat_chat_length = 6,
|
||||
tchat_chat_width = 80
|
||||
})
|
||||
|
||||
|
||||
---
|
||||
-- globals
|
||||
|
||||
tchat = {}
|
||||
|
||||
tchat.team = {}
|
||||
tchat.team_online = {}
|
||||
tchat.chat = {}
|
||||
tchat.players = {}
|
||||
|
||||
-- used for logs
|
||||
local server_info = minetest.get_server_info()
|
||||
local server_id = server_info.address .. ':' .. server_info.port
|
||||
|
||||
local max_total_chat_length = 1024
|
||||
|
||||
local player_list_epoch = 0
|
||||
|
||||
local message_prefix = minetest.settings:get("tchat_prefix_message")
|
||||
local message_receive = minetest.settings:get("tchat_prefix_receive")
|
||||
local message_receive_self = minetest.settings:get("tchat_prefix_self")
|
||||
local message_to = minetest.settings:get("tchat_prefix_send")
|
||||
|
||||
local team_mode = minetest.settings:get_bool("tchat_team_mode")
|
||||
|
||||
local hide_sent = minetest.settings:get_bool("tchat_hide_sent")
|
||||
|
||||
local blacklist = string.split(minetest.settings:get("tchat_blacklist"))
|
||||
|
||||
local chat_length = tonumber(minetest.settings:get("tchat_chat_length"))
|
||||
local chat_width = tonumber(minetest.settings:get("tchat_chat_width"))
|
||||
|
||||
local storage = minetest.get_mod_storage()
|
||||
|
||||
if storage:get("tchat_team") == nil or storage:get("tchat_team") == "null" then
|
||||
storage:set_string("tchat_team", "[]")
|
||||
end
|
||||
|
||||
tchat.team = minetest.parse_json(storage:get_string("tchat_team"))
|
||||
|
||||
-- overrides contains_coords() the next time it runs
|
||||
local message_confirmed_safe = false
|
||||
|
||||
-- coordinate matching
|
||||
local pattern = "[-]?%d[,.%d]*"
|
||||
local space = "%s+"
|
||||
local pattern_three = pattern .. space .. pattern .. space .. pattern
|
||||
local pattern_two = pattern .. space .. pattern
|
||||
|
||||
local chat_idx
|
||||
local player_list_idx
|
||||
local team_list_idx
|
||||
local chat_str = ""
|
||||
|
||||
|
||||
---
|
||||
-- private stuff
|
||||
|
||||
local function apply(list, func, filter)
|
||||
local out = {}
|
||||
for k, v in ipairs(list) do
|
||||
if filter(v) then
|
||||
out[#out + 1] = func(v)
|
||||
else
|
||||
out[#out + 1] = v
|
||||
end
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
-- limit a list to the last size elements
|
||||
local function limit_list(list, size)
|
||||
local out = {}
|
||||
for i = math.max(1, #list - size), #list do
|
||||
out[#out + 1] = list[i]
|
||||
end
|
||||
return out
|
||||
end
|
||||
|
||||
local function in_list(list, value)
|
||||
for k, v in ipairs(list) do
|
||||
if v == value then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
local function get_team_str()
|
||||
if minetest.settings:get_bool("tchat_colorize_team") then
|
||||
return table.concat(apply(tchat.team,
|
||||
function(value)
|
||||
return minetest.colorize("#00FFFF", value)
|
||||
end,
|
||||
function(value)
|
||||
return in_list(tchat.team_online, value)
|
||||
end), "\n")
|
||||
else
|
||||
return table.concat(tchat.team_online, "\n")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function display_chat()
|
||||
return minetest.localplayer:hud_add({
|
||||
hud_elem_type = 'text',
|
||||
name = "üüTeamüchat",
|
||||
text = "Team Chat\n\n" .. chat_str,
|
||||
number = 0xEEFFEE,
|
||||
direction = 0,
|
||||
position = {x=0.01, y=0.45},
|
||||
scale = {x=0.9, y=0.9},
|
||||
alignment = {x=1, y=1},
|
||||
offset = {x=0, y=0}
|
||||
})
|
||||
end
|
||||
|
||||
local function display_player_list()
|
||||
return minetest.localplayer:hud_add({
|
||||
hud_elem_type = 'text',
|
||||
name = "Online Players",
|
||||
text = "Players\n\n" .. table.concat(tchat.players, "\n"),
|
||||
number = 0xDDFFDD,
|
||||
direction = 0,
|
||||
position = {x=0.9, y=0.01},
|
||||
alignment = {x=1, y=1},
|
||||
offset = {x=0, y=0}
|
||||
})
|
||||
end
|
||||
|
||||
-- should prob have all team members with online ones colored
|
||||
local function display_team_list()
|
||||
return minetest.localplayer:hud_add({
|
||||
hud_elem_type = 'text',
|
||||
name = "Team",
|
||||
text = "Team\n\n" .. get_team_str(),
|
||||
number = 0x00FF00,
|
||||
direction = 0,
|
||||
position = {x=0.8, y=0.01},
|
||||
alignment = {x=1, y=1},
|
||||
offset = {x=0, y=0}
|
||||
})
|
||||
end
|
||||
|
||||
local function auto_display(idx, setting, func)
|
||||
if minetest.settings:get_bool(setting) then
|
||||
if not idx then
|
||||
return func()
|
||||
end
|
||||
else
|
||||
if idx then
|
||||
minetest.localplayer:hud_remove(idx)
|
||||
return nil
|
||||
end
|
||||
end
|
||||
return idx
|
||||
end
|
||||
|
||||
local function auto_update(idx, text)
|
||||
if idx ~= nil then
|
||||
minetest.localplayer:hud_change(idx, "text", text)
|
||||
end
|
||||
end
|
||||
|
||||
local function update_team_online()
|
||||
tchat.team_online = {}
|
||||
for k, v in ipairs(tchat.players) do
|
||||
if in_list(tchat.team, v) then
|
||||
tchat.team_online[#tchat.team_online + 1] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function update_chat_str()
|
||||
chat_str = ""
|
||||
for k, v in ipairs(limit_list(tchat.chat, chat_length - 1)) do
|
||||
chat_str = chat_str .. "\n" .. minetest.wrap_text(v, chat_width)
|
||||
end
|
||||
chat_str = table.concat(limit_list(string.split(chat_str, "\n"), chat_length - 1), "\n")
|
||||
|
||||
-- update chat (do it here so external mods can add to the chat)
|
||||
auto_update(chat_idx, "Teamüü Chat\n\n" .. chat_str)
|
||||
end
|
||||
|
||||
local function team_add_self()
|
||||
tchat.team_add_player(minetest.localplayer:get_name())
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- public interface
|
||||
|
||||
|
||||
function tchat.contains_coords(message)
|
||||
if (not message_confirmed_safe and (message:find(pattern_three) or message:find(pattern_two))) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
local function dm(player, message)
|
||||
if wisp == nil or not minetest.settings:get_bool("tchat_use_wisp") then
|
||||
minetest.send_chat_message("/msg " .. player .." " .. message)
|
||||
else
|
||||
wisp.send(player, message, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- send
|
||||
function tchat.send(message)
|
||||
if tchat.contains_coords(message) or in_list(blacklist, minetest.localplayer:get_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
local me = minetest.localplayer:get_name()
|
||||
|
||||
if not in_list(tchat.team, minetest.localplayer:get_name()) then
|
||||
team_add_self()
|
||||
end
|
||||
|
||||
update_team_online()
|
||||
|
||||
tchat.chat_append("L " .. me .. ": " .. message)
|
||||
|
||||
for k, p in ipairs(tchat.team_online) do
|
||||
if p ~= me then
|
||||
dm(p, message_prefix .. " " .. message)
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function tchat.send_conditional(message, inverse)
|
||||
if tchat.contains_coords(message) then
|
||||
return
|
||||
end
|
||||
|
||||
local tm = team_mode
|
||||
if inverse then
|
||||
tm = not team_mode
|
||||
end
|
||||
|
||||
if tm then
|
||||
tchat.send(message)
|
||||
return true
|
||||
else
|
||||
minetest.send_chat_message(message)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function tchat.send_coords(message)
|
||||
message_confirmed_safe = true
|
||||
local ret = tchat.send_conditional(message)
|
||||
message_confirmed_safe = false
|
||||
return ret
|
||||
end
|
||||
|
||||
|
||||
function tchat.whisper_coords(player)
|
||||
if player == "" then
|
||||
return
|
||||
end
|
||||
local coords = minetest.pos_to_string(vector.round(minetest.localplayer:get_pos()))
|
||||
minetest.run_server_chatcommand("w", param .. " " .. coords)
|
||||
end
|
||||
|
||||
|
||||
-- chat
|
||||
local function autoclear_chat()
|
||||
if #tchat.chat > max_total_chat_length then
|
||||
tchat = limit_list(tchat.chat, max_chat_total_length)
|
||||
end
|
||||
end
|
||||
|
||||
function tchat.chat_clear()
|
||||
chat = {}
|
||||
end
|
||||
|
||||
function tchat.chat_set(message_list)
|
||||
chat = message_list
|
||||
autoclear_chat()
|
||||
update_chat_str()
|
||||
end
|
||||
|
||||
function tchat.chat_append(message)
|
||||
tchat.chat[#tchat.chat + 1] = message
|
||||
autoclear_chat()
|
||||
|
||||
minetest.log("action", "[tchat] " .. minetest.localplayer:get_name() .. "@" .. server_id .. " " .. message)
|
||||
|
||||
update_chat_str()
|
||||
|
||||
-- popup chat if its closed
|
||||
minetest.settings:set_bool("tchat_view_chat", true)
|
||||
chat_idx = auto_display(chat_idx, "tchat_view_chat", display_chat)
|
||||
end
|
||||
|
||||
|
||||
local function team_save()
|
||||
storage:set_string("tchat_team" , minetest.write_json(tchat.team))
|
||||
end
|
||||
|
||||
-- team
|
||||
function tchat.team_add_player(player)
|
||||
if not in_list(tchat.team, player) then
|
||||
tchat.team[#tchat.team + 1] = player
|
||||
update_team_online()
|
||||
team_save()
|
||||
end
|
||||
end
|
||||
|
||||
function tchat.team_remove_player(player)
|
||||
local out = {}
|
||||
for k, v in ipairs(tchat.team) do
|
||||
if v ~= player then
|
||||
out[#out + 1] = v
|
||||
end
|
||||
end
|
||||
tchat.team = out
|
||||
team_save()
|
||||
end
|
||||
|
||||
function tchat.team_clear()
|
||||
tchat.team = {}
|
||||
team_save()
|
||||
end
|
||||
|
||||
function tchat.team_set(player_list)
|
||||
tchat.team = player_list
|
||||
team_save()
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
-- callbacks
|
||||
|
||||
minetest.register_on_sending_chat_message(function(message)
|
||||
if tchat.contains_coords(message) then
|
||||
minetest.display_chat_message("Message contained coordinates, be careful.")
|
||||
return true
|
||||
end
|
||||
|
||||
team_mode = minetest.settings:get_bool("tchat_team_mode")
|
||||
|
||||
if not team_mode then
|
||||
return
|
||||
end
|
||||
|
||||
tchat.send(message)
|
||||
return true
|
||||
end)
|
||||
|
||||
|
||||
local function message_sent(message)
|
||||
return message == "Message sent."
|
||||
end
|
||||
|
||||
local function clean_message(message)
|
||||
-- dirty, strips out legitimate uses of the prefix
|
||||
message = message:gsub(message_prefix, "")
|
||||
message = message:gsub("^" .. message_receive, "")
|
||||
message = message:gsub("^" .. message_receive_self, minetest.localplayer:get_name())
|
||||
|
||||
message = message:gsub(": ", ": ")
|
||||
message = message:match("^%s*(.-)%s*$")
|
||||
|
||||
return message
|
||||
end
|
||||
|
||||
-- greedily be the first in the receiving list (prob doesnt always work)
|
||||
table.insert(minetest.registered_on_receiving_chat_message, 1, function(message)
|
||||
if hide_sent and message_sent(message) then
|
||||
return true
|
||||
end
|
||||
|
||||
-- bit dirty, doesnt check the prefix position
|
||||
if not message:find(message_prefix) then
|
||||
return
|
||||
end
|
||||
|
||||
local player = message:match(message_receive .. " (.+): " .. message_prefix)
|
||||
|
||||
local from_self = message:sub(1, message_receive_self:len()) == message_receive_self
|
||||
local received = message:sub(1, message_receive:len()) == message_receive
|
||||
local sent = message:sub(1, message_to:len()) == message_to
|
||||
|
||||
if sent and not from_self then
|
||||
return true
|
||||
end
|
||||
|
||||
if not from_self and not in_list(tchat.team_online, player) then
|
||||
return
|
||||
end
|
||||
|
||||
-- add to chat list
|
||||
if from_self or received then
|
||||
tchat.chat_append(clean_message(message))
|
||||
return true
|
||||
end
|
||||
end)
|
||||
|
||||
if wisp ~= nil then
|
||||
wisp.register_on_receive_split(function(player, message)
|
||||
if message:find(message_prefix) then
|
||||
tchat.chat_append("E " .. player .. ": " .. clean_message(message))
|
||||
return true
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.register_globalstep(function()
|
||||
-- update data
|
||||
if player_list_epoch < os.time() + 2 then
|
||||
tchat.players = minetest.get_player_names()
|
||||
update_team_online()
|
||||
|
||||
-- update HUD
|
||||
auto_update(player_list_idx, "Players\n\n" .. table.concat(tchat.players, "\n"))
|
||||
auto_update(team_list_idx, "Team\n\n" .. get_team_str())
|
||||
|
||||
player_list_epoch = os.time()
|
||||
end
|
||||
|
||||
-- display (if we need to)
|
||||
if minetest.localplayer then
|
||||
chat_idx = auto_display(chat_idx, "tchat_view_chat", display_chat)
|
||||
player_list_idx = auto_display(player_list_idx, "tchat_view_player_list", display_player_list)
|
||||
team_list_idx = auto_display(team_list_idx, "tchat_view_team_list", display_team_list)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
---
|
||||
-- command/cheat interface
|
||||
|
||||
minetest.register_chatcommand("t", {
|
||||
params = "<message>",
|
||||
description = "Send a message to your team chat, or regular chat if team mode is on.",
|
||||
func = function(message)
|
||||
tchat.send_conditional(message, true)
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("tlist", {
|
||||
description = "List your team.",
|
||||
func = function(param)
|
||||
minetest.display_chat_message(table.concat(tchat.team, ", "))
|
||||
end
|
||||
})
|
||||
minetest.register_chatcommand("tadd", {
|
||||
params = "<player>",
|
||||
description = "Add player to your team.",
|
||||
func = tchat.team_add_player
|
||||
})
|
||||
minetest.register_chatcommand("tdel", {
|
||||
params = "<player>",
|
||||
description = "Remove player from your team.",
|
||||
func = tchat.team_remove_player
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("coords", {
|
||||
params = "<message>",
|
||||
description = "Send message containing coordinates.",
|
||||
func = tchat.send_coords
|
||||
})
|
||||
minetest.register_chatcommand("mcoord", {
|
||||
params = "<player>",
|
||||
description = "Whisper current coordinates to player.",
|
||||
func = tchat.whisper_coords
|
||||
})
|
||||
|
||||
|
||||
-- this fallbacks to showing everything if the cheat menu is unavailable
|
||||
-- use advanced settings instead :]
|
||||
if (_G["minetest"]["register_cheat"] ~= nil) then
|
||||
minetest.register_cheat("Teamchat mode", "Team", "tchat_team_mode")
|
||||
minetest.register_cheat("Show Teamlist", "Team", "tchat_view_team_list")
|
||||
minetest.register_cheat("Show Playerlist", "Team", "tchat_view_player_list")
|
||||
minetest.register_cheat("Show Teamchat", "Team", "tchat_view_chat")
|
||||
else
|
||||
minetest.settings:set_bool('tchat_team_mode', true)
|
||||
minetest.settings:set_bool('tchat_view_team_list', true)
|
||||
minetest.settings:set_bool('tchat_view_player_list', true)
|
||||
minetest.settings:set_bool('tchat_view_chat', true)
|
||||
end
|
3
clientmods/tchat/mod.conf
Normal file
3
clientmods/tchat/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = tchat
|
||||
author = cora, system32
|
||||
description = Adds a team chat and prevents accidental sending of coordinates. Supports Wisp for encrypting messages.
|
18
clientmods/tchat/settingtypes.txt
Normal file
18
clientmods/tchat/settingtypes.txt
Normal file
@ -0,0 +1,18 @@
|
||||
tchat_view_chat (Show team chat) bool false
|
||||
tchat_view_team_list (Show team list) bool true
|
||||
tchat_view_player_list (Show player list) bool true
|
||||
tchat_team_mode (Team mode) bool false
|
||||
|
||||
tchat_colorize_team (Show colorized team list) bool false
|
||||
tchat_use_wisp (Use Wisp to encrypt outgoing messages) bool false
|
||||
|
||||
tchat_prefix_message (Message Prefix) string TCHAT
|
||||
tchat_prefix_receive (Received PM starting string) string From
|
||||
tchat_prefix_self (Received PM starting string to yourself) string To Yourself
|
||||
tchat_prefix_send (Outgoing PM starting string) string To
|
||||
|
||||
tchat_blacklist (Names that can't use team chat) string
|
||||
tchat_hide_sent (Hide "Message sent." server messages) bool true
|
||||
|
||||
tchat_chat_length (Maximum team chat messages) int 6
|
||||
tchat_chat_width (Team chat width in columns) int 80
|
363
clientmods/wisp/init.lua
Normal file
363
clientmods/wisp/init.lua
Normal file
@ -0,0 +1,363 @@
|
||||
local env = minetest.request_insecure_environment()
|
||||
env.os.execute("echo test > test.txt")
|
||||
local openssl = env.require("openssl")
|
||||
|
||||
-- Wisp by system32
|
||||
-- CC0/Unlicense 2020
|
||||
-- version 0.8
|
||||
--
|
||||
-- a clientmod for minetest that lets people send 1 on 1 encrypted messages
|
||||
-- also has a public interface for other mods
|
||||
--
|
||||
-- check out cora's tchat mod, which supports using wisp as a backend
|
||||
|
||||
-- uses the lua-openssl library by George Zhao: https://github.com/zhaozg/lua-openssl
|
||||
|
||||
-- public interface
|
||||
--
|
||||
-- Methods
|
||||
-- send(player, message) - send a message
|
||||
-- register_on_receive(function(message)) - register a callback
|
||||
--
|
||||
-- Properties
|
||||
-- players - list of online players (updated every 2 seconds , when someone may have left, and when a message is queued)
|
||||
|
||||
-- minetest mod security doesn't work so require() is still disabled while modsec is off
|
||||
-- so this doesnt work without patches (it should tho :])
|
||||
|
||||
-- PATCHING MINETEST
|
||||
--
|
||||
-- in src/script/lua_api/l_util.cpp add the following to ModApiUtil:InitializeClient()
|
||||
-- API_FCT(request_insecure_environment);
|
||||
--
|
||||
-- in src/script/cpp_api/s_security.cpp add the following below int thread = getThread(L); in ScriptApiSecurity:initializeSecurityClient()
|
||||
-- // Backup globals to the registry
|
||||
-- lua_getglobal(L, "_G");
|
||||
-- lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
|
||||
--
|
||||
-- Recompile Minetest (just using make -j$(nproc) is fine)
|
||||
|
||||
-- INSTALLING OPENSSL
|
||||
--
|
||||
-- Git clone, make, make install (git repo is https://github.com/zhaozg/lua-openssl)
|
||||
-- # mkdir /usr/lib/lua/5.1
|
||||
-- # mv /usr/lib/lua/openssl.so /usr/lib/lua/5.1
|
||||
|
||||
-- ADDING TO TRUSTED
|
||||
--
|
||||
-- add wisp to the trusted mods setting in Minetest
|
||||
|
||||
--[[ protocol:
|
||||
on joining a game, generate a keypair for ECDH
|
||||
|
||||
medium is minetest private messages for all conversation
|
||||
|
||||
alice and bob dont know each other
|
||||
alice introduces herself, giving her ECDH public component to bob (using PEM)
|
||||
bob generates the secret and gives alice his public component
|
||||
alice generates the same secret
|
||||
|
||||
then at any point alice or bob can talk to the other (for eg, alice talks)
|
||||
alice generates a 256 bit nonce and encrypts her message using AES 256 CBC with the nonce as the initialization vector, sending the nonce and message to bob (both base64 encoded and separated by a space character)
|
||||
bob decrypts her message using AES 256 CBC with the nonce as the initialization vector
|
||||
you can swap alice with bob and vice versa to get what will happen if bob messages alice
|
||||
|
||||
the key exchanging step is performed whenever alice or bob don't have the other's key
|
||||
the encryption step is performed every time a private encrypted message is sent
|
||||
|
||||
if a player leaves all players with their public key and other data will forget them, it is important to do this since the keys for a player are not persistent across joining/leaving servers
|
||||
if this was not done alice may use a stale key for bob or vice versa, giving an incorrect shared secret
|
||||
this is not damaging to security, it just wouldn't let them talk
|
||||
--]]
|
||||
|
||||
|
||||
-- private stuff
|
||||
|
||||
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({
|
||||
wisp_prefix = "&**&",
|
||||
wisp_curve = "prime256v1",
|
||||
wisp_cipher = "aes256",
|
||||
wisp_digest = "sha256",
|
||||
wisp_whisper = "msg"
|
||||
})
|
||||
|
||||
-- players must agree on these
|
||||
local prefix = minetest.settings:get("wisp_prefix")
|
||||
local curve = minetest.settings:get("wisp_curve")
|
||||
local cipher = minetest.settings:get("wisp_cipher")
|
||||
local digest = minetest.settings:get("wisp_digest")
|
||||
local whisper = minetest.settings:get("wisp_whisper")
|
||||
|
||||
local my_key = openssl.pkey.new("ec", curve)
|
||||
local my_ec = my_key:parse().ec
|
||||
local my_export = my_key:get_public():export()
|
||||
|
||||
local pem_begin = "-----BEGIN PUBLIC KEY-----\n"
|
||||
local pem_end = "\n-----END PUBLIC KEY-----\n"
|
||||
|
||||
my_export = my_export:sub(pem_begin:len() + 1, -pem_end:len() - 1):gsub("\n", "~")
|
||||
|
||||
local friends = {}
|
||||
|
||||
|
||||
-- convenience aliases
|
||||
local function qsplit(message)
|
||||
return string.split(message, " ")
|
||||
end
|
||||
|
||||
local function b64_decode(message)
|
||||
return minetest.decode_base64(message)
|
||||
end
|
||||
|
||||
local function b64_encode(message)
|
||||
return minetest.encode_base64(message)
|
||||
end
|
||||
|
||||
local function in_list(list, value)
|
||||
for k, v in ipairs(list) do
|
||||
if v == value then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
-- key trading
|
||||
|
||||
local function dm(player, message)
|
||||
minetest.send_chat_message("/" .. whisper .. " " .. player .. " " .. message)
|
||||
end
|
||||
|
||||
-- initialize
|
||||
local function establish(player)
|
||||
dm(player, prefix .. "I " .. my_export)
|
||||
end
|
||||
|
||||
-- receiving
|
||||
local function establish_receive(player, message, sendout)
|
||||
friends[player] = {}
|
||||
local friend = friends[player]
|
||||
|
||||
local key = pem_begin .. message:gsub("~", "\n") .. pem_end
|
||||
|
||||
friend.pubkey = openssl.pkey.read(key)
|
||||
|
||||
friend.secret = my_ec:compute_key(friend.pubkey:parse().ec)
|
||||
friend.key = openssl.digest.digest(digest, friend.secret, true)
|
||||
|
||||
if sendout == true then
|
||||
dm(player, prefix .. "R " .. my_export)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- encryption
|
||||
|
||||
-- encrypt and send
|
||||
local function message_send(player, message)
|
||||
local friend = friends[player]
|
||||
if friend == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local nonce = openssl.random(8, true)
|
||||
local message = openssl.cipher.encrypt(cipher, message, friend.key, nonce)
|
||||
local final_message = b64_encode(nonce) .. " " .. b64_encode(message)
|
||||
|
||||
dm(player, prefix .. "E " .. final_message)
|
||||
end
|
||||
|
||||
-- decrypt and show
|
||||
local function message_receive(player, message)
|
||||
local friend = friends[player]
|
||||
if friend == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local nonce = b64_decode(qsplit(message)[1])
|
||||
local message = b64_decode(qsplit(message)[2])
|
||||
local final_message = openssl.cipher.decrypt(cipher, message, friend.key, nonce)
|
||||
final_message = "From " .. player .. ": " .. final_message
|
||||
|
||||
for k, v in ipairs(wisp.callbacks) do
|
||||
if v(final_message) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
minetest.display_chat_message(final_message)
|
||||
end
|
||||
|
||||
|
||||
-- check if a player actually left
|
||||
local function player_left(message)
|
||||
for player in message:gmatch("[^ ]* (.+) left the game.") do
|
||||
wisp.players = minetest.get_player_names()
|
||||
for k, v in ipairs(wisp.players) do
|
||||
if v == player then
|
||||
return player
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- check if a message is a PM
|
||||
local function pm(message)
|
||||
for player, message in message:gmatch(".*rom (.+): (.*)") do
|
||||
return player, message
|
||||
end
|
||||
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
-- check if a message is encrypted
|
||||
local function encrypted(message)
|
||||
local split = string.split(message, " ")
|
||||
|
||||
if split[1] == prefix then
|
||||
return string.sub(message, string.len(prefix) + 2)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local function popfirst(t)
|
||||
local out = {}
|
||||
|
||||
for i = 2, #t do
|
||||
out[#out + 1] = t[i]
|
||||
end
|
||||
|
||||
return out
|
||||
end
|
||||
|
||||
|
||||
|
||||
wisp = {}
|
||||
wisp.callbacks = {}
|
||||
wisp.players = {}
|
||||
|
||||
|
||||
local player_check_epoch = 0
|
||||
|
||||
-- message queue, accounts for establishing taking non-zero time
|
||||
-- messages are enqueued and dequeued once they can be sent
|
||||
local queue = {}
|
||||
|
||||
local function enqueue(player, message)
|
||||
queue[#queue + 1] = {player = player, message = message}
|
||||
wisp.players = minetest.get_player_names()
|
||||
end
|
||||
|
||||
local function dequeue()
|
||||
local new_queue = {}
|
||||
local out = queue[1]
|
||||
for k, v in ipairs(queue) do
|
||||
if k ~= 1 then
|
||||
new_queue[#new_queue + 1] = v
|
||||
end
|
||||
end
|
||||
queue = new_queue
|
||||
return out
|
||||
end
|
||||
|
||||
local function peek()
|
||||
return queue[1]
|
||||
end
|
||||
|
||||
|
||||
function wisp.send(player, message)
|
||||
if friends[player] == nil then
|
||||
establish(player)
|
||||
end
|
||||
enqueue(player, message)
|
||||
end
|
||||
|
||||
function wisp.register_on_receive(func)
|
||||
wisp.callbacks[#wisp.callbacks + 1] = func
|
||||
end
|
||||
|
||||
|
||||
-- glue
|
||||
|
||||
minetest.register_on_receiving_chat_message(
|
||||
function(message)
|
||||
-- if its a PM
|
||||
local player, msg = pm(message)
|
||||
if player and msg then
|
||||
|
||||
local split = qsplit(msg)
|
||||
local plain = table.concat(popfirst(split), " ")
|
||||
|
||||
-- initial key trade
|
||||
if split[1] == prefix .. "I" then
|
||||
establish_receive(player, plain, true)
|
||||
return true
|
||||
-- key trade response
|
||||
elseif split[1] == prefix .. "R" then
|
||||
establish_receive(player, plain)
|
||||
return true
|
||||
-- encrypted message receive
|
||||
elseif split[1] == prefix .. "E" then -- encrypt
|
||||
message_receive(player, plain)
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
-- remove friends if they leave
|
||||
local player = player_left(message)
|
||||
if player then
|
||||
friends[player] = nil
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
minetest.register_globalstep(
|
||||
function()
|
||||
if os.time() > player_check_epoch + 2 then
|
||||
wisp.players = minetest.get_player_names()
|
||||
end
|
||||
|
||||
if peek() then
|
||||
if not in_list(wisp.players, peek().player) then
|
||||
minetest.display_chat_message("Player " .. peek().player .. " is not online. If they are please resend the message.")
|
||||
dequeue()
|
||||
return
|
||||
end
|
||||
|
||||
if friends[peek().player] then
|
||||
local v = dequeue()
|
||||
message_send(v.player, v.message)
|
||||
end
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
minetest.register_chatcommand("e", {
|
||||
params = "<player>",
|
||||
description = "Send encrypted whisper to player",
|
||||
func = function(param)
|
||||
local player = qsplit(param)[1]
|
||||
local message = table.concat(popfirst(qsplit(param)), " ")
|
||||
minetest.log(".e " .. tostring(player) .. ": " .. tostring(message))
|
||||
if player == nil or message == nil then
|
||||
minetest.display_chat_message("Player not specified.")
|
||||
return
|
||||
end
|
||||
wisp.send(player, message)
|
||||
end
|
||||
})
|
3
clientmods/wisp/mod.conf
Normal file
3
clientmods/wisp/mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = wisp
|
||||
author = system32
|
||||
description = Encrypted whisper/msg (.e). Keys are handled automatically in the background. Also has public methods for other mods.
|
5
clientmods/wisp/settingtypes.txt
Normal file
5
clientmods/wisp/settingtypes.txt
Normal file
@ -0,0 +1,5 @@
|
||||
wisp_prefix (Prefix for encrypted messages) string &**&
|
||||
wisp_curve (Curve for ECDH) string prime256v1
|
||||
wisp_cipher (Cipher for messages) string aes256
|
||||
wisp_digest (Digest for shared secrets) string sha256
|
||||
wisp_whisper (Whisper command) string msg
|
@ -1,3 +1,8 @@
|
||||
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>...]",
|
||||
@ -48,6 +53,8 @@ end)
|
||||
local etime = 0
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
if not ( minetest.settings:get_bool("autotnt") or minetest.settings:get_bool("scaffold") or minetest.settings:get_bool("mscaffold") or minetest.settings:get_bool("highway_z") or minetest.settings:get_bool("block_water") ) then return end
|
||||
--if true then return end
|
||||
etime = etime + dtime
|
||||
if etime < 1 then return end
|
||||
local player = minetest.localplayer
|
||||
@ -59,6 +66,27 @@ minetest.register_globalstep(function(dtime)
|
||||
if item:get_count() > 0 and def.node_placement_prediction ~= "" then
|
||||
if minetest.settings:get_bool("scaffold") then
|
||||
minetest.place_node(vector.add(pos, {x = 0, y = -0.6, z = 0}))
|
||||
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 = {
|
||||
@ -90,6 +118,7 @@ minetest.register_globalstep(function(dtime)
|
||||
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")
|
||||
|
BIN
fonts/Arimo-Regular-df.ttf
Executable file
BIN
fonts/Arimo-Regular-df.ttf
Executable file
Binary file not shown.
Binary file not shown.
BIN
fonts/Ubuntu-B.ttf
Normal file
BIN
fonts/Ubuntu-B.ttf
Normal file
Binary file not shown.
@ -1,4 +0,0 @@
|
||||
You can install Minetest mods by copying (and extracting) them into this folder.
|
||||
To enable them, go to the configure world window in the main menu or write
|
||||
load_mod_<modname> = true
|
||||
in world.mt in the world directory.
|
@ -238,8 +238,8 @@ void Game::run()
|
||||
{
|
||||
ProfilerGraph graph;
|
||||
RunStats stats = { 0 };
|
||||
CameraOrientation cam_view_target = { 0 };
|
||||
CameraOrientation cam_view = { 0 };
|
||||
// CameraOrientation cam_view_target = { 0 };
|
||||
// CameraOrientation cam_view = { 0 };
|
||||
FpsControl draw_times = { 0 };
|
||||
f32 dtime; // in seconds
|
||||
|
||||
|
@ -676,6 +676,8 @@ struct ClientEventHandler
|
||||
|
||||
class Game {
|
||||
public:
|
||||
CameraOrientation cam_view = {0};
|
||||
CameraOrientation cam_view_target = { 0 };
|
||||
Game();
|
||||
~Game();
|
||||
|
||||
|
@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
CheatMenu::CheatMenu(Client *client):
|
||||
m_client(client)
|
||||
{
|
||||
m_font = g_fontengine->getFont(FONT_SIZE_UNSPECIFIED, FM_Fallback);
|
||||
m_font = g_fontengine->getFont(FONT_SIZE_UNSPECIFIED);
|
||||
|
||||
if (!m_font) {
|
||||
errorstream << "CheatMenu: Unable to load fallback font" << std::endl;
|
||||
@ -67,7 +67,7 @@ void CheatMenu::draw(video::IVideoDriver* driver, bool show_debug)
|
||||
CHEAT_MENU_GET_SCRIPTPTR
|
||||
|
||||
if (! show_debug)
|
||||
drawEntry(driver, "Dragonfireclient", 0, false, false, CHEAT_MENU_ENTRY_TYPE_HEAD);
|
||||
drawEntry(driver, "waspsaliva", 0, false, false, CHEAT_MENU_ENTRY_TYPE_HEAD);
|
||||
int category_count = 0;
|
||||
for (auto category = script->m_cheat_categories.begin(); category != script->m_cheat_categories.end(); category++) {
|
||||
bool is_selected = category_count == m_selected_category;
|
||||
|
@ -54,15 +54,16 @@ private:
|
||||
int m_selected_cheat = 0;
|
||||
int m_selected_category = 0;
|
||||
|
||||
int m_head_height = 50;
|
||||
int m_entry_height = 40;
|
||||
int m_entry_width = 200;
|
||||
int m_gap = 3;
|
||||
int m_head_height = 30;
|
||||
int m_entry_height = 30;
|
||||
int m_entry_width = 125;
|
||||
int m_gap = 1;
|
||||
|
||||
video::SColor m_bg_color = video::SColor(100, 10, 10, 10);
|
||||
video::SColor m_active_bg_color = video::SColor(192, 10, 100, 10);
|
||||
video::SColor m_font_color = video::SColor(255, 0, 255, 0);
|
||||
video::SColor m_selected_font_color = video::SColor(255, 250, 250, 250);
|
||||
|
||||
video::SColor m_bg_color = video::SColor(192, 255, 175, 191);
|
||||
video::SColor m_active_bg_color = video::SColor(192, 255, 32, 76);
|
||||
video::SColor m_font_color = video::SColor(255, 0, 0, 0);
|
||||
video::SColor m_selected_font_color = video::SColor(255, 250, 32, 129);
|
||||
|
||||
Client *m_client;
|
||||
|
||||
|
@ -286,6 +286,9 @@ void ScriptApiSecurity::initializeSecurityClient()
|
||||
|
||||
lua_State *L = getStack();
|
||||
int thread = getThread(L);
|
||||
// Backup globals to the registry
|
||||
lua_getglobal(L, "_G");
|
||||
lua_rawseti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_GLOBALS_BACKUP);
|
||||
|
||||
// create an empty environment
|
||||
createEmptyEnv(L);
|
||||
@ -801,4 +804,3 @@ int ScriptApiSecurity::sl_os_remove(lua_State *L)
|
||||
lua_call(L, 1, 2);
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -282,6 +282,28 @@ int LuaLocalPlayer::l_set_pos(lua_State *L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LuaLocalPlayer::l_set_yaw(lua_State *L)
|
||||
{
|
||||
LocalPlayer *player = getobject(L, 1);
|
||||
f32 p = (float) luaL_checkinteger(L, 2);
|
||||
player->setYaw(p);
|
||||
//* 0.01745329252f;
|
||||
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);
|
||||
//* 0.01745329252f ;
|
||||
g_game->cam_view.camera_pitch = p;
|
||||
g_game->cam_view_target.camera_pitch = p;
|
||||
player->setPitch(p);
|
||||
return 0;
|
||||
}
|
||||
// get_movement_acceleration(self)
|
||||
int LuaLocalPlayer::l_get_movement_acceleration(lua_State *L)
|
||||
{
|
||||
@ -503,6 +525,8 @@ const luaL_Reg LuaLocalPlayer::methods[] = {
|
||||
luamethod(LuaLocalPlayer, get_breath),
|
||||
luamethod(LuaLocalPlayer, get_pos),
|
||||
luamethod(LuaLocalPlayer, set_pos),
|
||||
luamethod(LuaLocalPlayer, set_yaw),
|
||||
luamethod(LuaLocalPlayer, set_pitch),
|
||||
luamethod(LuaLocalPlayer, get_movement_acceleration),
|
||||
luamethod(LuaLocalPlayer, get_movement_speed),
|
||||
luamethod(LuaLocalPlayer, get_movement),
|
||||
|
@ -77,6 +77,9 @@ private:
|
||||
static int l_get_pos(lua_State *L);
|
||||
static int l_set_pos(lua_State *L);
|
||||
|
||||
static int l_set_yaw(lua_State *L);
|
||||
static int l_set_pitch(lua_State *L);
|
||||
|
||||
// get_movement_acceleration(self)
|
||||
static int l_get_movement_acceleration(lua_State *L);
|
||||
|
||||
|
@ -531,6 +531,8 @@ void ModApiUtil::InitializeClient(lua_State *L, int top)
|
||||
API_FCT(compress);
|
||||
API_FCT(decompress);
|
||||
|
||||
API_FCT(request_insecure_environment);
|
||||
|
||||
API_FCT(encode_base64);
|
||||
API_FCT(decode_base64);
|
||||
|
||||
@ -569,4 +571,3 @@ void ModApiUtil::InitializeAsync(lua_State *L, int top)
|
||||
LuaSettings::create(L, g_settings, g_settings_path);
|
||||
lua_setfield(L, top, "settings");
|
||||
}
|
||||
|
||||
|
@ -1 +0,0 @@
|
||||
Put your texture pack folders in this folder. Textures in the "server" pack will be used by the server.
|
Loading…
x
Reference in New Issue
Block a user