This commit is contained in:
1F616EMO 2023-08-28 11:02:04 +08:00
parent 44e6ec4a74
commit fcf1ba988c
No known key found for this signature in database
GPG Key ID: EF52EFA8E05859B2
22 changed files with 714 additions and 1 deletions

12
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,12 @@
{
"Lua.diagnostics.globals": [
"rp_nodes",
"minetest",
"rp_core",
"VoxelArea",
"vector",
"VoxelManip",
"dump",
"ItemStack"
]
}

21
LICENSE.md Normal file
View File

@ -0,0 +1,21 @@
## License of the code
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
## License of media
All of them are CC BY-SA 4.0 or later unless other specified.
License URl: https://creativecommons.org/licenses/by-sa/4.0/

View File

@ -1 +1,3 @@
# r_place
# r/place on Minetest
This game provids a canvas for pixel painting. Inspired by [Minetest r/place mod on Reddit](https://www.reddit.com/r/Minetest/comments/1608nhe/minetest_rplace_mod/), but not taking any source codes from it.

5
game.conf Normal file
View File

@ -0,0 +1,5 @@
name = r_place
title = rPlace
description = Reddit place in Minetest
allowed_mapgens = singlenode
disabled_settings = enable_damage, !creative_mode

BIN
menu/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

183
mods/rp_core/border.lua Normal file
View File

@ -0,0 +1,183 @@
-- r_place/mods/rp_core/mapgen.lua
-- Handle border generation
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
local function v(x,z)
return vector.new(x,1,z)
end
local WP = minetest.get_worldpath()
local NEW_BORDER
-- ^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]?%s*%)()
do
local BORDER_POS1_SETTINGS = minetest.settings:get("r_place.area_pos1") or "(30,30)"
local BORDER_POS2_SETTINGS = minetest.settings:get("r_place.area_pos2") or "(-30,-30)"
local BORDER_POS1x, BORDER_POS1z = string.match(
BORDER_POS1_SETTINGS,
"^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]?%s*%)()"
)
local BORDER_POS2x, BORDER_POS2z = string.match(
BORDER_POS2_SETTINGS,
"^%s*%(%s*([^%s,]+)%s*[,%s]%s*([^%s,]+)%s*[,%s]?%s*%)()"
)
BORDER_POS1x, BORDER_POS1z = tonumber(BORDER_POS1x), tonumber(BORDER_POS1z)
BORDER_POS2x, BORDER_POS2z = tonumber(BORDER_POS2x), tonumber(BORDER_POS2z)
if not (BORDER_POS1x and BORDER_POS1z and BORDER_POS2x and BORDER_POS2z) then
error("[rp_core] Please pass valid coordinates into r_place.area_pos{1,2}!")
end
NEW_BORDER = {
{
BORDER_POS1x < BORDER_POS2x and BORDER_POS1x or BORDER_POS2x,
BORDER_POS1z < BORDER_POS2z and BORDER_POS1z or BORDER_POS2z
}, {
BORDER_POS1x >= BORDER_POS2x and BORDER_POS1x or BORDER_POS2x,
BORDER_POS1z >= BORDER_POS2z and BORDER_POS1z or BORDER_POS2z
}
}
end
rp_core.area = NEW_BORDER
minetest.after(0,function()
do -- Clear old barrier and remove out-of-range nodes
local CACHE_PATH = WP .. "/" .. "rp_core_border_cache"
local CACHE_READ = io.open(CACHE_PATH, "r")
if CACHE_READ then
local OLD_BORDER = minetest.deserialize(CACHE_READ:read("*a"))
if OLD_BORDER
and (OLD_BORDER[1][1] ~= NEW_BORDER[1][1]
or OLD_BORDER[1][2] ~= NEW_BORDER[1][2]
or OLD_BORDER[2][1] ~= NEW_BORDER[2][1]
or OLD_BORDER[2][2] ~= NEW_BORDER[2][2]) then
-- Not equal
rp_core.log("action","Removing old area barriers...")
local remove_queue = {}
-- Remove building nodes
for x = OLD_BORDER[1][1], OLD_BORDER[2][1], 1 do
for z = OLD_BORDER[1][2], OLD_BORDER[2][2], 1 do
if x < NEW_BORDER[1][1]
or x > NEW_BORDER[2][1]
or z < NEW_BORDER[1][2]
or z > NEW_BORDER[2][2] then
table.insert(remove_queue,{x,z})
end
end
end
-- Remove old border
for x = OLD_BORDER[1][1] - 1, OLD_BORDER[2][1] + 1, 1 do
table.insert(remove_queue,{x,OLD_BORDER[1][2] - 1})
table.insert(remove_queue,{x,OLD_BORDER[2][2] + 1})
end
for z = OLD_BORDER[1][2] - 1, OLD_BORDER[2][2] + 1, 1 do
table.insert(remove_queue,{OLD_BORDER[1][1] - 1,z})
table.insert(remove_queue,{OLD_BORDER[2][1] + 1,z})
end
local VM = VoxelManip()
local pmin, pmax = VM:read_from_map(
v(OLD_BORDER[1][1] - 1,OLD_BORDER[1][2] - 1),
v(OLD_BORDER[2][1] + 1,OLD_BORDER[2][2] + 1)
)
local data = VM:get_data()
local VA = VoxelArea(pmin,pmax)
for _,pos in pairs(remove_queue) do
local vm_i = VA:index(pos[1],1,pos[2])
data[vm_i] = minetest.CONTENT_AIR
end
VM:set_data(data)
VM:calc_lighting()
VM:write_to_map()
minetest.after(1,minetest.fix_light,pmin,pmax)
end
CACHE_READ:close()
end
-- Write back to cache
local CACHE_WRITE = io.open(CACHE_PATH, "w")
if CACHE_WRITE then
CACHE_WRITE:write(minetest.serialize(NEW_BORDER))
CACHE_WRITE:close()
end
end
do -- Construct area
rp_core.log("action","Constructing area")
local CONTENT_BORDER = minetest.get_content_id("rp_mapgen_nodes:border")
local CONTENT_FILL = minetest.get_content_id("rp_mapgen_nodes:default_fill")
local CONTENT_AIR = minetest.CONTENT_AIR
local CONTENT_IGNORE = minetest.CONTENT_IGNORE
local VM = VoxelManip()
local pmin, pmax = VM:read_from_map(
v(NEW_BORDER[1][1] - 1,NEW_BORDER[1][2] - 1),
v(NEW_BORDER[2][1] + 1,NEW_BORDER[2][2] + 1)
)
local data = VM:get_data()
local VA = VoxelArea(pmin,pmax)
for vm_i, d in ipairs(data) do
local pos = VA:position(vm_i)
local x,y,z = pos.x, pos.y, pos.z
if y ~= 1
or x < NEW_BORDER[1][1] - 1
or x > NEW_BORDER[2][1] + 1
or z < NEW_BORDER[1][2] - 1
or z > NEW_BORDER[2][2] + 1 then
data[vm_i] = CONTENT_IGNORE
elseif x == NEW_BORDER[1][1] - 1
or x == NEW_BORDER[2][1] + 1
or z == NEW_BORDER[1][2] - 1
or z == NEW_BORDER[2][2] + 1 then
data[vm_i] = CONTENT_BORDER
elseif d == CONTENT_AIR
or d == CONTENT_IGNORE
or d == CONTENT_BORDER then
data[vm_i] = CONTENT_FILL
else
data[vm_i] = CONTENT_IGNORE
end
end
VM:set_data(data)
VM:write_to_map()
minetest.after(1,minetest.fix_light,pmin,pmax)
end
end)
function rp_core.in_area(pos)
local x, y, z = pos.x, pos.y, pos.z
if y ~= 1
or x < rp_core.area[1][1]
or x > rp_core.area[2][1]
or z < rp_core.area[1][2]
or z > rp_core.area[2][2] then
return false
end
return true
end

