diff --git a/.gitattributes b/.gitattributes index 3412304..286e88c 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ -buildscripts export-ignore +buildscripts export-ignore +my_changes export-ignore diff --git a/buildscripts/03_my_updates.sh b/buildscripts/03_my_updates.sh index 104ad49..38dfe72 100755 --- a/buildscripts/03_my_updates.sh +++ b/buildscripts/03_my_updates.sh @@ -2,7 +2,7 @@ LIB="$(realpath $(dirname $0))" # Absolute path PROJ="$(dirname $LIB)" # Game dir (..) -SRC="$PROJ"/../my_changes/ # My changes dir +SRC="$PROJ"/my_changes/ # My changes dir DST="$PROJ"/mods/ # Game mods dir #echo $LIB #echo $PROJ @@ -38,7 +38,7 @@ MOD_PATCH=( ) #patch names #MOD_PATCHES - all patches defined #MOD_PATCHES - first is path and all patch names are separeted by ":" #MOD_PATCHES=("mobs/water_life:poison.patch" "buildings/doors:doors_update.patch" "player/3d_armor:mob_damage.patch" "player/hbsprint:no_damage.patch" "player/hunger_ng:effects.patch") -MOD_PATCHES=("buildings/doors:doors_update.patch" "buildings/doors:doors_update54.patch" "buildings/ts_doors:ts_doors_update54.patch" "player/hbsprint:no_damage.patch" "mobs/mobs_mobkit/water_life:poison.patch" "mobs/mobs_mobkit/water_life:poison_hunger_ng.patch" "buildings/mg_villages:villages.patch" "player/fire_plus:extend_fire.patch" "mobs/mobs_mobs/advanced_npc:adv_npc_log.patch" "mobs/mobs_mobs/advanced_npc:bugtrade184.patch" "mobs/mobs_mobs/mg_villages_npc:bug.patch" "mobs/mobs_mobs/mg_villages_npc:patch_log.patch") +MOD_PATCHES=("buildings/doors:doors_update.patch" "buildings/doors:doors_update54.patch" "buildings/ts_doors:ts_doors_update54.patch" "player/hbsprint:no_damage.patch" "mobs/mobs_mobkit/water_life:poison.patch" "mobs/mobs_mobkit/water_life:poison_hunger_ng.patch" "buildings/mg_villages:villages.patch" "player/fire_plus:extend_fire.patch" "mobs/mobs_mobs/advanced_npc:adv_npc_log.patch" "mobs/mobs_mobs/advanced_npc:bugtrade184.patch" "mobs/mobs_mobs/mg_villages_npc:bug.patch" "mobs/mobs_mobs/mg_villages_npc:patch_log.patch" "gui/i3:progressive_creative.patch") #"mobs/mobs_mobs/goblins:goblins_nil.patch" #MOD_PATCHES=( ) diff --git a/my_changes/LICENSE.txt b/my_changes/LICENSE.txt new file mode 100644 index 0000000..ceb1897 --- /dev/null +++ b/my_changes/LICENSE.txt @@ -0,0 +1,9 @@ +License of my media (textures, sounds, ...) +------------------------------------------- + https://creativecommons.org/licenses/by-sa/3.0/ + +License of my source code +------------------------- + https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html + + or mod licence diff --git a/my_changes/_not-used/environment/dynamic_liquid/bucket.patch b/my_changes/_not-used/environment/dynamic_liquid/bucket.patch new file mode 100644 index 0000000..89a3c03 --- /dev/null +++ b/my_changes/_not-used/environment/dynamic_liquid/bucket.patch @@ -0,0 +1,28 @@ +diff --git a/cooling_lava.lua b/cooling_lava.lua +index 035c4fd..c57da0a 100644 +--- a/cooling_lava.lua ++++ b/cooling_lava.lua +@@ -221,4 +221,21 @@ minetest.register_abm({ + action = function(...) + cool_lava_source(...) + end, +-}) +\ No newline at end of file ++}) ++ ++-- new water types to work with lava cooling ++dynamic_liquid.add_to_water_nodes = function(new_source, new_flowing) ++ -- Flowing liquid ++ table.insert(dynamic_lava_flowing_destroys, new_flowing) ++ table.insert(dynamic_lava_source_destroys, new_flowing) ++ ++ table.insert(all_flowing_nodes, new_flowing) ++ table.insert(all_source_nodes, new_flowing) ++ ++ --Source liquid ++ table.insert(dynamic_lava_source_destroys, new_source) ++ table.insert(dynamic_cools_lava_flowing, new_source) ++ table.insert(dynamic_cools_lava_source, new_source) ++ ++ table.insert(all_source_nodes, new_source) ++end diff --git a/my_changes/_not-used/gui/craftguide/init.lua b/my_changes/_not-used/gui/craftguide/init.lua new file mode 100644 index 0000000..e4853ef --- /dev/null +++ b/my_changes/_not-used/gui/craftguide/init.lua @@ -0,0 +1,2347 @@ +craftguide = {} + +-- Caches +local pdata = {} +local init_items = {} +local searches = {} +local recipes_cache = {} +local usages_cache = {} +local fuel_cache = {} +local replacements = {fuel = {}} +local toolrepair + +local progressive_mode = core.settings:get_bool "craftguide_progressive_mode" + +local http = core.request_http_api() +local singleplayer = core.is_singleplayer() + +local reg_items = core.registered_items +local reg_tools = core.registered_tools +local reg_entities = core.registered_entities +local reg_aliases = core.registered_aliases + +local log = core.log +local after = core.after +local clr = core.colorize +local parse_json = core.parse_json +local write_json = core.write_json +local chat_send = core.chat_send_player +local show_formspec = core.show_formspec +local globalstep = core.register_globalstep +local on_shutdown = core.register_on_shutdown +local get_players = core.get_connected_players +local get_craft_result = core.get_craft_result +local translate = minetest.get_translated_string +local on_joinplayer = core.register_on_joinplayer +local get_all_recipes = core.get_all_craft_recipes +local register_command = core.register_chatcommand +local get_player_by_name = core.get_player_by_name +local slz, dslz = core.serialize, core.deserialize +local on_mods_loaded = core.register_on_mods_loaded +local on_leaveplayer = core.register_on_leaveplayer +local get_player_info = core.get_player_information +local on_receive_fields = core.register_on_player_receive_fields + +local ESC = core.formspec_escape +local S = core.get_translator "craftguide" + +local ES = function(...) + return ESC(S(...)) +end + +local maxn, sort, concat, copy, insert, remove = + table.maxn, table.sort, table.concat, table.copy, + table.insert, table.remove + +local sprintf, find, gmatch, match, sub, split, upper, lower = + string.format, string.find, string.gmatch, string.match, + string.sub, string.split, string.upper, string.lower + +local min, max, floor, ceil, abs = math.min, math.max, math.floor, math.ceil, math.abs +local pairs, ipairs, next, type, setmetatable, tonum = + pairs, ipairs, next, type, setmetatable, tonumber + +local vec_add, vec_mul = vector.add, vector.multiply + +local ROWS = 9 +local LINES = 10 +local IPP = ROWS * LINES +local MAX_FAVS = 6 +local ITEM_BTN_SIZE = 1.1 + +-- Progressive mode +local POLL_FREQ = 0.25 +local HUD_TIMER_MAX = 1.5 + +local PNG = { + bg = "craftguide_bg.png", + bg_full = "craftguide_bg_full.png", + search = "craftguide_search_icon.png", + clear = "craftguide_clear_icon.png", + prev = "craftguide_next_icon.png^\\[transformFX", + next = "craftguide_next_icon.png", + arrow = "craftguide_arrow.png", + fire = "craftguide_fire.png", + fire_anim = "craftguide_fire_anim.png", + book = "craftguide_book.png", + sign = "craftguide_sign.png", + nothing = "craftguide_no.png", + selected = "craftguide_selected.png", + furnace_anim = "craftguide_furnace_anim.png", + + search_hover = "craftguide_search_icon_hover.png", + clear_hover = "craftguide_clear_icon_hover.png", + prev_hover = "craftguide_next_icon_hover.png^\\[transformFX", + next_hover = "craftguide_next_icon_hover.png", +} + +local fs_elements = { + box = "box[%f,%f;%f,%f;%s]", + label = "label[%f,%f;%s]", + image = "image[%f,%f;%f,%f;%s]", + button = "button[%f,%f;%f,%f;%s;%s]", + tooltip = "tooltip[%f,%f;%f,%f;%s]", + item_image = "item_image[%f,%f;%f,%f;%s]", + bg9 = "background9[%f,%f;%f,%f;%s;false;%u]", + model = "model[%f,%f;%f,%f;%s;%s;%s;0,0;true]", + image_button = "image_button[%f,%f;%f,%f;%s;%s;%s]", + animated_image = "animated_image[%f,%f;%f,%f;;%s;%u;%u]", + scrollbar = "scrollbar[%f,%f;%f,%f;horizontal;%s;%u]", + item_image_button = "item_image_button[%f,%f;%f,%f;%s;%s;%s]", + arrow = "image_button[%f,%f;0.7,0.7;%s;%s;;;false;%s]", +} + +local styles = sprintf([[ + style_type[label,field;font_size=+0] + style_type[image_button;border=false;sound=craftguide_click] + style_type[item_image_button;border=false;bgimg_hovered=%s;bgimg_pressed=%s; + sound=craftguide_click] + + style[filter;border=false] + style[search;fgimg=%s;fgimg_hovered=%s] + style[clear;fgimg=%s;fgimg_hovered=%s] + style[prev_page;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] + style[next_page;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] + style[prev_recipe;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] + style[next_recipe;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] + style[prev_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] + style[next_usage;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s] + style[pagenum,no_item,no_rcp;border=false;font=bold;font_size=+2;content_offset=0] + style[craft_rcp,craft_usg;border=false;noclip=true;font_size=+0;sound=craftguide_craft; + bgimg=craftguide_btn9.png;bgimg_hovered=craftguide_btn9_hovered.png; + bgimg_pressed=craftguide_btn9_pressed.png;bgimg_middle=4,6] +]], +PNG.selected, PNG.selected, +PNG.search, PNG.search_hover, +PNG.clear, PNG.clear_hover, +PNG.prev, PNG.prev_hover, PNG.prev_hover, +PNG.next, PNG.next_hover, PNG.next_hover, +PNG.prev, PNG.prev_hover, PNG.prev_hover, +PNG.next, PNG.next_hover, PNG.next_hover, +PNG.prev, PNG.prev_hover, PNG.prev_hover, +PNG.next, PNG.next_hover, PNG.next_hover) + +local function get_lang_code(name) + local info = get_player_info(name) + return info and info.lang_code +end + +local function outdated(name) + local fs = sprintf([[ + size[6.6,1.3] + image[0,0;1,1;%s] + label[1,0;%s] + button_exit[2.8,0.8;1,1;;OK] + ]], + PNG.book, + "Your Minetest client is outdated.\n" .. + "Get the latest version on minetest.net to use the Crafting Guide.") + + return show_formspec(name, "craftguide", fs) +end + +craftguide.group_stereotypes = { + dye = "dye:white", + wool = "wool:white", + wood = "default:wood", + tree = "default:tree", + sand = "default:sand", + glass = "default:glass", + stick = "default:stick", + stone = "default:stone", + leaves = "default:leaves", + coal = "default:coal_lump", + vessel = "vessels:glass_bottle", + flower = "flowers:dandelion_yellow", + water_bucket = "bucket:bucket_water", + mesecon_conductor_craftable = "mesecons:wire_00000000_off", +} + +local group_names = { + dye = S"Any dye", + coal = S"Any coal", + sand = S"Any sand", + tree = S"Any tree", + wool = S"Any wool", + glass = S"Any glass", + stick = S"Any stick", + stone = S"Any stone", + carpet = S"Any carpet", + flower = S"Any flower", + leaves = S"Any leaves", + vessel = S"Any vessel", + wood = S"Any wood planks", + mushroom = S"Any mushroom", + + ["color_red,flower"] = S"Any red flower", + ["color_blue,flower"] = S"Any blue flower", + ["color_black,flower"] = S"Any black flower", + ["color_white,flower"] = S"Any white flower", + ["color_green,flower"] = S"Any green flower", + ["color_orange,flower"] = S"Any orange flower", + ["color_yellow,flower"] = S"Any yellow flower", + ["color_violet,flower"] = S"Any violet flower", + + ["color_red,dye"] = S"Any red dye", + ["color_blue,dye"] = S"Any blue dye", + ["color_grey,dye"] = S"Any grey dye", + ["color_pink,dye"] = S"Any pink dye", + ["color_cyan,dye"] = S"Any cyan dye", + ["color_black,dye"] = S"Any black dye", + ["color_white,dye"] = S"Any white dye", + ["color_brown,dye"] = S"Any brown dye", + ["color_green,dye"] = S"Any green dye", + ["color_orange,dye"] = S"Any orange dye", + ["color_yellow,dye"] = S"Any yellow dye", + ["color_violet,dye"] = S"Any violet dye", + ["color_magenta,dye"] = S"Any magenta dye", + ["color_dark_grey,dye"] = S"Any dark grey dye", + ["color_dark_green,dye"] = S"Any dark green dye", +} + +craftguide.model_alias = { + ["boats:boat"] = {name = "boats:boat", drawtype = "entity"}, + --["carts:cart"] = {name = "carts:cart", drawtype = "entity"}, -- animation broken +} + +local function err(str) + return log("error", str) +end + +local function msg(name, str) + return chat_send(name, sprintf("[craftguide] %s", str)) +end + +local function is_str(x) + return type(x) == "string" +end + +local function true_str(str) + return is_str(str) and str ~= "" +end + +local function is_table(x) + return type(x) == "table" +end + +local function is_func(x) + return type(x) == "function" +end + +local function is_group(item) + return sub(item, 1, 6) == "group:" +end + +local function fmt(elem, ...) + return sprintf(fs_elements[elem], ...) +end + +local function clean_name(item) + if sub(item, 1, 1) == ":" then + item = sub(item, 2) + end + + return item +end + +local function array_diff(t1, t2) + local hash = {} + + for i = 1, #t1 do + local v = t1[i] + hash[v] = true + end + + for i = 1, #t2 do + local v = t2[i] + hash[v] = nil + end + + local diff, c = {}, 0 + + for i = 1, #t1 do + local v = t1[i] + if hash[v] then + c = c + 1 + diff[c] = v + end + end + + return diff +end + +local function table_eq(T1, T2) + local avoid_loops = {} + + local function recurse(t1, t2) + if type(t1) ~= type(t2) then return end + + if not is_table(t1) then + return t1 == t2 + end + + if avoid_loops[t1] then + return avoid_loops[t1] == t2 + end + + avoid_loops[t1] = t2 + local t2k, t2kv = {}, {} + + for k in pairs(t2) do + if is_table(k) then + insert(t2kv, k) + end + + t2k[k] = true + end + + for k1, v1 in pairs(t1) do + local v2 = t2[k1] + if type(k1) == "table" then + local ok + for i = 1, #t2kv do + local tk = t2kv[i] + if table_eq(k1, tk) and recurse(v1, t2[tk]) then + remove(t2kv, i) + t2k[tk] = nil + ok = true + break + end + end + + if not ok then return end + else + if v2 == nil then return end + t2k[k1] = nil + if not recurse(v1, v2) then return end + end + end + + if next(t2k) then return end + return true + end + + return recurse(T1, T2) +end + +local function table_merge(t1, t2, hash) + t1 = t1 or {} + t2 = t2 or {} + + if hash then + for k, v in pairs(t2) do + t1[k] = v + end + else + local c = #t1 + + for i = 1, #t2 do + c = c + 1 + t1[c] = t2[i] + end + end + + return t1 +end + +local function table_replace(t, val, new) + for k, v in pairs(t) do + if v == val then + t[k] = new + end + end +end + +local craft_types = {} + +function craftguide.register_craft_type(name, def) + if not true_str(name) then + return err "craftguide.register_craft_type(): name missing" + end + + if not is_str(def.description) then + def.description = "" + end + + if not is_str(def.icon) then + def.icon = "" + end + + craft_types[name] = def +end + +function craftguide.register_craft(def) + local width, c = 0, 0 + + if true_str(def.url) then + if not http then + return err(sprintf([[craftguide.register_craft(): Unable to reach %s. + No HTTP support for this mod: add it to the `secure.http_mods` or + `secure.trusted_mods` setting.]], def.url)) + end + + http.fetch({url = def.url}, function(result) + if result.succeeded then + local t = parse_json(result.data) + if is_table(t) then + return craftguide.register_craft(t) + end + end + end) + + return + end + + if not is_table(def) or not next(def) then + return err "craftguide.register_craft(): craft definition missing" + end + + if #def > 1 then + for _, v in pairs(def) do + craftguide.register_craft(v) + end + return + end + + if def.result then + def.output = def.result -- Backward compatibility + def.result = nil + end + + if not true_str(def.output) then + return err "craftguide.register_craft(): output missing" + end + + if not is_table(def.items) then + def.items = {} + end + + if def.grid then + if not is_table(def.grid) then + def.grid = {} + end + + if not is_table(def.key) then + def.key = {} + end + + local cp = copy(def.grid) + sort(cp, function(a, b) + return #a > #b + end) + + width = #cp[1] + + for i = 1, #def.grid do + while #def.grid[i] < width do + def.grid[i] = def.grid[i] .. " " + end + end + + for symbol in gmatch(concat(def.grid), ".") do + c = c + 1 + def.items[c] = def.key[symbol] + end + else + local items, len = def.items, #def.items + def.items = {} + + for i = 1, len do + items[i] = items[i]:gsub(",", ", ") + local rlen = #split(items[i], ",") + + if rlen > width then + width = rlen + end + end + + for i = 1, len do + while #split(items[i], ",") < width do + items[i] = items[i] .. ", " + end + end + + for name in gmatch(concat(items, ","), "[%s%w_:]+") do + c = c + 1 + def.items[c] = match(name, "%S+") + end + end + + local item = match(def.output, "%S+") + recipes_cache[item] = recipes_cache[item] or {} + + def.custom = true + def.width = width + + insert(recipes_cache[item], def) +end + +local recipe_filters = {} + +function craftguide.add_recipe_filter(name, f) + if not true_str(name) then + return err "craftguide.add_recipe_filter(): name missing" + elseif not is_func(f) then + return err "craftguide.add_recipe_filter(): function missing" + end + + recipe_filters[name] = f +end + +function craftguide.set_recipe_filter(name, f) + if not is_str(name) then + return err "craftguide.set_recipe_filter(): name missing" + elseif not is_func(f) then + return err "craftguide.set_recipe_filter(): function missing" + end + + recipe_filters = {[name] = f} +end + +function craftguide.remove_recipe_filter(name) + recipe_filters[name] = nil +end + +function craftguide.get_recipe_filters() + return recipe_filters +end + +local function apply_recipe_filters(recipes, player) + for _, filter in pairs(recipe_filters) do + recipes = filter(recipes, player) + end + + return recipes +end + +local search_filters = {} + +function craftguide.add_search_filter(name, f) + if not true_str(name) then + return err "craftguide.add_search_filter(): name missing" + elseif not is_func(f) then + return err "craftguide.add_search_filter(): function missing" + end + + search_filters[name] = f +end + +function craftguide.remove_search_filter(name) + search_filters[name] = nil +end + +function craftguide.get_search_filters() + return search_filters +end + +local function weird_desc(str) + return not true_str(str) or find(str, "\n") or not find(str, "%u") +end + +local function toupper(str) + return str:gsub("%f[%w]%l", upper):gsub("_", " ") +end + +local function snip(str, limit) + return #str > limit and sprintf("%s...", sub(str, 1, limit - 3)) or str +end + +local function get_desc(item, lang_code) + if sub(item, 1, 1) == "_" then + item = sub(item, 2) + end + + local def = reg_items[item] + + if def then + local desc = def.description + desc = lang_code and translate(lang_code, desc) or desc + + if true_str(desc) then + desc = desc:trim():match("[^\n]*") + + if not find(desc, "%u") then + desc = toupper(desc) + end + + return desc + + elseif true_str(item) then + return toupper(match(item, ":(.*)")) + end + end + + return S("Unknown Item (@1)", item) +end + +local function item_has_groups(item_groups, groups) + for i = 1, #groups do + local group = groups[i] + if (item_groups[group] or 0) == 0 then return end + end + + return true +end + +local function extract_groups(str) + if sub(str, 1, 6) == "group:" then + return split(sub(str, 7), ",") + end +end + +local function get_filtered_items(player, data) + local items, known, c = {}, 0, 0 + + for i = 1, #init_items do + local item = init_items[i] + local recipes = recipes_cache[item] + local usages = usages_cache[item] + + recipes = #apply_recipe_filters(recipes or {}, player) + usages = #apply_recipe_filters(usages or {}, player) + + if recipes > 0 or usages > 0 then + c = c + 1 + items[c] = item + + if data then + known = known + recipes + usages + end + end + end + + if data then + data.known_recipes = known + end + + return items +end + +local function get_burntime(item) + return get_craft_result{method = "fuel", items = {item}}.time +end + +local function cache_fuel(item) + local burntime = get_burntime(item) + if burntime > 0 then + fuel_cache[item] = { + type = "fuel", + items = {item}, + burntime = burntime, + replacements = replacements.fuel[item], + } + end +end + +local function show_item(def) + return def and not (def.groups.not_in_craft_guide == 1 or + def.groups.not_in_creative_inventory == 1) and + def.description and def.description ~= "" +end + +local function get_usages(recipe) + local added = {} + + for _, item in pairs(recipe.items) do + item = reg_aliases[item] or item + if not added[item] then + local groups = extract_groups(item) + if groups then + for name, def in pairs(reg_items) do + if not added[name] and show_item(def) and + item_has_groups(def.groups, groups) then + local usage = copy(recipe) + table_replace(usage.items, item, name) + usages_cache[name] = usages_cache[name] or {} + insert(usages_cache[name], 1, usage) + added[name] = true + end + end + elseif show_item(reg_items[item]) then + usages_cache[item] = usages_cache[item] or {} + insert(usages_cache[item], 1, recipe) + end + + added[item] = true + end + end +end + +local function cache_usages(item) + local recipes = recipes_cache[item] or {} + + for i = 1, #recipes do + get_usages(recipes[i]) + end + + if fuel_cache[item] then + usages_cache[item] = table_merge(usages_cache[item] or {}, {fuel_cache[item]}) + end +end + +local function drop_table(name, drop) + local count_sure = 0 + local drop_items = drop.items or {} + local max_items = drop.max_items + + for i = 1, #drop_items do + local di = drop_items[i] + local valid_rarity = di.rarity and di.rarity > 1 + + if di.rarity or not max_items or + (max_items and not di.rarity and count_sure < max_items) then + for j = 1, #di.items do + local dstack = ItemStack(di.items[j]) + local dname = dstack:get_name() + local dcount = dstack:get_count() + local empty = dstack:is_empty() + + if not empty and (dname ~= name or + (dname == name and dcount > 1)) then + local rarity = valid_rarity and di.rarity + + craftguide.register_craft{ + type = rarity and "digging_chance" or "digging", + items = {name}, + output = sprintf("%s %u", dname, dcount), + rarity = rarity, + tools = di.tools, + } + end + end + end + + if not di.rarity then + count_sure = count_sure + 1 + end + end +end + +local function cache_drops(name, drop) + if true_str(drop) then + local dstack = ItemStack(drop) + local dname = dstack:get_name() + local empty = dstack:is_empty() + + if not empty and dname ~= name then + craftguide.register_craft{ + type = "digging", + items = {name}, + output = drop, + } + end + elseif is_table(drop) then + drop_table(name, drop) + end +end + +local function cache_recipes(item) + local recipes = get_all_recipes(item) + + if replacements[item] then + local _recipes = {} + + for k, v in ipairs(recipes or {}) do + _recipes[#recipes + 1 - k] = v + end + + local shift = 0 + local size_rpl = maxn(replacements[item]) + local size_rcp = #_recipes + + if size_rpl > size_rcp then + shift = size_rcp - size_rpl + end + + for k, v in pairs(replacements[item]) do + k = k + shift + + if _recipes[k] then + _recipes[k].replacements = v + end + end + + recipes = _recipes + end + + if recipes then + recipes_cache[item] = table_merge(recipes, recipes_cache[item] or {}) + end +end + +local function get_recipes(item, data, player) + local clean_item = reg_aliases[item] or item + local recipes = recipes_cache[clean_item] + local usages = usages_cache[clean_item] + + if recipes then + recipes = apply_recipe_filters(recipes, player) + end + + local no_recipes = not recipes or #recipes == 0 + if no_recipes and not usages then return end + usages = apply_recipe_filters(usages, player) + + local no_usages = not usages or #usages == 0 + + return not no_recipes and recipes or nil, + not no_usages and usages or nil +end + +local function groups_to_items(groups, get_all) + if not get_all and #groups == 1 then + local group = groups[1] + local stereotype = craftguide.group_stereotypes[group] + local def = reg_items[stereotype] + + if def and show_item(def) then + return stereotype + end + end + + local names = {} + for name, def in pairs(reg_items) do + if show_item(def) and item_has_groups(def.groups, groups) then + if get_all then + names[#names + 1] = name + else + return name + end + end + end + + return get_all and names or "" +end + +local function get_stack_max(data, is_recipe, rcp) + data.inv = data.player:get_inventory() + local list = data.inv:get_list("main") + local size = data.inv:get_size("main") + local counts_inv, counts_rcp, counts = {}, {}, {} + local rcp_usg = is_recipe and "recipe" or "usage" + + for _, it in pairs(rcp.items) do + counts_rcp[it] = (counts_rcp[it] or 0) + 1 + end + + data.export_counts[rcp_usg] = {} + data.export_counts[rcp_usg].rcp = counts_rcp + + for i = 1, size do + local stack = list[i] + + if not stack:is_empty() then + local item = stack:get_name() + local count = stack:get_count() + + for name in pairs(counts_rcp) do + if is_group(name) then + local def = reg_items[item] + local groups = extract_groups(name) + + if item_has_groups(def.groups, groups) then + counts_inv[name] = (counts_inv[name] or 0) + count + end + end + end + + counts_inv[item] = (counts_inv[item] or 0) + count + end + end + + data.export_counts[rcp_usg].inv = counts_inv + + for name in pairs(counts_rcp) do + counts[name] = floor((counts_inv[name] or 0) / (counts_rcp[name] or 0)) + end + + local max_stacks = math.huge + + for _, count in pairs(counts) do + if count < max_stacks then + max_stacks = count + end + end + + return max_stacks +end + +local function craft_stack(player, pname, data, craft_rcp) + local rcp_usg = craft_rcp and "recipe" or "usage" + local output = craft_rcp and data.recipes[data.rnum].output or data.usages[data.unum].output + output = ItemStack(output) + local stackname, stackcount = output:get_name(), output:get_count() + local scrbar_val = data[sprintf("scrbar_%s", craft_rcp and "rcp" or "usg")] or 1 + + for name, count in pairs(data.export_counts[rcp_usg].rcp) do + local items = {[name] = count} + + if is_group(name) then + items = {} + local groups = extract_groups(name) + local item_groups = groups_to_items(groups, true) + local remaining = count + + for _, item in ipairs(item_groups) do + for _name, _count in pairs(data.export_counts[rcp_usg].inv) do + if item == _name and remaining > 0 then + local c = min(remaining, _count) + items[item] = c + remaining = remaining - c + end + + if remaining == 0 then break end + end + end + end + + for k, v in pairs(items) do + data.inv:remove_item("main", sprintf("%s %s", k, v * scrbar_val)) + end + end + + local count = stackcount * scrbar_val + local stack = ItemStack(sprintf("%s %s", stackname, count)) + local desc = get_desc(stackname) + local message + + if count > 1 then + message = clr("#ff0", sprintf("%s x %s", count, desc)) + else + message = clr("#ff0", sprintf("%s", desc)) + end + + if data.inv:room_for_item("main", stack) then + data.inv:add_item("main", stack) + msg(pname, sprintf("%s added in your inventory", message)) + else + local dir = player:get_look_dir() + local ppos = player:get_pos() + ppos.y = ppos.y + 1.625 + local look_at = vec_add(ppos, vec_mul(dir, 1)) + + core.add_item(look_at, stack) + msg(pname, sprintf("%s crafted", message)) + end +end + +local function select_item(player, data, _f) + local item + + for field in pairs(_f) do + if find(field, ":") then + item = field + break + end + end + + if not item then + return + elseif sub(item, -4) == "_inv" then + item = sub(item, 1, -5) + elseif sub(item, 1, 1) == "_" then + item = sub(item, 2) + elseif sub(item, 1, 6) == "group|" then + item = match(item, "([%w:_]+)$") + end + + item = reg_aliases[item] or item + + if item == data.query_item then return end + + local recipes, usages = get_recipes(item, data, player) + if not recipes and not usages then return end + if data.show_usages and not usages then return end + + data.query_item = item + data.recipes = recipes + data.usages = usages + data.rnum = 1 + data.unum = 1 + data.scrbar_rcp = 1 + data.scrbar_usg = 1 + data.export_rcp = nil + data.export_usg = nil +end + +local function repairable(tool) + local def = reg_tools[tool] + return toolrepair and def and def.groups and def.groups.disable_repair ~= 1 +end + +local function is_fav(favs, query_item) + local fav, i + for j = 1, #favs do + if favs[j] == query_item then + fav = true + i = j + break + end + end + + return fav, i +end + +local function get_tooltip(item, info) + local tooltip + + if info.groups then + sort(info.groups) + tooltip = group_names[concat(info.groups, ",")] + + if not tooltip then + local groupstr = {} + + for i = 1, #info.groups do + insert(groupstr, clr("#ff0", info.groups[i])) + end + + groupstr = concat(groupstr, ", ") + tooltip = S("Any item belonging to the group(s): @1", groupstr) + end + else + tooltip = get_desc(item) + end + + local function add(str) + return sprintf("%s\n%s", tooltip, str) + end + + if info.cooktime then + tooltip = add(S("Cooking time: @1", clr("#ff0", info.cooktime))) + end + + if info.burntime then + tooltip = add(S("Burning time: @1", clr("#ff0", info.burntime))) + end + + if info.replace then + for i = 1, #info.replace.items do + local rpl = match(info.replace.items[i], "%S+") + local desc = clr("#ff0", get_desc(rpl)) + + if info.replace.type == "cooking" then + tooltip = add(S("Replaced by @1 on smelting", desc)) + elseif info.replace.type == "fuel" then + tooltip = add(S("Replaced by @1 on burning", desc)) + else + tooltip = add(S("Replaced by @1 on crafting", desc)) + end + end + end + + if info.repair then + tooltip = add(S("Repairable by step of @1", clr("#ff0", toolrepair .. "%"))) + end + + if info.rarity then + local chance = (1 / max(1, info.rarity)) * 100 + tooltip = add(S("@1 of chance to drop", clr("#ff0", chance .. "%"))) + end + + if info.tools then + local several = #info.tools > 1 + local names = several and "\n" or "" + + if several then + for i = 1, #info.tools do + names = sprintf("%s\t\t- %s\n", + names, clr("#ff0", get_desc(info.tools[i]))) + end + + tooltip = add(S("Only drop if using one of these tools: @1", + sub(names, 1, -2))) + else + tooltip = add(S("Only drop if using this tool: @1", + clr("#ff0", get_desc(info.tools[1])))) + end + end + + return sprintf("tooltip[%s;%s]", item, ESC(tooltip)) +end + +local function get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_size, _btn_size) + local custom_recipe = craft_types[rcp.type] + + if custom_recipe or shapeless or rcp.type == "cooking" then + local icon = custom_recipe and custom_recipe.icon or + shapeless and "shapeless" or "furnace" + + if not custom_recipe then + icon = sprintf("craftguide_%s.png^[resize:16x16", icon) + end + + local pos_x = right + btn_size + 0.42 + local pos_y = data.yoffset + 0.9 + + if sub(icon, 1, 18) == "craftguide_furnace" then + fs(fmt("animated_image", pos_x, pos_y, 0.5, 0.5, PNG.furnace_anim, 8, 180)) + else + fs(fmt("image", pos_x, pos_y, 0.5, 0.5, icon)) + end + + local tooltip = custom_recipe and custom_recipe.description or + shapeless and S"Shapeless" or S"Cooking" + + fs(fmt("tooltip", pos_x, pos_y, 0.5, 0.5, ESC(tooltip))) + end + + local arrow_X = right + 0.2 + (_btn_size or ITEM_BTN_SIZE) + local X = arrow_X + 1.2 + local Y = data.yoffset + 1.4 + + fs(fmt("image", arrow_X, Y + 0.06, 1, 1, PNG.arrow)) + + if rcp.type == "fuel" then + fs(fmt("animated_image", X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.fire_anim, 8, 180)) + else + local item = rcp.output + item = ItemStack(clean_name(item)) + local name = item:get_name() + local count = item:get_count() + local bt_s = ITEM_BTN_SIZE * 1.2 + + fs(fmt("image", X, Y - 0.11, bt_s, bt_s, PNG.selected)) + + local _name = sprintf("_%s", name) + + fs(fmt("item_image_button", X + 0.1, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, + sprintf("%s %u", name, + count * (is_recipe and data.scrbar_rcp or data.scrbar_usg or 1)), + _name, "")) + + local def = reg_items[name] + local unknown = not def or nil + local desc = def and def.description + local weird = name ~= "" and desc and weird_desc(desc) or nil + local burntime = fuel_cache[name] and fuel_cache[name].burntime + + local infos = { + unknown = unknown, + weird = weird, + burntime = burntime, + repair = repairable(name), + rarity = rcp.rarity, + tools = rcp.tools, + } + + if next(infos) then + fs(get_tooltip(_name, infos)) + end + end +end + +local function get_grid_fs(fs, data, rcp, is_recipe) + local width = rcp.width or 1 + local right, btn_size, _btn_size = 0, ITEM_BTN_SIZE + local cooktime, shapeless + + if rcp.type == "cooking" then + cooktime, width = width, 1 + elseif width == 0 and not rcp.custom then + shapeless = true + local n = #rcp.items + width = (n < 5 and n > 1) and 2 or min(3, max(1, n)) + end + + local rows = ceil(maxn(rcp.items) / width) + local large_recipe = width > 3 or rows > 3 + + if large_recipe then + fs("style_type[item_image_button;border=true]") + end + + for i = 1, width * rows do + local item = rcp.items[i] or "" + item = clean_name(item) + local name = match(item, "%S*") + + local X = ceil((i - 1) % width - width) + X = X + (X * 0.2) + data.xoffset + 3.9 + + local Y = ceil(i / width) - min(2, rows) + Y = Y + (Y * 0.15) + data.yoffset + 1.4 + + if large_recipe then + btn_size = (3 / width) * (3 / rows) + 0.3 + _btn_size = btn_size + + local xi = (i - 1) % width + local yi = floor((i - 1) / width) + + X = btn_size * xi + data.xoffset + 0.3 + (xi * 0.05) + Y = btn_size * yi + data.yoffset + 0.2 + (yi * 0.05) + end + + if X > right then + right = X + end + + local groups + + if is_group(name) then + groups = extract_groups(name) + item = groups_to_items(groups) + end + + local label = groups and "\nG" or "" + local replace + + for j = 1, #(rcp.replacements or {}) do + local replacement = rcp.replacements[j] + if replacement[1] == name then + replace = replace or {type = rcp.type, items = {}} + + local added + + for _, v in ipairs(replace.items) do + if replacement[2] == v then + added = true + break + end + end + + if not added then + label = sprintf("%s%s\nR", label ~= "" and "\n" or "", label) + replace.items[#replace.items + 1] = replacement[2] + end + end + end + + if not large_recipe then + fs(fmt("image", X, Y, btn_size, btn_size, PNG.selected)) + end + + local btn_name = groups and sprintf("group|%s|%s", groups[1], item) or item + + fs(fmt("item_image_button", X, Y, btn_size, btn_size, + sprintf("%s %u", item, is_recipe and data.scrbar_rcp or data.scrbar_usg or 1), + btn_name, label)) + + local def = reg_items[name] + local unknown = not def or nil + unknown = not groups and unknown or nil + local desc = def and def.description + local weird = name ~= "" and desc and weird_desc(desc) or nil + local burntime = fuel_cache[name] and fuel_cache[name].burntime + + local infos = { + unknown = unknown, + weird = weird, + groups = groups, + burntime = burntime, + cooktime = cooktime, + replace = replace, + } + + if next(infos) then + fs(get_tooltip(btn_name, infos)) + end + end + + if large_recipe then + fs("style_type[item_image_button;border=false]") + end + + get_output_fs(fs, data, rcp, is_recipe, shapeless, right, btn_size, _btn_size) +end + +local function get_rcp_lbl(fs, data, panel, rn, is_recipe) + local lbl = ES("Usage @1 of @2", data.unum, rn) + + if is_recipe then + lbl = ES("Recipe @1 of @2", data.rnum, rn) + end + + local _lbl = translate(data.lang_code, lbl) + local lbl_len = #_lbl:gsub("[\128-\191]", "") -- Count chars, not bytes in UTF-8 strings + local shift = min(0.9, abs(12 - max(12, lbl_len)) * 0.15) + + fs(fmt("label", data.xoffset + 5.65 - shift, data.yoffset + 3.37, lbl)) + + if rn > 1 then + local btn_suffix = is_recipe and "recipe" or "usage" + local prev_name = sprintf("prev_%s", btn_suffix) + local next_name = sprintf("next_%s", btn_suffix) + local x_arrow = data.xoffset + 4.9 + local y_arrow = data.yoffset + 3 + + fs(fmt("arrow", x_arrow - shift, y_arrow, PNG.prev, prev_name, ""), + fmt("arrow", x_arrow + 2.3, y_arrow, PNG.next, next_name, "")) + end + + local rcp = is_recipe and panel.rcp[data.rnum] or panel.rcp[data.unum] + get_grid_fs(fs, data, rcp, is_recipe) +end + +local function get_model_fs(fs, data, def, model_alias) + if model_alias then + if model_alias.drawtype == "entity" then + def = reg_entities[model_alias.name] + local init_props = def.initial_properties + def.textures = init_props and init_props.textures or def.textures + def.mesh = init_props and init_props.mesh or def.mesh + else + def = reg_items[model_alias.name] + end + end + + local tiles = def.tiles or def.textures or {} + local t = {} + + for _, v in ipairs(tiles) do + local _name + + if v.color then + local hex = sprintf("%02x", v.color) + + while #hex < 8 do + hex = "0" .. hex + end + + _name = sprintf("%s^[multiply:%s", v.name, + sprintf("#%s%s", sub(hex, 3), sub(hex, 1, 2))) + + elseif v.animation then + _name = sprintf("%s^[verticalframe:%u:0", v.name, v.animation.aspect_h) + end + + t[#t + 1] = _name or v.name or v + end + + while #t < 6 do + t[#t + 1] = t[#t] + end + + fs(fmt("model", + data.xoffset + 6.6, data.yoffset + 0.05, 1.3, 1.3, "", def.mesh, concat(t, ","))) +end + +local function get_title_fs(fs, data) + local fav = is_fav(data.favs, data.query_item) + local nfavs = #data.favs + local star_x, star_y, star_size = data.xoffset + 0.4, data.yoffset + 0.5, 0.4 + + if nfavs < MAX_FAVS or (nfavs == MAX_FAVS and fav) then + local fav_marked = sprintf("craftguide_fav%s.png", fav and "_off" or "") + + fs(sprintf("style[fav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]", + sprintf("craftguide_fav%s.png", fav and "" or "_off"), fav_marked, fav_marked), + fmt("image_button", star_x, star_y, star_size, star_size, "", "fav", ""), + sprintf("tooltip[fav;%s]", fav and ES"Unmark this item" or ES"Mark this item")) + else + fs(sprintf("style[nofav;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]", + "craftguide_fav_off.png", PNG.nothing, PNG.nothing), + fmt("image_button", star_x, star_y, star_size, star_size, "", "nofav", ""), + sprintf("tooltip[nofav;%s]", ES"Cannot mark this item. Bookmark limit reached.")) + end + + fs("style_type[label;font=bold;font_size=+6]", + fmt("label", data.xoffset + 1.05, data.yoffset + 0.47, + snip(ESC(get_desc(data.query_item, data.lang_code)), 32)), + "style_type[label;font=mono;font_size=+0]", + fmt("label", data.xoffset + 1.05, data.yoffset + 0.97, + clr("#7bf", snip(data.query_item, 34))), + "style_type[label;font=normal]") + + local def = reg_items[data.query_item] + local model_alias = craftguide.model_alias[data.query_item] + + if def.drawtype == "mesh" or model_alias then + get_model_fs(fs, data, def, model_alias) + else + fs(fmt("item_image", + data.xoffset + 6.8, data.yoffset + 0.17, 1.1, 1.1, data.query_item)) + end +end + +local function get_export_fs(fs, data, panel, is_recipe, is_usage, max_stacks_rcp, max_stacks_usg) + local name = is_recipe and "rcp" or "usg" + local show_export = (is_recipe and data.export_rcp) or (is_usage and data.export_usg) + + fs(sprintf("style[export_%s;fgimg=%s;fgimg_hovered=%s;fgimg_pressed=%s]", + name, sprintf("craftguide_export%s.png", show_export and "" or "_off"), + "craftguide_export.png", "craftguide_export.png"), + fmt("image_button", + data.xoffset + 7.35, data.yoffset + 0.2, 0.45, 0.45, "", + sprintf("export_%s", name), ""), + sprintf("tooltip[export_%s;%s]", name, ES"Craft this stack")) + + if not show_export then return end + + local item = (is_recipe and panel.rcp[data.rnum].output) or + (is_usage and panel.rcp[data.unum].output) + item = clean_name(item) + local _name = match(item, "%S*") + local stack = ItemStack(_name) + local stack_max = stack:get_stack_max() + local craft_max = is_recipe and max_stacks_rcp or max_stacks_usg + local stack_fs = (is_recipe and data.scrbar_rcp) or (is_usage and data.scrbar_usg) or 1 + + if stack_fs > craft_max then + stack_fs = craft_max + + if is_recipe then + data.scrbar_rcp = craft_max + elseif is_usage then + data.scrbar_usg = craft_max + end + end + + fs(sprintf("style[scrbar_%s;noclip=true]", name), + sprintf("scrollbaroptions[min=1;max=%u;smallstep=1]", min(craft_max, stack_max)), + fmt("scrollbar", + data.xoffset + 8.1, data.yoffset, 3, 0.35, sprintf("scrbar_%s", name), stack_fs), + fmt("button", data.xoffset + 8.1, data.yoffset + 0.4, 3, 0.7, sprintf("craft_%s", name), + sprintf("%s", sprintf(stack_fs > 1 and ES"Craft %u stacks" or ES"Craft %u stack", + stack_fs)))) +end + +local function get_rcp_extra(fs, data, panel, is_recipe, is_usage) + local rn = panel.rcp and #panel.rcp + + if rn then + local rcp_normal = is_recipe and panel.rcp[data.rnum].type == "normal" + local usg_normal = is_usage and panel.rcp[data.unum].type == "normal" + local max_stacks_rcp, max_stacks_usg = 0, 0 + + if rcp_normal then + max_stacks_rcp = get_stack_max(data, is_recipe, panel.rcp[data.rnum]) + end + + if usg_normal then + max_stacks_usg = get_stack_max(data, is_recipe, panel.rcp[data.unum]) + end + + if is_recipe and max_stacks_rcp == 0 then + data.export_rcp = nil + data.scrbar_rcp = 1 + elseif is_usage and max_stacks_usg == 0 then + data.export_usg = nil + data.scrbar_usg = 1 + end + + if max_stacks_rcp > 0 or max_stacks_usg > 0 then + get_export_fs(fs, data, panel, is_recipe, is_usage, max_stacks_rcp, + max_stacks_usg) + end + + get_rcp_lbl(fs, data, panel, rn, is_recipe) + else + local lbl = is_recipe and ES"No recipes" or ES"No usages" + fs(fmt("button", + data.xoffset + 0.1, data.yoffset + (panel.height / 2) - 0.5, + 7.8, 1, "no_rcp", lbl)) + end +end + +local function get_favs(fs, data) + fs(fmt("label", data.xoffset + 0.4, data.yoffset + 0.4, ES"Bookmarks")) + + for i = 1, #data.favs do + local item = data.favs[i] + local X = data.xoffset - 0.7 + (i * 1.2) + local Y = data.yoffset + 0.8 + + if data.query_item == item then + fs(fmt("image", X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, PNG.selected)) + end + + fs(fmt("item_image_button", X, Y, ITEM_BTN_SIZE, ITEM_BTN_SIZE, item, item, "")) + end +end + +local function get_panels(fs, data) + local _title = {name = "title", height = 1.4} + local _favs = {name = "favs", height = 2.2} + local _recipes = {name = "recipes", rcp = data.recipes, height = 3.9} + local _usages = {name = "usages", rcp = data.usages, height = 3.9} + local panels = {_title, _recipes, _usages, _favs} + + for idx = 1, #panels do + local panel = panels[idx] + data.yoffset = 0 + + if idx > 1 then + for _idx = idx - 1, 1, -1 do + data.yoffset = data.yoffset + panels[_idx].height + 0.1 + end + end + + fs(fmt("bg9", data.xoffset + 0.1, data.yoffset, 7.9, panel.height, PNG.bg_full, 10)) + + local is_recipe, is_usage = panel.name == "recipes", panel.name == "usages" + + if is_recipe or is_usage then + get_rcp_extra(fs, data, panel, is_recipe, is_usage) + elseif panel.name == "title" then + get_title_fs(fs, data) + elseif panel.name == "favs" then + get_favs(fs, data) + end + end +end + +local function make_fs(data) + local fs = setmetatable({}, { + __call = function(t, ...) + t[#t + 1] = concat({...}) + end + }) + + data.xoffset = ROWS + 1.04 + + fs(sprintf([[ + formspec_version[%u] + size[%f,%f] + no_prepend[] + bgcolor[#0000] + ]], + MIN_FORMSPEC_VERSION, data.xoffset + (data.query_item and 8 or 0), LINES + 1.7), styles) + + fs(fmt("bg9", 0, 0, data.xoffset, LINES + 1.7, PNG.bg_full, 10)) + + fs(sprintf([[ + box[0.2,0.2;3.5,0.6;#bababa25] + set_focus[filter] + field[0.2,0.2;3.5,0.6;filter;;%s] + field_close_on_enter[filter;false] + ]], ESC(data.filter)), + fmt("image_button", 3.75, 0.15, 0.7, 0.7, "", "search", ""), + fmt("image_button", 4.43, 0.15, 0.7, 0.7, "", "clear", "")) + + fs(fmt("image_button", data.xoffset - 3.2, 0.15, 0.7, 0.7, "", "prev_page", ""), + fmt("image_button", data.xoffset - 0.7, 0.15, 0.7, 0.7, "", "next_page", "")) + + data.pagemax = max(1, ceil(#data.items / IPP)) + + fs(fmt("button", + data.xoffset - 2.53, 0.15, 1.88, 0.7, "pagenum", + sprintf("%s / %u", clr("#ff0", data.pagenum), data.pagemax))) + + if #data.items == 0 then + local lbl = ES"No item to show" + + if next(recipe_filters) and #init_items > 0 and data.filter == "" then + lbl = ES"Collect items to reveal more recipes" + end + + fs(fmt("button", 0, 3, data.xoffset, 1, "no_item", lbl)) + end + + local first_item = (data.pagenum - 1) * IPP + + for i = first_item, first_item + IPP - 1 do + local item = data.items[i + 1] + if not item then break end + + local X = i % ROWS + X = X + (X * 0.08) + 0.2 + + local Y = (i % IPP - X) / ROWS + 1 + Y = Y + (Y * 0.06) + + if data.query_item == item then + fs(fmt("image", X, Y, 1, 1, PNG.selected)) + end + + fs(fmt("item_image_button", X, Y, 1, 1, item, sprintf("%s_inv", item), "")) + end + + if (data.recipes and #data.recipes > 0) or (data.usages and #data.usages > 0) then + get_panels(fs, data) + end + + return concat(fs) +end + +local show_fs = function(player, name) + local data = pdata[name] + show_formspec(name, "craftguide", make_fs(data)) +end + +craftguide.register_craft_type("digging", { + description = ES"Digging", + icon = "craftguide_steelpick.png", +}) + +craftguide.register_craft_type("digging_chance", { + description = ES"Digging (by chance)", + icon = "craftguide_mesepick.png", +}) + +local function search(data) + local filter = data.filter + + if searches[filter] then + data.items = searches[filter] + return + end + + local opt = "^(.-)%+([%w_]+)=([%w_,]+)" + local search_filter = next(search_filters) and match(filter, opt) + local filters = {} + + if search_filter then + for filter_name, values in gmatch(filter, sub(opt, 6)) do + if search_filters[filter_name] then + values = split(values, ",") + filters[filter_name] = values + end + end + end + + local filtered_list, c = {}, 0 + + for i = 1, #data.items_raw do + local item = data.items_raw[i] + local def = reg_items[item] + local desc = lower(translate(data.lang_code, def and def.description)) or "" + local search_in = sprintf("%s %s", item, desc) + local to_add + + if search_filter then + for filter_name, values in pairs(filters) do + if values then + local func = search_filters[filter_name] + to_add = func(item, values) and (search_filter == "" or + find(search_in, search_filter, 1, true)) + end + end + else + to_add = find(search_in, filter, 1, true) + end + + if to_add then + c = c + 1 + filtered_list[c] = item + end + end + + if not next(recipe_filters) then + -- Cache the results only if searched 2 times + if searches[filter] == nil then + searches[filter] = false + else + searches[filter] = filtered_list + end + end + + data.items = filtered_list +end + +craftguide.add_search_filter("groups", function(item, groups) + local def = reg_items[item] + local has_groups = true + + for i = 1, #groups do + local group = groups[i] + if not def.groups[group] then + has_groups = nil + break + end + end + + return has_groups +end) + +--[[ As `core.get_craft_recipe` and `core.get_all_craft_recipes` do not + return the fuel, replacements and toolrepair recipes, we have to + override `core.register_craft` and do some reverse engineering. + See engine's issues #4901, #5745 and #8920. ]] + +local old_register_craft = core.register_craft +local rcp_num = {} + +core.register_craft = function(def) + old_register_craft(def) + + if def.type == "toolrepair" then + toolrepair = def.additional_wear * -100 + end + + local output = def.output or (true_str(def.recipe) and def.recipe) or nil + if not output then return end + output = {match(output, "%S+")} + + local groups + + if is_group(output[1]) then + groups = extract_groups(output[1]) + output = groups_to_items(groups, true) + end + + for i = 1, #output do + local item = output[i] + rcp_num[item] = (rcp_num[item] or 0) + 1 + + if def.replacements then + if def.type == "fuel" then + replacements.fuel[item] = def.replacements + else + replacements[item] = replacements[item] or {} + replacements[item][rcp_num[item]] = def.replacements + end + end + end +end + +local old_clear_craft = core.clear_craft + +core.clear_craft = function(def) + old_clear_craft(def) + + if true_str(def) then + return -- TODO + elseif is_table(def) then + return -- TODO + end +end + +local function resolve_aliases(hash) + for oldname, newname in pairs(reg_aliases) do + cache_recipes(oldname) + local recipes = recipes_cache[oldname] + + if recipes then + if not recipes_cache[newname] then + recipes_cache[newname] = {} + end + + local similar + + for i = 1, #recipes_cache[oldname] do + local rcp_old = recipes_cache[oldname][i] + + for j = 1, #recipes_cache[newname] do + local rcp_new = copy(recipes_cache[newname][j]) + rcp_new.output = oldname + + if table_eq(rcp_old, rcp_new) then + similar = true + break + end + end + + if not similar then + insert(recipes_cache[newname], rcp_old) + end + end + end + + if newname ~= "" and recipes_cache[oldname] and not hash[newname] then + init_items[#init_items + 1] = newname + end + end +end + +local function get_init_items() + local _select, _preselect = {}, {} + + for name, def in pairs(reg_items) do + if name ~= "" and show_item(def) then + cache_drops(name, def.drop) + cache_fuel(name) + cache_recipes(name) + + _preselect[name] = true + end + end + + for name in pairs(_preselect) do + cache_usages(name) + end + + for name in pairs(_preselect) do + if recipes_cache[name] or usages_cache[name] then + init_items[#init_items + 1] = name + _select[name] = true + end + end + + resolve_aliases(_select) + sort(init_items) + + if http and true_str(craftguide.export_url) then + local post_data = { + recipes = recipes_cache, + usages = usages_cache, + } + + http.fetch_async{ + url = craftguide.export_url, + post_data = write_json(post_data), + } + end +end + +local function init_data(name) + pdata[name] = { +<<<<<<< HEAD + filter = "", + pagenum = 1, + items = init_items, + items_raw = init_items, + favs = {}, + lang_code = get_lang_code(name), +======= + filter = "", + pagenum = 1, + items = init_items, + items_raw = init_items, + favs = {}, + export_counts = {}, + lang_code = get_lang_code(info), + fs_version = get_formspec_version(info), + player = get_player_by_name(name), +>>>>>>> origin/master + } +end + +local function reset_data(data) + data.filter = "" + data.pagenum = 1 + data.rnum = 1 + data.unum = 1 + data.scrbar_rcp = 1 + data.scrbar_usg = 1 + data.query_item = nil + data.recipes = nil + data.usages = nil + data.show_usages = nil + data.export_rcp = nil + data.export_usg = nil + data.items = data.items_raw +end + +on_mods_loaded(get_init_items) + +on_joinplayer(function(player) + local name = player:get_player_name() + init_data(name) + + if not pdata[name].lang_code then + outdated(name) + end +end) + +local function fields(player, _f) + if _f.quit then return end + local name = player:get_player_name() + local data = pdata[name] + local sb_rcp, sb_usg = _f.scrbar_rcp, _f.scrbar_usg + + if _f.clear then + reset_data(data) + + elseif _f.prev_recipe or _f.next_recipe then + local num = data.rnum + (_f.prev_recipe and -1 or 1) + data.rnum = data.recipes[num] and num or (_f.prev_recipe and #data.recipes or 1) + data.export_rcp = nil + data.scrbar_rcp = 1 + + elseif _f.prev_usage or _f.next_usage then + local num = data.unum + (_f.prev_usage and -1 or 1) + data.unum = data.usages[num] and num or (_f.prev_usage and #data.usages or 1) + data.export_usg = nil + data.scrbar_usg = 1 + + elseif _f.key_enter_field == "filter" or _f.search then + if _f.filter == "" then + reset_data(data) + return true, show_fs(player, name) + end + + local str = lower(_f.filter) + if data.filter == str then return end + + data.filter = str + data.pagenum = 1 + + search(data) + + elseif _f.prev_page or _f.next_page then + if data.pagemax == 1 then return end + data.pagenum = data.pagenum - (_f.prev_page and 1 or -1) + + if data.pagenum > data.pagemax then + data.pagenum = 1 + elseif data.pagenum == 0 then + data.pagenum = data.pagemax + end + + elseif _f.fav then + local fav, i = is_fav(data.favs, data.query_item) + local total = #data.favs + + if total < MAX_FAVS and not fav then + data.favs[total + 1] = data.query_item + elseif fav then + remove(data.favs, i) + end + + elseif _f.export_rcp or _f.export_usg then + if _f.export_rcp then + data.export_rcp = not data.export_rcp + else + data.export_usg = not data.export_usg + end + + elseif (sb_rcp and sub(sb_rcp, 1, 3) == "CHG") or (sb_usg and sub(sb_usg, 1, 3) == "CHG") then + data.scrbar_rcp = sb_rcp and tonum(match(sb_rcp, "%d+")) + data.scrbar_usg = sb_usg and tonum(match(sb_usg, "%d+")) + + elseif _f.craft_rcp or _f.craft_usg then + craft_stack(player, name, data, _f.craft_rcp) + else + select_item(player, data, _f) + end + + return true, show_fs(player, name) +end + +<<<<<<< HEAD +if sfinv_only then + sfinv.register_page("craftguide:craftguide", { + title = S"Craft Guide", + + is_in_nav = function(self, player, context) + local name = player:get_player_name() + return get_lang_code(name) + end, + + get = function(self, player, context) + local name = player:get_player_name() + local data = pdata[name] + + return sfinv.make_formspec(player, context, make_fs(data)) + end, + + on_enter = function(self, player, context) + if next(recipe_filters) then + local name = player:get_player_name() + local data = pdata[name] + + data.items_raw = get_filtered_items(player) + search(data) + end + end, +======= +on_receive_fields(function(player, formname, _f) + if formname == "craftguide" then + fields(player, _f) + end +end) +>>>>>>> origin/master + +local function on_use(user) + local name = user:get_player_name() + local data = pdata[name] + + if data.fs_version < MIN_FORMSPEC_VERSION then + return outdated(name) + end + +<<<<<<< HEAD + if not data.lang_code then + return outdated(name) + end +======= + if next(recipe_filters) then + data.items_raw = get_filtered_items(user) + search(data) + end +>>>>>>> origin/master + + show_formspec(name, "craftguide", make_fs(data)) +end + +core.register_craftitem("craftguide:book", { + description = S"Crafting Guide", + inventory_image = PNG.book, + wield_image = PNG.book, + stack_max = 1, + groups = {book = 1}, + on_use = function(itemstack, user) + on_use(user) + end +}) + +core.register_node("craftguide:sign", { + description = S"Crafting Guide Sign", + drawtype = "nodebox", + tiles = {PNG.sign}, + inventory_image = PNG.sign, + wield_image = PNG.sign, + paramtype = "light", + paramtype2 = "wallmounted", + sunlight_propagates = true, + groups = { + choppy = 1, + attached_node = 1, + oddly_breakable_by_hand = 1, + flammable = 3, + }, + node_box = { + type = "wallmounted", + wall_top = {-0.5, 0.4375, -0.5, 0.5, 0.5, 0.5}, + wall_bottom = {-0.5, -0.5, -0.5, 0.5, -0.4375, 0.5}, + wall_side = {-0.5, -0.5, -0.5, -0.4375, 0.5, 0.5} + }, + + on_construct = function(pos) + local meta = core.get_meta(pos) + meta:set_string("infotext", "Crafting Guide Sign") + end, + + on_rightclick = function(pos, node, user, itemstack) + on_use(user) + end +}) + +core.register_craft{ + output = "craftguide:book", + type = "shapeless", + recipe = {"default:book"} +} + +core.register_craft{ + type = "fuel", + recipe = "craftguide:book", + burntime = 3 +} + +core.register_craft{ + output = "craftguide:sign", + type = "shapeless", + recipe = {"default:sign_wall_wood"} +} + +core.register_craft{ + type = "fuel", + recipe = "craftguide:sign", + burntime = 10 +} + +if progressive_mode then + local function item_in_inv(item, inv_items) + local inv_items_size = #inv_items + + if is_group(item) then + local groups = extract_groups(item) + for i = 1, inv_items_size do + local def = reg_items[inv_items[i]] + + if def then + if item_has_groups(def.groups, groups) then + return true + end + end + end + else + for i = 1, inv_items_size do + if inv_items[i] == item then + return true + end + end + end + end + + local function recipe_in_inv(rcp, inv_items) + for _, item in pairs(rcp.items) do + if not item_in_inv(item, inv_items) then return end + end + + return true + end + + local function progressive_filter(recipes, player) + if not recipes then + return {} + end + + local name = player:get_player_name() + local data = pdata[name] + + if #data.inv_items == 0 then + return {} + end + + local filtered, c = {}, 0 + for i = 1, #recipes do + local recipe = recipes[i] + if recipe_in_inv(recipe, data.inv_items) then + c = c + 1 + filtered[c] = recipe + end + end + + return filtered + end + + local item_lists = {"main", "craft", "craftpreview"} + + local function get_inv_items(player) + local inv = player:get_inventory() + local stacks = {} + + for i = 1, #item_lists do + local list = inv:get_list(item_lists[i]) + table_merge(stacks, list) + end + + local inv_items, c = {}, 0 + + for i = 1, #stacks do + local stack = stacks[i] + if not stack:is_empty() then + local name = stack:get_name() + if reg_items[name] then + c = c + 1 + inv_items[c] = name + end + end + end + + return inv_items + end + + local function init_hud(player, data) + data.hud = { + bg = player:hud_add{ + hud_elem_type = "image", + position = {x = 0.78, y = 1}, + alignment = {x = 1, y = 1}, + scale = {x = 370, y = 112}, + text = PNG.bg, + z_index = 0xDEAD, + }, + + book = player:hud_add{ + hud_elem_type = "image", + position = {x = 0.79, y = 1.02}, + alignment = {x = 1, y = 1}, + scale = {x = 4, y = 4}, + text = PNG.book, + z_index = 0xDEAD, + }, + + text = player:hud_add{ + hud_elem_type = "text", + position = {x = 0.84, y = 1.04}, + alignment = {x = 1, y = 1}, + number = 0xffffff, + text = "", + z_index = 0xDEAD, + }, + } + end + + local function show_hud_success(player, data) + -- It'd better to have an engine function `hud_move` to only need + -- 2 calls for the notification's back and forth. + + local hud_info_bg = player:hud_get(data.hud.bg) + local dt = 0.016 + + if hud_info_bg.position.y <= 0.9 then + data.show_hud = false + data.hud_timer = (data.hud_timer or 0) + dt + end + + if data.show_hud then + for _, def in pairs(data.hud) do + local hud_info = player:hud_get(def) + + player:hud_change(def, "position", { + x = hud_info.position.x, + y = hud_info.position.y - (dt / 5) + }) + end + + player:hud_change(data.hud.text, "text", + S("@1 new recipe(s) discovered!", data.discovered)) + + elseif data.show_hud == false then + if data.hud_timer >= HUD_TIMER_MAX then + for _, def in pairs(data.hud) do + local hud_info = player:hud_get(def) + + player:hud_change(def, "position", { + x = hud_info.position.x, + y = hud_info.position.y + (dt / 5) + }) + end + + if hud_info_bg.position.y >= 1 then + data.show_hud = nil + data.hud_timer = nil + end + end + end + end + + -- Workaround. Need an engine call to detect when the contents of + -- the player inventory changed, instead. + local function poll_new_items() + local players = get_players() + for i = 1, #players do + local player = players[i] + local name = player:get_player_name() + local data = pdata[name] + + local inv_items = get_inv_items(player) + local diff = array_diff(inv_items, data.inv_items) + + if #diff > 0 then + data.inv_items = table_merge(diff, data.inv_items) + local oldknown = data.known_recipes or 0 + get_filtered_items(player, data) + data.discovered = data.known_recipes - oldknown + + if data.show_hud == nil and data.discovered > 0 then + data.show_hud = true + end + end + end + + after(POLL_FREQ, poll_new_items) + end + + poll_new_items() + + globalstep(function() + local players = get_players() + for i = 1, #players do + local player = players[i] + local name = player:get_player_name() + local data = pdata[name] + + if data.show_hud ~= nil and singleplayer then + show_hud_success(player, data) + end + end + end) + + craftguide.add_recipe_filter("Default progressive filter", progressive_filter) + + on_joinplayer(function(player) + local name = player:get_player_name() + local data = pdata[name] + + local meta = player:get_meta() + data.inv_items = dslz(meta:get_string "inv_items") or {} + data.known_recipes = dslz(meta:get_string "known_recipes") or 0 + + if singleplayer then + init_hud(player, data) + end + end) + + local to_save = {"inv_items", "known_recipes"} + + local function save_meta(player) + local meta = player:get_meta() + local name = player:get_player_name() + local data = pdata[name] + + for i = 1, #to_save do + local meta_name = to_save[i] + meta:set_string(meta_name, slz(data[meta_name])) + end + end + + on_leaveplayer(save_meta) + + on_shutdown(function() + local players = get_players() + for i = 1, #players do + local player = players[i] + save_meta(player) + end + end) +end + +on_leaveplayer(function(player) + local name = player:get_player_name() + pdata[name] = nil +end) + +function craftguide.show(name, item, show_usages) + if not true_str(name) then + return err "craftguide.show(): player name missing" + end + + local data = pdata[name] + local player = get_player_by_name(name) + local query_item = data.query_item + + reset_data(data) + + item = reg_items[item] and item or query_item + local recipes, usages = get_recipes(item, data, player) + + if not recipes and not usages then + if not recipes_cache[item] and not usages_cache[item] then + return false, msg(name, sprintf("%s: %s", + S"No recipe or usage for this item", get_desc(item))) + end + + return false, msg(name, sprintf("%s: %s", + S"You don't know a recipe or usage for this item", get_desc(item))) + end + + data.query_item = item + data.recipes = recipes + data.usages = usages + + show_fs(player, name) +end + +register_command("craft", { + description = S"Show recipe(s) of the pointed node", + func = function(name) + local player = get_player_by_name(name) + local dir = player:get_look_dir() + local ppos = player:get_pos() + ppos.y = ppos.y + 1.625 + + local node_name + + for i = 1, 10 do + local look_at = vec_add(ppos, vec_mul(dir, i)) + local node = core.get_node(look_at) + + if node.name ~= "air" then + node_name = node.name + break + end + end + + if not node_name then + return false, msg(name, S"No node pointed") + end + + return true, craftguide.show(name, node_name) + end, +}) diff --git a/my_changes/_not-used/hunger_ng/effects.patch b/my_changes/_not-used/hunger_ng/effects.patch new file mode 100644 index 0000000..7a072a3 --- /dev/null +++ b/my_changes/_not-used/hunger_ng/effects.patch @@ -0,0 +1,14 @@ +diff --git a/init.lua b/init.lua +index d329d0f..7a82145 100644 +--- a/init.lua ++++ b/init.lua +@@ -147,7 +147,8 @@ local api_functions = { + attributes = hunger_ng.attributes, + translator = hunger_ng.configuration.translator, + get_data = hunger_ng.functions.get_data, +- set_data = hunger_ng.functions.set_data ++ set_data = hunger_ng.functions.set_data, ++ effects = hunger_ng.effects, + } + } + diff --git a/my_changes/_not-used/hunger_ng/init.lua b/my_changes/_not-used/hunger_ng/init.lua new file mode 100644 index 0000000..7a82145 --- /dev/null +++ b/my_changes/_not-used/hunger_ng/init.lua @@ -0,0 +1,155 @@ +-- Exit if damage is not enabled and create dummy functions so mods using the +-- API do not crash the server. +if not minetest.is_yes(minetest.settings:get('enable_damage')) then + local info = 'Hunger NG is disabled because damage is disabled.' + + local call = function (function_name) + minetest.log('warning', ('+m tried to use +f but +i'):gsub('%+%a+', { + ['+m'] = minetest.get_current_modname(), + ['+f'] = 'hunger_ng.'..function_name..'()', + ['+i'] = info + })) + end + + hunger_ng = { + add_hunger_data = function () call('add_hunger_data') end, + alter_hunger = function () call('alter_hunger') end, + configure_hunger = function () call('configure_hunger') end, + get_hunger_information = function () call('get_hunger_information') end + } + + minetest.log('info', '[hunger_ng] '..info) + + return +end + + +-- Paths for later use +local modpath = minetest.get_modpath('hunger_ng')..DIR_DELIM +local worldpath = minetest.get_worldpath()..DIR_DELIM +local configpath = worldpath..'_hunger_ng'..DIR_DELIM..'hunger_ng_settings.conf' + + +-- World-specific configuration interface for use in the get function +local worldconfig = Settings(configpath) + + +-- Wrapper for getting configuration options +-- +-- The function automatically prefixes the given setting with `hunger_ng_` and +-- returns the requested setting from one of the three sources. +-- +-- 1. world-specific `./worlds/worldname/_hunger_ng/hunger_ng.conf` file +-- 2. default `minetest.conf` file +-- 3. the given default value +-- +-- If 1. is found then it will be returned from there. If 2. is found then it +-- will be returned from there and after that it will be returned using 3. +-- +-- @param setting The unprefixed setting name +-- @param default The default value if the setting is not found +-- @return string The value for the requested setting +local get = function (setting, default) + local parameter = 'hunger_ng_'..setting + local global_setting = minetest.settings:get(parameter) + local world_specific_setting = worldconfig:get(parameter) + return world_specific_setting or global_setting or default +end + + +-- Global hunger_ng table that will be used to pass around variables and use +-- them later in the game. +hunger_ng = { + functions = {}, + food_items = { + satiating = 0, + starving = 0, + healing = 0, + injuring = 0, + }, + attributes = { + hunger_bar_id = 'hunger_ng:hunger_bar_id', + hunger_value = 'hunger_ng:hunger_value', + eating_timestamp = 'hunger_ng:eating_timestamp', + hunger_disabled = 'hunger_ng:hunger_disabled' + }, + configuration = { + debug_mode = minetest.is_yes(get('debug_mode', false)), + log_prefix = '[hunger_ng] ', + translator = minetest.get_translator('hunger_ng') + }, + settings = { + hunger_bar = { + image = get('hunger_bar_image', 'hunger_ng_builtin_bread_icon.png'), + use = minetest.is_yes(get('use_hunger_bar', true)) + }, + timers = { + heal = tonumber(get('timer_heal', 5)), + starve = tonumber(get('timer_starve', 10)), + basal_metabolism = tonumber(get('timer_basal_metabolism', 60)), + movement = tonumber(get('timer_movement', 0.5)) + }, + hunger = { + timeout = tonumber(get('hunger_timeout', 0)), + persistent = minetest.is_yes(get('hunger_persistent', true)), + start_with = tonumber(get('hunger_start_with', 20)), + maximum = tonumber(get('hunger_maximum', 20)) + } + }, + effects = { + heal = { + above = tonumber(get('heal_above', 16)), + amount = tonumber(get('heal_amount', 1)) + }, + starve = { + below = tonumber(get('starve_below', 1)), + amount = tonumber(get('starve_amount', 1)), + die = minetest.is_yes(get('starve_die', false)) + }, + disabled_attribute = 'hunger_ng:hunger_disabled' + }, + costs = { + base = tonumber(get('cost_base', 0.1)), + dig = tonumber(get('cost_dig', 0.005)), + place = tonumber(get('cost_place', 0.01)), + movement = tonumber(get('cost_movement', 0.008)) + } +} + + +-- Load mod parts +dofile(modpath..'system'..DIR_DELIM..'hunger_functions.lua') +dofile(modpath..'system'..DIR_DELIM..'chat_commands.lua') +dofile(modpath..'system'..DIR_DELIM..'timers.lua') +dofile(modpath..'system'..DIR_DELIM..'register_on.lua') +dofile(modpath..'system'..DIR_DELIM..'add_hunger_data.lua') +dofile(modpath..'system'..DIR_DELIM..'interoperability.lua') + + +-- Log debug mode warning +if hunger_ng.configuration.debug_mode then + local log_prefix = hunger_ng.configuration.log_prefix + minetest.log('warning', log_prefix..'Mod loaded with debug mode enabled!') +end + + +-- Replace the global table used for easy variable access within the mod with +-- an API-like global table for other mods to utilize. +local api_functions = { + add_hunger_data = hunger_ng.functions.add_hunger_data, + alter_hunger = hunger_ng.functions.alter_hunger, + configure_hunger = hunger_ng.functions.configure_hunger, + get_hunger_information = hunger_ng.functions.get_hunger_information, + hunger_bar_image = hunger_ng.settings.hunger_bar.image, + food_items = hunger_ng.food_items, + interoperability = { + settings = hunger_ng.settings, + attributes = hunger_ng.attributes, + translator = hunger_ng.configuration.translator, + get_data = hunger_ng.functions.get_data, + set_data = hunger_ng.functions.set_data, + effects = hunger_ng.effects, + } +} + +hunger_ng = api_functions diff --git a/my_changes/_not-used/water_life/files/hud.lua b/my_changes/_not-used/water_life/files/hud.lua new file mode 100644 index 0000000..4ed006a --- /dev/null +++ b/my_changes/_not-used/water_life/files/hud.lua @@ -0,0 +1,88 @@ + +water_life.playerhud = {} +water_life.playerhud.poison = {} +water_life.playerhud.repellant = {} + + + +water_life.hud_poison = { + + hud_elem_type = "image", + + position = {x=0.5, y=0.8}, + -- Left corner position of element + + name = "water_life_poison", + + scale = {x = 0.1, y = 0.1}, + + text = "water_life_emptyhud.png", + + +} + + + +water_life.hud_repellant = { + hud_elem_type = "image", + + position = {x=0.55, y=0.8}, + -- Left corner position of element + + name = "water_life_repellant", + + scale = {x = 0.1, y = 0.1}, + + text = "water_life_emptyhud.png", +} + + +function water_life.change_hud(player,selection,switch) + local value = "" + if not player then return end + if not selection then selection = "poison" end + if not switch then switch = 1 end + + + local name = player:get_player_name() + + if selection == "poison" then + if switch == 1 then value = "water_life_poison.png" else value = "water_life_emptyhud.png" end + player:hud_change(water_life.playerhud.poison[name], "text", value) + end + + if selection == "repellant" then + if switch == 1 then value = "water_life_repellanthud.png" else value = "water_life_emptyhud.png" end + player:hud_change(water_life.playerhud.repellant[name], "text", value) + end + +end + + + +minetest.register_on_joinplayer(function(player) + if not player then return end + + local meta=player:get_meta() + meta:set_int("repellant",0) + local name = player:get_player_name() + + water_life.playerhud.poison[name] = player:hud_add(water_life.hud_poison) + water_life.playerhud.repellant[name] = player:hud_add(water_life.hud_repellant) + + if meta:get_int("snakepoison") > 0 then + minetest.after(5, function(player) + water_life.change_hud(player,"poison") + end, player) + end + +end) + +minetest.register_on_dieplayer(function(player) + if not player then return end + if water_life.poison_after_death then return end + + local meta=player:get_meta() + meta:set_int("snakepoison",0) + water_life.change_hud(player,"poison",0) +end) diff --git a/my_changes/_not-used/water_life/files/spawn.lua b/my_changes/_not-used/water_life/files/spawn.lua new file mode 100644 index 0000000..59aa23b --- /dev/null +++ b/my_changes/_not-used/water_life/files/spawn.lua @@ -0,0 +1,394 @@ +local timer = 0 +local landtimer = 0 +local pi = math.pi +local random = water_life.random +local landinterval = 60 -- check every 60 seconds for spawnpos on land +local waterinterval = 20 -- check every 20 seconds for spawnpos in water + + +local function getcount(name) + if not name then + return 0 + else + return name + end +end + + +local function spawnstep(dtime) + + timer = timer + dtime + landtimer = landtimer + dtime + + if timer > waterinterval then + + for _,plyr in ipairs(minetest.get_connected_players()) do + + local toomuch = false + + if plyr and plyr:is_player() and plyr:get_pos().y > -50 and plyr:get_pos().y < 150 then -- each player gets a spawn chance every 10s on average + + local pos = plyr:get_pos() + local yaw = plyr:get_look_horizontal() + local animal = water_life.count_objects(pos) + local meta = plyr:get_meta() + + if meta:get_int("snakepoison") > 0 then + poison_value = 1 --defautl poison value + local pl_name=plyr:get_player_name() -- player name + local hunger_ng_infos = hunger_ng.get_hunger_information(pl_name) -- information from hunger_ng + --minetest.log(dump(hunger_ng_infos)) + local hunger_ng_interoper = hunger_ng.interoperability + --minetest.log(dump(hunger_ng_interoper)) + -- if healing is enabled, then add healing to poison value + -- if the same you have the chance to survive if you stay satiated + if hunger_ng_infos.effects.healing then + poison_value = ((waterinterval/hunger_ng_interoper.settings.timers.heal)*hunger_ng_interoper.effects.heal.amount) + 0.1 --+ poison_value -- if you want decrease healt even with healing + end + minetest.log("Poison: "..dump(poison_value)) + + local score = plyr:get_hp()-poison_value + --if score < 0 then score = 0 end + minetest.log("Health: "..dump(score)) + plyr:set_hp(score) + end + + if meta:get_int("repellant") > 0 then + if math.floor(os.clock()) - meta:get_int("repellant") > water_life.repeltime then + water_life.change_hud(plyr,"repellant",0) + meta:set_int("repellant",0) + end + end + + if animal.all > water_life.maxmobs then toomuch = true end + + -- find a pos randomly in look direction of player + local radius = (water_life.abr * 12) -- 75% from 16 = 12 nodes + radius = random(7,radius) -- not nearer than 7 nodes in front of player + local angel = math.rad(random(75)) -- look for random angel 0 - 75 degrees + if water_life.leftorright() then yaw = yaw + angel else yaw = yaw - angel end -- add or substract to/from yaw + + local pos2 = mobkit.pos_translate2d(pos,yaw,radius) -- calculate position + local depth, stype, surface = water_life.water_depth(pos2,25) -- get surface pos and water depth + local bdata = water_life_get_biome_data(pos2) -- get biome data at spawn position + local ground = {} + local dalam = depth + local landpos = nil + local geckopos = nil + local moskitopos = nil + + -- no need of so many postions on land + if landtimer > landinterval then + landpos = water_life.find_node_under_air(pos2) + geckopos = water_life.find_node_under_air(pos2,5,{"group:tree","group:leaves","default:junglegrass"}) + moskitopos = water_life.find_node_under_air(pos2,5,{"default:river_water_source","water_life:muddy_river_water_source","group:flora","default:dirt_with_rainforest_litter"}) + end + + + if moskitopos and not water_life.dangerous then + local mlevel = minetest.get_node_light(moskitopos) + local ptime = water_life.get_game_time() + local mdata = water_life_get_biome_data(moskitopos) + --minetest.chat_send_all("MOSKITO: "..dump(moskitopos).." : "..dump(mdata.temp).." : "..dump(ptime).." : "..dump(mlevel)) + + if ((ptime and ptime > 2) or mlevel < 8) and mdata.temp > 16 then --from 3pm to 5am or in shadows all day long + + minetest.set_node(moskitopos, {name = "water_life:moskito"}) + minetest.get_node_timer(moskitopos):start(random(15,45)) + local pmeta = minetest.get_meta(moskitopos) + pmeta:set_int("mlife",math.floor(os.clock())) + + end + end + + --some spawn on land, too + + if landpos then + local landdata = water_life_get_biome_data(landpos) + + + if not water_life.dangerous then + -- the snake + local mobname = 'water_life:snake' + local faktor = (100 - getcount(animal[mobname]) * 50) + if random(100) < faktor then + local fits = minetest.is_protected(landpos,mobname) + --minetest.chat_send_all(dump(fits)) + + if (string.match(landdata.name,"desert") or string.match(landdata.name,"savanna")) + and not fits and landdata.temp > 15 then + + local obj=minetest.add_entity(landpos,mobname) -- ok spawn it already damnit + end + end + + + end + + + --the beaver + local mobname = 'water_life:beaver' + local faktor = (100 - getcount(animal[mobname]) * 25) + if random(100) < faktor then + + if string.match(landdata.name,"coniferous") and landdata.temp > -5 and landdata.temp < 20 then + + local obj=minetest.add_entity(landpos,mobname) -- ok spawn it already damnit + end + end + end + + + if geckopos then + local landdata = water_life_get_biome_data(geckopos) + + local mobname = 'water_life:gecko' + local faktor = (100 - getcount(animal[mobname]) * 50) + if random(100) < faktor then + + + if (string.match(landdata.name,"rainforest") or string.match(landdata.name,"savanna")) + and landdata.temp > 20 then + + local obj=minetest.add_entity(geckopos,mobname) -- ok spawn it already damnit + end + end + end + + + + --water spawn + + if depth and depth > 0 then + if water_life.radar_debug then + water_life.temp_show(surface,9,5) + minetest.chat_send_all(">>> Depth ="..dump(depth).." <<< "..dump(stype)) + minetest.chat_send_all(dump(bdata.name)) + end + pos2 = surface + + end + + local liquidflag = nil + + if stype == "default:water_source" then + liquidflag = "sea" + + elseif stype == "default:river_water_source" then + liquidflag = "river" + + elseif stype == "water_life:muddy_river_water_source" then + liquidflag = "muddy" + + end + + if liquidflag and not toomuch and surface then + ground = mobkit.pos_shift(surface,{y=(dalam*-1)}) + + + if not water_life.dangerous then + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + local mobname = 'water_life:croc' + local faktor = 100 - getcount(animal[mobname]) * 33 + if random(100) < faktor then + local fits = false + if string.match(bdata.name,"rainforest") or string.match(bdata.name,"savanna") then fits = true end + + if depth < 4 and fits then --shark min water depth + local obj=minetest.add_entity(surface,mobname) -- ok spawn it already damnit + end + + + end + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + + local mobname = 'water_life:snake' + local faktor = (100 - getcount(animal[mobname]) * 50) +25 + if random(100) < faktor then + local fits = false + if string.match(bdata.name,"desert") or string.match(bdata.name,"savanna") then fits = true end + + if depth < 3 and fits then --snake max water depth + local obj=minetest.add_entity(surface,mobname) -- ok spawn it already damnit + end + + + end + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + local mobname = 'water_life:shark' + if water_life.shark_spawn_rate >= random(1000) then + + local bcheck = water_life.count_objects(pos2,12) + if getcount(animal[mobname]) < water_life.maxsharks and liquidflag == "sea" and not bcheck["water_life:shark_buoy"] + and not animal["water_life:croc"] then + + if depth > 4 then --shark min water depth + local obj=minetest.add_entity(mobkit.pos_shift(ground,{y=2}),mobname) -- spawn it 2 nodes above sea ground + end + end + + end + end + + local mobname = "water_life:gull" + local faktor = 100 - getcount(animal[mobname]) * 20 + if random(100) < faktor and liquidflag == "sea" then + if depth > 4 then + local spawn = mobkit.pos_shift(surface,{y=12}) + --spawn.y = spawn.y + 12 + local obj=minetest.add_entity(spawn,mobname) -- ok spawn it already damnit + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:urchin" + if water_life.urchin_spawn_rate >= random(1000) then + + local upos1 = mobkit.pos_shift(ground,{x=-5,y=-2,z=-5}) + local upos2 = mobkit.pos_shift(ground,{x=5,y=2,z=5}) + local coraltable = minetest.find_nodes_in_area(upos1, upos2, water_life.urchinspawn) + --local nearlife = water_life.count_objects(ground,5,"water_life:urchin") + if coraltable and #coraltable > 0 and getcount(animal[mobname]) < 15 and liquidflag == "sea" then + local coralpos = coraltable[random(#coraltable)] + coralpos.y = coralpos.y +1 + local node = minetest.get_node(coralpos) + + if node.name == "default:water_source" then + local obj= water_life.set_urchin(coralpos) --minetest.add_entity(coralpos,mobname) + end + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:clams" + if water_life.clams_spawn_rate >= random(1000) then + local clpos1 = mobkit.pos_shift(ground,{x=-8, y=-2, z=8}) + local clpos2 = mobkit.pos_shift(ground,{x=8, y=2, z=8}) + local coraltable = minetest.find_nodes_in_area(clpos1, clpos2, water_life.clams_spawn) + ----minetest.chat_send_all("seagrass ="..dump(#coraltable)) + local nearlife = water_life.count_objects(ground,8,"water_life:clams") + if coraltable and #coraltable > 0 and getcount(animal[mobname]) < 10 and liquidflag == "sea" then + local coralpos = mobkit.pos_shift(coraltable[random(#coraltable)],{y=1}) + + local node = minetest.get_node(coralpos) + if node.name == "default:water_source" then + local obj= water_life.set_urchin(coralpos,"water_life:clams") + end + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:jellyfish" + + + local faktor = 100 - getcount(animal[mobname]) * 20 + if random(100) < faktor and liquidflag == "sea" and depth > 2 then + local obj=minetest.add_entity(mobkit.pos_shift(ground,{y=2}),mobname) + end + + + mobname = "water_life:coralfish" + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + local cfpos1 = mobkit.pos_shift(ground,{x=-5,y=-2,z=-5}) + local cfpos2 = mobkit.pos_shift(ground,{x=5,y=2,z=5}) + local coraltable = minetest.find_nodes_in_area(cfpos1,cfpos2,water_life.urchinspawn) + --local nearlife = water_life.count_objects(ground,nil,mobname) + faktor = 100 - getcount(animal[mobname]) * 6.66 + if random(100) < faktor and liquidflag == "sea" and #coraltable > 1 then + local cfish = coraltable[random(#coraltable)] + cfish.y = cfish.y +1 + local maxfish = random(3,7) + for i = 1,maxfish,1 do + local obj=minetest.add_entity(cfish,mobname) + if obj then + local entity = obj:get_luaentity() + entity.base = cfish + entity.head = random(65535) + end + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:clownfish" + + faktor = 100 - getcount(animal[mobname]) * 50 + if random(100) < faktor and liquidflag == "sea" and #coraltable > 1 then + local cfish = coraltable[random(#coraltable)] + cfish.y = cfish.y +1 + local obj=minetest.add_entity(cfish,mobname) + if obj then + local entity = obj:get_luaentity() + entity.base = cfish + end + end + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = 'water_life:fish' + --local nearlife = water_life.count_objects(pos2,24,"water_life:piranha") + if water_life.fish_spawn_rate >= random(1000) and ((animal.all < (water_life.maxmobs-5)) or getcount(animal[mobname]) < 5) and (liquidflag == "river" or liquidflag == "muddy") then + + local table = minetest.get_biome_data(pos) + + if not water_life.dangerous and table and water_life.piranha_biomes[minetest.get_biome_name(table.biome)] then + mobname = "water_life:piranha" + end + + if depth > 2 then -- min water depth for piranha and riverfish + if mobname == "water_life:fish" then + local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit + else + if getcount(animal[mobname]) < 10 then + for i = 1,3,1 do + local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit + end + end + end + end + + + end + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + mobname = 'water_life:whale' + if water_life.whale_spawn_rate >= random(1000) and getcount(animal[mobname]) < (water_life.maxwhales) and liquidflag == "sea" then + + + if depth > 8 then -- min water depth for whales + + local gotwhale = true + local whpos = mobkit.pos_shift(surface,{y=-3}) + for i = 0,3,1 do + local whpos2 = mobkit.pos_translate2d(whpos,math.rad(i*90),30) + local under = water_life.find_collision(whpos,whpos2, false) + ----minetest.chat_send_all(dump(under)) + if under and under < 25 then + gotwhale = false + break + end + end + if gotwhale then local obj=minetest.add_entity(surface,mobname) end -- ok spawn it already damnit + + end + end + + end + end + end + timer = 0 + if landtimer > landinterval then landtimer = 0 end + end + +end + + + +minetest.register_globalstep(spawnstep) diff --git a/my_changes/_not-used/water_life/poison.patch b/my_changes/_not-used/water_life/poison.patch new file mode 100644 index 0000000..1d5d506 --- /dev/null +++ b/my_changes/_not-used/water_life/poison.patch @@ -0,0 +1,77 @@ +diff --git a/hud.lua b/hud.lua +index bff0dd4..4ed006a 100644 +--- a/hud.lua ++++ b/hud.lua +@@ -78,4 +78,11 @@ minetest.register_on_joinplayer(function(player) + + end) + ++minetest.register_on_dieplayer(function(player) ++ if not player then return end ++ if water_life.poison_after_death then return end + ++ local meta=player:get_meta() ++ meta:set_int("snakepoison",0) ++ water_life.change_hud(player,"poison",0) ++end) +diff --git a/init.lua b/init.lua +index f92c3c3..97833b3 100644 +--- a/init.lua ++++ b/init.lua +@@ -31,6 +31,7 @@ water_life.moskitolifetime = tonumber(minetest.settings:get("water_life_moskitol + water_life.radar_debug = minetest.settings:get_bool("water_life_radar_debug") or false + water_life.muddy_water = minetest.settings:get_bool("water_life_muddy_water") or false + water_life.repeltime = math.floor (720 / (tonumber(minetest.settings:get("time_speed")) or 72)*60) -- the repellent lasts half a minetest day ++water_life.poison_after_death = minetest.settings:get_bool("water_life_poison_after_death") or false + + local path = minetest.get_modpath(minetest.get_current_modname()) + +diff --git a/settingtypes.txt b/settingtypes.txt +index 24bb049..4eb03f3 100644 +--- a/settingtypes.txt ++++ b/settingtypes.txt +@@ -62,3 +62,7 @@ water_life_muddy_water (muddy water in rainforest and savanna biome) bool false + #- + # turn this value to true to see api function debug + water_life_radar_debug (api function debug shown in chat) bool false ++ ++# ++# Turn this Value to true, if you want poison to persist after death ++water_life_poison_after_death (Poison stays after death) bool false +diff --git a/spawn.lua b/spawn.lua +index e6cef07..d2653f9 100644 +--- a/spawn.lua ++++ b/spawn.lua +@@ -35,8 +35,25 @@ local function spawnstep(dtime) + + + if meta:get_int("snakepoison") > 0 then +- local score = plyr:get_hp() +- plyr:set_hp(score-1) ++ --local score = plyr:get_hp() ++ --plyr:set_hp(score-1) ++ poison_value = 1 --defautl poison value ++ local pl_name=plyr:get_player_name() -- player name ++ local hunger_ng_infos = hunger_ng.get_hunger_information(pl_name) -- information from hunger_ng ++ --minetest.log(dump(hunger_ng_infos)) ++ local hunger_ng_interoper = hunger_ng.interoperability ++ --minetest.log(dump(hunger_ng_interoper)) ++ -- if healing is enabled, then add healing to poison value ++ -- if the same you have the chance to survive if you stay satiated ++ if hunger_ng_infos.effects.healing then ++ poison_value = ((waterinterval/hunger_ng_interoper.settings.timers.heal)*hunger_ng_interoper.effects.heal.amount) + 0.1 --+ poison_value -- if you want decrease healt even with healing ++ end ++ --minetest.log("Poison: "..dump(poison_value)) ++ ++ local score = plyr:get_hp()-poison_value ++ --if score < 0 then score = 0 end ++ --minetest.log("Health: "..dump(score)) ++ plyr:set_hp(score) + end + + if meta:get_int("repellant") > 0 then +@@ -378,4 +395,3 @@ end + + + minetest.register_globalstep(spawnstep) +- diff --git a/my_changes/_not-used/water_life/poison_dead_only.patch b/my_changes/_not-used/water_life/poison_dead_only.patch new file mode 100644 index 0000000..d85c54b --- /dev/null +++ b/my_changes/_not-used/water_life/poison_dead_only.patch @@ -0,0 +1,40 @@ +diff --git a/hud.lua b/hud.lua +index bff0dd4..9635342 100644 +--- a/hud.lua ++++ b/hud.lua +@@ -78,4 +78,11 @@ minetest.register_on_joinplayer(function(player) + + end) + ++minetest.register_on_dieplayer(function(player) ++ if not player then return end ++ if water_life.poison_after_death then return end + ++ local meta=player:get_meta() ++ meta:set_int("snakepoison",0) ++ water_life.change_hud(player,"poison",0) ++end) +diff --git a/init.lua b/init.lua +index 0e4fd8a..7c32a0b 100644 +--- a/init.lua ++++ b/init.lua +@@ -31,6 +31,7 @@ water_life.moskitolifetime = tonumber(minetest.settings:get("water_life_moskitol + water_life.radar_debug = minetest.settings:get_bool("water_life_radar_debug") or false + water_life.muddy_water = minetest.settings:get_bool("water_life_muddy_water") or false + water_life.repeltime = math.floor (720 / (tonumber(minetest.settings:get("time_speed")) or 72)*60) -- the repellent lasts half a minetest day ++water_life.poison_after_death = minetest.settings:get_bool("water_life_poison_after_death") or false + + local path = minetest.get_modpath(minetest.get_current_modname()) + +diff --git a/settingtypes.txt b/settingtypes.txt +index 24bb049..4eb03f3 100644 +--- a/settingtypes.txt ++++ b/settingtypes.txt +@@ -62,3 +62,7 @@ water_life_muddy_water (muddy water in rainforest and savanna biome) bool false + #- + # turn this value to true to see api function debug + water_life_radar_debug (api function debug shown in chat) bool false ++ ++# ++# Turn this Value to true, if you want poison to persist after death ++water_life_poison_after_death (Poison stays after death) bool false diff --git a/my_changes/buildings/doors/doors_update.patch b/my_changes/buildings/doors/doors_update.patch new file mode 100644 index 0000000..16ff82f --- /dev/null +++ b/my_changes/buildings/doors/doors_update.patch @@ -0,0 +1,72 @@ +diff --git a/README.txt b/README.txt +index 79320a1..a1eec4f 100644 +--- a/README.txt ++++ b/README.txt +@@ -173,8 +173,9 @@ Minetest 0.4.15+ required + Installation + ---------------------- + +- 1) Unzip the archive into the mods directory of your game. +- 2) Rename the doors-master directory to "doors". ++ 1) Backup the original "doors" mod to a safe location. ++ 2) Unzip the archive into the mods directory of your game. ++ 3) Rename the doors-master directory to "doors". + + Source code license + ---------------------------------------------------------- +diff --git a/api.lua b/api.lua +index d7685bd..1a822da 100644 +--- a/api.lua ++++ b/api.lua +@@ -1,5 +1,5 @@ + -------------------------------------------------------- +--- Minetest :: Doors Redux Mod v1.1 (doors) ++-- Minetest :: Doors Redux Mod (doors) + -- + -- See README.txt for licensing and other information. + -- Copyright (c) 2016-2020, Leslie E. Krause +@@ -972,3 +972,9 @@ minetest.register_craft( { + { "default:steel_ingot" }, + } + } ) ++ ++-- compatibility for Minetest S3 engine ++ ++if not vector.offset_y or not minetest.get_node_above then ++ dofile( minetest.get_modpath( "doors" ) .. "/compatibility.lua" ) ++end +diff --git a/init.lua b/init.lua +index 647191b..e6ceffd 100644 +--- a/init.lua ++++ b/init.lua +@@ -193,7 +193,9 @@ doors.register_door( "doors:door_mansion1", { + { "group:wood", "group:wood", "default:steel_rod" }, + { "group:wood", "group:wood", "dye:white" }, + { "group:wood", "group:wood", "default:steel_rod" }, +- } ++ }, ++ is_lockable = true, ++ is_closable = true, + } ) + + doors.register_door( "doors:door_mansion2", { +@@ -205,7 +207,9 @@ doors.register_door( "doors:door_mansion2", { + { "group:wood", "group:wood", "default:steel_rod" }, + { "group:wood", "group:wood", "dye:black" }, + { "group:wood", "group:wood", "default:steel_rod" }, +- } ++ }, ++ is_lockable = true, ++ is_closable = true, + } ) + + doors.register_door( "doors:door_steel", { +@@ -261,7 +265,7 @@ doors.register_door( "doors:door_dungeon2", { + } ) + + doors.register_door( "doors:door_steelpanel1", { +- tiles = {{ name = "doors_door_steelpanel.png", backface_culling = true}}, ++ tiles = {{ name = "doors_door_steelpanel1.png", backface_culling = true}}, + description = "Steel Colonial Door", + inventory_image = "doors_item_steelpanel1.png", + protected = true, diff --git a/my_changes/buildings/doors/doors_update54.patch b/my_changes/buildings/doors/doors_update54.patch new file mode 100644 index 0000000..52acab9 --- /dev/null +++ b/my_changes/buildings/doors/doors_update54.patch @@ -0,0 +1,281 @@ +diff --git a/api.lua b/api.lua +index 1a822da..9ef1f43 100644 +--- a/api.lua ++++ b/api.lua +@@ -1,5 +1,5 @@ + -------------------------------------------------------- +--- Minetest :: Doors Redux Mod (doors) ++-- Minetest :: Doors Redux Mod v1.1 (doors) + -- + -- See README.txt for licensing and other information. + -- Copyright (c) 2016-2020, Leslie E. Krause +@@ -23,6 +23,7 @@ doors.ADJUST_LOCKING = 1 + doors.ADJUST_CLOSING = 2 + + minetest.register_node( "doors:hidden", { ++ use_texture_alpha = "clip", + description = "Hidden Door Segment", + drawtype = "nodebox", -- cannot use air-like, since falling nodes would be stuck + paramtype = "light", +@@ -972,9 +973,3 @@ minetest.register_craft( { + { "default:steel_ingot" }, + } + } ) +- +--- compatibility for Minetest S3 engine +- +-if not vector.offset_y or not minetest.get_node_above then +- dofile( minetest.get_modpath( "doors" ) .. "/compatibility.lua" ) +-end +diff --git a/init.lua b/init.lua +index e6ceffd..8533226 100644 +--- a/init.lua ++++ b/init.lua +@@ -18,6 +18,7 @@ dofile( minetest.get_modpath( "doors" ) .. "/api.lua" ) + + doors.register_door( "doors:door_wood", { + tiles = {{ name = "doors_door_wood.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Wooden Door", + inventory_image = "doors_item_wood.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -32,6 +33,7 @@ doors.register_door( "doors:door_wood", { + doors.register_door( "doors:door_woodpanel1", { + -- Colonial Style (6 panel) + tiles = {{ name = "doors_door_woodpanel1.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Wooden Colonial Door", + inventory_image = "doors_item_woodpanel1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -46,6 +48,7 @@ doors.register_door( "doors:door_woodpanel1", { + + doors.register_door( "doors:door_woodglass1", { + tiles = {{ name = "doors_door_woodglass1.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Wooden Single-Lite Door", + inventory_image = "doors_item_woodglass1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -60,6 +63,7 @@ doors.register_door( "doors:door_woodglass1", { + + doors.register_door( "doors:door_woodglass2", { + tiles = {{ name = "doors_door_woodglass2.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Wooden Double-Lite Door", + inventory_image = "doors_item_woodglass2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -74,6 +78,7 @@ doors.register_door( "doors:door_woodglass2", { + + doors.register_door( "doors:door_japanese", { + tiles = {{ name = "doors_door_japanese.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Japanese Door", + inventory_image = "doors_item_japanese.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -88,6 +93,7 @@ doors.register_door( "doors:door_japanese", { + + doors.register_door( "doors:door_french", { + tiles = {{ name = "doors_door_french.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "French Door", + inventory_image = "doors_item_french.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -102,6 +108,7 @@ doors.register_door( "doors:door_french", { + + doors.register_door( "doors:door_cottage1", { + tiles = {{ name = "doors_door_cottage1.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Cottage Interior Door", + inventory_image = "doors_item_cottage1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -116,6 +123,7 @@ doors.register_door( "doors:door_cottage1", { + + doors.register_door( "doors:door_cottage2", { + tiles = {{ name = "doors_door_cottage2.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Cottage Exterior Door", + inventory_image = "doors_item_cottage2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -130,6 +138,7 @@ doors.register_door( "doors:door_cottage2", { + + doors.register_door( "doors:door_barn1", { + tiles = {{ name = "doors_door_barn1.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Barn Interior Door", + inventory_image = "doors_item_barn1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -144,6 +153,7 @@ doors.register_door( "doors:door_barn1", { + + doors.register_door( "doors:door_barn2", { + tiles = {{ name = "doors_door_barn2.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Barn Exterior Door", + inventory_image = "doors_item_barn2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -158,6 +168,7 @@ doors.register_door( "doors:door_barn2", { + + doors.register_door( "doors:door_castle1", { + tiles = {{ name = "doors_door_castle1.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Castle Interior Door", + inventory_image = "doors_item_castle1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -172,6 +183,7 @@ doors.register_door( "doors:door_castle1", { + + doors.register_door( "doors:door_castle2", { + tiles = {{ name = "doors_door_castle2.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Castle Exterior Door", + inventory_image = "doors_item_castle2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -186,6 +198,7 @@ doors.register_door( "doors:door_castle2", { + + doors.register_door( "doors:door_mansion1", { + tiles = {{ name = "doors_door_mansion1.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Mansion Interior Door", + inventory_image = "doors_item_mansion1.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -193,13 +206,12 @@ doors.register_door( "doors:door_mansion1", { + { "group:wood", "group:wood", "default:steel_rod" }, + { "group:wood", "group:wood", "dye:white" }, + { "group:wood", "group:wood", "default:steel_rod" }, +- }, +- is_lockable = true, +- is_closable = true, ++ } + } ) + + doors.register_door( "doors:door_mansion2", { + tiles = {{ name = "doors_door_mansion2.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Mansion Exterior Door ", + inventory_image = "doors_item_mansion2.png", + groups = { choppy = 2, oddly_breakable_by_hand = 2, flammable = 2 }, +@@ -207,13 +219,12 @@ doors.register_door( "doors:door_mansion2", { + { "group:wood", "group:wood", "default:steel_rod" }, + { "group:wood", "group:wood", "dye:black" }, + { "group:wood", "group:wood", "default:steel_rod" }, +- }, +- is_lockable = true, +- is_closable = true, ++ } + } ) + + doors.register_door( "doors:door_steel", { + tiles = {{ name = "doors_door_steel.png", backface_culling = true}}, ++ use_texture_alpha = "clip", + description = "Steel Door", + inventory_image = "doors_item_steel.png", + protected = true, +@@ -232,6 +243,7 @@ doors.register_door( "doors:door_steel", { + + doors.register_door( "doors:door_dungeon1", { + tiles = {{ name = "doors_door_dungeon1.png", backface_culling = true}}, ++ use_texture_alpha = "clip", + description = "Dungeon Interior Door", + inventory_image = "doors_item_dungeon1.png", + protected = true, +@@ -249,6 +261,7 @@ doors.register_door( "doors:door_dungeon1", { + + doors.register_door( "doors:door_dungeon2", { + tiles = {{ name = "doors_door_dungeon2.png", backface_culling = true}}, ++ use_texture_alpha = "clip", + description = "Dungeon Exterior Door", + inventory_image = "doors_item_dungeon2.png", + protected = true, +@@ -266,6 +279,7 @@ doors.register_door( "doors:door_dungeon2", { + + doors.register_door( "doors:door_steelpanel1", { + tiles = {{ name = "doors_door_steelpanel1.png", backface_culling = true}}, ++ use_texture_alpha = "clip", + description = "Steel Colonial Door", + inventory_image = "doors_item_steelpanel1.png", + protected = true, +@@ -284,6 +298,7 @@ doors.register_door( "doors:door_steelpanel1", { + + doors.register_door( "doors:door_steelglass1", { + tiles = {{ name = "doors_door_steelglass1.png", backface_culling = true}}, ++ use_texture_alpha = "clip", + description = "Steel Single-Lite Door", + inventory_image = "doors_item_steelglass1.png", + protected = true, +@@ -302,6 +317,7 @@ doors.register_door( "doors:door_steelglass1", { + + doors.register_door( "doors:door_steelglass2", { + tiles = {{ name = "doors_door_steelglass2.png", backface_culling = true }}, ++ use_texture_alpha = "clip", + description = "Steel Double-Lite Door", + inventory_image = "doors_item_steelglass2.png", + protected = true, +@@ -320,6 +336,7 @@ doors.register_door( "doors:door_steelglass2", { + + doors.register_door( "doors:door_glass", { + tiles = { "doors_door_glass.png" }, ++ use_texture_alpha = "clip", + description = "Glass Door", + inventory_image = "doors_item_glass.png", + groups = { cracky = 3, oddly_breakable_by_hand = 3 }, +@@ -338,6 +355,7 @@ doors.register_door( "doors:door_glass", { + + doors.register_door( "doors:door_obsidian_glass", { + tiles = { "doors_door_obsidian_glass.png" }, ++ use_texture_alpha = "clip", + description = "Obsidian Glass Door", + inventory_image = "doors_item_obsidian_glass.png", + groups = { cracky = 3 }, +@@ -359,6 +377,7 @@ doors.register_door( "doors:door_obsidian_glass", { + ---------------------------- + + doors.register_trapdoor( "doors:trapdoor", { ++ use_texture_alpha = "clip", + description = "Trapdoor", + inventory_image = "doors_trapdoor.png", + wield_image = "doors_trapdoor.png", +@@ -371,6 +390,7 @@ doors.register_trapdoor( "doors:trapdoor", { + } ) + + doors.register_trapdoor( "doors:trapdoor_steel", { ++ use_texture_alpha = "clip", + description = "Steel Trapdoor", + inventory_image = "doors_trapdoor_steel.png", + wield_image = "doors_trapdoor_steel.png", +@@ -409,6 +429,7 @@ minetest.register_craft( { + ----------------------------- + + doors.register_fencegate( "doors:gate_wood", { ++ use_texture_alpha = "clip", + description = "Wooden Fence Gate", + texture = "default_wood.png", + material = "default:wood", +@@ -416,6 +437,7 @@ doors.register_fencegate( "doors:gate_wood", { + } ) + + doors.register_fencegate( "doors:gate_junglewood", { ++ use_texture_alpha = "clip", + description = "Junglewood Fence Gate", + texture = "default_junglewood.png", + material = "default:junglewood", +@@ -423,6 +445,7 @@ doors.register_fencegate( "doors:gate_junglewood", { + } ) + + doors.register_fencegate( "doors:gate_acacia_wood", { ++ use_texture_alpha = "clip", + description = "Acacia Fence Gate", + texture = "default_acacia_wood.png", + material = "default:acacia_wood", +@@ -430,6 +453,7 @@ doors.register_fencegate( "doors:gate_acacia_wood", { + } ) + + doors.register_fencegate( "doors:gate_pine_wood", { ++ use_texture_alpha = "clip", + description = "Pine Fence Gate", + texture = "default_pine_wood.png", + material = "default:pine_wood", +@@ -437,6 +461,7 @@ doors.register_fencegate( "doors:gate_pine_wood", { + } ) + + doors.register_fencegate( "doors:gate_aspen_wood", { ++ use_texture_alpha = "clip", + description = "Aspen Fence Gate", + texture = "default_aspen_wood.png", + material = "default:aspen_wood", diff --git a/my_changes/buildings/mg_villages/old_villages.patch b/my_changes/buildings/mg_villages/old_villages.patch new file mode 100644 index 0000000..8037fda --- /dev/null +++ b/my_changes/buildings/mg_villages/old_villages.patch @@ -0,0 +1,52 @@ +diff --git a/config.lua b/config.lua +index be08447..ed89fc5 100644 +--- a/config.lua ++++ b/config.lua +@@ -27,7 +27,7 @@ mg_villages.VILLAGE_DETECT_RANGE = 400; + mg_villages.REQUIRE_PRIV_FOR_TELEPORT = false; + + -- if set to true, players cannot modify spawned villages without buying the house from the village first +-mg_villages.ENABLE_PROTECTION = true; ++mg_villages.ENABLE_PROTECTION = false; + + -- the first village - the one the player spawns in - will be of this type + mg_villages.FIRST_VILLAGE_TYPE = 'medieval'; +@@ -35,7 +35,7 @@ mg_villages.FIRST_VILLAGE_TYPE = 'medieval'; + -- the mapgen will disregard mapchunks where min.y > mg_villages.MAX_HEIGHT_TREATED; + -- you can set this value to 64 if you have a slow machine and a mapgen which does not create extreme mountains + -- (or if you don't care if extreme mountains may create burried villages occasionally) +-mg_villages.MAX_HEIGHT_TREATED = 200; ++mg_villages.MAX_HEIGHT_TREATED = 400; + + -- choose the debug level you want + mg_villages.DEBUG_LEVEL = mg_villages.DEBUG_LEVEL_NORMAL +diff --git a/init.lua b/init.lua +index 2463866..b4017db 100644 +--- a/init.lua ++++ b/init.lua +@@ -104,7 +104,7 @@ dofile(mg_villages.modpath.."/terrain_blend.lua") + -- also takes care of spawning the player + dofile(mg_villages.modpath.."/mapgen.lua") + +-dofile(mg_villages.modpath.."/spawn_player.lua") ++-- dofile(mg_villages.modpath.."/spawn_player.lua") + + -- reconstruct the connection of the roads inside a village + dofile(mg_villages.modpath.."/roads.lua") +diff --git a/plotmarker_formspec.lua b/plotmarker_formspec.lua +index 0dd65ad..f54f4cf 100644 +--- a/plotmarker_formspec.lua ++++ b/plotmarker_formspec.lua +@@ -366,9 +366,9 @@ end + + mg_villages.form_input_handler = function( player, formname, fields) + -- mg_villages.print(mg_villages.DEBUG_LEVEL_NORMAL,minetest.serialize(fields)); +- if( not( mg_villages.ENABLE_PROTECTION )) then +- return false; +- end ++-- if( not( mg_villages.ENABLE_PROTECTION )) then ++-- return false; ++-- end + + -- teleport to a plot or mob + if( fields[ 'teleport_to' ] diff --git a/my_changes/buildings/mg_villages/villages.patch b/my_changes/buildings/mg_villages/villages.patch new file mode 100644 index 0000000..7652a00 --- /dev/null +++ b/my_changes/buildings/mg_villages/villages.patch @@ -0,0 +1,34 @@ +diff --git a/config.lua b/config.lua +index be08447..ea102e5 100644 +--- a/config.lua ++++ b/config.lua +@@ -27,10 +27,10 @@ mg_villages.VILLAGE_DETECT_RANGE = 400; + mg_villages.REQUIRE_PRIV_FOR_TELEPORT = false; + + -- if set to true, players cannot modify spawned villages without buying the house from the village first +-mg_villages.ENABLE_PROTECTION = true; ++mg_villages.ENABLE_PROTECTION = false; + + -- the first village - the one the player spawns in - will be of this type +-mg_villages.FIRST_VILLAGE_TYPE = 'medieval'; ++--mg_villages.FIRST_VILLAGE_TYPE = 'medieval'; + + -- the mapgen will disregard mapchunks where min.y > mg_villages.MAX_HEIGHT_TREATED; + -- you can set this value to 64 if you have a slow machine and a mapgen which does not create extreme mountains +diff --git a/plotmarker_formspec.lua b/plotmarker_formspec.lua +index 0dd65ad..002c7c7 100644 +--- a/plotmarker_formspec.lua ++++ b/plotmarker_formspec.lua +@@ -366,9 +366,9 @@ end + + mg_villages.form_input_handler = function( player, formname, fields) + -- mg_villages.print(mg_villages.DEBUG_LEVEL_NORMAL,minetest.serialize(fields)); +- if( not( mg_villages.ENABLE_PROTECTION )) then +- return false; +- end ++ -- if( not( mg_villages.ENABLE_PROTECTION )) then ++ -- return false; ++ -- end + + -- teleport to a plot or mob + if( fields[ 'teleport_to' ] diff --git a/my_changes/buildings/ts_doors/ts_doors_update54.patch b/my_changes/buildings/ts_doors/ts_doors_update54.patch new file mode 100644 index 0000000..da75ddb --- /dev/null +++ b/my_changes/buildings/ts_doors/ts_doors_update54.patch @@ -0,0 +1,68 @@ +diff --git a/init.lua b/init.lua +index 566ff86..2d235fc 100755 +--- a/init.lua ++++ b/init.lua +@@ -95,6 +95,7 @@ function ts_doors.register_door(item, description, texture, sounds, recipe) + end + + doors.register("ts_doors:door_" .. item:gsub(":", "_"), { ++ use_texture_alpha = "clip", + tiles = { { name = "[combine:32x38:0,0=" .. texture .. ":0,16=" .. texture .. ":0,32=" .. texture .. ":16,0=" .. texture .. ":16,16=" .. texture .. ":16,32=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base.png^[noalpha^[makealpha:0,255,0", backface_culling = true } }, + description = S(description .. " Windowed Door"), + inventory_image = "[combine:32x32:0,8=" .. texture .. ":16,8=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_inv.png^[noalpha^[makealpha:0,255,0", +@@ -115,6 +116,7 @@ function ts_doors.register_door(item, description, texture, sounds, recipe) + }) + + doors.register_trapdoor("ts_doors:trapdoor_" .. item:gsub(":", "_"), { ++ use_texture_alpha = "clip", + description = S("Windowed " .. description .. " Trapdoor"), + inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor.png^[noalpha^[makealpha:0,255,0", + wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor.png^[noalpha^[makealpha:0,255,0", +@@ -127,6 +129,7 @@ function ts_doors.register_door(item, description, texture, sounds, recipe) + }) + + doors.register_trapdoor("ts_doors:trapdoor_full_" .. item:gsub(":", "_"), { ++ use_texture_alpha = "clip", + description = S("Solid " .. description .. " Trapdoor"), + inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full.png^[noalpha", + wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full.png^[noalpha", +@@ -141,6 +144,7 @@ function ts_doors.register_door(item, description, texture, sounds, recipe) + door_groups.level = 2 + + doors.register("ts_doors:door_locked_" .. item:gsub(":", "_"), { ++ use_texture_alpha = "clip", + tiles = { { name = "[combine:32x38:0,0=" .. texture .. ":0,16=" .. texture .. ":0,32=" .. texture .. ":16,0=" .. texture .. ":16,16=" .. texture .. ":16,32=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_locked.png^[noalpha^[makealpha:0,255,0", backface_culling = true } }, + description = S("Windowed Locked " .. description .. " Door"), + inventory_image = "[combine:32x32:0,8=" .. texture .. ":16,8=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_locked_inv.png^[noalpha^[makealpha:0,255,0", +@@ -154,6 +158,7 @@ function ts_doors.register_door(item, description, texture, sounds, recipe) + }) + + doors.register("ts_doors:door_full_locked_" .. item:gsub(":", "_"), { ++ use_texture_alpha = "clip", + tiles = { { name = "[combine:32x38:0,0=" .. texture .. ":0,16=" .. texture .. ":0,32=" .. texture .. ":16,0=" .. texture .. ":16,16=" .. texture .. ":16,32=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_full_locked.png^[noalpha", backface_culling = true } }, + description = S("Solid Locked " .. description .. " Door"), + inventory_image = "[combine:32x32:0,8=" .. texture .. ":16,8=" .. texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_full_locked_inv.png^[noalpha^[makealpha:0,255,0", +@@ -167,6 +172,7 @@ function ts_doors.register_door(item, description, texture, sounds, recipe) + }) + + doors.register_trapdoor("ts_doors:trapdoor_locked_" .. item:gsub(":", "_"), { ++ use_texture_alpha = "clip", + description = S("Windowed Locked " .. description .. " Trapdoor"), + inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_locked.png^[noalpha^[makealpha:0,255,0", + wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_locked.png^[noalpha^[makealpha:0,255,0", +@@ -180,6 +186,7 @@ function ts_doors.register_door(item, description, texture, sounds, recipe) + }) + + doors.register_trapdoor("ts_doors:trapdoor_full_locked_" .. item:gsub(":", "_"), { ++ use_texture_alpha = "clip", + description = S("Solid Locked " .. description .. " Trapdoor"), + inventory_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full_locked.png^[noalpha", + wield_image = texture .. "^[transformR90^[colorize:#fff:30^ts_doors_base_trapdoor_full_locked.png^[noalpha", +@@ -542,6 +549,7 @@ local function can_dig(pos, player) + end + + ts_workshop.register_workshop("ts_doors", "workshop", { ++ use_texture_alpha = "clip", + description = S("Door Workshop"), + tiles = { + "default_wood.png", diff --git a/my_changes/gui/i3/progressive_creative.patch b/my_changes/gui/i3/progressive_creative.patch new file mode 100644 index 0000000..c0cc718 --- /dev/null +++ b/my_changes/gui/i3/progressive_creative.patch @@ -0,0 +1,13 @@ +diff --git a/init.lua b/init.lua +index 0a953e7..619952d 100644 +--- a/init.lua ++++ b/init.lua +@@ -12,7 +12,7 @@ local toolrepair + + local tabs = {} + +-local progressive_mode = core.settings:get_bool "i3_progressive_mode" ++local progressive_mode = core.settings:get_bool "i3_progressive_mode" and not(core.is_creative_enabled()) + local damage_enabled = core.settings:get_bool "enable_damage" + + local __3darmor, __skinsdb, __awards diff --git a/my_changes/gui/smart_inventory/textures/doc_awards_icon_generic.png b/my_changes/gui/smart_inventory/textures/doc_awards_icon_generic.png new file mode 100644 index 0000000..97f2435 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/doc_awards_icon_generic.png differ diff --git a/my_changes/gui/smart_inventory/textures/doc_button_icon_lores.png b/my_changes/gui/smart_inventory/textures/doc_button_icon_lores.png new file mode 100644 index 0000000..97f2435 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/doc_button_icon_lores.png differ diff --git a/my_changes/gui/smart_inventory/textures/inventory_plus_doc_inventory_plus.png b/my_changes/gui/smart_inventory/textures/inventory_plus_doc_inventory_plus.png new file mode 100644 index 0000000..97f2435 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/inventory_plus_doc_inventory_plus.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_compress_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_compress_button.png new file mode 100644 index 0000000..66d9672 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_compress_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_craftable_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_craftable_button.png new file mode 100644 index 0000000..43f95c5 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_craftable_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_crafting_inventory_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_crafting_inventory_button.png new file mode 100644 index 0000000..b8af7bf Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_crafting_inventory_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_creative_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_creative_button.png new file mode 100644 index 0000000..d8322cf Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_creative_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_exit_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_exit_button.png new file mode 100644 index 0000000..867a927 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_exit_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_get1_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_get1_button.png new file mode 100644 index 0000000..e085770 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_get1_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_get2_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_get2_button.png new file mode 100644 index 0000000..03ba990 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_get2_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_get3_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_get3_button.png new file mode 100644 index 0000000..2d039ea Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_get3_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_preview_to_crafting_field.png b/my_changes/gui/smart_inventory/textures/smart_inventory_preview_to_crafting_field.png new file mode 100644 index 0000000..9e52a26 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_preview_to_crafting_field.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_reveal_tips_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_reveal_tips_button.png new file mode 100644 index 0000000..849aa5a Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_reveal_tips_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_save1_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_save1_button.png new file mode 100644 index 0000000..2c5144b Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_save1_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_save2_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_save2_button.png new file mode 100644 index 0000000..89be1ab Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_save2_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_save3_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_save3_button.png new file mode 100644 index 0000000..e26defc Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_save3_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_swapline_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_swapline_button.png new file mode 100644 index 0000000..de67b18 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_swapline_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_sweep_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_sweep_button.png new file mode 100644 index 0000000..dc86463 Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_sweep_button.png differ diff --git a/my_changes/gui/smart_inventory/textures/smart_inventory_trash_all_button.png b/my_changes/gui/smart_inventory/textures/smart_inventory_trash_all_button.png new file mode 100644 index 0000000..bf6e63f Binary files /dev/null and b/my_changes/gui/smart_inventory/textures/smart_inventory_trash_all_button.png differ diff --git a/my_changes/mobs/mobs_mobkit/petz/petz/user.conf b/my_changes/mobs/mobs_mobkit/petz/petz/user.conf new file mode 100644 index 0000000..ed48ba3 --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/petz/petz/user.conf @@ -0,0 +1,15 @@ +##Tamagochi Mode (Take care of your pet: fed it...) +tamagochi_mode = false + +##Shears +shears = mobs:shears + +##Selling +selling = false + +##Bloody Mode +blood = true + +##Capture Mobs +lasso = mobs:lasso +rob_mobs = true diff --git a/my_changes/mobs/mobs_mobkit/water_life/files/apa_patch.lua b/my_changes/mobs/mobs_mobkit/water_life/files/apa_patch.lua new file mode 100644 index 0000000..d14688d --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/files/apa_patch.lua @@ -0,0 +1,11 @@ + +water_life.poison_after_death = minetest.settings:get_bool("water_life_poison_after_death") or false + +minetest.register_on_dieplayer(function(player) + if not player then return end + if water_life.poison_after_death then return end + + local meta=player:get_meta() + meta:set_int("snakepoison",0) + water_life.change_hud(player,"poison",0) +end) \ No newline at end of file diff --git a/my_changes/mobs/mobs_mobkit/water_life/files/api.lua b/my_changes/mobs/mobs_mobkit/water_life/files/api.lua new file mode 100644 index 0000000..78e30f0 --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/files/api.lua @@ -0,0 +1,900 @@ + +local abs = math.abs +local pi = math.pi +local floor = math.floor +local ceil = math.ceil +local sqrt = math.sqrt +local max = math.max +local min = math.min +local pow = math.pow +local sign = math.sign +local time = os.time +local rad = math.rad +local deg=math.deg +local tan = math.tan +local cos = math.cos +local atan=math.atan + + + +local neighbors ={ + {x=1,z=0}, + {x=1,z=1}, + {x=0,z=1}, + {x=-1,z=1}, + {x=-1,z=0}, + {x=-1,z=-1}, + {x=0,z=-1}, + {x=1,z=-1} + } + + +-- pseudo random generator, init and call function +water_life.randomtable = PcgRandom(math.random(2^23)+1) + +function water_life.random(min,max) + if not min and not max then return math.abs(water_life.randomtable:next() / 2^31) end + if not max then + max = min + min = 1 + end + if max and not min then min = 1 end + if max < min then return water_life.randomtable:next(max,min) end + + return water_life.randomtable:next(min,max) +end + +-- +local random = water_life.random -- do not delete, this MUST be here! +-- + +--checks if entity is in a small water pool +function water_life.check_for_pool(self,deep,minr,pos) + if not self and not pos then return nil end + if not deep then deep = 3 end + if not minr then minr = 3 end + + local max = 16 + if not pos then + pos = self.object:get_pos() + end + + local d,t,s = water_life.water_depth(pos,max) + if not d then return nil end + local cpos = {} + local ispool = 0 + + for i = 0,270,90 do + cpos = mobkit.pos_translate2d(pos,rad(i),minr) + if water_life.find_collision(pos,cpos,false) then ispool = ispool + 1 end + end + + if ispool > 2 and d < deep then return true end + return false +end + + +-- returns ingame time, 1 = morning, 2 = noon, 3 = afternoon, 4 = night +function water_life.get_game_time() + local time = minetest.get_timeofday() + local hour = math.floor(time*24) + + if hour >= 5 and hour < 10 then return 1 end + if hour >= 10 and hour < 15 then return 2 end + if hour >= 15 and hour < 20 then return 3 end + if hour > 20 or hour < 5 then return 4 end +end + + +function water_life_get_biome_data(pos) + if not pos then return nil end + local table = minetest.get_biome_data(pos) + if not table then return nil end + local biome = {} + biome.id = table.biome + biome.name = minetest.get_biome_name(table.biome) + biome.temp = math.floor((table.heat-32)*5/9) --turn fahrenheit into celsius + biome.humid = math.floor(table.humidity*100)/100 + return biome +end + + + +-- returns closest enemy or player, if player is true enemies must be in entity definition: predators = {[name1]=1,[name2]=1,.....} +function water_life.get_closest_enemy(self,player) + local cobj = nil + local dist = water_life.abr*64 + local pos = self.object:get_pos() + local otable = minetest.get_objects_inside_radius(pos, self.view_range) + + if not self.predators and not player then return nil end + + for _,obj in ipairs(otable) do + local luaent = obj:get_luaentity() + + if mobkit.is_alive(obj) and not obj:is_player() and luaent and self.predators[luaent.name] then + local opos = obj:get_pos() + local odist = abs(opos.x-pos.x) + abs(opos.z-pos.z) + if odist < dist then + dist=odist + cobj=obj + end + elseif mobkit.is_alive(obj) and obj:is_player() and player then + local opos = obj:get_pos() + local odist = abs(opos.x-pos.x) + abs(opos.z-pos.z) + if odist < dist then + dist=odist + cobj=obj + end + end + end + return cobj +end + + +--player knockback from entity +function water_life.knockback_player(self,target,force) + if not target:is_player() then return end + if not self.object then return end + if not force then force = 10 end + local dir = minetest.yaw_to_dir(self.object:get_yaw()) + dir = vector.multiply(dir, force) + dir = {x=dir.x, y=dir.y+force/2, z= dir.z} + target:add_player_velocity(dir) +end + + +--sets an urchin somewhere but not in the center of a node +function water_life.set_urchin(pos,name) + if not pos then return end + if not name then name = "water_life:urchin" end + local x = random()/2 + local z = random()/2 + if water_life.leftorright() then pos.x = pos.x +x else pos.x=pos.x - x end + if water_life.leftorright() then pos.z = pos.z +z else pos.z=pos.z - z end + local obj = minetest.add_entity(pos, name) + return obj +end + +-- add vector cross function for flying behavior if not yet there +if vector and not vector.cross then + function vector.cross(a, b) + return { + x = a.y * b.z - a.z * b.y, + y = a.z * b.x - a.x * b.z, + z = a.x * b.y - a.y * b.x + } + end +end + + + +-- show temp marker +function water_life.temp_show(pos,time,pillar) + if not pos then return end + if not time then time = 5 end + local step = 1 + if not pillar then pillar = 1 end + if pillar < 0 then step = -1 end + + for i = 1,pillar,step do + + local obj = minetest.add_entity({x=pos.x, y=pos.y+i, z=pos.z}, "water_life:pos") + if obj then + minetest.after(time, function(obj) obj:remove() end, obj) + end + end + +end + + +-- throws a coin +function water_life.leftorright() + local rnd = random() + if rnd > 0.5 then return true else return false end +end + + +-- distance from self to target +function water_life.dist2tgt(self,tgt) + local pos = mobkit.get_stand_pos(self) + local tpos = tgt:get_pos() + return vector.distance(pos,tpos) +end + + +function water_life.dumbstep(self,height,tpos,speed_factor,idle_duration) + if height <= 0.001 then + mobkit.lq_turn2pos(self,tpos) + water_life.lq_dumbwalk(self,tpos,speed_factor) + else + mobkit.lq_turn2pos(self,tpos) + water_life.lq_dumbjump(self,height) + end + idle_duration = idle_duration or 6 + mobkit.lq_idle(self,random(ceil(idle_duration*0.5),idle_duration)) +end + + + + -- drop on death what is definded in the entity table +function water_life.handle_drops(self) + if not self.drops then return end + + for _,item in ipairs(self.drops) do + + local amount = random (item.min, item.max) + local chance = random(1,100) + local pos = self.object:get_pos() + pos.y = pos.y + self.collisionbox[5] +1 + + if chance < (100/item.chance) then + local obj = minetest.add_item(pos, item.name.." "..tostring(amount)) + end + + end +end + + + +function water_life.register_shark_food(name) + table.insert(water_life.shark_food,name) +end + +function water_life.register_gull_bait(name) + if name then water_life.gull_bait[name] = 1 end +end + + +function water_life.feed_shark(self) + for i = 1,#water_life.shark_food,1 do + if water_life.shark_food[i] ~= "water_life:fish" and water_life.shark_food[i] ~= "water_life:fish_tamed" then + local target = mobkit.get_closest_entity(self,water_life.shark_food[i]) + if target then + return target + end + end + end + return nil +end + + + + + +function water_life.get_close_drops(self,name) + + + local objs = minetest.get_objects_inside_radius(self.object:get_pos(), self.view_range) + if #objs < 1 then return nil end + + for i = #objs,1,-1 do + local entity = objs[i]:get_luaentity() + if not entity or not entity.name == "__builtin:item" then table.remove(objs,i) end -- remove any entity different from a drop + end + + if #objs < 1 then return nil end + if not name then return objs[random(#objs)] end -- no name, return random drop + + for i=#objs,1,-1 do + local entity = objs[i]:get_luaentity() + if not entity.itemstring then + table.remove(objs,i) + else + if not string.match(entity.itemstring,name) then table.remove(objs,i) end -- remove anything different from name + end + end + + if #objs < 1 then + return nil + else + return objs[random(#objs)] + end +end + + +function water_life.inwater(obj) + if not obj then return nil end + local pos = obj:get_pos() + local node = minetest.get_node(pos) + if not node or node.name == 'ignore' then return nil end + if not minetest.registered_nodes[node.name] then return nil end -- handle unknown nodes + + local type = minetest.registered_nodes[node.name]["liquidtype"] + if type == "none" then return nil end + return true +end + +function water_life.aqua_radar_dumb(pos,yaw,range,reverse,shallow) -- same as mobkit's but added shallow water if true + range = range or 4 + + local function okpos(p) + local node = mobkit.nodeatpos(p) + if node then + if node.drawtype == 'liquid' then + local nodeu = mobkit.nodeatpos(mobkit.pos_shift(p,{y=1})) + local noded = mobkit.nodeatpos(mobkit.pos_shift(p,{y=-1})) + if ((nodeu and nodeu.drawtype == 'liquid') or (noded and noded.drawtype == 'liquid')) or shallow then + return true + else + return false + end + else + local h,l = mobkit.get_terrain_height(p) + if h then + local node2 = mobkit.nodeatpos({x=p.x,y=h+1.99,z=p.z}) + if node2 and node2.drawtype == 'liquid' then return true, h end + else + return false + end + end + else + return false + end + end + + local fpos = mobkit.pos_translate2d(pos,yaw,range) + local ok,h = okpos(fpos) + if not ok then + local ffrom, fto, fstep + if reverse then + ffrom, fto, fstep = 3,1,-1 + else + ffrom, fto, fstep = 1,3,1 + end + for i=ffrom, fto, fstep do + local ok,h = okpos(mobkit.pos_translate2d(pos,yaw+i,range)) + if ok then return yaw+i,h end + ok,h = okpos(mobkit.pos_translate2d(pos,yaw-i,range)) + if ok then return yaw-i,h end + end + return yaw+pi,h + else + return yaw, h + end +end + + + +-- counts animals in specified radius or active_block_range, returns a table containing numbers +function water_life.count_objects(pos,radius,name) + +if not radius then radius = water_life.abr * 16 end + +local all_objects = minetest.get_objects_inside_radius(pos, radius) +local hasil = {} +hasil.whales = 0 +hasil.sharks = 0 +hasil.fish = 0 +hasil.name = 0 +hasil.all = #all_objects or 0 + +local _,obj +for _,obj in ipairs(all_objects) do + local entity = obj:get_luaentity() + if name then + if entity and entity.name == name then + hasil.name = hasil.name +1 + end + end + if entity and entity.name == "water_life:whale" then + hasil.whales = hasil.whales +1 + elseif entity and entity.name == "water_life:shark" then + hasil.sharks = hasil.sharks +1 + elseif entity and (entity.name == "water_life:fish" or entity.name == "water_life:fish_tamed") then + hasil.fish = hasil.fish +1 + end + + if entity and entity.name then + if not hasil[entity.name] then + hasil[entity.name] = 1 + else + hasil[entity.name] = hasil[entity.name] +1 + end + end + end + + return hasil +end + + +function water_life.get_herd_members(self,radius) + + local pos = mobkit.get_stand_pos(self) + local name = self.name + + if not radius then radius = water_life.abo * 16 end + + local all_objects = minetest.get_objects_inside_radius(pos, radius) + if #all_objects < 1 then return nil end + + for i = #all_objects,1,-1 do + local entity = all_objects[i]:get_luaentity() + + if entity and entity.name ~= name then + table.remove(all_objects,i) + end + + end + + if #all_objects < 1 then + return nil + else + return all_objects + end +end + + +-- returns 2D angle from self to target in radians +function water_life.get_yaw_to_object(self,target) + + local pos = mobkit.get_stand_pos(self) + local tpos = target:get_pos() + local tyaw = minetest.dir_to_yaw(vector.direction(pos, tpos)) + return tyaw +end + +-- returns 2D angle from self to pos in radians +function water_life.get_yaw_to_pos(self,tpos) + + local pos = mobkit.get_stand_pos(self) + local tyaw = minetest.dir_to_yaw(vector.direction(pos, tpos)) + + return tyaw +end + + + + + + +function water_life.isinliquid(target) + if not target then return false end + local nodepos = mobkit.get_stand_pos(target) + local node1 = mobkit.nodeatpos(nodepos) + nodepos.y = nodepos.y -1 + local node2 = mobkit.nodeatpos(nodepos) + if node1 and node1.drawtype=='liquid' or (node2 and node2.drawtype=='liquid' and node1 and node1.drawtype=='airlike') then + return true + end +end + + +-- find if there is a node between pos1 and pos2 +-- water = true means water = obstacle +-- returns distance to obstacle in nodes or nil + +function water_life.find_collision(pos1,pos2,water,objects) + local ray = minetest.raycast(pos1, pos2, objects, water) + for pointed_thing in ray do + if pointed_thing.type == "node" then + local dist = math.floor(vector.distance(pos1,pointed_thing.under)) + return dist + end + end + return nil +end + + +-- fast radar, less accurate +-- yaw-x to the right, yaw + x to the left ! +-- sonar = true water is no obstacle + +function water_life.radar_fast(self,dist,sonar) + local water = not sonar + if not dist then dist = self.view_range end + local angel = atan(3/dist) + local yaw = self.object:get_yaw() + local tpos = self.object:get_pos() + local tapos = mobkit.pos_translate2d(tpos,(yaw-angel),dist) + local tbpos = mobkit.pos_translate2d(tpos,yaw,dist) + local tcpos = mobkit.pos_translate2d(tpos,(yaw+angel),dist) + local tupos = mobkit.pos_shift(tbpos,{y=2}) + local tdpos = mobkit.pos_shift(tbpos,{y=-2}) + local right = water_life.find_collision(tpos,tapos,water) + local left = water_life.find_collision(tpos,tcpos,water) + local center = water_life.find_collision(tpos,tbpos,water) + local up = water_life.find_collision(tpos,tupos,water) + local down = water_life.find_collision(tpos,tdpos,water) + + return left,right,center,up,down + +end + + +-- WIP radar, not ready to use ! +function water_life.radar_fast_cols(obj,dist,sonar,rev) --sonar = true, water no obstacle :: rev = true array contains possible positions + if not dist then dist = 3 end + local pos = obj:get_pos() + local yaw = 0 + local box = {} + local counter = 1 + local rarray = {} + + + if obj:is_player() then + yaw = obj:get_look_horizontal() + box = obj:get_properties().collisionbox + else + yaw = obj:get_yaw() + if obj:get_luaentity().name == "water_life:whale" then yaw = yaw + rad(180) end + box = obj:get_luaentity().collisionbox + end + + local vec = minetest.yaw_to_dir(yaw) + local crasha = mobkit.get_box_displace_cols(pos,box,vec,dist) + + + if crasha then + for i = #crasha,1,-1 do + for j = #crasha[i],1,-1 do + local cpos ={x=crasha[i][j].x, y= pos.y, z= crasha[i][j].z} + --local cyaw = abs(math.floor(minetest.dir_to_yaw(vector.direction(pos,cpos))*10)) + local node = minetest.get_node(cpos) + if minetest.registered_nodes[node.name] then + local kill = false + if minetest.registered_nodes[node.name]["drawtype"] == "airlike" then kill = true end + if minetest.registered_nodes[node.name]["buildable_to"] then kill = true end + if minetest.registered_nodes[node.name]["drawtype"] == "liquid" then kill = sonar end + + if kill then + if not rev then + table.remove(crasha[i],j) + else + rarray[counter] = cpos + counter = counter +1 + end + else + if not rev then + rarray[counter] = cpos + counter = counter +1 + else + table.remove(crasha[i],j) + end + end + end + end + + end + end + return rarray +end + +-- radar function for obstacles lying in front of an entity +-- use water = true if water should be an obstacle + +function water_life.radar(pos, yaw, radius, water,fast) + + if not radius or radius < 1 then radius = 16 end + local left = 0 + local right = 0 + if not water then water = false end + for j = 0,3,1 do + for i = 0,4,1 do + local pos2 = mobkit.pos_translate2d(pos,yaw+(i*pi/16),radius) + local pos3 = mobkit.pos_translate2d(pos,yaw-(i*pi/16),radius) + --minetest.set_node(pos2,{name="default:stone"}) + if water_life.find_collision(pos,{x=pos2.x, y=pos2.y + j*2, z=pos2.z}, water) then + left = left + 5 - i + end + if water_life.find_collision(pos,{x=pos3.x, y=pos3.y + j*2, z=pos3.z},water) then + right = right + 5 - i + end + end + end + local up =0 + local down = 0 + if not fast then + for j = -4,4,1 do + for i = -3,3,1 do + local k = i + local pos2 = mobkit.pos_translate2d(pos,yaw+(i*pi/16),radius) + local collide = water_life.find_collision(pos,{x=pos2.x, y=pos2.y + j, z=pos2.z}, water) + if k < 0 then k = k * -1 end + if collide and j <= 0 then + down = down + math.floor((7+j-k)*collide/radius*2) + elseif collide and j >= 0 then + up = up + math.floor((7-j-k)*collide/radius*2) + end + end + end + end + local under = water_life.find_collision(pos,{x=pos.x, y=pos.y - radius, z=pos.z}, water) + if not under then under = radius end + local above = water_life.find_collision(pos,{x=pos.x, y=pos.y + radius, z=pos.z}, water) + if not above then above = radius end + if water_life.radar_debug then + -- minetest.chat_send_all(dump(water_life.radar_debug).." left = "..left.." right = "..right.." up = "..up.." down = "..down.." under = "..under.." above = "..above) + end + return left, right, up, down, under, above +end + + +--find a spawn position under air +function water_life.find_node_under_air(pos,radius,name) + if not pos then return nil end + if not radius then radius = 3 end + if not name then name={"group:crumbly","group:stone","group:tree"} end + + local pos1 = {x=pos.x-radius, y=pos.y-radius, z=pos.z-radius} --mobkit.pos_shift(pos,{x=radius*-1,y=radius*-1,z=radius*-1}) + local pos2 = {x=pos.x+radius, y=pos.y+radius, z=pos.z+radius} --mobkit.pos_shift(pos,{x=radius,y=radius,z=radius}) + local spawner = minetest.find_nodes_in_area_under_air(pos1, pos2, name) + if not spawner or #spawner < 1 then + return nil + else + local rpos = spawner[random(#spawner)] + rpos = mobkit.pos_shift(rpos,{y=1}) + return rpos + end +end + +-- function to find liquid surface and depth at that position +function water_life.water_depth(pos,max) + + + local surface = {} + local depth = 0 + local type = "" + if not max then max = 10 end + if not pos then return nil end + local tempos = {} + local node = minetest.get_node(pos) + if not node or node.name == 'ignore' then return nil end + if not minetest.registered_nodes[node.name] then return nil end -- handle unknown nodes + + local type = minetest.registered_nodes[node.name]["liquidtype"] + local found = false + --minetest.chat_send_all(">>>"..dump(node.name).." <<<") + if type == "none" then -- start in none liquid try to find surface + + local under = water_life.find_collision(pos,{x=pos.x, y=pos.y - max, z=pos.z}, true) + --minetest.chat_send_all(dump(under).." "..dump(node.name)) + if under then + local check = {x=pos.x, y=pos.y - under-1, z=pos.z} + local cname = minetest.get_node(check).name + if not minetest.registered_nodes[cname] then return nil end -- handle unknown nodes + if minetest.registered_nodes[cname]["liquidtype"] == "source" then + surface = check + found = true + end + end + if not found then + return nil + end + + else -- start in liquid find way up first + + local lastpos = pos + for i = 1,max,1 do + tempos = {x=pos.x, y=pos.y+i, z= pos.z} + node = minetest.get_node(tempos) + if not minetest.registered_nodes[node.name] then return nil end -- handle unknown nodes + local ctype = minetest.registered_nodes[node.name]["liquidtype"] + + if ctype == "none" then + surface = lastpos + found = true + break + end + lastpos = tempos + end + if not found then surface = lastpos end + end + + pos = surface + type = minetest.get_node(pos).name or "" + local under = water_life.find_collision(pos,{x=pos.x, y=pos.y - max, z=pos.z}, false) + depth = under or max + + return depth, type, surface +end + + +-- amphibious version of mobkit +function water_life.get_next_waypoint_fast(self,tpos,nogopos) + local pos = mobkit.get_stand_pos(self) + local dir=vector.direction(pos,tpos) + local neighbor = mobkit.dir2neighbor(dir) + local height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor) + local heightr = nil + local heightl = nil + local liq = nil + + if height then + local fast = false + heightl = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-1)) + if heightl and abs(heightl-height)<0.001 then + heightr = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,1)) + if heightr and abs(heightr-height)<0.001 then + fast = true + dir.y = 0 + local dirn = vector.normalize(dir) + local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor])) + local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z) + pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor}) + end + end + return height, pos2, fast + else + + for i=1,4 do + -- scan left + height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-i)) + if height then return height,pos2 end + -- scan right + height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,i)) + if height then return height,pos2 end + end + end +end + +-- amphibious version of mobkit +function water_life.goto_next_waypoint(self,tpos) + local height, pos2 = water_life.get_next_waypoint_fast(self,tpos) + + if not height then return false end + + if height <= 0.01 then + local yaw = self.object:get_yaw() + local tyaw = minetest.dir_to_yaw(vector.direction(self.object:get_pos(),pos2)) + if abs(tyaw-yaw) > 1 then + mobkit.lq_turn2pos(self,pos2) + end + mobkit.lq_dumbwalk(self,pos2) + else + mobkit.lq_turn2pos(self,pos2) + mobkit.lq_dumbjump(self,height) + end + return true +end + + + +function water_life.get_next_waypoint(self,tpos) + local pos = mobkit.get_stand_pos(self) + local dir=vector.direction(pos,tpos) + local neighbor = mobkit.dir2neighbor(dir) + local function update_pos_history(self,pos) + table.insert(self.pos_history,1,pos) + if #self.pos_history > 2 then table.remove(self.pos_history,#self.pos_history) end + end + local nogopos = self.pos_history[2] + + local height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor) +--minetest.chat_send_all('pos2 ' .. minetest.serialize(pos2)) +--minetest.chat_send_all('nogopos ' .. minetest.serialize(nogopos)) + if height and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then + + local heightl = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-1)) + if heightl and abs(heightl-height)<0.001 then + local heightr = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,1)) + if heightr and abs(heightr-height)<0.001 then + dir.y = 0 + local dirn = vector.normalize(dir) + local npos = mobkit.get_node_pos(mobkit.pos_shift(pos,neighbors[neighbor])) + local factor = abs(dirn.x) > abs(dirn.z) and abs(npos.x-pos.x) or abs(npos.z-pos.z) + pos2=mobkit.pos_shift(pos,{x=dirn.x*factor,z=dirn.z*factor}) + end + end + update_pos_history(self,pos2) + return height, pos2 + else + + for i=1,3 do + -- scan left + local height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,-i*self.path_dir)) + if height and not liq + and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then + update_pos_history(self,pos2) + return height,pos2 + end + -- scan right + height, pos2, liq = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,i*self.path_dir)) + if height and not liq + and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then + update_pos_history(self,pos2) + return height,pos2 + end + end + --scan rear + height, pos2, liquidflag = mobkit.is_neighbor_node_reachable(self,mobkit.neighbor_shift(neighbor,4)) + if height and not liquidflag + and not (nogopos and mobkit.isnear2d(pos2,nogopos,0.1)) then + update_pos_history(self,pos2) + return height,pos2 + end + end + -- stuck condition here + table.remove(self.pos_history,2) + self.path_dir = self.path_dir*-1 -- subtle change in pathfinding +end + + +-- blood effects +function water_life.spilltheblood(object,size) + if not water_life.bloody then return end + if not size then size = 1 end + local particlespawner_id = minetest.add_particlespawner({ + amount = 50, + time = 1, + minpos = vector.new(-0.3, size/2, -0.3), + maxpos = vector.new( 0.3, size, 0.3), + minvel = {x = -1, y = 0, z = -1}, + maxvel = {x = 1, y = 1, z = 1}, + minacc = {x = 0, y = 2, z = 0}, + maxacc = {x = 0, y = 3, z = 0}, + minexptime = 0.5, + maxexptime = 1, + minsize = 1, + maxsize = 2, + texture = "water_life_bloodeffect1.png", + collisiondetection = true, + collision_removal = true, + object_collision = true, + attached = object, + }) +end + + +-- Entity definitions + +-- entity for showing positions in debug +minetest.register_entity("water_life:pos", { + initial_properties = { + visual = "cube", + collide_with_objects = false, + visual_size = {x=1.1, y=1.1}, + textures = {"water_life_pos.png", "water_life_pos.png", + "water_life_pos.png", "water_life_pos.png", + "water_life_pos.png", "water_life_pos.png"}, + collisionbox = {-0.55, -0.55, -0.55, 0.55, 0.55, 0.55}, + physical = false, + } +}) + +if water_life.radar_debug then +minetest.register_on_player_hpchange(function(player, hp_change, reason) + if not player or hp_change >= 0 then return hp_change end + local name = player:get_player_name() + local privs = minetest.get_player_privs(name) + if not privs.god then return hp_change end + return 0 + end, true) + +minetest.register_privilege("god", {description ="unvulnerable"}) +end + + +--check here for antiserum group of eaten food +minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, user, pointed_thing) + if not user or not user:is_player() then return end + if not itemstack then return end + local name = user:get_player_name() + local antiserum = itemstack:get_definition().groups.antiserum + if antiserum then + local meta = user:get_meta() + local score = user:get_hp() + + if meta:get_int("snakepoison") > 0 then meta:set_int("snakepoison",0) hunger_ng.set_effect(user:get_player_name(), "heal", "enabled") end + water_life.change_hud(user,"poison",0) + end + + return +end) + + +--new players are immune to snakepoison +minetest.register_on_newplayer(function(player) + if not player or not player:is_player() then return end + local meta = player:get_meta() + local join = os.time() + meta:set_int("jointime",join) +end) + +-- but not forever +minetest.register_on_joinplayer(function(player) + if not player or not player:is_player() then return end + local meta = player:get_meta() + meta:set_int("bitten",0) + meta:set_int("repellant",0) +end) diff --git a/my_changes/mobs/mobs_mobkit/water_life/files/behaviors.lua b/my_changes/mobs/mobs_mobkit/water_life/files/behaviors.lua new file mode 100644 index 0000000..61935b6 --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/files/behaviors.lua @@ -0,0 +1,1367 @@ + +local abs = math.abs +local pi = math.pi +local floor = math.floor +local ceil = math.ceil +local sqrt = math.sqrt +local max = math.max +local min = math.min +local pow = math.pow +local sign = math.sign +local time = os.time +local rad = math.rad +local random = water_life.random +local deg=math.deg +local tan = math.tan +local cos = math.cos +local atan=math.atan + + + + +-- flying stuff + +local function chose_turn(self,a,b) + + local remember = mobkit.recall(self,"turn") + if not remember then + if water_life.leftorright() then + remember = "1" + mobkit.remember(self,"time", self.time_total) + mobkit.remember(self,"turn", "1") + else + remember = "0" + mobkit.remember(self,"time", self.time_total) + mobkit.remember(self,"turn", "0") + end + end + + if a > b then + mobkit.remember(self,"turn", "1") + mobkit.remember(self,"time", self.time_total) + return false + + elseif a < b then + mobkit.remember(self,"turn","0") + mobkit.remember(self,"time", self.time_total) + return true + + else + + if remember == "0" then return true else return false end + + end +end + + + +local function pitchroll2pitchyaw(aoa,roll) + if roll == 0.0 then return aoa,0 end + -- assumed vector x=0,y=0,z=1 + local p1 = tan(aoa) + local y = cos(roll)*p1 + local x = sqrt(p1^2-y^2) + local pitch = atan(y) + local yaw=atan(x)*math.sign(roll) + return pitch,yaw +end + + + +------------------ +-- LQ behaviors -- +------------------ +--[[ +params: +lift: [number] +multiplier for lift. faster objects need less, slower need more. typical value: 0.6 for speeds around 4 m/s + +pitch: [degrees] +angle between the longitudinal axis and horizontal plane. typical range: <-15.15> + +aoa: +[degrees] angle of attack - the angle between the longitudinal axis and velocity vector. + +roll: [degrees] +bank angle. positive is right, negative is left, this is how they turn. if set too large they'll loose height rapidly + +acc: [number] +propulsion. use with positive pitch to make them fly level or climb, set it to 0 with slight negative pitch to make +them glide. typical value: around 1.0 + +anim: [string] +animation. +The example uses two simple high level behaviors to keep them between 18 and 24 nodes above ground, seems good already for ambient type flying creatures. +warning: never set_velocity when using these behaviors. +]] + +function water_life.lq_fly_aoa(self,lift,aoa,roll,acc,anim) + aoa=rad(aoa) + roll=rad(roll) + local hpitch = 0 + local hyaw = 0 + local caoa = 0 + local laoa = nil + local croll=roll + local lroll = nil + local lastrot = nil + local init = true + local func=function(self) + local rotation=self.object:get_rotation() + local vel = self.object:get_velocity() + local vrot = mobkit.dir_to_rot(vel,lastrot) + lastrot = vrot + if init then + if anim then mobkit.animate(self,anim) end + init = false + end + + local accel=self.object:get_acceleration() + + -- gradual changes + if abs(roll-rotation.z) > 0.5*self.dtime then + croll = rotation.z+0.5*self.dtime*math.sign(roll-rotation.z) + end + + if croll~=lroll then + hpitch,hyaw = pitchroll2pitchyaw(aoa,croll) + lroll = croll + end + + local hrot = {x=vrot.x+hpitch,y=vrot.y-hyaw,z=croll} + self.object:set_rotation(hrot) + local hdir = mobkit.rot_to_dir(hrot) + local cross = vector.cross(vel,hdir) + local lift_dir = vector.normalize(vector.cross(cross,hdir)) + + local daoa = deg(aoa) + local lift_coefficient = 0.24*abs(daoa)*(1/(0.025*daoa+1))^4*math.sign(aoa) -- homegrown formula + local lift_val = lift*vector.length(vel)^2*lift_coefficient + + local lift_acc = vector.multiply(lift_dir,lift_val) + lift_acc=vector.add(vector.multiply(minetest.yaw_to_dir(rotation.y),acc),lift_acc) + + self.object:set_acceleration(vector.add(accel,lift_acc)) + end + mobkit.queue_low(self,func) +end + +function water_life.lq_fly_pitch(self,lift,pitch,roll,acc,anim) + pitch = rad(pitch) + roll=rad(roll) + local cpitch = pitch + local croll = roll + local hpitch = 0 + local hyaw = 0 + local lpitch = nil + local lroll = nil + local lastrot = nil + local init = true + + local func=function(self) + if init then + if anim then mobkit.animate(self,anim) end + init = false + end + local rotation=self.object:get_rotation() + local accel=self.object:get_acceleration() + local vel = self.object:get_velocity() + local speed = vector.length(vel) + local vdir = vector.normalize(vel) + local vrot = mobkit.dir_to_rot(vel,lastrot) + lastrot = vrot + + -- gradual changes + if abs(roll-rotation.z) > 0.5*self.dtime then + croll = rotation.z+0.5*self.dtime*math.sign(roll-rotation.z) + end + if abs(pitch-rotation.x) > 0.5*self.dtime then + cpitch = rotation.x+0.5*self.dtime*math.sign(pitch-rotation.x) + end + + if cpitch~=lpitch or croll~=lroll then + hpitch,hyaw = pitchroll2pitchyaw(cpitch,croll) + lpitch = cpitch lroll = croll + end + + local aoa = deg(-vrot.x+cpitch) -- angle of attack + local hrot = {x=hpitch, y=vrot.y-hyaw, z=croll} -- hull rotation + self.object:set_rotation(hrot) + local hdir = mobkit.rot_to_dir(hrot) -- hull dir + + local cross = vector.cross(hdir,vel) + local lift_dir = vector.normalize(vector.cross(hdir,cross)) + + local lift_coefficient = 0.24*max(aoa,0)*(1/(0.025*max(aoa,0)+1))^4 -- homegrown formula +-- local lift_val = mobkit.minmax(lift*speed^2*lift_coefficient,speed/self.dtime) +-- local lift_val = max(lift*speed^2*lift_coefficient,0) + local lift_val = min(lift*speed^2*lift_coefficient,20) +--if lift_val > 10 then minetest.chat_send_all('lift: '.. lift_val ..' vel:'.. speed ..' aoa:'.. aoa) end + + local lift_acc = vector.multiply(lift_dir,lift_val) + lift_acc=vector.add(vector.multiply(minetest.yaw_to_dir(rotation.y),acc),lift_acc) + accel=vector.add(accel,lift_acc) + accel=vector.add(accel,vector.multiply(vdir,-speed*speed*0.02)) -- drag + accel=vector.add(accel,vector.multiply(hdir,acc)) -- propeller + + self.object:set_acceleration(accel) + + end + mobkit.queue_low(self,func) +end + + + +function water_life.lq_dumbjump(self,height,anim) + anim = anim or 'stand' + local jump = true + local func=function(self) + local yaw = self.object:get_yaw() + + if jump then + mobkit.animate(self,anim) + local dir = minetest.yaw_to_dir(yaw) + dir.y = -mobkit.gravity*sqrt((height+0.35)*2/-mobkit.gravity) + self.object:set_velocity(dir) + jump = false + else -- the eagle has landed + return true + end + + + end + mobkit.queue_low(self,func) +end + + +function water_life.lq_dumbwalk(self,dest,speed_factor) + local timer = 3 -- failsafe + speed_factor = speed_factor or 1 + local func=function(self) + mobkit.animate(self,'walk') + timer = timer - self.dtime + if timer < 0 then return true end + + local pos = mobkit.get_stand_pos(self) + local y = self.object:get_velocity().y + local dir = vector.normalize(vector.direction({x=pos.x,y=0,z=pos.z}, + {x=dest.x,y=0,z=dest.z})) + dir = vector.multiply(dir,self.max_speed*speed_factor) + mobkit.turn2yaw(self,minetest.dir_to_yaw(dir)) + dir.y = y + self.object:set_velocity(dir) + + end + mobkit.queue_low(self,func) +end + + +function water_life.lq_jumpattack(self,height,target,extra) + local phase=1 + local timer=0.5 + local tgtbox = target:get_properties().collisionbox + local func=function(self) + local selfname = self.object:get_luaentity().name + if not mobkit.is_alive(target) then return true end + if self.isonground then + if phase==1 then -- collision bug workaround + local vel = self.object:get_velocity() + vel.y = -mobkit.gravity*sqrt(height*2/-mobkit.gravity) + self.object:set_velocity(vel) + mobkit.make_sound(self,'charge') + phase=2 + else + mobkit.lq_idle(self,0.3) + return true + end + elseif phase==2 then + local dir = minetest.yaw_to_dir(self.object:get_yaw()) + local vy = self.object:get_velocity().y + dir=vector.multiply(dir,6) + dir.y=vy + self.object:set_velocity(dir) + phase=3 + elseif phase==3 then -- in air + local tgtpos = target:get_pos() + local pos = self.object:get_pos() + -- calculate attack spot + local yaw = self.object:get_yaw() + local dir = minetest.yaw_to_dir(yaw) + local apos = mobkit.pos_translate2d(pos,yaw,self.attack.range) + + if mobkit.is_pos_in_box(apos,tgtpos,tgtbox) then --bite + target:punch(self.object,1,self.attack) + if selfname and target:is_player() then + if selfname == "water_life:snake" then + local meta = target:get_meta() + local name = target:get_player_name() + local join = meta:get_int("jointime") + if not join or (os.time() - join) > water_life.newplayerbonus * 86400 then + hunger_ng.set_effect(target:get_player_name(), "heal", "disabled") + meta:set_int("snakepoison",1) + water_life.change_hud(target,"poison") + else + local left = water_life.newplayerbonus - math.floor((os.time() - join)/86400*100)/100 + minetest.chat_send_player(target:get_player_name(),minetest.colorize('#fd4000',">>> A rattlesnake bit you. New player bonus of "..left.. + " days left. Catch 3 snakes to craft antiserum")) + meta:set_int("bitten",1) + + minetest.after(10,function() + meta:set_int("bitten",0) + end,meta) + end + end + end + -- bounce off + local vy = self.object:get_velocity().y + self.object:set_velocity({x=dir.x*-3,y=vy,z=dir.z*-3}) + -- play attack sound if defined + mobkit.make_sound(self,'attack') + phase=4 + end + end + end + mobkit.queue_low(self,func) +end + + + +------------------ +-- HQ behaviors -- +------------------ + + +-- on land only, go to tgt and remove it +function water_life.hq_catch_drop(self,prty,tgt) + + local func = function(self) + + if self.isinliquid then return true end + if not tgt then return true end + if mobkit.is_queue_empty_low(self) then + local pos = mobkit.get_stand_pos(self) + local tpos = tgt:get_pos() + if pos and tpos then + local dist = vector.distance(pos,tpos) + if dist < 2 then + tgt:remove() + return true + else + if pos.y +0.5 >= tpos.y then + water_life.lq_dumbwalk(self,tpos,0.1) + else + water_life.lq_dumbjump(self,1) + end + end + else + return true + end + end + end + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_aquaidle(self,prty,anim) + local init = true + if not anim then anim = 'def' end + + local func = function(self) + if init then + mobkit.animate(self,anim) + self.object:set_velocity({x=0,y=0,z=0}) + init = false + end + + if self.name == "water_life:alligator" then + if random(100) < 5 then + mobkit.animate(self,'roll') + end + end + end + + mobkit.queue_high(self,func,prty) +end + + +-- same as mobkit.hq_aqua_turn but for large mobs +function water_life.big_hq_aqua_turn(self,prty,tyaw,speed) + + local func = function(self) + if not speed then speed = 0.4 end + if speed < 0 then speed = speed * -1 end + + local finished=mobkit.turn2yaw(self,tyaw,speed) + if finished then return true end + end + mobkit.queue_high(self,func,prty) +end + + + +-- same as mobkit.hq_aqua_roam but for large mobs +function water_life.big_aqua_roam(self,prty,speed,anim) + local tyaw = 0 + local init = true + local prvscanpos = {x=0,y=0,z=0} + local center = self.object:get_pos() + if not anim then anim = 'def' end + + local func = function(self) + if init then + mobkit.animate(self,anim) + init = false + end + local pos = mobkit.get_stand_pos(self) + local yaw = self.object:get_yaw() + local scanpos = mobkit.get_node_pos(mobkit.pos_translate2d(pos,yaw,speed)) + if not vector.equals(prvscanpos,scanpos) then + prvscanpos=scanpos + local nyaw,height = water_life.aqua_radar_dumb(pos,yaw,speed,true) + if height and height > pos.y then + local vel = self.object:get_velocity() + vel.y = vel.y+0.1 + self.object:set_velocity(vel) + end + if yaw ~= nyaw then + tyaw=nyaw + mobkit.hq_aqua_turn(self,prty+1,tyaw,speed) + return + end + end + if mobkit.timer(self,10) then + if vector.distance(pos,center) > water_life.abr*16*0.5 then + tyaw = minetest.dir_to_yaw(vector.direction(pos,{x=center.x+random()*10-5,y=center.y,z=center.z+random()*10-5})) + else + if random(10)>=9 then tyaw=tyaw+random()*pi - pi*0.5 end + end + end + + if mobkit.timer(self,20) then mobkit.turn2yaw(self,tyaw,-1) end + --local yaw = self.object:get_yaw() + mobkit.go_forward_horizontal(self,speed) + end + mobkit.queue_high(self,func,prty) +end + + +-- this is the same as mobkit's, but allows movement in shallow water +function water_life.hq_aqua_roam(self,prty,speed,anim) + if not anim then anim = "def" end + local tyaw = 0 + local init = true + local prvscanpos = {x=0,y=0,z=0} + local center = self.object:get_pos() + local func = function(self) + if init then + mobkit.animate(self,anim) + init = false + end + local pos = mobkit.get_stand_pos(self) + local yaw = self.object:get_yaw() + local scanpos = mobkit.get_node_pos(mobkit.pos_translate2d(pos,yaw,speed)) + if not vector.equals(prvscanpos,scanpos) then + prvscanpos=scanpos + local nyaw,height = water_life.aqua_radar_dumb(pos,yaw,speed,true,true) + if height and height > pos.y then + local vel = self.object:get_velocity() + vel.y = vel.y+1 + self.object:set_velocity(vel) + end + if yaw ~= nyaw then + tyaw=nyaw + mobkit.hq_aqua_turn(self,prty+1,tyaw,speed) + return + end + end + if mobkit.timer(self,1) then + if vector.distance(pos,center) > water_life.abr*16*0.5 then + tyaw = minetest.dir_to_yaw(vector.direction(pos,{x=center.x+random()*10-5,y=center.y,z=center.z+random()*10-5})) + else + if random(10)>=9 then tyaw=tyaw+random()*pi - pi*0.5 end + end + end + + mobkit.turn2yaw(self,tyaw,3) +-- local yaw = self.object:get_yaw() + mobkit.go_forward_horizontal(self,speed) + end + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_attack(self,prty,tgtobj) + local func = function(self) + if self.isinliquid then return true end + if not mobkit.is_alive(tgtobj) then return true end + if mobkit.is_queue_empty_low(self) then + local meta = nil + local poison = 0 + local pos = mobkit.get_stand_pos(self) +-- local tpos = tgtobj:get_pos() + local tpos = mobkit.get_stand_pos(tgtobj) + local dist = vector.distance(pos,tpos) + if tgtobj:is_player() then + meta = tgtobj:get_meta() + poison = meta:get_int("snakepoison") + noob = meta:get_int("bitten") + end + + if dist > 3 or poison > 0 or noob > 0 then + return true + else + mobkit.lq_turn2pos(self,tpos) + local height = tgtobj:is_player() and 0.35 or tgtobj:get_luaentity().height*0.6 + if tpos.y+height>pos.y then + mobkit.make_sound(self,"attack") + water_life.lq_jumpattack(self,tpos.y+height-pos.y,tgtobj) + else + mobkit.lq_dumbwalk(self,mobkit.pos_shift(tpos,{x=random()-0.5,z=random()-0.5})) + end + end + end + end + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_hunt(self,prty,tgtobj,lost,anim) + if not lost then lost = self.view_range end + if random(100) < 20 then mobkit.make_sound(self,"attack") end + + + local func = function(self) + if not mobkit.is_alive(tgtobj) then return true end + if self.isinliquid then return true end + if mobkit.is_queue_empty_low(self) and self.isonground then + local pos = mobkit.get_stand_pos(self) + local opos = tgtobj:get_pos() + local dist = vector.distance(pos,opos) + local meta = nil + local poison = 0 + local noob = 0 + + if tgtobj:is_player() then + meta = tgtobj:get_meta() + poison = meta:get_int("snakepoison") + noob = meta:get_int("bitten") + end + + if poison > 0 or noob > 0 then return true end + + if mobkit.is_in_deep(tgtobj) then + return true --water_life.hq_water_attack(self,tgtobj,prty+1,7) + end + if dist > lost or math.abs(pos.y - opos.y) > 5 then + return true + elseif dist > 3 then + water_life.goto_next_waypoint(self,opos) + else + water_life.hq_attack(self,prty+1,tgtobj) + end + end + end + mobkit.queue_high(self,func,prty) +end + +-- slowly roam on land, breaks are taken with max of 120 seconds +function water_life.hq_slow_roam(self,prty,idle) + if not idle then idle = random(30,120) end + + local func=function(self) + if self.isinliquid then return true end + if mobkit.is_queue_empty_low(self) and self.isonground then + local pos = mobkit.get_stand_pos(self) + local neighbor = random(8) + + local height, tpos, liquidflag = mobkit.is_neighbor_node_reachable(self,neighbor) + if height and not liquidflag then mobkit.dumbstep(self,height,tpos,0.1,idle) end + end + end + mobkit.queue_high(self,func,prty) +end + + +--find any water nearby and go into it +function water_life.hq_go2water(self,prty,speed) + local pos = mobkit.get_stand_pos(self) + local target = minetest.find_node_near(pos, self.view_range, {"group:water"}) + --if target then water_life.temp_show(target,10,10) end + if not speed then speed = 0.1 end + + local func=function(self) + --minetest.chat_send_all(dump(vector.distance(pos,target))) + if self.isinliquid or not target then return true end + + if mobkit.is_queue_empty_low(self) and self.isonground then + pos = mobkit.get_stand_pos(self) + local height = target.y - pos.y + water_life.dumbstep(self,height,target,speed,0) + end + end + mobkit.queue_high(self,func,prty) +end + + +-- looks for a landing point on shore under air. tgt is optional +-- and must be an object, so it will start searching yaw2tgt - 15 degrees +function water_life.hq_go2land(self,prty,tgt) + local init = false + local offset = 1 + local target = nil + local start = 1 + if tgt then + local ayaw = water_life.get_yaw_to_object(self,tgt) + if ayaw then start = math.deg(ayaw) -15 end + end + + local func = function(self) + + + local fpos = nil + local pos = mobkit.get_stand_pos(self) + + if not init then + + for i = start,359,15 do + local yaw = rad(i) + target = mobkit.pos_translate2d(pos,yaw,self.view_range) + fpos = water_life.find_collision(pos,target,false) + if fpos then + target = mobkit.pos_translate2d(pos,yaw,fpos+0.5) + local node=minetest.get_node({x=target.x,y=target.y+1,z=target.z}) + + if node.name == "air" then + --water_life.temp_show(target,5,2) + break + else + target = nil + end + else + target = nil + end + end + init = true + end + + if self.isonground then return true end + + if target then + local y=self.object:get_velocity().y + local pos2d = {x=pos.x,y=0,z=pos.z} + local dir=vector.normalize(vector.direction(pos2d,target)) + local yaw = minetest.dir_to_yaw(dir) + + if mobkit.timer(self,1) then + local pos1 = mobkit.pos_shift(mobkit.pos_shift(pos,{x=-dir.z*offset,z=dir.x*offset}),dir) + local h,l = mobkit.get_terrain_height(pos1) + if h and h>pos.y then + mobkit.lq_freejump(self) + else + local pos2 = mobkit.pos_shift(mobkit.pos_shift(pos,{x=dir.z*offset,z=-dir.x*offset}),dir) + local h,l = mobkit.get_terrain_height(pos2) + if h and h>pos.y then + mobkit.lq_freejump(self) + end + end + elseif mobkit.turn2yaw(self,yaw) then + dir.y = y + self.object:set_velocity(dir) + end + else + return true + end + --minetest.chat_send_all("angel= "..dump(yaw).." viewrange= "..dump(self.view_range).." distance= "..dump(vector.distance(pos,opos))) + + + + end + mobkit.queue_high(self,func,prty) +end + +function water_life.hq_snail_move(self,prty) + local ground = mobkit.get_stand_pos(self) + local coraltable = minetest.find_nodes_in_area({x=ground.x-3, y=ground.y-1, z=ground.z-3}, {x=ground.x+3, y=ground.y, z=ground.z+3}, water_life.urchinspawn) + if not coraltable or #coraltable < 1 then return end + local tgpos = coraltable[random(#coraltable)] + + local func = function(self) + if not mobkit.is_alive(self) then return true end + local pos = mobkit.get_stand_pos(self) + local dist = vector.distance(pos,tgpos) + + mobkit.drive_to_pos(self,tgpos,0.01,0.1,1.5) + --minetest.chat_send_all(dump(dist)) + if dist <= 1.8 then return true end + end + + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_idle(self,prty,duration,anim) + anim = anim or 'stand' + local init = true + + local func=function(self) + if init then + mobkit.animate(self,anim) + init=false + end + duration = duration-self.dtime + if duration <= 0 then return true end + end + mobkit.queue_high(self,func,prty) +end + + +-- swim to the next "node" which is inside viewrange or quit -- node can be string or table of string +-- if tgtpos is given node will be ignored +function water_life.hq_swimto(self,prty,speed,node,tgtpos) + + local endpos = tgtpos + local pos = self.object:get_pos() + local r = self.view_range + if not tgtpos then + endpos = minetest.find_node_near(pos, r, node) + end + if not endpos then return true end + + + local func = function(self) + + + local yaw = water_life.get_yaw_to_pos(self,endpos) + if not mobkit.is_alive(self) then return true end + local pos = self.object:get_pos() + + if mobkit.timer(self,1) then + if vector.distance(pos,endpos) > 1 then + + --minetest.chat_send_all(vector.distance(pos,endpos)) + if endpos.y > pos.y then + local vel = self.object:get_velocity() + vel.y = vel.y+0.4 + self.object:set_velocity(vel) + end + if endpos.y < pos.y then + local vel = self.object:get_velocity() + vel.y = vel.y-0.1 + self.object:set_velocity(vel) + end + mobkit.hq_aqua_turn(self,prty+5,yaw,speed) + pos = self.object:get_pos() --mobkit.get_stand_pos(self) + yaw = water_life.get_yaw_to_pos(self,endpos) + + else + return true + end + end + +end + mobkit.queue_high(self,func,prty) + +end + + + +-- turn around 180degrees from tgtob and swim away until out of sight +function water_life.hq_swimfrom(self,prty,tgtobj,speed,outofsight) + local init = true + + local func = function(self) + if not outofsight then outofsight = self.view_range * 1.5 end + if not mobkit.is_alive(tgtobj) then return true end + + + local pos = mobkit.get_stand_pos(self) + local opos = tgtobj:get_pos() + local yaw = water_life.get_yaw_to_object(self,tgtobj) + math.rad(random(-30,30))+math.rad(180) + local distance = vector.distance(pos,opos) + if self.isonground then return true end + + if init then + + mobkit.animate(self,"swim") + init=false + + end + + if distance < outofsight then + + local swimto, height = water_life.aqua_radar_dumb(pos,yaw,3) + if height and height > pos.y then + local vel = self.object:get_velocity() + vel.y = vel.y+0.1 + self.object:set_velocity(vel) + end + mobkit.hq_aqua_turn(self,51,swimto,speed) + + else + return true + end + + --minetest.chat_send_all("angel= "..dump(yaw).." viewrange= "..dump(self.view_range).." distance= "..dump(vector.distance(pos,opos))) + + + + end + mobkit.queue_high(self,func,prty) +end + + + + +function water_life.hq_water_attack(self,tgtobj,prty,speed,shallow) + + local pos = self.object:get_pos() + local selfbox = self.object:get_properties().collisionbox + local tgtbox = tgtobj:get_properties().collisionbox + if not speed then speed = 1 end + + local func = function(self) + + if not mobkit.is_alive(self) or not mobkit.is_alive(tgtobj) or tgtobj:get_attach() ~= nil then return true end + local pos = self.object:get_pos() + local endpos = tgtobj:get_pos() + if not shallow then + if not mobkit.is_in_deep(tgtobj) and vector.distance (pos,endpos) > 2 then return true end + else + if not water_life.isinliquid(tgtobj) and vector.distance (pos,endpos) > 2 then return true end + end + local yaw = water_life.get_yaw_to_pos(self,endpos) + local entity = nil + if not tgtobj:is_player() then entity = tgtobj:get_luaentity() end + + + if vector.distance(pos,endpos) > selfbox[5]+tgtbox[5] then + --minetest.chat_send_all(dump(vector.distance(pos,endpos)).." "..dump(selfbox[5]+tgtbox[5])) + if endpos.y > pos.y+selfbox[5] then + local vel = vector.add(self.object:get_velocity(),{x=0,y=0.5,z=0}) + self.object:set_velocity(vel) + end + if endpos.y < pos.y-selfbox[5] then + local vel = vector.add(self.object:get_velocity(),{x=0,y=-0.5,z=0}) + self.object:set_velocity(vel) + end + + mobkit.hq_aqua_turn(self,prty+5,yaw,speed) + + + else + if mobkit.is_alive(tgtobj) then + + --minetest.chat_send_all("<<>>") + tgtobj:punch(self.object,1,self.attack) + return true + + + else + return true + end + end + if entity and string.match(entity.name,"petz") and vector.distance(pos,endpos) < 2 then + if mobkit.is_alive(tgtobj) then + --minetest.chat_send_all("<<>>") + mobkit.hurt(entity,self.attack.damage_groups.fleshy or 4) + + else + return true + end + end + +end + mobkit.queue_high(self,func,prty) + +end + + +-- hq flying behaviors + +function water_life.hq_climb(self,prty,fmin,fmax) + if not max then max = 30 end + if not min then min = 20 end + + local func=function(self) + if mobkit.timer(self,1) then + local remember = mobkit.recall(self,"time") + if remember then + if self.time_total - remember > 15 then + mobkit.forget(self,"turn") + mobkit.forget(self,"time") + + end + end + self.action = "fly" + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + + --local tim = minetest.get_us_time() + local left, right, up, down, under, above = water_life.radar(pos,yaw,32,true) + --minetest.chat_send_all(minetest.get_us_time()-tim) + + if (down < 3) and (under >= fmax) then + water_life.hq_glide(self,prty,fmin,fmax) + return true + end + if left > 3 or right > 3 then + local lift = 0.6 + local pitch = 8 + local roll = 6 + local acc = 1.2 + --roll = (max(left,right)/30 *3)+(down/100)*3+roll + roll = (max(left,right)/30 * 7.5) + lift = lift + (down - up) /400 + pitch = pitch + (down - up) /30 + --lift = lift + (down/100) - (up/100) + local turn = chose_turn(self,left,right) + if turn then + mobkit.clear_queue_low(self) + water_life.lq_fly_pitch(self,lift,pitch,roll*-1,acc,'fly') + else + mobkit.clear_queue_low(self) + water_life.lq_fly_pitch(self,lift,pitch,roll,acc,'fly') + end + end + end + if mobkit.timer(self,15) then mobkit.clear_queue_low(self) end + if mobkit.is_queue_empty_low(self) then water_life.lq_fly_pitch(self,0.6,8,(random(2)-1.5)*30,1.2,'fly') end + end + mobkit.queue_high(self,func,prty) +end + +function water_life.hq_glide(self,prty,fmin,fmax) + if not max then fmax = 30 end + if not min then fmin = 20 end + + local func = function(self) + if mobkit.timer(self,1) then + self.action = "glide" + local remember = mobkit.recall(self,"time") + if remember then + if self.time_total - remember > 15 then + mobkit.forget(self,"turn") + mobkit.forget(self,"time") + + end + end + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + local left, right, up, down, under, above = water_life.radar(pos,yaw,32,true) + if (down > 10) or (under < fmin) then + water_life.hq_climb(self,prty,fmin,fmax) + return true + end + if left > 3 or right > 3 then + local lift = 0.6 + local pitch = 8 + local roll = 0 + local acc = 1.2 + --roll = (max(left,right)/30 *3)+(down/100)*3+roll + roll = (max(left,right)/30 *7.5) + local turn = chose_turn(self,left,right) + if turn then + mobkit.clear_queue_low(self) + water_life.lq_fly_pitch(self,lift,pitch,roll*-1,acc,'glide') + else + mobkit.clear_queue_low(self) + water_life.lq_fly_pitch(self,lift,pitch,roll,acc,'glide') + end + end + end + if mobkit.timer(self,20) then mobkit.clear_queue_low(self) end + if mobkit.is_queue_empty_low(self) then water_life.lq_fly_pitch(self,0.6,-4,(random(2)-1.5)*30,0,'glide') end + end + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_water_takeoff(self,prty,anim,tyaw) + local init = true + local startup = true + local turned = false + local timer = 0 + if not anim then anim = 'def' end + local pos2 = {} + + + local func=function(self) + + local yaw = self.object:get_yaw() + local pos = self.object:get_pos() + + if startup then + if tyaw then yaw = tyaw end + --water_life.temp_show(pos,5,1) + for i = 0,330,30 do + pos2 = mobkit.pos_translate2d(pos,yaw+rad(i),self.view_range*2) + + if not water_life.find_collision(pos,pos2,false) then + tyaw = yaw + rad(i) + --water_life.temp_show(pos2,5,10) + break + end + end + startup = false + end + + if not startup then + if not tyaw then return true end + if mobkit.turn2yaw(self,tyaw,5) then turned = true end + end + + if turned then + if init then + self.object:set_velocity({x=0, y=0.5, z=0}) + minetest.after(2,function() + mobkit.animate(self,anim) + end) + init = false + end + + + minetest.after(4,function() + mobkit.animate(self,'fly') + end) + + if timer > 3 then + self.object:add_velocity({x=0,y=0.25,z=0}) + end + + mobkit.go_forward_horizontal(self,3) + timer = timer + self.dtime + + if timer > 8 then + local vec = vector.multiply(minetest.yaw_to_dir(tyaw),2) + vec.y = vec.y + 4 + self.object:add_velocity(vec) + mobkit.remember(self,"airlife",os.time()) + mobkit.forget(self,"landlife") + mobkit.forget(self,"waterlife") + return true + end + end + end + + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_fly2obj(self,prty,tgt,break_dist,force) + + local func=function(self) + if not break_dist then break_dist = 5 end + if not tgt then + mobkit.clear_queue_high(self) + water_life.hq_climb(self,prty) + return true + end + + local wname = "" + local roll = 0 + local pos = self.object:get_pos() + local yaw = self.object:get_yaw() + local tgtpos = tgt:get_pos() + local tgtyaw = tgt:get_yaw() --water_life.get_yaw_to_object(self,tgt) + local tgtspeed = math.floor(vector.length(tgt:get_velocity() or {x=0,y=0,z=0})) + if not tgt:is_player() and tgt:get_luaentity() and tgt:get_luaentity().name == "water_life:whale" then tgtyaw = tgtyaw + rad(180) end -- whales moving backwards XD + + if tgt:is_player() then + tgtyaw = tgt:get_look_horizontal() + local stack = tgt:get_wielded_item() + wname = stack:get_name() + end + + if tgtpos.y < 0 then tgtpos.y = 1 end + + + + if not water_life.gull_bait[wname] and not force then + mobkit.clear_queue_high(self) + mobkit.clear_queue_low(self) + water_life.hq_climb(self,15,4,16) + return true + end + --minetest.chat_send_all(dump(tgtpos).." "..dump(tgtyaw).." "..dump(tgtspeed)) + if not tgtyaw or not tgtspeed or not mobkit.is_alive(tgt) or self.isonground or self.isinliquid then + mobkit.clear_queue_high(self) + water_life.hq_climb(self,prty) + return true + end + local turn = 0 + local diff = 0 + local lift = 1.2 + local pitch = 5 + local acc = 0.6 + local anim = "fly" + local truetpos=mobkit.pos_translate2d(tgtpos,tgtyaw,tgtspeed*3) + local ddistance = vector.distance(pos,{x=truetpos.x,y= pos.y, z=truetpos.z}) + local alpha = atan((pos.y - truetpos.y)/ ddistance) + local truetyaw = water_life.get_yaw_to_pos(self,truetpos) + local realdistance = vector.distance(pos,tgtpos) + local ang2tgt = mobkit.pos_translate2d(pos,truetyaw,15) + + --chose right or left turn + if yaw < truetyaw then + turn = -1 + elseif yaw > truetyaw then + turn = 1 + end + + diff = abs(truetyaw - yaw) + + -- or chose straight ahead + if ddistance > 30 and diff <= 0.5 then + turn = 0 + end + if ddistance > 20 and diff <= 0.3 then + turn = 0 + end + if diff <= 0.1 then + turn = 0 + end + --minetest.chat_send_all(">>> "..dump(math.floor(diff*100)/100).." <<<") + --minetest.chat_send_all("distance ="..dump(math.floor(ddistance*100)/100).." yawdiff ="..dump(math.floor((truetyaw-yaw)*100)/100)) + + if ddistance > 32 then + roll = 15 * turn + elseif ddistance > 22 then + roll = 10 * turn + elseif ddistance > 12 then + roll = 5 * turn + elseif ddistance <= 12 then + roll = 2 * turn + end + + --water_life.temp_show(truetpos,1,3) + --minetest.chat_send_all(dump(minetest.pos_to_string(truetpos,2)).." -- "..dump(minetest.pos_to_string(pos,2))) + + if pos.y > truetpos.y + 1 and pos.y > 2 and ddistance < 25 then + anim = "glide" + pitch = -10 + elseif pos.y < truetpos.y - 1 then + pitch = 15 + else + pitch = 5 + end + + + --tim = minetest.get_us_time() + local left,right,center,up,down = water_life.radar_fast(self,20) + --minetest.chat_send_all(minetest.get_us_time()-tim) + + if down and down < 16 then pitch = 15 end + if up and not down and not center then pitch = -10 end + if right and not center then roll = 10 end + if left and not center then roll = -10 end + if left and right and not center then roll = 0 end + if center and down and center < 5 then + mobkit.clear_queue_high(self) + mobkit.clear_queue_low(self) + water_life.hq_climb(self,15,4,16) + return true + end + + if water_life.radar_debug then + water_life.temp_show(ang2tgt,1) + for i = 1,10,1 do + water_life.temp_show({x=truetpos.x, y=truetpos.y+i*2, z=truetpos.z},1) + end + --minetest.chat_send_all("Alpha= "..dump(alpha)..", Hight= "..dump(math.floor(pos.y)).." ###"..dump(yaw).."### hityaw="..dump(truetyaw)) + --minetest.chat_send_all("distance ="..dump(math.floor(ddistance*100)/100).." Alpha ="..dump(math.floor(deg(alpha)*100)/100)) + --minetest.chat_send_all("distance2prey ="..dump(vector.distance(pos,tgtpos))) + end + + mobkit.clear_queue_low(self) + + + if realdistance < break_dist+0.5 then -- steal bait from players + -- minetest.chat_send_all(">>> "..dump(math.floor(ddistance*100)/100).."<<< ###"..dump(math.floor(realdistance*100)/100).." ###") + if tgt:is_player() then + local bstack = tgt:get_wielded_item() + local bait = bstack:get_name() + if water_life.gull_bait[bait] then + bstack:take_item(1) + tgt:set_wielded_item(bstack) + end + end + mobkit.clear_queue_high(self) + mobkit.clear_queue_low(self) + water_life.hq_climb(self,15,4,16) + return true + + else + water_life.lq_fly_pitch(self,lift,pitch,roll,acc,anim) + end + + + + end + mobkit.queue_high(self,func,prty) +end + +--snakes +function water_life.hq_snake_warn(self,target,prty,duration,anim) + anim = anim or 'warn' + local init = true + + local func=function(self) + if init then + mobkit.make_sound(self,"warn") + minetest.after(1,function(anim) + mobkit.animate(self,anim) + end,anim) + init=false + end + local yaw = water_life.get_yaw_to_object(self,target) + self.object:set_yaw(yaw) + duration = duration-self.dtime + local dist = water_life.dist2tgt(self,target) + if dist > self.view_range then + minetest.after(3,function() + return true + end) + end + if duration <= 0 or dist < 4 then + mobkit.remember(self,"warned",target:get_player_name()) + return true + end + end + mobkit.queue_high(self,func,prty) +end + + + +function water_life.hq_snake_move(self,prty,anim) + anim = anim or 'look' + local init = true + local getpos = nil + + local func=function(self) + local getpos = nil + local pos = mobkit.get_stand_pos(self) --self.object:get_pos() + local yaw = 0 + + if init then + mobkit.animate(self,anim) + init=false + yaw = rad(random(360)) + pos = mobkit.pos_translate2d(pos,yaw,self.view_range+5) + getpos = water_life.find_node_under_air(pos,self.view_range) + --water_life.temp_show(getpos,5,5) + + end + + + if getpos then + + water_life.hq_idle(self,prty+2,5,anim) + water_life.hq_findpath(self,prty+1,getpos, 1.5,0.1,true) + return true + + + else + return true + + + end + + + end + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_snakerun(self,prty,tgtobj) + local init=true + local timer=6 + local func = function(self) + + if not mobkit.is_alive(tgtobj) then return true end + if self.isinliquid then return true end + + if init then + timer = timer-self.dtime + if timer <=0 or vector.distance(self.object:get_pos(),tgtobj:get_pos()) < 8 then + mobkit.make_sound(self,'scared') + init=false + end + return + end + + if mobkit.is_queue_empty_low(self) and self.isonground then + local pos = mobkit.get_stand_pos(self) + local opos = tgtobj:get_pos() + if vector.distance(pos,opos) < (self.view_range*3) then + --minetest.chat_send_all(dump(vector.distance(pos,opos)).." "..dump(self.view_range*3)) + local tpos = {x=2*pos.x - opos.x, + y=opos.y, + z=2*pos.z - opos.z} + water_life.goto_next_waypoint(self,tpos) + else + mobkit.clear_queue_low(self) + mobkit.clear_queue_high(self) + --water_life.hq_idle(self,10,random(60,120),"sleep") + water_life.hq_snake_move(self,15) + return true + end + end + end + mobkit.queue_high(self,func,prty) +end + + +function water_life.hq_runfrom(self,prty,tgtobj) + local init=true + local timer=6 + local func = function(self) + + if self.isinliquid then return true end + if not mobkit.is_alive(tgtobj) then return true end + --[[if init then + timer = timer-self.dtime + if timer <=0 or vector.distance(self.object:get_pos(),tgtobj:get_pos()) < 8 then + mobkit.make_sound(self,'scared') + init=false + end + return + end]] + + if mobkit.is_queue_empty_low(self) and self.isonground then + local pos = mobkit.get_stand_pos(self) + local opos = tgtobj:get_pos() + if vector.distance(pos,opos) < self.view_range*1.1 then + local tpos = {x=2*pos.x - opos.x, + y=opos.y, + z=2*pos.z - opos.z} + mobkit.goto_next_waypoint(self,tpos) + else + self.object:set_velocity({x=0,y=0,z=0}) + return true + end + end + end + mobkit.queue_high(self,func,prty) +end + + +-- dying +function water_life.hq_die(self,anim) + local timer = 5 + local start = true + local func = function(self) + if start then + + if not anim then + mobkit.lq_fallover(self) + else + mobkit.animate(self,anim) + end + self.logic = function(self) end -- brain dead as well + start=false + end + timer = timer-self.dtime + if timer < 0 then self.object:remove() end + end + mobkit.queue_high(self,func,100) +end diff --git a/my_changes/mobs/mobs_mobkit/water_life/files/crafts.lua b/my_changes/mobs/mobs_mobkit/water_life/files/crafts.lua new file mode 100644 index 0000000..5e5bf71 --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/files/crafts.lua @@ -0,0 +1,558 @@ +local random = water_life.random + + + +if not water_life.petz and not water_life.mobsredo then +-- lasso + + minetest.register_tool("water_life:lasso", { + description = ("Lasso (right-click animal to capture it)"), + inventory_image = "water_life_lasso.png", + groups = {flammable = 2} + }) + + if minetest.get_modpath("farming") then + minetest.register_craft({ + output = "water_life:lasso", + recipe = { + {"farming:string", "", "farming:string"}, + {"", "default:diamond", ""}, + {"farming:string", "", "farming:string"} + } + }) + end + + +end + + +-- only one kind of meat if mobs_redo is present +if not water_life.mobsredo then + + -- raw meat + minetest.register_craftitem("water_life:meat_raw", { + description = ("Raw Meat"), + inventory_image = "water_life_meat_raw.png", + on_use = minetest.item_eat(3), + groups = {food_meat_raw = 1, flammable = 2} + }) + + -- cooked meat + minetest.register_craftitem("water_life:meat", { + description = ("Meat"), + inventory_image = "water_life_meat.png", + on_use = minetest.item_eat(8), + groups = {food_meat = 1, flammable = 2} + }) + + minetest.register_craft({ + type = "cooking", + output = "water_life:meat", + recipe = "water_life:meat_raw", + cooktime = 5 + }) + + minetest.register_alias("mobs:meat_raw","water_life:meat_raw") + minetest.register_alias("mobs:meat","water_life:meat") + +else + minetest.register_alias("water_life:meat_raw","mobs:meat_raw") + minetest.register_alias("water_life:meat","mobs:meat") + +end + +-- revive corals if a living one is around +minetest.register_abm({ + nodenames = {"default:coral_skeleton","water_life:artificial_skeleton"}, + neighbors = {"default:water_source"}, + interval = 30, --30 + chance = 5, --10 + catch_up = false, + action = function(pos, node) + local table = minetest.find_nodes_in_area({x=pos.x-2, y=pos.y-2, z=pos.z-2}, {x=pos.x+2, y=pos.y+2, z=pos.z+2}, water_life.urchinspawn) + local nname = "default:coral_skeleton" + if table and #table > 0 then nname = minetest.get_node(table[water_life.random(#table)]).name end + minetest.set_node(pos, {name = nname}) + end, +}) + + +minetest.register_node("water_life:artificial_skeleton", { + description = "artificial coral skeleton", + tiles = {"default_coral_skeleton.png"}, + groups = {cracky = 3}, + sounds = default.node_sound_stone_defaults(), +}) + +minetest.register_craft({ + + output = "water_life:artificial_skeleton 4", + type = "shapeless", + recipe = {"default:silver_sandstone","default:silver_sandstone","default:silver_sandstone","default:coral_skeleton"} + }) + + +-- moskito repellant + if water_life.farming and farming.mod == "redo" then + minetest.register_craft({ + output = "water_life:repellant", + recipe = { + {"", "farming:mint_leaf", "farming:bottle_ethanol"}, + {"farming:garlic", "farming:chili_pepper", "farming:onion"}, + {"", "farming:mortar_pestle", ""}}, + replacements = {{"group:food_mortar_pestle", "farming:mortar_pestle"}} + }) + else + minetest.register_craft({ + output = "water_life:repellant", + recipe = { + {"", "farming:cotton", ""}, + {"flowers:tulip_black", "flowers:mushroom_red", "flowers:geranium"}, + {"", "vessels:glass_bottle", ""}} + }) + end + +if not water_life.apionly then + + minetest.register_craftitem("water_life:riverfish", { + description = ("Riverfish"), + inventory_image = "water_life_riverfish_item.png", + wield_scale = {x = 0.5, y = 0.5, z = 0.5}, + stack_max = 10, + liquids_pointable = false, + range = 10, + on_use = minetest.item_eat(3), + groups = {food_meat = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + if placer and not placer:is_player() then return itemstack end + if not pointed_thing then return itemstack end + if not pointed_thing.type == "node" then return itemstack end + + local pos = pointed_thing.above + local number = water_life.count_objects(pos) + if number.all > water_life.maxmobs or number.fish > 10 then return itemstack end + + local name = placer:get_player_name() + if minetest.is_protected(pos,name) then return itemstack end + + local obj = minetest.add_entity(pos, "water_life:fish_tamed") + obj = obj:get_luaentity() + itemstack:take_item() + obj.owner = name + return itemstack + end, + }) + + minetest.register_craftitem("water_life:piranha", { + description = ("Piranha"), + inventory_image = "water_life_piranha_item.png", + wield_scale = {x = 0.5, y = 0.5, z = 0.5}, + stack_max = 10, + liquids_pointable = false, + range = 10, + on_use = minetest.item_eat(5), + groups = {food_meat = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + if placer and not placer:is_player() then return itemstack end + if not pointed_thing then return itemstack end + if not pointed_thing.type == "node" then return itemstack end + + local pos = pointed_thing.above + local number = water_life.count_objects(pos,nil,"water_life:piranha") + if number.all > water_life.maxmobs or number.name > 10 then return itemstack end + + local name = placer:get_player_name() + if minetest.is_protected(pos,name) then return itemstack end + + local obj = minetest.add_entity(pos, "water_life:piranha_tamed") + obj = obj:get_luaentity() + itemstack:take_item() + --obj.owner = name + return itemstack + end, + }) + + minetest.register_craftitem("water_life:coralfish", { + description = ("Coralfish"), + inventory_image = "water_life_coralfish_item.png", + wield_scale = {x = 0.5, y = 0.5, z = 0.5}, + stack_max = 10, + liquids_pointable = false, + range = 10, + on_use = minetest.item_eat(1), + groups = {food_meat = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + if placer and not placer:is_player() then return itemstack end + if not pointed_thing then return itemstack end + if not pointed_thing.type == "node" then return itemstack end + + local pos = pointed_thing.above + local number = water_life.count_objects(pos,nil,"water_life:coralfish_tamed") + if number.all > water_life.maxmobs or number.name > 10 then return itemstack end + + local name = placer:get_player_name() + if minetest.is_protected(pos,name) then return itemstack end + + local obj = minetest.add_entity(pos, "water_life:coralfish_tamed") + if obj then + local entity = obj:get_luaentity() + entity.base = nil + entity.owner = name + entity.head = random(65535) + end + itemstack:take_item() + + return itemstack + end, + }) + + minetest.register_craftitem("water_life:clownfish", { + description = ("Clownfish"), + inventory_image = "water_life_clownfish_item.png", + wield_scale = {x = 0.5, y = 0.5, z = 0.5}, + stack_max = 10, + liquids_pointable = false, + range = 10, + on_use = minetest.item_eat(1), + groups = {food_meat = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + if placer and not placer:is_player() then return itemstack end + if not pointed_thing then return itemstack end + if not pointed_thing.type == "node" then return itemstack end + + local pos = pointed_thing.above + local number = water_life.count_objects(pos,nil,"water_life:clownfish_tamed") + if number.all > water_life.maxmobs or number.name > 10 then return itemstack end + + local name = placer:get_player_name() + if minetest.is_protected(pos,name) then return itemstack end + + local obj = minetest.add_entity(pos, "water_life:clownfish_tamed") + obj = obj:get_luaentity() + itemstack:take_item() + obj.owner = name + return itemstack + end, + }) + + minetest.register_craftitem("water_life:urchin_item", { + description = ("Sea urchin"), + inventory_image = "water_life_urchin_item.png", + wield_scale = {x = 0.4, y = 0.4, z = 0.4}, + stack_max = 10, + liquids_pointable = false, + range = 10, + on_use = minetest.item_eat(2), + groups = {food_meat = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + if placer and not placer:is_player() then return itemstack end + if not pointed_thing then return itemstack end + if not pointed_thing.type == "node" then return itemstack end + + local pos = pointed_thing.above + local number = water_life.count_objects(pos,10,"water_life:urchin") + if number.all > water_life.maxmobs or number.name > 10 then return itemstack end + + local name = placer:get_player_name() + if minetest.is_protected(pos,name) then return itemstack end + + local obj = water_life.set_urchin(pos) + obj = obj:get_luaentity() + itemstack:take_item() + --obj.owner = name + return itemstack + end, + }) + + + + + minetest.register_craftitem("water_life:jellyfish_item", { + description = ("Jellyfish"), + inventory_image = "water_life_jellyfish_item.png", + wield_scale = {x = 0.4, y = 0.4, z = 0.4}, + stack_max = 10, + liquids_pointable = false, + range = 10, + on_use = minetest.item_eat(1), + groups = {food_meat = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + if placer and not placer:is_player() then return itemstack end + if not pointed_thing then return itemstack end + if not pointed_thing.type == "node" then return itemstack end + + local pos = pointed_thing.above + local number = water_life.count_objects(pos,10,"water_life:jellyfish") + if number.all > water_life.maxmobs or number.name > 10 then return itemstack end + + local name = placer:get_player_name() + if minetest.is_protected(pos,name) then return itemstack end + + local obj = minetest.add_entity(pos, "water_life:jellyfish") + + if obj then itemstack:take_item() end + + return itemstack + end, + }) + + + + + minetest.register_craftitem("water_life:snake_item", { + description = ("Rattlesnake"), + inventory_image = "water_life_snake_item.png", + wield_scale = {x = 0.4, y = 0.4, z = 0.4}, + stack_max = 10, + liquids_pointable = false, + range = 10, + on_use = minetest.item_eat(5), + groups = {food_meat = 1, flammable = 2}, + on_place = function(itemstack, placer, pointed_thing) + if placer and not placer:is_player() then return itemstack end + if not pointed_thing then return itemstack end + if not pointed_thing.type == "node" then return itemstack end + + local pos = pointed_thing.above + local number = water_life.count_objects(pos,water_life.abr * 16,"water_life:snake") + if number.all > water_life.maxmobs or number.name > 5 then return itemstack end + + local name = placer:get_player_name() + if minetest.is_protected(pos,name) then return itemstack end + + local obj = minetest.add_entity(pos, "water_life:snake") + + if obj then itemstack:take_item() end + + return itemstack + end, + }) + + minetest.register_craftitem("water_life:antiserum", { + description = ("Antiserum, cures snake bites"), + inventory_image = "water_life_antiserum.png", + wield_scale = {x = 0.4, y = 0.4, z = 0.4}, + liquids_pointable = false, + on_use = function(itemstack, user, pointed_thing) + if not user or not user:is_player() then return itemstack end + + local name = user:get_player_name() + local meta = user:get_meta() + local score = user:get_hp() + + if meta:get_int("snakepoison") > 0 then meta:set_int("snakepoison",0) hunger_ng.set_effect(user:get_player_name(), "heal", "enabled") end + user:set_hp(score+10) + itemstack:take_item() + water_life.change_hud(user,"poison",0) + return itemstack + end, + + groups = {vessel = 1}, + }) + + + minetest.register_craftitem("water_life:repellant", { + description = ("No moskitos for half a day"), + inventory_image = "water_life_repell.png", + wield_scale = {x = 0.4, y = 0.4, z = 0.4}, + liquids_pointable = false, + on_use = function(itemstack, user, pointed_thing) + if not user or not user:is_player() then return itemstack end + + local name = user:get_player_name() + local meta = user:get_meta() + + meta:set_int("repellant",math.floor(os.time())) + itemstack:take_item() + + water_life.change_hud(user,"repellant") + return itemstack + end, + + groups = {vessel = 1}, + }) + + minetest.register_craft({ + type = "shapeless", + output = "water_life:antiserum", + recipe = {"water_life:snake_item","water_life:snake_item","water_life:snake_item"}, + }) + + minetest.register_craftitem("water_life:beaver_fur", { + description = ("Beaver fur"), + inventory_image = "water_life_beaverfur.png", + groups = {flammable = 2, fur = 1} + }) +end + + +--muddy water + +if water_life.muddy_water then + + minetest.register_node("water_life:muddy_river_water_source", { + description = "Muddy river water source", + drawtype = "liquid", + waving = 3, + tiles = { + { + name="water_life_muddy_river_water_flowing.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + }, + }, + special_tiles = { + { + name="water_life_muddy_river_water_flowing.png", + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 2.0, + }, + backface_culling = false, + }, + }, + alpha = 224, + paramtype = "light", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "water_life:muddy_river_water_flowing", + liquid_alternative_source = "water_life:muddy_river_water_source", + liquid_viscosity = 1, + liquid_renewable = true, + liquid_range = 3, + post_effect_color = {a = 232, r = 92, g = 80, b = 48}, + groups = {water = 3, liquid = 3, puts_out_fire = 1}, + }) + + minetest.register_node("water_life:muddy_river_water_flowing", { + description = "Flowing muddy river water", + drawtype = "flowingliquid", + waving = 3, + tiles = {"water_life_muddy_river_water_source.png"}, + special_tiles = { + { + image="water_life_muddy_river_water_flowing.png", + backface_culling = false, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.8, + }, + }, + { + image="water_life_muddy_river_water_flowing.png", + backface_culling = true, + animation = { + type = "vertical_frames", + aspect_w = 16, + aspect_h = 16, + length = 0.8, + }, + }, + }, + alpha = 224, + paramtype = "light", + paramtype2 = "flowingliquid", + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + is_ground_content = false, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "water_life:muddy_river_water_flowing", + liquid_alternative_source = "water_life:muddy_river_water_source", + liquid_viscosity = 1, + liquid_renewable = true, + liquid_range = 3, + post_effect_color = {a = 232, r = 92, g = 80, b = 48}, + groups = {water = 3, liquid = 3, puts_out_fire = 1, + not_in_creative_inventory = 1}, + }) + + if minetest.get_modpath("bucket") then + bucket.register_liquid( + "water_life:muddy_river_water_source", + "water_life:muddy_river_water_flowing", + "water_life:bucket_muddy_river_water", + "water_life_bucket_muddy_water.png", + "Muddy Water Bucket", + {water_bucket = 1} + ) + end +end + + + +-- make corals to dye +if minetest.get_modpath("dye") then + + minetest.register_craft({ + type = "shapeless", + output = "dye:green", + recipe = {"default:coral_green"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = "dye:cyan", + recipe = {"default:coral_cyan"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = "dye:pink", + recipe = {"default:coral_pink"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = "dye:magenta", + recipe = {"water_life:coralmagenta"}, + }) + + minetest.register_craft({ + type = "shapeless", + output = "dye:blue", + recipe = {"water_life:coralskyblue"}, + }) + end + +if minetest.get_modpath("unified_inventory") then + minetest.register_craft({ + output = "water_life:croc_bag", + recipe = { + {"farming:string", "water_life:crocleather", "farming:string"}, + {"water_life:crocleather", "water_life:crocleather", "water_life:crocleather"}, + {"farming:string", "water_life:crocleather", "farming:string"} + } + }) + + minetest.register_tool("water_life:croc_bag", { + description = ("CrocBag"), + inventory_image = "water_life_crocbag.png", + groups = {bagslots=24}, + }) +end + +minetest.register_craftitem("water_life:crocleather", { + description = ("Crockleather"), + inventory_image = "water_life_crocleather.png", + wield_scale = {x = 0.5, y = 0.5, z = 0.5}, + liquids_pointable = false, + groups = {leather = 1, flammable = 2}, + }) diff --git a/my_changes/mobs/mobs_mobkit/water_life/files/hud.lua b/my_changes/mobs/mobs_mobkit/water_life/files/hud.lua new file mode 100644 index 0000000..1b205ba --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/files/hud.lua @@ -0,0 +1,82 @@ + +water_life.playerhud = {} +water_life.playerhud.poison = {} +water_life.playerhud.repellant = {} + + + +water_life.hud_poison = { + + hud_elem_type = "image", + + position = {x=0.5, y=0.8}, + -- Left corner position of element + + name = "water_life_poison", + + scale = {x = 0.1, y = 0.1}, + + text = "water_life_emptyhud.png", + + +} + + + +water_life.hud_repellant = { + hud_elem_type = "image", + + position = {x=0.55, y=0.8}, + -- Left corner position of element + + name = "water_life_repellant", + + scale = {x = 0.1, y = 0.1}, + + text = "water_life_emptyhud.png", +} + + +function water_life.change_hud(player,selection,switch) + local value = "" + if not player then return end + if not selection then selection = "poison" end + if not switch then switch = 1 end + + + local name = player:get_player_name() + + if selection == "poison" then + if switch == 1 then value = "water_life_poison.png" else value = "water_life_emptyhud.png" end + player:hud_change(water_life.playerhud.poison[name], "text", value) + end + + if selection == "repellant" then + if switch == 1 then value = "water_life_repellanthud.png" else value = "water_life_emptyhud.png" end + player:hud_change(water_life.playerhud.repellant[name], "text", value) + end + +end + + + +minetest.register_on_joinplayer(function(player) + if not player then return end + + local meta=player:get_meta() + meta:set_int("repellant",0) + local name = player:get_player_name() + + water_life.playerhud.poison[name] = player:hud_add(water_life.hud_poison) + water_life.playerhud.repellant[name] = player:hud_add(water_life.hud_repellant) + + if meta:get_int("snakepoison") > 0 then + hunger_ng.set_effect(player:get_player_name(), "heal", "disabled") + minetest.after(5, function(player) + water_life.change_hud(player,"poison") + end, player) + end + +end) + + diff --git a/mods/mobs/mobs_mobkit/water_life/init.lua.orig b/my_changes/mobs/mobs_mobkit/water_life/files/init.lua similarity index 99% rename from mods/mobs/mobs_mobkit/water_life/init.lua.orig rename to my_changes/mobs/mobs_mobkit/water_life/files/init.lua index 2dc625e..8b5a455 100644 --- a/mods/mobs/mobs_mobkit/water_life/init.lua.orig +++ b/my_changes/mobs/mobs_mobkit/water_life/files/init.lua @@ -6,7 +6,7 @@ ----------------------------------------------------------- water_life = {} -water_life.version = "210207" +water_life.version = "020201" water_life.shark_food = {} water_life.repellant = {} water_life.gull_bait = {} @@ -43,9 +43,7 @@ water_life.bloody = minetest.settings:get_bool("water_life_bloody") or true local path = minetest.get_modpath(minetest.get_current_modname()) - dofile(path.."/api.lua") -- load water_life api -dofile(path.."/compat.lua") dofile(path.."/paths.lua") -- load pathfinding if water_life.muddy_water then dofile(path.."/mapgen.lua") end -- load muddy_water dofile(path.."/crafts.lua") -- load crafts diff --git a/my_changes/mobs/mobs_mobkit/water_life/files/settingtypes.txt b/my_changes/mobs/mobs_mobkit/water_life/files/settingtypes.txt new file mode 100644 index 0000000..a28a034 --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/files/settingtypes.txt @@ -0,0 +1,81 @@ + +# +# Turn this Value to true, if you want poison to persist after death +water_life_poison_after_death (Poison stays after death) bool false + +# all settings for client menu or in minetest.conf on servers + +# - +# I am a baby, please turn off the dangerous wild animals +water_life_dangerous (turn off agressive animals) bool false + +# - +# Sound volume adjustment +# 0.9 means 90% of original sound volume +# 1.1 means 110% of original sound volume +# every step of 0.1 adds/reduces 10% +water_life_soundadjust (volume adjustment) float 1.0 + +# - +# controls spawn chance of whales 10 promille = 1 % +water_life_whale_spawn_rate (Whales spawn chance in promille) int 100 + +# - +# controls spawn chance of sharks 10 promille = 1 % +water_life_shark_spawn_rate (Shark spawn chance in promille) int 100 + +# - +# controls spawn chance of Riverfish 10 promille = 1 % +water_life_fish_spawn_rate (Riverfish spawn chance in promille) int 1000 + +# - +# controls spawn chance of sea urchins 10 promille = 1 % +water_life_urchin_spawn_rate (Sea urchin spawn chance in promille) int 300 + +#- +# controls spawn chance of clams 10 promille = 1 % +water_life_clams_spawn_rate (Clams spawn chance in promille) int 500 + +# - +# total max number of whales spawning in aktive area +water_life_maxwhales (Max possible whales in aktive area) int 1 + +# - +# total max number of sharks spawning in aktive area +water_life_maxsharks (Max possible sharks in aktive area) int 5 + +# - +# max lifetime of a moskito (default 120 = 2 minutes) +water_life_moskitolifetime (Max lifetime of a moskito in seconds) int 120 + + +# - +# total max number of animals in an aktive area +# other mods might not care about this setting +water_life_maxmobs (Max possible animals in aktive area) int 60 + +# - +# turn this to true if you only need the api but do +# not want to have the animals +water_life_apionly (no animals please, I just need the api) bool false + +# - +#replace riverwater with muddywater +#in rainforest and savanna biome +water_life_muddy_water (muddy water in rainforest and savanna biome) bool false + +#- +# turn this value to true to see api function debug +water_life_radar_debug (api function debug shown in chat) bool false + +#- +#number in days where new players are not affected by rattlesnake poison +water_life_newplayerbonus (days for newplayer immune to rattlesnake) int 5 + +#- +#I really hate insects, kill 'em all +water_life_hate_insects (no spawning of insects if true) bool false + +#- +#Let me see all that blood - blood effect on +water_life_bloody (blood effect on) bool true diff --git a/my_changes/mobs/mobs_mobkit/water_life/files/spawn.lua b/my_changes/mobs/mobs_mobkit/water_life/files/spawn.lua new file mode 100644 index 0000000..bb46d6e --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/files/spawn.lua @@ -0,0 +1,442 @@ +local timer = 0 +local landtimer = 0 +local dttot=0 +local dtavg=0 +local dtnum=0 +local dtmax=0 +local dttimer = 10 +local pi = math.pi +local random = water_life.random +local landinterval = 120 -- check every 60 seconds for spawnpos on land +local waterinterval = 40 -- check every 20 seconds for spawnpos in water + + +local function getcount(name) + if not name then + return 0 + else + return name + end +end + + +local function spawnstep(dtime) + + -- dtime measurement by Termos + if dtnum < 10001 then + dttot=dttot+dtime + dtnum=dtnum+1 + dtmax = dtime>dtmax and dtime or dtmax + + if dttot>dttimer then + dttimer=dttimer+10 + water_life.avg_dtime = dttot/dtnum + water_life.max_dtime = dtmax + dtmax=0 + end + else -- reset after 10000 steps + dtnum = 0 + dtavg = 0 + dttot = 0 + dtmax = 0 + dttimer = 10 + end + -- end dtime measurement + + timer = timer + dtime + landtimer = landtimer + dtime + + if timer > waterinterval then + + + for _,plyr in ipairs(minetest.get_connected_players()) do + + local toomuch = false + + if plyr and plyr:is_player() then + local meta = plyr:get_meta() + + if meta:get_int("snakepoison") > 0 then + local score = plyr:get_hp() + hunger_ng.set_effect(plyr:get_player_name(), "heal", "disabled") + plyr:set_hp(score-1) + end + + if meta:get_int("repellant") > 0 then + if math.floor(os.time()) - meta:get_int("repellant") > water_life.repeltime then + water_life.change_hud(plyr,"repellant",0) + meta:set_int("repellant",0) + end + end + end + + if plyr and plyr:is_player() and plyr:get_pos().y > -50 and plyr:get_pos().y < 150 and not water_life.apionly then -- each player gets a spawn chance every 10s on average + + local pos = plyr:get_pos() + local yaw = plyr:get_look_horizontal() + local animal = water_life.count_objects(pos) + local meta = plyr:get_meta() + + if animal.all > water_life.maxmobs then toomuch = true end + + -- find a pos randomly in look direction of player + local radius = (water_life.abr * 12) -- 75% from 16 = 12 nodes + radius = random(7,radius) -- not nearer than 7 nodes in front of player + local angel = math.rad(random(75)) -- look for random angel 0 - 75 degrees + if water_life.leftorright() then yaw = yaw + angel else yaw = yaw - angel end -- add or substract to/from yaw + + local pos2 = mobkit.pos_translate2d(pos,yaw,radius) -- calculate position + local depth, stype, surface = water_life.water_depth(pos2,25) -- get surface pos and water depth + local bdata = water_life_get_biome_data(pos2) -- get biome data at spawn position + local ground = {} + local dalam = depth + local landpos = nil + local geckopos = nil + local moskitopos = nil + local mobname = "" + + -- no need of so many postions on land + if landtimer > landinterval then + landpos = water_life.find_node_under_air(pos2) + geckopos = water_life.find_node_under_air(pos2,5,{"group:tree","group:leaves","default:junglegrass"}) + if not water_life.ihateinsects then + moskitopos = water_life.find_node_under_air(pos2,5,{"group:water","group:flora","group:crumbly"}) + end + end + + + if moskitopos and not water_life.dangerous and moskitopos.y > -10 and moskitopos.y < 100 then + local mlevel = minetest.get_node_light(moskitopos) + local ptime = water_life.get_game_time() + local mdata = water_life_get_biome_data(moskitopos) + --minetest.chat_send_all("MOSKITO: "..dump(moskitopos).." : "..dump(mdata.temp).." : "..dump(ptime).." : "..dump(mlevel)) + --minetest.chat_send_all(">>> Bzzzz ... SPAWN") + if ((ptime and ptime > 2) or mlevel < 8) and mdata.temp > 20 then --from 3pm to 5am or in shadows all day long + + minetest.set_node(moskitopos, {name = "water_life:moskito"}) + minetest.get_node_timer(moskitopos):start(random(15,45)) + local pmeta = minetest.get_meta(moskitopos) + pmeta:set_int("mlife",math.floor(os.time())) + + end + end + + --some spawn on land, too + + if landpos then + local landdata = water_life_get_biome_data(landpos) + + + if not water_life.dangerous then + -- the snake + mobname = 'water_life:snake' + local faktor = (100 - getcount(animal[mobname]) * 50) + if random(100) < faktor then + local fits = minetest.is_protected(landpos,mobname) + --minetest.chat_send_all(dump(fits)) + + if (string.match(landdata.name,"desert") or string.match(landdata.name,"savanna")) + and not fits and landdata.temp > 15 then + + local obj=minetest.add_entity(landpos,mobname) -- ok spawn it already damnit + end + end + + + end + + + --the beaver + mobname = 'water_life:beaver' + local faktor = (100 - getcount(animal[mobname]) * 25) + if random(100) < faktor then + + if string.match(landdata.name,"coniferous") and landdata.temp > -5 and landdata.temp < 20 then + + local obj=minetest.add_entity(landpos,mobname) -- ok spawn it already damnit + end + end + end + + + if geckopos then + local landdata = water_life_get_biome_data(geckopos) + + mobname = 'water_life:gecko' + local faktor = (100 - getcount(animal[mobname]) * 50) + if random(100) < faktor then + + + if (string.match(landdata.name,"rainforest") or string.match(landdata.name,"savanna")) + and landdata.temp > 20 then + + local obj=minetest.add_entity(geckopos,mobname) -- ok spawn it already damnit + end + end + end + + + + --water spawn + + if depth and depth > 0 then + if water_life.radar_debug then + water_life.temp_show(surface,9,5) + minetest.chat_send_all(">>> Depth ="..dump(depth).." <<< "..dump(stype)) + minetest.chat_send_all(dump(bdata.name)) + end + pos2 = surface + + end + + local liquidflag = nil + + if stype == "default:water_source" then + liquidflag = "sea" + + elseif stype == "default:river_water_source" then + liquidflag = "river" + + elseif stype == "water_life:muddy_river_water_source" then + liquidflag = "muddy" + + elseif water_life.swampz and stype == "swaz:water_source" then + liquidflag = "swamp" + + end + + if liquidflag and not toomuch and surface then + ground = mobkit.pos_shift(surface,{y=(dalam*-1)}) + local pool = water_life.check_for_pool(nil,4,8,surface) + + if water_life.radar_debug then + minetest.chat_send_all(">> A pool: "..dump(pool).." <<") + end + + if not water_life.dangerous then + + + if water_life.swampz then + + mobname = 'water_life:alligator' + local faktor = 100 - getcount(animal[mobname]) * 20 + if random(100) < faktor then + local fits = false + if string.match(bdata.name,"swampz") and liquidflag == "swamp" then fits = true end + + if depth < 4 and fits then --gator min water depth + local obj=minetest.add_entity(surface,mobname) -- ok spawn it already damnit + + end + + + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = 'water_life:croc' + local faktor = 100 - getcount(animal[mobname]) * 33 + if random(100) < faktor then + local fits = false + if string.match(bdata.name,"rainforest") or string.match(bdata.name,"savanna") then fits = true end + + if depth < 4 and fits and pool == false then --croc min water depth and no pools - do not check for nil + local obj=minetest.add_entity(surface,mobname) -- ok spawn it already damnit + end + + + end + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + + mobname = 'water_life:snake' + local faktor = (100 - getcount(animal[mobname]) * 50) +25 + if random(100) < faktor then + local fits = false + if string.match(bdata.name,"desert") or string.match(bdata.name,"savanna") then fits = true end + + if depth < 3 and fits then --snake max water depth + local obj=minetest.add_entity(surface,mobname) -- ok spawn it already damnit + end + + + end + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + mobname = 'water_life:shark' + if water_life.shark_spawn_rate >= random(1000) then + + local bcheck = water_life.count_objects(pos2,12) + if getcount(animal[mobname]) < water_life.maxsharks and liquidflag == "sea" and not bcheck["water_life:shark_buoy"] + and not animal["water_life:croc"] then + + if depth > 4 and pool == false then --shark min water depth + local obj=minetest.add_entity(mobkit.pos_shift(ground,{y=2}),mobname) -- spawn it 2 nodes above sea ground + end + end + + end + end + + mobname = "water_life:gull" + local faktor = 100 - getcount(animal[mobname]) * 20 + if random(100) < faktor and (liquidflag == "sea" or liquidflag == "river") then + if depth > 2 and not water_life.check_for_pool(nil,2,10,surface)then + --local spawn = mobkit.pos_shift(surface,{y=-1}) + --spawn.y = spawn.y + 12 + local obj=minetest.add_entity(surface,mobname) -- ok spawn it already damnit + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:urchin" + if water_life.urchin_spawn_rate >= random(1000) then + + local upos1 = mobkit.pos_shift(ground,{x=-5,y=-2,z=-5}) + local upos2 = mobkit.pos_shift(ground,{x=5,y=2,z=5}) + local coraltable = minetest.find_nodes_in_area(upos1, upos2, water_life.urchinspawn) + --local nearlife = water_life.count_objects(ground,5,"water_life:urchin") + if coraltable and #coraltable > 0 and getcount(animal[mobname]) < 15 and liquidflag == "sea" then + local coralpos = coraltable[random(#coraltable)] + coralpos.y = coralpos.y +1 + local node = minetest.get_node(coralpos) + + if node.name == "default:water_source" then + local obj= water_life.set_urchin(coralpos) --minetest.add_entity(coralpos,mobname) + end + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:clams" + if water_life.clams_spawn_rate >= random(1000) then + local clpos1 = mobkit.pos_shift(ground,{x=-8, y=-2, z=8}) + local clpos2 = mobkit.pos_shift(ground,{x=8, y=2, z=8}) + local coraltable = minetest.find_nodes_in_area(clpos1, clpos2, water_life.clams_spawn) + ----minetest.chat_send_all("seagrass ="..dump(#coraltable)) + local nearlife = water_life.count_objects(ground,8,"water_life:clams") + if coraltable and #coraltable > 0 and getcount(animal[mobname]) < 10 and liquidflag == "sea" then + local coralpos = mobkit.pos_shift(coraltable[random(#coraltable)],{y=1}) + + local node = minetest.get_node(coralpos) + if node.name == "default:water_source" then + local obj= water_life.set_urchin(coralpos,"water_life:clams") + end + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:jellyfish" + + + local faktor = 100 - getcount(animal[mobname]) * 20 + if random(100) < faktor and liquidflag == "sea" and depth > 2 then + local obj=minetest.add_entity(mobkit.pos_shift(ground,{y=2}),mobname) + end + + + mobname = "water_life:coralfish" + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + local cfpos1 = mobkit.pos_shift(ground,{x=-5,y=-2,z=-5}) + local cfpos2 = mobkit.pos_shift(ground,{x=5,y=2,z=5}) + local coraltable = minetest.find_nodes_in_area(cfpos1,cfpos2,water_life.urchinspawn) + --local nearlife = water_life.count_objects(ground,nil,mobname) + faktor = 100 - getcount(animal[mobname]) * 6.66 + if random(100) < faktor and liquidflag == "sea" and #coraltable > 1 then + local cfish = coraltable[random(#coraltable)] + cfish.y = cfish.y +1 + local maxfish = random(3,7) + for i = 1,maxfish,1 do + local obj=minetest.add_entity(cfish,mobname) + if obj then + local entity = obj:get_luaentity() + entity.base = cfish + entity.head = random(65535) + end + end + end + + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = "water_life:clownfish" + + faktor = 100 - getcount(animal[mobname]) * 50 + if random(100) < faktor and liquidflag == "sea" and #coraltable > 1 then + local cfish = coraltable[random(#coraltable)] + cfish.y = cfish.y +1 + local obj=minetest.add_entity(cfish,mobname) + if obj then + local entity = obj:get_luaentity() + entity.base = cfish + end + end + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + mobname = 'water_life:fish' + --local nearlife = water_life.count_objects(pos2,24,"water_life:piranha") + if water_life.fish_spawn_rate >= random(1000) and ((animal.all < (water_life.maxmobs-5)) or getcount(animal[mobname]) < 5) and (liquidflag == "river" or liquidflag == "muddy") then + + local table = minetest.get_biome_data(pos) + + if not water_life.dangerous and table and water_life.piranha_biomes[minetest.get_biome_name(table.biome)] then + mobname = "water_life:piranha" + end + + if depth > 2 then -- min water depth for piranha and riverfish + if mobname == "water_life:fish" then + local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit + else + if getcount(animal[mobname]) < 10 then + for i = 1,3,1 do + local obj=minetest.add_entity(pos2,mobname) -- ok spawn it already damnit + end + end + end + end + + + end + + --minetest.chat_send_all(dump(minetest.pos_to_string(surface)).." "..dump(minetest.pos_to_string(ground))) + + mobname = 'water_life:whale' + if water_life.whale_spawn_rate >= random(1000) and getcount(animal[mobname]) < (water_life.maxwhales) and liquidflag == "sea" then + + + if depth > 8 then -- min water depth for whales + + local gotwhale = true + local whpos = mobkit.pos_shift(surface,{y=-3}) + for i = 0,3,1 do + local whpos2 = mobkit.pos_translate2d(whpos,math.rad(i*90),30) + local under = water_life.find_collision(whpos,whpos2, false) + ----minetest.chat_send_all(dump(under)) + if under and under < 25 then + gotwhale = false + break + end + end + if gotwhale then local obj=minetest.add_entity(surface,mobname) end -- ok spawn it already damnit + + end + end + + end + end + end + timer = 0 + if landtimer > landinterval then landtimer = 0 end + end + +end + + + +minetest.register_globalstep(spawnstep) + diff --git a/my_changes/mobs/mobs_mobkit/water_life/poison.patch b/my_changes/mobs/mobs_mobkit/water_life/poison.patch new file mode 100644 index 0000000..ff7ae48 --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/poison.patch @@ -0,0 +1,41 @@ +diff --git a/apa_patch.lua b/apa_patch.lua +new file mode 100644 +index 0000000..d14688d +--- /dev/null ++++ b/apa_patch.lua +@@ -0,0 +1,11 @@ ++ ++water_life.poison_after_death = minetest.settings:get_bool("water_life_poison_after_death") or false ++ ++minetest.register_on_dieplayer(function(player) ++ if not player then return end ++ if water_life.poison_after_death then return end ++ ++ local meta=player:get_meta() ++ meta:set_int("snakepoison",0) ++ water_life.change_hud(player,"poison",0) ++end) +\ No newline at end of file +diff --git a/init.lua b/init.lua +index 22c16c9..8b5a455 100644 +--- a/init.lua ++++ b/init.lua +@@ -187,3 +187,5 @@ if minetest.get_modpath("farming") then + end + + ++-- Patch for a planet alive ++dofile(path.."/apa_patch.lua") +diff --git a/settingtypes.txt b/settingtypes.txt +index 3864685..a28a034 100644 +--- a/settingtypes.txt ++++ b/settingtypes.txt +@@ -1,3 +1,8 @@ ++ ++# ++# Turn this Value to true, if you want poison to persist after death ++water_life_poison_after_death (Poison stays after death) bool false ++ + # all settings for client menu or in minetest.conf on servers + + # - diff --git a/my_changes/mobs/mobs_mobkit/water_life/poison_hunger_ng.patch b/my_changes/mobs/mobs_mobkit/water_life/poison_hunger_ng.patch new file mode 100644 index 0000000..4a82fcc --- /dev/null +++ b/my_changes/mobs/mobs_mobkit/water_life/poison_hunger_ng.patch @@ -0,0 +1,62 @@ +diff --git a/api.lua b/api.lua +index c390549..78e30f0 100644 +--- a/api.lua ++++ b/api.lua +@@ -875,7 +875,7 @@ minetest.register_on_item_eat(function(hp_change, replace_with_item, itemstack, + local meta = user:get_meta() + local score = user:get_hp() + +- if meta:get_int("snakepoison") > 0 then meta:set_int("snakepoison",0) end ++ if meta:get_int("snakepoison") > 0 then meta:set_int("snakepoison",0) hunger_ng.set_effect(user:get_player_name(), "heal", "enabled") end + water_life.change_hud(user,"poison",0) + end + +diff --git a/behaviors.lua b/behaviors.lua +index 654fc5f..61935b6 100644 +--- a/behaviors.lua ++++ b/behaviors.lua +@@ -297,6 +297,7 @@ function water_life.lq_jumpattack(self,height,target,extra) + local name = target:get_player_name() + local join = meta:get_int("jointime") + if not join or (os.time() - join) > water_life.newplayerbonus * 86400 then ++ hunger_ng.set_effect(target:get_player_name(), "heal", "disabled") + meta:set_int("snakepoison",1) + water_life.change_hud(target,"poison") + else +diff --git a/crafts.lua b/crafts.lua +index 84703e4..5e5bf71 100644 +--- a/crafts.lua ++++ b/crafts.lua +@@ -340,7 +340,7 @@ if not water_life.apionly then + local meta = user:get_meta() + local score = user:get_hp() + +- if meta:get_int("snakepoison") > 0 then meta:set_int("snakepoison",0) end ++ if meta:get_int("snakepoison") > 0 then meta:set_int("snakepoison",0) hunger_ng.set_effect(user:get_player_name(), "heal", "enabled") end + user:set_hp(score+10) + itemstack:take_item() + water_life.change_hud(user,"poison",0) +diff --git a/hud.lua b/hud.lua +index bff0dd4..1b205ba 100644 +--- a/hud.lua ++++ b/hud.lua +@@ -71,6 +71,7 @@ minetest.register_on_joinplayer(function(player) + water_life.playerhud.repellant[name] = player:hud_add(water_life.hud_repellant) + + if meta:get_int("snakepoison") > 0 then ++ hunger_ng.set_effect(player:get_player_name(), "heal", "disabled") + minetest.after(5, function(player) + water_life.change_hud(player,"poison") + end, player) +diff --git a/spawn.lua b/spawn.lua +index 00b5afc..bb46d6e 100644 +--- a/spawn.lua ++++ b/spawn.lua +@@ -58,6 +58,7 @@ local function spawnstep(dtime) + + if meta:get_int("snakepoison") > 0 then + local score = plyr:get_hp() ++ hunger_ng.set_effect(plyr:get_player_name(), "heal", "disabled") + plyr:set_hp(score-1) + end + diff --git a/my_changes/mobs/mobs_mobs/advanced_npc/adv_npc_log.patch b/my_changes/mobs/mobs_mobs/advanced_npc/adv_npc_log.patch new file mode 100644 index 0000000..ed88070 --- /dev/null +++ b/my_changes/mobs/mobs_mobs/advanced_npc/adv_npc_log.patch @@ -0,0 +1,354 @@ +diff --git a/backup/npc.lua.bkp.before.process.lua b/backup/npc.lua.bkp.before.process.lua +index 6134e46..89db0d5 100644 +--- a/backup/npc.lua.bkp.before.process.lua ++++ b/backup/npc.lua.bkp.before.process.lua +@@ -72,7 +72,7 @@ npc.texture_check = { + -- Logging + function npc.log(level, message) + if npc.log_level[level] then +- minetest.log("[advanced_npc] "..level..": "..message) ++ minetest.log("info","[advanced_npc] "..level..": "..message) + end + end + +@@ -1995,7 +1995,7 @@ function npc.schedule_check(self) + -- Speed is default wandering speed. Target pos is node_pos + -- Calculate dir if dir is random + local dir = npc.commands.get_direction(start_pos, node_pos) +- minetest.log("actions: "..dump(actions[node.name][i])) ++ minetest.log("info","actions: "..dump(actions[node.name][i])) + if actions[node.name][i].args.dir == "random" then + dir = math.random(0,7) + elseif type(actions[node.name][i].args.dir) == "number" then +@@ -2086,7 +2086,7 @@ end + -- and other functions that are assigned to the Lua entity definition + -- This function is executed each time the NPC is loaded + function npc.after_activate(self) +- minetest.log("Self: "..dump(self)) ++ minetest.log("info","Self: "..dump(self)) + if not self.actions then + npc.log("WARNING", "Found NPC on bad initialization state: no 'self.actions' object.\nReinitializing...") + npc.initialize(self, self.object:getpos(), true) +diff --git a/dialogue.lua b/dialogue.lua +index f6968be..783dad2 100644 +--- a/dialogue.lua ++++ b/dialogue.lua +@@ -448,7 +448,7 @@ function npc.dialogue.start_dialogue(self, player, show_married_dialogue) + dialogue = self.dialogues.normal[math.random(1, #self.dialogues.normal)] + elseif chance >= 90 then + -- Check if gift items hints are enabled +- minetest.log("Self gift data enable: "..dump(self.gift_data.enable_gift_items_hints)) ++ minetest.log("info","Self gift data enable: "..dump(self.gift_data.enable_gift_items_hints)) + if self.gift_data.enable_gift_items_hints then + -- Choose a random dialogue line from the favorite/disliked item hints + dialogue = self.dialogues.hints[math.random(1, 4)] +diff --git a/executable/actions.lua b/executable/actions.lua +index cbb18aa..56db8a0 100644 +--- a/executable/actions.lua ++++ b/executable/actions.lua +@@ -1217,7 +1217,7 @@ function npc.commands.use_sittable(self, args) + end + -- Stand + npc.enqueue_command(self, npc.commands.cmd.STAND, {pos=pos_out_of_sittable, dir=dir}) +- minetest.log("Setting sittable at "..minetest.pos_to_string(pos).." as not used") ++ minetest.log("info","Setting sittable at "..minetest.pos_to_string(pos).." as not used") + if enable_usage_marking then + -- Set place as unused + npc.locations.mark_place_used(pos, npc.locations.USE_STATE.NOT_USED) +@@ -1264,7 +1264,7 @@ end + -- going to be considered walkable for the algorithm to find a + -- path. + npc.commands.register_script("advanced_npc:walk_to_pos", function(self, args) +- minetest.log("Received arguments: "..dump(args)) ++ minetest.log("info","Received arguments: "..dump(args)) + -- Get arguments for this task + local use_access_node = true + if args.use_access_node ~= nil then +@@ -1332,7 +1332,7 @@ npc.commands.register_script("advanced_npc:walk_to_pos", function(self, args) + if use_access_node == true then + dir = npc.commands.get_direction(end_pos, node_pos) + end +- minetest.log("Dir: "..dump(dir)) ++ minetest.log("info","Dir: "..dump(dir)) + -- Change dir if using access_node + npc.enqueue_command(self, npc.commands.cmd.STAND, {dir = dir}) + break +@@ -1488,7 +1488,7 @@ npc.commands.register_script("advanced_npc:idle", function (self, args) + else + -- Set interval + npc.commands.execute(self, npc.commands.cmd.SET_INTERVAL, {interval=obj_search_interval}) +- minetest.log("No obj found") ++ minetest.log("info","No obj found") + end + end + end) +@@ -1546,7 +1546,7 @@ npc.commands.register_script_function("advanced_npc:follow", "follow_player", fu + local player_name = args.player_name + local objs = minetest.get_objects_inside_radius(self.object:getpos(), args.radius) + -- Check if objects were found +- minetest.log("Objects found: "..dump(objs)) ++ minetest.log("info","Objects found: "..dump(objs)) + if #objs > 0 then + for _,obj in pairs(objs) do + if obj then +diff --git a/executable/helper.lua b/executable/helper.lua +index 438c980..3d2414c 100644 +--- a/executable/helper.lua ++++ b/executable/helper.lua +@@ -216,19 +216,19 @@ function npc.programs.helper.get_pos_argument(self, pos, use_access_node) + local use_access_node = pos.use_access_node or false + local try_alternative_if_used = pos.try_alternative_if_used or false + local places = npc.locations.get_by_type(self, pos.place_type) +- minetest.log("Place type: "..dump(pos.place_type)) +- minetest.log("Places: "..dump(places)) ++ minetest.log("info","Place type: "..dump(pos.place_type)) ++ minetest.log("info","Places: "..dump(places)) + -- Check index is valid on the places map + if #places >= index then + local place = places[index] + -- Check if place is used, and if it is, find alternative if required + if try_alternative_if_used == true then +- minetest.log("Self places map: "..dump(self.places_map)) +- minetest.log("Place category: "..dump(pos.place_category)) +- minetest.log("Place type: "..dump(pos.place_type)) +- minetest.log("Original Place: "..dump(place)) ++ minetest.log("info","Self places map: "..dump(self.places_map)) ++ minetest.log("info","Place category: "..dump(pos.place_category)) ++ minetest.log("info","Place type: "..dump(pos.place_type)) ++ minetest.log("info","Original Place: "..dump(place)) + place = npc.locations.find_unused_place(self, pos.place_category, pos.place_type, place) +- minetest.log("New place: "..dump(place)) ++ minetest.log("info","New place: "..dump(place)) + + if next(place) ~= nil then + --minetest.log("Mark as used? "..dump(pos.mark_target_as_used)) +diff --git a/executable/instructions/builtin_instructions.lua b/executable/instructions/builtin_instructions.lua +index b53b359..67ada14 100644 +--- a/executable/instructions/builtin_instructions.lua ++++ b/executable/instructions/builtin_instructions.lua +@@ -180,7 +180,7 @@ npc.programs.instr.register("advanced_npc:dig", function(self, args) + npc.add_item_to_inventory(self, drop_itemname, 1) + end + -- Dig node +- minetest.log("Setting air at pos: "..minetest.pos_to_string(pos)) ++ minetest.log("info","Setting air at pos: "..minetest.pos_to_string(pos)) + minetest.set_node(pos, {name="air"}) + end + end +diff --git a/executable/locations.lua b/executable/locations.lua +index 9605a14..6553b06 100644 +--- a/executable/locations.lua ++++ b/executable/locations.lua +@@ -548,7 +548,7 @@ end + -- furnaces, storage (e.g. chests) and openable (e.g. doors). + -- Returns a table with these classifications + function npc.locations.scan_area_for_usable_nodes(pos1, pos2) +- minetest.log("Bed Nodes: "..dump(npc.locations.nodes.bed)) ++ minetest.log("info","Bed Nodes: "..dump(npc.locations.nodes.bed)) + local result = { + bed_type = {}, + sittable_type = {}, +diff --git a/executable/programs/builtin/follow.lua b/executable/programs/builtin/follow.lua +index ac52b1c..66d5e4e 100644 +--- a/executable/programs/builtin/follow.lua ++++ b/executable/programs/builtin/follow.lua +@@ -55,7 +55,7 @@ npc.programs.instr.register("advanced_npc:follow:follow_player", function(self, + local player_name = args.player_name + local objs = minetest.get_objects_inside_radius(self.object:getpos(), args.radius) + -- Check if objects were found +- minetest.log("Objects found: "..dump(objs)) ++ minetest.log("info","Objects found: "..dump(objs)) + if #objs > 0 then + for _,obj in pairs(objs) do + if obj then +diff --git a/executable/programs/builtin/idle.lua b/executable/programs/builtin/idle.lua +index d7891d5..b7b6ddd 100644 +--- a/executable/programs/builtin/idle.lua ++++ b/executable/programs/builtin/idle.lua +@@ -160,7 +160,7 @@ npc.programs.register("advanced_npc:idle", function(self, args) + -- Set interval + npc.programs.instr.execute(self, "advanced_npc:wait", {time=5}) + --npc.programs.instr.execute(self, npc.programs.instr.default.SET_PROCESS_INTERVAL, {interval=obj_search_interval}) +- minetest.log("No obj found") ++ minetest.log("info","No obj found") + end + end + end) +diff --git a/executable/programs/builtin/use_sittable.lua b/executable/programs/builtin/use_sittable.lua +index 2ec7260..30565c1 100644 +--- a/executable/programs/builtin/use_sittable.lua ++++ b/executable/programs/builtin/use_sittable.lua +@@ -17,7 +17,7 @@ npc.programs.register("advanced_npc:use_sittable", function(self, args) + local node = minetest.get_node(pos) + + if action == npc.programs.const.node_ops.sittable.SIT then +- minetest.log("Sitting...") ++ minetest.log("info","Sitting...") + -- Calculate position depending on bench + -- Error here due to ignore. Need to come up with better solution + if node.name == "ignore" then +@@ -54,7 +54,7 @@ npc.programs.register("advanced_npc:use_sittable", function(self, args) + end + -- Stand + npc.programs.instr.execute(self, npc.programs.instr.default.STAND, {pos=pos_out_of_sittable, dir=dir}) +- minetest.log("Setting sittable at "..minetest.pos_to_string(pos).." as not used") ++ minetest.log("info","Setting sittable at "..minetest.pos_to_string(pos).." as not used") + if enable_usage_marking then + -- Set place as unused + npc.locations.mark_place_used(pos, npc.locations.USE_STATE.NOT_USED) +diff --git a/executable/programs/builtin/wander.lua b/executable/programs/builtin/wander.lua +index 866be02..b9aa741 100644 +--- a/executable/programs/builtin/wander.lua ++++ b/executable/programs/builtin/wander.lua +@@ -48,7 +48,7 @@ npc.programs.register("advanced_npc:wander", function(self, args) + }) + npc.exec.proc.enqueue(self, npc.programs.instr.default.STAND, {}) + else +- minetest.log("Walking randomly") ++ minetest.log("info","Walking randomly") + -- Walk in a random direction + local npc_pos = self.object:getpos() + npc.exec.proc.enqueue(self, npc.programs.instr.default.WALK_STEP, { +diff --git a/npc.lua b/npc.lua +index 88d7442..a1b16ae 100755 +--- a/npc.lua ++++ b/npc.lua +@@ -65,7 +65,7 @@ npc.texture_check = { + -- Logging + function npc.log(level, message) + if npc.log_level[level] then +- minetest.log("[advanced_npc] "..level..": "..message) ++ minetest.log("info","[advanced_npc] "..level..": "..message) + end + end + +@@ -1102,7 +1102,7 @@ function npc.exec.interrupt(self, new_program, new_arguments, interrupt_options) + _exec.priority_enqueue(self, + {[1] = {program_name=new_program, arguments=new_arguments, interrupt_options=interrupt_options}}) + --minetest.log("Pause") +- minetest.log("Interrupted process: "..dump(self.execution.process_queue[1])) ++ minetest.log("info","Interrupted process: "..dump(self.execution.process_queue[1])) + -- Check process - if the instruction queue is empty, do not store + -- Pause current process + _exec.pause_process(self) +@@ -1205,7 +1205,7 @@ end + function _exec.restore_process(self) + local current_process = self.execution.process_queue[1] + if current_process then +- minetest.log("Restoring process: "..dump(current_process.program_name)) ++ minetest.log("info","Restoring process: "..dump(current_process.program_name)) + -- Change process state + current_process.state = npc.exec.proc.state.RUNNING + -- Check if any instruction was interrupted +@@ -1215,7 +1215,7 @@ function _exec.restore_process(self) + -- Restore position + --self.object:setpos(current_process.current_instruction.pos) + -- Execute instruction +- minetest.log("Re-executing instruction: "..dump(current_process.current_instruction.entry.name)) ++ minetest.log("info","Re-executing instruction: "..dump(current_process.current_instruction.entry.name)) + _exec.proc.execute(self, current_process.current_instruction.entry) + end + end +diff --git a/occupations/occupations.lua b/occupations/occupations.lua +index 092f451..4108634 100644 +--- a/occupations/occupations.lua ++++ b/occupations/occupations.lua +@@ -387,7 +387,7 @@ function npc.occupations.initialize_occupation_values(self, occupation_name) + self.selected_texture = "default_"..self.gender..".png" + end + end +- minetest.log("Result: "..dump(self.selected_texture)) ++ minetest.log("info","Result: "..dump(self.selected_texture)) + + -- Set texture and base texture + self.textures = {self.selected_texture} +@@ -464,7 +464,7 @@ function npc.occupations.initialize_occupation_values(self, occupation_name) + end + + -- Initialize properties +- minetest.log("def.properties: "..dump(def.properties)) ++ minetest.log("info","def.properties: "..dump(def.properties)) + if def.properties then + -- Initialize trader status + if def.properties.initial_trader_status then +diff --git a/spawner.lua b/spawner.lua +index 9c06f3f..3d47a3d 100644 +--- a/spawner.lua ++++ b/spawner.lua +@@ -299,8 +299,8 @@ function npc.spawner.determine_npc_occupation(building_type, workplace_nodes, np + end + else + -- Try to match building type with the occupation local building types +- minetest.log("Building type: "..dump(building_type)) +- minetest.log("Occupation local building types: "..dump(local_building_types)) ++ minetest.log("info","Building type: "..dump(building_type)) ++ minetest.log("info","Occupation local building types: "..dump(local_building_types)) + for i = 1, #occupation_names do + for j = 1, #local_building_types do + if building_type == local_building_types[j] then +@@ -311,7 +311,7 @@ function npc.spawner.determine_npc_occupation(building_type, workplace_nodes, np + end + end + end +- minetest.log("Local building match after: "..dump(result)) ++ minetest.log("info","Local building match after: "..dump(result)) + end + end + end +@@ -323,9 +323,9 @@ function npc.spawner.determine_npc_occupation(building_type, workplace_nodes, np + -- - If count is less than three (only two NPCs), default_basic occupation. + -- - If count is greater than two, assign any eligible occupation with 50% chance + -- - If not NPC is working, choose an occupation that is not default_basic +- minetest.log("Current building occupations: "..dump(current_building_npc_occupations)) +- minetest.log("Result #: "..dump(#result)) +- minetest.log("Result: "..dump(result)) ++ minetest.log("info","Current building occupations: "..dump(current_building_npc_occupations)) ++ minetest.log("info","Result #: "..dump(#result)) ++ minetest.log("info","Result: "..dump(result)) + if next(current_building_npc_occupations) ~= nil then + for i = 1, #current_building_npc_occupations do + if current_building_npc_occupations[i] ~= npc.occupations.basic_name then +@@ -839,7 +839,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) + + -- Scan for usable nodes + local area_info = npc.spawner.scan_area_for_spawn(start_pos, end_pos, player:get_player_name(), pos) +- minetest.log("Area info: "..dump(area_info)) ++ minetest.log("info","Area info: "..dump(area_info)) + -- Assign occupation + local occupation_data = npc.spawner.determine_npc_occupation( + fields.building_type or area_info.building_type, +@@ -1094,8 +1094,8 @@ if minetest.get_modpath("mg_villages") ~= nil then + -- TODO: Change formspec to a more detailed one. + on_rightclick = function(pos, node, clicker, itemstack, pointed_thing) + local meta = minetest.get_meta(pos) +- minetest.log("NPCs: "..dump(minetest.deserialize(meta:get_string("npcs")))) +- minetest.log("Node data: "..dump(minetest.deserialize(meta:get_string("node_data")))) ++ minetest.log("info","NPCs: "..dump(minetest.deserialize(meta:get_string("npcs")))) ++ minetest.log("info","Node data: "..dump(minetest.deserialize(meta:get_string("node_data")))) + return mg_villages.plotmarker_formspec( pos, nil, {}, clicker ) + end, + +@@ -1201,7 +1201,7 @@ minetest.register_chatcommand("restore_area", { + privs = {server = true}, + func = function(name, param) + local args = npc.utils.split(param, " ") +- minetest.log("Params: "..dump(args)) ++ minetest.log("info","Params: "..dump(args)) + if #args < 2 then + minetest.chat_send_player("Please specify horizontal and vertical radius.") + return +diff --git a/trade/trade.lua b/trade/trade.lua +index de535fc..56b814f 100644 +--- a/trade/trade.lua ++++ b/trade/trade.lua +@@ -451,8 +451,8 @@ function npc.trade.get_dedicated_trade_offers(self) + -- If it is, create a sell offer, else create a buy offer if possible. + -- Also, avoid creating sell offers immediately if the item was just bought + local item = npc.inventory_contains(self, item_name) +- minetest.log("Searched item: "..dump(item_name)) +- minetest.log("Found: "..dump(item)) ++ minetest.log("info","Searched item: "..dump(item_name)) ++ minetest.log("info","Found: "..dump(item)) + if item ~= nil and trade_info.last_offer_type ~= npc.trade.OFFER_BUY then + -- Check if item can be sold + if trade_info.item_sold_count == nil diff --git a/my_changes/mobs/mobs_mobs/advanced_npc/bugtrade184.patch b/my_changes/mobs/mobs_mobs/advanced_npc/bugtrade184.patch new file mode 100644 index 0000000..69761c1 --- /dev/null +++ b/my_changes/mobs/mobs_mobs/advanced_npc/bugtrade184.patch @@ -0,0 +1,22 @@ +diff --git a/trade/trade.lua b/trade/trade.lua +index 56b814f..6526b9b 100644 +--- a/trade/trade.lua ++++ b/trade/trade.lua +@@ -173,7 +173,8 @@ function npc.trade.show_trade_offer_formspec(self, player, offer_type) + prompt_string = " wants to sell to you" + buy_sell_string = "Buy" + end +- ++ ++ if trade_offer.item ~= nil then + local formspec = "size[8,4]".. + default.gui_bg.. + default.gui_bg_img.. +@@ -192,6 +193,7 @@ function npc.trade.show_trade_offer_formspec(self, player, offer_type) + } + -- Show formspec to player + minetest.show_formspec(player:get_player_name(), "advanced_npc:trade_offer", formspec) ++ end + end + + diff --git a/my_changes/mobs/mobs_mobs/goblins/goblins_nil.patch b/my_changes/mobs/mobs_mobs/goblins/goblins_nil.patch new file mode 100644 index 0000000..1e86472 --- /dev/null +++ b/my_changes/mobs/mobs_mobs/goblins/goblins_nil.patch @@ -0,0 +1,33 @@ +diff --git a/behaviors.lua b/behaviors.lua +index baac807..453807d 100644 +--- a/behaviors.lua ++++ b/behaviors.lua +@@ -669,7 +669,21 @@ function goblins.tunneling(self, type) + end + + function goblins.danger_dig(self,freq,depth) +- local pos = vector.round(self.object:get_pos()) ++ local self_pos = self.object:get_pos() ++ if self_pos ~= nil then ++ local vx = self_pos.x ++ local vy = self_pos.y ++ local vz = self_pos.z ++ local pos = {x = math.floor(vx + 0.5), ++ y = math.floor(vy + 0.5), ++ z = math.floor(vz + 0.5) ++ } ++ --minetest.log("self_pos: "..dump(self_pos)) ++ else ++ --minetest.log("self_pos: "..dump(self_pos)) ++ end ++ ++ --local pos = vector.round(self.object:get_pos()) + if pos then + local lol = minetest.get_node_light(pos) or 0 + local freq = freq or 0.1 +@@ -814,5 +828,3 @@ function goblins.goblin_dog_behaviors(self) + --]] + end + end +- +- diff --git a/my_changes/mobs/mobs_mobs/mg_villages_npc/bug.patch b/my_changes/mobs/mobs_mobs/mg_villages_npc/bug.patch new file mode 100644 index 0000000..9ff9c78 --- /dev/null +++ b/my_changes/mobs/mobs_mobs/mg_villages_npc/bug.patch @@ -0,0 +1,26 @@ +diff --git a/data/dialogues_data.lua b/data/dialogues_data.lua +index 8d1dae4..26dd4cb 100644 +--- a/data/dialogues_data.lua ++++ b/data/dialogues_data.lua +@@ -63,18 +63,18 @@ npc.dialogue.register_dialogue({ + text = "Yes, how can I help?", + action_type = "dialogue", + action = { +- text = "Could you please give me 3 "..npc.trade.prices.currency.tier3.name.."?", ++ text = "Could you please give me 3 "..npc.trade.prices.get_currency_name(npc.trade.prices.currency.tier3).."?", + responses = { + [1] = { + text = "Yes, ok, here", + action_type = "function", + action = function(self, player) + -- Take item +- if npc.commands.execute(self, npc.commands.cmd.TAKE_ITEM, { ++ if npc.programs.instr.execute(self, npc.programs.instr.default.TAKE_ITEM, { + player=player:get_player_name(), + pos=nil, + inv_list="main", +- item_name=npc.trade.prices.currency.tier3.string, ++ item_name=npc.trade.prices.get_currency_itemstring("tier3"), + count=3 + }) then + -- Send message diff --git a/my_changes/mobs/mobs_mobs/mg_villages_npc/patch_log.patch b/my_changes/mobs/mobs_mobs/mg_villages_npc/patch_log.patch new file mode 100644 index 0000000..b0c8e16 --- /dev/null +++ b/my_changes/mobs/mobs_mobs/mg_villages_npc/patch_log.patch @@ -0,0 +1,13 @@ +diff --git a/data/occupations/default_farmer.lua b/data/occupations/default_farmer.lua +index 673019b..b5452cd 100644 +--- a/data/occupations/default_farmer.lua ++++ b/data/occupations/default_farmer.lua +@@ -33,7 +33,7 @@ npc.programs.register("mg_villages_npc:farmer:walk_to_field", function(self, arg + -- Get plotmarker + local plotmarker_pos = npc.locations.get_by_type(self, npc.locations.data.other.home_plotmarker) + -- There should always be just one plotmarker +- minetest.log("Got: "..dump(plotmarker_pos)) ++ minetest.log("info","Got: "..dump(plotmarker_pos)) + plotmarker_pos = plotmarker_pos[1].pos + -- Search building area for gates + local meta = minetest.get_meta(plotmarker_pos) diff --git a/my_changes/player/fire_plus/extend_fire.patch b/my_changes/player/fire_plus/extend_fire.patch new file mode 100644 index 0000000..9146903 --- /dev/null +++ b/my_changes/player/fire_plus/extend_fire.patch @@ -0,0 +1,82 @@ +diff --git a/api.lua b/api.lua +index 013dae3..cce2937 100644 +--- a/api.lua ++++ b/api.lua +@@ -68,8 +68,27 @@ function fire_plus.burn_player(player, burns, damage, not_initial) + maxexptime = 1, + minsize = 3, + maxsize = 3, +- texture = "fire_basic_flame.png", ++ texture = "smoke_puff.png", + collisiondetection = true, ++ glow = 0, ++ attached = player, ++ }), ++ particlespawner_id2 = minetest.add_particlespawner({ ++ amount = 5, ++ time = 0, ++ minpos = vector.new(0, 0.5, -0.3), ++ maxpos = vector.new( 0, 0.5, 0.3), ++ minvel = {x = 0, y = 0, z = 0}, ++ maxvel = {x = 0, y = 0, z = 0}, ++ minacc = {x = 0, y = 0, z = 0}, ++ maxacc = {x = 0, y = 0, z = 0}, ++ minexptime = 0.5, ++ maxexptime = 1, ++ minsize = 10, ++ maxsize = 10, ++ texture = "fire_basic_flame_animated.png", ++ animation = {type="vertical_frames", aspect_w=16, aspect_h=16, length = 1,}, ++ collisiondetection = false, + glow = minetest.LIGHT_MAX, + attached = player, + }) +@@ -120,6 +139,7 @@ function fire_plus.extinguish_player(player) + end + + minetest.delete_particlespawner(fire_plus.burning[name].particlespawner_id) +- ++ minetest.delete_particlespawner(fire_plus.burning[name].particlespawner_id2) ++ + fire_plus.burning[name] = nil + end +diff --git a/init.lua b/init.lua +index f89a241..43cc4f7 100644 +--- a/init.lua ++++ b/init.lua +@@ -24,6 +24,8 @@ fire_plus = { + dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/api.lua") + + local time = 0 ++local img_num = 1 ++local img_num_max = 8 + minetest.register_globalstep(function(dtime) + time = time + dtime + +@@ -40,6 +42,26 @@ minetest.register_globalstep(function(dtime) + + if fire_plus.burning[name] then + ++ -- change HUD to next image to simulate animation ++ --local img_name = "fire_basic_flame_"..img_num..".png" ++ img_name = "fire_basic_flame_animated.png".."^[verticalframe:"..img_num_max..":"..img_num ++ --minetest.log(dump(img_name)) ++ player:hud_remove(fire_plus.burning[name].hud_id) ++ fire_plus.burning[name].hud_id = player:hud_add({ ++ hud_elem_type = "image", ++ position = {x = 0.5, y = 0.95}, ++ offset = {x = 0, y = 0}, ++ text = img_name, ++ alignment = -1, ++ scale = {x = 100, y = 32}, ++ number = 0xFFFFFF, ++ }) ++ if img_num >= img_num_max then ++ img_num = 1 ++ else ++ img_num = img_num + 1 ++ end ++ + local nodename = minetest.get_node(player:get_pos()).name + local nodename_head = minetest.get_node(vector.add(player:get_pos(), + vector.new(0, 1, 0))).name diff --git a/my_changes/player/hbsprint/no_damage.patch b/my_changes/player/hbsprint/no_damage.patch new file mode 100644 index 0000000..81a4564 --- /dev/null +++ b/my_changes/player/hbsprint/no_damage.patch @@ -0,0 +1,13 @@ +diff --git a/init.lua b/init.lua +index 3e5ff0d..18f5150 100644 +--- a/init.lua ++++ b/init.lua +@@ -230,7 +230,7 @@ local function sprint_step(player, dtime) + local hunger = 30 + if starve == "hbhunger" then + hunger = tonumber(hbhunger.hunger[name]) +- elseif starve == "hunger_ng" then ++ elseif starve == "hunger_ng" and minetest.is_yes(minetest.settings:get('enable_damage')) then + hunger = hunger_ng.get_hunger_information(name).hunger.exact + end + diff --git a/my_changes/player/skinsdb/meta/character_female_1.txt b/my_changes/player/skinsdb/meta/character_female_1.txt new file mode 100644 index 0000000..65f809c --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_1.txt @@ -0,0 +1,4 @@ +horrible spring sdzen +sdzen +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_10.txt b/my_changes/player/skinsdb/meta/character_female_10.txt new file mode 100644 index 0000000..7d93f14 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_10.txt @@ -0,0 +1,4 @@ +rize +rexyGYM +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_11.txt b/my_changes/player/skinsdb/meta/character_female_11.txt new file mode 100644 index 0000000..02ab661 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_11.txt @@ -0,0 +1,4 @@ +alejandra +rexyGYM +CC BY 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_12.txt b/my_changes/player/skinsdb/meta/character_female_12.txt new file mode 100644 index 0000000..15db943 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_12.txt @@ -0,0 +1,4 @@ +Aurora (child of light) +WD/Ubisoft +CC BY-NC-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_13.txt b/my_changes/player/skinsdb/meta/character_female_13.txt new file mode 100644 index 0000000..21419f0 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_13.txt @@ -0,0 +1,4 @@ +Xenia +HeyGirlHey +CC BY 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_14.txt b/my_changes/player/skinsdb/meta/character_female_14.txt new file mode 100644 index 0000000..cab1971 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_14.txt @@ -0,0 +1,4 @@ +stef325 +stef325 +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_female_15.txt b/my_changes/player/skinsdb/meta/character_female_15.txt new file mode 100644 index 0000000..9c464ff --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_15.txt @@ -0,0 +1,4 @@ +Cloé +Sporax +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_16.txt b/my_changes/player/skinsdb/meta/character_female_16.txt new file mode 100644 index 0000000..a71d384 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_16.txt @@ -0,0 +1,4 @@ +Julia +nelly +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_17.txt b/my_changes/player/skinsdb/meta/character_female_17.txt new file mode 100644 index 0000000..48d6d28 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_17.txt @@ -0,0 +1,4 @@ +Morgane +loupicate +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_18.txt b/my_changes/player/skinsdb/meta/character_female_18.txt new file mode 100644 index 0000000..b7c0806 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_18.txt @@ -0,0 +1,4 @@ +Elf +loupicate +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_19.txt b/my_changes/player/skinsdb/meta/character_female_19.txt new file mode 100644 index 0000000..8427c9b --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_19.txt @@ -0,0 +1,4 @@ +Angel +nelly +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_2.txt b/my_changes/player/skinsdb/meta/character_female_2.txt new file mode 100644 index 0000000..ed3050c --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_2.txt @@ -0,0 +1,4 @@ +Summer +lizzie +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_20.txt b/my_changes/player/skinsdb/meta/character_female_20.txt new file mode 100644 index 0000000..1da2800 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_20.txt @@ -0,0 +1,4 @@ +Female angel +loupicate +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_21.txt b/my_changes/player/skinsdb/meta/character_female_21.txt new file mode 100644 index 0000000..b7c0806 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_21.txt @@ -0,0 +1,4 @@ +Elf +loupicate +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_22.txt b/my_changes/player/skinsdb/meta/character_female_22.txt new file mode 100644 index 0000000..5f2a90d --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_22.txt @@ -0,0 +1,4 @@ +Blonde Girl +Rin +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_23.txt b/my_changes/player/skinsdb/meta/character_female_23.txt new file mode 100644 index 0000000..dbc46cf --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_23.txt @@ -0,0 +1,4 @@ +bikini +anonme +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_24.txt b/my_changes/player/skinsdb/meta/character_female_24.txt new file mode 100644 index 0000000..83c4b7e --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_24.txt @@ -0,0 +1,4 @@ +White Music Girl +ElMehdiBen +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_25.txt b/my_changes/player/skinsdb/meta/character_female_25.txt new file mode 100644 index 0000000..d2b0a7d --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_25.txt @@ -0,0 +1,4 @@ +MLP-Fluttershy +julito +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_26.txt b/my_changes/player/skinsdb/meta/character_female_26.txt new file mode 100644 index 0000000..7209d27 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_26.txt @@ -0,0 +1,4 @@ +Flower Girl +julito +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_27.txt b/my_changes/player/skinsdb/meta/character_female_27.txt new file mode 100644 index 0000000..659e756 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_27.txt @@ -0,0 +1,4 @@ +Rin-chan 1 +Rin +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_28.txt b/my_changes/player/skinsdb/meta/character_female_28.txt new file mode 100644 index 0000000..6e11043 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_28.txt @@ -0,0 +1,4 @@ +Tahlia +loupicate +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_29.txt b/my_changes/player/skinsdb/meta/character_female_29.txt new file mode 100644 index 0000000..b1bc4c3 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_29.txt @@ -0,0 +1,4 @@ +MC cute girls polar bear +SAM7777 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_3.txt b/my_changes/player/skinsdb/meta/character_female_3.txt new file mode 100644 index 0000000..0e9705a --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_3.txt @@ -0,0 +1,4 @@ +lisa +hansuke123 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_30.txt b/my_changes/player/skinsdb/meta/character_female_30.txt new file mode 100644 index 0000000..c089903 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_30.txt @@ -0,0 +1,4 @@ +Blue Wolf-Girl +AuroreTheWolf +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_31.txt b/my_changes/player/skinsdb/meta/character_female_31.txt new file mode 100644 index 0000000..75300e9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_31.txt @@ -0,0 +1,4 @@ +Pretresse +AuroreTheWolf +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_32.txt b/my_changes/player/skinsdb/meta/character_female_32.txt new file mode 100644 index 0000000..94c49e7 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_32.txt @@ -0,0 +1,4 @@ +bear63681 +SAM7777 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_33.txt b/my_changes/player/skinsdb/meta/character_female_33.txt new file mode 100644 index 0000000..269dacc --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_33.txt @@ -0,0 +1,4 @@ +CreativeFox +SAM7777 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_34.txt b/my_changes/player/skinsdb/meta/character_female_34.txt new file mode 100644 index 0000000..1ae55b9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_34.txt @@ -0,0 +1,4 @@ +FluffyGirl +SAM7777 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_35.txt b/my_changes/player/skinsdb/meta/character_female_35.txt new file mode 100644 index 0000000..8ba844b --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_35.txt @@ -0,0 +1,4 @@ +Nenha +SAM7777 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_36.txt b/my_changes/player/skinsdb/meta/character_female_36.txt new file mode 100644 index 0000000..516dcab --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_36.txt @@ -0,0 +1,4 @@ +Abril +julito +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_37.txt b/my_changes/player/skinsdb/meta/character_female_37.txt new file mode 100644 index 0000000..71df092 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_37.txt @@ -0,0 +1,4 @@ +Custom Skin 1 +Rin0002 +CC BY 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_38.txt b/my_changes/player/skinsdb/meta/character_female_38.txt new file mode 100644 index 0000000..cf60f85 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_38.txt @@ -0,0 +1,4 @@ +Black Flower Crown +Rin0002 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_39.txt b/my_changes/player/skinsdb/meta/character_female_39.txt new file mode 100644 index 0000000..d5cbbd6 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_39.txt @@ -0,0 +1,4 @@ +Name this pls 2 +Rin0002 +CC BY 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_4.txt b/my_changes/player/skinsdb/meta/character_female_4.txt new file mode 100644 index 0000000..81637da --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_4.txt @@ -0,0 +1,4 @@ +Ladyvioletkitty +lordphoenixmh +CC BY 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_40.txt b/my_changes/player/skinsdb/meta/character_female_40.txt new file mode 100644 index 0000000..e594567 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_40.txt @@ -0,0 +1,4 @@ +Lilly +Karelys26 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_41.txt b/my_changes/player/skinsdb/meta/character_female_41.txt new file mode 100644 index 0000000..8a600f4 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_41.txt @@ -0,0 +1,4 @@ +Nani +Karelys26 +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_42.txt b/my_changes/player/skinsdb/meta/character_female_42.txt new file mode 100644 index 0000000..e424939 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_42.txt @@ -0,0 +1,4 @@ +Karita +Karelys26 +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_43.txt b/my_changes/player/skinsdb/meta/character_female_43.txt new file mode 100644 index 0000000..8f75fe9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_43.txt @@ -0,0 +1,4 @@ +Athena +skindex +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_44.txt b/my_changes/player/skinsdb/meta/character_female_44.txt new file mode 100644 index 0000000..bb09d93 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_44.txt @@ -0,0 +1,4 @@ +Lotte +skindex +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_45.txt b/my_changes/player/skinsdb/meta/character_female_45.txt new file mode 100644 index 0000000..6658265 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_45.txt @@ -0,0 +1,4 @@ +Yuzuki_Airi +planetmc +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_46.txt b/my_changes/player/skinsdb/meta/character_female_46.txt new file mode 100644 index 0000000..c774203 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_46.txt @@ -0,0 +1,4 @@ +Raina +XrystalFox +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_47.txt b/my_changes/player/skinsdb/meta/character_female_47.txt new file mode 100644 index 0000000..58acf94 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_47.txt @@ -0,0 +1,4 @@ +Marisa +ZUN +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_female_48.txt b/my_changes/player/skinsdb/meta/character_female_48.txt new file mode 100644 index 0000000..d1dd70d --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_48.txt @@ -0,0 +1,4 @@ +KittyKat_2 +skindex +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_49.txt b/my_changes/player/skinsdb/meta/character_female_49.txt new file mode 100644 index 0000000..c8b2bc9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_49.txt @@ -0,0 +1,4 @@ +KittyKat +skindex +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_5.txt b/my_changes/player/skinsdb/meta/character_female_5.txt new file mode 100644 index 0000000..c26e2c0 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_5.txt @@ -0,0 +1,4 @@ +Mammu +hansuke123 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_50.txt b/my_changes/player/skinsdb/meta/character_female_50.txt new file mode 100644 index 0000000..bbe5492 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_50.txt @@ -0,0 +1,4 @@ +Yuzuki_Airi +skindex +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_51.txt b/my_changes/player/skinsdb/meta/character_female_51.txt new file mode 100644 index 0000000..19b4777 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_51.txt @@ -0,0 +1,4 @@ +Black_MagicGirlX(1.2) +IFRFSX +CC BY-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_52.txt b/my_changes/player/skinsdb/meta/character_female_52.txt new file mode 100644 index 0000000..40f1ce8 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_52.txt @@ -0,0 +1,4 @@ +LadyK +LadyK +CC BY-NC-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_53.txt b/my_changes/player/skinsdb/meta/character_female_53.txt new file mode 100644 index 0000000..b042f1f --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_53.txt @@ -0,0 +1,4 @@ +RainbowGirl +unknown +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_54.txt b/my_changes/player/skinsdb/meta/character_female_54.txt new file mode 100644 index 0000000..1cdd1a0 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_54.txt @@ -0,0 +1,4 @@ +Inga +unknown +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_55.txt b/my_changes/player/skinsdb/meta/character_female_55.txt new file mode 100644 index 0000000..8a332e1 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_55.txt @@ -0,0 +1,4 @@ +smilla +ie +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_6.txt b/my_changes/player/skinsdb/meta/character_female_6.txt new file mode 100644 index 0000000..da5d9b3 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_6.txt @@ -0,0 +1,4 @@ +Jayne +Andromeda +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_7.txt b/my_changes/player/skinsdb/meta/character_female_7.txt new file mode 100644 index 0000000..a74dc10 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_7.txt @@ -0,0 +1,4 @@ +blue girl +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_8.txt b/my_changes/player/skinsdb/meta/character_female_8.txt new file mode 100644 index 0000000..d946b1f --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_8.txt @@ -0,0 +1,4 @@ +Adventer girl +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_female_9.txt b/my_changes/player/skinsdb/meta/character_female_9.txt new file mode 100644 index 0000000..b64a8b7 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_female_9.txt @@ -0,0 +1,4 @@ +BrightGirl +Malarif +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_100.txt b/my_changes/player/skinsdb/meta/character_male_100.txt new file mode 100644 index 0000000..1ec44f5 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_100.txt @@ -0,0 +1,4 @@ +Sam I +Jordach +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_101.txt b/my_changes/player/skinsdb/meta/character_male_101.txt new file mode 100644 index 0000000..937768b --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_101.txt @@ -0,0 +1,4 @@ +Tuxedo Sam +Jordach +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_102.txt b/my_changes/player/skinsdb/meta/character_male_102.txt new file mode 100644 index 0000000..8e81e63 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_102.txt @@ -0,0 +1,4 @@ +philipbenr +philipbenr +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_103.txt b/my_changes/player/skinsdb/meta/character_male_103.txt new file mode 100644 index 0000000..51733e2 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_103.txt @@ -0,0 +1,4 @@ +CaligoPL +CaligoPL +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_104.txt b/my_changes/player/skinsdb/meta/character_male_104.txt new file mode 100644 index 0000000..3740d21 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_104.txt @@ -0,0 +1,4 @@ +Hobo/Homeless person +Minetestian +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_105.txt b/my_changes/player/skinsdb/meta/character_male_105.txt new file mode 100644 index 0000000..0481e39 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_105.txt @@ -0,0 +1,4 @@ +Naruto +LuxAtheris +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_106.txt b/my_changes/player/skinsdb/meta/character_male_106.txt new file mode 100644 index 0000000..03c3665 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_106.txt @@ -0,0 +1,4 @@ +lordphoenixmh +lordphoenixmh +CC BY 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_107.txt b/my_changes/player/skinsdb/meta/character_male_107.txt new file mode 100644 index 0000000..91daeda --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_107.txt @@ -0,0 +1,4 @@ +4°district +Ferdi Napoli +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_108.txt b/my_changes/player/skinsdb/meta/character_male_108.txt new file mode 100644 index 0000000..6587603 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_108.txt @@ -0,0 +1,4 @@ +Gangnam Style +Ferdi Napoli +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_109.txt b/my_changes/player/skinsdb/meta/character_male_109.txt new file mode 100644 index 0000000..e6dcf85 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_109.txt @@ -0,0 +1,4 @@ +Finn The Adventured +Ferdi Napoli +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_110.txt b/my_changes/player/skinsdb/meta/character_male_110.txt new file mode 100644 index 0000000..f59d490 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_110.txt @@ -0,0 +1,4 @@ +Seth Rollins +Ferdi Napoli +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_111.txt b/my_changes/player/skinsdb/meta/character_male_111.txt new file mode 100644 index 0000000..6c334c0 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_111.txt @@ -0,0 +1,4 @@ +Jesus +Ferdi Napoli +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_112.txt b/my_changes/player/skinsdb/meta/character_male_112.txt new file mode 100644 index 0000000..4ea8c3f --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_112.txt @@ -0,0 +1,4 @@ +Renan123 +sou o melhor +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_113.txt b/my_changes/player/skinsdb/meta/character_male_113.txt new file mode 100644 index 0000000..9acdaac --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_113.txt @@ -0,0 +1,4 @@ +Finnzzin +João Neto +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_114.txt b/my_changes/player/skinsdb/meta/character_male_114.txt new file mode 100644 index 0000000..c70ddbd --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_114.txt @@ -0,0 +1,4 @@ +DanTDM +hansuke123 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_115.txt b/my_changes/player/skinsdb/meta/character_male_115.txt new file mode 100644 index 0000000..84145d8 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_115.txt @@ -0,0 +1,4 @@ +Esteban +Esteban +CC BY-NC-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_116.txt b/my_changes/player/skinsdb/meta/character_male_116.txt new file mode 100644 index 0000000..3bdbda6 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_116.txt @@ -0,0 +1,4 @@ +Akatsuki sasuke +bajanhgk +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_117.txt b/my_changes/player/skinsdb/meta/character_male_117.txt new file mode 100644 index 0000000..98ae9c0 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_117.txt @@ -0,0 +1,4 @@ +Notch +bajanhgk +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_118.txt b/my_changes/player/skinsdb/meta/character_male_118.txt new file mode 100644 index 0000000..63ee79a --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_118.txt @@ -0,0 +1,4 @@ +WindHero +HeroOfTheWinds +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_119.txt b/my_changes/player/skinsdb/meta/character_male_119.txt new file mode 100644 index 0000000..4ad399d --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_119.txt @@ -0,0 +1,4 @@ +Hunky Simon with Jacket +Andromeda +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_120.txt b/my_changes/player/skinsdb/meta/character_male_120.txt new file mode 100644 index 0000000..e752c25 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_120.txt @@ -0,0 +1,4 @@ +Red-brown-shirt-dude +Krock +CC BY-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_121.txt b/my_changes/player/skinsdb/meta/character_male_121.txt new file mode 100644 index 0000000..e5dbeee --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_121.txt @@ -0,0 +1,4 @@ +Bangarng Kid +hansuke123 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_122.txt b/my_changes/player/skinsdb/meta/character_male_122.txt new file mode 100644 index 0000000..28c53b4 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_122.txt @@ -0,0 +1,4 @@ +Oliver_MV +hansuke123 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_123.txt b/my_changes/player/skinsdb/meta/character_male_123.txt new file mode 100644 index 0000000..cdd7493 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_123.txt @@ -0,0 +1,4 @@ +Nero +Nero3605 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_124.txt b/my_changes/player/skinsdb/meta/character_male_124.txt new file mode 100644 index 0000000..d3bea19 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_124.txt @@ -0,0 +1,4 @@ +take bake the night sensei +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_125.txt b/my_changes/player/skinsdb/meta/character_male_125.txt new file mode 100644 index 0000000..0964bb5 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_125.txt @@ -0,0 +1,4 @@ +take bake the night studant +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_126.txt b/my_changes/player/skinsdb/meta/character_male_126.txt new file mode 100644 index 0000000..5107ae9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_126.txt @@ -0,0 +1,4 @@ +dwarf from lottmob +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_127.txt b/my_changes/player/skinsdb/meta/character_male_127.txt new file mode 100644 index 0000000..b2c9701 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_127.txt @@ -0,0 +1,4 @@ +elf from lottmob +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_128.txt b/my_changes/player/skinsdb/meta/character_male_128.txt new file mode 100644 index 0000000..8b02cf7 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_128.txt @@ -0,0 +1,4 @@ +Sokomine +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_129.txt b/my_changes/player/skinsdb/meta/character_male_129.txt new file mode 100644 index 0000000..2d859c4 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_129.txt @@ -0,0 +1,4 @@ +the 10the doctor +lovehart +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_130.txt b/my_changes/player/skinsdb/meta/character_male_130.txt new file mode 100644 index 0000000..9b7ece7 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_130.txt @@ -0,0 +1,4 @@ +Michal VonFlynee +Michal VonFlynee +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_131.txt b/my_changes/player/skinsdb/meta/character_male_131.txt new file mode 100644 index 0000000..a12f21d --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_131.txt @@ -0,0 +1,4 @@ +nman3600 +nman3600 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_132.txt b/my_changes/player/skinsdb/meta/character_male_132.txt new file mode 100644 index 0000000..4c9cc82 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_132.txt @@ -0,0 +1,4 @@ +war-sloop +ange_black69 +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_133.txt b/my_changes/player/skinsdb/meta/character_male_133.txt new file mode 100644 index 0000000..82ef8f7 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_133.txt @@ -0,0 +1,4 @@ +Doctor Sam +unknown +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_male_134.txt b/my_changes/player/skinsdb/meta/character_male_134.txt new file mode 100644 index 0000000..fe726b1 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_134.txt @@ -0,0 +1,4 @@ +Esteban II (Cape Version) +Esteban +CC BY-NC-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_135.txt b/my_changes/player/skinsdb/meta/character_male_135.txt new file mode 100644 index 0000000..e9d8ee3 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_135.txt @@ -0,0 +1,4 @@ +Link +mastersword +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_136.txt b/my_changes/player/skinsdb/meta/character_male_136.txt new file mode 100644 index 0000000..4de2bf1 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_136.txt @@ -0,0 +1,4 @@ +NejWolf +NejWolf +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_137.txt b/my_changes/player/skinsdb/meta/character_male_137.txt new file mode 100644 index 0000000..76ac7da --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_137.txt @@ -0,0 +1,4 @@ +Lyoligamer +LyoliGamer +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_male_138.txt b/my_changes/player/skinsdb/meta/character_male_138.txt new file mode 100644 index 0000000..6ada3a8 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_138.txt @@ -0,0 +1,4 @@ +MBB +MBB +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_139.txt b/my_changes/player/skinsdb/meta/character_male_139.txt new file mode 100644 index 0000000..8929830 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_139.txt @@ -0,0 +1,4 @@ +FisherX +I come from Norway +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_140.txt b/my_changes/player/skinsdb/meta/character_male_140.txt new file mode 100644 index 0000000..32f0161 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_140.txt @@ -0,0 +1,4 @@ +Onyx +onyx58 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_141.txt b/my_changes/player/skinsdb/meta/character_male_141.txt new file mode 100644 index 0000000..51ea2c3 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_141.txt @@ -0,0 +1,4 @@ +vangleidson +Vangleidson Extreme +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_142.txt b/my_changes/player/skinsdb/meta/character_male_142.txt new file mode 100644 index 0000000..ba24f79 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_142.txt @@ -0,0 +1,4 @@ +Mr Business +Gold +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_143.txt b/my_changes/player/skinsdb/meta/character_male_143.txt new file mode 100644 index 0000000..313f477 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_143.txt @@ -0,0 +1,4 @@ +Pikachu Boy +ElMehdiBen +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_144.txt b/my_changes/player/skinsdb/meta/character_male_144.txt new file mode 100644 index 0000000..7f373c6 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_144.txt @@ -0,0 +1,4 @@ +chico blanco +daniel pereira +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_145.txt b/my_changes/player/skinsdb/meta/character_male_145.txt new file mode 100644 index 0000000..d22e81f --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_145.txt @@ -0,0 +1,4 @@ +Near +TheGamer +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_146.txt b/my_changes/player/skinsdb/meta/character_male_146.txt new file mode 100644 index 0000000..9f5f74e --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_146.txt @@ -0,0 +1,4 @@ +abu +anon +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_male_147.txt b/my_changes/player/skinsdb/meta/character_male_147.txt new file mode 100644 index 0000000..9ab607e --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_147.txt @@ -0,0 +1,4 @@ +Male +TenPlus1 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_148.txt b/my_changes/player/skinsdb/meta/character_male_148.txt new file mode 100644 index 0000000..ffe841f --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_148.txt @@ -0,0 +1,4 @@ +MCL 2 Skin +MineClone MC Skins +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_149.txt b/my_changes/player/skinsdb/meta/character_male_149.txt new file mode 100644 index 0000000..d9d26a9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_149.txt @@ -0,0 +1,4 @@ +The Green Wizard +Extex +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_150.txt b/my_changes/player/skinsdb/meta/character_male_150.txt new file mode 100644 index 0000000..dd4160c --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_150.txt @@ -0,0 +1,4 @@ +Duke Nukem +unknown +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_151.txt b/my_changes/player/skinsdb/meta/character_male_151.txt new file mode 100644 index 0000000..72164b1 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_151.txt @@ -0,0 +1,4 @@ +Mumbo Jumbo +Miniontoby +CC BY-NC-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_male_152.txt b/my_changes/player/skinsdb/meta/character_male_152.txt new file mode 100644 index 0000000..859af30 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_152.txt @@ -0,0 +1,4 @@ +Scientist 2 +duckduck +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_male_153.txt b/my_changes/player/skinsdb/meta/character_male_153.txt new file mode 100644 index 0000000..b5b1542 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_153.txt @@ -0,0 +1,4 @@ +SirYakari with clothes +SirYakari +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_male_154.txt b/my_changes/player/skinsdb/meta/character_male_154.txt new file mode 100644 index 0000000..c4731e7 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_male_154.txt @@ -0,0 +1,4 @@ +SirYakari without clothes +SirYakari +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_xcost_200.txt b/my_changes/player/skinsdb/meta/character_xcost_200.txt new file mode 100644 index 0000000..00b0098 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_200.txt @@ -0,0 +1,4 @@ +viv100 +viv100 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_201.txt b/my_changes/player/skinsdb/meta/character_xcost_201.txt new file mode 100644 index 0000000..dc82402 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_201.txt @@ -0,0 +1,4 @@ +AMMOnym +AMMOnym +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_202.txt b/my_changes/player/skinsdb/meta/character_xcost_202.txt new file mode 100644 index 0000000..6707a11 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_202.txt @@ -0,0 +1,4 @@ +SuperSam +AMMOnym +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_203.txt b/my_changes/player/skinsdb/meta/character_xcost_203.txt new file mode 100644 index 0000000..a5093bc --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_203.txt @@ -0,0 +1,4 @@ +santa +jordan4ibanez +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_204.txt b/my_changes/player/skinsdb/meta/character_xcost_204.txt new file mode 100644 index 0000000..e7e2a72 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_204.txt @@ -0,0 +1,4 @@ +Golden Knight +Nero3605 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_205.txt b/my_changes/player/skinsdb/meta/character_xcost_205.txt new file mode 100644 index 0000000..fb9a367 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_205.txt @@ -0,0 +1,4 @@ +Wii +ClotsPlays +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_206.txt b/my_changes/player/skinsdb/meta/character_xcost_206.txt new file mode 100644 index 0000000..8e8f0f9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_206.txt @@ -0,0 +1,4 @@ +Batman +unknown +CC BY 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_207.txt b/my_changes/player/skinsdb/meta/character_xcost_207.txt new file mode 100644 index 0000000..ba1a8b5 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_207.txt @@ -0,0 +1,4 @@ +Sam Angel +WidDos +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_208.txt b/my_changes/player/skinsdb/meta/character_xcost_208.txt new file mode 100644 index 0000000..f8cdea8 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_208.txt @@ -0,0 +1,4 @@ +King Sam +Gabo +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_209.txt b/my_changes/player/skinsdb/meta/character_xcost_209.txt new file mode 100644 index 0000000..d1621de --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_209.txt @@ -0,0 +1,4 @@ +RoboCop +Malarif +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_210.txt b/my_changes/player/skinsdb/meta/character_xcost_210.txt new file mode 100644 index 0000000..d5d303a --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_210.txt @@ -0,0 +1,4 @@ +star war +edwar masterchieft YT +CC BY-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_211.txt b/my_changes/player/skinsdb/meta/character_xcost_211.txt new file mode 100644 index 0000000..6bb67a6 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_211.txt @@ -0,0 +1,4 @@ +WW2 Reich Soldier +Guitarbro_ +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_xcost_212.txt b/my_changes/player/skinsdb/meta/character_xcost_212.txt new file mode 100644 index 0000000..1680a26 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_212.txt @@ -0,0 +1,4 @@ +Soldier +jmf +CC 0 (1.0) + diff --git a/my_changes/player/skinsdb/meta/character_xcost_213.txt b/my_changes/player/skinsdb/meta/character_xcost_213.txt new file mode 100644 index 0000000..06dcc3e --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_213.txt @@ -0,0 +1,4 @@ +KyloRen +KyloRen +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_214.txt b/my_changes/player/skinsdb/meta/character_xcost_214.txt new file mode 100644 index 0000000..2a87a39 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_214.txt @@ -0,0 +1,4 @@ +deadpool +skrullox13 +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_215.txt b/my_changes/player/skinsdb/meta/character_xcost_215.txt new file mode 100644 index 0000000..a8e813c --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_215.txt @@ -0,0 +1,4 @@ +Ashley +loupicate +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_216.txt b/my_changes/player/skinsdb/meta/character_xcost_216.txt new file mode 100644 index 0000000..876d63c --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_216.txt @@ -0,0 +1,4 @@ +Male angel +loupicate +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_217.txt b/my_changes/player/skinsdb/meta/character_xcost_217.txt new file mode 100644 index 0000000..3151c12 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_217.txt @@ -0,0 +1,4 @@ +Police Officer +maruyuki +CC BY-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_218.txt b/my_changes/player/skinsdb/meta/character_xcost_218.txt new file mode 100644 index 0000000..9872e9e --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_218.txt @@ -0,0 +1,4 @@ +Cap +Christopher Tamuklevich +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_219.txt b/my_changes/player/skinsdb/meta/character_xcost_219.txt new file mode 100644 index 0000000..95b9079 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_219.txt @@ -0,0 +1,4 @@ +iron man(skin iron man 2) +julito +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_220.txt b/my_changes/player/skinsdb/meta/character_xcost_220.txt new file mode 100644 index 0000000..e48e02a --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_220.txt @@ -0,0 +1,4 @@ +TheFlash +julito +CC BY-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_221.txt b/my_changes/player/skinsdb/meta/character_xcost_221.txt new file mode 100644 index 0000000..b903459 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_221.txt @@ -0,0 +1,4 @@ +zm78(old skully) +zm78(experiminer) +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_222.txt b/my_changes/player/skinsdb/meta/character_xcost_222.txt new file mode 100644 index 0000000..b4ba922 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_222.txt @@ -0,0 +1,4 @@ +King Arthur +TMSB aka Dragoni or Dragon-ManioNM +CC BY-NC-SA 4.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_223.txt b/my_changes/player/skinsdb/meta/character_xcost_223.txt new file mode 100644 index 0000000..35ae998 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_223.txt @@ -0,0 +1,4 @@ +StormTrooper +unknown +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_224.txt b/my_changes/player/skinsdb/meta/character_xcost_224.txt new file mode 100644 index 0000000..952ad66 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_224.txt @@ -0,0 +1,4 @@ +Chewie +LordTrilobite +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_225.txt b/my_changes/player/skinsdb/meta/character_xcost_225.txt new file mode 100644 index 0000000..f1c1ce9 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_225.txt @@ -0,0 +1,4 @@ +Darth Vader +halucid +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_226.txt b/my_changes/player/skinsdb/meta/character_xcost_226.txt new file mode 100644 index 0000000..501ceef --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_226.txt @@ -0,0 +1,4 @@ +Ducky +Queen_HD_ +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_227.txt b/my_changes/player/skinsdb/meta/character_xcost_227.txt new file mode 100644 index 0000000..0acccb8 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_227.txt @@ -0,0 +1,4 @@ +Frodo +Frodo +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_228.txt b/my_changes/player/skinsdb/meta/character_xcost_228.txt new file mode 100644 index 0000000..2ea62af --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_228.txt @@ -0,0 +1,4 @@ +Man +unknown +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_229.txt b/my_changes/player/skinsdb/meta/character_xcost_229.txt new file mode 100644 index 0000000..4293326 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_229.txt @@ -0,0 +1,4 @@ +Elf +unknown +CC BY-SA 3.0 + diff --git a/my_changes/player/skinsdb/meta/character_xcost_230.txt b/my_changes/player/skinsdb/meta/character_xcost_230.txt new file mode 100644 index 0000000..28980d0 --- /dev/null +++ b/my_changes/player/skinsdb/meta/character_xcost_230.txt @@ -0,0 +1,4 @@ +LUCAS +LUCAS +CC BY-NC-SA 3.0 + diff --git a/my_changes/player/skinsdb/textures/character_female_1.png b/my_changes/player/skinsdb/textures/character_female_1.png new file mode 100644 index 0000000..0bda626 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_1.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_10.png b/my_changes/player/skinsdb/textures/character_female_10.png new file mode 100644 index 0000000..aac13dc Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_10.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_11.png b/my_changes/player/skinsdb/textures/character_female_11.png new file mode 100644 index 0000000..1d9079e Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_11.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_12.png b/my_changes/player/skinsdb/textures/character_female_12.png new file mode 100644 index 0000000..dcb3484 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_12.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_13.png b/my_changes/player/skinsdb/textures/character_female_13.png new file mode 100644 index 0000000..3d685cc Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_13.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_14.png b/my_changes/player/skinsdb/textures/character_female_14.png new file mode 100644 index 0000000..287293c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_14.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_15.png b/my_changes/player/skinsdb/textures/character_female_15.png new file mode 100644 index 0000000..3194a39 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_15.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_16.png b/my_changes/player/skinsdb/textures/character_female_16.png new file mode 100644 index 0000000..d7fa112 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_16.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_17.png b/my_changes/player/skinsdb/textures/character_female_17.png new file mode 100644 index 0000000..210a17b Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_17.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_18.png b/my_changes/player/skinsdb/textures/character_female_18.png new file mode 100644 index 0000000..6333261 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_18.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_19.png b/my_changes/player/skinsdb/textures/character_female_19.png new file mode 100644 index 0000000..a185472 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_19.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_2.png b/my_changes/player/skinsdb/textures/character_female_2.png new file mode 100644 index 0000000..76e141c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_2.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_20.png b/my_changes/player/skinsdb/textures/character_female_20.png new file mode 100644 index 0000000..3f2f083 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_20.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_21.png b/my_changes/player/skinsdb/textures/character_female_21.png new file mode 100644 index 0000000..f0b3adf Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_21.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_22.png b/my_changes/player/skinsdb/textures/character_female_22.png new file mode 100644 index 0000000..d6855af Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_22.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_23.png b/my_changes/player/skinsdb/textures/character_female_23.png new file mode 100644 index 0000000..ff05359 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_23.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_24.png b/my_changes/player/skinsdb/textures/character_female_24.png new file mode 100644 index 0000000..5fb4c4c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_24.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_25.png b/my_changes/player/skinsdb/textures/character_female_25.png new file mode 100644 index 0000000..52fce3c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_25.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_26.png b/my_changes/player/skinsdb/textures/character_female_26.png new file mode 100644 index 0000000..621ac7d Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_26.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_27.png b/my_changes/player/skinsdb/textures/character_female_27.png new file mode 100644 index 0000000..ff707ad Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_27.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_28.png b/my_changes/player/skinsdb/textures/character_female_28.png new file mode 100644 index 0000000..feb6a0d Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_28.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_29.png b/my_changes/player/skinsdb/textures/character_female_29.png new file mode 100644 index 0000000..599f656 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_29.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_3.png b/my_changes/player/skinsdb/textures/character_female_3.png new file mode 100644 index 0000000..a1c44e1 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_3.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_30.png b/my_changes/player/skinsdb/textures/character_female_30.png new file mode 100644 index 0000000..9c799b8 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_30.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_31.png b/my_changes/player/skinsdb/textures/character_female_31.png new file mode 100644 index 0000000..4b37bb8 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_31.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_32.png b/my_changes/player/skinsdb/textures/character_female_32.png new file mode 100644 index 0000000..38b9dea Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_32.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_33.png b/my_changes/player/skinsdb/textures/character_female_33.png new file mode 100644 index 0000000..cc56457 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_33.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_34.png b/my_changes/player/skinsdb/textures/character_female_34.png new file mode 100644 index 0000000..fe2bc4f Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_34.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_35.png b/my_changes/player/skinsdb/textures/character_female_35.png new file mode 100644 index 0000000..a88dcb2 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_35.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_36.png b/my_changes/player/skinsdb/textures/character_female_36.png new file mode 100644 index 0000000..8162734 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_36.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_37.png b/my_changes/player/skinsdb/textures/character_female_37.png new file mode 100644 index 0000000..b644f96 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_37.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_38.png b/my_changes/player/skinsdb/textures/character_female_38.png new file mode 100644 index 0000000..626f3b8 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_38.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_39.png b/my_changes/player/skinsdb/textures/character_female_39.png new file mode 100644 index 0000000..e0cad94 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_39.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_4.png b/my_changes/player/skinsdb/textures/character_female_4.png new file mode 100644 index 0000000..4900d5b Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_4.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_40.png b/my_changes/player/skinsdb/textures/character_female_40.png new file mode 100644 index 0000000..7460615 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_40.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_41.png b/my_changes/player/skinsdb/textures/character_female_41.png new file mode 100644 index 0000000..46ec824 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_41.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_42.png b/my_changes/player/skinsdb/textures/character_female_42.png new file mode 100644 index 0000000..3869c2d Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_42.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_43.png b/my_changes/player/skinsdb/textures/character_female_43.png new file mode 100644 index 0000000..fdb43e2 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_43.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_44.png b/my_changes/player/skinsdb/textures/character_female_44.png new file mode 100644 index 0000000..109e1c3 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_44.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_45.png b/my_changes/player/skinsdb/textures/character_female_45.png new file mode 100644 index 0000000..7357214 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_45.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_46.png b/my_changes/player/skinsdb/textures/character_female_46.png new file mode 100644 index 0000000..0efe414 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_46.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_47.png b/my_changes/player/skinsdb/textures/character_female_47.png new file mode 100644 index 0000000..d61d392 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_47.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_48.png b/my_changes/player/skinsdb/textures/character_female_48.png new file mode 100644 index 0000000..78a12b4 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_48.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_49.png b/my_changes/player/skinsdb/textures/character_female_49.png new file mode 100644 index 0000000..2ce273f Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_49.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_5.png b/my_changes/player/skinsdb/textures/character_female_5.png new file mode 100644 index 0000000..4c3eb3d Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_5.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_50.png b/my_changes/player/skinsdb/textures/character_female_50.png new file mode 100644 index 0000000..f1c7ee3 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_50.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_51.png b/my_changes/player/skinsdb/textures/character_female_51.png new file mode 100644 index 0000000..1c46d24 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_51.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_52.png b/my_changes/player/skinsdb/textures/character_female_52.png new file mode 100644 index 0000000..715fff0 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_52.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_53.png b/my_changes/player/skinsdb/textures/character_female_53.png new file mode 100644 index 0000000..7298777 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_53.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_54.png b/my_changes/player/skinsdb/textures/character_female_54.png new file mode 100644 index 0000000..2a36f45 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_54.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_55.png b/my_changes/player/skinsdb/textures/character_female_55.png new file mode 100644 index 0000000..100d33d Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_55.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_6.png b/my_changes/player/skinsdb/textures/character_female_6.png new file mode 100644 index 0000000..1c5043d Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_6.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_7.png b/my_changes/player/skinsdb/textures/character_female_7.png new file mode 100644 index 0000000..058b4c6 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_7.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_8.png b/my_changes/player/skinsdb/textures/character_female_8.png new file mode 100644 index 0000000..3c7fa36 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_8.png differ diff --git a/my_changes/player/skinsdb/textures/character_female_9.png b/my_changes/player/skinsdb/textures/character_female_9.png new file mode 100644 index 0000000..8b0fe27 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_female_9.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_100.png b/my_changes/player/skinsdb/textures/character_male_100.png new file mode 100644 index 0000000..45e42a9 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_100.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_101.png b/my_changes/player/skinsdb/textures/character_male_101.png new file mode 100644 index 0000000..d45c82e Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_101.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_102.png b/my_changes/player/skinsdb/textures/character_male_102.png new file mode 100644 index 0000000..f56dc34 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_102.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_103.png b/my_changes/player/skinsdb/textures/character_male_103.png new file mode 100644 index 0000000..2dbed8c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_103.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_104.png b/my_changes/player/skinsdb/textures/character_male_104.png new file mode 100644 index 0000000..2d6e508 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_104.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_105.png b/my_changes/player/skinsdb/textures/character_male_105.png new file mode 100644 index 0000000..fb65e85 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_105.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_106.png b/my_changes/player/skinsdb/textures/character_male_106.png new file mode 100644 index 0000000..840ff1b Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_106.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_107.png b/my_changes/player/skinsdb/textures/character_male_107.png new file mode 100644 index 0000000..80c4537 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_107.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_108.png b/my_changes/player/skinsdb/textures/character_male_108.png new file mode 100644 index 0000000..90057f5 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_108.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_109.png b/my_changes/player/skinsdb/textures/character_male_109.png new file mode 100644 index 0000000..790e7d1 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_109.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_110.png b/my_changes/player/skinsdb/textures/character_male_110.png new file mode 100644 index 0000000..8833c60 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_110.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_111.png b/my_changes/player/skinsdb/textures/character_male_111.png new file mode 100644 index 0000000..d55aa6a Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_111.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_112.png b/my_changes/player/skinsdb/textures/character_male_112.png new file mode 100644 index 0000000..09bc2c3 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_112.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_113.png b/my_changes/player/skinsdb/textures/character_male_113.png new file mode 100644 index 0000000..2760c83 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_113.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_114.png b/my_changes/player/skinsdb/textures/character_male_114.png new file mode 100644 index 0000000..1b16d08 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_114.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_115.png b/my_changes/player/skinsdb/textures/character_male_115.png new file mode 100644 index 0000000..706b61a Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_115.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_116.png b/my_changes/player/skinsdb/textures/character_male_116.png new file mode 100644 index 0000000..c875574 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_116.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_117.png b/my_changes/player/skinsdb/textures/character_male_117.png new file mode 100644 index 0000000..d3c3aa1 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_117.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_118.png b/my_changes/player/skinsdb/textures/character_male_118.png new file mode 100644 index 0000000..88597a6 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_118.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_119.png b/my_changes/player/skinsdb/textures/character_male_119.png new file mode 100644 index 0000000..b981f8e Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_119.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_120.png b/my_changes/player/skinsdb/textures/character_male_120.png new file mode 100644 index 0000000..8255a2b Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_120.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_121.png b/my_changes/player/skinsdb/textures/character_male_121.png new file mode 100644 index 0000000..28c64d9 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_121.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_122.png b/my_changes/player/skinsdb/textures/character_male_122.png new file mode 100644 index 0000000..7d42e09 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_122.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_123.png b/my_changes/player/skinsdb/textures/character_male_123.png new file mode 100644 index 0000000..664f961 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_123.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_124.png b/my_changes/player/skinsdb/textures/character_male_124.png new file mode 100644 index 0000000..aa612fa Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_124.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_125.png b/my_changes/player/skinsdb/textures/character_male_125.png new file mode 100644 index 0000000..9ded604 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_125.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_126.png b/my_changes/player/skinsdb/textures/character_male_126.png new file mode 100644 index 0000000..bcbd42c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_126.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_127.png b/my_changes/player/skinsdb/textures/character_male_127.png new file mode 100644 index 0000000..bc2c751 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_127.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_128.png b/my_changes/player/skinsdb/textures/character_male_128.png new file mode 100644 index 0000000..6bd9175 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_128.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_129.png b/my_changes/player/skinsdb/textures/character_male_129.png new file mode 100644 index 0000000..232c8ec Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_129.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_130.png b/my_changes/player/skinsdb/textures/character_male_130.png new file mode 100644 index 0000000..137d2e4 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_130.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_131.png b/my_changes/player/skinsdb/textures/character_male_131.png new file mode 100644 index 0000000..16709b9 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_131.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_132.png b/my_changes/player/skinsdb/textures/character_male_132.png new file mode 100644 index 0000000..6ba7a65 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_132.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_133.png b/my_changes/player/skinsdb/textures/character_male_133.png new file mode 100644 index 0000000..9d650b3 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_133.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_134.png b/my_changes/player/skinsdb/textures/character_male_134.png new file mode 100644 index 0000000..6de2fae Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_134.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_135.png b/my_changes/player/skinsdb/textures/character_male_135.png new file mode 100644 index 0000000..5b98909 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_135.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_136.png b/my_changes/player/skinsdb/textures/character_male_136.png new file mode 100644 index 0000000..8ab356c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_136.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_137.png b/my_changes/player/skinsdb/textures/character_male_137.png new file mode 100644 index 0000000..1678778 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_137.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_138.png b/my_changes/player/skinsdb/textures/character_male_138.png new file mode 100644 index 0000000..50cba98 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_138.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_139.png b/my_changes/player/skinsdb/textures/character_male_139.png new file mode 100644 index 0000000..4b34122 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_139.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_140.png b/my_changes/player/skinsdb/textures/character_male_140.png new file mode 100644 index 0000000..6ddb8ae Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_140.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_141.png b/my_changes/player/skinsdb/textures/character_male_141.png new file mode 100644 index 0000000..7d18c95 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_141.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_142.png b/my_changes/player/skinsdb/textures/character_male_142.png new file mode 100644 index 0000000..b262b13 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_142.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_143.png b/my_changes/player/skinsdb/textures/character_male_143.png new file mode 100644 index 0000000..905c89a Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_143.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_144.png b/my_changes/player/skinsdb/textures/character_male_144.png new file mode 100644 index 0000000..d5d207c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_144.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_145.png b/my_changes/player/skinsdb/textures/character_male_145.png new file mode 100644 index 0000000..b8f69fc Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_145.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_146.png b/my_changes/player/skinsdb/textures/character_male_146.png new file mode 100644 index 0000000..c0de766 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_146.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_147.png b/my_changes/player/skinsdb/textures/character_male_147.png new file mode 100644 index 0000000..9356398 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_147.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_148.png b/my_changes/player/skinsdb/textures/character_male_148.png new file mode 100644 index 0000000..8bf839e Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_148.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_149.png b/my_changes/player/skinsdb/textures/character_male_149.png new file mode 100644 index 0000000..860b4bd Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_149.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_150.png b/my_changes/player/skinsdb/textures/character_male_150.png new file mode 100644 index 0000000..e621095 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_150.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_151.png b/my_changes/player/skinsdb/textures/character_male_151.png new file mode 100644 index 0000000..f6accd4 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_151.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_152.png b/my_changes/player/skinsdb/textures/character_male_152.png new file mode 100644 index 0000000..d116937 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_152.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_153.png b/my_changes/player/skinsdb/textures/character_male_153.png new file mode 100644 index 0000000..9532587 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_153.png differ diff --git a/my_changes/player/skinsdb/textures/character_male_154.png b/my_changes/player/skinsdb/textures/character_male_154.png new file mode 100644 index 0000000..75687b4 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_male_154.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_200.png b/my_changes/player/skinsdb/textures/character_xcost_200.png new file mode 100644 index 0000000..f7fa1cc Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_200.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_201.png b/my_changes/player/skinsdb/textures/character_xcost_201.png new file mode 100644 index 0000000..3be6e56 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_201.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_202.png b/my_changes/player/skinsdb/textures/character_xcost_202.png new file mode 100644 index 0000000..ca8b1f1 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_202.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_203.png b/my_changes/player/skinsdb/textures/character_xcost_203.png new file mode 100644 index 0000000..cc7c131 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_203.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_204.png b/my_changes/player/skinsdb/textures/character_xcost_204.png new file mode 100644 index 0000000..aed256e Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_204.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_205.png b/my_changes/player/skinsdb/textures/character_xcost_205.png new file mode 100644 index 0000000..68198c0 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_205.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_206.png b/my_changes/player/skinsdb/textures/character_xcost_206.png new file mode 100644 index 0000000..36995fd Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_206.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_207.png b/my_changes/player/skinsdb/textures/character_xcost_207.png new file mode 100644 index 0000000..359f912 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_207.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_208.png b/my_changes/player/skinsdb/textures/character_xcost_208.png new file mode 100644 index 0000000..1c8d831 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_208.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_209.png b/my_changes/player/skinsdb/textures/character_xcost_209.png new file mode 100644 index 0000000..c9f6cc8 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_209.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_210.png b/my_changes/player/skinsdb/textures/character_xcost_210.png new file mode 100644 index 0000000..ae3c022 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_210.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_211.png b/my_changes/player/skinsdb/textures/character_xcost_211.png new file mode 100644 index 0000000..37549e8 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_211.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_212.png b/my_changes/player/skinsdb/textures/character_xcost_212.png new file mode 100644 index 0000000..79ebca1 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_212.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_213.png b/my_changes/player/skinsdb/textures/character_xcost_213.png new file mode 100644 index 0000000..99839b7 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_213.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_214.png b/my_changes/player/skinsdb/textures/character_xcost_214.png new file mode 100644 index 0000000..b8d889e Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_214.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_215.png b/my_changes/player/skinsdb/textures/character_xcost_215.png new file mode 100644 index 0000000..8e834b6 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_215.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_216.png b/my_changes/player/skinsdb/textures/character_xcost_216.png new file mode 100644 index 0000000..459b523 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_216.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_217.png b/my_changes/player/skinsdb/textures/character_xcost_217.png new file mode 100644 index 0000000..2a98c7b Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_217.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_218.png b/my_changes/player/skinsdb/textures/character_xcost_218.png new file mode 100644 index 0000000..505930c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_218.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_219.png b/my_changes/player/skinsdb/textures/character_xcost_219.png new file mode 100644 index 0000000..17a675c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_219.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_220.png b/my_changes/player/skinsdb/textures/character_xcost_220.png new file mode 100644 index 0000000..7440d6c Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_220.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_221.png b/my_changes/player/skinsdb/textures/character_xcost_221.png new file mode 100644 index 0000000..4d88e98 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_221.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_222.png b/my_changes/player/skinsdb/textures/character_xcost_222.png new file mode 100644 index 0000000..8628fe2 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_222.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_223.png b/my_changes/player/skinsdb/textures/character_xcost_223.png new file mode 100644 index 0000000..a2053ad Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_223.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_224.png b/my_changes/player/skinsdb/textures/character_xcost_224.png new file mode 100644 index 0000000..2046d96 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_224.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_225.png b/my_changes/player/skinsdb/textures/character_xcost_225.png new file mode 100644 index 0000000..c55b7f0 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_225.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_226.png b/my_changes/player/skinsdb/textures/character_xcost_226.png new file mode 100644 index 0000000..a7b5739 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_226.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_227.png b/my_changes/player/skinsdb/textures/character_xcost_227.png new file mode 100644 index 0000000..0822f2e Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_227.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_228.png b/my_changes/player/skinsdb/textures/character_xcost_228.png new file mode 100644 index 0000000..a0cacbd Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_228.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_229.png b/my_changes/player/skinsdb/textures/character_xcost_229.png new file mode 100644 index 0000000..d1883e1 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_229.png differ diff --git a/my_changes/player/skinsdb/textures/character_xcost_230.png b/my_changes/player/skinsdb/textures/character_xcost_230.png new file mode 100644 index 0000000..f2eb220 Binary files /dev/null and b/my_changes/player/skinsdb/textures/character_xcost_230.png differ