summaryrefslogtreecommitdiffstats
path: root/src/main/java/net/minecraft/server/ItemBlock.java
blob: b1ae3950d25b7f5821dceb2c468f5e37b9686666 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package net.minecraft.server;

// CraftBukkit start
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.craftbukkit.block.CraftBlockState;
import org.bukkit.craftbukkit.inventory.CraftItemStack;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Type;
import org.bukkit.event.block.BlockPlaceEvent;
// CraftBukkit end

public class ItemBlock extends Item {

    private int a;

    public ItemBlock(int i) {
        super(i);
        this.a = i + 256;
        this.b(Block.byId[i + 256].a(2));
    }

    public boolean a(ItemStack itemstack, EntityHuman entityhuman, World world, int i, int j, int k, int l) {
        // CraftBukkit start
        // Bail if we have nothing of the item in hand
        if (itemstack.count == 0) {
            return false;
        }

        // CraftBukkit store info of the clicked block
        CraftBlock blockClicked = (CraftBlock) ((WorldServer) world).getWorld().getBlockAt(i, j, k);
        BlockFace faceClicked = CraftBlock.notchToBlockFace(l);
        // CraftBukkit end

        if (world.getTypeId(i, j, k) == Block.SNOW.id) {
            l = 0;
        } else {
            if (l == 0) {
                --j;
            }

            if (l == 1) {
                ++j;
            }

            if (l == 2) {
                --k;
            }

            if (l == 3) {
                ++k;
            }

            if (l == 4) {
                --i;
            }

            if (l == 5) {
                ++i;
            }
        }

        if (itemstack.count == 0) {
            return false;
        } else {
            // CraftBukkit start
            /* We store the old data so we can undo it. Snow(78) and half-steps(44) are special in that they replace the block itself, 
            * rather than the block touching the face we clicked on.
            */
            org.bukkit.block.Block replacedBlock = (blockClicked.getTypeId() == Block.SNOW.id || blockClicked.getTypeId() == Block.STEP.id) ? blockClicked:blockClicked.getFace(faceClicked);
            final BlockState replacedBlockState = new CraftBlockState(replacedBlock);
            // CraftBukkit end

            if (world.a(this.a, i, j, k, false)) {
                Block block = Block.byId[this.a];

                // CraftBukkit start - This executes the placement of the block
                /*
                * This replaces world.b(IIIII), we're doing this because we need to
                * hook between the 'placement' and the informing to 'world' so we can
                * sanely undo this.
                *
                * Whenever the call to 'world.b' changes we need to figure out again what to
                * replace this with.
                */
                if (world.setTypeIdAndData(i, j, k, a, a(itemstack.h()))) { // <-- world.b does this to place the block
                    org.bukkit.Server server = ((WorldServer) world).getServer();
                    Type eventType = Type.BLOCK_PLACED;
                    org.bukkit.block.Block placedBlock = blockClicked.getFace(faceClicked) ;
                    org.bukkit.inventory.ItemStack itemInHand = new CraftItemStack(itemstack);
                    Player thePlayer = (entityhuman ==null) ? null : (Player) entityhuman.getBukkitEntity();

                    int distanceFromSpawn = (int) Math.max(Math.abs(i - world.spawnX), Math.abs(k - world.spawnZ));

                    // CraftBukkit hardcoded Spawn distance for now
                    // TODO make spawn size configurable
                    boolean canBuild = distanceFromSpawn > 16 || thePlayer.isOp();

                    BlockPlaceEvent event = new BlockPlaceEvent(eventType, placedBlock, replacedBlockState, blockClicked, itemInHand, thePlayer, canBuild);
                    server.getPluginManager().callEvent(event);

                    if (event.isCancelled() || !event.canBuild()) {
                        // CraftBukkit Undo!

                        if (this.a == block.ICE.id) {
                            // Ice will explode if we set straight to 0
                            world.setTypeId(i, j, k, 20);
                        } else if ((this.a == Block.STEP.id) && (world.getTypeId(i, j - 1, k) == Block.DOUBLE_STEP.id) && (world.getTypeId(i, j, k) == 0)) {
                            // Half steps automatically set the block below to a double
                            world.setTypeId(i, j - 1, k, 44);
                        }

                        world.setTypeIdAndData(i, j, k, replacedBlockState.getTypeId(), replacedBlockState.getData().getData());
                    } else {
                        world.f(i, j, k, a); // <-- world.b does this on success (tell the world)

                        Block.byId[this.a].c(world, i, j, k, l);
                        Block.byId[this.a].a(world, i, j, k, (EntityLiving) entityhuman);
                        world.a((double) ((float) i + 0.5F), (double) ((float) j + 0.5F), (double) ((float) k + 0.5F), block.stepSound.c(), (block.stepSound.a() + 1.0F) / 2.0F, block.stepSound.b() * 0.8F);
                        --itemstack.count;
                    }
                    // CraftBukkit end
                }
            }

            return true;
        }
    }

    public String a() {
        return Block.byId[this.a].e();
    }
}