задокументированная работа спелла:
Description: Protect yourself with a magical shield.
Effect:
Applies Magic Shield (buff) to the caster. Duration is dependent on the caster's Casting Mode, 10 30 or 120 seconds.
Никаких уровней сил не имеет, только длительность.
Код:
накладывает ЭФФЕКТ(
Magic Shield (buff) на кастера. никакой брони не добавляет и не может этого делать. в коде такого не прописано. ни в сингле. ни на сервере.
длительность эффекта зависит от кастинг-мода игрока.
эффект: это такая штука на игроке, которая
изменяет существующий параметр игрока.
например прыгучесть. игрок умеет прыгать, делает это на 1 блок, прыгучесть увеличивает высоту прыжка и снижает дамаг от падения при прыжке.
например броня. игрок имеет броню, равную 1 (входящий урон например в 5 ед, будет равен 4). увеличение брони на 1 даст эффект брони равным 2 (входящий урон в 5 ед будет равен 3). уменьшение брони даст эффект равным -1. (входящий урон в 5 ед будет равен 5).
При наличии у цел пробивания брони (игнорирования параметра брони) - игрок получает полный урон, так как броня не учитывается.
Одновременно может быть активно любое количество
разных эффектов, даже противоположных по влиянию (например, эффекты насыщения и голода могут быть на цели одновременно).
Нельзя получить несколько
одинаковых эффектов в один момент времени (если у вас защита на цели, то нельзя получить еще одну защиту, можно или обновить течение старой, или улучшить существующую). если игрок/моб/цель получает эффект, больший или равный чем тот что у него уже есть, новый эффект
заменит/обновит старый.
работа эффекта с ид 41 (зарегистрирован как "Magic Shield (buff) Ars Magica":
The Buff ID of Magic Shield is 41. |
задокументированная автором:
Increases the buff target's armor rating for the duration of the buff. Reduces physical and magical damage. |
в коде:
Повышает бафф брони цели (если у цели есть броня, когда броня равна 0 = повышение соответственно равно 0).
Снижает входящий физический и магический (ars magica!)
стандартный урон на кол-во брони. Если броня равна 0 = снижение равно 0.
Согласно физике майнкрафта, как эффект,
СНИМАЕТ наличие всех других аналогичных эффектов, заменяя собой.
В данном случае, берет вашу надетую вами броню, и заменяет ее собой на длительность своего эффекта.
Не влияет и не может влиять на наложенные на игрока другие эффекты (физика майнкрафта) - работает правильно,
не может влиять на фиксированный жестко заданный урон (должен получить дамаг 10, получит дамаг 10, просто потому что это "Х - 10", где Х = хп игрока (работает правильно).
полностью игнорируется пробиванием у мобов. так как мобы игнорируют эффект на игроке. они бьют в броню.
нивелирует в ноль защиту вашей брони, потому что заменяет ее собой.
полностью уничтожает защиту брони от пробиваний со снижением урона, потому что у брони такой параметр есть (и по вашим же тестам это водно, с броней моб бьет меньше), а вот у эффекта такого параметра НЕТ - он просто эффект.
А так как на время действия эффекта он замещает собой вашу броню (потому что у энтити НЕ МОЖЕТ быть два одинаковых эффекта) - то ваша защита равна НУЛЮ на действие этого баффа.
Так же, данный щит принимает урон в существующую на вашем персонаже в данный момент ману. Маны нет - нет защиты.
Мобы ликанитов НЕ бьют в ману, им плевать на вашу ману. Они бьют в броню, которая у вас равна нулю, потому что на энтити не может быть двух одинаковых эффектов.
Данный бафф имеет смысл использовать только БЕЗ брони вообще, ЛИБО на броню, которая дает ДРУГИЕ эффекты. Любые другие, кроме брони. ЛИБО учитывать, что ваша броня во время действия этого баффа равна нулю.
Работает абсолютно верно.
Так же, не стоит считать урон от мобов, равным определенной цифре. У всех мобов на руне без исключения, урон варьируется от точка A до точки B, то есть не имеют жестко заданных параметров. Один и тот же моб, за одну и ту же серию атак, может ударить с разной силой, с разными процентом пробивания и с разными эффектами. Каждый удар рассчитывается заново. В целом все они подчиняются статам моба, но так как статы не имеют жестких рамок, а все заданы от А до Б - любой входящий дамаг от моба на каждый тик может быть разным.
Так же, не стоит тестировать в сингле. Либо Вам нужно в сингл добыть точно таких же мобов. С точно такими же параметрами.
Что невозможно, так как сингл и моды на нем установленные этого просто не поддерживают.
код:
Код:
@SubscribeEvent
public void onEntityAttacked(LivingAttackEvent event)
{
if (event.source.isFireDamage() && event.entityLiving instanceof EntityPlayer && ((EntityPlayer) event.entityLiving).inventory.armorInventory[3] != null && ((EntityPlayer) event.entityLiving).inventory.armorInventory[3].getItem() == ItemsCommonProxy.fireEars)
event.setCanceled(true);
else if (event.entityLiving.isPotionActive(BuffList.manaShield) && ExtendedProperties.For(event.entityLiving).getCurrentMana() >= event.ammount * 250.0F)
{
ExtendedProperties.For(event.entityLiving).deductMana(event.ammount * 100.0F);
ExtendedProperties.For(event.entityLiving).forceSync();
for (int i = 0; i < Math.min(event.ammount, 5 * AMCore.config.getGFXLevel()); ++i)
{
AMCore.proxy.particleManager.BoltFromPointToPoint(event.entityLiving.worldObj, event.entityLiving.posX, event.entityLiving.posY + event.entityLiving.worldObj.rand.nextFloat() * event.entityLiving.getEyeHeight(), event.entityLiving.posZ, event.entityLiving.posX - 1.0D + event.entityLiving.worldObj.rand.nextFloat() * 2.0F, event.entityLiving.posY - 1.0D + event.entityLiving.worldObj.rand.nextFloat() * 2.0F, event.entityLiving.posZ - 1.0D + event.entityLiving.worldObj.rand.nextFloat() * 2.0F, 6, -1);
}
event.entityLiving.worldObj.playSoundAtEntity(event.entityLiving, "arsmagica2:misc.event.mana_shield_block", 1.0F, event.entityLiving.worldObj.rand.nextFloat() + 0.5F);
event.setCanceled(true);
}
}
Код:
@SubscribeEvent
public void onEntityHurt(LivingHurtEvent event)
{
if (event.source.isFireDamage() && event.entityLiving instanceof EntityPlayer && ((EntityPlayer) event.entityLiving).inventory.armorInventory[3] != null && ((EntityPlayer) event.entityLiving).inventory.armorInventory[3].getItem() == ItemsCommonProxy.fireEars)
event.setCanceled(true);
else
{
if (event.entityLiving.isPotionActive(BuffList.magicShield))
event.ammount *= 0.25F;
if (event.entityLiving.isPotionActive(BuffList.manaShield))
{
float manaToTake = Math.min(ExtendedProperties.For(event.entityLiving).getCurrentMana(), event.ammount * 250.0F);
event.ammount -= manaToTake / 250.0F;
ExtendedProperties.For(event.entityLiving).deductMana(manaToTake);
ExtendedProperties.For(event.entityLiving).forceSync();
for (int i = 0; i < Math.min(event.ammount, 5 * AMCore.config.getGFXLevel()); ++i)
{
AMCore.proxy.particleManager.BoltFromPointToPoint(event.entityLiving.worldObj, event.entityLiving.posX, event.entityLiving.posY + event.entityLiving.worldObj.rand.nextFloat() * event.entityLiving.getEyeHeight(), event.entityLiving.posZ, event.entityLiving.posX - 1.0D + event.entityLiving.worldObj.rand.nextFloat() * 2.0F, event.entityLiving.posY + event.entityLiving.getEyeHeight() - 1.0D + event.entityLiving.worldObj.rand.nextFloat() * 2.0F, event.entityLiving.posZ - 1.0D + event.entityLiving.worldObj.rand.nextFloat() * 2.0F, 6, -1);
}
event.entityLiving.worldObj.playSoundAtEntity(event.entityLiving, "arsmagica2:misc.event.mana_shield_block", 1.0F, event.entityLiving.worldObj.rand.nextFloat() + 0.5F);
if (event.ammount <= 0.0F)
{
event.setCanceled(true);
return;
}
}
Entity entitySource = event.source.getSourceOfDamage();
if (entitySource instanceof EntityPlayer && ((EntityPlayer) entitySource).inventory.armorInventory[2] != null && ((EntityPlayer) entitySource).inventory.armorInventory[2].getItem() == ItemsCommonProxy.earthGuardianArmor && ((EntityPlayer) entitySource).getCurrentEquippedItem() == null)
{
event.ammount += 4.0F;
if (EventConfig.enableEarthArmorKnockback)
{
double deltaZ = event.entityLiving.posZ - entitySource.posZ;
double deltaX = event.entityLiving.posX - entitySource.posX;
double angle = Math.atan2(deltaZ, deltaX);
double speed = entitySource.isSprinting() ? 3.0D : 2.0D;
double vertSpeed = entitySource.isSprinting() ? 0.5D : 0.325D;
if (event.entityLiving instanceof EntityPlayer)
AMNetHandler.INSTANCE.sendVelocityAddPacket(event.entityLiving.worldObj, event.entityLiving, speed * Math.cos(angle), vertSpeed, speed * Math.sin(angle));
else
{
event.entityLiving.motionX += speed * Math.cos(angle);
event.entityLiving.motionZ += speed * Math.sin(angle);
event.entityLiving.motionY += vertSpeed;
}
}
event.entityLiving.worldObj.playSoundAtEntity(event.entityLiving, "arsmagica2:spell.cast.earth", 0.4F, event.entityLiving.worldObj.rand.nextFloat() * 0.1F + 0.9F);
}
EntityLivingBase ent = event.entityLiving;
ExtendedProperties extendedProperties = ExtendedProperties.For(ent);
if (HURT_PROCESSING_ENTITIES.add(ent))
{
try
{
if (extendedProperties.getContingencyType() == ContingencyTypes.DAMAGE_TAKEN)
extendedProperties.procContingency();
if (extendedProperties.getContingencyType() == ContingencyTypes.HEALTH_LOW && ent.getHealth() <= ent.getMaxHealth() / 3.0F)
extendedProperties.procContingency();
}
finally
{
HURT_PROCESSING_ENTITIES.remove(ent);
}
}
if (ent.isPotionActive(BuffList.fury.id))
event.ammount /= 2.0F;
if (entitySource instanceof EntityLivingBase && ((EntityLivingBase) entitySource).isPotionActive(BuffList.shrink))
event.ammount /= 2.0F;
}
}
Работает идеально верно.
Не баг. Закрыт.