forked from MineClone5/MineClone5
#363 Flush transitional merge (might be overwritten)
This commit is contained in:
parent
56ab442645
commit
a6b20364a3
|
@ -1,2 +1,5 @@
|
||||||
# Text Editor TMP Files
|
# Text Editor TMP Files
|
||||||
*.swp
|
*.swp
|
||||||
|
*.blend1
|
||||||
|
*.blend2
|
||||||
|
*.blend3
|
||||||
|
|
2
API.md
2
API.md
|
@ -42,7 +42,7 @@ A lot of things are possible by using one of the APIs in the mods. Note that not
|
||||||
* Buckets: `ITEMS/mcl_buckets`
|
* Buckets: `ITEMS/mcl_buckets`
|
||||||
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
||||||
|
|
||||||
## Mobs
|
### Mobs
|
||||||
* Mobs: `ENTITIES/mcl_mobs`
|
* Mobs: `ENTITIES/mcl_mobs`
|
||||||
|
|
||||||
MineClone 5 uses its own mobs framework, called “Mobs Redo: MineClone 5 Edition” or “MRM” for short.
|
MineClone 5 uses its own mobs framework, called “Mobs Redo: MineClone 5 Edition” or “MRM” for short.
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
# Contributor Covenant Code of Conduct
|
|
||||||
|
|
||||||
## Our Pledge
|
|
||||||
|
|
||||||
We as members, contributors, and leaders pledge to make participation in our
|
|
||||||
community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
||||||
identity and expression, level of experience, education, socio-economic status,
|
|
||||||
nationality, personal appearance, race, religion, or sexual identity
|
|
||||||
and orientation.
|
|
||||||
|
|
||||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
||||||
diverse, inclusive, and healthy community.
|
|
||||||
|
|
||||||
## Our Standards
|
|
||||||
|
|
||||||
Examples of behavior that contributes to a positive environment for our
|
|
||||||
community include:
|
|
||||||
|
|
||||||
* Demonstrating empathy and kindness toward other people
|
|
||||||
* Being respectful of differing opinions, viewpoints, and experiences
|
|
||||||
* Giving and gracefully accepting constructive feedback
|
|
||||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
||||||
and learning from the experience
|
|
||||||
* Focusing on what is best not just for us as individuals, but for the
|
|
||||||
overall community
|
|
||||||
|
|
||||||
Examples of unacceptable behavior include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery, and sexual attention or
|
|
||||||
advances of any kind
|
|
||||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing others' private information, such as a physical or email
|
|
||||||
address, without their explicit permission
|
|
||||||
* Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
|
||||||
|
|
||||||
Community leaders are responsible for clarifying and enforcing our standards of
|
|
||||||
acceptable behavior and will take appropriate and fair corrective action in
|
|
||||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
||||||
or harmful.
|
|
||||||
|
|
||||||
Community leaders have the right and responsibility to remove, edit, or reject
|
|
||||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
||||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
||||||
decisions when appropriate.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
This Code of Conduct applies within all community spaces, and also applies when
|
|
||||||
an individual is officially representing the community in public spaces.
|
|
||||||
Examples of representing our community include using an official e-mail address,
|
|
||||||
posting via an official social media account, or acting as an appointed
|
|
||||||
representative at an online or offline event.
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
||||||
reported to the community leaders responsible for enforcement at
|
|
||||||
eliasfleckenstein@web.de.
|
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
|
||||||
reporter of any incident.
|
|
||||||
|
|
||||||
## Enforcement Guidelines
|
|
||||||
|
|
||||||
Community leaders will follow these Community Impact Guidelines in determining
|
|
||||||
the consequences for any action they deem in violation of this Code of Conduct:
|
|
||||||
|
|
||||||
### 1. Correction
|
|
||||||
|
|
||||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
||||||
unprofessional or unwelcome in the community.
|
|
||||||
|
|
||||||
**Consequence**: A private, written warning from community leaders, providing
|
|
||||||
clarity around the nature of the violation and an explanation of why the
|
|
||||||
behavior was inappropriate. A public apology may be requested.
|
|
||||||
|
|
||||||
### 2. Warning
|
|
||||||
|
|
||||||
**Community Impact**: A violation through a single incident or series
|
|
||||||
of actions.
|
|
||||||
|
|
||||||
**Consequence**: A warning with consequences for continued behavior. No
|
|
||||||
interaction with the people involved, including unsolicited interaction with
|
|
||||||
those enforcing the Code of Conduct, for a specified period of time. This
|
|
||||||
includes avoiding interactions in community spaces as well as external channels
|
|
||||||
like social media. Violating these terms may lead to a temporary or
|
|
||||||
permanent ban.
|
|
||||||
|
|
||||||
### 3. Temporary Ban
|
|
||||||
|
|
||||||
**Community Impact**: A serious violation of community standards, including
|
|
||||||
sustained inappropriate behavior.
|
|
||||||
|
|
||||||
**Consequence**: A temporary ban from any sort of interaction or public
|
|
||||||
communication with the community for a specified period of time. No public or
|
|
||||||
private interaction with the people involved, including unsolicited interaction
|
|
||||||
with those enforcing the Code of Conduct, is allowed during this period.
|
|
||||||
Violating these terms may lead to a permanent ban.
|
|
||||||
|
|
||||||
### 4. Permanent Ban
|
|
||||||
|
|
||||||
**Community Impact**: Demonstrating a pattern of violation of community
|
|
||||||
standards, including sustained inappropriate behavior, harassment of an
|
|
||||||
individual, or aggression toward or disparagement of classes of individuals.
|
|
||||||
|
|
||||||
**Consequence**: A permanent ban from any sort of public interaction within
|
|
||||||
the community.
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
||||||
version 2.0, available at
|
|
||||||
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
|
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by [Mozilla's code of conduct
|
|
||||||
enforcement ladder](https://github.com/mozilla/diversity).
|
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
|
||||||
https://www.contributor-covenant.org/faq. Translations are available at
|
|
||||||
https://www.contributor-covenant.org/translations.
|
|
|
@ -41,6 +41,7 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
||||||
* `flammable=-1` Does not get destroyed by fire
|
* `flammable=-1` Does not get destroyed by fire
|
||||||
* `fire_encouragement`: How quickly this block catches fire
|
* `fire_encouragement`: How quickly this block catches fire
|
||||||
* `fire_flammability`: How fast the block will burn away
|
* `fire_flammability`: How fast the block will burn away
|
||||||
|
* `path_creation_possible=1`: Node can be turned into grass path by using a shovel on it
|
||||||
* `spreading_dirt_type=1`: A dirt-type block with a cover (e.g. grass) which may spread to neighbor dirt blocks
|
* `spreading_dirt_type=1`: A dirt-type block with a cover (e.g. grass) which may spread to neighbor dirt blocks
|
||||||
* `dirtifies_below_solid=1`: This node turns into dirt immediately when a solid or dirtifier node is placed on top
|
* `dirtifies_below_solid=1`: This node turns into dirt immediately when a solid or dirtifier node is placed on top
|
||||||
* `dirtifier=1`: This node turns nodes the above group into dirt when placed above
|
* `dirtifier=1`: This node turns nodes the above group into dirt when placed above
|
||||||
|
@ -56,6 +57,7 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
||||||
* `no_eat_delay=1`: Only for foodstuffs. When eating this, all eating delays are ignored.
|
* `no_eat_delay=1`: Only for foodstuffs. When eating this, all eating delays are ignored.
|
||||||
* `can_eat_when_full=1`: Only for foodstuffs. This item can be eaten when the user has a full hunger bar
|
* `can_eat_when_full=1`: Only for foodstuffs. This item can be eaten when the user has a full hunger bar
|
||||||
* `attached_node_facedir=1`: Like `attached_node`, but for facedir nodes
|
* `attached_node_facedir=1`: Like `attached_node`, but for facedir nodes
|
||||||
|
* `supported_node=1`: Like `attached_node`, but can be placed on any nodes that do not have the `drawtype="airlike"` attribute.
|
||||||
* `cauldron`: Cauldron. 1: Empty. 2-4: Water height
|
* `cauldron`: Cauldron. 1: Empty. 2-4: Water height
|
||||||
* `anvil`: Anvil. 1: No damage. 2-3: Higher damage levels
|
* `anvil`: Anvil. 1: No damage. 2-3: Higher damage levels
|
||||||
* `no_rename=1`: Item cannot be renamed by anvil
|
* `no_rename=1`: Item cannot be renamed by anvil
|
||||||
|
@ -71,7 +73,7 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
||||||
* `coral_block=X`: Coral block (1 = alive, 2 = dead)
|
* `coral_block=X`: Coral block (1 = alive, 2 = dead)
|
||||||
* `coral_species=X`: Specifies the species of a coral; equal X means equal species
|
* `coral_species=X`: Specifies the species of a coral; equal X means equal species
|
||||||
* `set_on_fire=X`: Sets any (not fire-resistant) mob or player on fire for X seconds when touching
|
* `set_on_fire=X`: Sets any (not fire-resistant) mob or player on fire for X seconds when touching
|
||||||
* `compostability`: Amount from 1 to 100 that defines the percentage of likelyhood that the composter will advance a level.
|
* `compostability=X`: Amount from 1 to 100 that defines the percentage of likelyhood that the composter will advance a level.
|
||||||
|
|
||||||
#### Footnotes
|
#### Footnotes
|
||||||
|
|
||||||
|
@ -100,6 +102,8 @@ Please read <http://minecraft.gamepedia.com/Breaking> to learn how digging times
|
||||||
* `water_bucket=1`: Bucket containing a liquid of group “water”
|
* `water_bucket=1`: Bucket containing a liquid of group “water”
|
||||||
* `enchantability=X`: How good the enchantments are the item gets (1 equals book)
|
* `enchantability=X`: How good the enchantments are the item gets (1 equals book)
|
||||||
* `enchanted=1`: The item is already enchanted, meaning that it can't be enchanted using an enchanting table
|
* `enchanted=1`: The item is already enchanted, meaning that it can't be enchanted using an enchanting table
|
||||||
|
* `cobble=1`: Cobblestone of any kind
|
||||||
|
* `soul_block`: Fire burning on these blocks turns to soul fire, can be used to craft soul torch
|
||||||
|
|
||||||
### Material groups
|
### Material groups
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,324 @@
|
||||||
|
# MineClone 2
|
||||||
|
一個非官方的Minetest遊戲,遊玩方式和Minecraft類似。由davedevils從MineClone分拆。
|
||||||
|
由許多人開發。並非由Mojang Studios開發。<!-- "Mojang AB"'s Name changed at 2020/05, main README should change too -->
|
||||||
|
|
||||||
|
版本:0.71.0
|
||||||
|
|
||||||
|
### 遊玩
|
||||||
|
你開始在一個完全由方塊隨機生成的世界裡。你可以探索這個世界,挖掘和建造世界上幾乎所有的方塊,以創造新的結構。你可以選擇在「生存模式」中進行遊戲,在這個模式中,你必須與怪物戰鬥,飢餓求生,並在遊戲的其他各個環節中慢慢進步,如採礦、養殖、建造機器等等。
|
||||||
|
|
||||||
|
或者你也可以在「創造模式」中玩,在這個模式中,你可以瞬間建造大部分東西。
|
||||||
|
#### Gameplay summary
|
||||||
|
|
||||||
|
* 沙盒式遊戲,沒有明確目標
|
||||||
|
* 生存:與怪物和飢餓搏鬥
|
||||||
|
* 挖礦來獲得礦物和寶物
|
||||||
|
* 附魔:獲得經驗值並以附魔強化你的工具
|
||||||
|
* 使用收集的方塊來創造偉大的建築
|
||||||
|
* 收集鮮花(和其他染料來源),令世界多姿多彩
|
||||||
|
* 找些種子並開始耕種
|
||||||
|
* 尋找或合成數百個物品之一
|
||||||
|
* 建立一個鐵路系統,並從礦車中得到樂趣
|
||||||
|
* 用紅石電路建造複雜的機器
|
||||||
|
* 在創造模式下,你幾乎可以免費建造任何東西,而且沒有限制。
|
||||||
|
|
||||||
|
## 如何開始
|
||||||
|
### 開始生存
|
||||||
|
* **挖樹幹**直到其破裂並收集木材
|
||||||
|
* 將木頭**放入2×2的格子中**(你的物品欄中的「合成格子」),然後製作4塊木材。
|
||||||
|
* 將4塊木材按2×2的形狀擺放在合成格子裡,製作成合成臺。
|
||||||
|
* **右鍵單擊製作臺**以獲得3×3製作網格,製作更複雜的東西
|
||||||
|
* 使用**合成指南**(書形圖標)了解所有可能的合成方式
|
||||||
|
* **製作一個木鎬**,這樣你就可以挖石頭了。
|
||||||
|
* 不同的工具可以打破不同種類的方塊。試試吧!
|
||||||
|
* 繼續玩你想玩的。盡情享受吧!
|
||||||
|
|
||||||
|
### 耕種
|
||||||
|
* 找到種子
|
||||||
|
* 合成鋤頭
|
||||||
|
* 用鋤頭右鍵點擊泥土或類似的方塊,創建農田
|
||||||
|
* 將種子放在農田上,看著它們長出來
|
||||||
|
* Collect plant when fully grown
|
||||||
|
* If near water, farmland becomes wet and speeds up growth
|
||||||
|
|
||||||
|
### Furnace
|
||||||
|
* Craft furnace
|
||||||
|
* Furnace allows you to obtain more items
|
||||||
|
* Upper slot must contain a smeltable item (example: iron ore)
|
||||||
|
* Lower slot must contain a fuel item (example: coal)
|
||||||
|
* See tooltips in crafting guide to learn about fuels and smeltable items
|
||||||
|
|
||||||
|
### Additional help
|
||||||
|
More help about the gameplay, blocks items and much more can be found from inside
|
||||||
|
the game. You can access the help from your inventory menu.
|
||||||
|
|
||||||
|
### Special items
|
||||||
|
The following items are interesting for Creative Mode and for adventure
|
||||||
|
map builders. They can not be obtained in-game or in the creative inventory.
|
||||||
|
|
||||||
|
* Barrier: `mcl_core:barrier`
|
||||||
|
|
||||||
|
Use the `/giveme` chat command to obtain them. See the in-game help for
|
||||||
|
an explanation.
|
||||||
|
|
||||||
|
#### Incomplete items
|
||||||
|
These items do not work yet, but you can get them with `/giveme` for testing:
|
||||||
|
|
||||||
|
* Minecart with Chest: `mcl_minecarts:chest_minecart`
|
||||||
|
* Minecart with Furnace: `mcl_minecarts:furnace_minecart`
|
||||||
|
* Minecart with Hopper: `mcl_minecarts:hopper_minecart`
|
||||||
|
* Minecart with Command Block: `mcl_minecarts:command_block_minecart`
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
This game requires [Minetest](http://minetest.net) to run (version 5.0.0 or
|
||||||
|
later). So you need to install Minetest first. Only stable versions of Minetest
|
||||||
|
are officially supported.
|
||||||
|
There is no support for running MineClone 2 in development versions of Minetest.
|
||||||
|
|
||||||
|
To install MineClone 2 (if you haven't already), move this directory into the
|
||||||
|
“games” directory of your Minetest data directory. Consult the help of
|
||||||
|
Minetest to learn more.
|
||||||
|
|
||||||
|
## Project description
|
||||||
|
The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software.
|
||||||
|
|
||||||
|
* **開發目標:我的世界, Java版, 版本 1.12**
|
||||||
|
* MineClone2還包括Minetest支持的Optifine功能。
|
||||||
|
* 後期Minecraft版本的功能可能會偷偷加入,但它們的優先級較低。
|
||||||
|
* 總的來說,Minecraft的目標是在Minetest目前允許的情況下進行克隆。
|
||||||
|
* 克隆Minecraft是最優先的。
|
||||||
|
* MineClone2將使用不同的圖形和聲音,但風格相似。
|
||||||
|
* 克隆界面沒有優先權。只會被粗略地模仿。
|
||||||
|
* 在Minetest中發現的局限性將在開發過程中被記錄和報告。
|
||||||
|
|
||||||
|
## 完成程度
|
||||||
|
該遊戲目前處於**alpha**階段。
|
||||||
|
它是可玩的,但尚未完成,預計會出現許多錯誤。
|
||||||
|
向後兼容性是**不能保證的**,更新你的世界可能會造成大大小小的bug(比如「缺少節點」的錯誤甚至崩潰)。
|
||||||
|
|
||||||
|
已經實現以下功能:
|
||||||
|
|
||||||
|
* 工具,武器
|
||||||
|
* 盔甲
|
||||||
|
* 合成和熔煉系統:2×2 合成格, 合成臺 (3×3 合成格), 熔爐, 合成教學
|
||||||
|
* 儲物箱,大型儲物箱,終界箱和界伏盒
|
||||||
|
* 熔爐, 漏斗
|
||||||
|
* 飢餓和飽食
|
||||||
|
* 大多數怪物和動物
|
||||||
|
* Minecraft 1.12中的所有礦物<!-- Minecraft 1.17 added copper, so here must mark the version is 1.12, then main README should also add this -->
|
||||||
|
* 主世界的大部分方塊
|
||||||
|
* 水和岩漿
|
||||||
|
* 天氣
|
||||||
|
* 28個生態域
|
||||||
|
* 地獄,熾熱的維度
|
||||||
|
* 紅石電路(部分)
|
||||||
|
* 礦車(部分)
|
||||||
|
* 狀態效果(部分)
|
||||||
|
* 經驗系統
|
||||||
|
* 附魔
|
||||||
|
* 釀造,藥水,藥水箭(部分)
|
||||||
|
* 船
|
||||||
|
* 火
|
||||||
|
* 建築方塊:樓梯、半磚、門、地板門、柵欄、柵欄門、牆。
|
||||||
|
* 時鐘
|
||||||
|
* 指南針
|
||||||
|
* 海綿
|
||||||
|
* 史萊姆方塊(不與紅石互動)
|
||||||
|
* 小植物和樹苗
|
||||||
|
* 染料
|
||||||
|
* 旗幟
|
||||||
|
* 裝飾方塊:玻璃、染色玻璃、玻璃片、鐵柵欄、陶土(和染色版本)、頭顱等
|
||||||
|
* 物品展示框
|
||||||
|
* 唱片機
|
||||||
|
* 床
|
||||||
|
* 物品欄
|
||||||
|
* 創造模式物品欄
|
||||||
|
* 生產
|
||||||
|
* 書和羽毛筆
|
||||||
|
* 一些服務器命令
|
||||||
|
* 還有更多!
|
||||||
|
|
||||||
|
以下是不完整的特性:
|
||||||
|
|
||||||
|
* 生成結構(特別是村莊)
|
||||||
|
* 一些怪物和動物
|
||||||
|
* 紅石系統
|
||||||
|
* 終界
|
||||||
|
* 特殊的礦車
|
||||||
|
* 一些不簡單的方塊和物品。
|
||||||
|
|
||||||
|
額外功能(在Minecraft 1.11中沒有)。
|
||||||
|
|
||||||
|
* 內置合成指南,向你展示製作和熔煉的配方
|
||||||
|
* 遊戲中的幫助系統包含了大量關於遊戲基礎知識、方塊、物品等方面的幫助。
|
||||||
|
* 臨時製作配方。它們的存在只是為了在你不在創造模式下時,提供一些其他無法獲得的物品。這些配方將隨著開發的進行和更多功能的出現而被移除。
|
||||||
|
* v6地圖生成器中箱子裡的樹苗。
|
||||||
|
* 完全可修改(得益於Minetest強大的Lua API)。
|
||||||
|
* 新的方塊和物品:
|
||||||
|
* 查找工具,顯示觸及事物的幫助
|
||||||
|
* 更多的半磚和樓梯
|
||||||
|
* 地獄磚柵欄門
|
||||||
|
* 紅地獄磚柵欄
|
||||||
|
* 紅地獄磚柵欄門
|
||||||
|
|
||||||
|
與Minecraft的技性術差異:
|
||||||
|
|
||||||
|
* 高度限制為31000格(遠高於Minecraft)
|
||||||
|
* 水平世界大小約為62000×62000格(比Minecraft中的小得多,但仍然非常大)。
|
||||||
|
* 仍然非常不完整和有問題
|
||||||
|
* 塊、物品、敵人和其他功能缺失。
|
||||||
|
* 一些項目的名稱略有不同,以便於區分。
|
||||||
|
* 唱片機的音樂不同
|
||||||
|
* 不同的材質(像素完美)
|
||||||
|
* 不同的聲音(各種來源)
|
||||||
|
* 不同的引擎(Minetest)
|
||||||
|
|
||||||
|
...最後,MineClone2是自由軟件!
|
||||||
|
|
||||||
|
## 錯誤報告
|
||||||
|
請在此處報告所有錯誤和缺少的功能:
|
||||||
|
|
||||||
|
<https://git.minetest.land/MineClone2/MineClone2/issues>
|
||||||
|
|
||||||
|
## Chating with the community
|
||||||
|
我們有Discord交流羣:
|
||||||
|
|
||||||
|
<https://discord.gg/84GKcxczG3>
|
||||||
|
|
||||||
|
|
||||||
|
## Other readme files
|
||||||
|
|
||||||
|
* `LICENSE.txt`:GPLv3許可文本
|
||||||
|
* `CONTRIBUTING.md`: 為那些想參與貢獻的人提供資訊
|
||||||
|
* `MISSING_ENGINE_FEATURES.md`: MineClone2需要改进,Minetest中缺失的功能列表。
|
||||||
|
* `API.md`: 關於MineClone2的API
|
||||||
|
|
||||||
|
## 參與者
|
||||||
|
有這麼多人要列出(抱歉)。詳情請查看各mod目錄。本節只是粗略地介紹了本遊戲的核心作者。
|
||||||
|
|
||||||
|
### 程式碼
|
||||||
|
* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082):大多數mod的主要程序員(已退休)
|
||||||
|
* davedevils:MineClone 2的原型——「MineClone」的創造者
|
||||||
|
* [ex-bart](https://github.com/ex-bart):紅石比較器
|
||||||
|
* [Rootyjr](https://github.com/Rootyjr):釣竿和錯誤修復
|
||||||
|
* [aligator](https://github.com/aligator):改進門
|
||||||
|
* [ryvnf](https://github.com/ryvnf):爆炸物理
|
||||||
|
* MysticTempest:錯誤修復
|
||||||
|
* [bzoss](https://github.com/bzoss):狀態效果,釀造,藥水
|
||||||
|
* kay27 <kay27@bk.ru>:經驗系統,錯誤修復和優化(當前維護者)
|
||||||
|
* [EliasFleckenstein03](https://github.com/EliasFleckenstein03):終界水晶,附魔,燃燒的怪物/玩家,箱子的動畫和錯誤修復(當前維護者)
|
||||||
|
* epCode:更好的玩家動畫,新徽標
|
||||||
|
* 2mac:修復動力鐵軌的錯誤
|
||||||
|
* 更多:待篇寫 (請查看各mod目錄)
|
||||||
|
|
||||||
|
#### Mod(概括)
|
||||||
|
|
||||||
|
* `controls`: Arcelmi
|
||||||
|
* `flowlib`: Qwertymine13
|
||||||
|
* `walkover`: lordfingle
|
||||||
|
* `drippingwater`: kddekadenz
|
||||||
|
* `mobs_mc`: maikerumine, 22i and others
|
||||||
|
* `awards`: rubenwardy
|
||||||
|
* `screwdriver`: RealBadAngel, Maciej Kastakin, Minetest contributors
|
||||||
|
* `xpanes`: Minetest contributors
|
||||||
|
* `mesecons` mods: Jeija and contributors
|
||||||
|
* `wieldview`: Stuart Jones
|
||||||
|
* `mcl_meshhand`: Based on `newhand` by jordan4ibanez
|
||||||
|
* `mcl_mobs`: Based on Mobs Redo [`mobs`] by TenPlus1 and contributors
|
||||||
|
* 大多其他的Mod: Wuzzy
|
||||||
|
|
||||||
|
每个mod的详细參與者可以在各个mod目录中找到。
|
||||||
|
|
||||||
|
### 圖形
|
||||||
|
* [XSSheep](http://www.minecraftforum.net/members/XSSheep):主要作者;Minecraft 1.11的Pixel Perfection资源包的制作者
|
||||||
|
* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082):主菜單圖像和各種編輯和添加的材質包
|
||||||
|
* [kingoscargames](https://github.com/kingoscargames):現有材質的各種編輯和添加
|
||||||
|
* [leorockway](https://github.com/leorockway):怪物紋理的一些編輯
|
||||||
|
* [xMrVizzy](https://minecraft.curseforge.com/members/xMrVizzy):釉陶(材質以後會被替換)
|
||||||
|
* yutyo <tanakinci2002@gmail.com>:MineClone2標志
|
||||||
|
* 其他:GUI圖片
|
||||||
|
|
||||||
|
### 翻譯
|
||||||
|
* Wuzzy:德語
|
||||||
|
* Rocher Laurent <rocherl@club-internet.fr>:法語
|
||||||
|
* wuniversales:西班牙語
|
||||||
|
* kay27 <kay27@bk.ru>:俄語
|
||||||
|
* [Emoji](https://toyshost2.ddns.net):繁體中文<!-- Hi, after the translate finish, this name should add to the main README too! -->
|
||||||
|
|
||||||
|
### 模型
|
||||||
|
* [22i](https://github.com/22i):所有模型的作者
|
||||||
|
* [tobyplowy](https://github.com/tobyplowy):對上述模型進行UV映射修復
|
||||||
|
|
||||||
|
### 聲音和音樂
|
||||||
|
多種來源。 有關詳細信息,請參見相應的mod目錄。
|
||||||
|
|
||||||
|
### 特殊感謝
|
||||||
|
|
||||||
|
* Wuzzy,感謝他啟動和維護MineClone2多年。
|
||||||
|
* celeron55,創建Minetest。
|
||||||
|
* Minetest的社區提供了大量的mods選擇,其中一些最終被納入MineClone 2。
|
||||||
|
* Jordach,為《Big Freaking Dig》的唱片機音樂合輯而來
|
||||||
|
* 花了太多時間為Minecraft Wiki寫作的工作狂。它是創建這個遊戲的寶貴資源。
|
||||||
|
* Notch和Jeb是Minecraft背后的主要力量
|
||||||
|
* XSSheep用於創建Pixel Perfection資源包。
|
||||||
|
* [22i](https://github.com/22i) 提供出色的模型和支持
|
||||||
|
* [maikerumine](http://github.com/maikerumine) 揭開生物和生物群落的序幕
|
||||||
|
|
||||||
|
## 給程序員的信息
|
||||||
|
你可以在「API.md」中找到有趣和有用的信息。
|
||||||
|
|
||||||
|
## 法律信息
|
||||||
|
這是一款粉絲開發的遊戲,並非由Mojang AB開發或認可。
|
||||||
|
|
||||||
|
複製是一種愛的行為。請複制和分享! <3
|
||||||
|
下面是詳細的法律條文,有需要的朋友可以參考。
|
||||||
|
|
||||||
|
### License of source code
|
||||||
|
```
|
||||||
|
MineClone 2 (by kay27, EliasFleckenstein, Wuzzy, davedevils and countless others)
|
||||||
|
is an imitation of Minecraft.
|
||||||
|
|
||||||
|
MineClone 2 is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License (in the LICENSE.txt file) for more
|
||||||
|
details.
|
||||||
|
|
||||||
|
In the mods you might find in the read-me or license
|
||||||
|
text files a different license. This counts as dual-licensing.
|
||||||
|
You can choose which license applies to you: Either the
|
||||||
|
license of MineClone 2 (GNU GPLv3) or the mod's license.
|
||||||
|
|
||||||
|
MineClone 2 is a direct continuation of the discontinued MineClone
|
||||||
|
project by davedevils.
|
||||||
|
|
||||||
|
Mod credits:
|
||||||
|
See `README.txt` or `README.md` in each mod directory for information about other authors.
|
||||||
|
For mods that do not have such a file, the license is the source code license
|
||||||
|
of MineClone 2 and the author is Wuzzy.
|
||||||
|
```
|
||||||
|
|
||||||
|
### License of media (textures and sounds)
|
||||||
|
```
|
||||||
|
No non-free licenses are used anywhere.
|
||||||
|
|
||||||
|
The textures, unless otherwise noted, are based on the Pixel Perfection resource pack for Minecraft 1.11,
|
||||||
|
authored by XSSheep. Most textures are verbatim copies, while some textures have been changed or redone
|
||||||
|
from scratch.
|
||||||
|
The glazed terracotta textures have been created by (MysticTempest)[https://github.com/MysticTempest].
|
||||||
|
Source: <https://www.planetminecraft.com/texture_pack/131pixel-perfection/>
|
||||||
|
License: [CC BY-SA 4.0](http://creativecommons.org/licenses/by-sa/4.0/)
|
||||||
|
|
||||||
|
The main menu images are release under: [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
|
||||||
|
|
||||||
|
All other files, unless mentioned otherwise, fall under:
|
||||||
|
Creative Commons Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||||
|
http://creativecommons.org/licenses/by-sa/3.0/
|
||||||
|
|
||||||
|
See README.txt in each mod directory for detailed information about other authors.
|
||||||
|
```
|
|
@ -1,2 +1,3 @@
|
||||||
name = MineClone 5
|
title = MineClone 5
|
||||||
|
author = MineClone 5 Community
|
||||||
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
mods/ITEMS/mcl_fire/init.lua
|
||||||
|
mods/ITEMS/mcl_flowers/init.lua
|
||||||
|
mods/ITEMS/mcl_itemframes/init.lua
|
||||||
|
mods/ITEMS/mcl_lanterns/init.lua
|
||||||
|
mods/ITEMS/mcl_lanterns/mod.conf
|
||||||
|
mods/ITEMS/mcl_lanterns/register.lua
|
||||||
|
mods/ITEMS/mcl_maps/init.lua
|
||||||
|
mods/ITEMS/mcl_mobitems/init.lua
|
||||||
|
mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.fr.tr
|
||||||
|
mods/ITEMS/mcl_mobitems/locale/mcl_mobitems.ru.tr
|
||||||
|
mods/ITEMS/mcl_mushrooms/huge.lua
|
||||||
|
mods/ITEMS/mcl_mushrooms/small.lua
|
||||||
|
mods/ITEMS/mcl_nether/init.lua
|
||||||
|
mods/ITEMS/mcl_nether/nether_wart.lua
|
||||||
|
mods/ITEMS/mcl_nether/textures/mcl_nether_netheriteblock.png
|
||||||
|
mods/ITEMS/mcl_ocean/kelp.lua
|
||||||
|
mods/ITEMS/mcl_ocean/sea_pickle.lua
|
||||||
|
mods/ITEMS/mcl_ocean/seagrass.lua
|
||||||
|
mods/ITEMS/mcl_portals/portal_end.lua
|
||||||
|
mods/ITEMS/mcl_portals/portal_nether.lua
|
||||||
|
mods/ITEMS/mcl_raw_ores/init.lua
|
||||||
|
mods/ITEMS/mcl_raw_ores/mod.conf
|
||||||
|
mods/ITEMS/mcl_shields/init.lua
|
||||||
|
mods/ITEMS/mcl_smithing_table/init.lua
|
||||||
|
mods/ITEMS/mcl_smithing_table/locale/template.txt
|
||||||
|
mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_bottom.png
|
||||||
|
mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_front.png
|
||||||
|
mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_side.png
|
||||||
|
mods/ITEMS/mcl_smithing_table/textures/mcl_smithing_table_top.png
|
||||||
|
mods/ITEMS/mcl_smoker/README.md
|
||||||
|
mods/ITEMS/mcl_smoker/init.lua
|
||||||
|
mods/ITEMS/mcl_spyglass/init.lua
|
||||||
|
mods/ITEMS/mcl_spyglass/mod.conf
|
||||||
|
mods/ITEMS/mcl_tools/init.lua
|
||||||
|
mods/ITEMS/mcl_totems/init.lua
|
||||||
|
mods/MAPGEN/mcl_biomes/init.lua
|
||||||
|
mods/MAPGEN/mcl_biomes/mod.conf
|
||||||
|
mods/MAPGEN/mcl_dungeons/init.lua
|
||||||
|
mods/MAPGEN/mcl_mapgen_core/init.lua
|
||||||
|
mods/MAPGEN/mcl_strongholds/init.lua
|
||||||
|
mods/MAPGEN/mcl_structures/desert_temple.lua
|
||||||
|
mods/MAPGEN/mcl_structures/igloo.lua
|
||||||
|
mods/MAPGEN/mcl_structures/init.lua
|
||||||
|
mods/MAPGEN/mcl_structures/jungle_temple.lua
|
||||||
|
mods/MAPGEN/mcl_structures/mod.conf
|
||||||
|
mods/MAPGEN/mcl_structures/witch_hut.lua
|
||||||
|
mods/MAPGEN/mcl_villages/buildings.lua
|
||||||
|
mods/MAPGEN/mcl_villages/const.lua
|
||||||
|
mods/MAPGEN/mcl_villages/init.lua
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/blacksmith.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/butcher.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/church.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/farm.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/lamp.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/large_house.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/library.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/medium_house.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/small_house.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/tavern.mts
|
||||||
|
mods/MAPGEN/mcl_villages/schematics/well.mts
|
||||||
|
mods/MAPGEN/mcl_villages/utils.lua
|
||||||
|
mods/MISC/mcl_commands/locale/mcl_commands.ru.tr
|
||||||
|
mods/MISC/mcl_commands/summon.lua
|
||||||
|
mods/MISC/mcl_privs/init.lua
|
||||||
|
mods/PLAYER/mcl_player/init.lua
|
||||||
|
mods/PLAYER/mcl_playerplus/init.lua
|
||||||
|
mods/PLAYER/mcl_playerplus/mod.conf
|
||||||
|
mods/PLAYER/mcl_spawn/init.lua
|
||||||
|
mods/PLAYER/mcl_wieldview/init.lua
|
|
@ -1,29 +1,93 @@
|
||||||
|
-- Overrides the builtin minetest.check_single_for_falling.
|
||||||
|
-- We need to do this in order to handle nodes in mineclone specific groups
|
||||||
|
-- "supported_node" and "attached_node_facedir".
|
||||||
|
--
|
||||||
|
-- Nodes in group "supported_node" can be placed on any node that does not
|
||||||
|
-- have the "airlike" drawtype. Carpets are an example of this type.
|
||||||
|
|
||||||
local vector = vector
|
local vector = vector
|
||||||
|
|
||||||
local facedir_to_dir = minetest.facedir_to_dir
|
local facedir_to_dir = minetest.facedir_to_dir
|
||||||
local get_item_group = minetest.get_item_group
|
local get_item_group = minetest.get_item_group
|
||||||
local remove_node = minetest.remove_node
|
local remove_node = minetest.remove_node
|
||||||
local get_node = minetest.get_node
|
local get_node = minetest.get_node
|
||||||
|
local get_meta = minetest.get_meta
|
||||||
|
local registered_nodes = minetest.registered_nodes
|
||||||
|
local get_node_drops = minetest.get_node_drops
|
||||||
|
local add_item = minetest.add_item
|
||||||
|
|
||||||
|
-- drop_attached_node(p)
|
||||||
|
--
|
||||||
|
-- This function is copied verbatim from minetest/builtin/game/falling.lua
|
||||||
|
-- We need this to do the exact same dropping node handling in our override
|
||||||
|
-- minetest.check_single_for_falling() function as in the builtin function.
|
||||||
|
--
|
||||||
|
local function drop_attached_node(p)
|
||||||
|
local n = get_node(p)
|
||||||
|
local drops = get_node_drops(n, "")
|
||||||
|
local def = registered_nodes[n.name]
|
||||||
|
if def and def.preserve_metadata then
|
||||||
|
local oldmeta = get_meta(p):to_table().fields
|
||||||
|
-- Copy pos and node because the callback can modify them.
|
||||||
|
local pos_copy = vector.new(p)
|
||||||
|
local node_copy = {name=n.name, param1=n.param1, param2=n.param2}
|
||||||
|
local drop_stacks = {}
|
||||||
|
for k, v in pairs(drops) do
|
||||||
|
drop_stacks[k] = ItemStack(v)
|
||||||
|
end
|
||||||
|
drops = drop_stacks
|
||||||
|
def.preserve_metadata(pos_copy, node_copy, oldmeta, drops)
|
||||||
|
end
|
||||||
|
if def and def.sounds and def.sounds.fall then
|
||||||
|
core.sound_play(def.sounds.fall, {pos = p}, true)
|
||||||
|
end
|
||||||
|
remove_node(p)
|
||||||
|
for _, item in pairs(drops) do
|
||||||
|
local pos = {
|
||||||
|
x = p.x + math.random()/2 - 0.25,
|
||||||
|
y = p.y + math.random()/2 - 0.25,
|
||||||
|
z = p.z + math.random()/2 - 0.25,
|
||||||
|
}
|
||||||
|
add_item(pos, item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- minetest.check_single_for_falling(pos)
|
||||||
|
--
|
||||||
|
-- * causes an unsupported `group:falling_node` node to fall and causes an
|
||||||
|
-- unattached `group:attached_node` or `group:attached_node_facedir` node
|
||||||
|
-- or unsupported `group:supported_node` node to drop.
|
||||||
|
-- * does not spread these updates to neighbours.
|
||||||
|
--
|
||||||
|
-- Returns true if the node at <pos> has spawned a falling node or has been
|
||||||
|
-- dropped as item(s).
|
||||||
|
--
|
||||||
local original_function = minetest.check_single_for_falling
|
local original_function = minetest.check_single_for_falling
|
||||||
|
|
||||||
function minetest.check_single_for_falling(pos)
|
function minetest.check_single_for_falling(pos)
|
||||||
local ret_o = original_function(pos)
|
if original_function(pos) then
|
||||||
local ret = false
|
return true
|
||||||
local node = minetest.get_node(pos)
|
end
|
||||||
|
|
||||||
|
local node = get_node(pos)
|
||||||
if get_item_group(node.name, "attached_node_facedir") ~= 0 then
|
if get_item_group(node.name, "attached_node_facedir") ~= 0 then
|
||||||
local dir = facedir_to_dir(node.param2)
|
local dir = facedir_to_dir(node.param2)
|
||||||
if dir then
|
if dir then
|
||||||
if get_item_group(get_node(vector.add(pos, dir)).name, "solid") == 0 then
|
if get_item_group(get_node(vector.add(pos, dir)).name, "solid") == 0 then
|
||||||
remove_node(pos)
|
drop_attached_node(pos)
|
||||||
local drops = minetest.get_node_drops(node.name, "")
|
return true
|
||||||
for dr=1, #drops do
|
|
||||||
minetest.add_item(pos, drops[dr])
|
|
||||||
end
|
|
||||||
ret = true
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return ret_o or ret
|
|
||||||
|
if get_item_group(node.name, "supported_node") ~= 0 then
|
||||||
|
local def = registered_nodes[get_node(vector.offset(pos, 0, -1, 0)).name]
|
||||||
|
if def and def.drawtype == "airlike" then
|
||||||
|
drop_attached_node(pos)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
# mcl_damage
|
||||||
|
|
||||||
|
This mod is intended to overall minetest's native damage system, to provide a better integration between features that deals with entities' health.
|
||||||
|
|
||||||
|
WARNING: Not using it inside your mods may cause strange bugs (using the native damage system may cause conflicts with this system).
|
||||||
|
|
||||||
|
## Callbacks
|
||||||
|
|
||||||
|
To modify the amount of damage made by something:
|
||||||
|
|
||||||
|
```lua
|
||||||
|
--obj: an ObjectRef
|
||||||
|
mcl_damage.register_modifier(function(obj, damage, reason)
|
||||||
|
end, 0)
|
||||||
|
```
|
|
@ -14,7 +14,7 @@ mcl_damage = {
|
||||||
cactus = {},
|
cactus = {},
|
||||||
fall = {bypasses_armor = true},
|
fall = {bypasses_armor = true},
|
||||||
fly_into_wall = {bypasses_armor = true}, -- unused
|
fly_into_wall = {bypasses_armor = true}, -- unused
|
||||||
out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true},
|
out_of_world = {bypasses_armor = true, bypasses_magic = true, bypasses_invulnerability = true, bypasses_totem = true},
|
||||||
generic = {bypasses_armor = true},
|
generic = {bypasses_armor = true},
|
||||||
magic = {is_magic = true, bypasses_armor = true},
|
magic = {is_magic = true, bypasses_armor = true},
|
||||||
dragon_breath = {is_magic = true, bypasses_armor = true}, -- this is only used for dragon fireball; dragon fireball does not actually deal impact damage tho, so this is unreachable
|
dragon_breath = {is_magic = true, bypasses_armor = true}, -- this is only used for dragon fireball; dragon fireball does not actually deal impact damage tho, so this is unreachable
|
||||||
|
@ -78,7 +78,7 @@ function mcl_damage.from_punch(mcl_reason, object)
|
||||||
mcl_reason.type = "arrow"
|
mcl_reason.type = "arrow"
|
||||||
elseif luaentity._is_fireball then
|
elseif luaentity._is_fireball then
|
||||||
mcl_reason.type = "fireball"
|
mcl_reason.type = "fireball"
|
||||||
elseif luaentity._cmi_is_mob then
|
elseif luaentity.is_mob then
|
||||||
mcl_reason.type = "mob"
|
mcl_reason.type = "mob"
|
||||||
end
|
end
|
||||||
mcl_reason.source = mcl_reason.source or luaentity._source_object
|
mcl_reason.source = mcl_reason.source or luaentity._source_object
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# textdomain:mcl_explosions
|
||||||
|
@1 was caught in an explosion.=@1 被炸飛了
|
|
@ -271,6 +271,32 @@ function mcl_util.get_first_occupied_inventory_slot(inventory, listname)
|
||||||
return mcl_util.get_eligible_transfer_item_slot(inventory, listname)
|
return mcl_util.get_eligible_transfer_item_slot(inventory, listname)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function drop_item_stack(pos, stack)
|
||||||
|
if not stack or stack:is_empty() then return end
|
||||||
|
local drop_offset = vector.new(math.random() - 0.5, 0, math.random() - 0.5)
|
||||||
|
minetest.add_item(vector.add(pos, drop_offset), stack)
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_util.drop_items_from_meta_container(listname)
|
||||||
|
return function(pos, oldnode, oldmetadata)
|
||||||
|
if oldmetadata and oldmetadata.inventory then
|
||||||
|
-- process in after_dig_node callback
|
||||||
|
local main = oldmetadata.inventory.main
|
||||||
|
if not main then return end
|
||||||
|
for _, stack in pairs(main) do
|
||||||
|
drop_item_stack(pos, stack)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local inv = meta:get_inventory()
|
||||||
|
for i = 1, inv:get_size("main") do
|
||||||
|
drop_item_stack(pos, inv:get_stack("main", i))
|
||||||
|
end
|
||||||
|
meta:from_table()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Returns true if item (itemstring or ItemStack) can be used as a furnace fuel.
|
-- Returns true if item (itemstring or ItemStack) can be used as a furnace fuel.
|
||||||
-- Returns false otherwise
|
-- Returns false otherwise
|
||||||
function mcl_util.is_fuel(item)
|
function mcl_util.is_fuel(item)
|
||||||
|
@ -412,7 +438,7 @@ function mcl_util.deal_damage(target, damage, mcl_reason)
|
||||||
if luaentity.deal_damage then
|
if luaentity.deal_damage then
|
||||||
luaentity:deal_damage(damage, mcl_reason or {type = "generic"})
|
luaentity:deal_damage(damage, mcl_reason or {type = "generic"})
|
||||||
return
|
return
|
||||||
elseif luaentity._cmi_is_mob then
|
elseif luaentity.is_mob then
|
||||||
-- local puncher = mcl_reason and mcl_reason.direct or target
|
-- local puncher = mcl_reason and mcl_reason.direct or target
|
||||||
-- target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage)
|
-- target:punch(puncher, 1.0, {full_punch_interval = 1.0, damage_groups = {fleshy = damage}}, vector.direction(puncher:get_pos(), target:get_pos()), damage)
|
||||||
if luaentity.health > 0 then
|
if luaentity.health > 0 then
|
||||||
|
@ -433,7 +459,7 @@ end
|
||||||
function mcl_util.get_hp(obj)
|
function mcl_util.get_hp(obj)
|
||||||
local luaentity = obj:get_luaentity()
|
local luaentity = obj:get_luaentity()
|
||||||
|
|
||||||
if luaentity and luaentity._cmi_is_mob then
|
if luaentity and luaentity.is_mob then
|
||||||
return luaentity.health
|
return luaentity.health
|
||||||
else
|
else
|
||||||
return obj:get_hp()
|
return obj:get_hp()
|
||||||
|
@ -487,12 +513,11 @@ function mcl_util.replace_mob(obj, mob)
|
||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_util.get_pointed_thing(player)
|
function mcl_util.get_pointed_thing(player, liquids)
|
||||||
local pos = vector.offset(player:get_pos(), 0, player:get_properties().eye_height, 0)
|
local pos = vector.offset(player:get_pos(), 0, player:get_properties().eye_height, 0)
|
||||||
local look_dir = vector.multiply(player:get_look_dir(), 5)
|
local look_dir = vector.multiply(player:get_look_dir(), 5)
|
||||||
local pos2 = vector.add(pos, look_dir)
|
local pos2 = vector.add(pos, look_dir)
|
||||||
local ray = minetest.raycast(pos, pos2, false, true)
|
local ray = minetest.raycast(pos, pos2, false, liquids)
|
||||||
|
|
||||||
if ray then
|
if ray then
|
||||||
for pointed_thing in ray do
|
for pointed_thing in ray do
|
||||||
return pointed_thing
|
return pointed_thing
|
||||||
|
|
|
@ -156,6 +156,7 @@ end)
|
||||||
function mcl_worlds.get_cloud_parameters()
|
function mcl_worlds.get_cloud_parameters()
|
||||||
if mcl_mapgen.name == "valleys" then
|
if mcl_mapgen.name == "valleys" then
|
||||||
return {
|
return {
|
||||||
|
-- valleys has a much higher average elevation thus often "normal" landscape ends up in the clouds
|
||||||
height = 384,
|
height = 384,
|
||||||
speed = {x=-2, z=0},
|
speed = {x=-2, z=0},
|
||||||
thickness=5,
|
thickness=5,
|
||||||
|
|
|
@ -557,35 +557,7 @@ function image:encode(properties)
|
||||||
self:encode_footer() -- footer
|
self:encode_footer() -- footer
|
||||||
end
|
end
|
||||||
|
|
||||||
function image:save(filename, properties)
|
function image:save(filename)
|
||||||
local properties = properties or {}
|
|
||||||
properties.colormap = properties.colormap or {}
|
|
||||||
properties.compression = properties.compression or "RAW"
|
|
||||||
|
|
||||||
self.pixel_depth = #self.pixels[1][1] * 8
|
|
||||||
|
|
||||||
local color_format_defaults_by_pixel_depth = {
|
|
||||||
[8] = "Y8",
|
|
||||||
[24] = "B8G8R8",
|
|
||||||
[32] = "B8G8R8A8",
|
|
||||||
}
|
|
||||||
if nil == properties.color_format then
|
|
||||||
if 0 ~= #properties.colormap then
|
|
||||||
properties.color_format =
|
|
||||||
color_format_defaults_by_pixel_depth[
|
|
||||||
#properties.colormap[1] * 8
|
|
||||||
]
|
|
||||||
else
|
|
||||||
properties.color_format =
|
|
||||||
color_format_defaults_by_pixel_depth[
|
|
||||||
self.pixel_depth
|
|
||||||
]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
assert( nil ~= properties.color_format )
|
|
||||||
|
|
||||||
self:encode(properties)
|
|
||||||
|
|
||||||
local f = assert(io.open(filename, "wb"))
|
local f = assert(io.open(filename, "wb"))
|
||||||
f:write(self.data)
|
f:write(self.data)
|
||||||
f:close()
|
f:close()
|
||||||
|
|
|
@ -2,47 +2,45 @@
|
||||||
|
|
||||||
local get_connected_players = minetest.get_connected_players
|
local get_connected_players = minetest.get_connected_players
|
||||||
local get_node = minetest.get_node
|
local get_node = minetest.get_node
|
||||||
local vector_add = vector.add
|
local vector = vector
|
||||||
local ceil = math.ceil
|
local ceil = math.ceil
|
||||||
local pairs = pairs
|
local pairs = pairs
|
||||||
|
|
||||||
walkover = {}
|
walkover = {}
|
||||||
walkover.registered_globals = {}
|
|
||||||
|
|
||||||
function walkover.register_global(func)
|
|
||||||
table.insert(walkover.registered_globals, func)
|
|
||||||
end
|
|
||||||
|
|
||||||
local on_walk = {}
|
local on_walk = {}
|
||||||
local registered_globals = {}
|
local registered_globals = {}
|
||||||
|
|
||||||
|
walkover.registered_globals = registered_globals
|
||||||
|
|
||||||
|
function walkover.register_global(func)
|
||||||
|
table.insert(registered_globals, func)
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_on_mods_loaded(function()
|
minetest.register_on_mods_loaded(function()
|
||||||
for name,def in pairs(minetest.registered_nodes) do
|
for name,def in pairs(minetest.registered_nodes) do
|
||||||
if def.on_walk_over then
|
if def.on_walk_over then
|
||||||
on_walk[name] = def.on_walk_over
|
on_walk[name] = def.on_walk_over
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for _,func in ipairs(walkover.registered_globals) do --cache registered globals
|
|
||||||
table.insert(registered_globals, func)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local timer = 0
|
local timer = 0
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
timer = timer + dtime;
|
timer = timer + dtime
|
||||||
if timer >= 0.3 then
|
if timer >= 0.3 then
|
||||||
for _,player in pairs(get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
local pp = player:get_pos()
|
local ppos = player:get_pos()
|
||||||
pp.y = ceil(pp.y)
|
ppos.y = ceil(ppos.y)
|
||||||
local loc = vector_add(pp, {x=0,y=-1,z=0})
|
local npos = vector.add(ppos, vector.new(0, -1, 0))
|
||||||
if loc then
|
if npos then
|
||||||
local nodeiamon = get_node(loc)
|
local node = get_node(npos)
|
||||||
if nodeiamon then
|
if node then
|
||||||
if on_walk[nodeiamon.name] then
|
if on_walk[node.name] then
|
||||||
on_walk[nodeiamon.name](loc, nodeiamon, player)
|
on_walk[node.name](npos, node, player)
|
||||||
end
|
end
|
||||||
for i = 1, #registered_globals do
|
for i = 1, #registered_globals do
|
||||||
registered_globals[i](loc, nodeiamon, player)
|
registered_globals[i](npos, node, player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -127,9 +127,11 @@ end
|
||||||
|
|
||||||
local boat = {
|
local boat = {
|
||||||
physical = true,
|
physical = true,
|
||||||
|
pointable = true,
|
||||||
-- Warning: Do not change the position of the collisionbox top surface,
|
-- Warning: Do not change the position of the collisionbox top surface,
|
||||||
-- lowering it causes the boat to fall through the world if underwater
|
-- lowering it causes the boat to fall through the world if underwater
|
||||||
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
||||||
|
selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.3, 0.7},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mcl_boats_boat.b3d",
|
mesh = "mcl_boats_boat.b3d",
|
||||||
textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"},
|
textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"},
|
||||||
|
@ -336,7 +338,7 @@ function boat.on_step(self, dtime, moveresult)
|
||||||
|
|
||||||
for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
|
for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
|
||||||
local entity = obj:get_luaentity()
|
local entity = obj:get_luaentity()
|
||||||
if entity and entity._cmi_is_mob then
|
if entity and entity.is_mob then
|
||||||
attach_object(self, obj)
|
attach_object(self, obj)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# textdomain: mcl_boats
|
||||||
|
Acacia Boat=相思木船
|
||||||
|
Birch Boat=白樺木船
|
||||||
|
Boat=船
|
||||||
|
Boats are used to travel on the surface of water.=船是用來在水上行走的交通工具。
|
||||||
|
Dark Oak Boat=黑橡木船
|
||||||
|
Jungle Boat=叢林木船
|
||||||
|
Oak Boat=橡木船
|
||||||
|
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=右鍵單擊水源以放置船。右鍵單擊船以搭乘它。使用[左]和[右]進行轉向,[向前]加快速度,[向後]減速或向後移動。再次右鍵單擊船以離開它,打擊船以使其掉落為物品。
|
||||||
|
Spruce Boat=杉木船
|
||||||
|
Water vehicle=水上交通工具
|
|
@ -26,20 +26,64 @@ function mcl_burning.get_collisionbox(obj, smaller, storage)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local find_nodes_in_area = minetest.find_nodes_in_area
|
||||||
|
|
||||||
function mcl_burning.get_touching_nodes(obj, nodenames, storage)
|
function mcl_burning.get_touching_nodes(obj, nodenames, storage)
|
||||||
local pos = obj:get_pos()
|
local pos = obj:get_pos()
|
||||||
local minp, maxp = mcl_burning.get_collisionbox(obj, true, storage)
|
local minp, maxp = mcl_burning.get_collisionbox(obj, true, storage)
|
||||||
local nodes = minetest.find_nodes_in_area(vector.add(pos, minp), vector.add(pos, maxp), nodenames)
|
local nodes = find_nodes_in_area(vector.add(pos, minp), vector.add(pos, maxp), nodenames)
|
||||||
return nodes
|
return nodes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Manages the fire animation on a burning player's HUD
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- player - a valid player object;
|
||||||
|
--
|
||||||
|
-- If the player already has a fire HUD, updates the burning animation.
|
||||||
|
-- If the fire does not have a fire HUD, initializes the HUD.
|
||||||
|
--
|
||||||
|
function mcl_burning.update_hud(player)
|
||||||
|
local animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
|
||||||
|
local hud_flame_animated = "mcl_burning_hud_flame_animated.png^[opacity:180^[verticalframe:" .. animation_frames .. ":"
|
||||||
|
|
||||||
|
local storage = mcl_burning.get_storage(player)
|
||||||
|
if not storage.fire_hud_id then
|
||||||
|
storage.animation_frame = 1
|
||||||
|
storage.fire_hud_id = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.5, y = 0.5},
|
||||||
|
scale = {x = -100, y = -100},
|
||||||
|
text = hud_flame_animated .. storage.animation_frame,
|
||||||
|
z_index = 1000,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
storage.animation_frame = storage.animation_frame + 1
|
||||||
|
if storage.animation_frame > animation_frames - 1 then
|
||||||
|
storage.animation_frame = 0
|
||||||
|
end
|
||||||
|
player:hud_change(storage.fire_hud_id, "text", hud_flame_animated .. storage.animation_frame)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sets and object state as burning and adds a fire animation to the object.
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- obj - may be a player or a lua_entity;
|
||||||
|
-- burn_time - sets the object's burn duration;
|
||||||
|
--
|
||||||
|
-- If obj is a player, adds a fire animation to the HUD, if obj is a
|
||||||
|
-- lua_entity, adds an animated fire entity to obj.
|
||||||
|
-- The effective burn duration is modified by obj's armor protection.
|
||||||
|
-- If obj was already burning, its burn duration is updated if the current
|
||||||
|
-- duration is less than burn_time.
|
||||||
|
-- If obj is dead, fireproof or a creative player, this function does nothing.
|
||||||
|
--
|
||||||
function mcl_burning.set_on_fire(obj, burn_time)
|
function mcl_burning.set_on_fire(obj, burn_time)
|
||||||
if obj:get_hp() < 0 then
|
if obj:get_hp() < 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local storage = mcl_burning.get_storage(obj)
|
|
||||||
|
|
||||||
local luaentity = obj:get_luaentity()
|
local luaentity = obj:get_luaentity()
|
||||||
if luaentity and luaentity.fire_resistant then
|
if luaentity and luaentity.fire_resistant then
|
||||||
return
|
return
|
||||||
|
@ -60,52 +104,43 @@ function mcl_burning.set_on_fire(obj, burn_time)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if max_fire_prot_lvl > 0 then
|
if max_fire_prot_lvl > 0 then
|
||||||
burn_time = burn_time - math.floor(burn_time * max_fire_prot_lvl * 0.15)
|
burn_time = burn_time - math.floor(burn_time * max_fire_prot_lvl * 0.15)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if not storage.burn_time or burn_time >= storage.burn_time then
|
local storage = mcl_burning.get_storage(obj)
|
||||||
if obj:is_player() then
|
if storage.burn_time then
|
||||||
mcl_burning.channels[obj]:send_all(tostring(mcl_burning.animation_frames))
|
if burn_time > storage.burn_time then
|
||||||
mcl_burning.channels[obj]:send_all("start")
|
storage.burn_time = burn_time
|
||||||
end
|
end
|
||||||
storage.burn_time = burn_time
|
return
|
||||||
storage.fire_damage_timer = 0
|
end
|
||||||
|
storage.burn_time = burn_time
|
||||||
|
storage.fire_damage_timer = 0
|
||||||
|
|
||||||
local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire")
|
local minp, maxp = mcl_burning.get_collisionbox(obj, false, storage)
|
||||||
local minp, maxp = mcl_burning.get_collisionbox(obj, false, storage)
|
local size = vector.subtract(maxp, minp)
|
||||||
local obj_size = obj:get_properties().visual_size
|
size = vector.multiply(size, vector.new(1.1, 1.2, 1.1))
|
||||||
|
size = vector.divide(size, obj:get_properties().visual_size)
|
||||||
|
|
||||||
local vertical_grow_factor = 1.2
|
local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire")
|
||||||
local horizontal_grow_factor = 1.1
|
fire_entity:set_properties({visual_size = size})
|
||||||
local grow_vector = vector.new(horizontal_grow_factor, vertical_grow_factor, horizontal_grow_factor)
|
fire_entity:set_attach(obj, "", vector.new(0, size.y * 5, 0), vector.new(0, 0, 0))
|
||||||
|
|
||||||
local size = vector.subtract(maxp, minp)
|
if obj:is_player() then
|
||||||
size = vector.multiply(size, grow_vector)
|
mcl_burning.update_hud(obj)
|
||||||
size = vector.divide(size, obj_size)
|
|
||||||
local offset = vector.new(0, size.y * 10 / 2, 0)
|
|
||||||
|
|
||||||
fire_entity:set_properties({visual_size = size})
|
|
||||||
fire_entity:set_attach(obj, "", offset, {x = 0, y = 0, z = 0})
|
|
||||||
local fire_luaentity = fire_entity:get_luaentity()
|
|
||||||
|
|
||||||
for _, other in pairs(minetest.get_objects_inside_radius(fire_entity:get_pos(), 0)) do
|
|
||||||
local other_luaentity = other:get_luaentity()
|
|
||||||
if other_luaentity and other_luaentity.name == "mcl_burning:fire" and other_luaentity ~= fire_luaentity then
|
|
||||||
other:remove()
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_burning.extinguish(obj)
|
function mcl_burning.extinguish(obj)
|
||||||
|
if not obj:get_pos() then return end
|
||||||
if mcl_burning.is_burning(obj) then
|
if mcl_burning.is_burning(obj) then
|
||||||
local storage = mcl_burning.get_storage(obj)
|
local storage = mcl_burning.get_storage(obj)
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
mcl_burning.channels[obj]:send_all("stop")
|
if storage.fire_hud_id then
|
||||||
|
obj:hud_remove(storage.fire_hud_id)
|
||||||
|
end
|
||||||
mcl_burning.storage[obj] = {}
|
mcl_burning.storage[obj] = {}
|
||||||
else
|
else
|
||||||
storage.burn_time = nil
|
storage.burn_time = nil
|
||||||
|
|
|
@ -1,18 +1,27 @@
|
||||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
|
||||||
local pairs = pairs
|
|
||||||
|
|
||||||
local get_connected_players = minetest.get_connected_players
|
|
||||||
local get_item_group = minetest.get_item_group
|
|
||||||
|
|
||||||
mcl_burning = {
|
mcl_burning = {
|
||||||
storage = {},
|
-- the storage table holds a list of objects (players,luaentities) and tables
|
||||||
channels = {},
|
-- associated with these objects. These tables have the following attributes:
|
||||||
animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
|
-- burn_time:
|
||||||
|
-- Remaining time that object will burn.
|
||||||
|
-- fire_damage_timer:
|
||||||
|
-- Timer for dealing damage every second while burning.
|
||||||
|
-- fire_hud_id:
|
||||||
|
-- HUD id of the flames animation on a burning player's HUD.
|
||||||
|
-- animation_frame:
|
||||||
|
-- The HUD's current animation frame, used by update_hud().
|
||||||
|
-- collisionbox_cache:
|
||||||
|
-- Used by mcl_burning.get_collisionbox() to avoid recalculations.
|
||||||
|
storage = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
dofile(modpath .. "/api.lua")
|
dofile(modpath .. "/api.lua")
|
||||||
|
|
||||||
|
local pairs = pairs
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local get_item_group = minetest.get_item_group
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
for _, player in pairs(get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
local storage = mcl_burning.storage[player]
|
local storage = mcl_burning.storage[player]
|
||||||
|
@ -48,25 +57,43 @@ minetest.register_on_respawnplayer(function(player)
|
||||||
mcl_burning.extinguish(player)
|
mcl_burning.extinguish(player)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
function mcl_burning.init_player(player)
|
minetest.register_on_joinplayer(function(player)
|
||||||
local meta = player:get_meta()
|
local storage = {}
|
||||||
-- NOTE: mcl_burning:data may be "return nil" (which deserialize into nil) for reasons unknown.
|
local burn_data = player:get_meta():get_string("mcl_burning:data")
|
||||||
if meta:get_string("mcl_burning:data"):find("return nil", 1, true) then
|
if burn_data ~= "" then
|
||||||
minetest.log("warning", "[mcl_burning] 'mcl_burning:data' player meta field is invalid! Please report this bug")
|
storage = minetest.deserialize(burn_data) or storage
|
||||||
end
|
end
|
||||||
mcl_burning.storage[player] = meta:contains("mcl_burning:data") and minetest.deserialize(meta:get_string("mcl_burning:data")) or {}
|
mcl_burning.storage[player] = storage
|
||||||
mcl_burning.channels[player] = minetest.mod_channel_join("mcl_burning:" .. player:get_player_name())
|
if storage.burn_time and storage.burn_time > 0 then
|
||||||
|
mcl_burning.update_hud(player)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function on_leaveplayer(player)
|
||||||
|
local storage = mcl_burning.storage[player]
|
||||||
|
if not storage then
|
||||||
|
-- For some unexplained reasons, mcl_burning.storage can be `nil` here.
|
||||||
|
-- Logging this exception to assist in finding the cause of this.
|
||||||
|
minetest.log("warning", "on_leaveplayer: missing mcl_burning.storage "
|
||||||
|
.. "for player " .. player:get_player_name())
|
||||||
|
storage = {}
|
||||||
|
end
|
||||||
|
storage.fire_hud_id = nil
|
||||||
|
player:get_meta():set_string("mcl_burning:data", minetest.serialize(storage))
|
||||||
|
mcl_burning.storage[player] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_on_joinplayer(function(player)
|
|
||||||
mcl_burning.init_player(player)
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
minetest.register_on_leaveplayer(function(player)
|
||||||
player:get_meta():set_string("mcl_burning:data", minetest.serialize(mcl_burning.storage[player]))
|
on_leaveplayer(player)
|
||||||
mcl_burning.storage[player] = nil
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_shutdown(function()
|
||||||
|
for _,player in ipairs(minetest.get_connected_players()) do
|
||||||
|
on_leaveplayer(player)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
local animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
|
||||||
|
|
||||||
minetest.register_entity("mcl_burning:fire", {
|
minetest.register_entity("mcl_burning:fire", {
|
||||||
initial_properties = {
|
initial_properties = {
|
||||||
|
@ -74,42 +101,35 @@ minetest.register_entity("mcl_burning:fire", {
|
||||||
collisionbox = {0, 0, 0, 0, 0, 0},
|
collisionbox = {0, 0, 0, 0, 0, 0},
|
||||||
visual = "upright_sprite",
|
visual = "upright_sprite",
|
||||||
textures = {
|
textures = {
|
||||||
name = "mcl_burning_entity_flame_animated.png",
|
"mcl_burning_entity_flame_animated.png",
|
||||||
animation = {
|
"mcl_burning_entity_flame_animated.png"
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
spritediv = {x = 1, y = mcl_burning.animation_frames},
|
spritediv = {x = 1, y = animation_frames},
|
||||||
pointable = false,
|
pointable = false,
|
||||||
glow = -1,
|
glow = -1,
|
||||||
backface_culling = false,
|
backface_culling = false,
|
||||||
},
|
},
|
||||||
animation_frame = 0,
|
_mcl_animation_timer = 0,
|
||||||
animation_timer = 0,
|
|
||||||
on_activate = function(self)
|
on_activate = function(self)
|
||||||
self.object:set_sprite({x = 0, y = 0}, mcl_burning.animation_frames, 1.0 / mcl_burning.animation_frames)
|
self.object:set_sprite({x = 0, y = 0}, animation_frames, 1.0 / animation_frames)
|
||||||
end,
|
end,
|
||||||
on_step = function(self)
|
on_step = function(self, dtime)
|
||||||
if not self:sanity_check() then
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
sanity_check = function(self)
|
|
||||||
local parent = self.object:get_attach()
|
local parent = self.object:get_attach()
|
||||||
|
|
||||||
if not parent then
|
if not parent then
|
||||||
return false
|
self.object:remove()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local storage = mcl_burning.get_storage(parent)
|
local storage = mcl_burning.get_storage(parent)
|
||||||
|
|
||||||
if not storage or not storage.burn_time then
|
if not storage or not storage.burn_time then
|
||||||
return false
|
self.object:remove()
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if parent:is_player() then
|
||||||
|
self._mcl_animation_timer = self._mcl_animation_timer + dtime
|
||||||
|
if self._mcl_animation_timer >= 0.1 then
|
||||||
|
self._mcl_animation_timer = 0
|
||||||
|
mcl_burning.update_hud(parent)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# textdomain: mcl_falling_nodes
|
||||||
|
@1 was smashed by a falling anvil.=@1 被鐵砧壓扁了。
|
||||||
|
@1 was smashed by a falling block.=@1 被掉下來的方塊壓扁了。
|
|
@ -86,7 +86,6 @@ local function enable_physics(object, luaentity, ignore_check)
|
||||||
object:set_properties({
|
object:set_properties({
|
||||||
physical = true
|
physical = true
|
||||||
})
|
})
|
||||||
object:set_velocity({x=0,y=0,z=0})
|
|
||||||
object:set_acceleration({x=0,y=-get_gravity(),z=0})
|
object:set_acceleration({x=0,y=-get_gravity(),z=0})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -118,7 +117,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
if tick == true and pool[name] > 0 then
|
if tick == true and pool[name] > 0 then
|
||||||
minetest.sound_play("item_drop_pickup", {
|
minetest.sound_play("item_drop_pickup", {
|
||||||
pos = pos,
|
pos = pos,
|
||||||
gain = 0.7,
|
gain = 0.3,
|
||||||
max_hear_distance = 16,
|
max_hear_distance = 16,
|
||||||
pitch = math.random(70,110)/100
|
pitch = math.random(70,110)/100
|
||||||
})
|
})
|
||||||
|
@ -264,6 +263,8 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||||
|
|
||||||
local silk_touch_drop = false
|
local silk_touch_drop = false
|
||||||
local nodedef = minetest.registered_nodes[dug_node.name]
|
local nodedef = minetest.registered_nodes[dug_node.name]
|
||||||
|
if not nodedef then return end
|
||||||
|
|
||||||
if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then
|
if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then
|
||||||
if nodedef._mcl_shears_drop == true then
|
if nodedef._mcl_shears_drop == true then
|
||||||
drops = { dug_node.name }
|
drops = { dug_node.name }
|
||||||
|
@ -424,7 +425,11 @@ minetest.register_entity(":__builtin:item", {
|
||||||
end
|
end
|
||||||
local stack = ItemStack(itemstring)
|
local stack = ItemStack(itemstring)
|
||||||
if minetest.get_item_group(stack:get_name(), "compass") > 0 then
|
if minetest.get_item_group(stack:get_name(), "compass") > 0 then
|
||||||
stack:set_name("mcl_compass:16")
|
if string.find(stack:get_name(), "_lodestone") then
|
||||||
|
stack:set_name("mcl_compass:18_lodestone")
|
||||||
|
else
|
||||||
|
stack:set_name("mcl_compass:18")
|
||||||
|
end
|
||||||
itemstring = stack:to_string()
|
itemstring = stack:to_string()
|
||||||
self.itemstring = itemstring
|
self.itemstring = itemstring
|
||||||
end
|
end
|
||||||
|
@ -777,8 +782,8 @@ minetest.register_entity(":__builtin:item", {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Move item around on flowing liquids
|
-- Move item around on flowing liquids; add 'source' check to allow items to continue flowing a bit in the source block of flowing water.
|
||||||
if def and def.liquidtype == "flowing" then
|
if def and def.liquidtype == "flowing" or def.liquidtype == "source" then
|
||||||
|
|
||||||
--[[ Get flowing direction (function call from flowlib), if there's a liquid.
|
--[[ Get flowing direction (function call from flowlib), if there's a liquid.
|
||||||
NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
|
NOTE: According to Qwertymine, flowlib.quickflow is only reliable for liquids with a flowing distance of 7.
|
||||||
|
@ -787,35 +792,33 @@ minetest.register_entity(":__builtin:item", {
|
||||||
-- Just to make sure we don't manipulate the speed for no reason
|
-- Just to make sure we don't manipulate the speed for no reason
|
||||||
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
|
if vec.x ~= 0 or vec.y ~= 0 or vec.z ~= 0 then
|
||||||
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
|
-- Minecraft Wiki: Flowing speed is "about 1.39 meters per second"
|
||||||
local f = item_drop_settings.fluid_flow_rate --1.39
|
local f = item_drop_settings.fluid_flow_rate or 1.2 --1.39
|
||||||
|
|
||||||
-- Apply the force of the flowing liquid onto the item's velocity
|
-- Apply the force of the flowing liquid onto the item's velocity
|
||||||
local newv = vector.multiply(vec, f)
|
local newv = vector.multiply(vec, f)
|
||||||
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
self.object:set_acceleration({x = 0, y = 0, z = 0})
|
||||||
|
|
||||||
local oldvel = self.object:get_velocity() -- v is vector, vel is velocity
|
local oldvel = self.object:get_velocity() -- v is vector, vel is velocity
|
||||||
|
|
||||||
-- drag
|
-- drag
|
||||||
local fluid_drag = item_drop_settings.fluid_drag
|
local fluid_drag = item_drop_settings.fluid_drag
|
||||||
|
local floornn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||||
local floornn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
local floornode = floornn and minetest.registered_nodes[floornn]
|
||||||
local floornode = floornn and minetest.registered_nodes[floornn]
|
|
||||||
if floornode and minetest.get_item_group(floornode.name, "slippery") then
|
if floornode and minetest.get_item_group(floornode.name, "slippery") then
|
||||||
-- scale fluid drag on slippery floors
|
-- scale fluid drag on slippery floors
|
||||||
fluid_drag = fluid_drag * item_drop_settings.slippery_fluid_drag_factor
|
fluid_drag = fluid_drag * item_drop_settings.slippery_fluid_drag_factor
|
||||||
end
|
end
|
||||||
|
|
||||||
newv.x = newv.x - (oldvel.x - newv.x) * fluid_drag * dtime
|
newv.x = newv.x - (oldvel.x - newv.x) * fluid_drag * dtime
|
||||||
newv.y = newv.y - (oldvel.y - newv.y) * fluid_drag * dtime
|
newv.y = newv.y - (oldvel.y - newv.y) * fluid_drag * dtime
|
||||||
newv.z = newv.z - (oldvel.z - newv.z) * fluid_drag * dtime
|
newv.z = newv.z - (oldvel.z - newv.z) * fluid_drag * dtime
|
||||||
|
|
||||||
newv.y = newv.y + -0.22 -- (keep slight downward thrust from previous version of code)
|
newv.y = newv.y + -0.22 -- (keep slight downward thrust from previous version of code)
|
||||||
-- NOTE: is there any particular reason we have this, anyway?
|
-- NOTE: is there any particular reason we have this, anyway?
|
||||||
-- since fluid drag is now on, we could as well just
|
-- since fluid drag is now on, we could as well just
|
||||||
-- apply gravity here; drag will slow down the fall
|
-- apply gravity here; drag will slow down the fall
|
||||||
-- realistically
|
-- realistically
|
||||||
|
|
||||||
self.object:set_velocity({x = oldvel.x + newv.x * dtime, y = oldvel.y + newv.y * dtime, z = oldvel.z + newv.z * dtime})
|
self.object:set_velocity({x = oldvel.x + newv.x * dtime, y = oldvel.y + newv.y * dtime, z = oldvel.z + newv.z * dtime})
|
||||||
|
-- Swap to acceleration instead of a static speed to better mimic MC mechanics.
|
||||||
|
-- self.object:set_acceleration({x = newv.x, y = -0.22, z = newv.z})
|
||||||
|
|
||||||
self.physical_state = true
|
self.physical_state = true
|
||||||
self._flowing = true
|
self._flowing = true
|
||||||
|
@ -836,8 +839,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
|
||||||
local v = self.object:get_velocity()
|
local v = self.object:get_velocity()
|
||||||
local node = nn and minetest.registered_nodes[nn]
|
local node = nn and minetest.registered_nodes[nn]
|
||||||
|
if not node or node.walkable and v.y == 0 and not node.groups.slippery then
|
||||||
if not node or node.walkable and v.y == 0 then
|
|
||||||
if self.physical_state then
|
if self.physical_state then
|
||||||
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
||||||
-- Merge with close entities of the same item
|
-- Merge with close entities of the same item
|
||||||
|
|
|
@ -432,7 +432,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
-- Slow down or speed up
|
-- Slow down or speed up
|
||||||
local acc = dir.y * -1.8
|
local acc = dir.y * -1.8
|
||||||
local friction = 0.4
|
local friction = 0.4
|
||||||
local speed_mod = minetest.registered_nodes[minetest.get_node(pos).name]._rail_acceleration
|
local ndef = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||||
|
local speed_mod = ndef and ndef._rail_acceleration
|
||||||
|
|
||||||
acc = acc - friction
|
acc = acc - friction
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ local function register_rail(itemstring, tiles, def_extras, creative)
|
||||||
stack_max = 64,
|
stack_max = 64,
|
||||||
groups = groups,
|
groups = groups,
|
||||||
sounds = mcl_sounds.node_sound_metal_defaults(),
|
sounds = mcl_sounds.node_sound_metal_defaults(),
|
||||||
_mcl_blast_resistance = 3.5,
|
_mcl_blast_resistance = 0.7,
|
||||||
_mcl_hardness = 0.7,
|
_mcl_hardness = 0.7,
|
||||||
after_destruct = function(pos)
|
after_destruct = function(pos)
|
||||||
-- Scan for minecarts in this pos and force them to execute their "floating" check.
|
-- Scan for minecarts in this pos and force them to execute their "floating" check.
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,456 +0,0 @@
|
||||||
|
|
||||||
-- lib_mount by Blert2112 (edited by TenPlus1)
|
|
||||||
|
|
||||||
--local enable_crash = false
|
|
||||||
--local crash_threshold = 6.5 -- ignored if enable_crash=false
|
|
||||||
|
|
||||||
local math = math
|
|
||||||
local vector = vector
|
|
||||||
|
|
||||||
------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Helper functions
|
|
||||||
--
|
|
||||||
|
|
||||||
--[[local function node_ok(pos, fallback)
|
|
||||||
|
|
||||||
fallback = fallback or mobs.fallback_node
|
|
||||||
|
|
||||||
local node = minetest.get_node_or_nil(pos)
|
|
||||||
|
|
||||||
if node and minetest.registered_nodes[node.name] then
|
|
||||||
return node
|
|
||||||
end
|
|
||||||
|
|
||||||
return {name = fallback}
|
|
||||||
end]]
|
|
||||||
|
|
||||||
|
|
||||||
--[[local function node_is(pos)
|
|
||||||
|
|
||||||
local node = node_ok(pos)
|
|
||||||
|
|
||||||
if node.name == "air" then
|
|
||||||
return "air"
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_item_group(node.name, "lava") ~= 0 then
|
|
||||||
return "lava"
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_item_group(node.name, "liquid") ~= 0 then
|
|
||||||
return "liquid"
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.registered_nodes[node.name].walkable == true then
|
|
||||||
return "walkable"
|
|
||||||
end
|
|
||||||
|
|
||||||
return "other"
|
|
||||||
end]]
|
|
||||||
|
|
||||||
|
|
||||||
local function get_sign(i)
|
|
||||||
|
|
||||||
i = i or 0
|
|
||||||
|
|
||||||
if i == 0 then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return i / math.abs(i)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
--[[local function get_velocity(v, yaw, y)
|
|
||||||
local x = -math.sin(yaw) * v
|
|
||||||
local z = math.cos(yaw) * v
|
|
||||||
return {x = x, y = y, z = z}
|
|
||||||
end]]
|
|
||||||
|
|
||||||
|
|
||||||
local function get_v(v)
|
|
||||||
return math.sqrt(v.x * v.x + v.z * v.z)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local function force_detach(player)
|
|
||||||
|
|
||||||
local attached_to = player:get_attach()
|
|
||||||
|
|
||||||
if not attached_to then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local entity = attached_to:get_luaentity()
|
|
||||||
|
|
||||||
if entity.driver
|
|
||||||
and entity.driver == player then
|
|
||||||
|
|
||||||
entity.driver = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
player:set_detach()
|
|
||||||
mcl_player.player_attached[player:get_player_name()] = false
|
|
||||||
player:set_eye_offset({x = 0, y = 0, z = 0}, {x = 0, y = 0, z = 0})
|
|
||||||
mcl_player.player_set_animation(player, "stand" , 30)
|
|
||||||
player:set_properties({visual_size = {x = 1, y = 1} })
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
|
||||||
force_detach(player)
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_shutdown(function()
|
|
||||||
local players = minetest.get_connected_players()
|
|
||||||
for i = 1, #players do
|
|
||||||
force_detach(players[i])
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_dieplayer(function(player)
|
|
||||||
force_detach(player)
|
|
||||||
return true
|
|
||||||
end)
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
function mobs.attach(entity, player)
|
|
||||||
|
|
||||||
local attach_at, eye_offset
|
|
||||||
|
|
||||||
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
|
|
||||||
entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0}
|
|
||||||
entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0}
|
|
||||||
entity.driver_scale = entity.driver_scale or {x = 1, y = 1}
|
|
||||||
|
|
||||||
local rot_view = 0
|
|
||||||
|
|
||||||
if entity.player_rotation.y == 90 then
|
|
||||||
rot_view = math.pi/2
|
|
||||||
end
|
|
||||||
|
|
||||||
attach_at = entity.driver_attach_at
|
|
||||||
eye_offset = entity.driver_eye_offset
|
|
||||||
entity.driver = player
|
|
||||||
|
|
||||||
force_detach(player)
|
|
||||||
|
|
||||||
player:set_attach(entity.object, "", attach_at, entity.player_rotation)
|
|
||||||
mcl_player.player_attached[player:get_player_name()] = true
|
|
||||||
player:set_eye_offset(eye_offset, {x = 0, y = 0, z = 0})
|
|
||||||
|
|
||||||
player:set_properties({
|
|
||||||
visual_size = {
|
|
||||||
x = entity.driver_scale.x,
|
|
||||||
y = entity.driver_scale.y
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.after(0.2, function(name)
|
|
||||||
local player = minetest.get_player_by_name(name)
|
|
||||||
if player then
|
|
||||||
mcl_player.player_set_animation(player, "sit_mount" , 30)
|
|
||||||
end
|
|
||||||
end, player:get_player_name())
|
|
||||||
|
|
||||||
player:set_look_horizontal(entity.object:get_yaw() - rot_view)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function mobs.detach(player, offset)
|
|
||||||
|
|
||||||
force_detach(player)
|
|
||||||
|
|
||||||
mcl_player.player_set_animation(player, "stand" , 30)
|
|
||||||
|
|
||||||
--local pos = player:get_pos()
|
|
||||||
|
|
||||||
--pos = {x = pos.x + offset.x, y = pos.y + 0.2 + offset.y, z = pos.z + offset.z}
|
|
||||||
|
|
||||||
player:add_velocity(vector.new(math.random(-6,6), math.random(5,8), math.random(-6,6))) --throw the rider off
|
|
||||||
|
|
||||||
--[[
|
|
||||||
minetest.after(0.1, function(name, pos)
|
|
||||||
local player = minetest.get_player_by_name(name)
|
|
||||||
if player then
|
|
||||||
player:set_pos(pos)
|
|
||||||
end
|
|
||||||
end, player:get_player_name(), pos)
|
|
||||||
]]--
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
|
|
||||||
|
|
||||||
--local rot_view = 0
|
|
||||||
|
|
||||||
--if entity.player_rotation.y == 90 then
|
|
||||||
-- rot_view = math.pi/2
|
|
||||||
--end
|
|
||||||
|
|
||||||
--local acce_y = 0
|
|
||||||
local velo = entity.object:get_velocity()
|
|
||||||
|
|
||||||
entity.v = get_v(velo) * get_sign(entity.v)
|
|
||||||
|
|
||||||
-- process controls
|
|
||||||
if entity.driver then
|
|
||||||
|
|
||||||
local ctrl = entity.driver:get_player_control()
|
|
||||||
|
|
||||||
-- move forwards
|
|
||||||
if ctrl.up then
|
|
||||||
|
|
||||||
mobs.set_velocity(entity, entity.run_velocity)
|
|
||||||
|
|
||||||
mobs.set_mob_animation(entity, moving_anim)
|
|
||||||
|
|
||||||
-- move backwards
|
|
||||||
elseif ctrl.down then
|
|
||||||
|
|
||||||
mobs.set_velocity(entity, -entity.run_velocity)
|
|
||||||
|
|
||||||
mobs.set_mob_animation(entity, moving_anim)
|
|
||||||
|
|
||||||
--halt
|
|
||||||
else
|
|
||||||
|
|
||||||
mobs.set_velocity(entity, 0)
|
|
||||||
|
|
||||||
mobs.set_mob_animation(entity, stand_anim)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- mob rotation
|
|
||||||
local rotate = entity.rotate
|
|
||||||
if rotate then
|
|
||||||
local driver_look_horizontal = entity.driver:get_look_horizontal() or 0
|
|
||||||
local yaw = driver_look_horizontal - rotate
|
|
||||||
entity.yaw = yaw
|
|
||||||
entity.object:set_yaw(yaw)
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
if can_fly then
|
|
||||||
|
|
||||||
-- fly up
|
|
||||||
if ctrl.jump then
|
|
||||||
velo.y = velo.y + 1
|
|
||||||
if velo.y > entity.accel then velo.y = entity.accel end
|
|
||||||
|
|
||||||
elseif velo.y > 0 then
|
|
||||||
velo.y = velo.y - 0.1
|
|
||||||
if velo.y < 0 then velo.y = 0 end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- fly down
|
|
||||||
if ctrl.sneak then
|
|
||||||
velo.y = velo.y - 1
|
|
||||||
if velo.y < -entity.accel then velo.y = -entity.accel end
|
|
||||||
|
|
||||||
elseif velo.y < 0 then
|
|
||||||
velo.y = velo.y + 0.1
|
|
||||||
if velo.y > 0 then velo.y = 0 end
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
]]--
|
|
||||||
|
|
||||||
-- jump
|
|
||||||
if ctrl.jump then
|
|
||||||
|
|
||||||
mobs.jump(entity)
|
|
||||||
end
|
|
||||||
|
|
||||||
--end
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[
|
|
||||||
-- set moving animation
|
|
||||||
if moving_anim then
|
|
||||||
mobs:set_mob_animation(entity, moving_anim)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Stop!
|
|
||||||
local s = get_sign(entity.v)
|
|
||||||
|
|
||||||
entity.v = entity.v - 0.02 * s
|
|
||||||
|
|
||||||
if s ~= get_sign(entity.v) then
|
|
||||||
|
|
||||||
entity.object:set_velocity({x = 0, y = 0, z = 0})
|
|
||||||
entity.v = 0
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- enforce speed limit forward and reverse
|
|
||||||
local max_spd = entity.max_speed_reverse
|
|
||||||
|
|
||||||
if get_sign(entity.v) >= 0 then
|
|
||||||
max_spd = entity.max_speed_forward
|
|
||||||
end
|
|
||||||
|
|
||||||
if math.abs(entity.v) > max_spd then
|
|
||||||
entity.v = entity.v - get_sign(entity.v)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Set position, velocity and acceleration
|
|
||||||
local p = entity.object:get_pos()
|
|
||||||
local new_velo
|
|
||||||
local new_acce = {x = 0, y = -9.8, z = 0}
|
|
||||||
|
|
||||||
p.y = p.y - 0.5
|
|
||||||
|
|
||||||
local ni = node_is(p)
|
|
||||||
local v = entity.v
|
|
||||||
|
|
||||||
if ni == "air" then
|
|
||||||
|
|
||||||
if can_fly == true then
|
|
||||||
new_acce.y = 0
|
|
||||||
end
|
|
||||||
|
|
||||||
elseif ni == "liquid" or ni == "lava" then
|
|
||||||
|
|
||||||
if ni == "lava" and entity.lava_damage ~= 0 then
|
|
||||||
|
|
||||||
entity.lava_counter = (entity.lava_counter or 0) + dtime
|
|
||||||
|
|
||||||
if entity.lava_counter > 1 then
|
|
||||||
|
|
||||||
minetest.sound_play("default_punch", {
|
|
||||||
object = entity.object,
|
|
||||||
max_hear_distance = 5
|
|
||||||
}, true)
|
|
||||||
|
|
||||||
entity.object:punch(entity.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {fleshy = entity.lava_damage}
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
entity.lava_counter = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if entity.terrain_type == 2
|
|
||||||
or entity.terrain_type == 3 then
|
|
||||||
|
|
||||||
new_acce.y = 0
|
|
||||||
p.y = p.y + 1
|
|
||||||
|
|
||||||
if node_is(p) == "liquid" then
|
|
||||||
|
|
||||||
if velo.y >= 5 then
|
|
||||||
velo.y = 5
|
|
||||||
elseif velo.y < 0 then
|
|
||||||
new_acce.y = 20
|
|
||||||
else
|
|
||||||
new_acce.y = 5
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if math.abs(velo.y) < 1 then
|
|
||||||
local pos = entity.object:get_pos()
|
|
||||||
pos.y = math.floor(pos.y) + 0.5
|
|
||||||
entity.object:set_pos(pos)
|
|
||||||
velo.y = 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
v = v * 0.25
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
new_velo = get_velocity(v, entity.object:get_yaw() - rot_view, velo.y)
|
|
||||||
new_acce.y = new_acce.y + acce_y
|
|
||||||
|
|
||||||
entity.object:set_velocity(new_velo)
|
|
||||||
entity.object:set_acceleration(new_acce)
|
|
||||||
|
|
||||||
-- CRASH!
|
|
||||||
if enable_crash then
|
|
||||||
|
|
||||||
local intensity = entity.v2 - v
|
|
||||||
|
|
||||||
if intensity >= crash_threshold then
|
|
||||||
|
|
||||||
entity.object:punch(entity.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {fleshy = intensity}
|
|
||||||
}, nil)
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
entity.v2 = v
|
|
||||||
]]--
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- directional flying routine by D00Med (edited by TenPlus1)
|
|
||||||
|
|
||||||
function mobs.fly(entity, dtime, speed, shoots, arrow, moving_anim, stand_anim)
|
|
||||||
if true then
|
|
||||||
print("succ")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local ctrl = entity.driver:get_player_control()
|
|
||||||
local velo = entity.object:get_velocity()
|
|
||||||
local dir = entity.driver:get_look_dir()
|
|
||||||
local yaw = entity.driver:get_look_horizontal() + 1.57 -- offset fix between old and new commands
|
|
||||||
|
|
||||||
if ctrl.up then
|
|
||||||
entity.object:set_velocity({
|
|
||||||
x = dir.x * speed,
|
|
||||||
y = dir.y * speed + 2,
|
|
||||||
z = dir.z * speed
|
|
||||||
})
|
|
||||||
|
|
||||||
elseif ctrl.down then
|
|
||||||
entity.object:set_velocity({
|
|
||||||
x = -dir.x * speed,
|
|
||||||
y = dir.y * speed + 2,
|
|
||||||
z = -dir.z * speed
|
|
||||||
})
|
|
||||||
|
|
||||||
elseif not ctrl.down or ctrl.up or ctrl.jump then
|
|
||||||
entity.object:set_velocity({x = 0, y = -2, z = 0})
|
|
||||||
end
|
|
||||||
|
|
||||||
entity.object:set_yaw(yaw + math.pi + math.pi / 2 - entity.rotate)
|
|
||||||
|
|
||||||
-- firing arrows
|
|
||||||
if ctrl.LMB and ctrl.sneak and shoots then
|
|
||||||
|
|
||||||
local pos = entity.object:get_pos()
|
|
||||||
local obj = minetest.add_entity({
|
|
||||||
x = pos.x + 0 + dir.x * 2.5,
|
|
||||||
y = pos.y + 1.5 + dir.y,
|
|
||||||
z = pos.z + 0 + dir.z * 2.5}, arrow)
|
|
||||||
|
|
||||||
local ent = obj:get_luaentity()
|
|
||||||
if ent then
|
|
||||||
ent.switch = 1 -- for mob specific arrows
|
|
||||||
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
|
|
||||||
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
|
|
||||||
local yaw = entity.driver:get_look_horizontal()
|
|
||||||
obj:set_yaw(yaw + math.pi / 2)
|
|
||||||
obj:set_velocity(vec)
|
|
||||||
else
|
|
||||||
obj:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- change animation if stopped
|
|
||||||
if velo.x == 0 and velo.y == 0 and velo.z == 0 then
|
|
||||||
|
|
||||||
mobs:set_mob_animation(entity, stand_anim)
|
|
||||||
else
|
|
||||||
-- moving animation
|
|
||||||
mobs:set_mob_animation(entity, moving_anim)
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mcl_mobs")
|
||||||
|
|
||||||
-- name tag
|
-- name tag
|
||||||
minetest.register_craftitem("mcl_mobs:nametag", {
|
minetest.register_craftitem("mcl_mobs:nametag", {
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
|
|
||||||
local path = minetest.get_modpath(minetest.get_current_modname())
|
local path = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
|
||||||
local api_path = path.."/api"
|
|
||||||
|
|
||||||
-- Mob API
|
-- Mob API
|
||||||
dofile(api_path .. "/api.lua")
|
dofile(path .. "/api.lua")
|
||||||
|
|
||||||
-- Spawning Algorithm
|
-- Spawning Algorithm
|
||||||
dofile(api_path .. "/spawning.lua")
|
dofile(path .. "/spawning.lua")
|
||||||
|
|
||||||
-- Rideable Mobs
|
-- Rideable Mobs
|
||||||
dofile(api_path .. "/mount.lua")
|
dofile(path .. "/mount.lua")
|
||||||
|
|
||||||
-- Mob Items
|
-- Mob Items
|
||||||
dofile(path .. "/crafts.lua")
|
dofile(path .. "/crafts.lua")
|
|
@ -1,11 +0,0 @@
|
||||||
# textdomain: mcl_mobs
|
|
||||||
Peaceful mode active! No monsters will spawn.=Tryb pokojowy aktywowany! Potwory nie będą się pojawiać.
|
|
||||||
This allows you to place a single mob.=To pozwala na przywołanie jednego moba.
|
|
||||||
Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=Postaw to w miejscu w którym chcesz aby pojawił się mob. Zwierzęta pojawią się jako oswojone chyba, że będziesz się skradał podczas stawiania. Jeśli postawisz to na spawnerze to zmienisz którego moba przywołuje.
|
|
||||||
You need the “maphack” privilege to change the mob spawner.=Potrzebujesz przywileju "maphack", aby zmienić spawner.
|
|
||||||
Name Tag=Znacznik
|
|
||||||
A name tag is an item to name a mob.=Znacznik jest przedmiotem pozwalającym nazwać moba.
|
|
||||||
Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=Zanim użyjesz znacznika musisz wybrać imię przy kowadle. Następnie możesz użyć znacznika by nazwać moba. To zużywa znacznik.
|
|
||||||
Only peaceful mobs allowed!=Tylko pokojowe moby są dozwolone!
|
|
||||||
Give names to mobs=Nazwij moby
|
|
||||||
Set name at anvil=Wybierz imię przy kowadle
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
# textdomain: mcl_mobs
|
||||||
|
Peaceful mode active! No monsters will spawn.=和平模式已啓用!不會生成怪物。
|
||||||
|
This allows you to place a single mob.=允許你放置一個生物。
|
||||||
|
Just place it where you want the mob to appear. Animals will spawn tamed, unless you hold down the sneak key while placing. If you place this on a mob spawner, you change the mob it spawns.=把它放在你希望生物出現的地方。除非你在放置的時候按住潛行鍵,否則動物會被馴服地產生。如果你把它放在一個生怪磚上,你就會改變它所產的生物。
|
||||||
|
You need the “maphack” privilege to change the mob spawner.=你要「maphack」權限來修改生怪磚。
|
||||||
|
Name Tag=命名牌
|
||||||
|
A name tag is an item to name a mob.=命名牌是一個用於命名生物的物品
|
||||||
|
Before you use the name tag, you need to set a name at an anvil. Then you can use the name tag to name a mob. This uses up the name tag.=在使用名字標籤之前,你需要在一個鐵砧上設置一個名字。然後你就可以用名字標籤來給生物命名。這會消耗命名牌。
|
||||||
|
Only peaceful mobs allowed!=只允許和平生物!
|
||||||
|
Give names to mobs=替生物命名
|
||||||
|
Set name at anvil=在鐵砧上設置名字
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
if minetest.get_modpath("lucky_block") then
|
||||||
|
|
||||||
|
lucky_block:add_blocks({
|
||||||
|
{"dro", {"mcl_mobs:nametag"}, 1},
|
||||||
|
{"lig"},
|
||||||
|
})
|
||||||
|
end
|
|
@ -1,5 +1,4 @@
|
||||||
name = mcl_mobs
|
name = mcl_mobs
|
||||||
author = PilzAdam
|
|
||||||
description = Adds a mob API for mods to add animals or monsters, etc.
|
description = Adds a mob API for mods to add animals or monsters, etc.
|
||||||
depends = mcl_mapgen, mcl_particles
|
depends = mcl_mapgen, mcl_particles
|
||||||
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience
|
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
|
|
||||||
default_punch.1 = https://freesound.org/people/Merrick079/sounds/566436/
|
|
||||||
default_punch.2 = https://freesound.org/people/Merrick079/sounds/566435/
|
|
||||||
default_punch.3 = https://freesound.org/people/Merrick079/sounds/566434/
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,488 @@
|
||||||
|
--lua locals
|
||||||
|
local get_node = minetest.get_node
|
||||||
|
local get_item_group = minetest.get_item_group
|
||||||
|
local get_node_light = minetest.get_node_light
|
||||||
|
local find_nodes_in_area_under_air = minetest.find_nodes_in_area_under_air
|
||||||
|
local get_biome_name = minetest.get_biome_name
|
||||||
|
local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local minetest_get_perlin = minetest.get_perlin
|
||||||
|
|
||||||
|
local math_random = math.random
|
||||||
|
local math_floor = math.floor
|
||||||
|
local math_ceil = math.ceil
|
||||||
|
local math_cos = math.cos
|
||||||
|
local math_sin = math.sin
|
||||||
|
local math_round = function(x) return (x > 0) and math_floor(x + 0.5) or math_ceil(x - 0.5) end
|
||||||
|
|
||||||
|
--local vector_distance = vector.distance
|
||||||
|
local vector_new = vector.new
|
||||||
|
local vector_floor = vector.floor
|
||||||
|
|
||||||
|
local table_copy = table.copy
|
||||||
|
local table_remove = table.remove
|
||||||
|
|
||||||
|
local pairs = pairs
|
||||||
|
|
||||||
|
-- range for mob count
|
||||||
|
local aoc_range = 32
|
||||||
|
|
||||||
|
--do mobs spawn?
|
||||||
|
local mobs_spawn = minetest.settings:get_bool("mobs_spawn", true) ~= false
|
||||||
|
|
||||||
|
|
||||||
|
local noise_params = {
|
||||||
|
offset = 0,
|
||||||
|
scale = 3,
|
||||||
|
spread = {
|
||||||
|
x = 301,
|
||||||
|
y = 50,
|
||||||
|
z = 304,
|
||||||
|
},
|
||||||
|
seed = 100,
|
||||||
|
octaves = 3,
|
||||||
|
persistence = 0.5,
|
||||||
|
}
|
||||||
|
|
||||||
|
-- THIS IS THE BIG LIST OF ALL BIOMES - used for programming/updating mobs
|
||||||
|
-- Also used for missing parameter
|
||||||
|
-- Please update the list when adding new biomes!
|
||||||
|
|
||||||
|
local list_of_all_biomes = {
|
||||||
|
|
||||||
|
-- underground:
|
||||||
|
|
||||||
|
"FlowerForest_underground",
|
||||||
|
"JungleEdge_underground",
|
||||||
|
"ColdTaiga_underground",
|
||||||
|
"IcePlains_underground",
|
||||||
|
"IcePlainsSpikes_underground",
|
||||||
|
"MegaTaiga_underground",
|
||||||
|
"Taiga_underground",
|
||||||
|
"ExtremeHills+_underground",
|
||||||
|
"JungleM_underground",
|
||||||
|
"ExtremeHillsM_underground",
|
||||||
|
"JungleEdgeM_underground",
|
||||||
|
|
||||||
|
-- ocean:
|
||||||
|
|
||||||
|
"RoofedForest_ocean",
|
||||||
|
"JungleEdgeM_ocean",
|
||||||
|
"BirchForestM_ocean",
|
||||||
|
"BirchForest_ocean",
|
||||||
|
"IcePlains_deep_ocean",
|
||||||
|
"Jungle_deep_ocean",
|
||||||
|
"Savanna_ocean",
|
||||||
|
"MesaPlateauF_ocean",
|
||||||
|
"ExtremeHillsM_deep_ocean",
|
||||||
|
"Savanna_deep_ocean",
|
||||||
|
"SunflowerPlains_ocean",
|
||||||
|
"Swampland_deep_ocean",
|
||||||
|
"Swampland_ocean",
|
||||||
|
"MegaSpruceTaiga_deep_ocean",
|
||||||
|
"ExtremeHillsM_ocean",
|
||||||
|
"JungleEdgeM_deep_ocean",
|
||||||
|
"SunflowerPlains_deep_ocean",
|
||||||
|
"BirchForest_deep_ocean",
|
||||||
|
"IcePlainsSpikes_ocean",
|
||||||
|
"Mesa_ocean",
|
||||||
|
"StoneBeach_ocean",
|
||||||
|
"Plains_deep_ocean",
|
||||||
|
"JungleEdge_deep_ocean",
|
||||||
|
"SavannaM_deep_ocean",
|
||||||
|
"Desert_deep_ocean",
|
||||||
|
"Mesa_deep_ocean",
|
||||||
|
"ColdTaiga_deep_ocean",
|
||||||
|
"Plains_ocean",
|
||||||
|
"MesaPlateauFM_ocean",
|
||||||
|
"Forest_deep_ocean",
|
||||||
|
"JungleM_deep_ocean",
|
||||||
|
"FlowerForest_deep_ocean",
|
||||||
|
"MushroomIsland_ocean",
|
||||||
|
"MegaTaiga_ocean",
|
||||||
|
"StoneBeach_deep_ocean",
|
||||||
|
"IcePlainsSpikes_deep_ocean",
|
||||||
|
"ColdTaiga_ocean",
|
||||||
|
"SavannaM_ocean",
|
||||||
|
"MesaPlateauF_deep_ocean",
|
||||||
|
"MesaBryce_deep_ocean",
|
||||||
|
"ExtremeHills+_deep_ocean",
|
||||||
|
"ExtremeHills_ocean",
|
||||||
|
"MushroomIsland_deep_ocean",
|
||||||
|
"Forest_ocean",
|
||||||
|
"MegaTaiga_deep_ocean",
|
||||||
|
"JungleEdge_ocean",
|
||||||
|
"MesaBryce_ocean",
|
||||||
|
"MegaSpruceTaiga_ocean",
|
||||||
|
"ExtremeHills+_ocean",
|
||||||
|
"Jungle_ocean",
|
||||||
|
"RoofedForest_deep_ocean",
|
||||||
|
"IcePlains_ocean",
|
||||||
|
"FlowerForest_ocean",
|
||||||
|
"ExtremeHills_deep_ocean",
|
||||||
|
"MesaPlateauFM_deep_ocean",
|
||||||
|
"Desert_ocean",
|
||||||
|
"Taiga_ocean",
|
||||||
|
"BirchForestM_deep_ocean",
|
||||||
|
"Taiga_deep_ocean",
|
||||||
|
"JungleM_ocean",
|
||||||
|
|
||||||
|
-- water or beach?
|
||||||
|
|
||||||
|
"MesaPlateauFM_sandlevel",
|
||||||
|
"MesaPlateauF_sandlevel",
|
||||||
|
"MesaBryce_sandlevel",
|
||||||
|
"Mesa_sandlevel",
|
||||||
|
|
||||||
|
-- beach:
|
||||||
|
|
||||||
|
"FlowerForest_beach",
|
||||||
|
"Forest_beach",
|
||||||
|
"StoneBeach",
|
||||||
|
"ColdTaiga_beach_water",
|
||||||
|
"Taiga_beach",
|
||||||
|
"Savanna_beach",
|
||||||
|
"Plains_beach",
|
||||||
|
"ExtremeHills_beach",
|
||||||
|
"ColdTaiga_beach",
|
||||||
|
"Swampland_shore",
|
||||||
|
"MushroomIslandShore",
|
||||||
|
"JungleM_shore",
|
||||||
|
"Jungle_shore",
|
||||||
|
|
||||||
|
-- dimension biome:
|
||||||
|
|
||||||
|
"Nether",
|
||||||
|
"End",
|
||||||
|
|
||||||
|
-- Overworld regular:
|
||||||
|
|
||||||
|
"Mesa",
|
||||||
|
"FlowerForest",
|
||||||
|
"Swampland",
|
||||||
|
"Taiga",
|
||||||
|
"ExtremeHills",
|
||||||
|
"Jungle",
|
||||||
|
"Savanna",
|
||||||
|
"BirchForest",
|
||||||
|
"MegaSpruceTaiga",
|
||||||
|
"MegaTaiga",
|
||||||
|
"ExtremeHills+",
|
||||||
|
"Forest",
|
||||||
|
"Plains",
|
||||||
|
"Desert",
|
||||||
|
"ColdTaiga",
|
||||||
|
"MushroomIsland",
|
||||||
|
"IcePlainsSpikes",
|
||||||
|
"SunflowerPlains",
|
||||||
|
"IcePlains",
|
||||||
|
"RoofedForest",
|
||||||
|
"ExtremeHills+_snowtop",
|
||||||
|
"MesaPlateauFM_grasstop",
|
||||||
|
"JungleEdgeM",
|
||||||
|
"ExtremeHillsM",
|
||||||
|
"JungleM",
|
||||||
|
"BirchForestM",
|
||||||
|
"MesaPlateauF",
|
||||||
|
"MesaPlateauFM",
|
||||||
|
"MesaPlateauF_grasstop",
|
||||||
|
"MesaBryce",
|
||||||
|
"JungleEdge",
|
||||||
|
"SavannaM",
|
||||||
|
"Nether",
|
||||||
|
"WarpedForest",
|
||||||
|
"SoulsandValley"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- count how many mobs are in an area
|
||||||
|
local function count_mobs(pos)
|
||||||
|
local num = 0
|
||||||
|
for _,object in pairs(get_objects_inside_radius(pos, aoc_range)) do
|
||||||
|
if object and object:get_luaentity() and object:get_luaentity().is_mob then
|
||||||
|
num = num + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return num
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- global functions
|
||||||
|
|
||||||
|
function mcl_mobs:spawn_abm_check(pos, node, name)
|
||||||
|
-- global function to add additional spawn checks
|
||||||
|
-- return true to stop spawning mob
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--[[
|
||||||
|
Custom elements changed:
|
||||||
|
|
||||||
|
name:
|
||||||
|
the mobs name
|
||||||
|
|
||||||
|
dimension:
|
||||||
|
"overworld"
|
||||||
|
"nether"
|
||||||
|
"end"
|
||||||
|
|
||||||
|
types of spawning:
|
||||||
|
"water"
|
||||||
|
"ground"
|
||||||
|
"lava"
|
||||||
|
|
||||||
|
biomes: tells the spawner to allow certain mobs to spawn in certain biomes
|
||||||
|
{"this", "that", "grasslands", "whatever"}
|
||||||
|
|
||||||
|
|
||||||
|
what is aoc??? objects in area
|
||||||
|
|
||||||
|
WARNING: BIOME INTEGRATION NEEDED -> How to get biome through lua??
|
||||||
|
]]--
|
||||||
|
|
||||||
|
|
||||||
|
--this is where all of the spawning information is kept
|
||||||
|
local spawn_dictionary = {}
|
||||||
|
local summary_chance = 0
|
||||||
|
|
||||||
|
function mcl_mobs:spawn_setup(def)
|
||||||
|
if not mobs_spawn then return end
|
||||||
|
|
||||||
|
if not def then
|
||||||
|
minetest.log("warning", "Empty mob spawn setup definition")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local name = def.name
|
||||||
|
if not name then
|
||||||
|
minetest.log("warning", "Missing mob name")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local dimension = def.dimension or "overworld"
|
||||||
|
local type_of_spawning = def.type_of_spawning or "ground"
|
||||||
|
local biomes = def.biomes or list_of_all_biomes
|
||||||
|
local min_light = def.min_light or 0
|
||||||
|
local max_light = def.max_light or (minetest.LIGHT_MAX + 1)
|
||||||
|
local chance = def.chance or 1000
|
||||||
|
local aoc = def.aoc or aoc_range
|
||||||
|
local min_height = def.min_height or mcl_mapgen.overworld.min
|
||||||
|
local max_height = def.max_height or mcl_mapgen.overworld.max
|
||||||
|
local day_toggle = def.day_toggle
|
||||||
|
local on_spawn = def.on_spawn
|
||||||
|
local check_position = def.check_position
|
||||||
|
|
||||||
|
-- chance/spawn number override in minetest.conf for registered mob
|
||||||
|
local numbers = minetest.settings:get(name)
|
||||||
|
if numbers then
|
||||||
|
numbers = numbers:split(",")
|
||||||
|
chance = tonumber(numbers[1]) or chance
|
||||||
|
aoc = tonumber(numbers[2]) or aoc
|
||||||
|
if chance == 0 then
|
||||||
|
minetest.log("warning", string.format("[mcl_mobs] %s has spawning disabled", name))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
minetest.log("action", string.format("[mcl_mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
|
||||||
|
end
|
||||||
|
|
||||||
|
if chance < 1 then
|
||||||
|
chance = 1
|
||||||
|
minetest.log("warning", "Chance shouldn't be less than 1 (mob name: " .. name ..")")
|
||||||
|
end
|
||||||
|
|
||||||
|
spawn_dictionary[#spawn_dictionary + 1] = {
|
||||||
|
name = name,
|
||||||
|
dimension = dimension,
|
||||||
|
type_of_spawning = type_of_spawning,
|
||||||
|
biomes = biomes,
|
||||||
|
min_light = min_light,
|
||||||
|
max_light = max_light,
|
||||||
|
chance = chance,
|
||||||
|
aoc = aoc,
|
||||||
|
min_height = min_height,
|
||||||
|
max_height = max_height,
|
||||||
|
day_toggle = day_toggle,
|
||||||
|
check_position = check_position,
|
||||||
|
on_spawn = on_spawn,
|
||||||
|
}
|
||||||
|
summary_chance = summary_chance + chance
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_mobs:spawn_specific(name, dimension, type_of_spawning, biomes, min_light, max_light, interval, chance, aoc, min_height, max_height, day_toggle, on_spawn)
|
||||||
|
|
||||||
|
-- Do mobs spawn at all?
|
||||||
|
if not mobs_spawn then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
-- chance/spawn number override in minetest.conf for registered mob
|
||||||
|
local numbers = minetest.settings:get(name)
|
||||||
|
|
||||||
|
if numbers then
|
||||||
|
numbers = numbers:split(",")
|
||||||
|
chance = tonumber(numbers[1]) or chance
|
||||||
|
aoc = tonumber(numbers[2]) or aoc
|
||||||
|
|
||||||
|
if chance == 0 then
|
||||||
|
minetest.log("warning", string.format("[mcl_mobs] %s has spawning disabled", name))
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.log("action", string.format("[mcl_mobs] Chance setting for %s changed to %s (total: %s)", name, chance, aoc))
|
||||||
|
end
|
||||||
|
|
||||||
|
--load information into the spawn dictionary
|
||||||
|
local key = #spawn_dictionary + 1
|
||||||
|
spawn_dictionary[key] = {}
|
||||||
|
spawn_dictionary[key]["name"] = name
|
||||||
|
spawn_dictionary[key]["dimension"] = dimension
|
||||||
|
spawn_dictionary[key]["type_of_spawning"] = type_of_spawning
|
||||||
|
spawn_dictionary[key]["biomes"] = biomes
|
||||||
|
spawn_dictionary[key]["min_light"] = min_light
|
||||||
|
spawn_dictionary[key]["max_light"] = max_light
|
||||||
|
spawn_dictionary[key]["chance"] = chance
|
||||||
|
spawn_dictionary[key]["aoc"] = aoc
|
||||||
|
spawn_dictionary[key]["min_height"] = min_height
|
||||||
|
spawn_dictionary[key]["max_height"] = max_height
|
||||||
|
spawn_dictionary[key]["day_toggle"] = day_toggle
|
||||||
|
|
||||||
|
summary_chance = summary_chance + chance
|
||||||
|
end
|
||||||
|
|
||||||
|
local two_pi = 2 * math.pi
|
||||||
|
local function get_next_mob_spawn_pos(pos)
|
||||||
|
local distance = math_random(25, 32)
|
||||||
|
local angle = math_random() * two_pi
|
||||||
|
return {
|
||||||
|
x = math_round(pos.x + distance * math_cos(angle)),
|
||||||
|
y = pos.y,
|
||||||
|
z = math_round(pos.z + distance * math_sin(angle))
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function decypher_limits(posy)
|
||||||
|
posy = math_floor(posy)
|
||||||
|
return posy - 32, posy + 32
|
||||||
|
end
|
||||||
|
|
||||||
|
--a simple helper function for mob_spawn
|
||||||
|
local function biome_check(biome_list, biome_goal)
|
||||||
|
for _, data in pairs(biome_list) do
|
||||||
|
if data == biome_goal then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function is_farm_animal(n)
|
||||||
|
return n == "mobs_mc:pig" or n == "mobs_mc:cow" or n == "mobs_mc:sheep" or n == "mobs_mc:chicken" or n == "mobs_mc:horse" or n == "mobs_mc:donkey"
|
||||||
|
end
|
||||||
|
|
||||||
|
if mobs_spawn then
|
||||||
|
|
||||||
|
local perlin_noise
|
||||||
|
|
||||||
|
local function spawn_a_mob(pos, dimension, y_min, y_max)
|
||||||
|
local dimension = dimension or mcl_worlds.pos_to_dimension(pos)
|
||||||
|
local goal_pos = get_next_mob_spawn_pos(pos)
|
||||||
|
local spawning_position_list = find_nodes_in_area_under_air(
|
||||||
|
{x = goal_pos.x, y = y_min, z = goal_pos.z},
|
||||||
|
{x = goal_pos.x, y = y_max, z = goal_pos.z},
|
||||||
|
{"group:solid", "group:water", "group:lava"}
|
||||||
|
)
|
||||||
|
if #spawning_position_list <= 0 then return end
|
||||||
|
local spawning_position = spawning_position_list[math_random(1, #spawning_position_list)]
|
||||||
|
|
||||||
|
--hard code mob limit in area to 5 for now
|
||||||
|
if count_mobs(spawning_position) >= 5 then return end
|
||||||
|
|
||||||
|
local gotten_node = get_node(spawning_position).name
|
||||||
|
local gotten_biome = minetest.get_biome_data(spawning_position)
|
||||||
|
if not gotten_node or not gotten_biome then return end
|
||||||
|
gotten_biome = get_biome_name(gotten_biome.biome) --makes it easier to work with
|
||||||
|
|
||||||
|
--add this so mobs don't spawn inside nodes
|
||||||
|
spawning_position.y = spawning_position.y + 1
|
||||||
|
|
||||||
|
--only need to poll for node light if everything else worked
|
||||||
|
local gotten_light = get_node_light(spawning_position)
|
||||||
|
|
||||||
|
local is_water = get_item_group(gotten_node, "water") ~= 0
|
||||||
|
local is_lava = get_item_group(gotten_node, "lava") ~= 0
|
||||||
|
local is_ground = not (is_water or is_lava)
|
||||||
|
local is_grass = minetest.get_item_group(gotten_node,"grass_block") ~= 0
|
||||||
|
local has_bed = minetest.find_node_near(pos,25,{"group:bed"})
|
||||||
|
|
||||||
|
if not is_ground then
|
||||||
|
spawning_position.y = spawning_position.y - 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local mob_def
|
||||||
|
|
||||||
|
--create a disconnected clone of the spawn dictionary
|
||||||
|
--prevents memory leak
|
||||||
|
local mob_library_worker_table = table_copy(spawn_dictionary)
|
||||||
|
|
||||||
|
--grab mob that fits into the spawning location
|
||||||
|
--randomly grab a mob, don't exclude any possibilities
|
||||||
|
perlin_noise = perlin_noise or minetest_get_perlin(noise_params)
|
||||||
|
local noise = perlin_noise:get_3d(spawning_position)
|
||||||
|
local current_summary_chance = summary_chance
|
||||||
|
table.shuffle(mob_library_worker_table)
|
||||||
|
while #mob_library_worker_table > 0 do
|
||||||
|
local mob_chance_offset = (math_round(noise * current_summary_chance + 12345) % current_summary_chance) + 1
|
||||||
|
local mob_index = 1
|
||||||
|
local mob_chance = mob_library_worker_table[mob_index].chance
|
||||||
|
local step_chance = mob_chance
|
||||||
|
while step_chance < mob_chance_offset do
|
||||||
|
mob_index = mob_index + 1
|
||||||
|
mob_chance = mob_library_worker_table[mob_index].chance
|
||||||
|
step_chance = step_chance + mob_chance
|
||||||
|
end
|
||||||
|
local mob_def = mob_library_worker_table[mob_index]
|
||||||
|
local mob_type = minetest.registered_entities[mob_def.name].type
|
||||||
|
if mob_def
|
||||||
|
and spawning_position.y >= mob_def.min_height
|
||||||
|
and spawning_position.y <= mob_def.max_height
|
||||||
|
and mob_def.dimension == dimension
|
||||||
|
and biome_check(mob_def.biomes, gotten_biome)
|
||||||
|
and gotten_light >= mob_def.min_light
|
||||||
|
and gotten_light <= mob_def.max_light
|
||||||
|
and (is_ground or mob_def.type_of_spawning ~= "ground")
|
||||||
|
and (mob_def.check_position and mob_def.check_position(spawning_position) or true)
|
||||||
|
and (not is_farm_animal(mob_def.name) or is_grass)
|
||||||
|
and (mob_type ~= "npc" or has_bed)
|
||||||
|
then
|
||||||
|
--everything is correct, spawn mob
|
||||||
|
local object = minetest.add_entity(spawning_position, mob_def.name)
|
||||||
|
if object then
|
||||||
|
return mob_def.on_spawn and mob_def.on_spawn(object, pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
current_summary_chance = current_summary_chance - mob_chance
|
||||||
|
table_remove(mob_library_worker_table, mob_index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
--MAIN LOOP
|
||||||
|
|
||||||
|
local timer = 0
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
timer = timer + dtime
|
||||||
|
if timer < 10 then return end
|
||||||
|
timer = 0
|
||||||
|
for _, player in pairs(get_connected_players()) do
|
||||||
|
local pos = player:get_pos()
|
||||||
|
local dimension = mcl_worlds.pos_to_dimension(pos)
|
||||||
|
-- ignore void and unloaded area
|
||||||
|
if dimension ~= "void" and dimension ~= "default" then
|
||||||
|
local y_min, y_max = decypher_limits(pos.y)
|
||||||
|
for i = 1, math_random(1, 4) do
|
||||||
|
spawn_a_mob(pos, dimension, y_min, y_max)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
|
@ -1 +0,0 @@
|
||||||
--use vector.distance to count down mob despawn timer
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
# textdomain:mcl_paintings
|
||||||
|
Painting=畫
|
|
@ -0,0 +1,51 @@
|
||||||
|
local dim = {"x", "z"}
|
||||||
|
|
||||||
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
|
||||||
|
local function load_schem(filename)
|
||||||
|
local file = io.open(modpath .. "/schems/" .. filename, "r")
|
||||||
|
local data = minetest.deserialize(file:read())
|
||||||
|
file:close()
|
||||||
|
return data
|
||||||
|
end
|
||||||
|
|
||||||
|
local wither_spawn_schems = {}
|
||||||
|
|
||||||
|
for _, d in pairs(dim) do
|
||||||
|
wither_spawn_schems[d] = load_schem("wither_spawn_" .. d .. ".we")
|
||||||
|
end
|
||||||
|
|
||||||
|
local function check_schem(pos, schem)
|
||||||
|
for _, n in pairs(schem) do
|
||||||
|
if minetest.get_node(vector.add(pos, n)).name ~= n.name then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remove_schem(pos, schem)
|
||||||
|
for _, n in pairs(schem) do
|
||||||
|
minetest.remove_node(vector.add(pos, n))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function wither_spawn(pos)
|
||||||
|
for _, d in pairs(dim) do
|
||||||
|
for i = 0, 2 do
|
||||||
|
local p = vector.add(pos, {x = 0, y = -2, z = 0, [d] = -i})
|
||||||
|
local schem = wither_spawn_schems[d]
|
||||||
|
if check_schem(p, schem) then
|
||||||
|
remove_schem(p, schem)
|
||||||
|
minetest.add_entity(vector.add(p, {x = 0, y = 1, z = 0, [d] = 1}), "mobs_mc:wither")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local wither_head = minetest.registered_nodes["mcl_heads:wither_skeleton"]
|
||||||
|
local old_on_place = wither_head.on_place
|
||||||
|
function wither_head.on_place(itemstack, placer, pointed)
|
||||||
|
minetest.after(0, wither_spawn, pointed.above)
|
||||||
|
old_on_place(itemstack, placer, pointed)
|
||||||
|
end
|
|
@ -0,0 +1,4 @@
|
||||||
|
name = mcl_wither_spawning
|
||||||
|
description = Wither Spawning for MineClone2
|
||||||
|
author = Fleckenstein
|
||||||
|
depends = mobs_mc, mcl_heads
|
|
@ -0,0 +1 @@
|
||||||
|
return {{["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}, {["y"] = 0, ["x"] = 1, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 1, ["x"] = 1, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 1, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}, {["y"] = 1, ["x"] = 2, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 2, ["x"] = 2, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 2, ["param1"] = 15}}
|
|
@ -0,0 +1 @@
|
||||||
|
return {{["y"] = 0, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 1}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 0}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 1}, {["y"] = 1, ["x"] = 0, ["name"] = "mcl_nether:soul_sand", ["z"] = 2}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 0, ["param2"] = 1, ["param1"] = 15}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 1, ["param2"] = 1, ["param1"] = 15}, {["y"] = 2, ["x"] = 0, ["name"] = "mcl_heads:wither_skeleton", ["z"] = 2, ["param2"] = 1, ["param1"] = 15}}
|
|
@ -1,334 +0,0 @@
|
||||||
--[[ This table contains the concrete itemstrings to be used by this mod.
|
|
||||||
All mobs in this mod must use variables in this table, instead
|
|
||||||
of hardcoding the itemstring.
|
|
||||||
This way, external mods are enabled to replace the itemstrings to provide
|
|
||||||
their own items and game integration is made much simpler.
|
|
||||||
|
|
||||||
An item IDs is supposed to be overwritten by adding
|
|
||||||
mobs_mc.override.items["example:item"] in a game mod
|
|
||||||
with name "mobs_mc_gameconfig". ]]
|
|
||||||
|
|
||||||
|
|
||||||
-- Standard items
|
|
||||||
|
|
||||||
-- If true, mobs_mc adds the monster egg nodes (needs default mod).
|
|
||||||
-- Set to false in your gameconfig mod if you create your own monster egg nodes.
|
|
||||||
mobs_mc.create_monster_egg_nodes = true
|
|
||||||
|
|
||||||
--mobs_mc.items = {}
|
|
||||||
|
|
||||||
mobs_mc.items = {
|
|
||||||
-- Items defined in mobs_mc
|
|
||||||
blaze_rod = "mobs_mc:blaze_rod",
|
|
||||||
blaze_powder = "mobs_mc:blaze_powder",
|
|
||||||
chicken_raw = "mobs_mc:chicken_raw",
|
|
||||||
chicken_cooked = "mobs_mc:chicken_cooked",
|
|
||||||
feather = "mobs_mc:feather",
|
|
||||||
beef_raw = "mobs_mc:beef_raw",
|
|
||||||
beef_cooked = "mobs_mc:beef_cooked",
|
|
||||||
bowl = "mobs_mc:bowl",
|
|
||||||
mushroom_stew = "mobs_mc:mushroom_stew",
|
|
||||||
milk = "mobs_mc:milk_bucket",
|
|
||||||
dragon_egg = "mobs_mc:dragon_egg",
|
|
||||||
egg = "mobs_mc:egg",
|
|
||||||
ender_eye = "mobs_mc:ender_eye",
|
|
||||||
ghast_tear = "mobs_mc:ghast_tear",
|
|
||||||
saddle = "mobs:saddle",
|
|
||||||
iron_horse_armor = "mobs_mc:iron_horse_armor",
|
|
||||||
gold_horse_armor = "mobs_mc:gold_horse_armor",
|
|
||||||
diamond_horse_armor = "mobs_mc:diamond_horse_armor",
|
|
||||||
porkchop_raw = "mobs_mc:porkchop_raw",
|
|
||||||
porkchop_cooked = "mobs_mc:porkchop_cooked",
|
|
||||||
carrot_on_a_stick = "mobs_mc:carrot_on_a_stick",
|
|
||||||
rabbit_raw = "mobs_mc:rabbit_raw",
|
|
||||||
rabbit_cooked = "mobs_mc:rabbit_cooked",
|
|
||||||
rabbit_hide = "mobs_mc:rabbit_hide",
|
|
||||||
mutton_raw = "mobs_mc:mutton_raw",
|
|
||||||
mutton_cooked = "mobs_mc:mutton_cooked",
|
|
||||||
shulker_shell = "mobs_mc:shulker_shell",
|
|
||||||
magma_cream = "mobs_mc:magma_cream",
|
|
||||||
spider_eye = "mobs_mc:spider_eye",
|
|
||||||
snowball = "mobs_mc:snowball",
|
|
||||||
totem = "mobs_mc:totem",
|
|
||||||
rotten_flesh = "mobs_mc:rotten_flesh",
|
|
||||||
nether_star = "mobs_mc:nether_star",
|
|
||||||
bone = "mobs_mc:bone",
|
|
||||||
slimeball = "mobs_mc:slimeball",
|
|
||||||
arrow = "mobs_mc:arrow",
|
|
||||||
bow = "mobs_mc:bow_wood",
|
|
||||||
head_creeper = "mobs_mc:head_creeper",
|
|
||||||
head_zombie = "mobs_mc:head_zombie",
|
|
||||||
head_skeleton = "mobs_mc:head_skeleton",
|
|
||||||
head_wither_skeleton = "mobs_mc:head_wither_skeleton",
|
|
||||||
|
|
||||||
-- External items
|
|
||||||
-- Mobs Redo
|
|
||||||
leather = "mobs:leather",
|
|
||||||
shears = "mobs:shears",
|
|
||||||
|
|
||||||
-- Minetest Game
|
|
||||||
top_snow = "default:snow",
|
|
||||||
snow_block = "default:snowblock",
|
|
||||||
mushroom_red = "flowers:mushroom_red",
|
|
||||||
bucket = "bucket:bucket_empty",
|
|
||||||
grass_block = "default:dirt_with_grass",
|
|
||||||
string = "farming:string",
|
|
||||||
stick = "default:stick",
|
|
||||||
flint = "default:flint",
|
|
||||||
iron_ingot = "default:steel_ingot",
|
|
||||||
iron_block = "default:steelblock",
|
|
||||||
fire = "fire:basic_flame",
|
|
||||||
gunpowder = "tnt:gunpowder",
|
|
||||||
flint_and_steel = "fire:flint_and_steel",
|
|
||||||
water_source = "default:water_source",
|
|
||||||
water_flowing = "default:water_flowing",
|
|
||||||
river_water_source = "default:river_water_source",
|
|
||||||
--water_flowing = "default:river_water_flowing",
|
|
||||||
black_dye = "dye:black",
|
|
||||||
poppy = "flowers:rose",
|
|
||||||
dandelion = "flowers:dandelion_yellow",
|
|
||||||
coal = "default:coal_lump",
|
|
||||||
emerald = "default:diamond",
|
|
||||||
iron_axe = "default:axe_steel",
|
|
||||||
gold_sword = "default:sword_mese",
|
|
||||||
gold_ingot = "default:gold_ingot",
|
|
||||||
gold_nugget = "default:gold_lump",
|
|
||||||
glowstone_dust = "default:mese_crystal_fragment",
|
|
||||||
redstone = "default:mese_crystal_fragment",
|
|
||||||
glass_bottle = "vessels:glass_bottle",
|
|
||||||
sugar = "default:papyrus",
|
|
||||||
wheat = "farming:wheat",
|
|
||||||
hay_bale = "farming:straw",
|
|
||||||
prismarine_shard = "default:mese_crystal_fragment",
|
|
||||||
prismarine_crystals = "default:mese_crystal",
|
|
||||||
apple = "default:apple",
|
|
||||||
golden_apple = "default:apple",
|
|
||||||
rabbit_foot = "mobs_mc:rabbit_foot",
|
|
||||||
|
|
||||||
-- Boss items
|
|
||||||
wet_sponge = "default:gold_block", -- only dropped by elder guardian; there is no equivalent block in Minetest Game
|
|
||||||
|
|
||||||
-- Other
|
|
||||||
nether_brick_block = "nether:brick",
|
|
||||||
mycelium = "ethereal:mushroom_dirt",
|
|
||||||
carrot = "farming:carrot",
|
|
||||||
potato = "farming:potato",
|
|
||||||
golden_carrot = "farming:carrot_gold",
|
|
||||||
fishing_rod = "fishing:pole_wood",
|
|
||||||
fish_raw = "fishing:fish_raw",
|
|
||||||
salmon_raw = "fishing:carp_raw",
|
|
||||||
clownfish_raw = "fishing:clownfish_raw",
|
|
||||||
pufferfish_raw = "fishing:pike_raw",
|
|
||||||
|
|
||||||
cookie = "farming:cookie",
|
|
||||||
|
|
||||||
|
|
||||||
-- TODO: Add actual ender pearl
|
|
||||||
ender_pearl = "farorb:farorb",
|
|
||||||
|
|
||||||
nether_portal = "nether:portal",
|
|
||||||
netherrack = "nether:rack",
|
|
||||||
|
|
||||||
-- Wool (Minecraft color scheme)
|
|
||||||
wool_white = "wool:white",
|
|
||||||
wool_light_grey = "wool:grey",
|
|
||||||
wool_grey = "wool:dark_grey",
|
|
||||||
wool_blue = "wool:blue",
|
|
||||||
wool_lime = "wool:green",
|
|
||||||
wool_green = "wool:dark_green",
|
|
||||||
wool_purple = "wool:violet",
|
|
||||||
wool_pink = "wool:pink",
|
|
||||||
wool_yellow = "wool:yellow",
|
|
||||||
wool_orange = "wool:orange",
|
|
||||||
wool_brown = "wool:brown",
|
|
||||||
wool_red = "wool:red",
|
|
||||||
wool_cyan = "wool:cyan",
|
|
||||||
wool_magenta = "wool:magenta",
|
|
||||||
wool_black = "wool:black",
|
|
||||||
-- Light blue intentionally missing
|
|
||||||
|
|
||||||
-- Special items
|
|
||||||
music_discs = {}, -- No music discs by default; used by creeper. Override this if your game has music discs.
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Tables for attracting, feeding and breeding mobs
|
|
||||||
mobs_mc.follow = {
|
|
||||||
sheep = { mobs_mc.items.wheat },
|
|
||||||
cow = { mobs_mc.items.wheat },
|
|
||||||
chicken = { "farming:seed_wheat", "farming:seed_cotton" }, -- seeds in general
|
|
||||||
parrot = { "farming:seed_wheat", "farming:seed_cotton" }, -- seeds in general
|
|
||||||
horse = { mobs_mc.items.apple, mobs_mc.items.sugar, mobs_mc.items.wheat, mobs_mc.items.hay_bale, mobs_mc.items.golden_apple, mobs_mc.items.golden_carrot },
|
|
||||||
llama = { mobs_mc.items.wheat, mobs_mc.items.hay_bale, },
|
|
||||||
pig = { mobs_mc.items.potato, mobs_mc.items.carrot, mobs_mc.items.carrot_on_a_stick,
|
|
||||||
mobs_mc.items.apple, -- Minetest Game extra
|
|
||||||
},
|
|
||||||
rabbit = { mobs_mc.items.dandelion, mobs_mc.items.carrot, mobs_mc.items.golden_carrot, "farming_plus:carrot_item", },
|
|
||||||
ocelot = { mobs_mc.items.fish_raw, mobs_mc.items.salmon_raw, mobs_mc.items.clownfish_raw, mobs_mc.items.pufferfish_raw,
|
|
||||||
mobs_mc.items.chicken_raw, -- Minetest Game extra
|
|
||||||
},
|
|
||||||
wolf = { mobs_mc.items.bone },
|
|
||||||
dog = { mobs_mc.items.rabbit_raw, mobs_mc.items.rabbit_cooked, mobs_mc.items.mutton_raw, mobs_mc.items.mutton_cooked, mobs_mc.items.beef_raw, mobs_mc.items.beef_cooked, mobs_mc.items.chicken_raw, mobs_mc.items.chicken_cooked, mobs_mc.items.rotten_flesh,
|
|
||||||
-- Mobs Redo items
|
|
||||||
"mobs:meat", "mobs:meat_raw" },
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Contents for replace_what
|
|
||||||
mobs_mc.replace = {
|
|
||||||
-- Rabbits reduce carrot growth stage by 1
|
|
||||||
rabbit = {
|
|
||||||
-- Farming Redo carrots
|
|
||||||
{"farming:carrot_8", "farming:carrot_7", 0},
|
|
||||||
{"farming:carrot_7", "farming:carrot_6", 0},
|
|
||||||
{"farming:carrot_6", "farming:carrot_5", 0},
|
|
||||||
{"farming:carrot_5", "farming:carrot_4", 0},
|
|
||||||
{"farming:carrot_4", "farming:carrot_3", 0},
|
|
||||||
{"farming:carrot_3", "farming:carrot_2", 0},
|
|
||||||
{"farming:carrot_2", "farming:carrot_1", 0},
|
|
||||||
{"farming:carrot_1", "air", 0},
|
|
||||||
-- Farming Plus carrots
|
|
||||||
{"farming_plus:carrot", "farming_plus:carrot_7", 0},
|
|
||||||
{"farming_plus:carrot_6", "farming_plus:carrot_5", 0},
|
|
||||||
{"farming_plus:carrot_5", "farming_plus:carrot_4", 0},
|
|
||||||
{"farming_plus:carrot_4", "farming_plus:carrot_3", 0},
|
|
||||||
{"farming_plus:carrot_3", "farming_plus:carrot_2", 0},
|
|
||||||
{"farming_plus:carrot_2", "farming_plus:carrot_1", 0},
|
|
||||||
{"farming_plus:carrot_1", "air", 0},
|
|
||||||
},
|
|
||||||
-- Sheep eat grass
|
|
||||||
sheep = {
|
|
||||||
-- Grass Block
|
|
||||||
{ "default:dirt_with_grass", "default:dirt", -1 },
|
|
||||||
-- “Tall Grass”
|
|
||||||
{ "default:grass_5", "air", 0 },
|
|
||||||
{ "default:grass_4", "air", 0 },
|
|
||||||
{ "default:grass_3", "air", 0 },
|
|
||||||
{ "default:grass_2", "air", 0 },
|
|
||||||
{ "default:grass_1", "air", 0 },
|
|
||||||
},
|
|
||||||
-- Silverfish populate stone, etc. with monster eggs
|
|
||||||
silverfish = {
|
|
||||||
{"default:stone", "mobs_mc:monster_egg_stone", -1},
|
|
||||||
{"default:cobble", "mobs_mc:monster_egg_cobble", -1},
|
|
||||||
{"default:mossycobble", "mobs_mc:monster_egg_mossycobble", -1},
|
|
||||||
{"default:stonebrick", "mobs_mc:monster_egg_stonebrick", -1},
|
|
||||||
{"default:stone_block", "mobs_mc:monster_egg_stone_block", -1},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
-- List of nodes which endermen can take
|
|
||||||
mobs_mc.enderman_takable = {
|
|
||||||
-- Generic handling, useful for entensions
|
|
||||||
"group:enderman_takable",
|
|
||||||
|
|
||||||
-- Generic nodes
|
|
||||||
"group:sand",
|
|
||||||
"group:flower",
|
|
||||||
|
|
||||||
-- Minetest Game
|
|
||||||
"default:dirt",
|
|
||||||
"default:dirt_with_grass",
|
|
||||||
"default:dirt_with_dry_grass",
|
|
||||||
"default:dirt_with_snow",
|
|
||||||
"default:dirt_with_rainforest_litter",
|
|
||||||
"default:dirt_with_grass_footsteps",
|
|
||||||
-- FIXME: For some reason, Minetest has a Lua error when an enderman tries to place a Minetest Game cactus.
|
|
||||||
-- Maybe this is because default:cactus has rotate_and_place?
|
|
||||||
-- "default:cactus", -- TODO: Re-enable cactus when it works again
|
|
||||||
"default:gravel",
|
|
||||||
"default:clay",
|
|
||||||
"flowers:mushroom_red",
|
|
||||||
"flowers:mushroom_brown",
|
|
||||||
"tnt:tnt",
|
|
||||||
|
|
||||||
-- Nether mod
|
|
||||||
"nether:rack",
|
|
||||||
}
|
|
||||||
|
|
||||||
--[[ Table of nodes to replace when an enderman takes it.
|
|
||||||
If the enderman takes an indexed node, it the enderman will get the item in the value.
|
|
||||||
Table indexes: Original node, taken by enderman.
|
|
||||||
Table values: The item which the enderman *actually* gets
|
|
||||||
Example:
|
|
||||||
mobs_mc.enderman_node_replace = {
|
|
||||||
["default:dirt_with_dry_grass"] = "default_dirt_with_grass",
|
|
||||||
}
|
|
||||||
-- This means, if the enderman takes a dirt with dry grass, he will get a dirt with grass
|
|
||||||
-- on his hand instead.
|
|
||||||
]]
|
|
||||||
mobs_mc.enderman_replace_on_take = {} -- no replacements by default
|
|
||||||
|
|
||||||
-- A table which can be used to override block textures of blocks carried by endermen.
|
|
||||||
-- Only works for cube-shaped nodes and nodeboxes.
|
|
||||||
-- Key: itemstrings of the blocks to replace
|
|
||||||
-- Value: A table with the texture overrides (6 textures)
|
|
||||||
mobs_mc.enderman_block_texture_overrides = {
|
|
||||||
}
|
|
||||||
|
|
||||||
-- List of nodes on which mobs can spawn
|
|
||||||
mobs_mc.spawn = {
|
|
||||||
solid = { "group:cracky", "group:crumbly", "group:shovely", "group:pickaxey" }, -- spawn on "solid" nodes (this is mostly just guessing)
|
|
||||||
|
|
||||||
grassland = { mobs_mc.items.grass_block, "ethereal:prairie_dirt" },
|
|
||||||
savanna = { "default:dirt_with_dry_grass" },
|
|
||||||
grassland_savanna = { mobs_mc.items.grass_block, "default:dirt_with_dry_grass" },
|
|
||||||
desert = { "default:desert_sand", "group:sand" },
|
|
||||||
jungle = { "default:dirt_with_rainforest_litter", "default:jungleleaves", "default:junglewood", "mcl_core:jungleleaves", "mcl_core:junglewood" },
|
|
||||||
snow = { "default:snow", "default:snowblock", "default:dirt_with_snow" },
|
|
||||||
end_city = { "default:sandstonebrick", "mcl_end:purpur_block", "mcl_end:end_stone" },
|
|
||||||
wolf = { mobs_mc.items.grass_block, "default:dirt_with_rainforest_litter", "default:dirt", "default:dirt_with_snow", "default:snow", "default:snowblock" },
|
|
||||||
village = { "mg_villages:road" },
|
|
||||||
|
|
||||||
-- These probably don't need overrides
|
|
||||||
mushroom_island = { mobs_mc.items.mycelium, "mcl_core:mycelium" },
|
|
||||||
nether_fortress = { mobs_mc.items.nether_brick_block, "mcl_nether:nether_brick", },
|
|
||||||
nether = { mobs_mc.items.netherrack, "mcl_nether:netherrack", },
|
|
||||||
nether_portal = { mobs_mc.items.nether_portal, "mcl_portals:portal" },
|
|
||||||
water = { mobs_mc.items.water_source, "mcl_core:water_source", "default:water_source" },
|
|
||||||
}
|
|
||||||
|
|
||||||
-- This table contains important spawn height references for the mob spawn height.
|
|
||||||
-- Please base your mob spawn height on these numbers to keep things clean.
|
|
||||||
mobs_mc.spawn_height = {
|
|
||||||
water = tonumber(minetest.settings:get("water_level")) or 0, -- Water level in the Overworld
|
|
||||||
|
|
||||||
-- Overworld boundaries (inclusive) --I adjusted this to be more reasonable
|
|
||||||
overworld_min = -64,-- -2999,
|
|
||||||
overworld_max = 31000,
|
|
||||||
|
|
||||||
-- Nether boundaries (inclusive)
|
|
||||||
nether_min = -29067,-- -3369,
|
|
||||||
nether_max = -28939,-- -3000,
|
|
||||||
|
|
||||||
-- End boundaries (inclusive)
|
|
||||||
end_min = -6200,
|
|
||||||
end_max = -6000,
|
|
||||||
}
|
|
||||||
|
|
||||||
mobs_mc.misc = {
|
|
||||||
shears_wear = 276, -- Wear to add per shears usage (238 uses)
|
|
||||||
totem_fail_nodes = {} -- List of nodes in which the totem of undying fails
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Item name overrides from mobs_mc_gameconfig (if present)
|
|
||||||
if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override then
|
|
||||||
local tables = {"items", "follow", "replace", "spawn", "spawn_height", "misc"}
|
|
||||||
for t=1, #tables do
|
|
||||||
local tbl = tables[t]
|
|
||||||
if mobs_mc.override[tbl] then
|
|
||||||
for k, v in pairs(mobs_mc.override[tbl]) do
|
|
||||||
mobs_mc[tbl][k] = v
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if mobs_mc.override.enderman_takable then
|
|
||||||
mobs_mc.enderman_takable = mobs_mc.override.enderman_takable
|
|
||||||
end
|
|
||||||
if mobs_mc.override.enderman_replace_on_take then
|
|
||||||
mobs_mc.enderman_replace_on_take = mobs_mc.override.enderman_replace_on_take
|
|
||||||
end
|
|
||||||
if mobs_mc.enderman_block_texture_overrides then
|
|
||||||
mobs_mc.enderman_block_texture_overrides = mobs_mc.override.enderman_block_texture_overrides
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -1,402 +0,0 @@
|
||||||
--MCmobs v0.5
|
|
||||||
--maikerumine
|
|
||||||
--made for MC like Survival game
|
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
|
||||||
|
|
||||||
-- NOTE: Strings intentionally not marked for translation, other mods already have these items.
|
|
||||||
-- TODO: Remove this file eventually, all items here are already outsourced in other mods.
|
|
||||||
|
|
||||||
--local S = minetest.get_translator(minetest.get_current_modname())
|
|
||||||
|
|
||||||
--maikerumines throwing code
|
|
||||||
--arrow (weapon)
|
|
||||||
|
|
||||||
local c = mobs_mc.is_item_variable_overridden
|
|
||||||
|
|
||||||
minetest.register_node("mobs_mc:arrow_box", {
|
|
||||||
drawtype = "nodebox",
|
|
||||||
is_ground_content = false,
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
-- Shaft
|
|
||||||
{-6.5/17, -1.5/17, -1.5/17, -4.5/17, 1.5/17, 1.5/17},
|
|
||||||
{-4.5/17, -0.5/17, -0.5/17, 5.5/17, 0.5/17, 0.5/17},
|
|
||||||
{5.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17},
|
|
||||||
-- Tip
|
|
||||||
{-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17},
|
|
||||||
{-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17},
|
|
||||||
-- Fletching
|
|
||||||
{6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17},
|
|
||||||
{7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17},
|
|
||||||
{7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17},
|
|
||||||
{6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17},
|
|
||||||
|
|
||||||
{7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17},
|
|
||||||
{8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17},
|
|
||||||
{8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17},
|
|
||||||
{7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
tiles = {"mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow.png^[transformFX", "mcl_bows_arrow_back.png", "mcl_bows_arrow_front.png", "mcl_bows_arrow.png", "mcl_bows_arrow.png^[transformFX"},
|
|
||||||
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2 = "facedir",
|
|
||||||
sunlight_propagates = true,
|
|
||||||
groups = {not_in_creative_inventory=1, dig_immediate=3},
|
|
||||||
node_placement_prediction = "",
|
|
||||||
on_construct = function(pos)
|
|
||||||
minetest.log("error", "[mobs_mc] Trying to construct mobs_mc:arrow_box at "..minetest.pos_to_string(pos))
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
end,
|
|
||||||
drop = "",
|
|
||||||
})
|
|
||||||
|
|
||||||
local THROWING_ARROW_ENTITY={
|
|
||||||
physical = false,
|
|
||||||
timer=0,
|
|
||||||
visual = "wielditem",
|
|
||||||
visual_size = {x=0.1, y=0.1},
|
|
||||||
textures = {"mobs_mc:arrow_box"},
|
|
||||||
velocity = 10,
|
|
||||||
lastpos={},
|
|
||||||
collisionbox = {0,0,0,0,0,0},
|
|
||||||
}
|
|
||||||
|
|
||||||
--ARROW CODE
|
|
||||||
THROWING_ARROW_ENTITY.on_step = function(self, dtime)
|
|
||||||
self.timer=self.timer+dtime
|
|
||||||
local pos = self.object:get_pos()
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
|
|
||||||
minetest.add_particle({
|
|
||||||
pos = pos,
|
|
||||||
velocity = {x=0, y=0, z=0},
|
|
||||||
acceleration = {x=0, y=0, z=0},
|
|
||||||
expirationtime = .3,
|
|
||||||
size = 1,
|
|
||||||
collisiondetection = false,
|
|
||||||
vertical = false,
|
|
||||||
texture = "mobs_mc_arrow_particle.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
if self.timer>0.2 then
|
|
||||||
local objs = minetest.get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1.5)
|
|
||||||
for k, obj in pairs(objs) do
|
|
||||||
if obj:get_luaentity() then
|
|
||||||
if obj:get_luaentity().name ~= "mobs_mc:arrow_entity" and obj:get_luaentity().name ~= "__builtin:item" then
|
|
||||||
local damage = 3
|
|
||||||
minetest.sound_play("damage", {pos = pos}, true)
|
|
||||||
obj:punch(self.object, 1.0, {
|
|
||||||
full_punch_interval=1.0,
|
|
||||||
damage_groups={fleshy=damage},
|
|
||||||
}, nil)
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
else
|
|
||||||
local damage = 3
|
|
||||||
minetest.sound_play("damage", {pos = pos}, true)
|
|
||||||
obj:punch(self.object, 1.0, {
|
|
||||||
full_punch_interval=1.0,
|
|
||||||
damage_groups={fleshy=damage},
|
|
||||||
}, nil)
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if self.lastpos.x~=nil then
|
|
||||||
if node.name ~= "air" then
|
|
||||||
minetest.sound_play("bowhit1", {pos = pos}, true)
|
|
||||||
minetest.add_item(self.lastpos, "mobs_mc:arrow")
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.lastpos={x=pos.x, y=pos.y, z=pos.z}
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_entity("mobs_mc:arrow_entity", THROWING_ARROW_ENTITY)
|
|
||||||
|
|
||||||
local arrows = {
|
|
||||||
{"mobs_mc:arrow", "mobs_mc:arrow_entity" },
|
|
||||||
}
|
|
||||||
|
|
||||||
local throwing_shoot_arrow = function(itemstack, player)
|
|
||||||
for _,arrow in pairs(arrows) do
|
|
||||||
if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then
|
|
||||||
if not minetest.is_creative_enabled(player:get_player_name()) then
|
|
||||||
player:get_inventory():remove_item("main", arrow[1])
|
|
||||||
end
|
|
||||||
local playerpos = player:get_pos()
|
|
||||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, arrow[2]) --mc
|
|
||||||
local dir = player:get_look_dir()
|
|
||||||
obj:set_velocity({x=dir.x*22, y=dir.y*22, z=dir.z*22})
|
|
||||||
obj:set_acceleration({x=dir.x*-3, y=-10, z=dir.z*-3})
|
|
||||||
obj:set_yaw(player:get_look_yaw()+math.pi)
|
|
||||||
minetest.sound_play("throwing_sound", {pos=playerpos}, true)
|
|
||||||
if obj:get_luaentity().player == "" then
|
|
||||||
obj:get_luaentity().player = player
|
|
||||||
end
|
|
||||||
obj:get_luaentity().node = player:get_inventory():get_stack("main", 1):get_name()
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if c("arrow") then
|
|
||||||
minetest.register_craftitem("mobs_mc:arrow", {
|
|
||||||
description = "Arrow",
|
|
||||||
_doc_items_longdesc = "Arrows are ammunition for bows.",
|
|
||||||
_doc_items_usagehelp = "To use arrows as ammunition for a bow, put them in the inventory slot following the bow. Slots are counted left to right, top to bottom.",
|
|
||||||
inventory_image = "mcl_bows_arrow_inv.png",
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if c("arrow") and c("flint") and c("feather") and c("stick") then
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "mobs_mc:arrow 4",
|
|
||||||
recipe = {
|
|
||||||
{mobs_mc.items.flint},
|
|
||||||
{mobs_mc.items.stick},
|
|
||||||
{mobs_mc.items.feather},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
if c("bow") then
|
|
||||||
minetest.register_tool("mobs_mc:bow_wood", {
|
|
||||||
description = "Bow",
|
|
||||||
_doc_items_longdesc = "Bows are ranged weapons to shoot arrows at your foes.",
|
|
||||||
_doc_items_usagehelp = "To use the bow, you first need to have at least one arrow in slot following the bow. Leftclick to shoot. Each hit deals 3 damage.",
|
|
||||||
inventory_image = "mcl_bows_bow.png",
|
|
||||||
on_use = function(itemstack, user, pointed_thing)
|
|
||||||
if throwing_shoot_arrow(itemstack, user, pointed_thing) then
|
|
||||||
if not minetest.is_creative_enabled(user:get_player_name()) then
|
|
||||||
itemstack:add_wear(65535/50)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return itemstack
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "mobs_mc:bow_wood",
|
|
||||||
recipe = {
|
|
||||||
{mobs_mc.items.string, mobs_mc.items.stick, ""},
|
|
||||||
{mobs_mc.items.string, "", mobs_mc.items.stick},
|
|
||||||
{mobs_mc.items.string, mobs_mc.items.stick, ""},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local how_to_throw = "Hold it in your and and leftclick to throw."
|
|
||||||
|
|
||||||
-- egg throwing item
|
|
||||||
-- egg entity
|
|
||||||
if c("egg") then
|
|
||||||
local egg_GRAVITY = 9
|
|
||||||
local egg_VELOCITY = 19
|
|
||||||
|
|
||||||
mobs:register_arrow("mobs_mc:egg_entity", {
|
|
||||||
visual = "sprite",
|
|
||||||
visual_size = {x=.5, y=.5},
|
|
||||||
textures = {"mobs_chicken_egg.png"},
|
|
||||||
velocity = egg_VELOCITY,
|
|
||||||
|
|
||||||
hit_player = function(self, player)
|
|
||||||
player:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {},
|
|
||||||
}, nil)
|
|
||||||
end,
|
|
||||||
|
|
||||||
hit_mob = function(self, mob)
|
|
||||||
mob:punch(minetest.get_player_by_name(self.playername) or self.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {},
|
|
||||||
}, nil)
|
|
||||||
end,
|
|
||||||
|
|
||||||
hit_node = function(self, pos, node)
|
|
||||||
|
|
||||||
if math.random(1, 10) > 1 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
pos.y = pos.y + 1
|
|
||||||
|
|
||||||
local nod = minetest.get_node_or_nil(pos)
|
|
||||||
|
|
||||||
if not nod
|
|
||||||
or not minetest.registered_nodes[nod.name]
|
|
||||||
or minetest.registered_nodes[nod.name].walkable == true then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local mob = minetest.add_entity(pos, "mobs_mc:chicken")
|
|
||||||
local ent2 = mob:get_luaentity()
|
|
||||||
|
|
||||||
mob:set_properties({
|
|
||||||
visual_size = {
|
|
||||||
x = ent2.base_size.x / 2,
|
|
||||||
y = ent2.base_size.y / 2
|
|
||||||
},
|
|
||||||
collisionbox = {
|
|
||||||
ent2.base_colbox[1] / 2,
|
|
||||||
ent2.base_colbox[2] / 2,
|
|
||||||
ent2.base_colbox[3] / 2,
|
|
||||||
ent2.base_colbox[4] / 2,
|
|
||||||
ent2.base_colbox[5] / 2,
|
|
||||||
ent2.base_colbox[6] / 2
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
ent2.child = true
|
|
||||||
ent2.tamed = true
|
|
||||||
ent2.owner = self.playername
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
-- shoot egg
|
|
||||||
local function mobs_shoot_egg(item, player, pointed_thing)
|
|
||||||
|
|
||||||
local playerpos = player:get_pos()
|
|
||||||
|
|
||||||
minetest.sound_play("default_place_node_hard", {
|
|
||||||
pos = playerpos,
|
|
||||||
gain = 1.0,
|
|
||||||
max_hear_distance = 5,
|
|
||||||
}, true)
|
|
||||||
|
|
||||||
local obj = minetest.add_entity({
|
|
||||||
x = playerpos.x,
|
|
||||||
y = playerpos.y +1.5,
|
|
||||||
z = playerpos.z
|
|
||||||
}, "mobs_mc:egg_entity")
|
|
||||||
|
|
||||||
local ent = obj:get_luaentity()
|
|
||||||
local dir = player:get_look_dir()
|
|
||||||
|
|
||||||
ent.velocity = egg_VELOCITY -- needed for api internal timing
|
|
||||||
ent.switch = 1 -- needed so that egg doesn't despawn straight away
|
|
||||||
|
|
||||||
obj:set_velocity({
|
|
||||||
x = dir.x * egg_VELOCITY,
|
|
||||||
y = dir.y * egg_VELOCITY,
|
|
||||||
z = dir.z * egg_VELOCITY
|
|
||||||
})
|
|
||||||
|
|
||||||
obj:set_acceleration({
|
|
||||||
x = dir.x * -3,
|
|
||||||
y = -egg_GRAVITY,
|
|
||||||
z = dir.z * -3
|
|
||||||
})
|
|
||||||
|
|
||||||
-- pass player name to egg for chick ownership
|
|
||||||
local ent2 = obj:get_luaentity()
|
|
||||||
ent2.playername = player:get_player_name()
|
|
||||||
|
|
||||||
if not minetest.is_creative_enabled(player:get_player_name()) then
|
|
||||||
item:take_item()
|
|
||||||
end
|
|
||||||
|
|
||||||
return item
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_craftitem("mobs_mc:egg", {
|
|
||||||
description = "Egg",
|
|
||||||
_doc_items_longdesc = "Eggs can be thrown and break on impact. There is a small chance that 1 or even 4 chicks will pop out",
|
|
||||||
_doc_items_usagehelp = how_to_throw,
|
|
||||||
inventory_image = "mobs_chicken_egg.png",
|
|
||||||
on_use = mobs_shoot_egg,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Snowball
|
|
||||||
|
|
||||||
local snowball_GRAVITY = 9
|
|
||||||
local snowball_VELOCITY = 19
|
|
||||||
|
|
||||||
mobs:register_arrow("mobs_mc:snowball_entity", {
|
|
||||||
visual = "sprite",
|
|
||||||
visual_size = {x=.5, y=.5},
|
|
||||||
textures = {"mcl_throwing_snowball.png"},
|
|
||||||
velocity = snowball_VELOCITY,
|
|
||||||
|
|
||||||
hit_player = function(self, player)
|
|
||||||
-- FIXME: No knockback
|
|
||||||
player:punch(self.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {},
|
|
||||||
}, nil)
|
|
||||||
end,
|
|
||||||
|
|
||||||
hit_mob = function(self, mob)
|
|
||||||
-- Hurt blazes, but not damage to anything else
|
|
||||||
local dmg = {}
|
|
||||||
if mob:get_luaentity().name == "mobs_mc:blaze" then
|
|
||||||
dmg = {fleshy = 3}
|
|
||||||
end
|
|
||||||
-- FIXME: No knockback
|
|
||||||
mob:punch(self.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = dmg,
|
|
||||||
}, nil)
|
|
||||||
end,
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
if c("snowball") then
|
|
||||||
-- shoot snowball
|
|
||||||
local function mobs_shoot_snowball(item, player, pointed_thing)
|
|
||||||
|
|
||||||
local playerpos = player:get_pos()
|
|
||||||
|
|
||||||
local obj = minetest.add_entity({
|
|
||||||
x = playerpos.x,
|
|
||||||
y = playerpos.y +1.5,
|
|
||||||
z = playerpos.z
|
|
||||||
}, "mobs_mc:snowball_entity")
|
|
||||||
|
|
||||||
local ent = obj:get_luaentity()
|
|
||||||
local dir = player:get_look_dir()
|
|
||||||
|
|
||||||
ent.velocity = snowball_VELOCITY -- needed for api internal timing
|
|
||||||
ent.switch = 1 -- needed so that egg doesn't despawn straight away
|
|
||||||
|
|
||||||
obj:set_velocity({
|
|
||||||
x = dir.x * snowball_VELOCITY,
|
|
||||||
y = dir.y * snowball_VELOCITY,
|
|
||||||
z = dir.z * snowball_VELOCITY
|
|
||||||
})
|
|
||||||
|
|
||||||
obj:set_acceleration({
|
|
||||||
x = dir.x * -3,
|
|
||||||
y = -snowball_GRAVITY,
|
|
||||||
z = dir.z * -3
|
|
||||||
})
|
|
||||||
|
|
||||||
-- pass player name to egg for chick ownership
|
|
||||||
local ent2 = obj:get_luaentity()
|
|
||||||
ent2.playername = player:get_player_name()
|
|
||||||
|
|
||||||
if not minetest.is_creative_enabled(player:get_player_name()) then
|
|
||||||
item:take_item()
|
|
||||||
end
|
|
||||||
|
|
||||||
return item
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Snowball
|
|
||||||
minetest.register_craftitem("mobs_mc:snowball", {
|
|
||||||
description = "Snowball",
|
|
||||||
_doc_items_longdesc = "Snowballs can be thrown at your enemies. A snowball deals 3 damage to blazes, but is harmless to anything else.",
|
|
||||||
_doc_items_usagehelp = how_to_throw,
|
|
||||||
inventory_image = "mcl_throwing_snowball.png",
|
|
||||||
on_use = mobs_shoot_snowball,
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
--end maikerumine code
|
|
|
@ -1,63 +0,0 @@
|
||||||
local pr = PseudoRandom(os.time()*5)
|
|
||||||
|
|
||||||
local offsets = {}
|
|
||||||
for x=-2, 2 do
|
|
||||||
for z=-2, 2 do
|
|
||||||
table.insert(offsets, {x=x, y=0, z=z})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and
|
|
||||||
the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1.
|
|
||||||
Larger mobs might have space problems after teleportation.
|
|
||||||
|
|
||||||
* dist: Minimum required distance from owner to teleport. Default: 12
|
|
||||||
* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]]
|
|
||||||
mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval)
|
|
||||||
return function(self, dtime)
|
|
||||||
-- No teleportation if no owner or if sitting
|
|
||||||
if not self.owner or self.order == "sit" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if not teleport_check_interval then
|
|
||||||
teleport_check_interval = 4
|
|
||||||
end
|
|
||||||
if not dist then
|
|
||||||
dist = 12
|
|
||||||
end
|
|
||||||
if self._teleport_timer == nil then
|
|
||||||
self._teleport_timer = teleport_check_interval
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self._teleport_timer = self._teleport_timer - dtime
|
|
||||||
if self._teleport_timer <= 0 then
|
|
||||||
self._teleport_timer = teleport_check_interval
|
|
||||||
local mob_pos = self.object:get_pos()
|
|
||||||
local owner = minetest.get_player_by_name(self.owner)
|
|
||||||
if not owner then
|
|
||||||
-- No owner found, no teleportation
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local owner_pos = owner:get_pos()
|
|
||||||
local dist_from_owner = vector.distance(owner_pos, mob_pos)
|
|
||||||
if dist_from_owner > dist then
|
|
||||||
-- Check for nodes below air in a 5×1×5 area around the owner position
|
|
||||||
local check_offsets = table.copy(offsets)
|
|
||||||
-- Attempt to place mob near player. Must be placed on walkable node below a non-walkable one. Place inside that air node.
|
|
||||||
while #check_offsets > 0 do
|
|
||||||
local r = pr:next(1, #check_offsets)
|
|
||||||
local telepos = vector.add(owner_pos, check_offsets[r])
|
|
||||||
local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z}
|
|
||||||
table.remove(check_offsets, r)
|
|
||||||
-- Long story short, spawn on a platform
|
|
||||||
if minetest.registered_nodes[minetest.get_node(telepos).name].walkable == false and
|
|
||||||
minetest.registered_nodes[minetest.get_node(telepos_below).name].walkable == true then
|
|
||||||
-- Correct position found! Let's teleport.
|
|
||||||
self.object:set_pos(telepos)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,63 +0,0 @@
|
||||||
--MC Heads for minetest
|
|
||||||
--maikerumine
|
|
||||||
|
|
||||||
-- NOTE: Strings intentionally not marked for translation, other mods already have these items.
|
|
||||||
-- TODO: Remove this file eventually, all items here are already outsourced in other mods.
|
|
||||||
-- TODO: Add translation.
|
|
||||||
|
|
||||||
--local S = local S = minetest.get_translator(minetest.get_current_modname())
|
|
||||||
|
|
||||||
-- Heads system
|
|
||||||
|
|
||||||
local sounds
|
|
||||||
if minetest.get_modpath("default") then
|
|
||||||
sounds = default.node_sound_defaults({
|
|
||||||
footstep = {name="default_hard_footstep", gain=0.3}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
local function addhead(mobname, desc, longdesc)
|
|
||||||
if not mobs_mc.is_item_variable_overridden("head_"..mobname) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
minetest.register_node("mobs_mc:head_"..mobname, {
|
|
||||||
description = desc,
|
|
||||||
_doc_items_longdesc = longdesc,
|
|
||||||
drawtype = "nodebox",
|
|
||||||
is_ground_content = false,
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{ -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
groups = { oddly_breakable_by_hand=3, head=1, },
|
|
||||||
-- The head textures are based off the textures of an actual mob.
|
|
||||||
-- FIXME: This code assumes 16×16 textures for the mob textures!
|
|
||||||
tiles = {
|
|
||||||
-- Note: bottom texture is overlaid over top texture to get rid of possible transparency.
|
|
||||||
-- This is required for skeleton skull and wither skeleton skull.
|
|
||||||
"[combine:16x16:-4,4=mobs_mc_"..mobname..".png", -- top
|
|
||||||
"([combine:16x16:-4,4=mobs_mc_"..mobname..".png)^([combine:16x16:-12,4=mobs_mc_"..mobname..".png)", -- bottom
|
|
||||||
"[combine:16x16:-12,0=mobs_mc_"..mobname..".png", -- left
|
|
||||||
"[combine:16x16:4,0=mobs_mc_"..mobname..".png", -- right
|
|
||||||
"[combine:16x16:-20,0=mobs_mc_"..mobname..".png", -- back
|
|
||||||
"[combine:16x16:-4,0=mobs_mc_"..mobname..".png", -- front
|
|
||||||
},
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2 = "facedir",
|
|
||||||
sunlight_propagates = true,
|
|
||||||
walkable = true,
|
|
||||||
sounds = sounds,
|
|
||||||
selection_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = { -0.25, -0.5, -0.25, 0.25, 0.0, 0.25, },
|
|
||||||
},
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add heads
|
|
||||||
addhead("zombie", "Zombie Head", "A zombie head is a small decorative block which resembles the head of a zombie.")
|
|
||||||
addhead("creeper", "Creeper Head", "A creeper head is a small decorative block which resembles the head of a creeper.")
|
|
||||||
addhead("skeleton", "Skeleton Skull", "A skeleton skull is a small decorative block which resembles the skull of a skeleton.")
|
|
||||||
addhead("wither_skeleton", "Wither Skeleton Skull", "A wither skeleton skull is a small decorative block which resembles the skull of a wither skeleton.")
|
|
|
@ -1,20 +0,0 @@
|
||||||
local function is_forbidden_node(pos, node)
|
|
||||||
node = node or minetest.get_node(pos)
|
|
||||||
return minetest.get_item_group(node.name, "stair") > 0 or minetest.get_item_group(node.name, "slab") > 0 or minetest.get_item_group(node.name, "carpet") > 0
|
|
||||||
end
|
|
||||||
|
|
||||||
function mobs:spawn_abm_check(pos, node, name)
|
|
||||||
-- Don't spawn monsters on mycelium
|
|
||||||
if (node.name == "mcl_core:mycelium" or node.name == "mcl_core:mycelium_snow") and minetest.registered_entities[name].type == "monster" then
|
|
||||||
return true
|
|
||||||
--Don't Spawn mobs on stairs, slabs, or carpets
|
|
||||||
elseif is_forbidden_node(pos, node) or is_forbidden_node(vector.add(pos, vector.new(0, 1, 0))) then
|
|
||||||
return true
|
|
||||||
-- Spawn on opaque or liquid nodes
|
|
||||||
elseif minetest.get_item_group(node.name, "opaque") ~= 0 or minetest.registered_nodes[node.name].liquidtype ~= "none" or node.name == "mcl_core:grass_path" then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Reject everything else
|
|
||||||
return true
|
|
||||||
end
|
|
|
@ -75,6 +75,7 @@ Origin of those models:
|
||||||
* `mobs_mc_mushroom_brown.png` (CC0)
|
* `mobs_mc_mushroom_brown.png` (CC0)
|
||||||
|
|
||||||
* “Spawn egg” textures (`mobs_mc_spawn_icon_*`) by 22i
|
* “Spawn egg” textures (`mobs_mc_spawn_icon_*`) by 22i
|
||||||
|
* Llama decor (carpet) textures (`mobs_mc_llama_decor_*`) by erlehmann and rudzik8
|
||||||
* Any other texture not mentioned here are licensed under the MIT License
|
* Any other texture not mentioned here are licensed under the MIT License
|
||||||
|
|
||||||
## Sounds
|
## Sounds
|
||||||
|
@ -190,10 +191,9 @@ Origin of those models:
|
||||||
* [Spennnyyy](https://freesound.org/people/Spennnyyy/) (CC0)
|
* [Spennnyyy](https://freesound.org/people/Spennnyyy/) (CC0)
|
||||||
* `mcl_totems_totem.ogg`
|
* `mcl_totems_totem.ogg`
|
||||||
* Source: <https://freesound.org/people/Spennnyyy/sounds/323502/>
|
* Source: <https://freesound.org/people/Spennnyyy/sounds/323502/>
|
||||||
* [Baŝto](https://opengameart.org/users/ba%C5%9Dto) (remixer) and [kantouth](https://freesound.org/people/kantouth/) (original author)
|
* [Baŝto](https://opengameart.org/users/ba%C5%9Dto)
|
||||||
* `mobs_mc_skeleton_random.*.ogg` (CC BY 3.0)
|
* `mobs_mc_skeleton_random.*.ogg` (CC BY 3.0)
|
||||||
* Source: <https://opengameart.org/content/walking-skeleton>
|
* Source: <https://opengameart.org/content/walking-skeleton>
|
||||||
* Based on: <https://freesound.org/people/kantouth/sounds/115113/>
|
|
||||||
* [spookymodem](https://freesound.org/people/spookymodem/)
|
* [spookymodem](https://freesound.org/people/spookymodem/)
|
||||||
* `mobs_mc_skeleton_death.ogg` (CC0)
|
* `mobs_mc_skeleton_death.ogg` (CC0)
|
||||||
* <https://freesound.org/people/spookymodem/sounds/202091/>
|
* <https://freesound.org/people/spookymodem/sounds/202091/>
|
||||||
|
@ -307,4 +307,4 @@ Origin of those models:
|
||||||
|
|
||||||
Note: Many of these sounds have been more or less modified to fit the game.
|
Note: Many of these sounds have been more or less modified to fit the game.
|
||||||
|
|
||||||
Sounds not mentioned here are licensed under CC0.
|
Sounds not mentioned hre are licensed under CC0.
|
||||||
|
|
|
@ -18,11 +18,6 @@ This mod adds mobs which closely resemble the mobs from the game Minecraft, vers
|
||||||
* Code: GNU General Public License, version 3 (see `LICENSE`)
|
* Code: GNU General Public License, version 3 (see `LICENSE`)
|
||||||
* Media: MIT, CC0, CC BY 3.0 CC BY-SA 4.0, LGPLv2.1, GPLv3. See `LICENSE_media.md` for details
|
* Media: MIT, CC0, CC BY 3.0 CC BY-SA 4.0, LGPLv2.1, GPLv3. See `LICENSE_media.md` for details
|
||||||
|
|
||||||
## Useful information for developers
|
|
||||||
|
|
||||||
### Game integration
|
|
||||||
Want to include this mod in your game? Read `gameconfig.md`.
|
|
||||||
|
|
||||||
### Links
|
### Links
|
||||||
|
|
||||||
* [`mobs_mc`](https://github.com/maikerumine/mobs_mc)
|
* [`mobs_mc`](https://github.com/maikerumine/mobs_mc)
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
--###################
|
|
||||||
--################### AGENT - seemingly unused
|
|
||||||
--###################
|
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:agent", {
|
|
||||||
type = "npc",
|
|
||||||
spawn_class = "passive",
|
|
||||||
passive = true,
|
|
||||||
hp_min = 20,
|
|
||||||
hp_max = 20,
|
|
||||||
armor = 100,
|
|
||||||
collisionbox = {-0.35, -0.01, -0.35, 0.35, 1, 0.35},
|
|
||||||
visual = "mesh",
|
|
||||||
mesh = "mobs_mc_agent.b3d",
|
|
||||||
textures = {
|
|
||||||
{"mobs_mc_agent.png"},
|
|
||||||
},
|
|
||||||
-- TODO: sounds
|
|
||||||
visual_size = {x=3, y=3},
|
|
||||||
walk_chance = 0,
|
|
||||||
walk_velocity = 0.6,
|
|
||||||
run_velocity = 2,
|
|
||||||
jump = true,
|
|
||||||
animation = {
|
|
||||||
stand_speed = 25,
|
|
||||||
walk_speed = 25,
|
|
||||||
run_speed = 50,
|
|
||||||
stand_start = 20,
|
|
||||||
stand_end = 60,
|
|
||||||
walk_start = 0,
|
|
||||||
walk_end = 20,
|
|
||||||
run_start = 0,
|
|
||||||
run_end = 20,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
mobs:register_egg("mobs_mc:agent", S("Agent"), "mobs_mc_spawn_icon_agent.png", 0)
|
|
|
@ -1,16 +1,13 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:bat", {
|
mcl_mobs:register_mob("mobs_mc:bat", {
|
||||||
description = S("Bat"),
|
description = S("Bat"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "ambient",
|
spawn_class = "ambient",
|
||||||
can_despawn = true,
|
can_despawn = true,
|
||||||
passive = true,
|
passive = true,
|
||||||
rotate = 270,
|
|
||||||
tilt_fly = true,
|
|
||||||
fly = true,
|
|
||||||
hp_min = 6,
|
hp_min = 6,
|
||||||
hp_max = 6,
|
hp_max = 6,
|
||||||
collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25},
|
collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25},
|
||||||
|
@ -48,7 +45,9 @@ mobs:register_mob("mobs_mc:bat", {
|
||||||
fall_damage = 0,
|
fall_damage = 0,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
fear_height = 0,
|
fear_height = 0,
|
||||||
|
|
||||||
jump = false,
|
jump = false,
|
||||||
|
fly = true,
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -66,7 +65,7 @@ else
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Spawn on solid blocks at or below Sea level and the selected light level
|
-- Spawn on solid blocks at or below Sea level and the selected light level
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:bat",
|
"mobs_mc:bat",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -139,9 +138,9 @@ maxlight,
|
||||||
20,
|
20,
|
||||||
5000,
|
5000,
|
||||||
2,
|
2,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.water-1)
|
mobs_mc.water_level-1)
|
||||||
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:bat", S("Bat"), "mobs_mc_spawn_icon_bat.png", 0)
|
mcl_mobs:register_egg("mobs_mc:bat", S("Bat"), "mobs_mc_spawn_icon_bat.png", 0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### CHICKEN
|
--################### CHICKEN
|
||||||
|
@ -8,7 +8,7 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:chicken", {
|
mcl_mobs:register_mob("mobs_mc:chicken", {
|
||||||
description = S("Chicken"),
|
description = S("Chicken"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
@ -18,8 +18,7 @@ mobs:register_mob("mobs_mc:chicken", {
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
xp_max = 3,
|
xp_max = 3,
|
||||||
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2},
|
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.69, 0.2},
|
||||||
skittish = true,
|
runaway = true,
|
||||||
fall_slow = true,
|
|
||||||
floats = 1,
|
floats = 1,
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_chicken.b3d",
|
mesh = "mobs_mc_chicken.b3d",
|
||||||
|
@ -27,17 +26,16 @@ mobs:register_mob("mobs_mc:chicken", {
|
||||||
{"mobs_mc_chicken.png"},
|
{"mobs_mc_chicken.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=2.2, y=2.2},
|
visual_size = {x=2.2, y=2.2},
|
||||||
rotate = 270,
|
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 3,
|
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.chicken_raw,
|
{name = "mcl_mobitems:chicken",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
{name = mobs_mc.items.feather,
|
{name = "mcl_mobitems:feather",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
|
@ -66,25 +64,19 @@ mobs:register_mob("mobs_mc:chicken", {
|
||||||
run_start = 0, run_end = 40,
|
run_start = 0, run_end = 40,
|
||||||
},
|
},
|
||||||
|
|
||||||
follow = "mcl_farming:wheat_seeds",
|
follow = {
|
||||||
breed_distance = 1.5,
|
"mcl_farming:wheat_seeds",
|
||||||
baby_size = 0.5,
|
"mcl_farming:melon_seeds",
|
||||||
follow_distance = 2,
|
"mcl_farming:pumpkin_seeds",
|
||||||
|
"mcl_farming:beetroot_seeds",
|
||||||
|
},
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
|
|
||||||
--why do chickend breed if they lay eggs??
|
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
--attempt to enter breed state
|
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||||
if mobs.enter_breed_state(self,clicker) then
|
if mcl_mobs:protect(self, clicker) then return end
|
||||||
return
|
if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
|
||||||
end
|
|
||||||
|
|
||||||
--make baby grow faster
|
|
||||||
if self.baby then
|
|
||||||
mobs.make_baby_grow_faster(self,clicker)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
@ -102,7 +94,7 @@ mobs:register_mob("mobs_mc:chicken", {
|
||||||
|
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
|
|
||||||
minetest.add_item(pos, mobs_mc.items.egg)
|
minetest.add_item(pos, "mcl_throwing:egg")
|
||||||
|
|
||||||
minetest.sound_play("mobs_mc_chicken_lay_egg", {
|
minetest.sound_play("mobs_mc_chicken_lay_egg", {
|
||||||
pos = pos,
|
pos = pos,
|
||||||
|
@ -111,83 +103,57 @@ mobs:register_mob("mobs_mc:chicken", {
|
||||||
}, true)
|
}, true)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--head code
|
|
||||||
has_head = true,
|
|
||||||
head_bone = "head",
|
|
||||||
|
|
||||||
swap_y_with_x = false,
|
|
||||||
reverse_head_yaw = false,
|
|
||||||
|
|
||||||
head_bone_pos_y = 1.675,
|
|
||||||
head_bone_pos_z = 0,
|
|
||||||
|
|
||||||
head_height_offset = 0.55,
|
|
||||||
head_direction_offset = 0.0925,
|
|
||||||
|
|
||||||
head_pitch_modifier = -math.pi/2,
|
|
||||||
--end head code
|
|
||||||
})
|
})
|
||||||
|
|
||||||
--spawn
|
--spawn
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:chicken",
|
"mobs_mc:chicken",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"FlowerForest_beach",
|
"flat",
|
||||||
"Forest_beach",
|
|
||||||
"StoneBeach",
|
|
||||||
"ColdTaiga_beach_water",
|
|
||||||
"Taiga_beach",
|
|
||||||
"Savanna_beach",
|
|
||||||
"Plains_beach",
|
|
||||||
"ExtremeHills_beach",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"Swampland_shore",
|
|
||||||
"JungleM_shore",
|
|
||||||
"Jungle_shore",
|
|
||||||
"MesaPlateauFM_sandlevel",
|
|
||||||
"MesaPlateauF_sandlevel",
|
|
||||||
"MesaBryce_sandlevel",
|
|
||||||
"Mesa_sandlevel",
|
|
||||||
"Mesa",
|
|
||||||
"FlowerForest",
|
|
||||||
"Swampland",
|
|
||||||
"Taiga",
|
|
||||||
"ExtremeHills",
|
|
||||||
"Jungle",
|
|
||||||
"Savanna",
|
|
||||||
"BirchForest",
|
|
||||||
"MegaSpruceTaiga",
|
|
||||||
"MegaTaiga",
|
|
||||||
"ExtremeHills+",
|
|
||||||
"Forest",
|
|
||||||
"Plains",
|
|
||||||
"Desert",
|
|
||||||
"ColdTaiga",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"ColdTaiga",
|
||||||
"IcePlains",
|
"ColdTaiga_beach",
|
||||||
"RoofedForest",
|
"ColdTaiga_beach_water",
|
||||||
"ExtremeHills+_snowtop",
|
"MegaTaiga",
|
||||||
"MesaPlateauFM_grasstop",
|
"MegaSpruceTaiga",
|
||||||
"JungleEdgeM",
|
"ExtremeHills",
|
||||||
|
"ExtremeHills_beach",
|
||||||
"ExtremeHillsM",
|
"ExtremeHillsM",
|
||||||
"JungleM",
|
"ExtremeHills+",
|
||||||
|
"ExtremeHills+_snowtop",
|
||||||
|
"StoneBeach",
|
||||||
|
"Plains",
|
||||||
|
"Plains_beach",
|
||||||
|
"SunflowerPlains",
|
||||||
|
"Taiga",
|
||||||
|
"Taiga_beach",
|
||||||
|
"Forest",
|
||||||
|
"Forest_beach",
|
||||||
|
"FlowerForest",
|
||||||
|
"FlowerForest_beach",
|
||||||
|
"BirchForest",
|
||||||
"BirchForestM",
|
"BirchForestM",
|
||||||
"MesaPlateauF",
|
"RoofedForest",
|
||||||
"MesaPlateauFM",
|
"Savanna",
|
||||||
"MesaPlateauF_grasstop",
|
"Savanna_beach",
|
||||||
"MesaBryce",
|
|
||||||
"JungleEdge",
|
|
||||||
"SavannaM",
|
"SavannaM",
|
||||||
|
"Jungle",
|
||||||
|
"Jungle_shore",
|
||||||
|
"JungleM",
|
||||||
|
"JungleM_shore",
|
||||||
|
"JungleEdge",
|
||||||
|
"JungleEdgeM",
|
||||||
|
"Swampland",
|
||||||
|
"Swampland_shore"
|
||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30, 17000,
|
30, 17000,
|
||||||
3,
|
3,
|
||||||
mobs_mc.spawn_height.water,
|
mobs_mc.water_level,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0)
|
mcl_mobs:register_egg("mobs_mc:chicken", S("Chicken"), "mobs_mc_spawn_icon_chicken.png", 0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
local cow_def = {
|
local cow_def = {
|
||||||
description = S("Cow"),
|
description = S("Cow"),
|
||||||
|
@ -10,7 +10,6 @@ local cow_def = {
|
||||||
hp_max = 10,
|
hp_max = 10,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
xp_max = 3,
|
xp_max = 3,
|
||||||
rotate = 270,
|
|
||||||
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45},
|
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.39, 0.45},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_cow.b3d",
|
mesh = "mobs_mc_cow.b3d",
|
||||||
|
@ -21,20 +20,19 @@ local cow_def = {
|
||||||
visual_size = {x=2.8, y=2.8},
|
visual_size = {x=2.8, y=2.8},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 3,
|
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.beef_raw,
|
{name = "mcl_mobitems:beef",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 3,
|
max = 3,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
{name = mobs_mc.items.leather,
|
{name = "mcl_mobitems:leather",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
},
|
},
|
||||||
skittish = true,
|
runaway = true,
|
||||||
sounds = {
|
sounds = {
|
||||||
random = "mobs_mc_cow",
|
random = "mobs_mc_cow",
|
||||||
damage = "mobs_mc_cow_hurt",
|
damage = "mobs_mc_cow_hurt",
|
||||||
|
@ -49,60 +47,37 @@ local cow_def = {
|
||||||
walk_end = 40, run_start = 0,
|
walk_end = 40, run_start = 0,
|
||||||
run_end = 40,
|
run_end = 40,
|
||||||
},
|
},
|
||||||
--follow = mobs_mc.follow.cow,
|
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
|
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||||
|
if mcl_mobs:protect(self, clicker) then return end
|
||||||
|
|
||||||
--attempt to enter breed state
|
if self.child then
|
||||||
if mobs.enter_breed_state(self,clicker) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
--make baby grow faster
|
|
||||||
if self.baby then
|
|
||||||
mobs.make_baby_grow_faster(self,clicker)
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
if item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
|
if item:get_name() == "mcl_buckets:bucket_empty" and clicker:get_inventory() then
|
||||||
local inv = clicker:get_inventory()
|
local inv = clicker:get_inventory()
|
||||||
inv:remove_item("main", mobs_mc.items.bucket)
|
inv:remove_item("main", "mcl_buckets:bucket_empty")
|
||||||
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
|
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
|
||||||
-- if room add bucket of milk to inventory, otherwise drop as item
|
-- if room add bucket of milk to inventory, otherwise drop as item
|
||||||
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
|
if inv:room_for_item("main", {name = "mcl_mobitems:milk_bucket"}) then
|
||||||
clicker:get_inventory():add_item("main", mobs_mc.items.milk)
|
clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket")
|
||||||
else
|
else
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
pos.y = pos.y + 0.5
|
pos.y = pos.y + 0.5
|
||||||
minetest.add_item(pos, {name = mobs_mc.items.milk})
|
minetest.add_item(pos, {name = "mcl_mobitems:milk_bucket"})
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
||||||
end,
|
end,
|
||||||
breed_distance = 1.5,
|
follow = "mcl_farming:wheat_item",
|
||||||
baby_size = 0.5,
|
|
||||||
follow_distance = 2,
|
|
||||||
follow = mobs_mc.items.wheat,
|
|
||||||
view_range = 10,
|
view_range = 10,
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
|
|
||||||
--head code
|
|
||||||
has_head = true,
|
|
||||||
head_bone = "head",
|
|
||||||
|
|
||||||
swap_y_with_x = false,
|
|
||||||
reverse_head_yaw = false,
|
|
||||||
|
|
||||||
head_bone_pos_y = 3.6,
|
|
||||||
head_bone_pos_z = -0.6,
|
|
||||||
|
|
||||||
head_height_offset = 1.0525,
|
|
||||||
head_direction_offset = 0.5,
|
|
||||||
head_pitch_modifier = 0,
|
|
||||||
--end head code
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:cow", cow_def)
|
mcl_mobs:register_mob("mobs_mc:cow", cow_def)
|
||||||
|
|
||||||
-- Mooshroom
|
-- Mooshroom
|
||||||
local mooshroom_def = table.copy(cow_def)
|
local mooshroom_def = table.copy(cow_def)
|
||||||
|
@ -110,27 +85,22 @@ mooshroom_def.description = S("Mooshroom")
|
||||||
mooshroom_def.mesh = "mobs_mc_cow.b3d"
|
mooshroom_def.mesh = "mobs_mc_cow.b3d"
|
||||||
mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } }
|
mooshroom_def.textures = { {"mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png"}, {"mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" } }
|
||||||
mooshroom_def.on_rightclick = function(self, clicker)
|
mooshroom_def.on_rightclick = function(self, clicker)
|
||||||
--attempt to enter breed state
|
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||||
if mobs.enter_breed_state(self,clicker) then
|
if mcl_mobs:protect(self, clicker) then return end
|
||||||
|
|
||||||
|
if self.child then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
--make baby grow faster
|
|
||||||
if self.baby then
|
|
||||||
mobs.make_baby_grow_faster(self,clicker)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
-- Use shears to get mushrooms and turn mooshroom into cow
|
-- Use shears to get mushrooms and turn mooshroom into cow
|
||||||
if item:get_name() == mobs_mc.items.shears then
|
if item:get_name() == "mcl_tools:shears" then
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
|
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
|
||||||
|
|
||||||
if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
|
if self.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
|
||||||
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, mobs_mc.items.mushroom_brown .. " 5")
|
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_mushrooms:mushroom_brown 5")
|
||||||
else
|
else
|
||||||
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, mobs_mc.items.mushroom_red .. " 5")
|
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_mushrooms:mushroom_red 5")
|
||||||
end
|
end
|
||||||
|
|
||||||
local oldyaw = self.object:get_yaw()
|
local oldyaw = self.object:get_yaw()
|
||||||
|
@ -139,105 +109,95 @@ mooshroom_def.on_rightclick = function(self, clicker)
|
||||||
cow:set_yaw(oldyaw)
|
cow:set_yaw(oldyaw)
|
||||||
|
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
item:add_wear(mobs_mc.misc.shears_wear)
|
item:add_wear(mobs_mc.shears_wear)
|
||||||
clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
|
clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
|
||||||
end
|
end
|
||||||
-- Use bucket to milk
|
-- Use bucket to milk
|
||||||
elseif item:get_name() == mobs_mc.items.bucket and clicker:get_inventory() then
|
elseif item:get_name() == "mcl_buckets:bucket_empty" and clicker:get_inventory() then
|
||||||
local inv = clicker:get_inventory()
|
local inv = clicker:get_inventory()
|
||||||
inv:remove_item("main", mobs_mc.items.bucket)
|
inv:remove_item("main", "mcl_buckets:bucket_empty")
|
||||||
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
|
minetest.sound_play("mobs_mc_cow_milk", {pos=self.object:get_pos(), gain=0.6})
|
||||||
-- If room, add milk to inventory, otherwise drop as item
|
-- If room, add milk to inventory, otherwise drop as item
|
||||||
if inv:room_for_item("main", {name=mobs_mc.items.milk}) then
|
if inv:room_for_item("main", {name="mcl_mobitems:milk_bucket"}) then
|
||||||
clicker:get_inventory():add_item("main", mobs_mc.items.milk)
|
clicker:get_inventory():add_item("main", "mcl_mobitems:milk_bucket")
|
||||||
else
|
else
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
pos.y = pos.y + 0.5
|
pos.y = pos.y + 0.5
|
||||||
minetest.add_item(pos, {name = mobs_mc.items.milk})
|
minetest.add_item(pos, {name = "mcl_mobitems:milk_bucket"})
|
||||||
end
|
end
|
||||||
-- Use bowl to get mushroom stew
|
-- Use bowl to get mushroom stew
|
||||||
elseif item:get_name() == mobs_mc.items.bowl and clicker:get_inventory() then
|
elseif item:get_name() == "mcl_core:bowl" and clicker:get_inventory() then
|
||||||
local inv = clicker:get_inventory()
|
local inv = clicker:get_inventory()
|
||||||
inv:remove_item("main", mobs_mc.items.bowl)
|
inv:remove_item("main", "mcl_core:bowl")
|
||||||
minetest.sound_play("mobs_mc_cow_mushroom_stew", {pos=self.object:get_pos(), gain=0.6})
|
minetest.sound_play("mobs_mc_cow_mushroom_stew", {pos=self.object:get_pos(), gain=0.6})
|
||||||
-- If room, add mushroom stew to inventory, otherwise drop as item
|
-- If room, add mushroom stew to inventory, otherwise drop as item
|
||||||
if inv:room_for_item("main", {name=mobs_mc.items.mushroom_stew}) then
|
if inv:room_for_item("main", {name="mcl_mushrooms:mushroom_stew"}) then
|
||||||
clicker:get_inventory():add_item("main", mobs_mc.items.mushroom_stew)
|
clicker:get_inventory():add_item("main", "mcl_mushrooms:mushroom_stew")
|
||||||
else
|
else
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
pos.y = pos.y + 0.5
|
pos.y = pos.y + 0.5
|
||||||
minetest.add_item(pos, {name = mobs_mc.items.mushroom_stew})
|
minetest.add_item(pos, {name = "mcl_mushrooms:mushroom_stew"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
||||||
end
|
end
|
||||||
mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
|
mcl_mobs:register_mob("mobs_mc:mooshroom", mooshroom_def)
|
||||||
|
|
||||||
|
|
||||||
-- Spawning
|
-- Spawning
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:cow",
|
"mobs_mc:cow",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"FlowerForest_beach",
|
"flat",
|
||||||
"Forest_beach",
|
|
||||||
"StoneBeach",
|
|
||||||
"ColdTaiga_beach_water",
|
|
||||||
"Taiga_beach",
|
|
||||||
"Savanna_beach",
|
|
||||||
"Plains_beach",
|
|
||||||
"ExtremeHills_beach",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"Swampland_shore",
|
|
||||||
"JungleM_shore",
|
|
||||||
"Jungle_shore",
|
|
||||||
"MesaPlateauFM_sandlevel",
|
|
||||||
"MesaPlateauF_sandlevel",
|
|
||||||
"MesaBryce_sandlevel",
|
|
||||||
"Mesa_sandlevel",
|
|
||||||
"Mesa",
|
|
||||||
"FlowerForest",
|
|
||||||
"Swampland",
|
|
||||||
"Taiga",
|
|
||||||
"ExtremeHills",
|
|
||||||
"Jungle",
|
|
||||||
"Savanna",
|
|
||||||
"BirchForest",
|
|
||||||
"MegaSpruceTaiga",
|
|
||||||
"MegaTaiga",
|
|
||||||
"ExtremeHills+",
|
|
||||||
"Forest",
|
|
||||||
"Plains",
|
|
||||||
"Desert",
|
|
||||||
"ColdTaiga",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"ColdTaiga",
|
||||||
"IcePlains",
|
"ColdTaiga_beach",
|
||||||
"RoofedForest",
|
"ColdTaiga_beach_water",
|
||||||
"ExtremeHills+_snowtop",
|
"MegaTaiga",
|
||||||
"MesaPlateauFM_grasstop",
|
"MegaSpruceTaiga",
|
||||||
"JungleEdgeM",
|
"ExtremeHills",
|
||||||
|
"ExtremeHills_beach",
|
||||||
"ExtremeHillsM",
|
"ExtremeHillsM",
|
||||||
"JungleM",
|
"ExtremeHills+",
|
||||||
|
"ExtremeHills+_snowtop",
|
||||||
|
"StoneBeach",
|
||||||
|
"Plains",
|
||||||
|
"Plains_beach",
|
||||||
|
"SunflowerPlains",
|
||||||
|
"Taiga",
|
||||||
|
"Taiga_beach",
|
||||||
|
"Forest",
|
||||||
|
"Forest_beach",
|
||||||
|
"FlowerForest",
|
||||||
|
"FlowerForest_beach",
|
||||||
|
"BirchForest",
|
||||||
"BirchForestM",
|
"BirchForestM",
|
||||||
"MesaPlateauF",
|
"RoofedForest",
|
||||||
"MesaPlateauFM",
|
"Savanna",
|
||||||
"MesaPlateauF_grasstop",
|
"Savanna_beach",
|
||||||
"MesaBryce",
|
|
||||||
"JungleEdge",
|
|
||||||
"SavannaM",
|
"SavannaM",
|
||||||
|
"Jungle",
|
||||||
|
"Jungle_shore",
|
||||||
|
"JungleM",
|
||||||
|
"JungleM_shore",
|
||||||
|
"JungleEdge",
|
||||||
|
"JungleEdgeM",
|
||||||
|
"Swampland",
|
||||||
|
"Swampland_shore"
|
||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
17000,
|
17000,
|
||||||
10,
|
10,
|
||||||
mobs_mc.spawn_height.water,
|
mobs_mc.water_level,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:mooshroom",
|
"mobs_mc:mooshroom",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -250,9 +210,9 @@ minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
17000,
|
17000,
|
||||||
5,
|
5,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn egg
|
-- spawn egg
|
||||||
mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0)
|
mcl_mobs:register_egg("mobs_mc:cow", S("Cow"), "mobs_mc_spawn_icon_cow.png", 0)
|
||||||
mobs:register_egg("mobs_mc:mooshroom", S("Mooshroom"), "mobs_mc_spawn_icon_mooshroom.png", 0)
|
mcl_mobs:register_egg("mobs_mc:mooshroom", S("Mooshroom"), "mobs_mc_spawn_icon_mooshroom.png", 0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### CREEPER
|
--################### CREEPER
|
||||||
|
@ -9,11 +9,9 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:creeper", {
|
mcl_mobs:register_mob("mobs_mc:creeper", {
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
hostile = true,
|
|
||||||
rotate = 270,
|
|
||||||
hp_min = 20,
|
hp_min = 20,
|
||||||
hp_max = 20,
|
hp_max = 20,
|
||||||
xp_min = 5,
|
xp_min = 5,
|
||||||
|
@ -35,48 +33,32 @@ mobs:register_mob("mobs_mc:creeper", {
|
||||||
explode = "tnt_explode",
|
explode = "tnt_explode",
|
||||||
distance = 16,
|
distance = 16,
|
||||||
},
|
},
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1.05,
|
walk_velocity = 1.05,
|
||||||
run_velocity = 2.1,
|
run_velocity = 2.1,
|
||||||
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
||||||
attack_type = "explode",
|
attack_type = "explode",
|
||||||
eye_height = 1.25,
|
|
||||||
--hssssssssssss
|
--hssssssssssss
|
||||||
|
|
||||||
explosion_strength = 3,
|
explosion_strength = 3,
|
||||||
--explosion_radius = 3,
|
explosion_radius = 3.5,
|
||||||
--explosion_damage_radius = 6,
|
explosion_damage_radius = 3.5,
|
||||||
--explosiontimer_reset_radius = 6,
|
explosiontimer_reset_radius = 6,
|
||||||
reach = 3,
|
reach = 3,
|
||||||
defuse_reach = 5.2,
|
explosion_timer = 1.5,
|
||||||
explosion_timer = 0.3,
|
|
||||||
allow_fuse_reset = true,
|
allow_fuse_reset = true,
|
||||||
stop_to_explode = true,
|
stop_to_explode = true,
|
||||||
|
|
||||||
--head code
|
|
||||||
has_head = true,
|
|
||||||
head_bone = "head",
|
|
||||||
|
|
||||||
swap_y_with_x = true,
|
|
||||||
reverse_head_yaw = true,
|
|
||||||
|
|
||||||
head_bone_pos_y = 2.4,
|
|
||||||
head_bone_pos_z = 0,
|
|
||||||
|
|
||||||
head_height_offset = 1.1,
|
|
||||||
head_direction_offset = 0,
|
|
||||||
head_pitch_modifier = 0,
|
|
||||||
--end head code
|
|
||||||
|
|
||||||
-- Force-ignite creeper with flint and steel and explode after 1.5 seconds.
|
-- Force-ignite creeper with flint and steel and explode after 1.5 seconds.
|
||||||
-- TODO: Make creeper flash after doing this as well.
|
-- TODO: Make creeper flash after doing this as well.
|
||||||
-- TODO: Test and debug this code.
|
-- TODO: Test and debug this code.
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
if self._forced_explosion_countdown_timer then
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
if item:get_name() == mobs_mc.items.flint_and_steel then
|
if item:get_name() == "mcl_fire:flint_and_steel" then
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
-- Wear tool
|
-- Wear tool
|
||||||
local wdef = item:get_definition()
|
local wdef = item:get_definition()
|
||||||
|
@ -92,11 +74,10 @@ mobs:register_mob("mobs_mc:creeper", {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
if self._forced_explosion_countdown_timer then
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
||||||
if self._forced_explosion_countdown_timer <= 0 then
|
if self._forced_explosion_countdown_timer <= 0 then
|
||||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
|
||||||
mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { griefing = mobs_griefing, drop_chance = 1.0}, self.object)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -107,14 +88,14 @@ mobs:register_mob("mobs_mc:creeper", {
|
||||||
if luaentity and luaentity.name:find("arrow") then
|
if luaentity and luaentity.name:find("arrow") then
|
||||||
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
|
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
|
||||||
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
|
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
|
||||||
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[math.random(1, #mobs_mc.items.music_discs)])
|
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
maxdrops = 2,
|
maxdrops = 2,
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.gunpowder,
|
{name = "mcl_mobitems:gunpowder",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
|
@ -122,7 +103,7 @@ mobs:register_mob("mobs_mc:creeper", {
|
||||||
|
|
||||||
-- Head
|
-- Head
|
||||||
-- TODO: Only drop if killed by charged creeper
|
-- TODO: Only drop if killed by charged creeper
|
||||||
{name = mobs_mc.items.head_creeper,
|
{name = "mcl_heads:creeper",
|
||||||
chance = 200, -- 0.5%
|
chance = 200, -- 0.5%
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,},
|
max = 1,},
|
||||||
|
@ -148,11 +129,10 @@ mobs:register_mob("mobs_mc:creeper", {
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:creeper_charged", {
|
mcl_mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
description = S("Charged Creeper"),
|
description = S("Creeper"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
hostile = true,
|
|
||||||
hp_min = 20,
|
hp_min = 20,
|
||||||
hp_max = 20,
|
hp_max = 20,
|
||||||
xp_min = 5,
|
xp_min = 5,
|
||||||
|
@ -169,7 +149,6 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
"mobs_mc_creeper_charge.png"},
|
"mobs_mc_creeper_charge.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
rotate = 270,
|
|
||||||
sounds = {
|
sounds = {
|
||||||
attack = "tnt_ignite",
|
attack = "tnt_ignite",
|
||||||
death = "mobs_mc_creeper_death",
|
death = "mobs_mc_creeper_death",
|
||||||
|
@ -178,19 +157,18 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
explode = "tnt_explode",
|
explode = "tnt_explode",
|
||||||
distance = 16,
|
distance = 16,
|
||||||
},
|
},
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1.05,
|
walk_velocity = 1.05,
|
||||||
run_velocity = 2.1,
|
run_velocity = 2.1,
|
||||||
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
runaway_from = { "mobs_mc:ocelot", "mobs_mc:cat" },
|
||||||
attack_type = "explode",
|
attack_type = "explode",
|
||||||
|
|
||||||
explosion_strength = 6,
|
explosion_strength = 6,
|
||||||
--explosion_radius = 3,
|
explosion_radius = 8,
|
||||||
--explosion_damage_radius = 6,
|
explosion_damage_radius = 8,
|
||||||
--explosiontimer_reset_radius = 3,
|
explosiontimer_reset_radius = 6,
|
||||||
reach = 3,
|
reach = 3,
|
||||||
defuse_reach = 5.2,
|
explosion_timer = 1.5,
|
||||||
explosion_timer = 0.3,
|
|
||||||
allow_fuse_reset = true,
|
allow_fuse_reset = true,
|
||||||
stop_to_explode = true,
|
stop_to_explode = true,
|
||||||
|
|
||||||
|
@ -198,11 +176,11 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
-- TODO: Make creeper flash after doing this as well.
|
-- TODO: Make creeper flash after doing this as well.
|
||||||
-- TODO: Test and debug this code.
|
-- TODO: Test and debug this code.
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
if self._forced_explosion_countdown_timer then
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
if item:get_name() == mobs_mc.items.flint_and_steel then
|
if item:get_name() == "mcl_fire:flint_and_steel" then
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
-- Wear tool
|
-- Wear tool
|
||||||
local wdef = item:get_definition()
|
local wdef = item:get_definition()
|
||||||
|
@ -218,11 +196,10 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
if self._forced_explosion_countdown_timer then
|
if self._forced_explosion_countdown_timer ~= nil then
|
||||||
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
self._forced_explosion_countdown_timer = self._forced_explosion_countdown_timer - dtime
|
||||||
if self._forced_explosion_countdown_timer <= 0 then
|
if self._forced_explosion_countdown_timer <= 0 then
|
||||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
mcl_mobs:boom(self, mcl_util.get_object_center(self.object), self.explosion_strength)
|
||||||
mcl_explosions.explode(mcl_util.get_object_center(self.object), self.explosion_strength, { griefing = mobs_griefing, drop_chance = 1.0}, self.object)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
@ -233,14 +210,14 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
if luaentity and luaentity.name:find("arrow") then
|
if luaentity and luaentity.name:find("arrow") then
|
||||||
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
|
local shooter_luaentity = luaentity._shooter and luaentity._shooter:get_luaentity()
|
||||||
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
|
if shooter_luaentity and (shooter_luaentity.name == "mobs_mc:skeleton" or shooter_luaentity.name == "mobs_mc:stray") then
|
||||||
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, mobs_mc.items.music_discs[math.random(1, #mobs_mc.items.music_discs)])
|
minetest.add_item({x=pos.x, y=pos.y+1, z=pos.z}, "mcl_jukebox:record_" .. math.random(9))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
maxdrops = 2,
|
maxdrops = 2,
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.gunpowder,
|
{name = "mcl_mobitems:gunpowder",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
|
@ -248,7 +225,7 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
|
|
||||||
-- Head
|
-- Head
|
||||||
-- TODO: Only drop if killed by charged creeper
|
-- TODO: Only drop if killed by charged creeper
|
||||||
{name = mobs_mc.items.head_creeper,
|
{name = "mcl_heads:creeper",
|
||||||
chance = 200, -- 0.5%
|
chance = 200, -- 0.5%
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,},
|
max = 1,},
|
||||||
|
@ -277,7 +254,7 @@ mobs:register_mob("mobs_mc:creeper_charged", {
|
||||||
glow = 3,
|
glow = 3,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:creeper",
|
"mobs_mc:creeper",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -427,8 +404,8 @@ mobs:spawn_specific(
|
||||||
20,
|
20,
|
||||||
16500,
|
16500,
|
||||||
2,
|
2,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0)
|
mcl_mobs:register_egg("mobs_mc:creeper", S("Creeper"), "mobs_mc_spawn_icon_creeper.png", 0)
|
||||||
|
|
|
@ -2,28 +2,21 @@
|
||||||
--################### ENDERDRAGON
|
--################### ENDERDRAGON
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:enderdragon", {
|
mcl_mobs:register_mob("mobs_mc:enderdragon", {
|
||||||
description = S("Ender Dragon"),
|
description = S("Ender Dragon"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
pathfinding = 1,
|
||||||
attacks_animals = true,
|
attacks_animals = true,
|
||||||
walk_chance = 100,
|
walk_chance = 100,
|
||||||
rotate = 270,
|
|
||||||
tilt_fly = true,
|
|
||||||
hostile = true,
|
|
||||||
shoot_arrow = function(self, pos, dir)
|
|
||||||
-- 2-4 damage per arrow
|
|
||||||
local dmg = math.random(2,4)
|
|
||||||
mobs.shoot_projectile_handling("mobs_mc:dragon_fireball", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
|
|
||||||
end,
|
|
||||||
hp_max = 200,
|
hp_max = 200,
|
||||||
hp_min = 200,
|
hp_min = 200,
|
||||||
xp_min = 500,
|
xp_min = 500,
|
||||||
xp_max = 500,
|
xp_max = 500,
|
||||||
collisionbox = {-2, 0, -2, 2, 2, 2},
|
collisionbox = {-2, 3, -2, 2, 5, 2},
|
||||||
eye_height = 1,
|
physical = false,
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_dragon.b3d",
|
mesh = "mobs_mc_dragon.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
|
@ -31,7 +24,6 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
view_range = 35,
|
view_range = 35,
|
||||||
reach = 20,
|
|
||||||
walk_velocity = 6,
|
walk_velocity = 6,
|
||||||
run_velocity = 6,
|
run_velocity = 6,
|
||||||
can_despawn = false,
|
can_despawn = false,
|
||||||
|
@ -43,6 +35,7 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||||
},
|
},
|
||||||
physical = true,
|
physical = true,
|
||||||
damage = 10,
|
damage = 10,
|
||||||
|
knock_back = false,
|
||||||
jump = true,
|
jump = true,
|
||||||
jump_height = 14,
|
jump_height = 14,
|
||||||
fly = true,
|
fly = true,
|
||||||
|
@ -55,10 +48,12 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||||
lava_damage = 0,
|
lava_damage = 0,
|
||||||
fire_damage = 0,
|
fire_damage = 0,
|
||||||
on_rightclick = nil,
|
on_rightclick = nil,
|
||||||
attack_type = "projectile",
|
attack_type = "dogshoot",
|
||||||
arrow = "mobs_mc:dragon_fireball",
|
arrow = "mobs_mc:dragon_fireball",
|
||||||
shoot_interval = 0.5,
|
shoot_interval = 0.5,
|
||||||
shoot_offset = -1.0,
|
shoot_offset = -1.0,
|
||||||
|
xp_min = 500,
|
||||||
|
xp_max = 500,
|
||||||
animation = {
|
animation = {
|
||||||
fly_speed = 8, stand_speed = 8,
|
fly_speed = 8, stand_speed = 8,
|
||||||
stand_start = 0, stand_end = 20,
|
stand_start = 0, stand_end = 20,
|
||||||
|
@ -104,18 +99,18 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||||
mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open")
|
mcl_structures.call_struct(self._portal_pos, "end_exit_portal_open")
|
||||||
if self._initial then
|
if self._initial then
|
||||||
mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000
|
mcl_experience.throw_xp(pos, 11500) -- 500 + 11500 = 12000
|
||||||
minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg})
|
minetest.set_node(vector.add(self._portal_pos, vector.new(3, 5, 3)), {name = "mcl_end:dragon_egg"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
fire_resistant = true,
|
fire_resistant = true,
|
||||||
})
|
})
|
||||||
|
|
||||||
--TODO: replace this setting by a proper gamerules system
|
|
||||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing", true)
|
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||||
|
|
||||||
-- dragon fireball (projectile)
|
-- dragon fireball (projectile)
|
||||||
mobs:register_arrow("mobs_mc:dragon_fireball", {
|
mcl_mobs:register_arrow("mobs_mc:dragon_fireball", {
|
||||||
visual = "sprite",
|
visual = "sprite",
|
||||||
visual_size = {x = 1.25, y = 1.25},
|
visual_size = {x = 1.25, y = 1.25},
|
||||||
textures = {"mobs_mc_dragon_fireball.png"},
|
textures = {"mobs_mc_dragon_fireball.png"},
|
||||||
|
@ -139,13 +134,10 @@ mobs:register_arrow("mobs_mc:dragon_fireball", {
|
||||||
|
|
||||||
-- node hit, explode
|
-- node hit, explode
|
||||||
hit_node = function(self, pos, node)
|
hit_node = function(self, pos, node)
|
||||||
--mobs:boom(self, pos, 2)
|
mcl_mobs:boom(self, pos, 2)
|
||||||
if mobs_griefing then
|
|
||||||
mcl_explosions.explode(self.object:get_pos(), 2, { drop_chance = 1.0 })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true)
|
mcl_mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true)
|
||||||
|
|
||||||
--mcl_wip.register_wip_item("mobs_mc:enderdragon")
|
mcl_wip.register_wip_item("mobs_mc:enderdragon")
|
||||||
|
|
|
@ -24,11 +24,9 @@
|
||||||
-- added rain damage.
|
-- added rain damage.
|
||||||
-- fixed the grass_with_dirt issue.
|
-- fixed the grass_with_dirt issue.
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
local vector = vector
|
local telesound = function(pos, is_source)
|
||||||
|
|
||||||
local function telesound(pos, is_source)
|
|
||||||
local snd
|
local snd
|
||||||
if is_source then
|
if is_source then
|
||||||
snd = "mobs_mc_enderman_teleport_src"
|
snd = "mobs_mc_enderman_teleport_src"
|
||||||
|
@ -50,6 +48,37 @@ local take_frequency_max = 245
|
||||||
local place_frequency_min = 235
|
local place_frequency_min = 235
|
||||||
local place_frequency_max = 245
|
local place_frequency_max = 245
|
||||||
|
|
||||||
|
|
||||||
|
-- Texuture overrides for enderman block. Required for cactus because it's original is a nodebox
|
||||||
|
-- and the textures have tranparent pixels.
|
||||||
|
local block_texture_overrides
|
||||||
|
do
|
||||||
|
local cbackground = "mobs_mc_enderman_cactus_background.png"
|
||||||
|
local ctiles = minetest.registered_nodes["mcl_core:cactus"].tiles
|
||||||
|
|
||||||
|
local ctable = {}
|
||||||
|
local last
|
||||||
|
for i=1, 6 do
|
||||||
|
if ctiles[i] then
|
||||||
|
last = ctiles[i]
|
||||||
|
end
|
||||||
|
table.insert(ctable, cbackground .. "^" .. last)
|
||||||
|
end
|
||||||
|
|
||||||
|
block_texture_overrides = {
|
||||||
|
["mcl_core:cactus"] = ctable,
|
||||||
|
-- FIXME: replace colorize colors with colors from palette
|
||||||
|
["mcl_core:dirt_with_grass"] =
|
||||||
|
{
|
||||||
|
"mcl_core_grass_block_top.png^[colorize:green:90",
|
||||||
|
"default_dirt.png",
|
||||||
|
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
|
||||||
|
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
|
||||||
|
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)",
|
||||||
|
"default_dirt.png^(mcl_core_grass_block_side_overlay.png^[colorize:green:90)"}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
-- Create the textures table for the enderman, depending on which kind of block
|
-- Create the textures table for the enderman, depending on which kind of block
|
||||||
-- the enderman holds (if any).
|
-- the enderman holds (if any).
|
||||||
local create_enderman_textures = function(block_type, itemstring)
|
local create_enderman_textures = function(block_type, itemstring)
|
||||||
|
@ -71,9 +100,9 @@ local create_enderman_textures = function(block_type, itemstring)
|
||||||
local tiles = minetest.registered_nodes[itemstring].tiles
|
local tiles = minetest.registered_nodes[itemstring].tiles
|
||||||
local textures = {}
|
local textures = {}
|
||||||
local last
|
local last
|
||||||
if mobs_mc.enderman_block_texture_overrides[itemstring] then
|
if block_texture_overrides[itemstring] then
|
||||||
-- Texture override available? Use these instead!
|
-- Texture override available? Use these instead!
|
||||||
textures = mobs_mc.enderman_block_texture_overrides[itemstring]
|
textures = block_texture_overrides[itemstring]
|
||||||
else
|
else
|
||||||
-- Extract the texture names
|
-- Extract the texture names
|
||||||
for i = 1, 6 do
|
for i = 1, 6 do
|
||||||
|
@ -191,23 +220,22 @@ end
|
||||||
|
|
||||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:enderman", {
|
mcl_mobs:register_mob("mobs_mc:enderman", {
|
||||||
description = S("Enderman"),
|
description = S("Enderman"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
neutral = true,
|
passive = true,
|
||||||
|
pathfinding = 1,
|
||||||
hp_min = 40,
|
hp_min = 40,
|
||||||
hp_max = 40,
|
hp_max = 40,
|
||||||
xp_min = 5,
|
xp_min = 5,
|
||||||
xp_max = 5,
|
xp_max = 5,
|
||||||
rotate = 270,
|
|
||||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 2.89, 0.3},
|
collisionbox = {-0.3, -0.01, -0.3, 0.3, 2.89, 0.3},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_enderman.b3d",
|
mesh = "mobs_mc_enderman.b3d",
|
||||||
textures = create_enderman_textures(),
|
textures = create_enderman_textures(),
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
eye_height = 2.5,
|
|
||||||
sounds = {
|
sounds = {
|
||||||
-- TODO: Custom war cry sound
|
-- TODO: Custom war cry sound
|
||||||
war_cry = "mobs_sandmonster",
|
war_cry = "mobs_sandmonster",
|
||||||
|
@ -216,33 +244,17 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
random = {name="mobs_mc_enderman_random", gain=0.5},
|
random = {name="mobs_mc_enderman_random", gain=0.5},
|
||||||
distance = 16,
|
distance = 16,
|
||||||
},
|
},
|
||||||
walk_velocity = 1,
|
walk_velocity = 0.2,
|
||||||
run_velocity = 4,
|
run_velocity = 3.4,
|
||||||
damage = 7,
|
damage = 7,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.ender_pearl,
|
{name = "mcl_throwing:ender_pearl",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "common"},
|
looting = "common"},
|
||||||
},
|
},
|
||||||
|
|
||||||
--head code
|
|
||||||
has_head = false,
|
|
||||||
head_bone = "head.low",
|
|
||||||
|
|
||||||
swap_y_with_x = false,
|
|
||||||
reverse_head_yaw = false,
|
|
||||||
|
|
||||||
head_bone_pos_y = 2.4,
|
|
||||||
head_bone_pos_z = 0,
|
|
||||||
|
|
||||||
head_height_offset = 1.1,
|
|
||||||
head_direction_offset = 0,
|
|
||||||
head_pitch_modifier = 0,
|
|
||||||
--end head code
|
|
||||||
|
|
||||||
animation = select_enderman_animation("normal"),
|
animation = select_enderman_animation("normal"),
|
||||||
_taken_node = "",
|
_taken_node = "",
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
@ -301,10 +313,10 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
--self:teleport(nil)
|
--self:teleport(nil)
|
||||||
--self.state = ""
|
--self.state = ""
|
||||||
--else
|
--else
|
||||||
if self.attacking then
|
if self.attack then
|
||||||
local target = self.attacking
|
local target = self.attack
|
||||||
local pos = target:get_pos()
|
local pos = target:get_pos()
|
||||||
if pos then
|
if pos ~= nil then
|
||||||
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
|
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
|
||||||
self:teleport(target)
|
self:teleport(target)
|
||||||
end
|
end
|
||||||
|
@ -320,12 +332,12 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
for n = 1, #objs do
|
for n = 1, #objs do
|
||||||
local obj = objs[n]
|
local obj = objs[n]
|
||||||
if obj then
|
if obj then
|
||||||
--if minetest.is_player(obj) then
|
if minetest.is_player(obj) then
|
||||||
-- Warp from players during day.
|
-- Warp from players during day.
|
||||||
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
|
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
|
||||||
-- self:teleport(nil)
|
-- self:teleport(nil)
|
||||||
--end
|
--end
|
||||||
if not obj:is_player() then
|
else
|
||||||
local lua = obj:get_luaentity()
|
local lua = obj:get_luaentity()
|
||||||
if lua then
|
if lua then
|
||||||
if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then
|
if lua.name == "mcl_bows:arrow_entity" or lua.name == "mcl_throwing:snowball_entity" then
|
||||||
|
@ -343,8 +355,8 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
-- self:teleport(nil)
|
-- self:teleport(nil)
|
||||||
-- self.state = ""
|
-- self.state = ""
|
||||||
--else
|
--else
|
||||||
if self.attack and not minetest.settings:get_bool("creative_mode") then
|
if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then
|
||||||
self.state = "attack"
|
self.state = 'attack'
|
||||||
end
|
end
|
||||||
--end
|
--end
|
||||||
end
|
end
|
||||||
|
@ -379,16 +391,11 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
--if looking in general head position, turn hostile
|
--if looking in general head position, turn hostile
|
||||||
if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then
|
if minetest.line_of_sight(ender_eye_pos, look_pos_base) and vector.distance(look_pos, ender_eye_pos) <= 0.4 then
|
||||||
self.provoked = "staring"
|
self.provoked = "staring"
|
||||||
self.state = "stand"
|
self.attack = minetest.get_player_by_name(obj:get_player_name())
|
||||||
self.hostile = false
|
|
||||||
break
|
break
|
||||||
--begin attacking the player
|
else -- I'm not sure what this part does, but I don't want to break anything - jordan4ibanez
|
||||||
else
|
|
||||||
if self.provoked == "staring" then
|
if self.provoked == "staring" then
|
||||||
self.provoked = "broke_contact"
|
self.provoked = "broke_contact"
|
||||||
self.hostile = true
|
|
||||||
self.state = "attack"
|
|
||||||
self.attacking = obj
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -412,20 +419,17 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
self._take_place_timer = 0
|
self._take_place_timer = 0
|
||||||
self._next_take_place_time = math.random(place_frequency_min, place_frequency_max)
|
self._next_take_place_time = math.random(place_frequency_min, place_frequency_max)
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
local takable_nodes = minetest.find_nodes_in_area_under_air({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, mobs_mc.enderman_takable)
|
local takable_nodes = minetest.find_nodes_in_area_under_air({x=pos.x-2, y=pos.y-1, z=pos.z-2}, {x=pos.x+2, y=pos.y+1, z=pos.z+2}, "group:enderman_takable")
|
||||||
if #takable_nodes >= 1 then
|
if #takable_nodes >= 1 then
|
||||||
local r = pr:next(1, #takable_nodes)
|
local r = pr:next(1, #takable_nodes)
|
||||||
local take_pos = takable_nodes[r]
|
local take_pos = takable_nodes[r]
|
||||||
local node = minetest.get_node(take_pos)
|
local node = minetest.get_node(take_pos)
|
||||||
-- Don't destroy protected stuff.
|
-- Don't destroy protected stuff.
|
||||||
if not minetest.is_protected(take_pos, "") then
|
if not minetest.is_protected(take_pos, "") then
|
||||||
local dug = minetest.dig_node(take_pos)
|
minetest.remove_node(take_pos)
|
||||||
if dug then
|
local dug = minetest.get_node_or_nil(take_pos)
|
||||||
if mobs_mc.enderman_replace_on_take[node.name] then
|
if dug and dug.name == "air" then
|
||||||
self._taken_node = mobs_mc.enderman_replace_on_take[node.name]
|
self._taken_node = node.name
|
||||||
else
|
|
||||||
self._taken_node = node.name
|
|
||||||
end
|
|
||||||
local def = minetest.registered_nodes[self._taken_node]
|
local def = minetest.registered_nodes[self._taken_node]
|
||||||
-- Update animation and texture accordingly (adds visibly carried block)
|
-- Update animation and texture accordingly (adds visibly carried block)
|
||||||
local block_type
|
local block_type
|
||||||
|
@ -454,14 +458,14 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
self.base_texture = create_enderman_textures(block_type, self._taken_node)
|
self.base_texture = create_enderman_textures(block_type, self._taken_node)
|
||||||
self.object:set_properties({ textures = self.base_texture })
|
self.object:set_properties({ textures = self.base_texture })
|
||||||
self.animation = select_enderman_animation("block")
|
self.animation = select_enderman_animation("block")
|
||||||
mobs.set_mob_animation(self, self.animation.current)
|
mcl_mobs:set_animation(self, self.animation.current)
|
||||||
if def.sounds and def.sounds.dug then
|
if def.sounds and def.sounds.dug then
|
||||||
minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true)
|
minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elseif self._taken_node and self._taken_node ~= "" and self._take_place_timer >= self._next_take_place_time then
|
elseif self._taken_node ~= nil and self._taken_node ~= "" and self._take_place_timer >= self._next_take_place_time then
|
||||||
-- Place taken node
|
-- Place taken node
|
||||||
self._take_place_timer = 0
|
self._take_place_timer = 0
|
||||||
self._next_take_place_time = math.random(take_frequency_min, take_frequency_max)
|
self._next_take_place_time = math.random(take_frequency_min, take_frequency_max)
|
||||||
|
@ -477,7 +481,7 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
local def = minetest.registered_nodes[self._taken_node]
|
local def = minetest.registered_nodes[self._taken_node]
|
||||||
-- Update animation accordingly (removes visible block)
|
-- Update animation accordingly (removes visible block)
|
||||||
self.animation = select_enderman_animation("normal")
|
self.animation = select_enderman_animation("normal")
|
||||||
mobs.set_mob_animation(self, self.animation.current)
|
mcl_mobs:set_animation(self, self.animation.current)
|
||||||
if def.sounds and def.sounds.place then
|
if def.sounds and def.sounds.place then
|
||||||
minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true)
|
minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}, true)
|
||||||
end
|
end
|
||||||
|
@ -487,12 +491,12 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
do_teleport = function(self, target)
|
do_teleport = function(self, target)
|
||||||
if target then
|
if target ~= nil then
|
||||||
local target_pos = target:get_pos()
|
local target_pos = target:get_pos()
|
||||||
-- Find all solid nodes below air in a 10×10×10 cuboid centered on the target
|
-- Find all solid nodes below air in a 10×10×10 cuboid centered on the target
|
||||||
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(target_pos, 5), vector.add(target_pos, 5), {"group:solid", "group:cracky", "group:crumbly"})
|
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(target_pos, 5), vector.add(target_pos, 5), {"group:solid", "group:cracky", "group:crumbly"})
|
||||||
local telepos
|
local telepos
|
||||||
if nodes then
|
if nodes ~= nil then
|
||||||
if #nodes > 0 then
|
if #nodes > 0 then
|
||||||
-- Up to 64 attempts to teleport
|
-- Up to 64 attempts to teleport
|
||||||
for n=1, math.min(64, #nodes) do
|
for n=1, math.min(64, #nodes) do
|
||||||
|
@ -502,7 +506,8 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
-- Selected node needs to have 3 nodes of free space above
|
-- Selected node needs to have 3 nodes of free space above
|
||||||
for u=1, 3 do
|
for u=1, 3 do
|
||||||
local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z})
|
local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z})
|
||||||
if minetest.registered_nodes[node.name].walkable then
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
if ndef and ndef.walkable then
|
||||||
node_ok = false
|
node_ok = false
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -527,7 +532,7 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
-- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract():
|
-- We need to add (or subtract) different random numbers to each vector component, so it couldn't be done with a nice single vector.add() or .subtract():
|
||||||
local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) )
|
local randomCube = vector.new( pos.x + 8*(pr:next(0,16)-8), pos.y + 8*(pr:next(0,16)-8), pos.z + 8*(pr:next(0,16)-8) )
|
||||||
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"})
|
local nodes = minetest.find_nodes_in_area_under_air(vector.subtract(randomCube, 4), vector.add(randomCube, 4), {"group:solid", "group:cracky", "group:crumbly"})
|
||||||
if nodes then
|
if nodes ~= nil then
|
||||||
if #nodes > 0 then
|
if #nodes > 0 then
|
||||||
-- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport
|
-- Up to 8 low-level (in total up to 8*8 = 64) attempts to teleport
|
||||||
for n=1, math.min(8, #nodes) do
|
for n=1, math.min(8, #nodes) do
|
||||||
|
@ -536,7 +541,8 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
node_ok = true
|
node_ok = true
|
||||||
for u=1, 3 do
|
for u=1, 3 do
|
||||||
local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z})
|
local node = minetest.get_node({x=nodepos.x, y=nodepos.y+u, z=nodepos.z})
|
||||||
if minetest.registered_nodes[node.name].walkable then
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
if ndef and ndef.walkable then
|
||||||
node_ok = false
|
node_ok = false
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -559,13 +565,13 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
end,
|
end,
|
||||||
on_die = function(self, pos)
|
on_die = function(self, pos)
|
||||||
-- Drop carried node on death
|
-- Drop carried node on death
|
||||||
if self._taken_node and self._taken_node ~= "" then
|
if self._taken_node ~= nil and self._taken_node ~= "" then
|
||||||
minetest.add_item(pos, self._taken_node)
|
minetest.add_item(pos, self._taken_node)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
do_punch = function(self, hitter, tflp, tool_caps, dir)
|
do_punch = function(self, hitter, tflp, tool_caps, dir)
|
||||||
-- damage from rain caused by itself so we don't want it to attack itself.
|
-- damage from rain caused by itself so we don't want it to attack itself.
|
||||||
if hitter ~= self.object and hitter then
|
if hitter ~= self.object and hitter ~= nil then
|
||||||
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
|
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
|
||||||
-- self:teleport(nil)
|
-- self:teleport(nil)
|
||||||
--else
|
--else
|
||||||
|
@ -581,12 +587,12 @@ mobs:register_mob("mobs_mc:enderman", {
|
||||||
water_damage = 8,
|
water_damage = 8,
|
||||||
view_range = 64,
|
view_range = 64,
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
attack_type = "punch",
|
attack_type = "dogfight",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
-- End spawn
|
-- End spawn
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:enderman",
|
"mobs_mc:enderman",
|
||||||
"end",
|
"end",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -598,10 +604,10 @@ minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
3000,
|
3000,
|
||||||
12,
|
12,
|
||||||
mobs_mc.spawn_height.end_min,
|
mcl_vars.mg_end_min,
|
||||||
mobs_mc.spawn_height.end_max)
|
mcl_vars.mg_end_max)
|
||||||
-- Overworld spawn
|
-- Overworld spawn
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:enderman",
|
"mobs_mc:enderman",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -751,24 +757,41 @@ mobs:spawn_specific(
|
||||||
30,
|
30,
|
||||||
19000,
|
19000,
|
||||||
2,
|
2,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- Nether spawn (rare)
|
-- Nether spawn (rare)
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:enderman",
|
"mobs_mc:enderman",
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"SoulsandValley",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
7,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
27500,
|
27500,
|
||||||
4,
|
4,
|
||||||
mobs_mc.spawn_height.nether_min,
|
mcl_vars.mg_nether_min,
|
||||||
mobs_mc.spawn_height.nether_max)
|
mcl_vars.mg_nether_max)
|
||||||
|
|
||||||
|
-- Warped Forest spawn (common)
|
||||||
|
mcl_mobs:spawn_specific(
|
||||||
|
"mobs_mc:enderman",
|
||||||
|
"nether",
|
||||||
|
"ground",
|
||||||
|
{
|
||||||
|
"WarpedForest"
|
||||||
|
},
|
||||||
|
0,
|
||||||
|
minetest.LIGHT_MAX+1,
|
||||||
|
30,
|
||||||
|
5000,
|
||||||
|
4,
|
||||||
|
mcl_vars.mg_nether_min,
|
||||||
|
mcl_vars.mg_nether_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)
|
mcl_mobs:register_egg("mobs_mc:enderman", S("Enderman"), "mobs_mc_spawn_icon_enderman.png", 0)
|
||||||
|
|
|
@ -2,22 +2,19 @@
|
||||||
--################### ENDERMITE
|
--################### ENDERMITE
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:endermite", {
|
mcl_mobs:register_mob("mobs_mc:endermite", {
|
||||||
description = S("Endermite"),
|
description = S("Endermite"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
passive = false,
|
passive = false,
|
||||||
rotate = 270,
|
|
||||||
hostile = true,
|
|
||||||
hp_min = 8,
|
hp_min = 8,
|
||||||
hp_max = 8,
|
hp_max = 8,
|
||||||
xp_min = 3,
|
xp_min = 3,
|
||||||
xp_max = 3,
|
xp_max = 3,
|
||||||
armor = {fleshy = 100, arthropod = 100},
|
armor = {fleshy = 100, arthropod = 100},
|
||||||
group_attack = true,
|
group_attack = true,
|
||||||
attack_type = "punch",
|
|
||||||
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.29, 0.2},
|
collisionbox = {-0.2, -0.01, -0.2, 0.2, 0.29, 0.2},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_endermite.b3d",
|
mesh = "mobs_mc_endermite.b3d",
|
||||||
|
@ -41,4 +38,4 @@ mobs:register_mob("mobs_mc:endermite", {
|
||||||
reach = 1,
|
reach = 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:register_egg("mobs_mc:endermite", S("Endermite"), "mobs_mc_spawn_icon_endermite.png", 0)
|
mcl_mobs:register_egg("mobs_mc:endermite", S("Endermite"), "mobs_mc_spawn_icon_endermite.png", 0)
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
# Game integration help
|
|
||||||
|
|
||||||
This mod has been designed to make game integration rather easy. Ideally, it should be possible to include this mod verbatim in your game, with modifications only done by an external mod.
|
|
||||||
|
|
||||||
To integrate this mod in a game, you have to do 2 things: Adding the mod, and adding another mod which tells `mobs_mc` which items to use. The idea is that `mobs_mc` should work with any items. Specifically, these are the steps you need to follow:
|
|
||||||
|
|
||||||
* Add the `mobs_mc` mod and its dependencies
|
|
||||||
* Add a mod with name “`mobs_mc_gameconfig`”
|
|
||||||
* In this mod, do this:
|
|
||||||
* Do *not* depend on `mobs_mc`
|
|
||||||
* Create the table `mobs_mc`
|
|
||||||
* Create the table `mobs_mc.override`
|
|
||||||
* In `mobs_mc.override`, create subtables (`items`, `spawn`, etc.) like in `0_gameconfig.lua`, defining the na
|
|
||||||
* Read `0_gameconfig.lua` to see which items you can override (and more explanations)
|
|
||||||
* In `on_construct` of a pumpkin or jack'o lantern node, call:
|
|
||||||
* `mobs_mc.tools.check_iron_golem_summon(pos)`
|
|
||||||
* `mobs_mc.tools.check_snow_golem_summon(pos)`
|
|
||||||
* For more information, see `snowman.lua` and `iron_golem.lua`
|
|
||||||
|
|
||||||
Some things to note:
|
|
||||||
|
|
||||||
* Every override is optional, but explicitly setting all the item overrides is strongly recommended
|
|
||||||
* `mobs_mc` ships many (but not all) items on its own. If not item name override is set, the `mobs_mc` item is used
|
|
||||||
* You decide whether your game defines its own items, outside of `mobs_mc` or if you let `mobs_mc` do the work.
|
|
||||||
* Make sure to avoid duplicate items!
|
|
||||||
* After finishing this, throughly test this
|
|
||||||
* Without `mobs_mc_gameconfig`, the mod assumes Minetest Game items
|
|
||||||
* `mobs_mc` optionally depends on `mobs_mc_gameconfig`
|
|
||||||
|
|
||||||
## Example `init.lua` in `mobs_mc_gameconfig`
|
|
||||||
```
|
|
||||||
mobs_mc = {}
|
|
||||||
|
|
||||||
mobs_mc.override = {}
|
|
||||||
|
|
||||||
-- Set the item names here
|
|
||||||
mobs_mc.override.items = {
|
|
||||||
blaze_rod = "mcl_mobitems:blaze_rod",
|
|
||||||
blaze_powder = "mcl_mobitems:blaze_powder",
|
|
||||||
chicken_raw = "mcl_mobitems:chicken",
|
|
||||||
-- And so on ...
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Set the “follow” field of mobs (used for attracting mob, feeding and breeding)
|
|
||||||
mobs_mc.override.follow = {
|
|
||||||
chicken = { "mcl_farming:wheat_seeds", "mcl_farming:melon_seeds", "mcl_farming:pumpkin_seeds", "mcl_farming:beetroot_seeds", },
|
|
||||||
horse = { "mcl_core:apple", mobs_mc.override.items.wheat }, -- TODO
|
|
||||||
pig = { "mcl_farming:potato", mobs_mc.override.items.carrot, mobs_mc.override.items.carrot_on_a_stick},
|
|
||||||
-- And so on ...
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Custom spawn nodes
|
|
||||||
mobs_mc.override.spawn = {
|
|
||||||
snow = { "example:snow", "example:snow2" },
|
|
||||||
-- And so on ...
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Take a look at the other possible tables, see 0_gameconfig.lua
|
|
||||||
```
|
|
|
@ -3,28 +3,24 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### GHAST
|
--################### GHAST
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:ghast", {
|
mcl_mobs:register_mob("mobs_mc:ghast", {
|
||||||
description = S("Ghast"),
|
description = S("Ghast"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
pathfinding = 1,
|
||||||
group_attack = true,
|
group_attack = true,
|
||||||
hostile = true,
|
|
||||||
fly_random_while_attack = true,
|
|
||||||
hp_min = 10,
|
hp_min = 10,
|
||||||
hp_max = 10,
|
hp_max = 10,
|
||||||
rotate = 270,
|
|
||||||
xp_min = 5,
|
xp_min = 5,
|
||||||
xp_max = 5,
|
xp_max = 5,
|
||||||
reach = 20,
|
collisionbox = {-2, 5, -2, 2, 9, 2},
|
||||||
eye_height = 2.5,
|
|
||||||
collisionbox = {-2, 0, -2, 2, 4, 2},
|
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_ghast.b3d",
|
mesh = "mobs_mc_ghast.b3d",
|
||||||
textures = {
|
textures = {
|
||||||
|
@ -40,13 +36,11 @@ mobs:register_mob("mobs_mc:ghast", {
|
||||||
-- TODO: damage
|
-- TODO: damage
|
||||||
-- TODO: better death
|
-- TODO: better death
|
||||||
},
|
},
|
||||||
|
|
||||||
walk_velocity = 1.6,
|
walk_velocity = 1.6,
|
||||||
run_velocity = 3.2,
|
run_velocity = 3.2,
|
||||||
|
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.gunpowder, chance = 1, min = 0, max = 2, looting = "common"},
|
{name = "mcl_mobitems:gunpowder", chance = 1, min = 0, max = 2, looting = "common"},
|
||||||
{name = mobs_mc.items.ghast_tear, chance = 10/6, min = 0, max = 1, looting = "common", looting_ignore_chance = true},
|
{name = "mcl_mobitems:ghast_tear", chance = 10/6, min = 0, max = 1, looting = "common", looting_ignore_chance = true},
|
||||||
},
|
},
|
||||||
animation = {
|
animation = {
|
||||||
stand_speed = 50, walk_speed = 50, run_speed = 50,
|
stand_speed = 50, walk_speed = 50, run_speed = 50,
|
||||||
|
@ -54,23 +48,22 @@ mobs:register_mob("mobs_mc:ghast", {
|
||||||
walk_start = 0, walk_end = 40,
|
walk_start = 0, walk_end = 40,
|
||||||
run_start = 0, run_end = 40,
|
run_start = 0, run_end = 40,
|
||||||
},
|
},
|
||||||
|
|
||||||
fall_damage = 0,
|
fall_damage = 0,
|
||||||
view_range = 28,
|
view_range = 100,
|
||||||
attack_type = "projectile",
|
attack_type = "dogshoot",
|
||||||
arrow = "mobs_mc:ghast_fireball",
|
arrow = "mobs_mc:fireball",
|
||||||
|
shoot_interval = 3.5,
|
||||||
|
shoot_offset = -5,
|
||||||
|
dogshoot_switch = 1,
|
||||||
|
dogshoot_count_max =1,
|
||||||
|
passive = false,
|
||||||
|
jump = true,
|
||||||
|
jump_height = 4,
|
||||||
floats=1,
|
floats=1,
|
||||||
fly = true,
|
fly = true,
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
|
instant_death = true,
|
||||||
fire_resistant = true,
|
fire_resistant = true,
|
||||||
projectile_cooldown_min = 5,
|
|
||||||
projectile_cooldown_max = 7,
|
|
||||||
shoot_arrow = function(self, pos, dir)
|
|
||||||
-- 2-4 damage per arrow
|
|
||||||
local dmg = math.random(2,4)
|
|
||||||
mobs.shoot_projectile_handling("mobs_mc:ghast_fireball", pos, dir, self.object:get_yaw(), self.object, 11, dmg,nil,nil,nil,-0.6)
|
|
||||||
end,
|
|
||||||
--[[
|
|
||||||
do_custom = function(self)
|
do_custom = function(self)
|
||||||
if self.firing == true then
|
if self.firing == true then
|
||||||
self.base_texture = {"mobs_mc_ghast_firing.png"}
|
self.base_texture = {"mobs_mc_ghast_firing.png"}
|
||||||
|
@ -80,60 +73,58 @@ mobs:register_mob("mobs_mc:ghast", {
|
||||||
self.object:set_properties({textures=self.base_texture})
|
self.object:set_properties({textures=self.base_texture})
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
]]--
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:ghast",
|
"mobs_mc:ghast",
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"SoulsandValley",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
7,
|
||||||
30,
|
30,
|
||||||
18000,
|
72000,
|
||||||
2,
|
2,
|
||||||
mobs_mc.spawn_height.nether_min,
|
mcl_vars.mg_nether_min,
|
||||||
mobs_mc.spawn_height.nether_max)
|
mcl_vars.mg_nether_max)
|
||||||
|
|
||||||
-- fireball (projectile)
|
-- fireball (projectile)
|
||||||
mobs:register_arrow("mobs_mc:ghast_fireball", {
|
mcl_mobs:register_arrow("mobs_mc:fireball", {
|
||||||
visual = "sprite",
|
visual = "sprite",
|
||||||
visual_size = {x = 1, y = 1},
|
visual_size = {x = 1, y = 1},
|
||||||
textures = {"mcl_fire_fire_charge.png"},
|
textures = {"mcl_fire_fire_charge.png"},
|
||||||
velocity = 15,
|
velocity = 15,
|
||||||
collisionbox = {-.5, -.5, -.5, .5, .5, .5},
|
collisionbox = {-.5, -.5, -.5, .5, .5, .5},
|
||||||
tail = 1,
|
|
||||||
tail_texture = "mobs_mc_spit.png^[colorize:black:255", --repurpose spit texture
|
|
||||||
tail_size = 5,
|
|
||||||
_is_fireball = true,
|
_is_fireball = true,
|
||||||
|
|
||||||
hit_player = function(self, player)
|
hit_player = function(self, player)
|
||||||
--[[
|
|
||||||
player:punch(self.object, 1.0, {
|
player:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
damage_groups = {fleshy = 6},
|
damage_groups = {fleshy = 6},
|
||||||
}, nil)
|
}, nil)
|
||||||
]]--
|
local p = self.object:get_pos()
|
||||||
--mobs:boom(self, self.object:get_pos(), 1, true)
|
if p then
|
||||||
mcl_explosions.explode(self.object:get_pos(), 3,{ drop_chance = 1.0 })
|
mcl_mobs:boom(self, p, 1, true)
|
||||||
|
else
|
||||||
|
mcl_mobs:boom(self, player:get_pos(), 1, true)
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
hit_mob = function(self, mob)
|
hit_mob = function(self, mob)
|
||||||
mob:punch(self.object, 1.0, {
|
mob:punch(self.object, 1.0, {
|
||||||
full_punch_interval = 1.0,
|
full_punch_interval = 1.0,
|
||||||
damage_groups = {fleshy = self._damage},
|
damage_groups = {fleshy = 6},
|
||||||
}, nil)
|
}, nil)
|
||||||
--mobs:boom(self, self.object:get_pos(), 1, true)
|
mcl_mobs:boom(self, self.object:get_pos(), 1, true)
|
||||||
mcl_explosions.explode(self.object:get_pos(), 3,{ drop_chance = 1.0 })
|
|
||||||
end,
|
end,
|
||||||
|
|
||||||
hit_node = function(self, pos, node)
|
hit_node = function(self, pos, node)
|
||||||
--mobs:boom(self, pos, 1, true)
|
mcl_mobs:boom(self, pos, 1, true)
|
||||||
mcl_explosions.explode(self.object:get_pos(), 3,{ drop_chance = 1.0 })
|
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -141,4 +132,4 @@ mobs:register_arrow("mobs_mc:ghast_fireball", {
|
||||||
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:ghast", S("Ghast"), "mobs_mc_spawn_icon_ghast.png", 0)
|
mcl_mobs:register_egg("mobs_mc:ghast", S("Ghast"), "mobs_mc_spawn_icon_ghast.png", 0)
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
--################### GUARDIAN
|
--################### GUARDIAN
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:guardian", {
|
mcl_mobs:register_mob("mobs_mc:guardian", {
|
||||||
description = S("Guardian"),
|
description = S("Guardian"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
@ -13,8 +13,8 @@ mobs:register_mob("mobs_mc:guardian", {
|
||||||
xp_min = 10,
|
xp_min = 10,
|
||||||
xp_max = 10,
|
xp_max = 10,
|
||||||
breath_max = -1,
|
breath_max = -1,
|
||||||
passive = false,
|
passive = false,
|
||||||
attack_type = "punch",
|
attack_type = "dogfight",
|
||||||
pathfinding = 1,
|
pathfinding = 1,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
walk_velocity = 2,
|
walk_velocity = 2,
|
||||||
|
@ -44,7 +44,7 @@ mobs:register_mob("mobs_mc:guardian", {
|
||||||
},
|
},
|
||||||
drops = {
|
drops = {
|
||||||
-- Greatly increased amounts of prismarine
|
-- Greatly increased amounts of prismarine
|
||||||
{name = mobs_mc.items.prismarine_shard,
|
{name = "mcl_ocean:prismarine_shard",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 32,
|
max = 32,
|
||||||
|
@ -53,37 +53,37 @@ mobs:register_mob("mobs_mc:guardian", {
|
||||||
|
|
||||||
-- The following drops are approximations
|
-- The following drops are approximations
|
||||||
-- Fish / prismarine crystal
|
-- Fish / prismarine crystal
|
||||||
{name = mobs_mc.items.fish_raw,
|
{name = "mcl_fishing:fish_raw",
|
||||||
chance = 4,
|
chance = 4,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
{name = mobs_mc.items.prismarine_crystals,
|
{name = "mcl_ocean:prismarine_crystals",
|
||||||
chance = 4,
|
chance = 4,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
|
|
||||||
-- Rare drop: fish
|
-- Rare drop: fish
|
||||||
{name = mobs_mc.items.fish_raw,
|
{name = "mcl_fishing:fish_raw",
|
||||||
chance = 160, -- 2.5% / 4
|
chance = 160, -- 2.5% / 4
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "rare",
|
looting = "rare",
|
||||||
looting_factor = 0.0025,},
|
looting_factor = 0.0025,},
|
||||||
{name = mobs_mc.items.salmon_raw,
|
{name = "mcl_fishing:salmon_raw",
|
||||||
chance = 160,
|
chance = 160,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "rare",
|
looting = "rare",
|
||||||
looting_factor = 0.0025,},
|
looting_factor = 0.0025,},
|
||||||
{name = mobs_mc.items.clownfish_raw,
|
{name = "mcl_fishing:clownfish_raw",
|
||||||
chance = 160,
|
chance = 160,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "rare",
|
looting = "rare",
|
||||||
looting_factor = 0.0025,},
|
looting_factor = 0.0025,},
|
||||||
{name = mobs_mc.items.pufferfish_raw,
|
{name = "mcl_fishing:pufferfish_raw",
|
||||||
chance = 160,
|
chance = 160,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
|
@ -92,13 +92,14 @@ mobs:register_mob("mobs_mc:guardian", {
|
||||||
},
|
},
|
||||||
fly = true,
|
fly = true,
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
|
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
|
||||||
jump = false,
|
jump = false,
|
||||||
|
view_range = 16,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Spawning disabled due to size issues
|
-- Spawning disabled due to size issues
|
||||||
-- TODO: Re-enable spawning
|
-- TODO: Re-enable spawning
|
||||||
--mobs:spawn_specific("mobs_mc:guardian", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water - 10)
|
--mcl_mobs:spawn_specific("mobs_mc:guardian", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 25000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level - 10)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:guardian", S("Guardian"), "mobs_mc_spawn_icon_guardian.png", 0)
|
mcl_mobs:register_egg("mobs_mc:guardian", S("Guardian"), "mobs_mc_spawn_icon_guardian.png", 0)
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
--################### GUARDIAN
|
--################### GUARDIAN
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:guardian_elder", {
|
mcl_mobs:register_mob("mobs_mc:guardian_elder", {
|
||||||
description = S("Elder Guardian"),
|
description = S("Elder Guardian"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
@ -15,8 +15,8 @@ mobs:register_mob("mobs_mc:guardian_elder", {
|
||||||
xp_min = 10,
|
xp_min = 10,
|
||||||
xp_max = 10,
|
xp_max = 10,
|
||||||
breath_max = -1,
|
breath_max = -1,
|
||||||
passive = false,
|
passive = false,
|
||||||
attack_type = "punch",
|
attack_type = "dogfight",
|
||||||
pathfinding = 1,
|
pathfinding = 1,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
walk_velocity = 2,
|
walk_velocity = 2,
|
||||||
|
@ -49,51 +49,51 @@ mobs:register_mob("mobs_mc:guardian_elder", {
|
||||||
-- TODO: Reduce # of drops when ocean monument is ready.
|
-- TODO: Reduce # of drops when ocean monument is ready.
|
||||||
|
|
||||||
-- Greatly increased amounts of prismarine
|
-- Greatly increased amounts of prismarine
|
||||||
{name = mobs_mc.items.prismarine_shard,
|
{name = "mcl_ocean:prismarine_shard",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 64,
|
max = 64,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
|
|
||||||
-- TODO: Only drop if killed by player
|
-- TODO: Only drop if killed by player
|
||||||
{name = mobs_mc.items.wet_sponge,
|
{name = "mcl_sponges:sponge_wet",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,},
|
max = 1,},
|
||||||
|
|
||||||
-- The following drops are approximations
|
-- The following drops are approximations
|
||||||
-- Fish / prismarine crystal
|
-- Fish / prismarine crystal
|
||||||
{name = mobs_mc.items.fish_raw,
|
{name = "mcl_fishing:fish_raw",
|
||||||
chance = 4,
|
chance = 4,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
{name = mobs_mc.items.prismarine_crystals,
|
{name = "mcl_ocean:prismarine_crystals",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 10,
|
max = 10,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
|
|
||||||
-- Rare drop: fish
|
-- Rare drop: fish
|
||||||
{name = mobs_mc.items.fish_raw,
|
{name = "mcl_fishing:fish_raw",
|
||||||
chance = 160, -- 2.5% / 4
|
chance = 160, -- 2.5% / 4
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "rare",
|
looting = "rare",
|
||||||
looting_factor = 0.01 / 4,},
|
looting_factor = 0.01 / 4,},
|
||||||
{name = mobs_mc.items.salmon_raw,
|
{name = "mcl_fishing:salmon_raw",
|
||||||
chance = 160,
|
chance = 160,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "rare",
|
looting = "rare",
|
||||||
looting_factor = 0.01 / 4,},
|
looting_factor = 0.01 / 4,},
|
||||||
{name = mobs_mc.items.clownfish_raw,
|
{name = "mcl_fishing:clownfish_raw",
|
||||||
chance = 160,
|
chance = 160,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "rare",
|
looting = "rare",
|
||||||
looting_factor = 0.01 / 4,},
|
looting_factor = 0.01 / 4,},
|
||||||
{name = mobs_mc.items.pufferfish_raw,
|
{name = "mcl_fishing:pufferfish_raw",
|
||||||
chance = 160,
|
chance = 160,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
|
@ -102,14 +102,15 @@ mobs:register_mob("mobs_mc:guardian_elder", {
|
||||||
},
|
},
|
||||||
fly = true,
|
fly = true,
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
fly_in = { mobs_mc.items.water_source, mobs_mc.items.river_water_source },
|
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
|
||||||
jump = false,
|
jump = false,
|
||||||
|
view_range = 16,
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Spawning disabled due to size issues <- what do you mean? -j4i
|
-- Spawning disabled due to size issues <- what do you mean? -j4i
|
||||||
-- TODO: Re-enable spawning
|
-- TODO: Re-enable spawning
|
||||||
-- mobs:spawn_specific("mobs_mc:guardian_elder", mobs_mc.spawn.water, mobs_mc.spawn_water, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.water-18)
|
-- mcl_mobs:spawn_specific("mobs_mc:guardian_elder", { "mcl_core:water_source", "mclx_core:river_water_source" }, { "mcl_core:water_source", "mclx_core:river_water_source" }, 0, minetest.LIGHT_MAX+1, 30, 40000, 2, mcl_vars.mg_overworld_min, mobs_mc.water_level-18)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0)
|
mcl_mobs:register_egg("mobs_mc:guardian_elder", S("Elder Guardian"), "mobs_mc_spawn_icon_guardian_elder.png", 0)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### HORSE
|
--################### HORSE
|
||||||
|
@ -38,9 +38,9 @@ end
|
||||||
local can_equip_horse_armor = function(entity_id)
|
local can_equip_horse_armor = function(entity_id)
|
||||||
return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse"
|
return entity_id == "mobs_mc:horse" or entity_id == "mobs_mc:skeleton_horse" or entity_id == "mobs_mc:zombie_horse"
|
||||||
end
|
end
|
||||||
--[[local can_equip_chest = function(entity_id)
|
local can_equip_chest = function(entity_id)
|
||||||
return entity_id == "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
|
return entity_id == "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
|
||||||
end]]
|
end
|
||||||
local can_breed = function(entity_id)
|
local can_breed = function(entity_id)
|
||||||
return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
|
return entity_id == "mobs_mc:horse" or "mobs_mc:mule" or entity_id == "mobs_mc:donkey"
|
||||||
end
|
end
|
||||||
|
@ -81,6 +81,20 @@ for b=1, #horse_base do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- in e7898352d890c2414af653eba624939df9c0b8b4 (0.76-dev) all items from mobs_mc were moved to mcl_mobitems
|
||||||
|
-- this results in existing horses wearing armor would still have the old texture filename in their
|
||||||
|
-- properties this function updates them. It should be removed some time in the future when we can be
|
||||||
|
-- reasonably sure all horses that want it get the new nexture.
|
||||||
|
local function update_textures(self)
|
||||||
|
local old = "mobs_mc_horse_armor_"
|
||||||
|
local txt = self.object:get_properties().textures
|
||||||
|
if txt[2]:find(old) then
|
||||||
|
txt[2] = txt[2]:gsub(old,"mcl_mobitems_horse_armor_")
|
||||||
|
self.object:set_properties({textures=txt})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Horse
|
-- Horse
|
||||||
local horse = {
|
local horse = {
|
||||||
description = S("Horse"),
|
description = S("Horse"),
|
||||||
|
@ -88,10 +102,6 @@ local horse = {
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_horse.b3d",
|
mesh = "mobs_mc_horse.b3d",
|
||||||
rotate = 270,
|
|
||||||
walk_velocity = 1,
|
|
||||||
run_velocity = 8,
|
|
||||||
skittish = true,
|
|
||||||
visual_size = {x=3.0, y=3.0},
|
visual_size = {x=3.0, y=3.0},
|
||||||
collisionbox = {-0.69825, -0.01, -0.69825, 0.69825, 1.59, 0.69825},
|
collisionbox = {-0.69825, -0.01, -0.69825, 0.69825, 1.59, 0.69825},
|
||||||
animation = {
|
animation = {
|
||||||
|
@ -101,7 +111,7 @@ local horse = {
|
||||||
walk_speed = 25,
|
walk_speed = 25,
|
||||||
walk_start = 0,
|
walk_start = 0,
|
||||||
walk_end = 40,
|
walk_end = 40,
|
||||||
run_speed = 120,
|
run_speed = 60,
|
||||||
run_start = 0,
|
run_start = 0,
|
||||||
run_end = 40,
|
run_end = 40,
|
||||||
},
|
},
|
||||||
|
@ -118,8 +128,14 @@ local horse = {
|
||||||
fly = false,
|
fly = false,
|
||||||
walk_chance = 60,
|
walk_chance = 60,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
follow = "mcl_farming:wheat_item",
|
follow = {
|
||||||
follow_distance = 3,
|
"mcl_core:apple",
|
||||||
|
"mcl_core:sugar",
|
||||||
|
"mcl_farming:wheat_item",
|
||||||
|
"mcl_farming:hay_block",
|
||||||
|
"mcl_core:apple_gold",
|
||||||
|
"mcl_farming:carrot_item_gold",
|
||||||
|
},
|
||||||
passive = true,
|
passive = true,
|
||||||
hp_min = 15,
|
hp_min = 15,
|
||||||
hp_max = 30,
|
hp_max = 30,
|
||||||
|
@ -130,13 +146,13 @@ local horse = {
|
||||||
jump = true,
|
jump = true,
|
||||||
jump_height = 5.75, -- can clear 2.5 blocks
|
jump_height = 5.75, -- can clear 2.5 blocks
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.leather,
|
{name = "mcl_mobitems:leather",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
},
|
},
|
||||||
|
on_spawn = update_textures,
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
|
||||||
-- set needed values if not already present
|
-- set needed values if not already present
|
||||||
|
@ -166,7 +182,7 @@ local horse = {
|
||||||
-- Some weird human is riding. Buck them off?
|
-- Some weird human is riding. Buck them off?
|
||||||
if self.driver and not self.tamed and self.buck_off_time <= 0 then
|
if self.driver and not self.tamed and self.buck_off_time <= 0 then
|
||||||
if math.random() < 0.2 then
|
if math.random() < 0.2 then
|
||||||
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
||||||
-- TODO bucking animation
|
-- TODO bucking animation
|
||||||
else
|
else
|
||||||
-- Nah, can't be bothered. Think about it again in one second
|
-- Nah, can't be bothered. Think about it again in one second
|
||||||
|
@ -187,7 +203,7 @@ local horse = {
|
||||||
-- if driver present and horse has a saddle allow control of horse
|
-- if driver present and horse has a saddle allow control of horse
|
||||||
if self.driver and self._saddle then
|
if self.driver and self._saddle then
|
||||||
|
|
||||||
mobs.drive(self, "run", "stand", false, dtime)
|
mcl_mobs.drive(self, "walk", "stand", false, dtime)
|
||||||
|
|
||||||
return false -- skip rest of mob functions
|
return false -- skip rest of mob functions
|
||||||
end
|
end
|
||||||
|
@ -199,11 +215,11 @@ local horse = {
|
||||||
|
|
||||||
-- drop saddle when horse is killed while riding
|
-- drop saddle when horse is killed while riding
|
||||||
if self._saddle then
|
if self._saddle then
|
||||||
minetest.add_item(pos, mobs_mc.items.saddle)
|
minetest.add_item(pos, "mcl_mobitems:saddle")
|
||||||
end
|
end
|
||||||
-- also detach from horse properly
|
-- also detach from horse properly
|
||||||
if self.driver then
|
if self.driver then
|
||||||
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
@ -219,21 +235,6 @@ local horse = {
|
||||||
local iname = item:get_name()
|
local iname = item:get_name()
|
||||||
local heal = 0
|
local heal = 0
|
||||||
|
|
||||||
--sneak click to breed the horse/feed it
|
|
||||||
if self.owner and self.owner == clicker:get_player_name() then
|
|
||||||
--attempt to enter breed state
|
|
||||||
if mobs.enter_breed_state(self,clicker) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--don't do any other logic with the baby
|
|
||||||
--make baby grow faster
|
|
||||||
if self.baby then
|
|
||||||
mobs.make_baby_grow_faster(self,clicker)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Taming
|
-- Taming
|
||||||
self.temper = self.temper or (math.random(1,100))
|
self.temper = self.temper or (math.random(1,100))
|
||||||
|
|
||||||
|
@ -242,24 +243,23 @@ local horse = {
|
||||||
|
|
||||||
-- Feeding, intentionally not using mobs:feed_tame because horse taming is
|
-- Feeding, intentionally not using mobs:feed_tame because horse taming is
|
||||||
-- different and more complicated
|
-- different and more complicated
|
||||||
if (iname == mobs_mc.items.sugar) then
|
if (iname == "mcl_core:sugar") then
|
||||||
temper_increase = 3
|
temper_increase = 3
|
||||||
elseif (iname == mobs_mc.items.wheat) then
|
elseif (iname == "mcl_farming:wheat_item") then
|
||||||
temper_increase = 3
|
temper_increase = 3
|
||||||
elseif (iname == mobs_mc.items.apple) then
|
elseif (iname == "mcl_core:apple") then
|
||||||
temper_increase = 3
|
temper_increase = 3
|
||||||
elseif (iname == mobs_mc.items.golden_carrot) then
|
elseif (iname == "mcl_farming:carrot_item_gold") then
|
||||||
temper_increase = 5
|
temper_increase = 5
|
||||||
elseif (iname == mobs_mc.items.golden_apple) then
|
elseif (iname == "mcl_core:apple_gold") then
|
||||||
temper_increase = 10
|
temper_increase = 10
|
||||||
-- Trying to ride
|
-- Trying to ride
|
||||||
elseif not self.driver then
|
elseif not self.driver then
|
||||||
self.object:set_properties({stepheight = 1.1})
|
self.object:set_properties({stepheight = 1.1})
|
||||||
mobs.attach(self, clicker)
|
mcl_mobs.attach(self, clicker)
|
||||||
self.buck_off_time = 40 -- TODO how long does it take in minecraft?
|
self.buck_off_time = 40 -- TODO how long does it take in minecraft?
|
||||||
if self.temper > 100 then
|
if self.temper > 100 then
|
||||||
self.tamed = true -- NOTE taming can only be finished by riding the horse
|
self.tamed = true -- NOTE taming can only be finished by riding the horse
|
||||||
mobs.tamed_effect(self)
|
|
||||||
if not self.owner or self.owner == "" then
|
if not self.owner or self.owner == "" then
|
||||||
self.owner = clicker:get_player_name()
|
self.owner = clicker:get_player_name()
|
||||||
end
|
end
|
||||||
|
@ -268,62 +268,58 @@ local horse = {
|
||||||
|
|
||||||
-- Clicking on the horse while riding ==> unmount
|
-- Clicking on the horse while riding ==> unmount
|
||||||
elseif self.driver and self.driver == clicker then
|
elseif self.driver and self.driver == clicker then
|
||||||
mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- If nothing happened temper_increase = 0 and addition does nothing
|
-- If nothing happened temper_increase = 0 and addition does nothing
|
||||||
self.temper = self.temper + temper_increase
|
self.temper = self.temper + temper_increase
|
||||||
|
|
||||||
--give the player some kind of idea
|
|
||||||
--of what's happening with the horse's temper
|
|
||||||
if self.temper <= 100 then
|
|
||||||
mobs.feed_effect(self)
|
|
||||||
else
|
|
||||||
mobs.tamed_effect(self)
|
|
||||||
end
|
|
||||||
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if can_breed(self.name) then
|
if can_breed(self.name) then
|
||||||
-- Breed horse with golden apple or golden carrot
|
-- Breed horse with golden apple or golden carrot
|
||||||
if (iname == mobs_mc.items.golden_apple) then
|
if (iname == "mcl_core:apple_gold") then
|
||||||
heal = 10
|
heal = 10
|
||||||
elseif (iname == mobs_mc.items.golden_carrot) then
|
elseif (iname == "mcl_farming:carrot_item_gold") then
|
||||||
heal = 4
|
heal = 4
|
||||||
end
|
end
|
||||||
if heal > 0 and mobs:feed_tame(self, clicker, heal, true, false) then
|
if heal > 0 and mcl_mobs:feed_tame(self, clicker, heal, true, false) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- Feed with anything else
|
-- Feed with anything else
|
||||||
-- TODO heal amounts don't work
|
-- TODO heal amounts don't work
|
||||||
if (iname == mobs_mc.items.sugar) then
|
if (iname == "mcl_core:sugar") then
|
||||||
heal = 1
|
heal = 1
|
||||||
elseif (iname == mobs_mc.items.wheat) then
|
elseif (iname == "mcl_farming:wheat_item") then
|
||||||
heal = 2
|
heal = 2
|
||||||
elseif (iname == mobs_mc.items.apple) then
|
elseif (iname == "mcl_core:apple") then
|
||||||
heal = 3
|
heal = 3
|
||||||
elseif (iname == mobs_mc.items.hay_bale) then
|
elseif (iname == "mcl_farming:hay_block") then
|
||||||
heal = 20
|
heal = 20
|
||||||
end
|
end
|
||||||
if heal > 0 and mobs:feed_tame(self, clicker, heal, false, false) then
|
if heal > 0 and mcl_mobs:feed_tame(self, clicker, heal, false, false) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if mcl_mobs:protect(self, clicker) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Make sure tamed horse is mature and being clicked by owner only
|
-- Make sure tamed horse is mature and being clicked by owner only
|
||||||
if self.tamed and not self.child and self.owner == clicker:get_player_name() then
|
if self.tamed and not self.child and self.owner == clicker:get_player_name() then
|
||||||
|
|
||||||
--local inv = clicker:get_inventory()
|
local inv = clicker:get_inventory()
|
||||||
|
|
||||||
-- detatch player already riding horse
|
-- detatch player already riding horse
|
||||||
if self.driver and clicker == self.driver then
|
if self.driver and clicker == self.driver then
|
||||||
|
|
||||||
mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
||||||
|
|
||||||
-- Put on saddle if tamed
|
-- Put on saddle if tamed
|
||||||
elseif not self.driver and not self._saddle
|
elseif not self.driver and not self._saddle
|
||||||
and iname == mobs_mc.items.saddle then
|
and iname == "mcl_mobitems:saddle" then
|
||||||
|
|
||||||
-- Put on saddle and take saddle from player's inventory
|
-- Put on saddle and take saddle from player's inventory
|
||||||
local w = clicker:get_wielded_item()
|
local w = clicker:get_wielded_item()
|
||||||
|
@ -380,15 +376,18 @@ local horse = {
|
||||||
elseif not self.driver and self._saddle then
|
elseif not self.driver and self._saddle then
|
||||||
|
|
||||||
self.object:set_properties({stepheight = 1.1})
|
self.object:set_properties({stepheight = 1.1})
|
||||||
mobs.attach(self, clicker)
|
mcl_mobs.attach(self, clicker)
|
||||||
|
|
||||||
|
-- Used to capture horse
|
||||||
|
elseif not self.driver and iname ~= "" then
|
||||||
|
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_breed = function(parent1, parent2)
|
on_breed = function(parent1, parent2)
|
||||||
local pos = parent1.object:get_pos()
|
local pos = parent1.object:get_pos()
|
||||||
local child = mobs:spawn_child(pos, parent1.name)
|
local child = mcl_mobs:spawn_child(pos, parent1.name)
|
||||||
if child then
|
if child then
|
||||||
local ent_c = child:get_luaentity()
|
local ent_c = child:get_luaentity()
|
||||||
local p = math.random(1, 2)
|
local p = math.random(1, 2)
|
||||||
|
@ -437,7 +436,7 @@ local horse = {
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:horse", horse)
|
mcl_mobs:register_mob("mobs_mc:horse", horse)
|
||||||
|
|
||||||
-- Skeleton horse
|
-- Skeleton horse
|
||||||
local skeleton_horse = table.copy(horse)
|
local skeleton_horse = table.copy(horse)
|
||||||
|
@ -446,7 +445,7 @@ skeleton_horse.breath_max = -1
|
||||||
skeleton_horse.armor = {undead = 100, fleshy = 100}
|
skeleton_horse.armor = {undead = 100, fleshy = 100}
|
||||||
skeleton_horse.textures = {{"blank.png", "mobs_mc_horse_skeleton.png", "blank.png"}}
|
skeleton_horse.textures = {{"blank.png", "mobs_mc_horse_skeleton.png", "blank.png"}}
|
||||||
skeleton_horse.drops = {
|
skeleton_horse.drops = {
|
||||||
{name = mobs_mc.items.bone,
|
{name = "mcl_mobitems:bone",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
|
@ -460,7 +459,7 @@ skeleton_horse.sounds = {
|
||||||
distance = 16,
|
distance = 16,
|
||||||
}
|
}
|
||||||
skeleton_horse.harmed_by_heal = true
|
skeleton_horse.harmed_by_heal = true
|
||||||
mobs:register_mob("mobs_mc:skeleton_horse", skeleton_horse)
|
mcl_mobs:register_mob("mobs_mc:skeleton_horse", skeleton_horse)
|
||||||
|
|
||||||
-- Zombie horse
|
-- Zombie horse
|
||||||
local zombie_horse = table.copy(horse)
|
local zombie_horse = table.copy(horse)
|
||||||
|
@ -469,7 +468,7 @@ zombie_horse.breath_max = -1
|
||||||
zombie_horse.armor = {undead = 100, fleshy = 100}
|
zombie_horse.armor = {undead = 100, fleshy = 100}
|
||||||
zombie_horse.textures = {{"blank.png", "mobs_mc_horse_zombie.png", "blank.png"}}
|
zombie_horse.textures = {{"blank.png", "mobs_mc_horse_zombie.png", "blank.png"}}
|
||||||
zombie_horse.drops = {
|
zombie_horse.drops = {
|
||||||
{name = mobs_mc.items.rotten_flesh,
|
{name = "mcl_mobitems:rotten_flesh",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
|
@ -484,7 +483,7 @@ zombie_horse.sounds = {
|
||||||
distance = 16,
|
distance = 16,
|
||||||
}
|
}
|
||||||
zombie_horse.harmed_by_heal = true
|
zombie_horse.harmed_by_heal = true
|
||||||
mobs:register_mob("mobs_mc:zombie_horse", zombie_horse)
|
mcl_mobs:register_mob("mobs_mc:zombie_horse", zombie_horse)
|
||||||
|
|
||||||
-- Donkey
|
-- Donkey
|
||||||
local d = 0.86 -- donkey scale
|
local d = 0.86 -- donkey scale
|
||||||
|
@ -515,7 +514,7 @@ donkey.collisionbox = {
|
||||||
donkey.jump = true
|
donkey.jump = true
|
||||||
donkey.jump_height = 3.75 -- can clear 1 block height
|
donkey.jump_height = 3.75 -- can clear 1 block height
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:donkey", donkey)
|
mcl_mobs:register_mob("mobs_mc:donkey", donkey)
|
||||||
|
|
||||||
-- Mule
|
-- Mule
|
||||||
local m = 0.94
|
local m = 0.94
|
||||||
|
@ -533,95 +532,59 @@ mule.collisionbox = {
|
||||||
horse.collisionbox[5] * m,
|
horse.collisionbox[5] * m,
|
||||||
horse.collisionbox[6] * m,
|
horse.collisionbox[6] * m,
|
||||||
}
|
}
|
||||||
mobs:register_mob("mobs_mc:mule", mule)
|
mcl_mobs:register_mob("mobs_mc:mule", mule)
|
||||||
|
|
||||||
--===========================
|
--===========================
|
||||||
--Spawn Function
|
--Spawn Function
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:horse",
|
"mobs_mc:horse",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"FlowerForest_beach",
|
"flat",
|
||||||
"Forest_beach",
|
"Plains",
|
||||||
"StoneBeach",
|
"Plains_beach",
|
||||||
"ColdTaiga_beach_water",
|
"SunflowerPlains",
|
||||||
"Taiga_beach",
|
"Savanna",
|
||||||
|
"Savanna_beach",
|
||||||
|
"SavannaM",
|
||||||
"Savanna_beach",
|
"Savanna_beach",
|
||||||
"Plains_beach",
|
"Plains_beach",
|
||||||
"ExtremeHills_beach",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"Swampland_shore",
|
|
||||||
"JungleM_shore",
|
|
||||||
"Jungle_shore",
|
|
||||||
"MesaPlateauFM_sandlevel",
|
|
||||||
"MesaPlateauF_sandlevel",
|
|
||||||
"MesaBryce_sandlevel",
|
|
||||||
"Mesa_sandlevel",
|
|
||||||
"Mesa",
|
|
||||||
"FlowerForest",
|
|
||||||
"Swampland",
|
|
||||||
"Taiga",
|
|
||||||
"ExtremeHills",
|
|
||||||
"Jungle",
|
|
||||||
"Savanna",
|
|
||||||
"BirchForest",
|
|
||||||
"MegaSpruceTaiga",
|
|
||||||
"MegaTaiga",
|
|
||||||
"ExtremeHills+",
|
|
||||||
"Forest",
|
|
||||||
"Plains",
|
|
||||||
"Desert",
|
|
||||||
"ColdTaiga",
|
|
||||||
"IcePlainsSpikes",
|
|
||||||
"SunflowerPlains",
|
|
||||||
"IcePlains",
|
|
||||||
"RoofedForest",
|
|
||||||
"ExtremeHills+_snowtop",
|
|
||||||
"MesaPlateauFM_grasstop",
|
|
||||||
"JungleEdgeM",
|
|
||||||
"ExtremeHillsM",
|
|
||||||
"JungleM",
|
|
||||||
"BirchForestM",
|
|
||||||
"MesaPlateauF",
|
|
||||||
"MesaPlateauFM",
|
|
||||||
"MesaPlateauF_grasstop",
|
|
||||||
"MesaBryce",
|
|
||||||
"JungleEdge",
|
|
||||||
"SavannaM",
|
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
15000,
|
||||||
4,
|
4,
|
||||||
mobs_mc.spawn_height.water+3,
|
mobs_mc.water_level+3,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
|
mcl_mobs:spawn_specific(
|
||||||
mobs:spawn_specific(
|
|
||||||
"mobs_mc:donkey",
|
"mobs_mc:donkey",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Mesa",
|
"flat",
|
||||||
"MesaPlateauFM_grasstop",
|
"Plains",
|
||||||
"MesaPlateauF",
|
"Plains_beach",
|
||||||
"MesaPlateauFM",
|
"SunflowerPlains",
|
||||||
"MesaPlateauF_grasstop",
|
"Savanna",
|
||||||
"MesaBryce",
|
"Savanna_beach",
|
||||||
|
"SavannaM",
|
||||||
|
"Savanna_beach",
|
||||||
|
"Plains_beach",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
15000,
|
||||||
4,
|
4,
|
||||||
mobs_mc.spawn_height.water+3,
|
mobs_mc.water_level+3,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
|
mcl_mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
|
||||||
mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
|
mcl_mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
|
||||||
--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
|
--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
|
||||||
mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
|
mcl_mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
|
||||||
mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)
|
mcl_mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)
|
||||||
|
|
|
@ -2,45 +2,100 @@
|
||||||
--maikerumine
|
--maikerumine
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
mobs_mc = {}
|
||||||
|
|
||||||
local path = minetest.get_modpath(minetest.get_current_modname())
|
local pr = PseudoRandom(os.time()*5)
|
||||||
|
|
||||||
if not minetest.get_modpath("mobs_mc_gameconfig") then
|
local offsets = {}
|
||||||
mobs_mc = {}
|
for x=-2, 2 do
|
||||||
|
for z=-2, 2 do
|
||||||
|
table.insert(offsets, {x=x, y=0, z=z})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- For utility functions
|
--[[ Periodically check and teleport mob to owner if not sitting (order ~= "sit") and
|
||||||
mobs_mc.tools = {}
|
the owner is too far away. To be used with do_custom. Note: Optimized for mobs smaller than 1×1×1.
|
||||||
|
Larger mobs might have space problems after teleportation.
|
||||||
|
|
||||||
-- This function checks if the item ID has been overwritten and returns true if it is unchanged
|
* dist: Minimum required distance from owner to teleport. Default: 12
|
||||||
if minetest.get_modpath("mobs_mc_gameconfig") and mobs_mc.override and mobs_mc.override.items then
|
* teleport_check_interval: Optional. Interval in seconds to check the mob teleportation. Default: 4 ]]
|
||||||
mobs_mc.is_item_variable_overridden = function(id)
|
mobs_mc.make_owner_teleport_function = function(dist, teleport_check_interval)
|
||||||
return mobs_mc.override.items[id] == nil
|
return function(self, dtime)
|
||||||
|
-- No teleportation if no owner or if sitting
|
||||||
|
if not self.owner or self.order == "sit" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if not teleport_check_interval then
|
||||||
|
teleport_check_interval = 4
|
||||||
|
end
|
||||||
|
if not dist then
|
||||||
|
dist = 12
|
||||||
|
end
|
||||||
|
if self._teleport_timer == nil then
|
||||||
|
self._teleport_timer = teleport_check_interval
|
||||||
|
return
|
||||||
|
end
|
||||||
|
self._teleport_timer = self._teleport_timer - dtime
|
||||||
|
if self._teleport_timer <= 0 then
|
||||||
|
self._teleport_timer = teleport_check_interval
|
||||||
|
local mob_pos = self.object:get_pos()
|
||||||
|
local owner = minetest.get_player_by_name(self.owner)
|
||||||
|
if not owner then
|
||||||
|
-- No owner found, no teleportation
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local owner_pos = owner:get_pos()
|
||||||
|
local dist_from_owner = vector.distance(owner_pos, mob_pos)
|
||||||
|
if dist_from_owner > dist then
|
||||||
|
-- Check for nodes below air in a 5×1×5 area around the owner position
|
||||||
|
local check_offsets = table.copy(offsets)
|
||||||
|
-- Attempt to place mob near player. Must be placed on walkable node below a non-walkable one. Place inside that air node.
|
||||||
|
while #check_offsets > 0 do
|
||||||
|
local r = pr:next(1, #check_offsets)
|
||||||
|
local telepos = vector.add(owner_pos, check_offsets[r])
|
||||||
|
local telepos_below = {x=telepos.x, y=telepos.y-1, z=telepos.z}
|
||||||
|
table.remove(check_offsets, r)
|
||||||
|
-- Long story short, spawn on a platform
|
||||||
|
local trynode = minetest.registered_nodes[minetest.get_node(telepos).name]
|
||||||
|
local trybelownode = minetest.registered_nodes[minetest.get_node(telepos_below).name]
|
||||||
|
if trynode and not trynode.walkable and
|
||||||
|
trybelownode and trybelownode.walkable then
|
||||||
|
-- Correct position found! Let's teleport.
|
||||||
|
self.object:set_pos(telepos)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
end
|
||||||
-- No items are overwritten, so always return true
|
|
||||||
mobs_mc.is_item_variable_overridden = function(id)
|
local function is_forbidden_node(pos, node)
|
||||||
|
node = node or minetest.get_node(pos)
|
||||||
|
return minetest.get_item_group(node.name, "stair") > 0 or minetest.get_item_group(node.name, "slab") > 0 or minetest.get_item_group(node.name, "carpet") > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_mobs:spawn_abm_check(pos, node, name)
|
||||||
|
-- Don't spawn monsters on mycelium
|
||||||
|
if (node.name == "mcl_core:mycelium" or node.name == "mcl_core:mycelium_snow") and minetest.registered_entities[name].type == "monster" then
|
||||||
return true
|
return true
|
||||||
|
--Don't Spawn mobs on stairs, slabs, or carpets
|
||||||
|
elseif is_forbidden_node(pos, node) or is_forbidden_node(vector.add(pos, vector.new(0, 1, 0))) then
|
||||||
|
return true
|
||||||
|
-- Spawn on opaque or liquid nodes
|
||||||
|
elseif minetest.get_item_group(node.name, "opaque") ~= 0 or minetest.registered_nodes[node.name].liquidtype ~= "none" or node.name == "mcl_core:grass_path" then
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Reject everything else
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--MOB ITEMS SELECTOR SWITCH
|
mobs_mc.shears_wear = 276
|
||||||
dofile(path .. "/0_gameconfig.lua")
|
mobs_mc.water_level = tonumber(minetest.settings:get("water_level")) or 0
|
||||||
--Items
|
|
||||||
dofile(path .. "/1_items_default.lua")
|
|
||||||
|
|
||||||
-- Bow, arrow and throwables
|
|
||||||
dofile(path .. "/2_throwing.lua")
|
|
||||||
|
|
||||||
-- Shared functions
|
|
||||||
dofile(path .. "/3_shared.lua")
|
|
||||||
|
|
||||||
--Mob heads
|
|
||||||
dofile(path .. "/4_heads.lua")
|
|
||||||
|
|
||||||
dofile(path .. "/5_spawn_abm_check.lua")
|
|
||||||
|
|
||||||
-- Animals
|
-- Animals
|
||||||
|
local path = minetest.get_modpath("mobs_mc")
|
||||||
dofile(path .. "/bat.lua") -- Mesh and animation by toby109tt / https://github.com/22i
|
dofile(path .. "/bat.lua") -- Mesh and animation by toby109tt / https://github.com/22i
|
||||||
dofile(path .. "/rabbit.lua") -- Mesh and animation byExeterDad
|
dofile(path .. "/rabbit.lua") -- Mesh and animation byExeterDad
|
||||||
dofile(path .. "/chicken.lua") -- Mesh and animation by Pavel_S
|
dofile(path .. "/chicken.lua") -- Mesh and animation by Pavel_S
|
||||||
|
@ -57,8 +112,6 @@ dofile(path .. "/squid.lua") -- Animation, sound and egg texture by daufinsyd
|
||||||
|
|
||||||
-- NPCs
|
-- NPCs
|
||||||
dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i
|
dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i
|
||||||
-- Agent texture missing
|
|
||||||
--dofile(path .. "/agent.lua") -- Mesh and animation by toby109tt / https://github.com/22i
|
|
||||||
|
|
||||||
-- Illagers and witch
|
-- Illagers and witch
|
||||||
dofile(path .. "/pillager.lua") -- Mesh by KrupnoPavel and MrRar, animation by MrRar
|
dofile(path .. "/pillager.lua") -- Mesh by KrupnoPavel and MrRar, animation by MrRar
|
||||||
|
@ -90,12 +143,3 @@ dofile(path .. "/slime+magma_cube.lua") -- Wuzzy
|
||||||
dofile(path .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture)
|
dofile(path .. "/spider.lua") -- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture)
|
||||||
dofile(path .. "/vex.lua") -- KrupnoPavel
|
dofile(path .. "/vex.lua") -- KrupnoPavel
|
||||||
dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i
|
dofile(path .. "/wither.lua") -- Mesh and animation by toby109tt / https://github.com/22i
|
||||||
--NOTES:
|
|
||||||
--
|
|
||||||
--[[
|
|
||||||
COLISIONBOX in minetest press f5 to see where you are looking at then put these wool collor nodes on the ground in direction of north/east/west... to make colisionbox editing easier
|
|
||||||
#1west-pink/#2down/#3south-blue/#4east-red/#5up/#6north-yelow
|
|
||||||
{-1, -0.5, -1, 1, 3, 1}, Right, Bottom, Back, Left, Top, Front
|
|
||||||
--]]
|
|
||||||
--
|
|
||||||
--
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### LLAMA
|
--################### LLAMA
|
||||||
|
@ -24,19 +24,10 @@ local carpets = {
|
||||||
unicolor_light_blue = { "mcl_wool:light_blue_carpet", "light_blue" },
|
unicolor_light_blue = { "mcl_wool:light_blue_carpet", "light_blue" },
|
||||||
}
|
}
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:llama", {
|
mcl_mobs:register_mob("mobs_mc:llama", {
|
||||||
description = S("Llama"),
|
description = S("Llama"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
rotate = 270,
|
|
||||||
neutral = true,
|
|
||||||
group_attack = true,
|
|
||||||
attack_type = "projectile",
|
|
||||||
shoot_arrow = function(self, pos, dir)
|
|
||||||
-- 2-4 damage per arrow
|
|
||||||
local dmg = 1
|
|
||||||
mobs.shoot_projectile_handling("mobs_mc:spit", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
|
|
||||||
end,
|
|
||||||
hp_min = 15,
|
hp_min = 15,
|
||||||
hp_max = 30,
|
hp_max = 30,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
|
@ -51,7 +42,6 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
{"blank.png", "blank.png", "mobs_mc_llama_gray.png"},
|
{"blank.png", "blank.png", "mobs_mc_llama_gray.png"},
|
||||||
{"blank.png", "blank.png", "mobs_mc_llama_white.png"},
|
{"blank.png", "blank.png", "mobs_mc_llama_white.png"},
|
||||||
{"blank.png", "blank.png", "mobs_mc_llama.png"},
|
{"blank.png", "blank.png", "mobs_mc_llama.png"},
|
||||||
-- TODO: Add llama carpet textures (Pixel Perfection seems to use verbatim copy from Minecraft :-( )
|
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
|
@ -59,13 +49,9 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 4.4,
|
run_velocity = 4.4,
|
||||||
follow_velocity = 4.4,
|
follow_velocity = 4.4,
|
||||||
breed_distance = 1.5,
|
|
||||||
baby_size = 0.5,
|
|
||||||
follow_distance = 2,
|
|
||||||
floats = 1,
|
floats = 1,
|
||||||
reach = 6,
|
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.leather,
|
{name = "mcl_mobitems:leather",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
|
@ -96,7 +82,7 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
look_start = 78,
|
look_start = 78,
|
||||||
look_end = 108,
|
look_end = 108,
|
||||||
},
|
},
|
||||||
follow = mobs_mc.items.hay_bale,
|
follow = { "mcl_farming:wheat_item", "mcl_farming:hay_block" },
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
|
||||||
|
@ -115,7 +101,7 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
-- if driver present allow control of llama
|
-- if driver present allow control of llama
|
||||||
if self.driver then
|
if self.driver then
|
||||||
|
|
||||||
mobs.drive(self, "walk", "stand", false, dtime)
|
mcl_mobs.drive(self, "walk", "stand", false, dtime)
|
||||||
|
|
||||||
return false -- skip rest of mob functions
|
return false -- skip rest of mob functions
|
||||||
end
|
end
|
||||||
|
@ -127,7 +113,7 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
|
|
||||||
-- detach from llama properly
|
-- detach from llama properly
|
||||||
if self.driver then
|
if self.driver then
|
||||||
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
||||||
end
|
end
|
||||||
|
|
||||||
end,
|
end,
|
||||||
|
@ -139,111 +125,68 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
--owner is broken for this
|
local item = clicker:get_wielded_item()
|
||||||
--we'll make the owner this guy
|
if item:get_name() == "mcl_farming:hay_block" then
|
||||||
--attempt to enter breed state
|
-- Breed with hay bale
|
||||||
if mobs.enter_breed_state(self,clicker) then
|
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
|
||||||
self.tamed = true
|
else
|
||||||
self.owner = clicker:get_player_name()
|
-- Feed with anything else
|
||||||
return
|
if mcl_mobs:feed_tame(self, clicker, 1, false, true) then return end
|
||||||
end
|
end
|
||||||
|
if mcl_mobs:protect(self, clicker) then return end
|
||||||
--ignore other logic
|
|
||||||
--make baby grow faster
|
|
||||||
if self.baby then
|
|
||||||
mobs.make_baby_grow_faster(self,clicker)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Make sure tamed llama is mature and being clicked by owner only
|
-- Make sure tamed llama is mature and being clicked by owner only
|
||||||
if self.tamed and not self.child and self.owner == clicker:get_player_name() then
|
if self.tamed and not self.child and self.owner == clicker:get_player_name() then
|
||||||
|
|
||||||
local item = clicker:get_wielded_item()
|
-- Place carpet
|
||||||
--safety catch
|
if minetest.get_item_group(item:get_name(), "carpet") == 1 and not self.carpet then
|
||||||
if not item then
|
for group, carpetdata in pairs(carpets) do
|
||||||
return
|
if minetest.get_item_group(item:get_name(), group) == 1 then
|
||||||
end
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
|
item:take_item()
|
||||||
|
clicker:set_wielded_item(item)
|
||||||
|
|
||||||
--put chest on carpeted llama
|
|
||||||
if self.carpet and not self.chest and item:get_name() == "mcl_chests:chest" then
|
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
|
||||||
item:take_item()
|
|
||||||
clicker:set_wielded_item(item)
|
|
||||||
end
|
|
||||||
|
|
||||||
self.base_texture = table.copy(self.base_texture)
|
|
||||||
self.base_texture[1] = "mobs_mc_llama_chest.png"
|
|
||||||
self.object:set_properties({
|
|
||||||
textures = self.base_texture,
|
|
||||||
})
|
|
||||||
self.chest = true
|
|
||||||
|
|
||||||
return --don't attempt to ride
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Place carpet
|
|
||||||
--TODO: Re-enable this code when carpet textures arrived.
|
|
||||||
if minetest.get_item_group(item:get_name(), "carpet") == 1 then
|
|
||||||
|
|
||||||
for group, carpetdata in pairs(carpets) do
|
|
||||||
if minetest.get_item_group(item:get_name(), group) == 1 then
|
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
|
||||||
item:take_item()
|
|
||||||
clicker:set_wielded_item(item)
|
|
||||||
|
|
||||||
--shoot off old carpet
|
|
||||||
if self.carpet then
|
|
||||||
minetest.add_item(self.object:get_pos(), self.carpet)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local substr = carpetdata[2]
|
|
||||||
local tex_carpet = "mobs_mc_llama_decor_"..substr..".png"
|
|
||||||
|
|
||||||
self.base_texture = table.copy(self.base_texture)
|
|
||||||
self.base_texture[2] = tex_carpet
|
|
||||||
self.object:set_properties({
|
|
||||||
textures = self.base_texture,
|
|
||||||
})
|
|
||||||
self.carpet = item:get_name()
|
|
||||||
self.drops = {
|
|
||||||
{name = mobs_mc.items.leather,
|
|
||||||
chance = 1,
|
|
||||||
min = 0,
|
|
||||||
max = 2,},
|
|
||||||
{name = item:get_name(),
|
|
||||||
chance = 1,
|
|
||||||
min = 1,
|
|
||||||
max = 1,},
|
|
||||||
}
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
local substr = carpetdata[2]
|
||||||
|
local tex_carpet = "mobs_mc_llama_decor_"..substr..".png"
|
||||||
|
self.base_texture = table.copy(self.base_texture)
|
||||||
|
self.base_texture[2] = tex_carpet
|
||||||
|
self.object:set_properties({
|
||||||
|
textures = self.base_texture,
|
||||||
|
})
|
||||||
|
self.carpet = item:get_name()
|
||||||
|
self.drops = {
|
||||||
|
{name = "mcl_mobitems:leather",
|
||||||
|
chance = 1,
|
||||||
|
min = 0,
|
||||||
|
max = 2,},
|
||||||
|
{name = item:get_name(),
|
||||||
|
chance = 1,
|
||||||
|
min = 1,
|
||||||
|
max = 1,},
|
||||||
|
}
|
||||||
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if self.carpet then
|
-- detatch player already riding llama
|
||||||
-- detatch player already riding llama
|
if self.driver and clicker == self.driver then
|
||||||
if self.driver and clicker == self.driver then
|
|
||||||
|
|
||||||
mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
mcl_mobs.detach(clicker, {x = 1, y = 0, z = 1})
|
||||||
|
|
||||||
-- attach player to llama
|
-- attach player to llama
|
||||||
elseif not self.driver then
|
elseif not self.driver then
|
||||||
|
|
||||||
self.object:set_properties({stepheight = 1.1})
|
self.object:set_properties({stepheight = 1.1})
|
||||||
mobs.attach(self, clicker)
|
mcl_mobs.attach(self, clicker)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
||||||
|
-- Used to capture llama
|
||||||
|
elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then
|
||||||
|
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
--[[
|
|
||||||
TODO: Enable this code when carpet textures arrived.
|
|
||||||
on_breed = function(parent1, parent2)
|
on_breed = function(parent1, parent2)
|
||||||
-- When breeding, make sure the child has no carpet
|
-- When breeding, make sure the child has no carpet
|
||||||
local pos = parent1.object:get_pos()
|
local pos = parent1.object:get_pos()
|
||||||
|
@ -253,7 +196,7 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
else
|
else
|
||||||
parent = parent2
|
parent = parent2
|
||||||
end
|
end
|
||||||
child = mobs:spawn_child(pos, parent.name)
|
child = mcl_mobs:spawn_child(pos, parent.name)
|
||||||
if child then
|
if child then
|
||||||
local ent_c = child:get_luaentity()
|
local ent_c = child:get_luaentity()
|
||||||
ent_c.base_texture = table.copy(ent_c.base_texture)
|
ent_c.base_texture = table.copy(ent_c.base_texture)
|
||||||
|
@ -265,65 +208,35 @@ mobs:register_mob("mobs_mc:llama", {
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
]]
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
--spawn
|
--spawn
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:llama",
|
"mobs_mc:llama",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Mesa",
|
"Mesa",
|
||||||
"MesaPlateauFM_grasstop",
|
"MesaPlateauFM_grasstop",
|
||||||
"MesaPlateauF",
|
"MesaPlateauF",
|
||||||
"MesaPlateauFM",
|
"MesaPlateauFM",
|
||||||
"MesaPlateauF_grasstop",
|
"MesaPlateauF_grasstop",
|
||||||
"MesaBryce",
|
"MesaBryce",
|
||||||
|
"Jungle",
|
||||||
|
"Jungle_shore",
|
||||||
|
"JungleM",
|
||||||
|
"JungleM_shore",
|
||||||
|
"JungleEdge",
|
||||||
|
"JungleEdgeM",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
15000,
|
||||||
5,
|
5,
|
||||||
mobs_mc.spawn_height.water+15,
|
mobs_mc.water_level+15,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0)
|
mcl_mobs:register_egg("mobs_mc:llama", S("Llama"), "mobs_mc_spawn_icon_llama.png", 0)
|
||||||
|
|
||||||
|
|
||||||
-- llama spit
|
|
||||||
mobs:register_arrow("mobs_mc:spit", {
|
|
||||||
visual = "sprite",
|
|
||||||
visual_size = {x = 0.3, y = 0.3},
|
|
||||||
textures = {"mobs_mc_spit.png"},
|
|
||||||
velocity = 1,
|
|
||||||
speed = 1,
|
|
||||||
tail = 1,
|
|
||||||
tail_texture = "mobs_mc_spit.png",
|
|
||||||
tail_size = 2,
|
|
||||||
tail_distance_divider = 4,
|
|
||||||
|
|
||||||
hit_player = function(self, player)
|
|
||||||
--[[if rawget(_G, "armor") and armor.last_damage_types then
|
|
||||||
armor.last_damage_types[player:get_player_name()] = "spit"
|
|
||||||
end]]
|
|
||||||
player:punch(self.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {fleshy = self._damage},
|
|
||||||
}, nil)
|
|
||||||
end,
|
|
||||||
|
|
||||||
hit_mob = function(self, mob)
|
|
||||||
mob:punch(self.object, 1.0, {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {fleshy = self._damage},
|
|
||||||
}, nil)
|
|
||||||
end,
|
|
||||||
|
|
||||||
hit_node = function(self, pos, node)
|
|
||||||
--does nothing
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
# textdomain: mobs_mc
|
# textdomain: mobs_mc
|
||||||
Totem of Undying=Totem der Unsterblichkeit
|
|
||||||
A totem of undying is a rare artifact which may safe you from certain death.=Ein Totem der Unsterblichkeit ist ein seltenes Artefakt, dass Sie vor dem sicheren Tod bewahren kann.
|
|
||||||
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Der Totem funktioniert nur, während Sie ihn halten. Wenn Sie normalerweise tödlich hohen Schaden erhalten, werden Sie vor dem Tod bewahrt und Sie erhalten eine zweite Chance mit 1 TP. Der Totem wird dabei zerstört.
|
|
||||||
Agent=Akteur
|
Agent=Akteur
|
||||||
Bat=Fledermaus
|
Bat=Fledermaus
|
||||||
Blaze=Lohe
|
Blaze=Lohe
|
||||||
|
@ -28,7 +25,6 @@ Pig=Schwein
|
||||||
Polar Bear=Eisbär
|
Polar Bear=Eisbär
|
||||||
Rabbit=Kaninchen
|
Rabbit=Kaninchen
|
||||||
Killer Bunny=Killerkaninchen
|
Killer Bunny=Killerkaninchen
|
||||||
The Killer Bunny=Das Killerkaninchen
|
|
||||||
Sheep=Schaf
|
Sheep=Schaf
|
||||||
Shulker=Shulker
|
Shulker=Shulker
|
||||||
Silverfish=Silberfischchen
|
Silverfish=Silberfischchen
|
||||||
|
@ -53,13 +49,6 @@ Wolf=Wolf
|
||||||
Husk=Wüstenzombie
|
Husk=Wüstenzombie
|
||||||
Zombie=Zombie
|
Zombie=Zombie
|
||||||
Zombie Pigman=Schweinezombie
|
Zombie Pigman=Schweinezombie
|
||||||
Iron Horse Armor=Eisenpferderüstung
|
|
||||||
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Eine Eisenpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden etwas zu erhöhen.
|
|
||||||
Golden Horse Armor=Goldpferderüstung
|
|
||||||
Golden horse armor can be worn by horses to increase their protection from harm.=Eine Goldpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden zu erhöhen.
|
|
||||||
Diamond Horse Armor=Diamantpferderüstung
|
|
||||||
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Eine Diamantpferderüstung kann von Pferden getragen werden, um ihren Schutz vor Schaden beträchtlich zu erhöhen.
|
|
||||||
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Platzieren Sie es auf einem Pferd, um die Pferderüstung aufzusetzen. Esel und Maultiere können keine Pferderüstung tragen.
|
|
||||||
Farmer=Bauer
|
Farmer=Bauer
|
||||||
Fisherman=Fischer
|
Fisherman=Fischer
|
||||||
Fletcher=Pfeilmacher
|
Fletcher=Pfeilmacher
|
||||||
|
@ -73,4 +62,3 @@ Weapon Smith=Waffenschmied
|
||||||
Tool Smith=Werkzeugschmied
|
Tool Smith=Werkzeugschmied
|
||||||
Cleric=Priester
|
Cleric=Priester
|
||||||
Nitwit=Dorftrottel
|
Nitwit=Dorftrottel
|
||||||
Protects you from death while wielding it=Schützt vor dem Tod, wenn es gehalten wird
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
# textdomain: mobs_mc
|
# textdomain: mobs_mc
|
||||||
Totem of Undying=Tótem de la inmortalidad
|
|
||||||
A totem of undying is a rare artifact which may safe you from certain death.=Un tótem de la inmortalidad es un artefacto raro que puede salvarte de una muerte segura.
|
|
||||||
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=El tótem solo funciona mientras lo sostienes en tu mano. Si recibes un daño crítico, no mueres y obtienes una segunda oportunidad con 1 HP. Sin embargo, el tótem se destruye en el proceso.
|
|
||||||
Agent=Agente
|
Agent=Agente
|
||||||
Bat=Murciélago
|
Bat=Murciélago
|
||||||
Blaze=Blaze
|
Blaze=Blaze
|
||||||
|
@ -28,7 +25,6 @@ Pig=Cerdo
|
||||||
Polar Bear=Oso polar
|
Polar Bear=Oso polar
|
||||||
Rabbit=Conejo
|
Rabbit=Conejo
|
||||||
Killer Bunny=Conejo asesino
|
Killer Bunny=Conejo asesino
|
||||||
The Killer Bunny=El Conejo asesino
|
|
||||||
Sheep=Oveja
|
Sheep=Oveja
|
||||||
Shulker=Shulker
|
Shulker=Shulker
|
||||||
Silverfish=Lepisma
|
Silverfish=Lepisma
|
||||||
|
@ -53,13 +49,6 @@ Wolf=Lobo
|
||||||
Husk=Husk
|
Husk=Husk
|
||||||
Zombie=Zombie
|
Zombie=Zombie
|
||||||
Zombie Pigman=Cerdo Zombie
|
Zombie Pigman=Cerdo Zombie
|
||||||
Iron Horse Armor=Armadura de hierro para caballo
|
|
||||||
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Los caballos pueden usar armadura de caballo de hierro para aumentar un poco su protección contra el daño.
|
|
||||||
Golden Horse Armor=Armadura de oro para caballo
|
|
||||||
Golden horse armor can be worn by horses to increase their protection from harm.=Los caballos pueden usar armadura de caballo de oro para aumentar su protección contra el daño.
|
|
||||||
Diamond Horse Armor=Armadura de diamante para caballo
|
|
||||||
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Los caballos pueden usar armadura de caballo de diamante para aumentar en gran medida su protección contra el daño.
|
|
||||||
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Colóquelo en un caballo para ponerle la armadura de caballo. Los burros y las mulas no pueden usar armadura de caballo.
|
|
||||||
Farmer=Granjero
|
Farmer=Granjero
|
||||||
Fisherman=Pescador
|
Fisherman=Pescador
|
||||||
Fletcher=Flechador
|
Fletcher=Flechador
|
||||||
|
|
|
@ -1,75 +0,0 @@
|
||||||
# textdomain: mobs_mc
|
|
||||||
Totem of Undying=Token nieśmiertelności
|
|
||||||
A totem of undying is a rare artifact which may safe you from certain death.=Totem nieśmiertelności to rzadki artefakt, który może uchronić cię przed pewną śmiercią.
|
|
||||||
The totem only works while you hold it in your hand. If you receive fatal damage, you are saved from death and you get a second chance with 1 HP. The totem is destroyed in the process, however.=Totem działa tylko kiedy trzymasz go w dłoni. Jeśli otrzymasz obrażenia od upadku zostaniesz oszczędzony i pozostanie ci 1 HP, jednak totem zostanie wtedy zniszczony.
|
|
||||||
Agent=Agent
|
|
||||||
Bat=Nietoperz
|
|
||||||
Blaze=Płomyk
|
|
||||||
Chicken=Kurczak
|
|
||||||
Cow=Krowa
|
|
||||||
Mooshroom=Muuuchomor
|
|
||||||
Creeper=Creeper
|
|
||||||
Ender Dragon=Smok kresu
|
|
||||||
Enderman=Enderman
|
|
||||||
Endermite=Endermit
|
|
||||||
Ghast=Ghast
|
|
||||||
Elder Guardian=Prastrażnik
|
|
||||||
Guardian=Strażnik
|
|
||||||
Horse=Koń
|
|
||||||
Skeleton Horse=Koń szkielet
|
|
||||||
Zombie Horse=Koń zombie
|
|
||||||
Donkey=Osioł
|
|
||||||
Mule=Muł
|
|
||||||
Iron Golem=Żelazny golem
|
|
||||||
Llama=Lama
|
|
||||||
Ocelot=Ocelot
|
|
||||||
Parrot=Papuga
|
|
||||||
Pig=Świnia
|
|
||||||
Polar Bear=Niedźwiedź polarny
|
|
||||||
Rabbit=Królik
|
|
||||||
Killer Bunny=Królik zabójca
|
|
||||||
Sheep=Owca
|
|
||||||
Shulker=Shulker
|
|
||||||
Silverfish=Rybik cukrowy
|
|
||||||
Skeleton=Szkielet
|
|
||||||
Stray=Tułacz
|
|
||||||
Wither Skeleton=Witherowy szkielet
|
|
||||||
Magma Cube=Kostka magmy
|
|
||||||
Slime=Szlam
|
|
||||||
Snow Golem=Śnieżny golem
|
|
||||||
Spider=Pająk
|
|
||||||
Cave Spider=Pająk jaskiniowy
|
|
||||||
Squid=Kałamarnica
|
|
||||||
Vex=Dręczyciel
|
|
||||||
Evoker=Przywoływacz
|
|
||||||
Illusioner=Iluzjonista
|
|
||||||
Villager=Osadnik
|
|
||||||
Vindicator=Obrońca
|
|
||||||
Zombie Villager=Osadnik zombie
|
|
||||||
Witch=Wiedźma
|
|
||||||
Wither=Wither
|
|
||||||
Wolf=Wilk
|
|
||||||
Husk=Posuch
|
|
||||||
Zombie=Zombie
|
|
||||||
Zombie Pigman=Świniak zombie
|
|
||||||
Iron Horse Armor=Żelazna zbroja dla konia
|
|
||||||
Iron horse armor can be worn by horses to increase their protection from harm a bit.=Żelazna zbroja dla konia może być noszona przez konie aby nieco zwiększyć ich odporność na obrażenia.
|
|
||||||
Golden Horse Armor=Złota zbroja dla konia
|
|
||||||
Golden horse armor can be worn by horses to increase their protection from harm.=Złota zbroja dla konia może być noszona przez konie aby zwiększyć ich odporność na obrażenia.
|
|
||||||
Diamond Horse Armor=Diamentowa zbroja dla konia
|
|
||||||
Diamond horse armor can be worn by horses to greatly increase their protection from harm.=Diamentowa zbroja dla konia może być noszona przez konie aby istotnie zwiększyć ich odporność na obrażenia.
|
|
||||||
Place it on a horse to put on the horse armor. Donkeys and mules can't wear horse armor.=Połóż ją na koniu aby założyć zbroję dla konia. Osły i muły nie mogą nosić zbroi dla konia.
|
|
||||||
Farmer=Rolnik
|
|
||||||
Fisherman=Rybak
|
|
||||||
Fletcher=Łuczarz
|
|
||||||
Shepherd=Pasterz
|
|
||||||
Librarian=Bibliotekarz
|
|
||||||
Cartographer=Kartograf
|
|
||||||
Armorer=Płatnerz
|
|
||||||
Leatherworker=Rymarz
|
|
||||||
Butcher=Rzeźnik
|
|
||||||
Weapon Smith=Zbrojmistrz
|
|
||||||
Tool Smith=Narzędziarz
|
|
||||||
Cleric=Kapłan
|
|
||||||
Nitwit=Głupiec
|
|
||||||
Protects you from death while wielding it=Chroni przed śmiercią gdy go trzymasz
|
|
|
@ -1,6 +1,6 @@
|
||||||
name = mobs_mc
|
name = mobs_mc
|
||||||
author = maikerumine
|
author = maikerumine
|
||||||
description = Adds Minecraft-like monsters and animals.
|
description = Adds Minecraft-like monsters and animals.
|
||||||
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip
|
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip, mcl_core
|
||||||
optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items
|
optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items
|
||||||
|
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Ghast fixed by epCode - Thanks!
|
|
Binary file not shown.
Binary file not shown.
|
@ -3,7 +3,7 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### OCELOT AND CAT
|
--################### OCELOT AND CAT
|
||||||
|
@ -13,16 +13,15 @@ local pr = PseudoRandom(os.time()*12)
|
||||||
|
|
||||||
local default_walk_chance = 70
|
local default_walk_chance = 70
|
||||||
|
|
||||||
-- Returns true if the item is food (taming) for the cat/ocelot
|
local follow = {
|
||||||
local is_food = function(itemstring)
|
"mcl_fishing:fish_raw",
|
||||||
for f=1, #mobs_mc.follow.ocelot do
|
"mcl_fishing:salmon_raw",
|
||||||
if itemstring == mobs_mc.follow.ocelot[f] then
|
"mcl_fishing:clownfish_raw",
|
||||||
return true
|
"mcl_fishing:pufferfish_raw",
|
||||||
elseif string.sub(itemstring, 1, 6) == "group:" and minetest.get_item_group(itemstring, string.sub(itemstring, 7, -1)) ~= 0 then
|
}
|
||||||
return true
|
|
||||||
end
|
local function is_food(itemstring)
|
||||||
end
|
return table.indexof(follow, itemstring) ~= -1
|
||||||
return false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Ocelot
|
-- Ocelot
|
||||||
|
@ -31,8 +30,6 @@ local ocelot = {
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
can_despawn = true,
|
can_despawn = true,
|
||||||
rotate = 270,
|
|
||||||
skittish = true,
|
|
||||||
hp_min = 10,
|
hp_min = 10,
|
||||||
hp_max = 10,
|
hp_max = 10,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
|
@ -45,7 +42,7 @@ local ocelot = {
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_chance = default_walk_chance,
|
walk_chance = default_walk_chance,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 10,
|
run_velocity = 3,
|
||||||
follow_velocity = 1,
|
follow_velocity = 1,
|
||||||
floats = 1,
|
floats = 1,
|
||||||
runaway = true,
|
runaway = true,
|
||||||
|
@ -59,7 +56,7 @@ local ocelot = {
|
||||||
},
|
},
|
||||||
animation = {
|
animation = {
|
||||||
speed_normal = 25,
|
speed_normal = 25,
|
||||||
run_speed = 150,
|
run_speed = 50,
|
||||||
stand_start = 0,
|
stand_start = 0,
|
||||||
stand_end = 0,
|
stand_end = 0,
|
||||||
walk_start = 0,
|
walk_start = 0,
|
||||||
|
@ -67,7 +64,7 @@ local ocelot = {
|
||||||
run_start = 0,
|
run_start = 0,
|
||||||
run_end = 40,
|
run_end = 40,
|
||||||
},
|
},
|
||||||
follow = mobs_mc.follow.ocelot,
|
follow = follow,
|
||||||
view_range = 12,
|
view_range = 12,
|
||||||
passive = true,
|
passive = true,
|
||||||
attack_type = "dogfight",
|
attack_type = "dogfight",
|
||||||
|
@ -101,7 +98,7 @@ local ocelot = {
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:ocelot", ocelot)
|
mcl_mobs:register_mob("mobs_mc:ocelot", ocelot)
|
||||||
|
|
||||||
-- Cat
|
-- Cat
|
||||||
local cat = table.copy(ocelot)
|
local cat = table.copy(ocelot)
|
||||||
|
@ -124,7 +121,9 @@ cat.sounds = {
|
||||||
distance = 16,
|
distance = 16,
|
||||||
}
|
}
|
||||||
cat.on_rightclick = function(self, clicker)
|
cat.on_rightclick = function(self, clicker)
|
||||||
if mobs:feed_tame(self, clicker, 1, true, false) then return end
|
if mcl_mobs:feed_tame(self, clicker, 1, true, false) then return end
|
||||||
|
if mcl_mobs:capture_mob(self, clicker, 0, 60, 5, false, nil) then return end
|
||||||
|
if mcl_mobs:protect(self, clicker) then return end
|
||||||
|
|
||||||
if self.child then return end
|
if self.child then return end
|
||||||
|
|
||||||
|
@ -149,13 +148,13 @@ cat.on_rightclick = function(self, clicker)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:cat", cat)
|
mcl_mobs:register_mob("mobs_mc:cat", cat)
|
||||||
|
|
||||||
--local base_spawn_chance = 5000
|
local base_spawn_chance = 5000
|
||||||
|
|
||||||
-- Spawn ocelot
|
-- Spawn ocelot
|
||||||
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i
|
--they get the same as the llama because I'm trying to rework so much of this code right now -j4i
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:ocelot",
|
"mobs_mc:ocelot",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -170,19 +169,19 @@ minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
15000,
|
||||||
5,
|
5,
|
||||||
mobs_mc.spawn_height.water+15,
|
mobs_mc.water_level+15,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
--[[
|
--[[
|
||||||
mobs:spawn({
|
mobs:spawn({
|
||||||
name = "mobs_mc:ocelot",
|
name = "mobs_mc:ocelot",
|
||||||
nodes = mobs_mc.spawn.jungle,
|
nodes = { "mcl_core:jungletree", "mcl_core:jungleleaves", "mcl_flowers:fern", "mcl_core:vine" },
|
||||||
neighbors = {"air"},
|
neighbors = {"air"},
|
||||||
light_max = minetest.LIGHT_MAX+1,
|
light_max = minetest.LIGHT_MAX+1,
|
||||||
light_min = 0,
|
light_min = 0,
|
||||||
chance = math.ceil(base_spawn_chance * 1.5), -- emulates 1/3 spawn failure rate
|
chance = math.ceil(base_spawn_chance * 1.5), -- emulates 1/3 spawn failure rate
|
||||||
active_object_count = 12,
|
active_object_count = 12,
|
||||||
min_height = mobs_mc.spawn_height.water+1, -- Right above ocean level
|
min_height = mobs_mc.water_level+1, -- Right above ocean level
|
||||||
max_height = mobs_mc.spawn_height.overworld_max,
|
max_height = mcl_vars.mg_overworld_max,
|
||||||
on_spawn = function(self, pos)
|
on_spawn = function(self, pos)
|
||||||
Note: Minecraft has a 1/3 spawn failure rate.
|
Note: Minecraft has a 1/3 spawn failure rate.
|
||||||
In this mod it is emulated by reducing the spawn rate accordingly (see above).
|
In this mod it is emulated by reducing the spawn rate accordingly (see above).
|
||||||
|
@ -232,4 +231,4 @@ mobs:spawn({
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
-- FIXME: The spawn icon shows a cat texture, not an ocelot texture
|
-- FIXME: The spawn icon shows a cat texture, not an ocelot texture
|
||||||
mobs:register_egg("mobs_mc:ocelot", S("Ocelot"), "mobs_mc_spawn_icon_cat.png", 0)
|
mcl_mobs:register_egg("mobs_mc:ocelot", S("Ocelot"), "mobs_mc_spawn_icon_cat.png", 0)
|
||||||
|
|
|
@ -3,15 +3,81 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### PARROT
|
--################### PARROT
|
||||||
--###################
|
--###################
|
||||||
|
local shoulders = {
|
||||||
|
left = vector.new(-3.75,10.5,0),
|
||||||
|
right = vector.new(3.75,10.5,0)
|
||||||
|
}
|
||||||
|
|
||||||
|
--find a free shoulder or return nil
|
||||||
|
local function get_shoulder(player)
|
||||||
|
local sh = "left"
|
||||||
|
for _,o in pairs(player:get_children()) do
|
||||||
|
local l = o:get_luaentity()
|
||||||
|
if l and l.name == "mobs_mc:parrot" then
|
||||||
|
local _,_,a = l.object:get_attach()
|
||||||
|
for _,s in pairs(shoulders) do
|
||||||
|
if a and vector.equals(a,s) then
|
||||||
|
if sh == "left" then
|
||||||
|
sh = "right"
|
||||||
|
else
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return shoulders[sh]
|
||||||
|
end
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:parrot", {
|
local function perch(self,player)
|
||||||
|
if self.tamed and player:get_player_name() == self.owner and not self.object:get_attach() then
|
||||||
|
local shoulder = get_shoulder(player)
|
||||||
|
if not shoulder then return true end
|
||||||
|
self.object:set_attach(player,"",shoulder,vector.new(0,0,0),true)
|
||||||
|
mcl_mobs:set_animation(self, "stand")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function check_perch(self,dtime)
|
||||||
|
if self.object:get_attach() then
|
||||||
|
for _,p in pairs(minetest.get_connected_players()) do
|
||||||
|
for _,o in pairs(p:get_children()) do
|
||||||
|
local l = o:get_luaentity()
|
||||||
|
if l and l.name == "mobs_mc:parrot" then
|
||||||
|
local n1 = minetest.get_node(vector.offset(p:get_pos(),0,-0.6,0)).name
|
||||||
|
local n2 = minetest.get_node(vector.offset(p:get_pos(),0,0,0)).name
|
||||||
|
local n3 = minetest.get_node(vector.offset(p:get_pos(),0,1,0)).name
|
||||||
|
if n1 == "air" or minetest.get_item_group(n2,"water") > 0 or minetest.get_item_group(n2,"lava") > 0 then
|
||||||
|
o:set_detach()
|
||||||
|
self.detach_timer = 0
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif not self.detach_timer then
|
||||||
|
for _,p in pairs(minetest.get_connected_players()) do
|
||||||
|
if vector.distance(self.object:get_pos(),p:get_pos()) < 0.5 then
|
||||||
|
perch(self,p)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif self.detach_timer then
|
||||||
|
if self.detach_timer > 1 then
|
||||||
|
self.detach_timer = nil
|
||||||
|
else
|
||||||
|
self.detach_timer = self.detach_timer + dtime
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_mobs:register_mob("mobs_mc:parrot", {
|
||||||
description = S("Parrot"),
|
description = S("Parrot"),
|
||||||
type = "npc",
|
type = "npc",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
@ -20,14 +86,11 @@ mobs:register_mob("mobs_mc:parrot", {
|
||||||
hp_max = 6,
|
hp_max = 6,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
xp_max = 3,
|
xp_max = 3,
|
||||||
tilt_fly = true,
|
collisionbox = {-0.25, -0.01, -0.25, 0.25, 0.89, 0.25},
|
||||||
collisionbox = {-0.25, 0, -0.25, 0.25, 0.9, 0.25},
|
|
||||||
eye_height = 0.45,
|
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_parrot.b3d",
|
mesh = "mobs_mc_parrot.b3d",
|
||||||
textures = {{"mobs_mc_parrot_blue.png"},{"mobs_mc_parrot_green.png"},{"mobs_mc_parrot_grey.png"},{"mobs_mc_parrot_red_blue.png"},{"mobs_mc_parrot_yellow_blue.png"}},
|
textures = {{"mobs_mc_parrot_blue.png"},{"mobs_mc_parrot_green.png"},{"mobs_mc_parrot_grey.png"},{"mobs_mc_parrot_red_blue.png"},{"mobs_mc_parrot_yellow_blue.png"}},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
rotate = 270,
|
|
||||||
walk_velocity = 3,
|
walk_velocity = 3,
|
||||||
run_velocity = 5,
|
run_velocity = 5,
|
||||||
sounds = {
|
sounds = {
|
||||||
|
@ -38,22 +101,22 @@ mobs:register_mob("mobs_mc:parrot", {
|
||||||
distance = 16,
|
distance = 16,
|
||||||
},
|
},
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.feather,
|
{name = "mcl_mobitems:feather",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
},
|
},
|
||||||
animation = {
|
animation = {
|
||||||
stand_speed = 50,
|
stand_speed = 50,
|
||||||
walk_speed = 50,
|
walk_speed = 50,
|
||||||
fly_speed = 50,
|
fly_speed = 50,
|
||||||
stand_start = 30,
|
stand_start = 0,
|
||||||
stand_end = 45,
|
stand_end = 0,
|
||||||
fly_start = 30,
|
fly_start = 30,
|
||||||
fly_end = 45,
|
fly_end = 45,
|
||||||
walk_start = 30,
|
walk_start = 0,
|
||||||
walk_end = 45,
|
walk_end = 20,
|
||||||
-- TODO: actual walk animation
|
-- TODO: actual walk animation
|
||||||
--walk_start = 0,
|
--walk_start = 0,
|
||||||
--walk_end = 20,
|
--walk_end = 20,
|
||||||
|
@ -69,12 +132,17 @@ mobs:register_mob("mobs_mc:parrot", {
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
fear_height = 0,
|
fear_height = 0,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
follow = mobs_mc.follow.parrot,
|
follow = {
|
||||||
|
"mcl_farming:wheat_seeds",
|
||||||
|
"mcl_farming:melon_seeds",
|
||||||
|
"mcl_farming:pumpkin_seeds",
|
||||||
|
"mcl_farming:beetroot_seeds",
|
||||||
|
},
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
if self._doomed then return end
|
if self._doomed then return end
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
-- Kill parrot if fed with cookie
|
-- Kill parrot if fed with cookie
|
||||||
if item:get_name() == mobs_mc.items.cookie then
|
if item:get_name() == "mcl_farming:cookie" then
|
||||||
minetest.sound_play("mobs_mc_animal_eat_generic", {object = self.object, max_hear_distance=16}, true)
|
minetest.sound_play("mobs_mc_animal_eat_generic", {object = self.object, max_hear_distance=16}, true)
|
||||||
self.health = 0
|
self.health = 0
|
||||||
-- Doomed to die
|
-- Doomed to die
|
||||||
|
@ -85,15 +153,22 @@ mobs:register_mob("mobs_mc:parrot", {
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Feed to tame, but not breed
|
-- Feed to tame, but not breed
|
||||||
if mobs:feed_tame(self, clicker, 1, false, true) then return end
|
if mcl_mobs:feed_tame(self, clicker, 1, false, true) then return end
|
||||||
|
perch(self,clicker)
|
||||||
|
end,
|
||||||
|
do_custom = function(self,dtime)
|
||||||
|
check_perch(self,dtime)
|
||||||
|
end,
|
||||||
|
do_punch = function(self,puncher) --do_punch is the mcl_mobs_redo variant - it gets called by on_punch later....
|
||||||
|
if self.object:get_attach() == puncher then
|
||||||
|
return false --return false explicitly here. mcl_mobs checks for that
|
||||||
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
|
-- Parrots spawn rarely in jungles. TODO: Also check for jungle *biome* <- I'll get to this eventually -j4i
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:parrot",
|
"mobs_mc:parrot",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -108,8 +183,8 @@ minetest.LIGHT_MAX+1,
|
||||||
7,
|
7,
|
||||||
30000,
|
30000,
|
||||||
1,
|
1,
|
||||||
mobs_mc.spawn_height.water+7,
|
mobs_mc.water_level+7,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)
|
mcl_mobs:register_egg("mobs_mc:parrot", S("Parrot"), "mobs_mc_spawn_icon_parrot.png", 0)
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:pig", {
|
mcl_mobs:register_mob("mobs_mc:pig", {
|
||||||
description = S("Pig"),
|
description = S("Pig"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
skittish = true,
|
runaway = true,
|
||||||
rotate = 270,
|
|
||||||
hp_min = 10,
|
hp_min = 10,
|
||||||
hp_max = 10,
|
hp_max = 10,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
|
@ -20,32 +19,13 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
"mobs_mc_pig.png", -- base
|
"mobs_mc_pig.png", -- base
|
||||||
"blank.png", -- saddle
|
"blank.png", -- saddle
|
||||||
}},
|
}},
|
||||||
|
|
||||||
--head code
|
|
||||||
has_head = true,
|
|
||||||
head_bone = "head",
|
|
||||||
|
|
||||||
swap_y_with_x = false,
|
|
||||||
reverse_head_yaw = false,
|
|
||||||
|
|
||||||
head_bone_pos_y = 2.4,
|
|
||||||
head_bone_pos_z = 0,
|
|
||||||
|
|
||||||
head_height_offset = 1.1,
|
|
||||||
head_direction_offset = 0,
|
|
||||||
head_pitch_modifier = 0,
|
|
||||||
--end head code
|
|
||||||
|
|
||||||
visual_size = {x=2.5, y=2.5},
|
visual_size = {x=2.5, y=2.5},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 3,
|
run_velocity = 3,
|
||||||
follow_velocity = 3.4,
|
follow_velocity = 3.4,
|
||||||
breed_distance = 1.5,
|
|
||||||
baby_size = 0.5,
|
|
||||||
follow_distance = 2,
|
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.porkchop_raw,
|
{name = "mcl_mobitems:porkchop",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 3,
|
max = 3,
|
||||||
|
@ -70,7 +50,12 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
run_start = 0,
|
run_start = 0,
|
||||||
run_end = 40,
|
run_end = 40,
|
||||||
},
|
},
|
||||||
follow = "mcl_farming:carrot_item",
|
follow = {
|
||||||
|
"mcl_farming:potato_item",
|
||||||
|
"mcl_farming:carrot_item",
|
||||||
|
"mcl_farming:beetroot_item",
|
||||||
|
"mcl_mobitems:carrot_on_a_stick"
|
||||||
|
},
|
||||||
view_range = 8,
|
view_range = 8,
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
|
|
||||||
|
@ -89,7 +74,7 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
-- if driver present allow control of horse
|
-- if driver present allow control of horse
|
||||||
if self.driver then
|
if self.driver then
|
||||||
|
|
||||||
mobs.drive(self, "walk", "stand", false, dtime)
|
mcl_mobs.drive(self, "walk", "stand", false, dtime)
|
||||||
|
|
||||||
return false -- skip rest of mob functions
|
return false -- skip rest of mob functions
|
||||||
end
|
end
|
||||||
|
@ -102,7 +87,7 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
-- drop saddle when horse is killed while riding
|
-- drop saddle when horse is killed while riding
|
||||||
-- also detach from horse properly
|
-- also detach from horse properly
|
||||||
if self.driver then
|
if self.driver then
|
||||||
mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
mcl_mobs.detach(self.driver, {x = 1, y = 0, z = 1})
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
@ -111,17 +96,12 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
--attempt to enter breed state
|
local wielditem = clicker:get_wielded_item()
|
||||||
if mobs.enter_breed_state(self,clicker) then
|
-- Feed pig
|
||||||
return
|
if wielditem:get_name() ~= "mcl_mobitems:carrot_on_a_stick" then
|
||||||
end
|
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||||
|
|
||||||
--ignore other logic
|
|
||||||
--make baby grow faster
|
|
||||||
if self.baby then
|
|
||||||
mobs.make_baby_grow_faster(self,clicker)
|
|
||||||
return
|
|
||||||
end
|
end
|
||||||
|
if mcl_mobs:protect(self, clicker) then return end
|
||||||
|
|
||||||
if self.child then
|
if self.child then
|
||||||
return
|
return
|
||||||
|
@ -129,9 +109,7 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
|
|
||||||
-- Put saddle on pig
|
-- Put saddle on pig
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
local wielditem = item
|
if item:get_name() == "mcl_mobitems:saddle" and self.saddle ~= "yes" then
|
||||||
|
|
||||||
if item:get_name() == mobs_mc.items.saddle and self.saddle ~= "yes" then
|
|
||||||
self.base_texture = {
|
self.base_texture = {
|
||||||
"blank.png", -- baby
|
"blank.png", -- baby
|
||||||
"mobs_mc_pig.png", -- base
|
"mobs_mc_pig.png", -- base
|
||||||
|
@ -143,11 +121,11 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
self.saddle = "yes"
|
self.saddle = "yes"
|
||||||
self.tamed = true
|
self.tamed = true
|
||||||
self.drops = {
|
self.drops = {
|
||||||
{name = mobs_mc.items.porkchop_raw,
|
{name = "mcl_mobitems:porkchop",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 3,},
|
max = 3,},
|
||||||
{name = mobs_mc.items.saddle,
|
{name = "mcl_mobitems:saddle",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,},
|
max = 1,},
|
||||||
|
@ -163,16 +141,16 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Mount or detach player
|
-- Mount or detach player
|
||||||
--local name = clicker:get_player_name()
|
local name = clicker:get_player_name()
|
||||||
if self.driver and clicker == self.driver then
|
if self.driver and clicker == self.driver then
|
||||||
-- Detach if already attached
|
-- Detach if already attached
|
||||||
mobs.detach(clicker, {x=1, y=0, z=0})
|
mcl_mobs.detach(clicker, {x=1, y=0, z=0})
|
||||||
return
|
return
|
||||||
|
|
||||||
elseif not self.driver and self.saddle == "yes" and wielditem:get_name() == mobs_mc.items.carrot_on_a_stick then
|
elseif not self.driver and self.saddle == "yes" and wielditem:get_name() == "mcl_mobitems:carrot_on_a_stick" then
|
||||||
-- Ride pig if it has a saddle and player uses a carrot on a stick
|
-- Ride pig if it has a saddle and player uses a carrot on a stick
|
||||||
|
|
||||||
mobs.attach(self, clicker)
|
mcl_mobs.attach(self, clicker)
|
||||||
|
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
|
|
||||||
|
@ -184,19 +162,23 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
if def.sounds and def.sounds.breaks then
|
if def.sounds and def.sounds.breaks then
|
||||||
minetest.sound_play(def.sounds.breaks, {pos = clicker:get_pos(), max_hear_distance = 8, gain = 0.5}, true)
|
minetest.sound_play(def.sounds.breaks, {pos = clicker:get_pos(), max_hear_distance = 8, gain = 0.5}, true)
|
||||||
end
|
end
|
||||||
wielditem = {name = mobs_mc.items.fishing_rod, count = 1}
|
wielditem = {name = "mcl_fishing:fishing_rod", count = 1}
|
||||||
else
|
else
|
||||||
wielditem:add_wear(2521)
|
wielditem:add_wear(2521)
|
||||||
end
|
end
|
||||||
inv:set_stack("main",self.driver:get_wield_index(), wielditem)
|
inv:set_stack("main",self.driver:get_wield_index(), wielditem)
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
|
|
||||||
|
-- Capture pig
|
||||||
|
elseif not self.driver and clicker:get_wielded_item():get_name() ~= "" then
|
||||||
|
mcl_mobs:capture_mob(self, clicker, 0, 5, 60, false, nil)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_breed = function(parent1, parent2)
|
on_breed = function(parent1, parent2)
|
||||||
local pos = parent1.object:get_pos()
|
local pos = parent1.object:get_pos()
|
||||||
local child = mobs:spawn_child(pos, parent1.name)
|
local child = mcl_mobs:spawn_child(pos, parent1.name)
|
||||||
if child then
|
if child then
|
||||||
local ent_c = child:get_luaentity()
|
local ent_c = child:get_luaentity()
|
||||||
ent_c.tamed = true
|
ent_c.tamed = true
|
||||||
|
@ -206,66 +188,55 @@ mobs:register_mob("mobs_mc:pig", {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:pig",
|
"mobs_mc:pig",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"FlowerForest_beach",
|
"flat",
|
||||||
"Forest_beach",
|
|
||||||
"StoneBeach",
|
|
||||||
"ColdTaiga_beach_water",
|
|
||||||
"Taiga_beach",
|
|
||||||
"Savanna_beach",
|
|
||||||
"Plains_beach",
|
|
||||||
"ExtremeHills_beach",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"Swampland_shore",
|
|
||||||
"JungleM_shore",
|
|
||||||
"Jungle_shore",
|
|
||||||
"MesaPlateauFM_sandlevel",
|
|
||||||
"MesaPlateauF_sandlevel",
|
|
||||||
"MesaBryce_sandlevel",
|
|
||||||
"Mesa_sandlevel",
|
|
||||||
"Mesa",
|
|
||||||
"FlowerForest",
|
|
||||||
"Swampland",
|
|
||||||
"Taiga",
|
|
||||||
"ExtremeHills",
|
|
||||||
"Jungle",
|
|
||||||
"Savanna",
|
|
||||||
"BirchForest",
|
|
||||||
"MegaSpruceTaiga",
|
|
||||||
"MegaTaiga",
|
|
||||||
"ExtremeHills+",
|
|
||||||
"Forest",
|
|
||||||
"Plains",
|
|
||||||
"Desert",
|
|
||||||
"ColdTaiga",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"ColdTaiga",
|
||||||
"IcePlains",
|
"ColdTaiga_beach",
|
||||||
"RoofedForest",
|
"ColdTaiga_beach_water",
|
||||||
"ExtremeHills+_snowtop",
|
"MegaTaiga",
|
||||||
"MesaPlateauFM_grasstop",
|
"MegaSpruceTaiga",
|
||||||
"JungleEdgeM",
|
"ExtremeHills",
|
||||||
|
"ExtremeHills_beach",
|
||||||
"ExtremeHillsM",
|
"ExtremeHillsM",
|
||||||
"JungleM",
|
"ExtremeHills+",
|
||||||
|
"ExtremeHills+_snowtop",
|
||||||
|
"StoneBeach",
|
||||||
|
"Plains",
|
||||||
|
"Plains_beach",
|
||||||
|
"SunflowerPlains",
|
||||||
|
"Taiga",
|
||||||
|
"Taiga_beach",
|
||||||
|
"Forest",
|
||||||
|
"Forest_beach",
|
||||||
|
"FlowerForest",
|
||||||
|
"FlowerForest_beach",
|
||||||
|
"BirchForest",
|
||||||
"BirchForestM",
|
"BirchForestM",
|
||||||
"MesaPlateauF",
|
"RoofedForest",
|
||||||
"MesaPlateauFM",
|
"Savanna",
|
||||||
"MesaPlateauF_grasstop",
|
"Savanna_beach",
|
||||||
"MesaBryce",
|
|
||||||
"JungleEdge",
|
|
||||||
"SavannaM",
|
"SavannaM",
|
||||||
|
"Jungle",
|
||||||
|
"Jungle_shore",
|
||||||
|
"JungleM",
|
||||||
|
"JungleM_shore",
|
||||||
|
"JungleEdge",
|
||||||
|
"JungleEdgeM",
|
||||||
|
"Swampland",
|
||||||
|
"Swampland_shore"
|
||||||
},
|
},
|
||||||
9,
|
9,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
15000,
|
||||||
8,
|
8,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0)
|
mcl_mobs:register_egg("mobs_mc:pig", S("Pig"), "mobs_mc_spawn_icon_pig.png", 0)
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### POLARBEAR
|
--################### POLARBEAR
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:polar_bear", {
|
mcl_mobs:register_mob("mobs_mc:polar_bear", {
|
||||||
description = S("Polar Bear"),
|
description = S("Polar Bear"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
@ -31,16 +31,16 @@ mobs:register_mob("mobs_mc:polar_bear", {
|
||||||
walk_velocity = 1.2,
|
walk_velocity = 1.2,
|
||||||
run_velocity = 2.4,
|
run_velocity = 2.4,
|
||||||
group_attack = true,
|
group_attack = true,
|
||||||
attack_type = "punch",
|
attack_type = "dogfight",
|
||||||
drops = {
|
drops = {
|
||||||
-- 3/4 chance to drop raw fish (poor approximation)
|
-- 3/4 chance to drop raw fish (poor approximation)
|
||||||
{name = mobs_mc.items.fish_raw,
|
{name = "mcl_fishing:fish_raw",
|
||||||
chance = 2,
|
chance = 2,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
-- 1/4 to drop raw salmon
|
-- 1/4 to drop raw salmon
|
||||||
{name = mobs_mc.items.salmon_raw,
|
{name = "mcl_fishing:salmon_raw",
|
||||||
chance = 4,
|
chance = 4,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
|
@ -68,7 +68,7 @@ mobs:register_mob("mobs_mc:polar_bear", {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:polar_bear",
|
"mobs_mc:polar_bear",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -83,8 +83,8 @@ minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
7000,
|
7000,
|
||||||
3,
|
3,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn egg
|
-- spawn egg
|
||||||
mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0)
|
mcl_mobs:register_egg("mobs_mc:polar_bear", S("Polar Bear"), "mobs_mc_spawn_icon_polarbear.png", 0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### SHEEP
|
--################### SHEEP
|
||||||
|
@ -8,21 +8,22 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
local colors = {
|
local colors = {
|
||||||
-- group = { wool, textures }
|
-- group = { wool, textures }
|
||||||
unicolor_white = { mobs_mc.items.wool_white, "#FFFFFF00" },
|
unicolor_white = { "mcl_wool:white", "#FFFFFF00" },
|
||||||
unicolor_dark_orange = { mobs_mc.items.wool_brown, "#502A00D0" },
|
unicolor_dark_orange = { "mcl_wool:brown", "#502A00D0" },
|
||||||
unicolor_grey = { mobs_mc.items.wool_light_grey, "#5B5B5BD0" },
|
unicolor_grey = { "mcl_wool:silver", "#5B5B5BD0" },
|
||||||
unicolor_darkgrey = { mobs_mc.items.wool_grey, "#303030D0" },
|
unicolor_darkgrey = { "mcl_wool:grey", "#303030D0" },
|
||||||
unicolor_blue = { mobs_mc.items.wool_blue, "#0000CCD0" },
|
unicolor_blue = { "mcl_wool:blue", "#0000CCD0" },
|
||||||
unicolor_dark_green = { mobs_mc.items.wool_green, "#005000D0" },
|
unicolor_dark_green = { "mcl_wool:green", "#005000D0" },
|
||||||
unicolor_green = { mobs_mc.items.wool_lime, "#50CC00D0" },
|
unicolor_green = { "mcl_wool:lime", "#50CC00D0" },
|
||||||
unicolor_violet = { mobs_mc.items.wool_purple , "#5000CCD0" },
|
unicolor_violet = { "mcl_wool:purple" , "#5000CCD0" },
|
||||||
unicolor_light_red = { mobs_mc.items.wool_pink, "#FF5050D0" },
|
unicolor_light_red = { "mcl_wool:pink", "#FF5050D0" },
|
||||||
unicolor_yellow = { mobs_mc.items.wool_yellow, "#CCCC00D0" },
|
unicolor_yellow = { "mcl_wool:yellow", "#CCCC00D0" },
|
||||||
unicolor_orange = { mobs_mc.items.wool_orange, "#CC5000D0" },
|
unicolor_orange = { "mcl_wool:orange", "#CC5000D0" },
|
||||||
unicolor_red = { mobs_mc.items.wool_red, "#CC0000D0" },
|
unicolor_red = { "mcl_wool:red", "#CC0000D0" },
|
||||||
unicolor_cyan = { mobs_mc.items.wool_cyan, "#00CCCCD0" },
|
unicolor_cyan = { "mcl_wool:cyan", "#00CCCCD0" },
|
||||||
unicolor_red_violet = { mobs_mc.items.wool_magenta, "#CC0050D0" },
|
unicolor_red_violet = { "mcl_wool:magenta", "#CC0050D0" },
|
||||||
unicolor_black = { mobs_mc.items.wool_black, "#000000D0" },
|
unicolor_black = { "mcl_wool:black", "#000000D0" },
|
||||||
|
unicolor_light_blue = { "mcl_wool:light_blue", "#5050FFD0" },
|
||||||
}
|
}
|
||||||
|
|
||||||
local rainbow_colors = {
|
local rainbow_colors = {
|
||||||
|
@ -38,10 +39,6 @@ local rainbow_colors = {
|
||||||
"unicolor_red_violet"
|
"unicolor_red_violet"
|
||||||
}
|
}
|
||||||
|
|
||||||
if minetest.get_modpath("mcl_wool") then
|
|
||||||
colors["unicolor_light_blue"] = { mobs_mc.items.wool_light_blue, "#5050FFD0" }
|
|
||||||
end
|
|
||||||
|
|
||||||
local sheep_texture = function(color_group)
|
local sheep_texture = function(color_group)
|
||||||
if not color_group then
|
if not color_group then
|
||||||
color_group = "unicolor_white"
|
color_group = "unicolor_white"
|
||||||
|
@ -55,7 +52,7 @@ end
|
||||||
local gotten_texture = { "blank.png", "mobs_mc_sheep.png" }
|
local gotten_texture = { "blank.png", "mobs_mc_sheep.png" }
|
||||||
|
|
||||||
--mcsheep
|
--mcsheep
|
||||||
mobs:register_mob("mobs_mc:sheep", {
|
mcl_mobs:register_mob("mobs_mc:sheep", {
|
||||||
description = S("Sheep"),
|
description = S("Sheep"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
@ -63,13 +60,8 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
hp_max = 8,
|
hp_max = 8,
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
xp_max = 3,
|
xp_max = 3,
|
||||||
skittish = true,
|
|
||||||
breed_distance = 1.5,
|
|
||||||
baby_size = 0.5,
|
|
||||||
follow_distance = 2,
|
|
||||||
follow = mobs_mc.items.wheat,
|
|
||||||
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45},
|
collisionbox = {-0.45, -0.01, -0.45, 0.45, 1.29, 0.45},
|
||||||
rotate = 270,
|
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
mesh = "mobs_mc_sheepfur.b3d",
|
mesh = "mobs_mc_sheepfur.b3d",
|
||||||
|
@ -78,25 +70,8 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
color = "unicolor_white",
|
color = "unicolor_white",
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1,
|
walk_velocity = 1,
|
||||||
run_velocity = 3,
|
|
||||||
|
|
||||||
--head code
|
|
||||||
has_head = true,
|
|
||||||
head_bone = "head",
|
|
||||||
|
|
||||||
swap_y_with_x = false,
|
|
||||||
reverse_head_yaw = false,
|
|
||||||
|
|
||||||
head_bone_pos_y = 3.6,
|
|
||||||
head_bone_pos_z = -0.6,
|
|
||||||
|
|
||||||
head_height_offset = 1.0525,
|
|
||||||
head_direction_offset = 0.5,
|
|
||||||
head_pitch_modifier = 0,
|
|
||||||
--end head code
|
|
||||||
|
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.mutton_raw,
|
{name = "mcl_mobitems:mutton",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 2,
|
max = 2,
|
||||||
|
@ -121,11 +96,15 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
walk_start = 0, walk_end = 40,
|
walk_start = 0, walk_end = 40,
|
||||||
run_start = 0, run_end = 40,
|
run_start = 0, run_end = 40,
|
||||||
},
|
},
|
||||||
|
follow = { "mcl_farming:wheat_item" },
|
||||||
view_range = 12,
|
view_range = 12,
|
||||||
|
|
||||||
-- Eat grass
|
-- Eat grass
|
||||||
replace_rate = 20,
|
replace_rate = 20,
|
||||||
replace_what = mobs_mc.replace.sheep,
|
replace_what = {
|
||||||
|
{ "mcl_core:dirt_with_grass", "mcl_core:dirt", -1 },
|
||||||
|
{ "mcl_flowers:tallgrass", "air", 0 },
|
||||||
|
},
|
||||||
-- Properly regrow wool after eating grass
|
-- Properly regrow wool after eating grass
|
||||||
on_replace = function(self, pos, oldnode, newnode)
|
on_replace = function(self, pos, oldnode, newnode)
|
||||||
if not self.color or not colors[self.color] then
|
if not self.color or not colors[self.color] then
|
||||||
|
@ -135,7 +114,7 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
self.base_texture = sheep_texture(self.color)
|
self.base_texture = sheep_texture(self.color)
|
||||||
self.object:set_properties({ textures = self.base_texture })
|
self.object:set_properties({ textures = self.base_texture })
|
||||||
self.drops = {
|
self.drops = {
|
||||||
{name = mobs_mc.items.mutton_raw,
|
{name = "mcl_mobitems:mutton",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
|
@ -150,6 +129,7 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
do_custom = function(self, dtime)
|
do_custom = function(self, dtime)
|
||||||
if not self.initial_color_set then
|
if not self.initial_color_set then
|
||||||
local r = math.random(0,100000)
|
local r = math.random(0,100000)
|
||||||
|
local textures
|
||||||
if r <= 81836 then
|
if r <= 81836 then
|
||||||
-- 81.836%
|
-- 81.836%
|
||||||
self.color = "unicolor_white"
|
self.color = "unicolor_white"
|
||||||
|
@ -172,7 +152,7 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
self.base_texture = sheep_texture(self.color)
|
self.base_texture = sheep_texture(self.color)
|
||||||
self.object:set_properties({ textures = self.base_texture })
|
self.object:set_properties({ textures = self.base_texture })
|
||||||
self.drops = {
|
self.drops = {
|
||||||
{name = mobs_mc.items.mutton_raw,
|
{name = "mcl_mobitems:mutton",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
|
@ -215,18 +195,10 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
|
|
||||||
--attempt to enter breed state
|
if mcl_mobs:feed_tame(self, clicker, 1, true, true) then return end
|
||||||
if mobs.enter_breed_state(self,clicker) then
|
if mcl_mobs:protect(self, clicker) then return end
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
--make baby grow faster
|
if item:get_name() == "mcl_tools:shears" and not self.gotten and not self.child then
|
||||||
if self.baby then
|
|
||||||
mobs.make_baby_grow_faster(self,clicker)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if item:get_name() == mobs_mc.items.shears and not self.gotten and not self.child then
|
|
||||||
self.gotten = true
|
self.gotten = true
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
|
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
|
||||||
|
@ -240,11 +212,11 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
textures = self.base_texture,
|
textures = self.base_texture,
|
||||||
})
|
})
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
item:add_wear(mobs_mc.misc.shears_wear)
|
item:add_wear(mobs_mc.shears_wear)
|
||||||
clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
|
clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
|
||||||
end
|
end
|
||||||
self.drops = {
|
self.drops = {
|
||||||
{name = mobs_mc.items.mutton_raw,
|
{name = "mcl_mobitems:mutton",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
|
@ -266,7 +238,7 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
})
|
})
|
||||||
self.color = group
|
self.color = group
|
||||||
self.drops = {
|
self.drops = {
|
||||||
{name = mobs_mc.items.mutton_raw,
|
{name = "mcl_mobitems:mutton",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
|
@ -280,11 +252,12 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
end
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
if mcl_mobs:capture_mob(self, clicker, 0, 5, 70, false, nil) then return end
|
||||||
end,
|
end,
|
||||||
on_breed = function(parent1, parent2)
|
on_breed = function(parent1, parent2)
|
||||||
-- Breed sheep and choose a fur color for the child.
|
-- Breed sheep and choose a fur color for the child.
|
||||||
local pos = parent1.object:get_pos()
|
local pos = parent1.object:get_pos()
|
||||||
local child = mobs:spawn_child(pos, parent1.name)
|
local child = mcl_mobs:spawn_child(pos, parent1.name)
|
||||||
if child then
|
if child then
|
||||||
local ent_c = child:get_luaentity()
|
local ent_c = child:get_luaentity()
|
||||||
local color1 = parent1.color
|
local color1 = parent1.color
|
||||||
|
@ -331,67 +304,55 @@ mobs:register_mob("mobs_mc:sheep", {
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:sheep",
|
"mobs_mc:sheep",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"FlowerForest_beach",
|
"flat",
|
||||||
"Forest_beach",
|
|
||||||
"StoneBeach",
|
|
||||||
"ColdTaiga_beach_water",
|
|
||||||
"Taiga_beach",
|
|
||||||
"Savanna_beach",
|
|
||||||
"Plains_beach",
|
|
||||||
"ExtremeHills_beach",
|
|
||||||
"ColdTaiga_beach",
|
|
||||||
"Swampland_shore",
|
|
||||||
"JungleM_shore",
|
|
||||||
"Jungle_shore",
|
|
||||||
"MesaPlateauFM_sandlevel",
|
|
||||||
"MesaPlateauF_sandlevel",
|
|
||||||
"MesaBryce_sandlevel",
|
|
||||||
"Mesa_sandlevel",
|
|
||||||
"Mesa",
|
|
||||||
"FlowerForest",
|
|
||||||
"Swampland",
|
|
||||||
"Taiga",
|
|
||||||
"ExtremeHills",
|
|
||||||
"Jungle",
|
|
||||||
"Savanna",
|
|
||||||
"BirchForest",
|
|
||||||
"MegaSpruceTaiga",
|
|
||||||
"MegaTaiga",
|
|
||||||
"ExtremeHills+",
|
|
||||||
"Forest",
|
|
||||||
"Plains",
|
|
||||||
"Desert",
|
|
||||||
"ColdTaiga",
|
|
||||||
"IcePlainsSpikes",
|
"IcePlainsSpikes",
|
||||||
"SunflowerPlains",
|
"ColdTaiga",
|
||||||
"IcePlains",
|
"ColdTaiga_beach",
|
||||||
"RoofedForest",
|
"ColdTaiga_beach_water",
|
||||||
"ExtremeHills+_snowtop",
|
"MegaTaiga",
|
||||||
"MesaPlateauFM_grasstop",
|
"MegaSpruceTaiga",
|
||||||
"JungleEdgeM",
|
"ExtremeHills",
|
||||||
|
"ExtremeHills_beach",
|
||||||
"ExtremeHillsM",
|
"ExtremeHillsM",
|
||||||
"JungleM",
|
"ExtremeHills+",
|
||||||
|
"ExtremeHills+_snowtop",
|
||||||
|
"StoneBeach",
|
||||||
|
"Plains",
|
||||||
|
"Plains_beach",
|
||||||
|
"SunflowerPlains",
|
||||||
|
"Taiga",
|
||||||
|
"Taiga_beach",
|
||||||
|
"Forest",
|
||||||
|
"Forest_beach",
|
||||||
|
"FlowerForest",
|
||||||
|
"FlowerForest_beach",
|
||||||
|
"BirchForest",
|
||||||
"BirchForestM",
|
"BirchForestM",
|
||||||
"MesaPlateauF",
|
"RoofedForest",
|
||||||
"MesaPlateauFM",
|
"Savanna",
|
||||||
"MesaPlateauF_grasstop",
|
"Savanna_beach",
|
||||||
"MesaBryce",
|
|
||||||
"JungleEdge",
|
|
||||||
"SavannaM",
|
"SavannaM",
|
||||||
|
"Jungle",
|
||||||
|
"Jungle_shore",
|
||||||
|
"JungleM",
|
||||||
|
"JungleM_shore",
|
||||||
|
"JungleEdge",
|
||||||
|
"JungleEdgeM",
|
||||||
|
"Swampland",
|
||||||
|
"Swampland_shore"
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
15000,
|
15000,
|
||||||
3,
|
3,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0)
|
mcl_mobs:register_egg("mobs_mc:sheep", S("Sheep"), "mobs_mc_spawn_icon_sheep.png", 0)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### SHULKER
|
--################### SHULKER
|
||||||
|
@ -11,11 +11,11 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
-- animation 45-80 is transition between passive and attack stance
|
-- animation 45-80 is transition between passive and attack stance
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:shulker", {
|
mcl_mobs:register_mob("mobs_mc:shulker", {
|
||||||
description = S("Shulker"),
|
description = S("Shulker"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
attack_type = "projectile",
|
attack_type = "shoot",
|
||||||
shoot_interval = 0.5,
|
shoot_interval = 0.5,
|
||||||
arrow = "mobs_mc:shulkerbullet",
|
arrow = "mobs_mc:shulkerbullet",
|
||||||
shoot_offset = 0.5,
|
shoot_offset = 0.5,
|
||||||
|
@ -33,9 +33,10 @@ mobs:register_mob("mobs_mc:shulker", {
|
||||||
-- TODO: Make shulker dye-able
|
-- TODO: Make shulker dye-able
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
walk_chance = 0,
|
walk_chance = 0,
|
||||||
|
knock_back = false,
|
||||||
jump = false,
|
jump = false,
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.shulker_shell,
|
{name = "mcl_mobitems:shulker_shell",
|
||||||
chance = 2,
|
chance = 2,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
|
@ -55,7 +56,7 @@ mobs:register_mob("mobs_mc:shulker", {
|
||||||
})
|
})
|
||||||
|
|
||||||
-- bullet arrow (weapon)
|
-- bullet arrow (weapon)
|
||||||
mobs:register_arrow("mobs_mc:shulkerbullet", {
|
mcl_mobs:register_arrow("mobs_mc:shulkerbullet", {
|
||||||
visual = "sprite",
|
visual = "sprite",
|
||||||
visual_size = {x = 0.25, y = 0.25},
|
visual_size = {x = 0.25, y = 0.25},
|
||||||
textures = {"mobs_mc_shulkerbullet.png"},
|
textures = {"mobs_mc_shulkerbullet.png"},
|
||||||
|
@ -80,9 +81,9 @@ mobs:register_arrow("mobs_mc:shulkerbullet", {
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0)
|
mcl_mobs:register_egg("mobs_mc:shulker", S("Shulker"), "mobs_mc_spawn_icon_shulker.png", 0)
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:shulker",
|
"mobs_mc:shulker",
|
||||||
"end",
|
"end",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -94,5 +95,5 @@ minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
5000,
|
5000,
|
||||||
2,
|
2,
|
||||||
mobs_mc.spawn_height.end_min,
|
mcl_vars.mg_end_min,
|
||||||
mobs_mc.spawn_height.end_max)
|
mcl_vars.mg_end_max)
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
local mod_bows = minetest.get_modpath("mcl_bows")
|
local mod_bows = minetest.get_modpath("mcl_bows") ~= nil
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### SKELETON
|
--################### SKELETON
|
||||||
|
@ -16,37 +16,21 @@ local skeleton = {
|
||||||
description = S("Skeleton"),
|
description = S("Skeleton"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
hostile = true,
|
|
||||||
rotate = 270,
|
|
||||||
hp_min = 20,
|
hp_min = 20,
|
||||||
hp_max = 20,
|
hp_max = 20,
|
||||||
xp_min = 6,
|
xp_min = 6,
|
||||||
xp_max = 6,
|
xp_max = 6,
|
||||||
breath_max = -1,
|
breath_max = -1,
|
||||||
eye_height = 1.5,
|
|
||||||
projectile_cooldown = 1.5,
|
|
||||||
armor = {undead = 100, fleshy = 100},
|
armor = {undead = 100, fleshy = 100},
|
||||||
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3},
|
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3},
|
||||||
pathfinding = 1,
|
pathfinding = 1,
|
||||||
group_attack = true,
|
group_attack = true,
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
mesh = "mobs_mc_skeleton.b3d",
|
mesh = "mobs_mc_skeleton.b3d",
|
||||||
|
textures = { {
|
||||||
--head code
|
"mcl_bows_bow_0.png", -- bow
|
||||||
has_head = false,
|
"mobs_mc_skeleton.png", -- skeleton
|
||||||
head_bone = "head",
|
} },
|
||||||
|
|
||||||
swap_y_with_x = true,
|
|
||||||
reverse_head_yaw = true,
|
|
||||||
|
|
||||||
head_bone_pos_y = 2.4,
|
|
||||||
head_bone_pos_z = 0,
|
|
||||||
|
|
||||||
head_height_offset = 1.1,
|
|
||||||
head_direction_offset = 0,
|
|
||||||
head_pitch_modifier = 0,
|
|
||||||
--end head code
|
|
||||||
|
|
||||||
visual_size = {x=1, y=1},
|
visual_size = {x=1, y=1},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
textures = {
|
textures = {
|
||||||
|
@ -59,19 +43,19 @@ local skeleton = {
|
||||||
walk_velocity = 1.2,
|
walk_velocity = 1.2,
|
||||||
run_velocity = 2.4,
|
run_velocity = 2.4,
|
||||||
damage = 2,
|
damage = 2,
|
||||||
reach = 3,
|
reach = 2,
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.arrow,
|
{name = "mcl_bows:arrow",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
{name = mobs_mc.items.bow,
|
{name = "mcl_bows:bow",
|
||||||
chance = 100 / 8.5,
|
chance = 100 / 8.5,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "rare",},
|
looting = "rare",},
|
||||||
{name = mobs_mc.items.bone,
|
{name = "mcl_mobitems:bone",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
|
@ -79,7 +63,7 @@ local skeleton = {
|
||||||
|
|
||||||
-- Head
|
-- Head
|
||||||
-- TODO: Only drop if killed by charged creeper
|
-- TODO: Only drop if killed by charged creeper
|
||||||
{name = mobs_mc.items.head_skeleton,
|
{name = "mcl_heads:skeleton",
|
||||||
chance = 200, -- 0.5% chance
|
chance = 200, -- 0.5% chance
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,},
|
max = 1,},
|
||||||
|
@ -91,8 +75,6 @@ local skeleton = {
|
||||||
walk_speed = 15,
|
walk_speed = 15,
|
||||||
walk_start = 40,
|
walk_start = 40,
|
||||||
walk_end = 60,
|
walk_end = 60,
|
||||||
run_start = 40,
|
|
||||||
run_end = 60,
|
|
||||||
run_speed = 30,
|
run_speed = 30,
|
||||||
shoot_start = 70,
|
shoot_start = 70,
|
||||||
shoot_end = 90,
|
shoot_end = 90,
|
||||||
|
@ -104,13 +86,13 @@ local skeleton = {
|
||||||
ignited_by_sunlight = true,
|
ignited_by_sunlight = true,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
attack_type = "projectile",
|
attack_type = "dogshoot",
|
||||||
arrow = "mcl_bows:arrow_entity",
|
arrow = "mcl_bows:arrow_entity",
|
||||||
shoot_arrow = function(self, pos, dir)
|
shoot_arrow = function(self, pos, dir)
|
||||||
if mod_bows then
|
if mod_bows then
|
||||||
-- 2-4 damage per arrow
|
-- 2-4 damage per arrow
|
||||||
local dmg = math.random(2,4)
|
local dmg = math.max(4, math.random(2, 8))
|
||||||
mobs.shoot_projectile_handling("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
|
mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
shoot_interval = 2,
|
shoot_interval = 2,
|
||||||
|
@ -120,7 +102,7 @@ local skeleton = {
|
||||||
harmed_by_heal = true,
|
harmed_by_heal = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:skeleton", skeleton)
|
mcl_mobs:register_mob("mobs_mc:skeleton", skeleton)
|
||||||
|
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
|
@ -157,10 +139,10 @@ table.insert(stray.drops, {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:stray", stray)
|
mcl_mobs:register_mob("mobs_mc:stray", stray)
|
||||||
|
|
||||||
-- Overworld spawn
|
-- Overworld spawn
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:skeleton",
|
"mobs_mc:skeleton",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -310,29 +292,29 @@ mobs:spawn_specific(
|
||||||
20,
|
20,
|
||||||
17000,
|
17000,
|
||||||
2,
|
2,
|
||||||
mobs_mc.spawn_height.overworld_min,
|
mcl_vars.mg_overworld_min,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
|
|
||||||
-- Nether spawn
|
-- Nether spawn
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:skeleton",
|
"mobs_mc:skeleton",
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"SoulsandValley",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
7,
|
minetest.LIGHT_MAX+1,
|
||||||
30,
|
30,
|
||||||
10000,
|
10000,
|
||||||
3,
|
3,
|
||||||
mobs_mc.spawn_height.nether_min,
|
mcl_vars.mg_nether_min,
|
||||||
mobs_mc.spawn_height.nether_max)
|
mcl_vars.mg_nether_max)
|
||||||
|
|
||||||
-- Stray spawn
|
-- Stray spawn
|
||||||
-- TODO: Spawn directly under the sky
|
-- TODO: Spawn directly under the sky
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:stray",
|
"mobs_mc:stray",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -347,10 +329,10 @@ mobs:spawn_specific(
|
||||||
20,
|
20,
|
||||||
19000,
|
19000,
|
||||||
2,
|
2,
|
||||||
mobs_mc.spawn_height.water,
|
mobs_mc.water_level,
|
||||||
mobs_mc.spawn_height.overworld_max)
|
mcl_vars.mg_overworld_max)
|
||||||
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:skeleton", S("Skeleton"), "mobs_mc_spawn_icon_skeleton.png", 0)
|
mcl_mobs:register_egg("mobs_mc:skeleton", S("Skeleton"), "mobs_mc_spawn_icon_skeleton.png", 0)
|
||||||
mobs:register_egg("mobs_mc:stray", S("Stray"), "mobs_mc_spawn_icon_stray.png", 0)
|
mcl_mobs:register_egg("mobs_mc:stray", S("Stray"), "mobs_mc_spawn_icon_stray.png", 0)
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
--###################
|
--###################
|
||||||
--################### WITHER SKELETON
|
--################### WITHER SKELETON
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:witherskeleton", {
|
mcl_mobs:register_mob("mobs_mc:witherskeleton", {
|
||||||
description = S("Wither Skeleton"),
|
description = S("Wither Skeleton"),
|
||||||
type = "monster",
|
type = "monster",
|
||||||
spawn_class = "hostile",
|
spawn_class = "hostile",
|
||||||
|
@ -44,19 +44,19 @@ mobs:register_mob("mobs_mc:witherskeleton", {
|
||||||
damage = 7,
|
damage = 7,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.coal,
|
{name = "mcl_core:coal_lump",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 1,
|
max = 1,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
{name = mobs_mc.items.bone,
|
{name = "mcl_mobitems:bone",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,
|
max = 2,
|
||||||
looting = "common",},
|
looting = "common",},
|
||||||
|
|
||||||
-- Head
|
-- Head
|
||||||
{name = mobs_mc.items.head_wither_skeleton,
|
{name = "mcl_heads:wither_skeleton",
|
||||||
chance = 40, -- 2.5% chance
|
chance = 40, -- 2.5% chance
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,
|
max = 1,
|
||||||
|
@ -87,7 +87,7 @@ mobs:register_mob("mobs_mc:witherskeleton", {
|
||||||
fire_damage = 0,
|
fire_damage = 0,
|
||||||
light_damage = 0,
|
light_damage = 0,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
attack_type = "punch",
|
attack_type = "dogfight",
|
||||||
dogshoot_switch = 1,
|
dogshoot_switch = 1,
|
||||||
dogshoot_count_max =0.5,
|
dogshoot_count_max =0.5,
|
||||||
fear_height = 4,
|
fear_height = 4,
|
||||||
|
@ -96,7 +96,7 @@ mobs:register_mob("mobs_mc:witherskeleton", {
|
||||||
})
|
})
|
||||||
|
|
||||||
--spawn
|
--spawn
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:witherskeleton",
|
"mobs_mc:witherskeleton",
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -108,8 +108,8 @@ mobs:spawn_specific(
|
||||||
30,
|
30,
|
||||||
5000,
|
5000,
|
||||||
5,
|
5,
|
||||||
mobs_mc.spawn_height.nether_min,
|
mcl_vars.mg_nether_min,
|
||||||
mobs_mc.spawn_height.nether_max)
|
mcl_vars.mg_nether_max)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)
|
mcl_mobs:register_egg("mobs_mc:witherskeleton", S("Wither Skeleton"), "mobs_mc_spawn_icon_witherskeleton.png", 0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
-- Returns a function that spawns children in a circle around pos.
|
-- Returns a function that spawns children in a circle around pos.
|
||||||
-- To be used as on_die callback.
|
-- To be used as on_die callback.
|
||||||
|
@ -16,7 +16,8 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
|
||||||
if not eject_speed then
|
if not eject_speed then
|
||||||
eject_speed = 1
|
eject_speed = 1
|
||||||
end
|
end
|
||||||
local mother_stuck = minetest.registered_nodes[minetest.get_node(pos).name].walkable
|
local mndef = minetest.registered_nodes[minetest.get_node(pos).name]
|
||||||
|
local mother_stuck = mndef and mndef.walkable
|
||||||
angle = math.random(0, math.pi*2)
|
angle = math.random(0, math.pi*2)
|
||||||
local children = {}
|
local children = {}
|
||||||
for i=1,children_count do
|
for i=1,children_count do
|
||||||
|
@ -26,27 +27,26 @@ local spawn_children_on_die = function(child_mob, children_count, spawn_distance
|
||||||
-- If child would end up in a wall, use position of the "mother", unless
|
-- If child would end up in a wall, use position of the "mother", unless
|
||||||
-- the "mother" was stuck as well
|
-- the "mother" was stuck as well
|
||||||
local speed_penalty = 1
|
local speed_penalty = 1
|
||||||
if (not mother_stuck) and minetest.registered_nodes[minetest.get_node(newpos).name].walkable then
|
local cndef = minetest.registered_nodes[minetest.get_node(newpos).name]
|
||||||
|
if (not mother_stuck) and cndef and cndef.walkable then
|
||||||
newpos = pos
|
newpos = pos
|
||||||
speed_penalty = 0.5
|
speed_penalty = 0.5
|
||||||
end
|
end
|
||||||
local mob = minetest.add_entity(newpos, child_mob)
|
local mob = minetest.add_entity(newpos, child_mob)
|
||||||
if mob then
|
if (not mother_stuck) then
|
||||||
if (not mother_stuck) then
|
mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty))
|
||||||
mob:set_velocity(vector.multiply(dir, eject_speed * speed_penalty))
|
|
||||||
end
|
|
||||||
mob:set_yaw(angle - math.pi/2)
|
|
||||||
table.insert(children, mob)
|
|
||||||
angle = angle + (math.pi*2)/children_count
|
|
||||||
end
|
end
|
||||||
|
mob:set_yaw(angle - math.pi/2)
|
||||||
|
table.insert(children, mob)
|
||||||
|
angle = angle + (math.pi*2)/children_count
|
||||||
end
|
end
|
||||||
-- If mother was murdered, children attack the killer after 1 second
|
-- If mother was murdered, children attack the killer after 1 second
|
||||||
if self.state == "attack" then
|
if self.state == "attack" then
|
||||||
minetest.after(1.0, function(children, enemy)
|
minetest.after(1.0, function(children, enemy)
|
||||||
for c = 1, #children do
|
for c=1, #children do
|
||||||
local child = children[c]
|
local child = children[c]
|
||||||
local le = child:get_luaentity()
|
local le = child:get_luaentity()
|
||||||
if le then
|
if le ~= nil then
|
||||||
le.state = "attack"
|
le.state = "attack"
|
||||||
le.attack = enemy
|
le.attack = enemy
|
||||||
end
|
end
|
||||||
|
@ -66,7 +66,6 @@ local slime_big = {
|
||||||
hp_max = 16,
|
hp_max = 16,
|
||||||
xp_min = 4,
|
xp_min = 4,
|
||||||
xp_max = 4,
|
xp_max = 4,
|
||||||
rotate = 270,
|
|
||||||
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
|
collisionbox = {-1.02, -0.01, -1.02, 1.02, 2.03, 1.02},
|
||||||
visual_size = {x=12.5, y=12.5},
|
visual_size = {x=12.5, y=12.5},
|
||||||
textures = {{"mobs_mc_slime.png", "mobs_mc_slime.png"}},
|
textures = {{"mobs_mc_slime.png", "mobs_mc_slime.png"}},
|
||||||
|
@ -98,9 +97,8 @@ local slime_big = {
|
||||||
},
|
},
|
||||||
fall_damage = 0,
|
fall_damage = 0,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
attack_type = "jump_punch",
|
attack_type = "dogfight",
|
||||||
passive = false,
|
passive = false,
|
||||||
jump_only = true,
|
|
||||||
jump = true,
|
jump = true,
|
||||||
walk_velocity = 2.5,
|
walk_velocity = 2.5,
|
||||||
run_velocity = 2.5,
|
run_velocity = 2.5,
|
||||||
|
@ -111,7 +109,7 @@ local slime_big = {
|
||||||
on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5),
|
on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5),
|
||||||
use_texture_alpha = true,
|
use_texture_alpha = true,
|
||||||
}
|
}
|
||||||
mobs:register_mob("mobs_mc:slime_big", slime_big)
|
mcl_mobs:register_mob("mobs_mc:slime_big", slime_big)
|
||||||
|
|
||||||
local slime_small = table.copy(slime_big)
|
local slime_small = table.copy(slime_big)
|
||||||
slime_small.sounds.base_pitch = 1.15
|
slime_small.sounds.base_pitch = 1.15
|
||||||
|
@ -128,7 +126,7 @@ slime_small.run_velocity = 1.3
|
||||||
slime_small.jump_height = 4.3
|
slime_small.jump_height = 4.3
|
||||||
slime_small.spawn_small_alternative = "mobs_mc:slime_tiny"
|
slime_small.spawn_small_alternative = "mobs_mc:slime_tiny"
|
||||||
slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 4, 0.6, 1.0)
|
slime_small.on_die = spawn_children_on_die("mobs_mc:slime_tiny", 4, 0.6, 1.0)
|
||||||
mobs:register_mob("mobs_mc:slime_small", slime_small)
|
mcl_mobs:register_mob("mobs_mc:slime_small", slime_small)
|
||||||
|
|
||||||
local slime_tiny = table.copy(slime_big)
|
local slime_tiny = table.copy(slime_big)
|
||||||
slime_tiny.sounds.base_pitch = 1.3
|
slime_tiny.sounds.base_pitch = 1.3
|
||||||
|
@ -142,7 +140,7 @@ slime_tiny.damage = 0
|
||||||
slime_tiny.reach = 2.5
|
slime_tiny.reach = 2.5
|
||||||
slime_tiny.drops = {
|
slime_tiny.drops = {
|
||||||
-- slimeball
|
-- slimeball
|
||||||
{name = mobs_mc.items.slimeball,
|
{name = "mcl_mobitems:slimeball",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 0,
|
min = 0,
|
||||||
max = 2,},
|
max = 2,},
|
||||||
|
@ -153,12 +151,12 @@ slime_tiny.jump_height = 3
|
||||||
slime_tiny.spawn_small_alternative = nil
|
slime_tiny.spawn_small_alternative = nil
|
||||||
slime_tiny.on_die = nil
|
slime_tiny.on_die = nil
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:slime_tiny", slime_tiny)
|
mcl_mobs:register_mob("mobs_mc:slime_tiny", slime_tiny)
|
||||||
|
|
||||||
local smin = mobs_mc.spawn_height.overworld_min
|
local smin = mcl_vars.mg_overworld_min
|
||||||
local smax = mobs_mc.spawn_height.water - 23
|
local smax = mobs_mc.water_level - 23
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:slime_tiny",
|
"mobs_mc:slime_tiny",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -202,7 +200,7 @@ minetest.LIGHT_MAX+1,
|
||||||
smin,
|
smin,
|
||||||
smax)
|
smax)
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:slime_small",
|
"mobs_mc:slime_small",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -246,7 +244,7 @@ minetest.LIGHT_MAX+1,
|
||||||
smin,
|
smin,
|
||||||
smax)
|
smax)
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:slime_big",
|
"mobs_mc:slime_big",
|
||||||
"overworld",
|
"overworld",
|
||||||
"ground",
|
"ground",
|
||||||
|
@ -313,12 +311,11 @@ local magma_cube_big = {
|
||||||
},
|
},
|
||||||
walk_velocity = 4,
|
walk_velocity = 4,
|
||||||
run_velocity = 4,
|
run_velocity = 4,
|
||||||
rotate = 270,
|
|
||||||
damage = 6,
|
damage = 6,
|
||||||
reach = 3,
|
reach = 3,
|
||||||
armor = 53,
|
armor = 53,
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.magma_cream,
|
{name = "mcl_mobitems:magma_cream",
|
||||||
chance = 4,
|
chance = 4,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 1,},
|
max = 1,},
|
||||||
|
@ -337,13 +334,12 @@ local magma_cube_big = {
|
||||||
},
|
},
|
||||||
water_damage = 0,
|
water_damage = 0,
|
||||||
lava_damage = 0,
|
lava_damage = 0,
|
||||||
fire_damage = 0,
|
fire_damage = 0,
|
||||||
light_damage = 0,
|
light_damage = 0,
|
||||||
fall_damage = 0,
|
fall_damage = 0,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
attack_type = "jump_punch",
|
attack_type = "dogfight",
|
||||||
passive = false,
|
passive = false,
|
||||||
jump_only = true,
|
|
||||||
jump = true,
|
jump = true,
|
||||||
jump_height = 8,
|
jump_height = 8,
|
||||||
walk_chance = 0,
|
walk_chance = 0,
|
||||||
|
@ -352,7 +348,7 @@ local magma_cube_big = {
|
||||||
on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 3, 0.8, 1.5),
|
on_die = spawn_children_on_die("mobs_mc:magma_cube_small", 3, 0.8, 1.5),
|
||||||
fire_resistant = true,
|
fire_resistant = true,
|
||||||
}
|
}
|
||||||
mobs:register_mob("mobs_mc:magma_cube_big", magma_cube_big)
|
mcl_mobs:register_mob("mobs_mc:magma_cube_big", magma_cube_big)
|
||||||
|
|
||||||
local magma_cube_small = table.copy(magma_cube_big)
|
local magma_cube_small = table.copy(magma_cube_big)
|
||||||
magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small"
|
magma_cube_small.sounds.jump = "mobs_mc_magma_cube_small"
|
||||||
|
@ -373,7 +369,7 @@ magma_cube_small.reach = 2.75
|
||||||
magma_cube_small.armor = 66
|
magma_cube_small.armor = 66
|
||||||
magma_cube_small.spawn_small_alternative = "mobs_mc:magma_cube_tiny"
|
magma_cube_small.spawn_small_alternative = "mobs_mc:magma_cube_tiny"
|
||||||
magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 4, 0.6, 1.0)
|
magma_cube_small.on_die = spawn_children_on_die("mobs_mc:magma_cube_tiny", 4, 0.6, 1.0)
|
||||||
mobs:register_mob("mobs_mc:magma_cube_small", magma_cube_small)
|
mcl_mobs:register_mob("mobs_mc:magma_cube_small", magma_cube_small)
|
||||||
|
|
||||||
local magma_cube_tiny = table.copy(magma_cube_big)
|
local magma_cube_tiny = table.copy(magma_cube_big)
|
||||||
magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small"
|
magma_cube_tiny.sounds.jump = "mobs_mc_magma_cube_small"
|
||||||
|
@ -395,18 +391,19 @@ magma_cube_tiny.drops = {}
|
||||||
magma_cube_tiny.spawn_small_alternative = nil
|
magma_cube_tiny.spawn_small_alternative = nil
|
||||||
magma_cube_tiny.on_die = nil
|
magma_cube_tiny.on_die = nil
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny)
|
mcl_mobs:register_mob("mobs_mc:magma_cube_tiny", magma_cube_tiny)
|
||||||
|
|
||||||
|
|
||||||
local mmin = mobs_mc.spawn_height.nether_min
|
local mmin = mcl_vars.mg_nether_min
|
||||||
local mmax = mobs_mc.spawn_height.nether_max
|
local mmax = mcl_vars.mg_nether_max
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:magma_cube_tiny",
|
"mobs_mc:magma_cube_tiny",
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -417,12 +414,13 @@ mmin,
|
||||||
mmax)
|
mmax)
|
||||||
|
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:magma_cube_small",
|
"mobs_mc:magma_cube_small",
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -432,12 +430,13 @@ minetest.LIGHT_MAX+1,
|
||||||
mmin,
|
mmin,
|
||||||
mmax)
|
mmax)
|
||||||
|
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:magma_cube_big",
|
"mobs_mc:magma_cube_big",
|
||||||
"nether",
|
"nether",
|
||||||
"ground",
|
"ground",
|
||||||
{
|
{
|
||||||
"Nether"
|
"Nether",
|
||||||
|
"BasaltDelta",
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
minetest.LIGHT_MAX+1,
|
minetest.LIGHT_MAX+1,
|
||||||
|
@ -447,11 +446,11 @@ minetest.LIGHT_MAX+1,
|
||||||
mmin,
|
mmin,
|
||||||
mmax)
|
mmax)
|
||||||
|
|
||||||
--mobs:spawn_specific("mobs_mc:magma_cube_tiny", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
|
--mcl_mobs:spawn_specific("mobs_mc:magma_cube_tiny", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11000, 4, mmin, mmax)
|
||||||
--mobs:spawn_specific("mobs_mc:magma_cube_small", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
|
--mcl_mobs:spawn_specific("mobs_mc:magma_cube_small", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11100, 4, mmin, mmax)
|
||||||
--mobs:spawn_specific("mobs_mc:magma_cube_big", mobs_mc.spawn.nether_fortress, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
|
--mcl_mobs:spawn_specific("mobs_mc:magma_cube_big", { "mcl_nether:nether_brick", "mcl_nether:netherrack" }, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 11200, 4, mmin, mmax)
|
||||||
|
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "mobs_mc_spawn_icon_magmacube.png")
|
mcl_mobs:register_egg("mobs_mc:magma_cube_big", S("Magma Cube"), "mobs_mc_spawn_icon_magmacube.png")
|
||||||
mobs:register_egg("mobs_mc:slime_big", S("Slime"), "mobs_mc_spawn_icon_slime.png")
|
mcl_mobs:register_egg("mobs_mc:slime_big", S("Slime"), "mobs_mc_spawn_icon_slime.png")
|
||||||
|
|
|
@ -3,12 +3,12 @@
|
||||||
--made for MC like Survival game
|
--made for MC like Survival game
|
||||||
--License for code WTFPL and otherwise stated in readmes
|
--License for code WTFPL and otherwise stated in readmes
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
local snow_trail_frequency = 0.5 -- Time in seconds for checking to add a new snow trail
|
local snow_trail_frequency = 0.5 -- Time in seconds for checking to add a new snow trail
|
||||||
|
|
||||||
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
|
||||||
local mod_throwing = minetest.get_modpath("mcl_throwing")
|
local mod_throwing = minetest.get_modpath("mcl_throwing") ~= nil
|
||||||
|
|
||||||
local gotten_texture = {
|
local gotten_texture = {
|
||||||
"mobs_mc_snowman.png",
|
"mobs_mc_snowman.png",
|
||||||
|
@ -20,7 +20,7 @@ local gotten_texture = {
|
||||||
"blank.png",
|
"blank.png",
|
||||||
}
|
}
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:snowman", {
|
mcl_mobs:register_mob("mobs_mc:snowman", {
|
||||||
description = S("Snow Golem"),
|
description = S("Snow Golem"),
|
||||||
type = "npc",
|
type = "npc",
|
||||||
spawn_class = "passive",
|
spawn_class = "passive",
|
||||||
|
@ -54,7 +54,7 @@ mobs:register_mob("mobs_mc:snowman", {
|
||||||
"farming_pumpkin_top.png", --left
|
"farming_pumpkin_top.png", --left
|
||||||
},
|
},
|
||||||
gotten_texture = gotten_texture,
|
gotten_texture = gotten_texture,
|
||||||
drops = {{ name = mobs_mc.items.snowball, chance = 1, min = 0, max = 15 }},
|
drops = {{ name = "mcl_throwing:snowball", chance = 1, min = 0, max = 15 }},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
walk_velocity = 0.6,
|
walk_velocity = 0.6,
|
||||||
run_velocity = 2,
|
run_velocity = 2,
|
||||||
|
@ -108,7 +108,7 @@ mobs:register_mob("mobs_mc:snowman", {
|
||||||
local belowdef = minetest.registered_nodes[minetest.get_node(below).name]
|
local belowdef = minetest.registered_nodes[minetest.get_node(below).name]
|
||||||
if belowdef and belowdef.walkable and (belowdef.node_box == nil or belowdef.node_box.type == "regular") then
|
if belowdef and belowdef.walkable and (belowdef.node_box == nil or belowdef.node_box.type == "regular") then
|
||||||
-- Place top snow
|
-- Place top snow
|
||||||
minetest.set_node(pos, {name = mobs_mc.items.top_snow})
|
minetest.set_node(pos, {name = "mcl_core:snow"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -116,7 +116,7 @@ mobs:register_mob("mobs_mc:snowman", {
|
||||||
-- Remove pumpkin if using shears
|
-- Remove pumpkin if using shears
|
||||||
on_rightclick = function(self, clicker)
|
on_rightclick = function(self, clicker)
|
||||||
local item = clicker:get_wielded_item()
|
local item = clicker:get_wielded_item()
|
||||||
if self.gotten ~= true and item:get_name() == mobs_mc.items.shears then
|
if self.gotten ~= true and item:get_name() == "mcl_tools:shears" then
|
||||||
-- Remove pumpkin
|
-- Remove pumpkin
|
||||||
self.gotten = true
|
self.gotten = true
|
||||||
self.object:set_properties({
|
self.object:set_properties({
|
||||||
|
@ -126,9 +126,13 @@ mobs:register_mob("mobs_mc:snowman", {
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
|
minetest.sound_play("mcl_tools_shears_cut", {pos = pos}, true)
|
||||||
|
|
||||||
|
if minetest.registered_items["mcl_farming:pumpkin_face"] then
|
||||||
|
minetest.add_item({x=pos.x, y=pos.y+1.4, z=pos.z}, "mcl_farming:pumpkin_face")
|
||||||
|
end
|
||||||
|
|
||||||
-- Wear out
|
-- Wear out
|
||||||
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
if not minetest.is_creative_enabled(clicker:get_player_name()) then
|
||||||
item:add_wear(mobs_mc.misc.shears_wear)
|
item:add_wear(mobs_mc.shears_wear)
|
||||||
clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
|
clicker:get_inventory():set_stack("main", clicker:get_wield_index(), item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -158,7 +162,7 @@ end
|
||||||
-- This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function
|
-- This is to be called when a pumpkin or jack'o lantern has been placed. Recommended: In the on_construct function
|
||||||
-- of the node.
|
-- of the node.
|
||||||
-- This summons a snow golen when pos is next to a row of two snow blocks.
|
-- This summons a snow golen when pos is next to a row of two snow blocks.
|
||||||
mobs_mc.tools.check_snow_golem_summon = function(pos)
|
function mobs_mc.check_snow_golem_summon(pos)
|
||||||
local checks = {
|
local checks = {
|
||||||
-- These are the possible placement patterns
|
-- These are the possible placement patterns
|
||||||
-- { snow block pos. 1, snow block pos. 2, snow golem spawn position }
|
-- { snow block pos. 1, snow block pos. 2, snow golem spawn position }
|
||||||
|
@ -176,14 +180,14 @@ mobs_mc.tools.check_snow_golem_summon = function(pos)
|
||||||
local place = checks[c][3]
|
local place = checks[c][3]
|
||||||
local b1n = minetest.get_node(b1)
|
local b1n = minetest.get_node(b1)
|
||||||
local b2n = minetest.get_node(b2)
|
local b2n = minetest.get_node(b2)
|
||||||
if b1n.name == mobs_mc.items.snow_block and b2n.name == mobs_mc.items.snow_block then
|
if b1n.name == "mcl_core:snowblock" and b2n.name == "mcl_core:snowblock" then
|
||||||
-- Remove the pumpkin and both snow blocks and summon the snow golem
|
-- Remove the pumpkin and both snow blocks and summon the snow golem
|
||||||
minetest.remove_node(pos)
|
minetest.remove_node(pos)
|
||||||
minetest.remove_node(b1)
|
minetest.remove_node(b1)
|
||||||
minetest.remove_node(b2)
|
minetest.remove_node(b2)
|
||||||
minetest.check_for_falling(pos)
|
core.check_for_falling(pos)
|
||||||
minetest.check_for_falling(b1)
|
core.check_for_falling(b1)
|
||||||
minetest.check_for_falling(b2)
|
core.check_for_falling(b2)
|
||||||
local obj = minetest.add_entity(place, "mobs_mc:snowman")
|
local obj = minetest.add_entity(place, "mobs_mc:snowman")
|
||||||
if obj then
|
if obj then
|
||||||
summon_particles(obj)
|
summon_particles(obj)
|
||||||
|
@ -194,4 +198,4 @@ mobs_mc.tools.check_snow_golem_summon = function(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Spawn egg
|
-- Spawn egg
|
||||||
mobs:register_egg("mobs_mc:snowman", S("Snow Golem"), "mobs_mc_spawn_icon_snowman.png", 0)
|
mcl_mobs:register_egg("mobs_mc:snowman", S("Snow Golem"), "mobs_mc_spawn_icon_snowman.png", 0)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -4,9 +4,9 @@
|
||||||
--################### SQUID
|
--################### SQUID
|
||||||
--###################
|
--###################
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator("mobs_mc")
|
||||||
|
|
||||||
mobs:register_mob("mobs_mc:squid", {
|
mcl_mobs:register_mob("mobs_mc:squid", {
|
||||||
description = S("Squid"),
|
description = S("Squid"),
|
||||||
type = "animal",
|
type = "animal",
|
||||||
spawn_class = "water",
|
spawn_class = "water",
|
||||||
|
@ -17,8 +17,6 @@ mobs:register_mob("mobs_mc:squid", {
|
||||||
xp_min = 1,
|
xp_min = 1,
|
||||||
xp_max = 3,
|
xp_max = 3,
|
||||||
armor = 100,
|
armor = 100,
|
||||||
rotate = 270,
|
|
||||||
tilt_swim = true,
|
|
||||||
-- FIXME: If the squid is near the floor, it turns black
|
-- FIXME: If the squid is near the floor, it turns black
|
||||||
collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.9, 0.4},
|
collisionbox = {-0.4, 0.0, -0.4, 0.4, 0.9, 0.4},
|
||||||
visual = "mesh",
|
visual = "mesh",
|
||||||
|
@ -42,7 +40,7 @@ mobs:register_mob("mobs_mc:squid", {
|
||||||
run_end = 60,
|
run_end = 60,
|
||||||
},
|
},
|
||||||
drops = {
|
drops = {
|
||||||
{name = mobs_mc.items.black_dye,
|
{name = "mcl_dye:black",
|
||||||
chance = 1,
|
chance = 1,
|
||||||
min = 1,
|
min = 1,
|
||||||
max = 3,
|
max = 3,
|
||||||
|
@ -50,7 +48,8 @@ mobs:register_mob("mobs_mc:squid", {
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=3, y=3},
|
||||||
makes_footstep_sound = false,
|
makes_footstep_sound = false,
|
||||||
swim = true,
|
fly = true,
|
||||||
|
fly_in = { "mcl_core:water_source", "mclx_core:river_water_source" },
|
||||||
breathes_in_water = true,
|
breathes_in_water = true,
|
||||||
jump = false,
|
jump = false,
|
||||||
view_range = 16,
|
view_range = 16,
|
||||||
|
@ -62,9 +61,9 @@ mobs:register_mob("mobs_mc:squid", {
|
||||||
|
|
||||||
-- Spawn near the water surface
|
-- Spawn near the water surface
|
||||||
|
|
||||||
local water = mobs_mc.spawn_height.water
|
local water = mobs_mc.water_level
|
||||||
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
|
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
|
||||||
mobs:spawn_specific(
|
mcl_mobs:spawn_specific(
|
||||||
"mobs_mc:squid",
|
"mobs_mc:squid",
|
||||||
"overworld",
|
"overworld",
|
||||||
"water",
|
"water",
|
||||||
|
@ -218,4 +217,4 @@ water-16,
|
||||||
water+1)
|
water+1)
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0)
|
mcl_mobs:register_egg("mobs_mc:squid", S("Squid"), "mobs_mc_spawn_icon_squid.png", 0)
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 606 B After Width: | Height: | Size: 385 B |
Binary file not shown.
After Width: | Height: | Size: 99 B |
Binary file not shown.
Before Width: | Height: | Size: 20 KiB |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue