You are not logged in.

  • Login
Bitte besucht unser neues Forum unter https://forum.nitrado.net | Please visit our new Forum at https://forum.nitrado.net

Dear visitor, welcome to Nitrado.net Prepaid Gameserver Community-Support - Archiv. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

strubel

User / Kunde

  • "strubel" started this thread

Posts: 863

  • Send private message

1

Saturday, February 22nd 2014, 12:59am

>Schwebender Falling Sand<

Ich hoffe es stört niemanden, das hier zweit Threads zum selben Thema sind, da ich in beiden ganz verschieden Lösungen habe.

Als allererstes braucht ihr diese, von @TeeePeee geschriebe Klasse, um eure Custom Entitys später registrieren zu können:

Spoiler Spoiler

Java source code

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    package de.derstrubel.teammatch;
     
    import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
     
    import net.minecraft.server.v1_7_R1.BiomeBase;
import net.minecraft.server.v1_7_R1.BiomeMeta;
import net.minecraft.server.v1_7_R1.EntityBat;
import net.minecraft.server.v1_7_R1.EntityFallingBlock;
import net.minecraft.server.v1_7_R1.Entity;
import net.minecraft.server.v1_7_R1.EntityTypes;
     
import org.bukkit.entity.EntityType;
     
    public enum CustomEntityType {
     
    TESTBAT("TestBat", 65, EntityType.BAT, EntityBat.class, TestBat.class),
    TESTFALLINGBLOCK("TestFallingBlock", 21, EntityType.FALLING_BLOCK, EntityFallingBlock.class, TestFallingBlock.class);
     
    private String name;
    private int id;
    private EntityType entityType;
    private Class<? extends Entity> nmsClass;
    private Class<? extends Entity> customClass;
     
    private CustomEntityType(String name, int id, EntityType entityType, Class<? extends Entity> nmsClass,
    Class<? extends Entity> customClass) {
    this.name = name;
    this.id = id;
    this.entityType = entityType;
    this.nmsClass = nmsClass;
    this.customClass = customClass;
    }
     
    public String getName() {
    return name;
    }
     
    public int getID() {
    return id;
    }
     
    public EntityType getEntityType() {
    return entityType;
    }
     
    public Class<? extends Entity> getNMSClass() {
    return nmsClass;
    }
     
    public Class<? extends Entity> getCustomClass() {
    return customClass;
    }
     
    /**
      * Register our entities.
      */
    public static void registerEntities() {
    for (CustomEntityType entity : values())
    a(entity.getCustomClass(), entity.getName(), entity.getID());
     
    // BiomeBase#biomes became private.
    BiomeBase[] biomes;
    try {
    biomes = (BiomeBase[]) getPrivateStatic(BiomeBase.class, "biomes");
    } catch (Exception exc) {
    // Unable to fetch.
    return;
    }
    for (BiomeBase biomeBase : biomes) {
    if (biomeBase == null)
    break;
     
    // This changed names from J, K, L and M.
    for (String field : new String[] { "as", "at", "au", "av" })
    try {
    Field list = BiomeBase.class.getDeclaredField(field);
    list.setAccessible(true);
    @SuppressWarnings("unchecked")
    List<BiomeMeta> mobList = (List<BiomeMeta>) list.get(biomeBase);
     
    // Write in our custom class.
    for (BiomeMeta meta : mobList)
    for (CustomEntityType entity : values())
    if (entity.getNMSClass().equals(meta.b))
    meta.b = entity.getCustomClass();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
     
    /**
      * Unregister our entities to prevent memory leaks. Call on disable.
      */
    public static void unregisterEntities() {
    for (CustomEntityType entity : values()) {
    // Remove our class references.
    try {
    ((Map) getPrivateStatic(EntityTypes.class, "d")).remove(entity.getCustomClass());
    } catch (Exception e) {
    e.printStackTrace();
    }
     
    try {
    ((Map) getPrivateStatic(EntityTypes.class, "f")).remove(entity.getCustomClass());
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
     
    for (CustomEntityType entity : values())
    try {
    // Unregister each entity by writing the NMS back in place of the custom class.
    a(entity.getNMSClass(), entity.getName(), entity.getID());
    } catch (Exception e) {
    e.printStackTrace();
    }
     
    // Biomes#biomes was made private so use reflection to get it.
    BiomeBase[] biomes;
    try {
    biomes = (BiomeBase[]) getPrivateStatic(BiomeBase.class, "biomes");
    } catch (Exception exc) {
    // Unable to fetch.
    return;
    }
    for (BiomeBase biomeBase : biomes) {
    if (biomeBase == null)
    break;
     
    // The list fields changed names but update the meta regardless.
    for (String field : new String[] { "as", "at", "au", "av" })
    try {
    Field list = BiomeBase.class.getDeclaredField(field);
    list.setAccessible(true);
    @SuppressWarnings("unchecked")
    List<BiomeMeta> mobList = (List<BiomeMeta>) list.get(biomeBase);
     
    // Make sure the NMS class is written back over our custom class.
    for (BiomeMeta meta : mobList)
    for (CustomEntityType entity : values())
    if (entity.getCustomClass().equals(meta.b))
    meta.b = entity.getNMSClass();
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }
     
    /**
      * A convenience method.
      * @param clazz The class.
      * @param f The string representation of the private static field.
      * @return The object found
      * @throws Exception if unable to get the object.
      */
    private static Object getPrivateStatic(Class clazz, String f) throws Exception {
    Field field = clazz.getDeclaredField(f);
    field.setAccessible(true);
    return field.get(null);
    }
     
    /*
      * Since 1.7.2 added a check in their entity registration, simply bypass it and write to the maps ourself.
      */
    private static void a(Class paramClass, String paramString, int paramInt) {
    try {
    ((Map) getPrivateStatic(EntityTypes.class, "c")).put(paramString, paramClass);
    ((Map) getPrivateStatic(EntityTypes.class, "d")).put(paramClass, paramString);
    ((Map) getPrivateStatic(EntityTypes.class, "e")).put(Integer.valueOf(paramInt), paramClass);
    ((Map) getPrivateStatic(EntityTypes.class, "f")).put(paramClass, Integer.valueOf(paramInt));
    ((Map) getPrivateStatic(EntityTypes.class, "g")).put(paramString, Integer.valueOf(paramInt));
    } catch (Exception exc) {
    // Unable to register the new class.
    }
    }
    }


Dann müsst ihr eine Klasse NewBat erstellen, das wird eure Custom Bat sein, in die schreibt ihr das rein:

Spoiler Spoiler

Java source code

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
package de.strubel.gravitygun;

import java.lang.reflect.Field;

import net.minecraft.server.v1_7_R1.DamageSource;
import net.minecraft.server.v1_7_R1.EntityBat;
import net.minecraft.server.v1_7_R1.PathfinderGoalSelector;
import net.minecraft.server.v1_7_R1.World;

import org.bukkit.craftbukkit.v1_7_R1.util.UnsafeList;

public class NewBat extends EntityBat {

	public NewBat(World world) {
		super(world);
		
		this.setInvisible(true);
		
	    try {
	        Field bField = PathfinderGoalSelector.class.getDeclaredField("b");
	        bField.setAccessible(true);
	        Field cField = PathfinderGoalSelector.class.getDeclaredField("c");
	        cField.setAccessible(true);
	        bField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
	        bField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
	        cField.set(goalSelector, new UnsafeList<PathfinderGoalSelector>());
	        cField.set(targetSelector, new UnsafeList<PathfinderGoalSelector>());
	        } catch (Exception exc) {
	        exc.printStackTrace();
	        }
		
	}
	
	@Override
	public boolean bk() {
		return false;
	}
	
	@Override
    public boolean damageEntity(DamageSource damagesource, float f) {
            return false;
        }
}


Das ist jetzt eine neu Entity, die keine PathFinderGoals hat, sich also nicht bewegt und keinen Schaden nimmt.

Dann braucht ihr zusätzlich noch diese Klasse, die euren CustomFallingBlock repräsentiert:

Spoiler Spoiler

Java source code

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
package de.derstrubel.teammatch;
 
import java.util.Iterator;

import net.minecraft.server.v1_7_R1.Block;
import net.minecraft.server.v1_7_R1.BlockFalling;
import net.minecraft.server.v1_7_R1.Blocks;
import net.minecraft.server.v1_7_R1.Entity;
import net.minecraft.server.v1_7_R1.EntityFallingBlock;
import net.minecraft.server.v1_7_R1.IContainer;
import net.minecraft.server.v1_7_R1.ItemStack;
import net.minecraft.server.v1_7_R1.Material;
import net.minecraft.server.v1_7_R1.MathHelper;
import net.minecraft.server.v1_7_R1.NBTBase;
import net.minecraft.server.v1_7_R1.NBTTagCompound;
import net.minecraft.server.v1_7_R1.TileEntity;
import net.minecraft.server.v1_7_R1.World;
 
public class TestFallingBlock extends EntityFallingBlock {
	
	boolean f;
 
    public TestFallingBlock(World paramWorld, double paramDouble1, double paramDouble2, double paramDouble3, Block paramInt) {
        super(paramWorld, paramDouble1, paramDouble2, paramDouble3, paramInt);
        this.dropItem = true;
        this.l = true;
        this.a(0.98F, 0.98F);
        
    }
    
    @Override
    public void h() {
        if (this.id.getMaterial() == Material.AIR) {
            this.die();
        } else {
            this.lastX = this.locX;
            this.lastY = this.locY;
            this.lastZ = this.locZ;
            ++this.b;
            this.motY -= 0.03999999910593033D;
            this.move(this.motX, this.motY, this.motZ);
            this.motX *= 0.9800000190734863D;
            this.motY *= 0.9800000190734863D;
            this.motZ *= 0.9800000190734863D;
            if (!this.world.isStatic) {
                int i = MathHelper.floor(this.locX);
                int j = MathHelper.floor(this.locY);
                int k = MathHelper.floor(this.locZ);

                if (this.b == 1) {
                    if (this.world.getType(i, j, k) != this.id) {
                        //this.die();
                        return;
                    }

                    this.world.setAir(i, j, k);
                }

                if (this.onGround) {
                    this.motX *= 0.699999988079071D;
                    this.motZ *= 0.699999988079071D;
                    this.motY *= -0.5D;
                    if (this.world.getType(i, j, k) != Blocks.PISTON_MOVING) {
                        this.die();
                        if (!this.f && this.world.mayPlace(this.id, i, j, k, true, 1, (Entity) null, (ItemStack) null) && !BlockFalling.canFall(this.world, i, j - 1, k) && this.world.setTypeAndData(i, j, k, this.id, this.data, 3)) {
                            if (this.id instanceof BlockFalling) {
                                ((BlockFalling) this.id).a(this.world, i, j, k, this.data);
                            }

                            if (this.tileEntityData != null && this.id instanceof IContainer) {
                                TileEntity tileentity = this.world.getTileEntity(i, j, k);

                                if (tileentity != null) {
                                    NBTTagCompound nbttagcompound = new NBTTagCompound();

                                    tileentity.b(nbttagcompound);
                                    Iterator iterator = this.tileEntityData.c().iterator();

                                    while (iterator.hasNext()) {
                                        String s = (String) iterator.next();
                                        NBTBase nbtbase = this.tileEntityData.get(s);

                                        if (!s.equals("x") && !s.equals("y") && !s.equals("z")) {
                                            nbttagcompound.set(s, nbtbase.clone());
                                        }
                                    }

                                    tileentity.a(nbttagcompound);
                                    tileentity.update();
                                }
                            }
                        } else if (this.dropItem && !this.f) {
                            this.a(new ItemStack(this.id, 1, this.id.getDropData(this.data)), 0.0F);
                        }
                    }
                } else if (this.b > 100 && !this.world.isStatic && (j < 1 || j > 256) || this.b > 600) {
                    if (this.dropItem) {
                        this.a(new ItemStack(this.id, 1, this.id.getDropData(this.data)), 0.0F);
                    }

                    //this.die();
                }
            }
        }
    }
    
}


Dort habe ich die Methode h() überschrieben, und jedes this.die() entfernt, sonst würde dieser FallingBlock nach einigen Minuten verschwinden.

jetzt müsst ihr diese drei Klassen nurnoch richtig anwenden. Als erstes führt ihr das in eurer onEnable() aus:

Java source code

1
		CustomEntityType.registerEntities();


Wenn ihr jetzt so einen fliegen Block spawnen wollt macht ihr das:

Java source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
	     World mcWorld = ((CraftWorld) world).getHandle();
	     TestBat vs = new TestBat(mcWorld);
	     
	     CraftBlock cb = ( (CraftBlock) event.getPlayer().getWorld().getBlockAt(event.getPlayer().getLocation()));
	     Block b = CraftMagicNumbers.getBlock(Material.STONE);
	     
	     TestFallingBlock tf = new TestFallingBlock(mcWorld, x, y, z, b);
	     tf.setPosition(x, y, z);
	     tf.dropItem = false;
	     
	     Bat e = (Bat) vs.getBukkitEntity();
	     
	     e.setPassenger(tf.getBukkitEntity());
	     
	     vs.setPosition(x, y, z);
	     mcWorld.addEntity(tf, SpawnReason.CUSTOM);
	     mcWorld.addEntity(vs, SpawnReason.CUSTOM);


Die Fledermaus müsst ihr natührlich noch entwerder mit einem Unsichtbatkeitstarank, oder einem nichtsender der Packets unsichtbar machen.

jetzt nützt das aber unbewegt nicht viele, also müsst ihr um das zu bewegen nur diesen Code ausführen:

Java source code

1
2
       		Vector vec = ziellocation.toVector().subtract(entity.getLocation().toVector());
       		entity.setVelocity(vec);


Ich würde mich über Feedback freuen :)
Alle Angaben ohne Gewähr!

This post has been edited 1 times, last edit by "strubel" (Feb 28th 2014, 8:47pm)


DarkBlade12

User / Kunde

  • "DarkBlade12" is male

Posts: 531

Occupation: ❤❤❤❤❤❤❤❤❤❤

Thanks: 7

  • Send private message

2

Tuesday, February 25th 2014, 10:57am

@strubel die Modifizierung der Entities und die Registrierung ist bei weitem nicht sehr effizient gemacht. Ich arbeite bereits an Klassen, bei denen die Bat so modifiziert ist, das sie keinen Schaden bekommen kann und auch nicht einfach entfernt wird wie normale Entities. Wenn ich damit fertig bin kann ich es ja mal posten.
--> #Läuft <--

strubel

User / Kunde

  • "strubel" started this thread

Posts: 863

  • Send private message

3

Tuesday, February 25th 2014, 1:25pm

@DarkBlade12:
Gut, ich verwende das nähmlich auch für mein aktuelles kleines Projekt und besser Klassen wären da natührlich besser.
Alle Angaben ohne Gewähr!

strubel

User / Kunde

  • "strubel" started this thread

Posts: 863

  • Send private message

4

Friday, February 28th 2014, 8:48pm

Kleines "update" die Fledermaus ist jetzt unverwundbar.
Alle Angaben ohne Gewähr!

TheMiners1999

User / Kunde

Posts: 106

  • Send private message

5

Monday, March 10th 2014, 5:05pm

Man kann das ja auch, laut deiner Aussage im PostCrafter-Forum mit Items machen. Wie sieht das in etwa aus?

PS: Sry, habe die alte Nachricht gelöscht, was ich eig. nicht wollte
Mivcon.net - Spielerlebnisse, die man nie vergisst. Joine jetzt: MIVCON.net

This post has been edited 1 times, last edit by "TheMiners1999" (Mar 10th 2014, 5:12pm)


mcf_

User / Kunde

Posts: 1,363

Thanks: 22

  • Send private message

6

Monday, March 10th 2014, 5:08pm

@TheMiners1999
Haste aber schnell bemerkt ;) Hast du etwa seine Signatur da gesehen? :D



TheMiners1999

User / Kunde

Posts: 106

  • Send private message

7

Monday, March 10th 2014, 5:36pm

@TheMiners1999
Haste aber schnell bemerkt ;) Hast du etwa seine Signatur da gesehen? :D
Ich lese nicht sehr oft Signaturen
Mivcon.net - Spielerlebnisse, die man nie vergisst. Joine jetzt: MIVCON.net

mcf_

User / Kunde

Posts: 1,363

Thanks: 22

  • Send private message

8

Monday, March 10th 2014, 5:38pm

@TheMiners1999
Weil sie meistens groß sind?



strubel

User / Kunde

  • "strubel" started this thread

Posts: 863

  • Send private message

9

Monday, March 10th 2014, 6:08pm

@TheMiners1999
Die CustomFallingBlovk klasse löschen, ein Item spawnen und das als Passagier auf eine Fledermaus setzen.
Alle Angaben ohne Gewähr!

HappyLooser

User / Kunde

Posts: 405

  • Send private message

10

Monday, March 10th 2014, 8:23pm

@TheMiners1999
Die CustomFallingBlovk klasse löschen, ein Item spawnen und das als Passagier auf eine Fledermaus setzen.


Kann man die Fledermaus mit Item oder so auch durch fahren oder ist sie nur virtuell unsichtbar ?

strubel

User / Kunde

  • "strubel" started this thread

Posts: 863

  • Send private message

11

Monday, March 10th 2014, 8:25pm

@HappyLooser
Die ist vorhanden, sie hat nur einen Trankeffekt.
Alle Angaben ohne Gewähr!

HappyLooser

User / Kunde

Posts: 405

  • Send private message

12

Monday, March 10th 2014, 8:28pm

@HappyLooser
Die ist vorhanden, sie hat nur einen Trankeffekt.


Schade suche noch eine Möglichkeit ein Item in der Luft zu halten. Das sollte aber nur einfach und schlicht sein ohne ressourcen zufressen.

strubel

User / Kunde

  • "strubel" started this thread

Posts: 863

  • Send private message

13

Monday, March 10th 2014, 8:31pm

Man kann aber durch sie durch gehen ohne das soe sich bewegt. Du kannst der Fledermaus auch einem DisplayName geben, mit ProtocoLib einen Outgoing Packet Listener machen und dann die Packets die diesen Namen haben nicht senden.
Alle Angaben ohne Gewähr!

HappyLooser

User / Kunde

Posts: 405

  • Send private message

14

Monday, March 10th 2014, 8:35pm

Hehehe ProtocoLib, wollte ne eigene Variante haben. Brauche es wenn denn nur für einige Spiele, alla Mario Jump und Run

Bitte besucht unser neues Forum unter https://forum.nitrado.net| Please visit our new Forum at https://forum.nitrado.net

Similar threads