784 lines
21 KiB
JavaScript
784 lines
21 KiB
JavaScript
// Why are entity type tags so weird
|
|
global.checkEntityTag = (entity, checkedTag) => {
|
|
if (!entity || !entity.entityType || !entity.entityType.tags) return false;
|
|
return entity.entityType.tags.anyMatch((tag) => tag.location() == checkedTag);
|
|
};
|
|
|
|
global.isFresh = (day, actionAge) => {
|
|
return day < actionAge;
|
|
};
|
|
|
|
global.getAnimalIsNotCramped = (target, scale, applyGlowing) => {
|
|
const level = target.getLevel();
|
|
const entities = level
|
|
.getEntitiesWithin(target.boundingBox.inflate(scale))
|
|
.filter((e) => global.checkEntityTag(e, "society:husbandry_animal"));
|
|
let cramped = entities.length > 5
|
|
if (cramped && applyGlowing) {
|
|
entities.forEach((entity) => {
|
|
entity.potionEffects.add("minecraft:glowing", 200, 0, false, false);
|
|
})
|
|
}
|
|
return !cramped;
|
|
};
|
|
|
|
global.isWarpedCow = (target) => {
|
|
if (target.type === "meadow:wooly_cow") {
|
|
if (target.toString().includes("WoolyCowEntity")) return Number(target.getNbt().Variant) === 2
|
|
let variant = target.Variant
|
|
if (variant && Number(variant) === 2) return true;
|
|
}
|
|
return false;
|
|
}
|
|
global.getMilkingTimeMult = (target, type) => {
|
|
const warped = global.isWarpedCow(target);
|
|
let mult;
|
|
global.husbandryMilkingDefinitions.forEach((definition) => {
|
|
if (!mult && definition.animal.equals(type.toString())) {
|
|
if (warped && definition.warped) mult = definition.cooldown;
|
|
if (!warped) mult = definition.cooldown;
|
|
}
|
|
});
|
|
return mult;
|
|
};
|
|
|
|
global.getHusbandryQuality = (hearts, mood, milk) => {
|
|
let heartQuality = 0;
|
|
let moodQuality = 0;
|
|
if (hearts > 0) {
|
|
if (milk) {
|
|
if (hearts >= 10 || (hearts > 0 && hearts % 5 === 0)) {
|
|
heartQuality = 3;
|
|
} else {
|
|
heartQuality = Math.floor((hearts % 11) / 2 - 2);
|
|
}
|
|
} else {
|
|
if (hearts >= 10) {
|
|
heartQuality = 3;
|
|
} else {
|
|
heartQuality = Math.floor((hearts % 11) / 2 - 2);
|
|
}
|
|
}
|
|
}
|
|
if (mood > 224) moodQuality = 3;
|
|
else if (mood > 192) moodQuality = 2;
|
|
else if (mood > 160) moodQuality = 1;
|
|
return Math.min(moodQuality, heartQuality);
|
|
};
|
|
|
|
const resolveMilk = (hearts, mood, target, type) => {
|
|
let large = hearts > 5 && Math.random() < (mood + hearts * 10) / 256;
|
|
let milk;
|
|
const warped = global.isWarpedCow(target);
|
|
global.husbandryMilkingDefinitions.forEach((definition) => {
|
|
if (!milk && definition.animal.equals(type.toString())) {
|
|
if (warped && definition.warped)
|
|
milk = large ? definition.milk.lg : definition.milk.sm;
|
|
if (!warped) milk = large ? definition.milk.lg : definition.milk.sm;
|
|
}
|
|
});
|
|
return milk;
|
|
};
|
|
|
|
const canMilk = (data, target, day, plushieModifiers) => {
|
|
const ageLastMilked = data.getInt("ageLastMilked");
|
|
const dayHasPassed =
|
|
day > ageLastMilked + global.getMilkingTimeMult(target, target.type) - 1;
|
|
const freshAnimal = global.isFresh(day, ageLastMilked);
|
|
if (plushieModifiers) return freshAnimal || dayHasPassed;
|
|
const hungry = global.compareDay(day, data.getInt("ageLastFed"), 1)
|
|
return !target.isBaby() && !hungry && (freshAnimal || dayHasPassed);
|
|
};
|
|
|
|
/**
|
|
* @param {Internal.Player|null} player
|
|
* player.stages, or auto-grabber NBT stages, or empty stages for mana milker
|
|
* @param {Internal.Stages|SocietyStages} stages
|
|
*/
|
|
global.getMilk = (
|
|
level,
|
|
target,
|
|
data,
|
|
player,
|
|
day,
|
|
raiseAffection,
|
|
plushieModifiers,
|
|
stages
|
|
) => {
|
|
const crackerBonus = data.animalCracker ? 2 : 1;
|
|
let affection;
|
|
let mood;
|
|
let affectionIncrease = 0;
|
|
if (plushieModifiers) {
|
|
affection = 1000;
|
|
mood = 256;
|
|
} else {
|
|
affection = data.getInt("affection") || 0;
|
|
mood = global.getOrFetchMood(level, target, day, player);
|
|
affectionIncrease = stages.has("animal_whisperer") || data.bribed ? 10 : 5;
|
|
}
|
|
let hearts = Math.floor(affection / 100);
|
|
|
|
let quality = 0;
|
|
if (canMilk(data, target, day, plushieModifiers)) {
|
|
const plushieDoubleDrops = plushieModifiers && plushieModifiers.doubleDrops;
|
|
const plushieProcessItems =
|
|
plushieModifiers && plushieModifiers.processItems;
|
|
if (raiseAffection) data.affection = affection + affectionIncrease;
|
|
if (!plushieModifiers) data.ageLastMilked = day;
|
|
if (mood >= 160) {
|
|
quality = global.getHusbandryQuality(hearts, mood, true);
|
|
}
|
|
let milkId = resolveMilk(hearts, mood, target, target.type);
|
|
if (milkId == "species:ichor_bottle" && hearts >= 5) quality = 3;
|
|
if (plushieProcessItems) {
|
|
let cheesePressOutput = global.cheesePressRecipes.get(milkId);
|
|
if (cheesePressOutput) {
|
|
milkId = Item.of(cheesePressOutput.output[0]).id;
|
|
}
|
|
}
|
|
return Item.of(
|
|
`${(stages.has("shepherd") ? 2 : 1) *
|
|
crackerBonus *
|
|
(plushieDoubleDrops ? 2 : 1)
|
|
}x ${milkId}`,
|
|
quality > 0 ? `{quality_food:{effects:[],quality:${quality}}}` : null
|
|
);
|
|
}
|
|
return -1;
|
|
};
|
|
|
|
/**
|
|
* @param {Internal.Player|null} player
|
|
* @param {Internal.Stages|SocietyStages} stages player.stages or auto-grabber NBT stages
|
|
*/
|
|
global.handleSpecialHarvest = (
|
|
level,
|
|
target,
|
|
player,
|
|
server,
|
|
block,
|
|
inventory,
|
|
plushieModifiers,
|
|
harvestFunction,
|
|
stages
|
|
) => {
|
|
const day = global.getDay(level);
|
|
const data = plushieModifiers ? target : target.persistentData;
|
|
const ageLastFed = plushieModifiers ? -1 : data.getInt("ageLastFed");
|
|
const ageLastDroppedSpecial = data.getInt("ageLastDroppedSpecial") || 0;
|
|
const type = target.type;
|
|
const freshAnimal = global.isFresh(day, ageLastDroppedSpecial);
|
|
const hungry = global.compareDay(day, ageLastFed, 1)
|
|
const crackerBonus = data.animalCracker ? 2 : 1;
|
|
if (freshAnimal || day > ageLastDroppedSpecial) {
|
|
let resolvedCount;
|
|
let resolvedItem;
|
|
global.husbandryForagingDefinitions.forEach((definition) => {
|
|
if (definition.animal.equals(type)) {
|
|
definition.forages.forEach((forage) => {
|
|
resolvedCount = forage.countMult;
|
|
if (forage.stage && stages.has(forage.stage.name)) {
|
|
resolvedCount = forage.stage.newCountMult;
|
|
}
|
|
if (forage.itemPool) {
|
|
resolvedItem =
|
|
forage.itemPool[
|
|
Math.floor(Math.random() * forage.itemPool.length)
|
|
];
|
|
} else {
|
|
resolvedItem = forage.item;
|
|
}
|
|
harvestFunction(
|
|
data,
|
|
day,
|
|
forage.chance,
|
|
hungry,
|
|
forage.minHearts,
|
|
resolvedCount * crackerBonus,
|
|
resolvedItem,
|
|
forage.hasQuality,
|
|
plushieModifiers,
|
|
{
|
|
level: level,
|
|
target: target,
|
|
player: player,
|
|
server: server,
|
|
block: block,
|
|
inventory: inventory,
|
|
}
|
|
);
|
|
});
|
|
}
|
|
});
|
|
if (
|
|
stages.has("coopmaster") &&
|
|
(plushieModifiers
|
|
? global.coopMasterAnimals.includes(data.type)
|
|
: global.checkEntityTag(target, "society:coopmaster_bird"))
|
|
) {
|
|
harvestFunction(
|
|
data,
|
|
day,
|
|
0.02,
|
|
hungry,
|
|
1,
|
|
1 * crackerBonus,
|
|
"vintagedelight:golden_egg",
|
|
true,
|
|
plushieModifiers,
|
|
{
|
|
level: level,
|
|
target: target,
|
|
player: player,
|
|
server: server,
|
|
block: block,
|
|
inventory: inventory,
|
|
}
|
|
);
|
|
}
|
|
if (data.bff && stages.has("bff")) {
|
|
harvestFunction(
|
|
data,
|
|
day,
|
|
0.1,
|
|
hungry,
|
|
10,
|
|
1 * crackerBonus,
|
|
"society:prismatic_shard",
|
|
false,
|
|
plushieModifiers,
|
|
{
|
|
level: level,
|
|
target: target,
|
|
player: player,
|
|
server: server,
|
|
block: block,
|
|
inventory: inventory,
|
|
}
|
|
);
|
|
}
|
|
if (player && !player.isFake() && !stages.has("animal_fancy")) {
|
|
harvestFunction(
|
|
data,
|
|
day,
|
|
0.05,
|
|
hungry,
|
|
4,
|
|
1,
|
|
"society:animal_fancy",
|
|
false,
|
|
plushieModifiers,
|
|
{
|
|
level: level,
|
|
target: target,
|
|
player: player,
|
|
server: server,
|
|
block: block,
|
|
inventory: inventory,
|
|
}
|
|
);
|
|
}
|
|
if (stages.has("reaping_scythe")) {
|
|
harvestFunction(
|
|
data,
|
|
day,
|
|
0.1,
|
|
hungry,
|
|
1,
|
|
1 * crackerBonus,
|
|
"quark:diamond_heart",
|
|
false,
|
|
plushieModifiers,
|
|
{
|
|
level: level,
|
|
target: target,
|
|
player: player,
|
|
server: server,
|
|
block: block,
|
|
inventory: inventory,
|
|
}
|
|
);
|
|
}
|
|
if (
|
|
plushieModifiers &&
|
|
plushieModifiers.newDrops &&
|
|
plushieModifiers.newDrops.length > 0
|
|
) {
|
|
plushieModifiers.newDrops.forEach((drop) => {
|
|
harvestFunction(
|
|
data,
|
|
day,
|
|
1,
|
|
hungry,
|
|
1,
|
|
drop.count * crackerBonus,
|
|
drop.id,
|
|
false,
|
|
plushieModifiers,
|
|
{
|
|
level: level,
|
|
target: target,
|
|
player: player,
|
|
server: server,
|
|
block: block,
|
|
inventory: inventory,
|
|
}
|
|
);
|
|
});
|
|
}
|
|
if (!plushieModifiers) data.ageLastDroppedSpecial = day;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* @param {Internal.Player|null} player
|
|
* player.stages, or auto grabber NBT stages, or empty stages for mana milker
|
|
* @param {Internal.Stages|SocietyStages} stages
|
|
*/
|
|
global.getMagicShearsOutput = (level, target, player, plushieModifiers, stages) => {
|
|
const day = global.getDay(level);
|
|
const data = plushieModifiers ? target : target.persistentData;
|
|
const ageLastMagicHarvested = data.getInt("ageLastMagicHarvested");
|
|
const freshAnimal = global.isFresh(day, ageLastMagicHarvested);
|
|
let affection;
|
|
let mood;
|
|
if (plushieModifiers) {
|
|
affection = 1000;
|
|
mood = 256;
|
|
} else {
|
|
affection = data.getInt("affection") || 0;
|
|
mood = global.getOrFetchMood(level, target, day, player);
|
|
}
|
|
|
|
let hearts = Math.floor((affection > 1000 ? 1000 : affection) / 100);
|
|
const targetId =
|
|
target.type === "meadow:wooly_cow"
|
|
? ["minecraft", "cow"]
|
|
: target.type.split(":");
|
|
const droppedLoot = Utils.rollChestLoot(
|
|
`${targetId[0]}:entities/${targetId[1]}`
|
|
).toArray();
|
|
let newLoot = [];
|
|
if (hearts >= 5 && (freshAnimal || day > ageLastMagicHarvested)) {
|
|
if (!plushieModifiers || !plushieModifiers.resetDay) {
|
|
data.ageLastMagicHarvested = day;
|
|
}
|
|
data.affection = affection - 7;
|
|
if (!plushieModifiers) {
|
|
level.spawnParticles(
|
|
"snowyspirit:glow_light",
|
|
true,
|
|
target.x,
|
|
target.y + 1.5,
|
|
target.z,
|
|
0.2 * rnd(1, 4),
|
|
0.2 * rnd(1, 4),
|
|
0.2 * rnd(1, 4),
|
|
20,
|
|
2
|
|
);
|
|
}
|
|
if (mood >= 160) {
|
|
let quality = global.getHusbandryQuality(hearts, mood);
|
|
for (let i = 0; i < droppedLoot.length; i++) {
|
|
droppedLoot[i] = Item.of(
|
|
droppedLoot[i].id,
|
|
`{quality_food:{effects:[],quality:${quality}}}`
|
|
);
|
|
}
|
|
}
|
|
if (stages.has("mana_hand")) {
|
|
let dropItem;
|
|
for (let i = 0; i < droppedLoot.length; i++) {
|
|
dropItem = droppedLoot[i];
|
|
if (dropItem.maxStackSize < dropItem.count * 2) {
|
|
newLoot.push(dropItem);
|
|
newLoot.push(dropItem);
|
|
} else {
|
|
dropItem.count = dropItem.count * 2;
|
|
newLoot.push(dropItem);
|
|
}
|
|
}
|
|
return newLoot;
|
|
}
|
|
for (let i = 0; i < droppedLoot.length; i++) {
|
|
newLoot.push(droppedLoot[i]);
|
|
}
|
|
if (stages.has("heretic")) {
|
|
newLoot.push(Item.of("3x society:sparkstone"));
|
|
if (!plushieModifiers) {
|
|
target.attack(2);
|
|
data.affection = affection - 20;
|
|
}
|
|
}
|
|
return newLoot;
|
|
} else return -1;
|
|
};
|
|
|
|
const getMoodImpactModifier = (target) => {
|
|
if (global.tierTwoHusbandryAnimals.includes(target.type)) return 1.25;
|
|
if (global.tierThreeHusbandryAnimals.includes(target.type)) return 1.5;
|
|
return 1;
|
|
};
|
|
|
|
const getNearbyBlocks = (level, target, radius, tag) => {
|
|
const { x, y, z } = target;
|
|
let blockCount = 0;
|
|
let scanBlock;
|
|
for (let pos of BlockPos.betweenClosed(
|
|
new BlockPos(x - radius, y - radius, z - radius),
|
|
[x + radius, y + radius, z + radius]
|
|
)) {
|
|
if (!level.isLoaded(pos)) continue;
|
|
scanBlock = level.getBlock(pos);
|
|
if (scanBlock.hasTag(tag)) {
|
|
blockCount++;
|
|
}
|
|
}
|
|
return blockCount;
|
|
};
|
|
|
|
|
|
/**
|
|
* @param {Internal.Player|null} player
|
|
*/
|
|
global.getOrFetchMood = (level, target, day, player, debugMood, disregardPet) => {
|
|
if (global.checkEntityTag(target, "society:pet_animal")) return 256;
|
|
const data = target.persistentData;
|
|
let moodDebuffs = 0;
|
|
let moodImpactModifier = getMoodImpactModifier(target);
|
|
if (!player && debugMood) {
|
|
console.log("getOrFetchMood: cannot debug mood because player is falsey!");
|
|
debugMood = false;
|
|
}
|
|
if (moodImpactModifier > 1 && debugMood) player.tell(Text.translatable("society.husbandry.mood.breed_impact", moodImpactModifier).gold());
|
|
if (!disregardPet && global.compareDay(day, data.getInt("ageLastPet"), 1)) {
|
|
moodDebuffs += 96;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.not_pet").red());
|
|
}
|
|
if (global.compareDay(day, data.getInt("ageLastFed"), 2)) {
|
|
moodDebuffs += 128;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.not_fed").red());
|
|
}
|
|
let requiredBlocks = 0;
|
|
if (global.coldMobs.includes(target.type)) {
|
|
requiredBlocks = getNearbyBlocks(level, target, 5, "society:cold_blocks");
|
|
if (requiredBlocks < 5) {
|
|
let coldDebuff = 32 - (32 * requiredBlocks) / 5
|
|
moodDebuffs += coldDebuff;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.not_cold", coldDebuff).red());
|
|
}
|
|
} else {
|
|
if (
|
|
global.getSeasonFromBiome(level, target.getPos()) === "winter" &&
|
|
level.canSeeSky(target.getPos())
|
|
) {
|
|
moodDebuffs += 32;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.too_cold").red());
|
|
}
|
|
}
|
|
if (!global.getAnimalIsNotCramped(target, 1.1, debugMood)) {
|
|
moodDebuffs += 96;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.cramped").red());
|
|
}
|
|
if (level.raining && level.canSeeSky(target.getPos())) {
|
|
moodDebuffs += 32;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.wet").red());
|
|
}
|
|
let baseDebuffs = moodDebuffs
|
|
moodDebuffs *= moodImpactModifier;
|
|
if (day - data.getInt("ageLastBoosted") == 1) {
|
|
moodDebuffs -= 24;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.boosted_food").green());
|
|
}
|
|
if (data.clockwork) {
|
|
moodDebuffs -= 64;
|
|
if (debugMood) player.tell(Text.translatable("society.husbandry.mood.clockwork").green());
|
|
}
|
|
if (debugMood) {
|
|
if (baseDebuffs > 0) player.tell(Text.translatable("society.husbandry.mood.total_debuffs", Number(baseDebuffs)).darkRed());
|
|
player.tell(Text.translatable("society.husbandry.mood.final_mood", Number(256 - moodDebuffs)).gray());
|
|
}
|
|
if (global.compareDay(day, data.getInt("ageLastSetMood"), 1)) {
|
|
data.lastMood = Math.max(0, 256 - moodDebuffs);
|
|
data.ageLastSetMood = day;
|
|
}
|
|
return data.lastMood;
|
|
};
|
|
/**
|
|
* Plushie Trait related drops and mechanics
|
|
*/
|
|
global.getPlushieModifiers = (level, data, plushieBlock) => {
|
|
let newDrops = [];
|
|
let doubleDrops = false;
|
|
let resetDay = false;
|
|
let qualityMult = data.quality + 1;
|
|
let probabilityIncrease = 0;
|
|
let processItems = false;
|
|
const roll = Math.random();
|
|
switch (data.type) {
|
|
case 0:
|
|
// Aquatic
|
|
if (roll < 0.05 * qualityMult) {
|
|
newDrops.push(
|
|
Item.of(rnd50() ? "society:river_jelly" : "society:ocean_jelly")
|
|
);
|
|
}
|
|
break;
|
|
case 1:
|
|
// Woodsy
|
|
let nearbyLogs = global.getTaggedBlocksInRadius(
|
|
level,
|
|
"society:raw_logs",
|
|
plushieBlock,
|
|
7,
|
|
true
|
|
);
|
|
if (nearbyLogs.length > 0) {
|
|
newDrops.push(
|
|
Item.of(
|
|
`${qualityMult * 8}x ${nearbyLogs[Math.floor(Math.random() * nearbyLogs.length)]
|
|
}`
|
|
)
|
|
);
|
|
}
|
|
break;
|
|
case 2:
|
|
// Eldritch
|
|
newDrops.push(Item.of(`${qualityMult}x oreganized:raw_silver`));
|
|
break;
|
|
case 3:
|
|
// Wrathful
|
|
newDrops.push(Item.of(`${qualityMult * 3}x oreganized:raw_lead`));
|
|
break;
|
|
case 4:
|
|
// Sommelier
|
|
if (roll < 0.25 * qualityMult) processItems = true;
|
|
break;
|
|
case 5:
|
|
// Sunlit
|
|
if (roll < (0.05 * qualityMult)) {
|
|
newDrops.push(Item.of("society:sunlit_crystal"));
|
|
}
|
|
break;
|
|
case 6:
|
|
// Hungry
|
|
if (roll < 0.1 * qualityMult) resetDay = true;
|
|
break;
|
|
case 7:
|
|
// Anxious
|
|
probabilityIncrease = 0.25 * qualityMult;
|
|
break;
|
|
case 8:
|
|
// Shy
|
|
if (
|
|
global.getTaggedBlocksInRadius(
|
|
level,
|
|
"society:plushies",
|
|
plushieBlock,
|
|
3 - (qualityMult - 1)
|
|
) == 1
|
|
) {
|
|
doubleDrops = true;
|
|
}
|
|
break;
|
|
case 9:
|
|
// Cheerful;
|
|
if (
|
|
global.getTaggedBlocksInRadius(
|
|
level,
|
|
"society:plushies",
|
|
plushieBlock,
|
|
2
|
|
) >
|
|
28 - 4 * qualityMult
|
|
) {
|
|
doubleDrops = true;
|
|
}
|
|
break;
|
|
case 10:
|
|
// Chill
|
|
newDrops.push(Item.of(`${qualityMult}x society:pristine_diamond`));
|
|
break;
|
|
case 11:
|
|
// Machiavellian
|
|
newDrops.push(Item.of(`${qualityMult}x minecraft:netherite_scrap`));
|
|
break;
|
|
case 12:
|
|
// Cutesy
|
|
newDrops.push(Item.of(`${qualityMult}x society:furniture_box`));
|
|
break;
|
|
case 13:
|
|
// Fashionista
|
|
if (
|
|
global.getTaggedBlocksInRadius(
|
|
level,
|
|
"society:loot_furniture",
|
|
plushieBlock,
|
|
2
|
|
) >=
|
|
28 - 4 * qualityMult
|
|
) {
|
|
doubleDrops = true;
|
|
}
|
|
break;
|
|
default:
|
|
case 14:
|
|
// Neutral
|
|
if (roll < 0.1 * qualityMult) doubleDrops = true;
|
|
break;
|
|
}
|
|
return {
|
|
newDrops: newDrops,
|
|
doubleDrops: doubleDrops,
|
|
resetDay: resetDay,
|
|
probabilityIncrease: probabilityIncrease,
|
|
processItems: processItems,
|
|
};
|
|
};
|
|
// const { newDrops, doubleDrops, resetDay, probabilityIncrease, processItems } =
|
|
// global.getPlushieDrops(plushieNbt, plushie);
|
|
|
|
global.executePlushieHusbandry = (
|
|
level,
|
|
server,
|
|
player,
|
|
item,
|
|
block,
|
|
specialHarvestFunction
|
|
) => {
|
|
let nbt = block.getEntityData();
|
|
const { animal } = nbt.data;
|
|
if (!animal) return;
|
|
let reset = false;
|
|
const day = global.getDay(level);
|
|
const plushieMods = global.getPlushieModifiers(level, nbt.data, block);
|
|
if (
|
|
item === "society:milk_pail" &&
|
|
global.milkableAnimals.includes(animal.type)
|
|
) {
|
|
let milkItem = global.getMilk(
|
|
level,
|
|
animal,
|
|
animal,
|
|
player,
|
|
day,
|
|
false,
|
|
plushieMods,
|
|
player.stages,
|
|
);
|
|
if (milkItem !== -1) {
|
|
let milk = level.createEntity("minecraft:item");
|
|
milk.x = player.x;
|
|
milk.y = player.y;
|
|
milk.z = player.z;
|
|
milk.item = milkItem;
|
|
milk.spawn();
|
|
server.runCommandSilent(
|
|
`playsound minecraft:entity.cow.milk block @a ${player.x} ${player.y} ${player.z}`
|
|
);
|
|
global.giveExperience(server, player, "husbandry", 30);
|
|
if (!plushieMods.resetDay) {
|
|
nbt.merge({
|
|
data: {
|
|
animal: {
|
|
ageLastMilked: day,
|
|
},
|
|
},
|
|
});
|
|
} else {
|
|
reset = true;
|
|
}
|
|
level.spawnParticles(
|
|
"minecraft:note",
|
|
true,
|
|
block.x,
|
|
block.y + 1.5,
|
|
block.z,
|
|
0.1 * rnd(1, 4),
|
|
0.1 * rnd(1, 4),
|
|
0.1 * rnd(1, 4),
|
|
3,
|
|
0.01
|
|
);
|
|
}
|
|
}
|
|
global.handleSpecialHarvest(
|
|
level,
|
|
animal,
|
|
player,
|
|
server,
|
|
block,
|
|
undefined,
|
|
plushieMods,
|
|
specialHarvestFunction,
|
|
player.stages,
|
|
);
|
|
if (!plushieMods.resetDay) {
|
|
nbt.merge({
|
|
data: {
|
|
animal: {
|
|
ageLastDroppedSpecial: day,
|
|
},
|
|
},
|
|
});
|
|
} else if (Number(animal.ageLastDroppedSpecial) < day) {
|
|
reset = true;
|
|
}
|
|
if (item === "society:magic_shears") {
|
|
const droppedLoot = global.getMagicShearsOutput(
|
|
level,
|
|
animal,
|
|
player,
|
|
plushieMods,
|
|
player.stages,
|
|
);
|
|
if (droppedLoot !== -1) {
|
|
server.runCommandSilent(
|
|
`playsound minecraft:entity.sheep.shear block @a ${player.x} ${player.y} ${player.z}`
|
|
);
|
|
for (let i = 0; i < droppedLoot.length; i++) {
|
|
let specialItem = level.createEntity("minecraft:item");
|
|
let dropItem = droppedLoot[i];
|
|
specialItem.x = player.x;
|
|
specialItem.y = player.y;
|
|
specialItem.z = player.z;
|
|
specialItem.item = dropItem;
|
|
specialItem.spawn();
|
|
}
|
|
level.spawnParticles(
|
|
"snowyspirit:glow_light",
|
|
true,
|
|
block.x,
|
|
block.y + 0.5,
|
|
block.z,
|
|
0.2 * rnd(1, 4),
|
|
0.2 * rnd(1, 4),
|
|
0.2 * rnd(1, 4),
|
|
20,
|
|
2
|
|
);
|
|
global.addItemCooldown(player, item, 1);
|
|
}
|
|
}
|
|
global.setBlockEntityData(block, nbt)
|
|
if (reset) {
|
|
server.runCommandSilent(
|
|
`playsound legendarycreatures:corpse_eater_death block @a ${block.x} ${block.y} ${block.z}`
|
|
);
|
|
level.spawnParticles(
|
|
"species:spectre_smoke",
|
|
true,
|
|
block.x,
|
|
block.y,
|
|
block.z,
|
|
0.2 * rnd(1, 4),
|
|
0.2 * rnd(1, 4),
|
|
0.2 * rnd(1, 4),
|
|
3,
|
|
0.01
|
|
);
|
|
}
|
|
};
|