61
mods/rp_core/commands.lua Normal file
View File

@ -0,0 +1,61 @@
-- r_place/mods/rp_core/commands.lua
-- Handle chatcommands
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
local S = minetest.get_translator("rp_core")
do
local CONTENT_IGNORE = minetest.CONTENT_IGNORE
local CONTENT_FILL = minetest.get_content_id("rp_mapgen_nodes:default_fill")
minetest.register_chatcommand("reset",{
description = S("Reset the area"),
privs = {server = true},
func = function(name,param)
local VM = VoxelManip()
local minp, maxp = VM:read_from_map(
{
x = rp_core.area[1][1],
y = 1,
z = rp_core.area[1][2]
}, {
x = rp_core.area[2][1],
y = 1,
z = rp_core.area[2][2]
})
local VA = VoxelArea(minp, maxp)
local data = {}
for i in VA:iterp(minp, maxp) do
local pos = VA:position(i)
if rp_core.in_area(pos) then
data[i] = CONTENT_FILL
else
data[i] = CONTENT_IGNORE
end
end
VM:set_data(data)
VM:write_to_map()
minetest.after(0,minetest.fix_light,minp,maxp)
return true, "Map reset"
end
})
end

41
mods/rp_core/init.lua Normal file
View File

@ -0,0 +1,41 @@
-- r_place/mods/rp_core/init.lua
-- Handle area and node placement
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
rp_core = {}
function rp_core.log(lvl,msg)
return minetest.log(lvl,"[rp_core] " .. msg)
end
local MP = minetest.get_modpath("rp_core")
local scripts = {
"player",
"mapgen",
"border",
"placement",
"commands",
}
for _,n in ipairs(scripts) do
dofile(MP .. "/" .. n .. ".lua")
end

