private void CharacterHited(Character character, int damage) { //Hit ratio var targetEvade = character.Evade; var belongCharacterEvade = BelongCharacter.Evade; const float maxOffset = 100f; const float baseHitRatio = 0.05f; const float belowRatio = 0.5f; const float upRatio = 0.45f; var hitRatio = baseHitRatio; if (targetEvade >= belongCharacterEvade) { hitRatio += ((float)belongCharacterEvade / (float)targetEvade) * belowRatio; } else { var upOffsetRatio = ((float)belongCharacterEvade - targetEvade) / maxOffset; if (upOffsetRatio > 1f) { upOffsetRatio = 1f; } hitRatio += belowRatio + upOffsetRatio * upRatio; } if (Globals.TheRandom.Next(101) <= (int)(hitRatio * 100f)) { var effect = damage - character.Defend; foreach (var magicSprite in character.MagicSpritesInEffect) { var magic = magicSprite.BelongMagic; switch (magic.MoveKind) { case 13: if (magic.SpecialKind == 3) { //Target character have protecter var damageReduce = MagicManager.GetEffectAmount(magic, character); effect -= damageReduce; } break; } } if (effect > character.Life) { //Effect amount should less than or equal target character current life amount. effect = character.Life; } character.DecreaseLifeAddHurt(effect < MinimalDamage ? MinimalDamage : effect); //Restore if (BelongMagic.RestoreProbability > 0 && Globals.TheRandom.Next(0, 100) < BelongMagic.RestoreProbability) { var restoreAmount = (effect * BelongMagic.RestorePercent) / 100; switch ((Magic.RestorePropertyType)BelongMagic.RestoreType) { case Magic.RestorePropertyType.Life: BelongCharacter.AddLife(restoreAmount); break; case Magic.RestorePropertyType.Mana: BelongCharacter.AddMana(restoreAmount); break; case Magic.RestorePropertyType.Thew: BelongCharacter.AddThew(restoreAmount); break; default: throw new ArgumentOutOfRangeException(); } } } { Player player = null; MagicListManager.MagicItemInfo info = null; if (BelongCharacter.IsPlayer) { player = BelongCharacter as Player; info = BelongMagic.ItemInfo; } else if (BelongCharacter.ControledMagicSprite != null) { player = BelongCharacter.ControledMagicSprite.BelongCharacter as Player; if (player != null) { info = player.CurrentMagicInUse; } } else if (BelongCharacter.SummonedByMagicSprite != null && BelongCharacter.SummonedByMagicSprite.BelongCharacter.IsPlayer) { //Summoned by player, add player's exp player = BelongCharacter.SummonedByMagicSprite.BelongCharacter as Player; if (player != null) { info = player.CurrentMagicInUse; } } if (player != null && info != null) { var amount = Utils.GetMagicExp(character.Level); player.AddMagicExp(info, amount); } } }
private void CharacterHited(Character character, int damage, int damage2, int damageMana, bool addMagicHitedExp = true) { var isInDeath = character.IsDeathInvoked; character.LastAttackerMagicSprite = this; //Hit ratio var targetEvade = character.Evade; var belongCharacterEvade = BelongCharacter.Evade; const float maxOffset = 100f; const float baseHitRatio = 0.05f; const float belowRatio = 0.5f; const float upRatio = 0.45f; var hitRatio = baseHitRatio; if (targetEvade >= belongCharacterEvade) { hitRatio += ((float)belongCharacterEvade / (float)targetEvade) * belowRatio; } else { var upOffsetRatio = ((float)belongCharacterEvade - targetEvade) / maxOffset; if (upOffsetRatio > 1f) { upOffsetRatio = 1f; } hitRatio += belowRatio + upOffsetRatio * upRatio; } if (_parasitiferCharacter != null || Globals.TheRandom.Next(101) <= (int)(hitRatio * 100f)) { var effect2 = damage2 - character.Defend2; var effect = (damage - character.Defend); foreach (var magicSprite in character.MagicSpritesInEffect) { var magic = magicSprite.BelongMagic; switch (magic.MoveKind) { case 13: if (magic.SpecialKind == 3) { //Target character have protecter var damageReduce = MagicManager.GetEffectAmount(magic, character); var damageReduce2 = MagicManager.GetEffectAmount2(magic, character); effect2 -= damageReduce2; effect -= damageReduce; } break; } } if (effect2 > 0) { effect += effect2; } if (effect > character.Life) { //Effect amount should less than or equal target character current life amount. effect = character.Life; } character.DecreaseLifeAddHurt(effect < MinimalDamage ? MinimalDamage : effect); character.DecreaseMana(damageMana); //Restore if (BelongMagic.RestoreProbability > 0 && Globals.TheRandom.Next(0, 100) < BelongMagic.RestoreProbability) { var restoreAmount = (effect * BelongMagic.RestorePercent) / 100; switch ((Magic.RestorePropertyType)BelongMagic.RestoreType) { case Magic.RestorePropertyType.Life: BelongCharacter.AddLife(restoreAmount); break; case Magic.RestorePropertyType.Mana: BelongCharacter.AddMana(restoreAmount); break; case Magic.RestorePropertyType.Thew: BelongCharacter.AddThew(restoreAmount); break; default: throw new ArgumentOutOfRangeException(); } } } if (_parasitiferCharacter != null) { _totalParasticEffect += damage; } if (character.MagicToUseWhenBeAttacked != null) { Vector2 destination; Character target = null; var dirType = (Character.BeAttackedUseMagicDirection)character.MagicDirectionWhenBeAttacked; switch (dirType) { case Character.BeAttackedUseMagicDirection.Attacker: destination = BelongCharacter.PositionInWorld; target = BelongCharacter; break; case Character.BeAttackedUseMagicDirection.MagicSpriteOppDirection: destination = RealMoveDirection == Vector2.Zero ? (character.PositionInWorld + Utils.GetDirection8(character.CurrentDirection)) : (character.PositionInWorld - RealMoveDirection); break; case Character.BeAttackedUseMagicDirection.CurrentNpcDirection: destination = character.PositionInWorld + Utils.GetDirection8(character.CurrentDirection); break; default: destination = BelongCharacter.PositionInWorld; break; } MagicManager.UseMagic(character, character.MagicToUseWhenBeAttacked, character.PositionInWorld, destination, target); } { Player player = null; MagicListManager.MagicItemInfo info = null; if (BelongCharacter.IsPlayer) { player = BelongCharacter as Player; info = BelongMagic.ItemInfo; } else if (BelongCharacter.ControledMagicSprite != null) { player = BelongCharacter.ControledMagicSprite.BelongCharacter as Player; if (player != null) { info = player.CurrentMagicInUse; } } else if (BelongCharacter.SummonedByMagicSprite != null && BelongCharacter.SummonedByMagicSprite.BelongCharacter.IsPlayer) { //Summoned by player, add player's exp player = BelongCharacter.SummonedByMagicSprite.BelongCharacter as Player; if (player != null) { info = player.CurrentMagicInUse; } } if (addMagicHitedExp && player != null && info != null) { var amount = Utils.GetMagicExp(character.Level); player.AddMagicExp(info, amount); } } //Exp if (BelongCharacter.IsPlayer || BelongCharacter.IsFighterFriend) { character.NotifyEnemyAndAllNeighbor(BelongCharacter); var isSummonedByPlayerorPartner = (BelongCharacter.SummonedByMagicSprite != null && (BelongCharacter.SummonedByMagicSprite.BelongCharacter.IsPlayer || BelongCharacter.SummonedByMagicSprite.BelongCharacter.IsPartner)); var isControledByPlayer = (BelongCharacter.ControledMagicSprite != null && BelongCharacter.ControledMagicSprite.BelongCharacter.IsPlayer); //Hited character death if (!isInDeath && //Alive before hited character.IsInDeathing && //Death after hited (BelongCharacter.IsPlayer || BelongCharacter.IsPartner || isSummonedByPlayerorPartner || isControledByPlayer)) { var player = Globals.ThePlayer; var exp = Utils.GetCharacterDeathExp(Globals.ThePlayer, character); player.AddExp(exp, true); } } }
/// <summary> /// Use magic. /// </summary> /// <param name="user">The magic user.</param> /// <param name="magic">Magic to use.</param> /// <param name="origin">Magic initial pixel postion in world.</param> /// <param name="destination">Magic destination pixel postiont in world.</param> /// <param name="target">Magic target</param> /// <param name="recursiveCounter"></param> public static void UseMagic(Character user, Magic magic, Vector2 origin, Vector2 destination, Character target = null, int recursiveCounter = 0) { if (user == null || magic == null) { return; } if (magic.SecondMagicFile != null) { AddUseMagicItem(new UseMagicInfoItem(magic.SecondMagicDelay, user, magic.SecondMagicFile, origin, destination, target)); } if (magic.BodyRadius > 0 && target != null && recursiveCounter == 0) { foreach (var body in ObjManager.GetBodyInRaidus(target.TilePosition, magic.BodyRadius, true)) { UseMagic(user, magic, body.PositionInWorld, destination, target, recursiveCounter + 1); } return; } _maigicSpriteIndex = 0; if (magic.FlyingSound != null) { magic.FlyingSound.Play(); } if (magic.BeginAtMouse > 0) { var dir = origin - destination; if (dir != Vector2.Zero) { dir.Normalize(); } origin = destination + dir; } else if (magic.BeginAtUser > 0) { destination = origin; } else if (magic.BeginAtUserAddDirectionOffset > 0) { var dir = destination - origin; if (dir != Vector2.Zero) { dir.Normalize(); } destination = origin + dir; } else if (magic.BeginAtUserAddUserDirectionOffset > 0) { var dir = Utils.GetDirection8(user.CurrentDirection); destination = origin + dir; } if (magic.MeteorMove > 0) { origin = destination; } switch (magic.MoveKind) { case 1: AddFixedPositionMagicSprite(user, magic, destination, true); break; case 2: AddMagicSprite(GetMoveMagicSprite(user, magic, origin, destination, false, GetSpeedRatio(destination - origin))); break; case 3: AddLineMoveMagicSprite(user, magic, origin, destination, false); break; case 4: AddCircleMoveMagicSprite(user, magic, origin, false); break; case 5: AddHeartMoveMagicSprite(user, magic, origin, false); break; case 6: AddSpiralMoveMagicSprite(user, magic, origin, destination, false); break; case 7: AddSectorMoveMagicSprite(user, magic, origin, destination, false); break; case 8: AddRandomSectorMoveMagicSprite(user, magic, origin, destination, false); break; case 9: AddFixedWallMagicSprite(user, magic, origin, destination, true); break; case 10: AddWallMoveMagicSprite(user, magic, origin, destination, false); break; case 11: { switch (magic.Region) { case 1: AddSquareFixedPositionMagicSprite(user, magic, destination, true); break; case 2: AddCrossFixedPositionMagicSprite(user, magic, origin, true); break; case 3: AddRegtangleFixedPositionMagicSprite(user, magic, origin, destination, true); break; case 4: AddIsoscelesTriangleMagicSprite(user, magic, origin, destination, true); break; case 5: AddVTypeFixedPOsitionMagicSprite(user, magic, origin, destination, true); break; case 6: AddRegionFileMagicSprite(user, magic, origin, destination, true); break; } break; } case 13: case 23: AddFollowCharacterMagicSprite(user, magic, origin, true, target); break; case 15: AddSuperModeMagic(user, magic, origin, true); break; case 16: AddFollowEnemyMagicSprite(user, magic, origin, destination, false); break; case 17: AddThrowMagicSprite(user, magic, origin, destination, true); break; case 18: //Empty break; case 19: { var info = new Kind19MagicInfo(magic.KeepMilliseconds, magic, user); _kind19Magics.AddLast(info); } break; case 20: { //Can't use transport magic when in transport if (!user.IsInTransport) { user.IsInTransport = true; AddFixedPositionMagicSprite(user, magic, destination, true); } } break; case 21: { var player = user as Player; if (player != null && target != null && !target.IsDeathInvoked && // Can't control dead people target.Level <= magic.MaxLevel ) { player.ControledCharacter = target; AddFixedPositionMagicSprite(user, magic, user.PositionInWorld, true); } } break; case 22: { AddFixedPositionMagicSprite(user, magic, destination, true); } break; } //Magic side effect if (magic.SideEffectProbability > 0 && Globals.TheRandom.Next(0, 100) < magic.SideEffectProbability) { var amount = ((GetEffectAmount(magic, user) + GetEffectAmount2(magic, user)) * magic.SideEffectPercent) / 100; switch ((Magic.SideEffectDamageType)magic.SideEffectType) { case Magic.SideEffectDamageType.Life: user.DecreaseLifeAddHurt(amount); break; case Magic.SideEffectDamageType.Mana: user.AddMana(-amount); break; case Magic.SideEffectDamageType.Thew: user.AddThew(-amount); break; default: throw new ArgumentOutOfRangeException(); } } if (magic.DieAfterUse > 0) { user.Death(); } }