public abstract class MixinEntityPlayerExample
extends net.minecraft.entity.EntityLivingBase
_combatTracker, arrowHitTimer, attackedAtYaw, attackingPlayer, cameraPitch, dead, deathTime, entityAge, entityLivingToAttack, field_70741_aB, field_70769_ao, field_70770_ap, hurtTime, isJumping, isSwingInProgress, jumpMovementFactor, lastDamage, limbSwing, limbSwingAmount, maxHurtResistantTime, maxHurtTime, movedDistance, moveForward, moveStrafing, newPosRotationIncrements, newPosX, newPosY, newPosZ, newRotationPitch, newRotationYaw, onGroundSpeedFactor, potionsNeedUpdate, prevCameraPitch, prevLimbSwingAmount, prevMovedDistance, prevOnGroundSpeedFactor, prevRenderYawOffset, prevRotationYawHead, prevSwingProgress, randomYawVelocity, recentlyHit, renderYawOffset, rotationYawHead, scoreValue, swingProgress, swingProgressInt
addedToChunk, chunkCoordX, chunkCoordY, chunkCoordZ, dataWatcher, dimension, distanceWalkedModified, distanceWalkedOnStepModified, entityCollisionReduction, entityUniqueID, fallDistance, fire, fireResistance, firstUpdate, forceSpawn, height, hurtResistantTime, ignoreFrustumCheck, inPortal, inWater, isAirBorne, isCollided, isCollidedHorizontally, isCollidedVertically, isDead, isImmuneToFire, isInWeb, lastTickPosX, lastTickPosY, lastTickPosZ, motionX, motionY, motionZ, noClip, onGround, portalCounter, posX, posY, posZ, prevDistanceWalkedModified, preventEntitySpawning, prevPosX, prevPosY, prevPosZ, prevRotationPitch, prevRotationYaw, rand, renderDistanceWeight, riddenByEntity, ridingEntity, rotationPitch, rotationYaw, serverPosX, serverPosY, serverPosZ, stepHeight, teleportDirection, ticksExisted, timeUntilPortal, velocityChanged, width, worldObj
Constructor and Description |
---|
MixinEntityPlayerExample(net.minecraft.world.World worldIn)
ctor, not used
|
Modifier and Type | Method and Description |
---|---|
double |
entityPlayer$getHealth()
Conflicting method, now magically safe to implement because the prefix makes it compile
|
boolean |
entityPlayer$isUsingItem()
This comes first in the file for a reason, but you should read the javadoc for
isUsingItem() first, then come back and read this... |
int |
entityPlayer$thisMethodDoesNotConflict()
This non-conflicting method is also prefixed, this is recommended for soft implementations because there is no
Override annotation and
thus if the method in the underlying interface changes, there is no compile-time error which indicates this. |
boolean |
isUsingItem()
It should be pretty obvious that because this method exists in target class
EntityPlayer and in the interface
IEntityPlayerConflict that we don't actually need an implementation here at dev time, because the underlying method in the
target class already implicitly 'implements' the method in the interface. |
int |
norDoesThisOne()
This method doesn't conflict, but is not tagged with the prefix.
|
addPotionEffect, addRandomDrop, applyArmorCalculations, applyEntityAttributes, applyPotionDamageCalculations, attackEntityAsMob, attackEntityFrom, canBeCollidedWith, canBePushed, canBreatheUnderwater, canDropLoot, canEntityBeSeen, clearActivePotions, collideWithEntity, collideWithNearbyEntities, damageArmor, damageEntity, decreaseAirSupply, dismountEntity, dropEquipment, dropFewItems, entityInit, fall, func_110146_f, func_175134_bD, func_180466_bG, func_94060_bK, getAbsorptionAmount, getActivePotionEffect, getActivePotionEffects, getAge, getAIMoveSpeed, getAITarget, getAlwaysRenderNameTagForRender, getArrowCountInEntity, getAttributeMap, getCombatTracker, getCreatureAttribute, getCurrentArmor, getDeathSound, getEntityAttribute, getEquipmentInSlot, getExperiencePoints, getFallSoundString, getHealth, getHeldItem, getHurtSound, getInventory, getLastAttacker, getLastAttackerTime, getLook, getLookVec, getMaxHealth, getRevengeTimer, getRNG, getRotationYawHead, getSoundPitch, getSoundVolume, getSwingProgress, getTeam, getTotalArmorValue, handleHealthUpdate, heal, isChild, isEntityAlive, isEntityUndead, isMovementBlocked, isOnLadder, isOnSameTeam, isOnTeam, isPlayer, isPlayerSleeping, isPotionActive, isPotionActive, isPotionApplicable, isServerWorld, jump, kill, knockBack, markPotionsDirty, mountEntity, moveEntityWithHeading, onChangedPotionEffect, onDeath, onDeathUpdate, onEntityUpdate, onFinishedPotionEffect, onItemPickup, onKillCommand, onLivingUpdate, onNewPotionEffect, onUpdate, performHurtAnimation, readEntityFromNBT, removePotionEffect, removePotionEffectClient, renderBrokenItemStack, resetPotionEffectMetadata, sendEndCombat, sendEnterCombat, setAbsorptionAmount, setAIMoveSpeed, setArrowCountInEntity, setBeenAttacked, setCurrentItemOrArmor, setHealth, setJumping, setLastAttacker, setPositionAndRotation2, setRevengeTarget, setRotationYawHead, setSprinting, swingItem, updateAITick, updateArmSwingProgress, updateEntityActionState, updateFallState, updatePotionEffects, updatePotionMetadata, updateRidden, writeEntityToNBT
addChatMessage, addEntityCrashInfo, addToPlayerScore, addVelocity, applyEntityCollision, canAttackWithItem, canCommandSenderUseCommand, canRenderOnFire, canTriggerWalking, copyDataFromOld, copyLocationAndAnglesFrom, createRunningParticles, dealFireDamage, doBlockCollisions, doesEntityNotTriggerPressurePlate, dropItem, dropItemWithOffset, entityDropItem, equals, extinguish, func_145781_i, func_174815_a, func_174817_o, func_174827_a, func_174834_g, func_180427_aV, getAir, getAlwaysRenderNameTag, getBoundingBox, getBrightness, getBrightnessForRender, getCollisionBorderSize, getCollisionBox, getCommandSenderEntity, getCommandSenderName, getCommandStats, getCustomNameTag, getDataWatcher, getDisplayName, getDistance, getDistanceSq, getDistanceSq, getDistanceSqToCenter, getDistanceSqToEntity, getDistanceToEntity, getEntityBoundingBox, getEntityId, getEntityString, getEntityWorld, getExplosionResistance, getEyeHeight, getFlag, getHorizontalFacing, getHoverEvent, getMaxFallHeight, getMaxInPortalTime, getMountedYOffset, getNBTTagCompound, getParts, getPortalCooldown, getPosition, getPositionEyes, getPositionVector, getSplashSound, getSwimSound, getTeleportDirection, getUniqueID, getVectorForRotation, getYOffset, handleWaterMovement, hasCustomName, hashCode, hitByEntity, interactAt, interactFirst, isBurning, isEating, isEntityEqual, isEntityInsideOpaqueBlock, isEntityInvulnerable, isImmuneToFire, isInLava, isInRangeToRender3d, isInRangeToRenderDist, isInsideOfMaterial, isInvisible, isInvisibleToPlayer, isInWater, isOffsetPositionInLiquid, isOutsideBorder, isPushedByWater, isRiding, isSilent, isSneaking, isSprinting, isWet, moveEntity, moveFlying, moveToBlockPosAndAngles, newDoubleNBTList, newFloatNBTList, onChunkLoad, onCollideWithPlayer, onKillEntity, onStruckByLightning, playSound, playStepSound, preparePlayerToSpawn, pushOutOfBlocks, rayTrace, readFromNBT, replaceItemInInventory, resetHeight, sendCommandFeedback, setAir, setAlwaysRenderNameTag, setAngles, setCommandStat, setCustomNameTag, setDead, setEating, setEntityBoundingBox, setEntityId, setFire, setFlag, setInPortal, setInvisible, setInWeb, setLocationAndAngles, setOnFireFromLava, setOutsideBorder, setPosition, setPositionAndRotation, setPositionAndUpdate, setRotation, setSilent, setSize, setSneaking, setVelocity, setWorld, shouldSetPosAfterLoading, spawnRunningParticles, toString, travelToDimension, updateRiderPosition, verifyExplosion, writeMountToNBT, writeToNBT, writeToNBTOptional
public MixinEntityPlayerExample(net.minecraft.world.World worldIn)
worldIn
- The world to spawn the player inpublic double entityPlayer$getHealth()
public int entityPlayer$thisMethodDoesNotConflict()
Override
annotation and
thus if the method in the underlying interface changes, there is no compile-time error which indicates this. By using the prefix even on
non-conflicting methods, the transformer can verify that the method exists in the target interface at application time.public int norDoesThisOne()
entityPlayer$thisMethodDoesNotConflict()
public boolean entityPlayer$isUsingItem()
This comes first in the file for a reason, but you should read the javadoc for isUsingItem()
first, then come back and read this...
Go on! Do it!
Okay, so you understand why we have the method below, it injects our custom code in the target class's method by overwriting the method
body with the new code. However in order to preserve that functionality across the obfuscation boundary we need to tag it with
Overwrite
.
The magic happens here. Because this method is not tagged with Overwrite
, it will not be obfuscated at build time,
this means it still implements the interface. At dev time, the method below (because it appears after this one) will be injected and
will overwrite this method. This is exactly what we want to happen, because otherwise this method (at dev time) would actually
end up just calling itself recursively!
However, post-obfuscation, this method magically becomes an accessor for the (now renamed) isUsingItem() in the target class, and thus allows both the custom code to be injected into the original method (by the declaration below) and the interface to be implemented all at once.
See the example below for where custom code is not required in the accessor
.public boolean isUsingItem()
It should be pretty obvious that because this method exists in target class EntityPlayer
and in the interface
IEntityPlayerConflict
that we don't actually need an implementation here at dev time, because the underlying method in the
target class already implicitly 'implements' the method in the interface. We only need to Overwrite
it if we need to include some
custom functionality as shown here. However of course the problems start when we traverse the obfuscation boundary, since the method ends up
actually named "func_71039_bw" and thus no longer implements the interface!
We need the Overwrite
annotation in order to have this method renamed, but we don't want to break the interface. So how do we do
that? See entityPlayer$isUsingItem()
above for how.