42
mods/rp_core/mapgen.lua Normal file
View File

@ -0,0 +1,42 @@
-- r_place/mods/rp_core/mapgen.lua
-- Handle area generation
-- With code from langton/mods/lg_mapgen/init.lua
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
minetest.set_mapgen_setting("mgname", "singlenode", true)
local ID_GROUND = minetest.get_content_id("rp_mapgen_nodes:transparent_ground")
minetest.register_on_generated(function(minp,maxp,seed)
if minp.y > 0 or maxp.y < 0 then return end
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local data = vm:get_data()
local y = 0
for z = minp.z, maxp.z do
for x = minp.x, maxp.x do
data[area:index(x,y,z)] = ID_GROUND
end
end
vm:set_data(data)
vm:calc_lighting()
vm:write_to_map(data)
end)

4
mods/rp_core/mod.conf Normal file
View File

@ -0,0 +1,4 @@
name = rp_core
title = Place: Core
description = Handle area and node placement
depends = rp_nodes, rp_mapgen_nodes

101
mods/rp_core/placement.lua Normal file
View File

@ -0,0 +1,101 @@
-- r_place/mods/rp_core/placement.lua
-- Handle node placement and area protection
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
local deny = {}
local deny_clear = {}
local delay_hud = {}
rp_core.time_delay = tonumber(minetest.settings:get("r_place.delay") or "5") or 5
local time_delay = rp_core.time_delay
local S = minetest.get_translator("rp_core")
minetest.register_privilege("no_delay", {
description = S("Disable build delay"),
give_to_singleplayer = false,
})
do
local old_is_protected = minetest.is_protected
function minetest.is_protected(pos, name)
if deny[name] and (os.time() - deny[name] <= time_delay) then
return true
elseif not rp_core.in_area(pos) then
return true
end
return old_is_protected(pos, name)
end
end
local function hud_loop()
local now = os.time()
for _, player in pairs(minetest.get_connected_players()) do
local name = player:get_player_name()
local text = ""
if deny[name] then
text = string.format("%d seconds left", time_delay + (deny[name] - now))
end
if not delay_hud[name] then
delay_hud[name] = player:hud_add({
hud_elem_type = "text",
position = {x = 1, y = 0},
scale = {x = 100, y = 100},
text = text,
number = 0xFFFFFF,
offset = {x = -6, y = 25},
alignment = {x = -1, y = 3}
})
else
player:hud_change(delay_hud[name], "text", text)
end
end
minetest.after(0.5,hud_loop)
end
minetest.after(0,hud_loop)
minetest.register_on_placenode(function(pos, newnode, placer, oldnode, itemstack, pointed_thing)
if not placer:is_player() then return true end
local name = placer:get_player_name()
if deny_clear[name] then
deny_clear[name]:cancel()
end
if minetest.check_player_privs(name, {no_delay = true}) then
return true
end
deny[name] = os.time()
deny_clear[name] = minetest.after(time_delay, function()
deny[name] = nil
deny_clear[name] = nil
end)
return true
end)
minetest.register_on_leaveplayer(function(player, timed_out)
local name = player:get_player_name()
deny[name] = nil
delay_hud[name] = nil
if deny_clear[name] then
deny_clear[name]:cancel()
deny_clear[name] = nil
end
end)

60
mods/rp_core/player.lua Normal file
View File

