diff --git a/README.md b/README.md index c9d451aa..23bd1483 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -# MineClone 2 -An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. +# Mineclonia +An unofficial Minecraft-like game for Minetest. Forked from MineClone2. Developed by many people. Not developed or endorsed by Mojang AB. Version: 0.71.0 @@ -74,24 +74,24 @@ These items do not work yet, but you can get them with `/giveme` for testing: * Minecart with Command Block: `mcl_minecarts:command_block_minecart` ## Installation -This game requires [Minetest](http://minetest.net) to run (version 5.0.0 or +This game requires [Minetest](http://minetest.net) to run (version 5.4.0 or later). So you need to install Minetest first. Only stable versions of Minetest are officially supported. -There is no support for running MineClone 2 in development versions of Minetest. +There is no support for running Mineclonia in development versions of Minetest. -To install MineClone 2 (if you haven't already), move this directory into the +To install Mineclonia (if you haven't already), move this directory into the “games” directory of your Minetest data directory. Consult the help of Minetest to learn more. ## Project description -The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software. +The main goal of **Mineclonia** is to be a clone of Minecraft and to be released as free software. * **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”) -* MineClone2 also includes Optifine features supported by the Minetest +* Mineclonia also includes Optifine features supported by the Minetest * Features of later Minecraft versions might sneak in, but they have a low priority * In general, Minecraft is aimed to be cloned as good as Minetest currently permits (no hacks) * Cloning the gameplay has highest priority -* MineClone 2 will use different graphics and sounds, but with a similar style +* Mineclonia will use different graphics and sounds, but with a similar style * Cloning the interface has no priority. It will only be roughly imitated * Limitations found in Minetest will be written down and reported in the course of development @@ -178,18 +178,18 @@ Technical differences from Minecraft: * Different sounds (various sources) * Different engine (Minetest) -… and finally, MineClone 2 is free software (“free” as in “freedom”)! +… and finally, Mineclonia is free software (“free” as in “freedom”)! ## Reporting bugs Please report all bugs and missing Minecraft features here: - + ## Other readme files * `LICENSE.txt`: The GPLv3 license text * `CONTRIBUTING.md`: Information for those who want to contribute -* `MISSING_ENGINE_FEATURES.md`: List of missing features in Minetest which MineClone 2 would need for improvement +* `MISSING_ENGINE_FEATURES.md`: List of missing features in Minetest which Mineclonia would need for improvement * `API.md`: For Minetest modders who want to mod this game ## Credits @@ -197,15 +197,15 @@ There are so many people to list (sorry). Check out the respective mod directori ### Coding * [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082): Main programmer of most mods (retired) -* davedevils: Creator of MineClone on which MineClone 2 is based on +* davedevils: Creator of MineClone on which Mineclonia is based on * [ex-bart](https://github.com/ex-bart): Redstone comparators * [Rootyjr](https://github.com/Rootyjr): Fishing rod and bugfixes * [aligator](https://github.com/aligator): Improvement of doors * [ryvnf](https://github.com/ryvnf): Explosion mechanics * MysticTempest: Bugfixes * [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand -* kay27 : Experience system, bugfixes, optimizations (Current maintainer) -* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer) +* kay27 : Experience system, bugfixes, optimizations +* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes * epCode: Better player animations, new logo * 2mac: Fix bug with powered rail * Lots of other people: TO BE WRITTEN (see mod directories for details) @@ -255,7 +255,7 @@ Various sources. See the respective mod directories for details. * davedevils for starting MineClone, the original version of this game * Wuzzy for starting and maintaining MineClone2 for several years * celeron55 for creating Minetest -* Minetest's modding community for providing a huge selection of mods, some of which ended up in MineClone 2 +* Minetest's modding community for providing a huge selection of mods, some of which ended up in Mineclonia * Jordach for the jukebox music compilation from Big Freaking Dig * The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game * Notch and Jeb for being the major forces behind Minecraft @@ -273,10 +273,9 @@ Copying is an act of love. Please copy and share! <3 Here's the detailed legalese for those who need it: ### License of source code -MineClone 2 (by kay27, EliasFleckenstein, Wuzzy, davedevils and countless others) -is an imitation of Minecraft. +Mineclonia is an imitation of Minecraft. -MineClone 2 is free software: you can redistribute it and/or modify +Mineclonia is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @@ -290,15 +289,15 @@ details. In the mods you might find in the read-me or license text files a different license. This counts as dual-licensing. You can choose which license applies to you: Either the -license of MineClone 2 (GNU GPLv3) or the mod's license. +license of Mineclonia (GNU GPLv3) or the mod's license. -MineClone 2 is a direct continuation of the discontinued MineClone -project by davedevils. +Mineclonia is a continuation of the discontinued MineClone project by davedevils +and the MineClone2 project by Wuzzy. Mod credits: See `README.txt` or `README.md` in each mod directory for information about other authors. For mods that do not have such a file, the license is the source code license -of MineClone 2 and the author is Wuzzy. +of Mineclonia and the author is Wuzzy. ### License of media (textures and sounds) No non-free licenses are used anywhere. diff --git a/game.conf b/game.conf index db735770..c8a07d45 100644 --- a/game.conf +++ b/game.conf @@ -1,2 +1,2 @@ -name = MineClone 2 +name = Mineclonia description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more. diff --git a/mods/CORE/mcl_explosions/init.lua b/mods/CORE/mcl_explosions/init.lua index 379d5700..79221d0e 100644 --- a/mods/CORE/mcl_explosions/init.lua +++ b/mods/CORE/mcl_explosions/init.lua @@ -202,7 +202,10 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher) npos_x - emin_x + 1 local cid = data[idx] - local br = node_blastres[cid] + + -- Set blast resistance to 0 for unknown nodes + local br = node_blastres[cid] or 0 + if br < INDESTRUCT_BLASTRES and br > max_blast_resistance then br = max_blast_resistance end diff --git a/mods/ENTITIES/mcl_minecarts/init.lua b/mods/ENTITIES/mcl_minecarts/init.lua index 6c022a9b..6ad3ff28 100644 --- a/mods/ENTITIES/mcl_minecarts/init.lua +++ b/mods/ENTITIES/mcl_minecarts/init.lua @@ -12,14 +12,15 @@ local function detach_driver(self) if not self._driver then return end - if self._driver:is_player() then - mcl_player.player_attached[self._driver:get_player_name()] = nil - self._driver:set_detach() - self._driver:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) - mcl_player.player_set_animation(self._driver, "stand" , 30) - end + mcl_player.player_attached[self._driver] = nil + local player = minetest.get_player_by_name(self._driver) self._driver = nil self._start_pos = nil + if player then + player:set_detach() + player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0}) + mcl_player.player_set_animation(player, "stand" , 30) + end end local function activate_tnt_minecart(self, timer) @@ -61,7 +62,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o on_rightclick = on_rightclick, - _driver = nil, -- player (or mob) who sits in and controls the minecart (only for minecart!) + _driver = nil, -- player who sits in and controls the minecart (only for minecart!) _punched = false, -- used to re-send _velocity and position _velocity = {x=0, y=0, z=0}, -- only used on punch _start_pos = nil, -- Used to calculate distance for “On A Rail” achievement @@ -96,101 +97,111 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction) - -- Punch: Pick up minecart (unless TNT was ignited) - if self._boomtimer then return end - if self._driver then - detach_driver(self) - end local pos = self.object:get_pos() - - -- Disable detector rail - local rou_pos = vector.round(pos) - local node = minetest.get_node(rou_pos) - if node.name == "mcl_minecarts:detector_rail_on" then - local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2} - minetest.swap_node(rou_pos, newnode) - mesecon.receptor_off(rou_pos) + if not self._railtype then + local node = minetest.get_node(vector.floor(pos)).name + self._railtype = minetest.get_item_group(node, "connect_to_raillike") end - -- Drop items and remove cart entity - if not minetest.is_creative_enabled(puncher:get_player_name()) then - for d=1, #drop do - minetest.add_item(self.object:get_pos(), drop[d]) + if not puncher or not puncher:is_player() then + local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, self._railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return end - elseif puncher and puncher:is_player() then - local inv = puncher:get_inventory() - for d=1, #drop do - if not inv:contains_item("main", drop[d]) then - inv:add_item("main", drop[d]) + self._velocity = vector.multiply(cart_dir, 3) + self._old_pos = nil + self._punched = true + return + end + + -- Punch+sneak: Pick up minecart (unless TNT was ignited) + if puncher:get_player_control().sneak and not self._boomtimer then + if self._driver then + if self._old_pos then + self.object:set_pos(self._old_pos) + end + detach_driver(self) + end + + -- Disable detector rail + local rou_pos = vector.round(pos) + local node = minetest.get_node(rou_pos) + if node.name == "mcl_minecarts:detector_rail_on" then + local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2} + minetest.swap_node(rou_pos, newnode) + mesecon.receptor_off(rou_pos) + end + + -- Drop items and remove cart entity + if not minetest.is_creative_enabled(puncher:get_player_name()) then + for d=1, #drop do + minetest.add_item(self.object:get_pos(), drop[d]) + end + elseif puncher and puncher:is_player() then + local inv = puncher:get_inventory() + for d=1, #drop do + if not inv:contains_item("main", drop[d]) then + inv:add_item("main", drop[d]) + end end end + + self.object:remove() + return end - self.object:remove() + local vel = self.object:get_velocity() + if puncher:get_player_name() == self._driver then + if math.abs(vel.x + vel.z) > 7 then + return + end + end + + local punch_dir = mcl_minecarts:velocity_to_dir(puncher:get_look_dir()) + punch_dir.y = 0 + local cart_dir = mcl_minecarts:get_rail_direction(pos, punch_dir, nil, nil, self._railtype) + if vector.equals(cart_dir, {x=0, y=0, z=0}) then + return + end + + time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval) + local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval) + + self._velocity = vector.multiply(cart_dir, f) + self._old_pos = nil + self._punched = true end cart.on_activate_by_rail = on_activate_by_rail function cart:on_step(dtime) local ctrl, player = nil, nil - local update = {} - local vel = self.object:get_velocity() - local pos, rou_pos, node - pos = self.object:get_pos() - rou_pos = vector.round(pos) - node = minetest.get_node(rou_pos) - local g = minetest.get_item_group(node.name, "connect_to_raillike") - if self._driver and self._driver:is_player() then - player = self._driver - ctrl = player:get_player_control() - -- player detach - if ctrl.sneak then - detach_driver(self) - return - end - if g == self._railtype then - if ctrl.right then - local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()-1.57), 0.2) - self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z})) - end - if ctrl.left then - local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()+1.57), 0.2) - self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z})) - end - if ctrl.up then - local c = vector.multiply(self._driver:get_look_dir(), 0.2) - self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z})) - end - if ctrl.down then - local c = vector.multiply(self._driver:get_look_dir(), 0.2) - self.object:set_velocity(vector.subtract(vel, {x=c.x, y=0, z=c.z})) + if self._driver then + player = minetest.get_player_by_name(self._driver) + if player then + ctrl = player:get_player_control() + -- player detach + if ctrl.sneak then + detach_driver(self) + return end end end + local vel = self.object:get_velocity() + local update = {} if self._last_float_check == nil then self._last_float_check = 0 else self._last_float_check = self._last_float_check + dtime end + local pos, rou_pos, node -- Drop minecart if it isn't on a rail anymore if self._last_float_check >= mcl_minecarts.check_float_time then - - - for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.3)) do - if object ~= self.object then - local mob = object:get_luaentity() - if mob then mob = mob._cmi_is_mob == true end - if mob and (not self._driver) and not object:get_attach() then - self._driver = object - object:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0}) - mobs:set_animation(self.object, "stand") - return - end - end - end - - + pos = self.object:get_pos() + rou_pos = vector.round(pos) + node = minetest.get_node(rou_pos) + local g = minetest.get_item_group(node.name, "connect_to_raillike") if g ~= self._railtype and self._railtype ~= nil then -- Detach driver if player then @@ -289,12 +300,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o end end - if update.vel then + if self._punched then vel = vector.add(vel, self._velocity) - if vel.x>8 then vel.x = 8 end - if vel.x<-8 then vel.x = -8 end - if vel.z>8 then vel.z = 8 end - if vel.z<-8 then vel.z = -8 end self.object:set_velocity(vel) self._old_dir.y = 0 elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then @@ -619,14 +626,17 @@ register_minecart( "mcl_minecarts_minecart_normal.png", {"mcl_minecarts:minecart"}, function(self, clicker) - if not clicker or not clicker:is_player() then return end - if clicker == self._driver then + local name = clicker:get_player_name() + if not clicker or not clicker:is_player() then + return + end + local player_name = clicker:get_player_name() + if self._driver and player_name == self._driver then detach_driver(self) - else - local name = clicker:get_player_name() - self._driver = clicker + elseif not self._driver then + self._driver = player_name self._start_pos = self.object:get_pos() - mcl_player.player_attached[name] = true + mcl_player.player_attached[player_name] = true clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0}) mcl_player.player_attached[name] = true minetest.after(0.2, function(name) @@ -637,7 +647,6 @@ register_minecart( mcl_tmp_message.message(clicker, S("Sneak to dismount")) end end, name) - clicker:set_look_horizontal(self.object:get_yaw()) end end, activate_normal_minecart ) diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr index 24d3fa32..6598cd48 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.de.tr @@ -28,6 +28,7 @@ Pig=Schwein Polar Bear=Eisbär Rabbit=Kaninchen Killer Bunny=Killerkaninchen +The Killer Bunny=Das Killerkaninchen Sheep=Schaf Shulker=Shulker Silverfish=Silberfischchen diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr index 240e7759..c61c0994 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.es.tr @@ -28,6 +28,7 @@ Pig=Cerdo Polar Bear=Oso polar Rabbit=Conejo Killer Bunny=Conejo asesino +The Killer Bunny=El Conejo asesino Sheep=Oveja Shulker=Shulker Silverfish=Lepisma diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr index ff1e2b9c..4c8bd562 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.fr.tr @@ -28,6 +28,7 @@ Pig=Cochon Polar Bear=Ours blanc Rabbit=Lapin Killer Bunny=Lapin tueur +The Killer Bunny=Le Lapin tueur Sheep=Mouton Shulker=Shulker Silverfish=Poisson d'argent diff --git a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr index 73807c00..8857dda9 100644 --- a/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr +++ b/mods/ENTITIES/mobs_mc/locale/mobs_mc.ru.tr @@ -28,6 +28,7 @@ Pig=Свинья Polar Bear=Полярный медведь Rabbit=Кролик Killer Bunny=Кролик-убийца +The Killer Bunny=Кролик-убийца Sheep=Овца Shulker=Шалкер Silverfish=Чешуйница diff --git a/mods/ENTITIES/mobs_mc/rabbit.lua b/mods/ENTITIES/mobs_mc/rabbit.lua index e167649f..34684bdc 100644 --- a/mods/ENTITIES/mobs_mc/rabbit.lua +++ b/mods/ENTITIES/mobs_mc/rabbit.lua @@ -99,7 +99,7 @@ killer_bunny.on_rightclick = nil killer_bunny.run_velocity = 6 killer_bunny.do_custom = function(self) if not self._killer_bunny_nametag_set then - self.nametag = "The Killer Bunny" + self.nametag = S("The Killer Bunny") self._killer_bunny_nametag_set = true end end diff --git a/mods/HUD/mcl_death_messages/init.lua b/mods/HUD/mcl_death_messages/init.lua index b2c656ac..ff6ef005 100644 --- a/mods/HUD/mcl_death_messages/init.lua +++ b/mods/HUD/mcl_death_messages/init.lua @@ -41,6 +41,9 @@ local msgs = { ["murder"] = { N("@1 was slain by @2 using [@3]"), }, + ["murder_by_named_mob"] = { + N("@1 was slain by @2."), + }, ["murder_any"] = { N("@1 was killed."), }, @@ -212,7 +215,7 @@ minetest.register_on_dieplayer(function(player, reason) end hittersubtype = hitter:get_luaentity().name if hittername then - msg = dmsg("murder", name, hittername) + msg = dmsg("murder_by_named_mob", name, hittername) elseif hittersubtype ~= nil and hittersubtype ~= "" then msg = mmsg(hittersubtype, name) else diff --git a/mods/MAPGEN/mcl_biomes/init.lua b/mods/MAPGEN/mcl_biomes/init.lua index ffb6ae62..66de6c13 100644 --- a/mods/MAPGEN/mcl_biomes/init.lua +++ b/mods/MAPGEN/mcl_biomes/init.lua @@ -2043,7 +2043,7 @@ local function register_dimension_ores() }) -- Nether quartz - if minetest.settings:get("mcl_generate_ores") == "true" then + if minetest.settings:get_bool("mcl_generate_ores", true) then minetest.register_ore({ ore_type = "scatter", ore = "mcl_nether:quartz_ore", diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index d3e792bc..2eed7dfc 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -2207,17 +2207,19 @@ local function basic(vm, data, data2, emin, emax, area, minp, maxp, blockseed) lvm_used = true end + return lvm_used, shadow +end + +local function basic_node(minp, maxp, blockseed) if mg_name ~= "singlenode" then -- Generate special decorations generate_underground_mushrooms(minp, maxp, blockseed) generate_nether_decorations(minp, maxp, blockseed) - generate_structures(minp, maxp, blockseed, biomemap) + generate_structures(minp, maxp, blockseed, minetest.get_mapgen_object("biomemap")) end - - return lvm_used, shadow end -mcl_mapgen_core.register_generator("main", basic, nil, 1, true) +mcl_mapgen_core.register_generator("main", basic, basic_node, 1, true) -- "Trivial" (actually NOT) function to just read the node and some stuff to not just return "ignore", like 5.3.0 does. -- p: Position, if it's wrong, {name="error"} node will return.