Skip to content

Commit 3ad5ff3

Browse files
committed
carpet created
1 parent ff59552 commit 3ad5ff3

File tree

6 files changed

+267
-7
lines changed

6 files changed

+267
-7
lines changed

src/world/block/Block.data.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ public partial class Block {
126126
public static Block CANDY;
127127
public static Block CANDY_SLAB;
128128
public static Block CANDY_STAIRS;
129+
public static Carpet CARPET;
129130

130131
//public static Block HEAD;
131132

@@ -1016,6 +1017,9 @@ public static void preLoad() {
10161017
CANDY_STAIRS.material(Material.FOOD);
10171018
CANDY_STAIRS.partialBlock();
10181019

1020+
CARPET = register("carpet", new Carpet("Carpet"));
1021+
CARPET.material(Material.ORGANIC);
1022+
10191023
//HEAD = register("head", new Block("Head"));
10201024
//HEAD.setTex(HeadUVs(0, 3, 1, 3, 2, 3, 3, 3, 4, 3, 5, 3));
10211025
//HEAD.setModel(BlockModel.makeHalfCube(HEAD));

src/world/entity/BigEye.cs

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
using BlockGame.main;
2+
using BlockGame.util;
3+
using BlockGame.world.item;
4+
using Molten.DoublePrecision;
5+
namespace BlockGame.world.entity;
6+
7+
public class BigEye : Hostile {
8+
protected override double detectRadius => 24.0;
9+
protected override float attackDamage => 4.0f;
10+
protected override int attackCooldown => 40;
11+
protected override bool usePathfinding => false; // handles own flight movement
12+
13+
private const double FLIGHT_SPEED = 1;
14+
private const double HOVER_HEIGHT = 18.0; // preferred height above ground
15+
16+
private Vector3D? flyTarget;
17+
private int retargetCooldown;
18+
19+
// don't take fall damage
20+
protected override bool needsFallDamage => false;
21+
22+
public override bool burnInSunlight => true;
23+
public override double eyeHeight => 0; // it's a fucking floating eye
24+
25+
public BigEye(World world) : base(world, "BigEye") {
26+
tex = "textures/entity/bigeye.png";
27+
flyMode = true;
28+
hp = 100;
29+
}
30+
31+
public override AABB calcAABB(Vector3D pos) {
32+
return new AABB(
33+
pos.X - 0.25, pos.Y - 0.25, pos.Z - 0.25,
34+
pos.X + 0.25, pos.Y + 0.25, pos.Z + 0.25
35+
);
36+
}
37+
38+
public override void AI(double dt) {
39+
spawnTicks++;
40+
updateSunlightBurn();
41+
42+
// call base for attack detection/management
43+
base.AI(dt);
44+
}
45+
46+
protected override void onTargetDetected(double dt, Entity target, double distance) {
47+
flyTowardsTarget(dt);
48+
}
49+
50+
protected override void onNoTargetDetected(double dt) {
51+
idleFlight(dt);
52+
}
53+
54+
private void flyTowardsTarget(double dt) {
55+
if (target == null) return;
56+
57+
var dir = target.position - position;
58+
dir.Y += 1.0;
59+
60+
if (dir.Length() > 0.01) {
61+
dir = Vector3D.Normalize(dir);
62+
63+
velocity.X += dir.X * FLIGHT_SPEED;
64+
velocity.Y += dir.Y * FLIGHT_SPEED;
65+
velocity.Z += dir.Z * FLIGHT_SPEED;
66+
67+
// look at target
68+
var yaw = Meth.rad2deg((float)Math.Atan2(dir.X, dir.Z));
69+
var pitch = Meth.rad2deg((float)Math.Atan2(-dir.Y, Math.Sqrt(dir.X * dir.X + dir.Z * dir.Z)));
70+
71+
rotation.Y = yaw;
72+
rotation.X = pitch;
73+
}
74+
}
75+
76+
private void idleFlight(double dt) {
77+
retargetCooldown--;
78+
79+
// pick new target
80+
if (flyTarget == null || retargetCooldown <= 0) {
81+
var angle = Game.random.NextSingle(0, MathF.PI * 2);
82+
var dist = Game.random.NextSingle(8f, 16f);
83+
var tx = position.X + MathF.Cos(angle) * dist;
84+
var tz = position.Z + MathF.Sin(angle) * dist;
85+
86+
// try to maintain hover height above ground
87+
var groundY = findGroundBelow((int)tx, (int)tz);
88+
var ty = groundY + HOVER_HEIGHT + Game.random.NextSingle(-2f, 2f);
89+
90+
flyTarget = new Vector3D(tx, ty, tz);
91+
retargetCooldown = 60 + Game.random.Next(120);
92+
}
93+
94+
// fly towards target
95+
if (flyTarget != null) {
96+
var dir = flyTarget.Value - position;
97+
var dist = dir.Length();
98+
99+
// reached target?
100+
if (dist < 2.0) {
101+
flyTarget = null;
102+
retargetCooldown = 20;
103+
return;
104+
}
105+
106+
dir = Vector3D.Normalize(dir);
107+
108+
velocity.X += dir.X * FLIGHT_SPEED * 0.6;
109+
velocity.Y += dir.Y * FLIGHT_SPEED * 0.6;
110+
velocity.Z += dir.Z * FLIGHT_SPEED * 0.6;
111+
112+
var yaw = Meth.rad2deg((float)Math.Atan2(dir.X, dir.Z));
113+
rotation.Y = yaw;
114+
}
115+
}
116+
117+
private double findGroundBelow(int x, int z) {
118+
// scan downwards to find ground level
119+
for (int y = (int)position.Y; y > 0; y--) {
120+
if (world.getBlock(x, y, z) != 0) {
121+
return y + 1;
122+
}
123+
}
124+
125+
return 64;
126+
}
127+
128+
// disable gravity
129+
protected override void prePhysics(double dt) {
130+
AI(dt);
131+
132+
// apply drag
133+
velocity *= 0.85;
134+
}
135+
136+
public override void getDrop(List<ItemStack> drops) {
137+
//if (id == BigEye.id && Game.random.Next(20) == 0) {
138+
// drops.Add(new ItemStack(LW_BOOTS.item, 1, 0));
139+
//}
140+
}
141+
}

src/world/item/CandyDyeRecipe.cs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace BlockGame.world.item;
66

7+
using static DyeItem;
8+
79
// 1 dye + 1 candy = dyed candy
810
public class CandyDyeRecipe : Recipe {
911
public override bool matches(CraftingGridInventory grid) {
@@ -34,20 +36,26 @@ public override bool matchesShape(CraftingGridInventory grid) {
3436

3537
public override ItemStack getResult(CraftingGridInventory grid) {
3638
int dyeMeta = -1;
39+
int candyMeta = -1;
3740

3841
foreach (var slot in grid.grid) {
39-
if (!isEmpty(slot) && slot.id == Item.DYE.id) {
40-
dyeMeta = slot.metadata;
41-
break;
42+
if (!isEmpty(slot)) {
43+
if (slot.id == Item.DYE.id) {
44+
dyeMeta = slot.metadata;
45+
} else if (slot.id == Block.CANDY.getItem().id) {
46+
candyMeta = slot.metadata;
47+
}
4248
}
4349
}
4450

45-
if (dyeMeta == -1) {
51+
if (dyeMeta == -1 || candyMeta == -1) {
4652
return ItemStack.EMPTY;
4753
}
4854

49-
// return dyed candy
50-
return new ItemStack(Block.CANDY.getItem(), 1, dyeMeta);
55+
// for candy, metadata IS the color directly (no orientation like carpet)
56+
int resultColor = mixColours(candyMeta, dyeMeta);
57+
58+
return new ItemStack(Block.CANDY.getItem(), 1, resultColor);
5159
}
5260

5361
public override void consumeIngredients(CraftingGridInventory grid) {

src/world/item/CarpetDyeRecipe.cs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
using BlockGame.util;
2+
using BlockGame.world.block;
3+
using BlockGame.world.item.inventory;
4+
5+
namespace BlockGame.world.item;
6+
7+
using static DyeItem;
8+
9+
// 1 dye + 1 carpet = dyed carpet
10+
public class CarpetDyeRecipe : Recipe {
11+
public override bool matches(CraftingGridInventory grid) {
12+
int dyeCount = 0;
13+
int carpetCount = 0;
14+
15+
foreach (var slot in grid.grid) {
16+
if (isEmpty(slot)) {
17+
continue;
18+
}
19+
20+
if (slot.id == Item.DYE.id) {
21+
dyeCount++;
22+
} else if (slot.id == Block.CARPET.getItem().id) {
23+
carpetCount++;
24+
} else {
25+
// invalid item
26+
return false;
27+
}
28+
}
29+
30+
return dyeCount == 1 && carpetCount == 1;
31+
}
32+
33+
public override bool matchesShape(CraftingGridInventory grid) {
34+
return matches(grid);
35+
}
36+
37+
public override ItemStack getResult(CraftingGridInventory grid) {
38+
int dyeMeta = -1;
39+
int carpetMeta = -1;
40+
41+
foreach (var slot in grid.grid) {
42+
if (!isEmpty(slot)) {
43+
if (slot.id == Item.DYE.id) {
44+
dyeMeta = slot.metadata;
45+
} else if (slot.id == Block.CARPET.getItem().id) {
46+
carpetMeta = slot.metadata;
47+
}
48+
}
49+
}
50+
51+
if (dyeMeta == -1 || carpetMeta == -1) {
52+
return ItemStack.EMPTY;
53+
}
54+
55+
// extract carpet color and mix with dye color
56+
byte carpetColor = Carpet.getColor((byte)carpetMeta);
57+
int resultColor = mixColours(carpetColor, dyeMeta);
58+
59+
// create carpet with mixed color (default floor orientation)
60+
byte resultMeta = 0;
61+
resultMeta = Carpet.setColor(resultMeta, (byte)resultColor);
62+
resultMeta = Carpet.setOrientation(resultMeta, Carpet.FLOOR);
63+
64+
return new ItemStack(Block.CARPET.getItem(), 1, resultMeta);
65+
}
66+
67+
public override void consumeIngredients(CraftingGridInventory grid) {
68+
bool dyeConsumed = false;
69+
bool carpetConsumed = false;
70+
71+
for (int i = 0; i < grid.grid.Length; i++) {
72+
var slot = grid.grid[i];
73+
74+
if (isEmpty(slot)) {
75+
continue;
76+
}
77+
78+
if (!dyeConsumed && slot.id == Item.DYE.id) {
79+
slot.quantity--;
80+
if (slot.quantity <= 0) {
81+
grid.grid[i] = ItemStack.EMPTY;
82+
}
83+
dyeConsumed = true;
84+
} else if (!carpetConsumed && slot.id == Block.CARPET.getItem().id) {
85+
slot.quantity--;
86+
if (slot.quantity <= 0) {
87+
grid.grid[i] = ItemStack.EMPTY;
88+
}
89+
carpetConsumed = true;
90+
}
91+
92+
if (dyeConsumed && carpetConsumed) {
93+
break;
94+
}
95+
}
96+
}
97+
}

src/world/item/Recipe.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,12 @@ public static void preLoad() {
126126

127127
// candy block mixing (any 2 candy blocks -> 2 of average colour)
128128
Registry.RECIPES.register("candyblock", new CandyBlockRecipe());
129-
130129
Registry.RECIPES.register("candydying", new CandyDyeRecipe());
131130

131+
// carpet mixing (any 2 carpets -> 1 of average colour)
132+
Registry.RECIPES.register("carpet", new CarpetRecipe());
133+
Registry.RECIPES.register("carpetdying", new CarpetDyeRecipe());
134+
132135
//dyes crafted from flowers
133136
yellow_dye = register(new ItemStack(Item.DYE, 6, 6));
134137
yellow_dye.noShape();

src/world/item/inventory/CreativeInventoryContext.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,13 @@ private void collectAllItems() {
6262
allItems.Add(new ItemStack(Block.CANDY_STAIRS.item, 1, metadata));
6363
}
6464
}
65+
// special handling for carpet - add all colour variants
66+
else if (i == Block.CARPET.id) {
67+
for (byte color = 0; color < 24; color++) {
68+
var metadata = Carpet.setColor(0, color);
69+
allItems.Add(new ItemStack(Block.CARPET.item, 1, metadata));
70+
}
71+
}
6572
/*else if (i == Block.CINNABAR_ORE.id) {
6673
allItems.Add(new ItemStack(Block.CINNABAR_ORE.item, 1, 0));
6774
allItems.Add(new ItemStack(Block.CINNABAR_ORE.item, 1, 1));

0 commit comments

Comments
 (0)