@ -0,0 +1,60 @@
-- r_place/mods/rp_core/player.lua
-- Player spawnpoint and hand
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
function minetest.get_spawn_level(x,z)
return 10
end
local list_nodes = {}
for name, def in pairs(minetest.registered_nodes) do
if def.groups and def.groups.rp_nodes == 1 then
list_nodes[#list_nodes + 1] = ItemStack(name)
end
end
local inventory_formspec = table.concat({
"size[8,4]",
"list[current_player;main;0,0;8,4;]"
}, "")
minetest.register_on_joinplayer(function(player, last_login)
local name = player:get_player_name()
-- Spawnpoint
local spawn_pos = {
x = (rp_core.area[1][1] + rp_core.area[2][1]) / 2,
y = 10,
z = (rp_core.area[1][2] + rp_core.area[2][2]) / 2
}
player:set_pos(spawn_pos)
-- Fly
local privs = minetest.get_player_privs(name)
privs.fly = true
minetest.set_player_privs(name,privs)
-- Initial items
local inv = player:get_inventory()
inv:set_list("main",list_nodes)
-- Formspec
player:set_inventory_formspec(inventory_formspec)
end)

View File

@ -0,0 +1,34 @@
-- r_place/mods/rp_initial_message/init.lua
-- Send message when a player joins
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
local S = minetest.get_translator("rp_initial_message")
local function C(msg)
return minetest.colorize("orange", msg)
end
minetest.register_on_joinplayer(function(player, last_login)
local name = player:get_player_name()
minetest.chat_send_player(name, C(S("Welcome to rPlace Minetest Server!")))
minetest.chat_send_player(name, C(S("Here, you can place pixels to form pictures!")))
minetest.chat_send_player(name, C(S("All colors are in your inventory; Press `I` to put them onto the hotbar.")))
end)

View File

@ -0,0 +1,2 @@
name = rp_initial_message
title = rPlace: Initial Message

View File

@ -0,0 +1,54 @@
-- r_place/mods/rp_mapgen_nodes/init.lua
-- Map generation nodes of Place
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
minetest.register_node("rp_mapgen_nodes:transparent_ground", {
description = "(Hack!) Transparent Ground",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
pointable = false,
diggable = false,
is_ground_content = true,
damage_per_second = math.huge,
})
minetest.register_node("rp_mapgen_nodes:noplace", {
description = "(Hack!) Place blocker",
drawtype = "airlike",
paramtype = "light",
sunlight_propagates = true,
pointable = false,
diggable = false,
walkable = true,
is_ground_content = true,
})
minetest.register_node("rp_mapgen_nodes:border", {
description = "(Hack!) Area Border",
tiles = {"rp_nodes_base.png^[colorize:#000000:255"},
pointable = true,
diggable = false,
is_ground_content = false,
damage_per_second = math.huge,
})
-- Black
minetest.register_alias("rp_mapgen_nodes:default_fill","rp_nodes:color_222222")

View File

@ -0,0 +1,4 @@
name = rp_mapgen_nodes
title = Place: Map generation nodes
description = Map generation nodes of Place
depends = rp_nodes

74
mods/rp_nodes/init.lua Normal file
View File

@ -0,0 +1,74 @@
-- r_place/mods/rp_nodes/init.lua
-- Nodes for Place
-- With code from parkour/mods/pkr_nodes/init.lua
--[[
Copyright (C) 2023 1F616EMO
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
USA
]]
rp_nodes = {}
local S = minetest.get_translator("rp_nodes")
rp_nodes.colors = { -- https://lospec.com/palette-list/r-place
["FFFFFF"] = S("White"),
["E4E4E4"] = S("Light grey"),
["888888"] = S("Dark grey"),
["222222"] = S("Black"),
["FFA7D1"] = S("Pink"),
["E50000"] = S("Red"),
["E59500"] = S("Orange"),
["A06A42"] = S("Brown"),
["E5D900"] = S("Yellow"),
["94E044"] = S("Light green"),
["02BE01"] = S("Green"),
["00D3DD"] = S("Cyan"),
["0083C7"] = S("Light blue"),
["0000EA"] = S("Blue"),
["CF6EE4"] = S("Dark pink"),
["820080"] = S("Magenta"),
}
local function on_place(itemstack, placer, pointed_thing)
local iname = itemstack:get_name()
local pnode = minetest.get_node(pointed_thing.under)
local pname = pnode.name
if iname ~= pname then
return minetest.item_place(itemstack, placer, pointed_thing)
end
return itemstack, nil
end
for hex, name in pairs(rp_nodes.colors) do
local alpha = ":200"
if hex == "222222" then
alpha = ":245"
elseif hex == "FFFFFF" then
alpha = ":80"
end
minetest.register_node("rp_nodes:color_" .. hex, {
description = S("@1 building block", name),
tiles = {"rp_nodes_base.png^[colorize:#" .. hex .. alpha},
groups = {rp_nodes = 1},
buildable_to = true,
is_ground_content = false,
node_placement_prediction = "",
on_place = on_place,
})
end

3
mods/rp_nodes/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = rp_nodes
title = Place: Nodes
description = Nodes for Place

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

10
settingtypes.txt Normal file
View File

@ -0,0 +1,10 @@
# Position 1 of r_place.
# Should in the format of (x,y).
r_place.area_pos1 (Place area position 1) string (30,30)
# Position 2 of r_place.
# Should in the format of (x,y).
r_place.area_pos2 (Place area position 2) string (-30,-30)
# Delay between placements in seconds
r_place.delay (Delay between placements) int 5