Compare commits
4 commits
5ec98f1bbc
...
ec30bad0a9
Author | SHA1 | Date | |
---|---|---|---|
ec30bad0a9 | |||
287cf8f9b8 | |||
bd85d77cc8 | |||
6beb86428d |
410
mods/ENTITIES/mobs_mc/creeper.lua
Normal file
|
@ -0,0 +1,410 @@
|
||||||
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
|
--###################
|
||||||
|
--################### CREEPER
|
||||||
|
--###################
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
mcl_mobs:register_mob("mobs_mc:creeper", {
|
||||||
|
type = "monster",
|
||||||
|
spawn_class = "hostile",
|
||||||
|
spawn_in_group = 1,
|
||||||
|
hp_min = 20,
|
||||||
|
hp_max = 20,
|
||||||
|
xp_min = 5,
|
||||||
|
xp_max = 5,
|
||||||
|
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3},
|
||||||
|
pathfinding = 1,
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "mobs_mc_creeper.b3d",
|
||||||
|
head_swivel = "Head_Control",
|
||||||
|
bone_eye_height = 2.35,
|
||||||
|
curiosity = 2,
|
||||||
|
textures = {
|
||||||
|
{"mobs_mc_creeper.png",
|
||||||
|
"mobs_mc_empty.png"},
|
||||||
|
},
|
||||||
|
visual_size = {x=3, y=3},
|
||||||
|
sounds = {
|
||||||
|
attack = "tnt_ignite",
|
||||||
|
death = "mobs_mc_creeper_death",
|
||||||
|
damage = "mobs_mc_creeper_hurt",
|
||||||
|
fuse = "tnt_ignite",
|
||||||
|
explode = "tnt_explode",
|
||||||
|
distance = 16,
|
||||||
|
},
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
walk_velocity = 1.05,
|
||||||
|
run_velocity = 2.1,
|
||||||
|
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
||||||
|
attack_type = "explode",
|
||||||
|
|
||||||
|
--hssssssssssss
|
||||||
|
|
||||||
|
explosion_strength = 3,
|
||||||
|
explosion_radius = 3.5,
|
||||||
|
explosion_damage_radius = 3.5,
|
||||||
|
explosiontimer_reset_radius = 6,
|
||||||
|
reach = 3,
|
||||||
|
explosion_timer = 5,
|
||||||
|
allow_fuse_reset = true,
|
||||||
|
stop_to_explode = true,
|
||||||
|
|
||||||
|
-- Force-ignite creeper with flint and steel and explode after 1.5 seconds.
|
||||||
|
-- TODO: Make creeper flash after doing this as well.
|
||||||
|
-- TODO: Test and debug this code.
|
||||||
|
on_rightclick = function(self, clicker)
|
||||||
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local item = clicker:get_wielded_item()
|
||||||
|
if item:get_name() == "mcl_fire:flint_and_steel" then
|
||||||
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
|
-- Wear tool
|
||||||
|
local wdef = item:get_definition()
|
||||||
|
item:add_wear(1000)
|
||||||
|
-- Tool break sound
|
||||||
|
if item:get_count() == 0 and wdef.sound and wdef.sound.breaks then
|
||||||
|
minetest.sound_play(wdef.sound.breaks, {pos = clicker:get_pos(), gain = 0.5}, true)
|
||||||
|
end
|
||||||
|
clicker:set_wielded_item(item)
|
||||||
|
end
|
||||||
|
self._forced_explosion_countdown_timer = self.explosion_timer
|
||||||
|
minetest.sound_play(self.sounds.attack, {pos = self.object:get_pos(), gain = 1, max_hear_distance = 16}, true)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
do_custom = function(self, dtime)
|
||||||
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
|
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
||||||
|
if self._forced_explosion_countdown_timer <= 0 then
|
||||||
|
mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_die = function(self, pos, cmi_cause)
|
||||||
|
-- Drop a random music disc when killed by skeleton or stray
|
||||||
|
if cmi_cause and cmi_cause.type == "punch" then
|
||||||
|
local luaentity = cmi_cause.puncher and cmi_cause.puncher:get_luaentity()
|
||||||
|
if luaentity and luaentity.name:find("arrow") then
|
||||||
|
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
|
||||||
|
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
|
||||||
|
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
maxdrops = 2,
|
||||||
|
drops = {
|
||||||
|
{name = "mcl_mobitems:gunpowder",
|
||||||
|
chance = 1,
|
||||||
|
min = 0,
|
||||||
|
max = 2,
|
||||||
|
looting = "common",},
|
||||||
|
|
||||||
|
-- Head
|
||||||
|
-- TODO: Only drop if killed by charged creeper
|
||||||
|
{name = "mcl_heads:creeper",
|
||||||
|
chance = 200, -- 0.5%
|
||||||
|
min = 1,
|
||||||
|
max = 1,},
|
||||||
|
},
|
||||||
|
animation = {
|
||||||
|
speed_normal = 24,
|
||||||
|
speed_run = 48,
|
||||||
|
stand_start = 0,
|
||||||
|
stand_end = 23,
|
||||||
|
walk_start = 24,
|
||||||
|
walk_end = 49,
|
||||||
|
run_start = 24,
|
||||||
|
run_end = 49,
|
||||||
|
hurt_start = 110,
|
||||||
|
hurt_end = 139,
|
||||||
|
death_start = 140,
|
||||||
|
death_end = 189,
|
||||||
|
look_start = 50,
|
||||||
|
look_end = 108,
|
||||||
|
},
|
||||||
|
floats = 1,
|
||||||
|
fear_height = 4,
|
||||||
|
view_range = 16,
|
||||||
|
})
|
||||||
|
|
||||||
|
mcl_mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
|
description = S("Creeper"),
|
||||||
|
type = "monster",
|
||||||
|
spawn_class = "hostile",
|
||||||
|
hp_min = 20,
|
||||||
|
hp_max = 20,
|
||||||
|
xp_min = 5,
|
||||||
|
xp_max = 5,
|
||||||
|
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.69, 0.3},
|
||||||
|
pathfinding = 1,
|
||||||
|
visual = "mesh",
|
||||||
|
mesh = "mobs_mc_creeper.b3d",
|
||||||
|
|
||||||
|
--BOOM
|
||||||
|
|
||||||
|
textures = {
|
||||||
|
{"mobs_mc_creeper.png",
|
||||||
|
"mobs_mc_creeper_charge.png"},
|
||||||
|
},
|
||||||
|
visual_size = {x=3, y=3},
|
||||||
|
sounds = {
|
||||||
|
attack = "tnt_ignite",
|
||||||
|
death = "mobs_mc_creeper_death",
|
||||||
|
damage = "mobs_mc_creeper_hurt",
|
||||||
|
fuse = "tnt_ignite",
|
||||||
|
explode = "tnt_explode",
|
||||||
|
distance = 16,
|
||||||
|
},
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
walk_velocity = 1.05,
|
||||||
|
run_velocity = 2.1,
|
||||||
|
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
||||||
|
attack_type = "explode",
|
||||||
|
|
||||||
|
explosion_strength = 6,
|
||||||
|
explosion_radius = 8,
|
||||||
|
explosion_damage_radius = 8,
|
||||||
|
explosiontimer_reset_radius = 6,
|
||||||
|
reach = 3,
|
||||||
|
explosion_timer = 1.5,
|
||||||
|
allow_fuse_reset = true,
|
||||||
|
stop_to_explode = true,
|
||||||
|
|
||||||
|
-- Force-ignite creeper with flint and steel and explode after 1.5 seconds.
|
||||||
|
-- TODO: Make creeper flash after doing this as well.
|
||||||
|
-- TODO: Test and debug this code.
|
||||||
|
on_rightclick = function(self, clicker)
|
||||||
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local item = clicker:get_wielded_item()
|
||||||
|
if item:get_name() == "mcl_fire:flint_and_steel" then
|
||||||
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
|
-- Wear tool
|
||||||
|
local wdef = item:get_definition()
|
||||||
|
item:add_wear(1000)
|
||||||
|
-- Tool break sound
|
||||||
|
if item:get_count() == 0 and wdef.sound and wdef.sound.breaks then
|
||||||
|
minetest.sound_play(wdef.sound.breaks, {pos = clicker:get_pos(), gain = 0.5}, true)
|
||||||
|
end
|
||||||
|
clicker:set_wielded_item(item)
|
||||||
|
end
|
||||||
|
self._forced_explosion_countdown_timer = self.explosion_timer
|
||||||
|
minetest.sound_play(self.sounds.attack, {pos = self.object:get_pos(), gain = 1, max_hear_distance = 16}, true)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
do_custom = function(self, dtime)
|
||||||
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
|
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
||||||
|
if self._forced_explosion_countdown_timer <= 0 then
|
||||||
|
mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
on_die = function(self, pos, cmi_cause)
|
||||||
|
-- Drop a random music disc when killed by skeleton or stray
|
||||||
|
if cmi_cause and cmi_cause.type == "punch" then
|
||||||
|
local luaentity = cmi_cause.puncher and cmi_cause.puncher:get_luaentity()
|
||||||
|
if luaentity and luaentity.name:find("arrow") then
|
||||||
|
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
|
||||||
|
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
|
||||||
|
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
maxdrops = 2,
|
||||||
|
drops = {
|
||||||
|
{name = "mcl_mobitems:gunpowder",
|
||||||
|
chance = 1,
|
||||||
|
min = 0,
|
||||||
|
max = 2,
|
||||||
|
looting = "common",},
|
||||||
|
|
||||||
|
-- Head
|
||||||
|
-- TODO: Only drop if killed by charged creeper
|
||||||
|
{name = "mcl_heads:creeper",
|
||||||
|
chance = 200, -- 0.5%
|
||||||
|
min = 1,
|
||||||
|
max = 1,},
|
||||||
|
},
|
||||||
|
animation = {
|
||||||
|
speed_normal = 24,
|
||||||
|
speed_run = 48,
|
||||||
|
stand_start = 0,
|
||||||
|
stand_end = 23,
|
||||||
|
walk_start = 24,
|
||||||
|
walk_end = 49,
|
||||||
|
run_start = 24,
|
||||||
|
run_end = 49,
|
||||||
|
hurt_start = 110,
|
||||||
|
hurt_end = 139,
|
||||||
|
death_start = 140,
|
||||||
|
death_end = 189,
|
||||||
|
look_start = 50,
|
||||||
|
look_end = 108,
|
||||||
|
},
|
||||||
|
floats = 1,
|
||||||
|
fear_height = 4,
|
||||||
|
view_range = 16,
|
||||||
|
--Having trouble when fire is placed with lightning
|
||||||
|
fire_resistant = true,
|
||||||
|
glow = 3,
|
||||||
|
})
|
||||||
|
|
||||||
|
mcl_mobs:spawn_specific(
|
||||||
|
"mobs_mc:creeper",
|
||||||
|
"overworld",
|
||||||
|
"ground",
|
||||||
|
{
|
||||||
|
"Mesa",
|
||||||
|
"FlowerForest",
|
||||||
|
"Swampland",
|
||||||
|
"Taiga",
|
||||||
|
"ExtremeHills",
|
||||||
|
"Jungle",
|
||||||
|
"Savanna",
|
||||||
|
"BirchForest",
|
||||||
|
"MegaSpruceTaiga",
|
||||||
|
"MegaTaiga",
|
||||||
|
"ExtremeHills+",
|
||||||
|
"Forest",
|
||||||
|
"Plains",
|
||||||
|
"Desert",
|
||||||
|
"ColdTaiga",
|
||||||
|
"IcePlainsSpikes",
|
||||||
|
"SunflowerPlains",
|
||||||
|
"IcePlains",
|
||||||
|
"RoofedForest",
|
||||||
|
"ExtremeHills+_snowtop",
|
||||||
|
"MesaPlateauFM_grasstop",
|
||||||
|
"JungleEdgeM",
|
||||||
|
"ExtremeHillsM",
|
||||||
|
"JungleM",
|
||||||
|
"BirchForestM",
|
||||||
|
"MesaPlateauF",
|
||||||
|
"MesaPlateauFM",
|
||||||
|
"MesaPlateauF_grasstop",
|
||||||
|
"MesaBryce",
|
||||||
|
"JungleEdge",
|
||||||
|
"SavannaM",
|
||||||
|
"FlowerForest_beach",
|
||||||
|
"Forest_beach",
|
||||||
|
"StoneBeach",
|
||||||
|
"ColdTaiga_beach_water",
|
||||||
|
"Taiga_beach",
|
||||||
|
"Savanna_beach",
|
||||||
|
"Plains_beach",
|
||||||
|
"ExtremeHills_beach",
|
||||||
|
"ColdTaiga_beach",
|
||||||
|
"Swampland_shore",
|
||||||
|
"JungleM_shore",
|
||||||
|
"Jungle_shore",
|
||||||
|
"MesaPlateauFM_sandlevel",
|
||||||
|
"MesaPlateauF_sandlevel",
|
||||||
|
"MesaBryce_sandlevel",
|
||||||
|
"Mesa_sandlevel",
|
||||||
|
"RoofedForest_ocean",
|
||||||
|
"JungleEdgeM_ocean",
|
||||||
|
"BirchForestM_ocean",
|
||||||
|
"BirchForest_ocean",
|
||||||
|
"IcePlains_deep_ocean",
|
||||||
|
"Jungle_deep_ocean",
|
||||||
|
"Savanna_ocean",
|
||||||
|
"MesaPlateauF_ocean",
|
||||||
|
"ExtremeHillsM_deep_ocean",
|
||||||
|
"Savanna_deep_ocean",
|
||||||
|
"SunflowerPlains_ocean",
|
||||||
|
"Swampland_deep_ocean",
|
||||||
|
"Swampland_ocean",
|
||||||
|
"MegaSpruceTaiga_deep_ocean",
|
||||||
|
"ExtremeHillsM_ocean",
|
||||||
|
"JungleEdgeM_deep_ocean",
|
||||||
|
"SunflowerPlains_deep_ocean",
|
||||||
|
"BirchForest_deep_ocean",
|
||||||
|
"IcePlainsSpikes_ocean",
|
||||||
|
"Mesa_ocean",
|
||||||
|
"StoneBeach_ocean",
|
||||||
|
"Plains_deep_ocean",
|
||||||
|
"JungleEdge_deep_ocean",
|
||||||
|
"SavannaM_deep_ocean",
|
||||||
|
"Desert_deep_ocean",
|
||||||
|
"Mesa_deep_ocean",
|
||||||
|
"ColdTaiga_deep_ocean",
|
||||||
|
"Plains_ocean",
|
||||||
|
"MesaPlateauFM_ocean",
|
||||||
|
"Forest_deep_ocean",
|
||||||
|
"JungleM_deep_ocean",
|
||||||
|
"FlowerForest_deep_ocean",
|
||||||
|
"MegaTaiga_ocean",
|
||||||
|
"StoneBeach_deep_ocean",
|
||||||
|
"IcePlainsSpikes_deep_ocean",
|
||||||
|
"ColdTaiga_ocean",
|
||||||
|
"SavannaM_ocean",
|
||||||
|
"MesaPlateauF_deep_ocean",
|
||||||
|
"MesaBryce_deep_ocean",
|
||||||
|
"ExtremeHills+_deep_ocean",
|
||||||
|
"ExtremeHills_ocean",
|
||||||
|
"Forest_ocean",
|
||||||
|
"MegaTaiga_deep_ocean",
|
||||||
|
"JungleEdge_ocean",
|
||||||
|
"MesaBryce_ocean",
|
||||||
|
"MegaSpruceTaiga_ocean",
|
||||||
|
"ExtremeHills+_ocean",
|
||||||
|
"Jungle_ocean",
|
||||||
|
"RoofedForest_deep_ocean",
|
||||||
|
"IcePlains_ocean",
|
||||||
|
"FlowerForest_ocean",
|
||||||
|
"ExtremeHills_deep_ocean",
|
||||||
|
"MesaPlateauFM_deep_ocean",
|
||||||
|
"Desert_ocean",
|
||||||
|
"Taiga_ocean",
|
||||||
|
"BirchForestM_deep_ocean",
|
||||||
|
"Taiga_deep_ocean",
|
||||||
|
"JungleM_ocean",
|
||||||
|
"FlowerForest_underground",
|
||||||
|
"JungleEdge_underground",
|
||||||
|
"StoneBeach_underground",
|
||||||
|
"MesaBryce_underground",
|
||||||
|
"Mesa_underground",
|
||||||
|
"RoofedForest_underground",
|
||||||
|
"Jungle_underground",
|
||||||
|
"Swampland_underground",
|
||||||
|
"BirchForest_underground",
|
||||||
|
"Plains_underground",
|
||||||
|
"MesaPlateauF_underground",
|
||||||
|
"ExtremeHills_underground",
|
||||||
|
"MegaSpruceTaiga_underground",
|
||||||
|
"BirchForestM_underground",
|
||||||
|
"SavannaM_underground",
|
||||||
|
"MesaPlateauFM_underground",
|
||||||
|
"Desert_underground",
|
||||||
|
"Savanna_underground",
|
||||||
|
"Forest_underground",
|
||||||
|
"SunflowerPlains_underground",
|
||||||
|
"ColdTaiga_underground",
|
||||||
|
"IcePlains_underground",
|
||||||
|
"IcePlainsSpikes_underground",
|
||||||
|
"MegaTaiga_underground",
|
||||||
|
"Taiga_underground",
|
||||||
|
"ExtremeHills+_underground",
|
||||||
|
"JungleM_underground",
|
||||||
|
"ExtremeHillsM_underground",
|
||||||
|
"JungleEdgeM_underground",
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
7,
|
||||||
|
20,
|
||||||
|
16500,
|
||||||
|
2,
|
||||||
|
mcl_vars.mg_overworld_min,
|
||||||
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
|
-- spawn eggs
|
||||||
|
mcl_mobs:register_egg("mobs_mc:creeper", S("Creeper"), "#0da70a", "#000000", 0)
|
BIN
mods/ENTITIES/mobs_mc/sounds/mobs_mc_creeper_hurt.ogg
Normal file
317
mods/ENVIRONMENT/mcl_weather/rain.lua
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
local PARTICLES_COUNT_RAIN = tonumber(minetest.settings:get("mcl_weather_rain_particles")) or 500
|
||||||
|
local PARTICLES_COUNT_THUNDER = tonumber(minetest.settings:get("mcl_weather_thunder_particles")) or 900
|
||||||
|
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local mgname = minetest.get_mapgen_setting("mg_name")
|
||||||
|
|
||||||
|
mcl_weather.rain = {
|
||||||
|
-- max rain particles created at time
|
||||||
|
particles_count = PARTICLES_COUNT_RAIN,
|
||||||
|
|
||||||
|
-- flag to turn on/off extinguish fire for rain
|
||||||
|
extinguish_fire = true,
|
||||||
|
|
||||||
|
-- flag useful when mixing weathers
|
||||||
|
raining = false,
|
||||||
|
|
||||||
|
-- keeping last timeofday value (rounded).
|
||||||
|
-- Defaulted to non-existing value for initial comparing.
|
||||||
|
sky_last_update = -1,
|
||||||
|
|
||||||
|
init_done = false,
|
||||||
|
}
|
||||||
|
local update_sound={}
|
||||||
|
|
||||||
|
local psdef= {
|
||||||
|
amount = mcl_weather.rain.particles_count,
|
||||||
|
time=0,
|
||||||
|
minpos = vector.new(-15,20,-15),
|
||||||
|
maxpos = vector.new(15,25,15),
|
||||||
|
minvel = vector.new(-2,-17,-2),
|
||||||
|
maxvel = vector.new(2,-8,2),
|
||||||
|
minacc = vector.new(0,0,0),
|
||||||
|
maxacc = vector.new(0,-0.5,0),
|
||||||
|
minexptime = 1,
|
||||||
|
maxexptime = 4,
|
||||||
|
minsize = 4,
|
||||||
|
maxsize= 8,
|
||||||
|
collisiondetection = true,
|
||||||
|
collision_removal = true,
|
||||||
|
vertical = true,
|
||||||
|
}
|
||||||
|
|
||||||
|
local textures = {"weather_pack_rain_raindrop_1.png", "weather_pack_rain_raindrop_2.png"}
|
||||||
|
|
||||||
|
function mcl_weather.has_rain(pos)
|
||||||
|
if not mcl_worlds.has_weather(pos) then return false end
|
||||||
|
if mgname == "singlenode" or mgname == "v6" then return true end
|
||||||
|
local bd = minetest.registered_biomes[minetest.get_biome_name(minetest.get_biome_data(pos).biome)]
|
||||||
|
if bd and bd._mcl_biome_type == "hot" then return false end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_weather.rain.sound_handler(player, fade)
|
||||||
|
local fadeSpeed = 0
|
||||||
|
if fade then
|
||||||
|
fadeSpeed = 0.5
|
||||||
|
end
|
||||||
|
local player_meta = mcl_weather.players[player:get_player_name()]
|
||||||
|
if mcl_weather.is_outdoor(player:get_pos()) then
|
||||||
|
player_meta.outdoor = true
|
||||||
|
return minetest.sound_play("weather_rain", {
|
||||||
|
to_player = player:get_player_name(),
|
||||||
|
loop = true,
|
||||||
|
fade = fadeSpeed
|
||||||
|
})
|
||||||
|
else
|
||||||
|
player_meta.outdoor = false
|
||||||
|
return minetest.sound_play("weather_rain_damp", {
|
||||||
|
to_player = player:get_player_name(),
|
||||||
|
loop = true,
|
||||||
|
fade = fadeSpeed
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- set skybox based on time (uses skycolor api)
|
||||||
|
function mcl_weather.rain.set_sky_box()
|
||||||
|
if mcl_weather.state == "rain" then
|
||||||
|
mcl_weather.skycolor.add_layer(
|
||||||
|
"weather-pack-rain-sky",
|
||||||
|
{{r=0, g=0, b=0},
|
||||||
|
{r=85, g=86, b=98},
|
||||||
|
{r=135, g=135, b=151},
|
||||||
|
{r=85, g=86, b=98},
|
||||||
|
{r=0, g=0, b=0}})
|
||||||
|
mcl_weather.skycolor.active = true
|
||||||
|
for _, player in pairs(get_connected_players()) do
|
||||||
|
player:set_clouds({color="#5D5D5FE8"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- no no no NO NO f*.. no. no manual particle creatin' PLS!! this sends EVERY particle over the net.
|
||||||
|
function mcl_weather.rain.add_rain_particles(player)
|
||||||
|
mcl_weather.rain.last_rp_count = mcl_weather.rain.particles_count
|
||||||
|
local l = false
|
||||||
|
for k,v in pairs(textures) do
|
||||||
|
psdef.texture=v
|
||||||
|
l = l or mcl_weather.add_spawner_player(player,"rain"..k,psdef)
|
||||||
|
end
|
||||||
|
if l then
|
||||||
|
update_sound[player:get_player_name()]=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- register player for rain weather.
|
||||||
|
-- basically needs for origin sky reference and rain sound controls.
|
||||||
|
function mcl_weather.rain.add_player(player)
|
||||||
|
if mcl_weather.players[player:get_player_name()] == nil then
|
||||||
|
local player_meta = {}
|
||||||
|
player_meta.origin_sky = {player:get_sky(true)}
|
||||||
|
mcl_weather.players[player:get_player_name()] = player_meta
|
||||||
|
update_sound[player:get_player_name()]=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- remove player from player list effected by rain.
|
||||||
|
-- be sure to remove sound before removing player otherwise soundhandler reference will be lost.
|
||||||
|
function mcl_weather.rain.remove_player(player)
|
||||||
|
local player_meta = mcl_weather.players[player:get_player_name()]
|
||||||
|
if player_meta and player_meta.origin_sky then
|
||||||
|
player:set_clouds({color="#FFF0F0E5"})
|
||||||
|
mcl_weather.players[player:get_player_name()] = nil
|
||||||
|
update_sound[player:get_player_name()]=true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- adds and removes rain sound depending how much rain particles around player currently exist.
|
||||||
|
-- have few seconds delay before each check to avoid on/off sound too often
|
||||||
|
-- when player stay on 'edge' where sound should play and stop depending from random raindrop appearance.
|
||||||
|
function mcl_weather.rain.update_sound(player)
|
||||||
|
if not update_sound[player:get_player_name()] then return end
|
||||||
|
local player_meta = mcl_weather.players[player:get_player_name()]
|
||||||
|
if player_meta then
|
||||||
|
|
||||||
|
if player_meta.outdoor ~= mcl_weather.is_outdoor(player:get_pos()) then
|
||||||
|
mcl_weather.rain.remove_sound(player)
|
||||||
|
player_meta.sound_handler = mcl_weather.rain.sound_handler(player)
|
||||||
|
end
|
||||||
|
|
||||||
|
if player_meta.sound_updated and player_meta.sound_updated + 5 > minetest.get_gametime() then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local isInaudible = not mcl_weather.is_outdoor(player:get_pos()) and player:get_pos().y < -10
|
||||||
|
|
||||||
|
if player_meta.sound_handler then
|
||||||
|
if mcl_weather.rain.last_rp_count == 0 or isInaudible then
|
||||||
|
minetest.sound_fade(player_meta.sound_handler, -0.5, 0.0)
|
||||||
|
player_meta.sound_handler = nil
|
||||||
|
end
|
||||||
|
elseif mcl_weather.rain.last_rp_count > 0 and not isInaudible then
|
||||||
|
player_meta.sound_handler = mcl_weather.rain.sound_handler(player, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
player_meta.sound_updated = minetest.get_gametime()
|
||||||
|
end
|
||||||
|
update_sound[player:get_player_name()]=false
|
||||||
|
end
|
||||||
|
|
||||||
|
-- rain sound removed from player.
|
||||||
|
function mcl_weather.rain.remove_sound(player)
|
||||||
|
local player_meta = mcl_weather.players[player:get_player_name()]
|
||||||
|
if player_meta and player_meta.sound_handler then
|
||||||
|
minetest.sound_fade(player_meta.sound_handler, -0.5, 0.0)
|
||||||
|
player_meta.sound_handler = nil
|
||||||
|
player_meta.sound_updated = nil
|
||||||
|
player_meta.outdoor = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- callback function for removing rain
|
||||||
|
function mcl_weather.rain.clear()
|
||||||
|
mcl_weather.rain.raining = false
|
||||||
|
mcl_weather.rain.sky_last_update = -1
|
||||||
|
mcl_weather.rain.init_done = false
|
||||||
|
mcl_weather.rain.set_particles_mode("rain")
|
||||||
|
mcl_weather.skycolor.remove_layer("weather-pack-rain-sky")
|
||||||
|
for _, player in pairs(get_connected_players()) do
|
||||||
|
mcl_weather.rain.remove_sound(player)
|
||||||
|
mcl_weather.rain.remove_player(player)
|
||||||
|
mcl_weather.remove_spawners_player(player)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
if mcl_weather.state ~= "rain" then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
mcl_weather.rain.make_weather()
|
||||||
|
end)
|
||||||
|
|
||||||
|
function mcl_weather.rain.make_weather()
|
||||||
|
if mcl_weather.rain.init_done == false then
|
||||||
|
mcl_weather.rain.raining = true
|
||||||
|
mcl_weather.rain.set_sky_box()
|
||||||
|
mcl_weather.rain.set_particles_mode(mcl_weather.mode)
|
||||||
|
mcl_weather.rain.init_done = true
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, player in pairs(get_connected_players()) do
|
||||||
|
local pos=player:get_pos()
|
||||||
|
if mcl_weather.is_underwater(player) or not mcl_weather.has_rain(pos) then
|
||||||
|
mcl_weather.rain.remove_sound(player)
|
||||||
|
mcl_weather.remove_spawners_player(player)
|
||||||
|
if mcl_worlds.has_weather(pos) then
|
||||||
|
mcl_weather.set_sky_box_clear(player)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if mcl_weather.has_snow(pos) then
|
||||||
|
mcl_weather.rain.remove_sound(player)
|
||||||
|
mcl_weather.snow.add_player(player)
|
||||||
|
mcl_weather.snow.set_sky_box()
|
||||||
|
else
|
||||||
|
mcl_weather.rain.add_player(player)
|
||||||
|
mcl_weather.rain.add_rain_particles(player)
|
||||||
|
mcl_weather.rain.update_sound(player)
|
||||||
|
mcl_weather.rain.set_sky_box()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Switch the number of raindrops: "thunder" for many raindrops, otherwise for normal raindrops
|
||||||
|
function mcl_weather.rain.set_particles_mode(mode)
|
||||||
|
if mode == "thunder" then
|
||||||
|
psdef.amount=PARTICLES_COUNT_THUNDER
|
||||||
|
mcl_weather.rain.particles_count = PARTICLES_COUNT_THUNDER
|
||||||
|
else
|
||||||
|
psdef.amount=PARTICLES_COUNT_RAIN
|
||||||
|
mcl_weather.rain.particles_count = PARTICLES_COUNT_RAIN
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if mcl_weather.allow_abm then
|
||||||
|
-- ABM for extinguish fire
|
||||||
|
minetest.register_abm({
|
||||||
|
label = "Rain extinguishes fire",
|
||||||
|
nodenames = {"mcl_fire:fire"},
|
||||||
|
interval = 2.0,
|
||||||
|
chance = 2,
|
||||||
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
-- Fire is extinguished if in rain or one of 4 neighbors is in rain
|
||||||
|
if mcl_weather.rain.raining and mcl_weather.rain.extinguish_fire then
|
||||||
|
local around = {
|
||||||
|
{ x = 0, y = 0, z = 0 },
|
||||||
|
{ x = -1, y = 0, z = 0 },
|
||||||
|
{ x = 1, y = 0, z = 0 },
|
||||||
|
{ x = 0, y = 0, z = -1 },
|
||||||
|
{ x = 0, y = 0, z = 1 },
|
||||||
|
}
|
||||||
|
for a=1, #around do
|
||||||
|
local apos = vector.add(pos, around[a])
|
||||||
|
if mcl_weather.is_outdoor(apos) then
|
||||||
|
minetest.remove_node(pos)
|
||||||
|
minetest.sound_play("fire_extinguish_flame", {pos = pos, max_hear_distance = 8, gain = 0.1}, true)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Slowly fill up cauldrons
|
||||||
|
minetest.register_abm({
|
||||||
|
label = "Rain fills cauldrons with water",
|
||||||
|
nodenames = {"mcl_cauldrons:cauldron", "mcl_cauldrons:cauldron_1", "mcl_cauldrons:cauldron_2"},
|
||||||
|
interval = 56.0,
|
||||||
|
chance = 1,
|
||||||
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
-- Rain is equivalent to a water bottle
|
||||||
|
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
|
||||||
|
if node.name == "mcl_cauldrons:cauldron" then
|
||||||
|
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_1"})
|
||||||
|
elseif node.name == "mcl_cauldrons:cauldron_1" then
|
||||||
|
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_2"})
|
||||||
|
elseif node.name == "mcl_cauldrons:cauldron_2" then
|
||||||
|
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"})
|
||||||
|
elseif node.name == "mcl_cauldrons:cauldron_1r" then
|
||||||
|
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_2r"})
|
||||||
|
elseif node.name == "mcl_cauldrons:cauldron_2r" then
|
||||||
|
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
||||||
|
-- Wetten the soil
|
||||||
|
minetest.register_abm({
|
||||||
|
label = "Rain hydrates farmland",
|
||||||
|
nodenames = {"mcl_farming:soil"},
|
||||||
|
interval = 22.0,
|
||||||
|
chance = 3,
|
||||||
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
if mcl_weather.rain.raining and mcl_weather.is_outdoor(pos) then
|
||||||
|
if node.name == "mcl_farming:soil" then
|
||||||
|
minetest.set_node(pos, {name="mcl_farming:soil_wet"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if mcl_weather.reg_weathers.rain == nil then
|
||||||
|
mcl_weather.reg_weathers.rain = {
|
||||||
|
clear = mcl_weather.rain.clear,
|
||||||
|
light_factor = 0.6,
|
||||||
|
-- 10min - 20min
|
||||||
|
min_duration = 600,
|
||||||
|
max_duration = 1200,
|
||||||
|
transitions = {
|
||||||
|
[65] = "none",
|
||||||
|
[70] = "snow",
|
||||||
|
[100] = "thunder",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
BIN
mods/ENVIRONMENT/mcl_weather/sounds/weather_rain_damp.ogg
Normal file
60
mods/ITEMS/mcl_colorbricks/init.lua
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
local mod_doc = minetest.get_modpath("doc")
|
||||||
|
|
||||||
|
local brick = {}
|
||||||
|
-- This uses a trick: you can first define the recipes using all of the base
|
||||||
|
-- colors, and then some recipes using more specific colors for a few non-base
|
||||||
|
-- colors available. When crafting, the last recipes will be checked first.
|
||||||
|
brick.dyes = {
|
||||||
|
-- name, texture, colorbrick desc., dye, color_group
|
||||||
|
{"white", "mcl_colorbricks_white", "White Brick", "white", "unicolor_white"},
|
||||||
|
{"grey", "mcl_colorbricks_dark_grey", "Grey Brick", "dark_grey", "unicolor_darkgrey"},
|
||||||
|
{"silver", "mcl_colorbricks_grey", "Light Grey Brick", "grey", "unicolor_grey"},
|
||||||
|
{"black", "mcl_colorbricks_black", "Black Brick", "black", "unicolor_black"},
|
||||||
|
{"yellow", "mcl_colorbricks_yellow", "Yellow Brick", "yellow", "unicolor_yellow"},
|
||||||
|
{"green", "mcl_colorbricks_dark_green", "Green Brick", "dark_green", "unicolor_dark_green"},
|
||||||
|
{"cyan", "mcl_colorbricks_cyan", "Cyan Brick", "cyan", "unicolor_cyan"},
|
||||||
|
{"blue", "mcl_colorbricks_blue", "Blue Brick", "blue", "unicolor_blue"},
|
||||||
|
{"magenta", "mcl_colorbricks_magenta", "Magenta Brick", "magenta", "unicolor_red_violet"},
|
||||||
|
{"orange", "mcl_colorbricks_orange", "Orange Brick", "orange", "unicolor_orange"},
|
||||||
|
{"purple", "mcl_colorbricks_violet", "Purple Brick", "violet", "unicolor_violet"},
|
||||||
|
{"brown", "mcl_colorbricks_brown", "Brown Brick", "brown", "unicolor_dark_orange"},
|
||||||
|
{"pink", "mcl_colorbricks_pink", "Pink Brick", "pink", "unicolor_light_red"},
|
||||||
|
{"lime", "mcl_colorbricks_lime", "Lime Brick", "green", "unicolor_green"},
|
||||||
|
{"light_blue", "mcl_colorbricks_light_blue", "Light Blue Brick", "lightblue", "unicolor_light_blue"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, row in ipairs(brick.dyes) do
|
||||||
|
local name = row[1]
|
||||||
|
local texture = row[2]
|
||||||
|
local desc_brick = row[3]
|
||||||
|
local dye = row[4]
|
||||||
|
local color_group = row[5]
|
||||||
|
|
||||||
|
-- Node Definition
|
||||||
|
minetest.register_node("mcl_colorbricks:colorbrick_"..name, {
|
||||||
|
description = S(desc_brick),
|
||||||
|
stack_max = 64,
|
||||||
|
is_ground_content = false,
|
||||||
|
tiles = {texture..".png"},
|
||||||
|
groups = {pickaxey=1, building_block=1, material_stone=1, [color_group]=1},
|
||||||
|
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||||
|
_mcl_blast_resistance = 6,
|
||||||
|
_mcl_hardness = 2,
|
||||||
|
})
|
||||||
|
|
||||||
|
if mod_doc and not is_canonical then
|
||||||
|
doc.add_entry_alias("nodes", "mcl_core:brick_block", "nodes", "mcl_colorbricks:colorbrick_"..name)
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_stairs.register_stair_and_slab_simple("colorbrick_"..name, "mcl_colorbricks:colorbrick_"..name, S(desc_brick.." Stairs"), S(desc_brick.." Slab"), S("Double "..desc_brick.." Slab"))
|
||||||
|
|
||||||
|
if dye then
|
||||||
|
-- Crafting from dye and white wool
|
||||||
|
minetest.register_craft({
|
||||||
|
type = "shapeless",
|
||||||
|
output = "mcl_colorbricks:colorbrick_"..name,
|
||||||
|
recipe = {"mcl_dye:"..dye, "mcl_core:brick_block"},
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
3
mods/ITEMS/mcl_colorbricks/mod.conf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
name = mcl_colorbricks
|
||||||
|
depends = mcl_colors, mcl_stairs, mclx_stairs
|
||||||
|
optional_depends = mcl_sounds, mcl_core, doc, mcl_dye
|
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_black.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_blue.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_brown.png
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_cyan.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 5.2 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_grey.png
Normal file
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.5 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_lime.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_magenta.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_orange.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_pink.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_violet.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_white.png
Normal file
After Width: | Height: | Size: 5.2 KiB |
BIN
mods/ITEMS/mcl_colorbricks/textures/mcl_colorbricks_yellow.png
Normal file
After Width: | Height: | Size: 5.5 KiB |
3
mods/ITEMS/mcl_prideflags/README.txt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
License of code: WTFPL
|
||||||
|
|
||||||
|
License of textures: See README.md in top directory of MineClone 2.
|
198
mods/ITEMS/mcl_prideflags/init.lua
Normal file
|
@ -0,0 +1,198 @@
|
||||||
|
local modname = minetest.get_current_modname()
|
||||||
|
local modpath = minetest.get_modpath(modname)
|
||||||
|
local S = minetest.get_translator(modname)
|
||||||
|
local N = function(s) return s end
|
||||||
|
|
||||||
|
local mod_mcl_core = minetest.get_modpath("mcl_core")
|
||||||
|
local mod_mcl_banners = minetest.get_modpath("mcl_banners")
|
||||||
|
local mod_mcl_dye = minetest.get_modpath("mcl_wool")
|
||||||
|
local mod_mcl_dye = minetest.get_modpath("mcl_dye")
|
||||||
|
local mod_doc = minetest.get_modpath("doc")
|
||||||
|
|
||||||
|
local standing_banner_entity_offset = { x=0, y=-0.499, z=0 }
|
||||||
|
local hanging_banner_entity_offset = { x=0, y=-1.7, z=0 }
|
||||||
|
|
||||||
|
local inv
|
||||||
|
local base
|
||||||
|
local finished_banner
|
||||||
|
|
||||||
|
base = "mcl_banners_item_base.png^mcl_prideflags_item_overlay.png^[resize:32x32"
|
||||||
|
finished_banner = base
|
||||||
|
|
||||||
|
inv = finished_banner
|
||||||
|
groups = { banner = 1, deco_block = 1, flammable = -1 }
|
||||||
|
|
||||||
|
-- Helper function
|
||||||
|
local function round(num, idp)
|
||||||
|
local mult = 10^(idp or 0)
|
||||||
|
return math.floor(num * mult + 0.5) / mult
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rotation_level_to_yaw(rotation_level)
|
||||||
|
return (rotation_level * (math.pi/8)) + math.pi
|
||||||
|
end
|
||||||
|
|
||||||
|
local function spawn_banner_entity(pos, hanging, itemstack)
|
||||||
|
local banner
|
||||||
|
if hanging then
|
||||||
|
banner = minetest.add_entity(pos, "mcl_banners:hanging_banner")
|
||||||
|
else
|
||||||
|
banner = minetest.add_entity(pos, "mcl_banners:standing_banner")
|
||||||
|
end
|
||||||
|
if banner == nil then
|
||||||
|
return banner
|
||||||
|
end
|
||||||
|
local imeta = itemstack:get_meta()
|
||||||
|
local layers = ""
|
||||||
|
local colorid = ""
|
||||||
|
banner:set_properties({textures = {"mcl_prideflags_base.png"}})
|
||||||
|
local mname = imeta:get_string("name")
|
||||||
|
if mname and mname ~= "" then
|
||||||
|
banner:get_luaentity()._item_name = mname
|
||||||
|
banner:get_luaentity()._item_description = imeta:get_string("description")
|
||||||
|
end
|
||||||
|
|
||||||
|
return banner
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_lbm({
|
||||||
|
label = "Respawn banner entities",
|
||||||
|
name = "mcl_prideflags:respawn_entities",
|
||||||
|
run_at_every_load = true,
|
||||||
|
nodenames = {"mcl_banners:standing_banner", "mcl_banners:hanging_banner"},
|
||||||
|
action = function(pos, node)
|
||||||
|
|
||||||
|
local hanging = node.name == "mcl_banners:hanging_banner"
|
||||||
|
local offset
|
||||||
|
if hanging then
|
||||||
|
offset = hanging_banner_entity_offset
|
||||||
|
else
|
||||||
|
offset = standing_banner_entity_offset
|
||||||
|
end
|
||||||
|
|
||||||
|
local bpos = vector.add(pos, offset)
|
||||||
|
local objects = minetest.get_objects_inside_radius(bpos, 0.5)
|
||||||
|
|
||||||
|
for _, v in ipairs(objects) do
|
||||||
|
local ent = v:get_luaentity()
|
||||||
|
if ent and (ent.name == "mcl_banners:standing_banner" or ent.name == "mcl_banners:hanging_banner") then
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if meta:get_int("pride") == 1 then
|
||||||
|
v:set_properties({textures = {"mcl_prideflags_base.png"}})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.register_craftitem("mcl_prideflags:pride_flag", {
|
||||||
|
description = S("Pride Flag"),
|
||||||
|
_tt_help = S("Pride Flag decoration"),
|
||||||
|
_doc_items_create_entry = false,
|
||||||
|
inventory_image = inv,
|
||||||
|
wield_image = inv,
|
||||||
|
-- Banner group groups together the banner items, but not the nodes.
|
||||||
|
-- Used for crafting.
|
||||||
|
groups = groups,
|
||||||
|
stack_max = 16,
|
||||||
|
|
||||||
|
on_place = function(itemstack, placer, pointed_thing)
|
||||||
|
local above = pointed_thing.above
|
||||||
|
local under = pointed_thing.under
|
||||||
|
|
||||||
|
local node_under = minetest.get_node(under)
|
||||||
|
if placer and not placer:get_player_control().sneak then
|
||||||
|
-- Use pointed node's on_rightclick function first, if present
|
||||||
|
if minetest.registered_nodes[node_under.name] and minetest.registered_nodes[node_under.name].on_rightclick then
|
||||||
|
return minetest.registered_nodes[node_under.name].on_rightclick(under, node_under, placer, itemstack) or itemstack
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Place the node!
|
||||||
|
local hanging = false
|
||||||
|
|
||||||
|
-- Standing or hanging banner. The placement rules are enforced by the node definitions
|
||||||
|
local _, success = minetest.item_place_node(ItemStack("mcl_banners:standing_banner"), placer, pointed_thing)
|
||||||
|
if not success then
|
||||||
|
-- Forbidden on ceiling
|
||||||
|
if pointed_thing.under.y ~= pointed_thing.above.y then
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
_, success = minetest.item_place_node(ItemStack("mcl_banners:hanging_banner"), placer, pointed_thing)
|
||||||
|
if not success then
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
hanging = true
|
||||||
|
end
|
||||||
|
local place_pos
|
||||||
|
if minetest.registered_nodes[node_under.name].buildable_to then
|
||||||
|
place_pos = under
|
||||||
|
else
|
||||||
|
place_pos = above
|
||||||
|
end
|
||||||
|
local bnode = minetest.get_node(place_pos)
|
||||||
|
if bnode.name ~= "mcl_banners:standing_banner" and bnode.name ~= "mcl_banners:hanging_banner" then
|
||||||
|
minetest.log("error", "[mcl_banners] The placed banner node is not what the mod expected!")
|
||||||
|
return itemstack
|
||||||
|
end
|
||||||
|
local meta = minetest.get_meta(place_pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
inv:set_size("banner", 1)
|
||||||
|
local store_stack = ItemStack(itemstack)
|
||||||
|
store_stack:set_count(1)
|
||||||
|
inv:set_stack("banner", 1, store_stack)
|
||||||
|
|
||||||
|
-- Spawn entity
|
||||||
|
local entity_place_pos
|
||||||
|
if hanging then
|
||||||
|
entity_place_pos = vector.add(place_pos, hanging_banner_entity_offset)
|
||||||
|
else
|
||||||
|
entity_place_pos = vector.add(place_pos, standing_banner_entity_offset)
|
||||||
|
end
|
||||||
|
local banner_entity = spawn_banner_entity(entity_place_pos, hanging, itemstack)
|
||||||
|
-- Set rotation
|
||||||
|
local final_yaw, rotation_level
|
||||||
|
if hanging then
|
||||||
|
local pdir = vector.direction(pointed_thing.under, pointed_thing.above)
|
||||||
|
final_yaw = minetest.dir_to_yaw(pdir)
|
||||||
|
if pdir.x > 0 then
|
||||||
|
rotation_level = 4
|
||||||
|
elseif pdir.z > 0 then
|
||||||
|
rotation_level = 8
|
||||||
|
elseif pdir.x < 0 then
|
||||||
|
rotation_level = 12
|
||||||
|
else
|
||||||
|
rotation_level = 0
|
||||||
|
end
|
||||||
|
else
|
||||||
|
-- Determine the rotation based on player's yaw
|
||||||
|
local yaw = placer:get_look_horizontal()
|
||||||
|
-- Select one of 16 possible rotations (0-15)
|
||||||
|
rotation_level = round((yaw / (math.pi*2)) * 16)
|
||||||
|
if rotation_level >= 16 then
|
||||||
|
rotation_level = 0
|
||||||
|
end
|
||||||
|
final_yaw = rotation_level_to_yaw(rotation_level)
|
||||||
|
end
|
||||||
|
meta:set_int("rotation_level", rotation_level)
|
||||||
|
meta:set_int("pride", 1)
|
||||||
|
|
||||||
|
if banner_entity then
|
||||||
|
banner_entity:set_yaw(final_yaw)
|
||||||
|
end
|
||||||
|
|
||||||
|
if not minetest.is_creative_enabled(placer:get_player_name()) then
|
||||||
|
itemstack:take_item()
|
||||||
|
end
|
||||||
|
minetest.sound_play({name="default_place_node_hard", gain=1.0}, {pos = place_pos}, true)
|
||||||
|
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
if mod_mcl_core then
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "mcl_prideflags:pride_flag",
|
||||||
|
recipe = { {"mcl_wool:red", "mcl_wool:orange", "mcl_wool:yellow"}, {"mcl_wool:green", "mcl_wool:blue", "mcl_wool:purple"}, {"", "mcl_core:stick", ""} }
|
||||||
|
})
|
||||||
|
end
|
4
mods/ITEMS/mcl_prideflags/mod.conf
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
name = mcl_prideflags
|
||||||
|
author = NilsG
|
||||||
|
description = Adds decorative pride flags
|
||||||
|
depends = mcl_colors, mcl_banners, mcl_dye, mcl_wool
|
BIN
mods/ITEMS/mcl_prideflags/textures/mcl_prideflags_base.png
Normal file
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 4.9 KiB |