So, changed up the code for ThrowAttack a bit, so that you can set an offset for the direction thrown. (Angle thrown at = Direction of the player + offset)
Replace everything inside your ThrowAttack.cs with this code
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using wServer.realm;
using wServer.realm.entities;
using wServer.svrPackets;
using Mono.Game;
using wServer.logic;
namespace wServer.logic.attack
{
class ThrowAttack : Behavior
{
float bombRadius;
float sightRadius;
int damage;
float offsetAngle;
private ThrowAttack(float bombRadius, float sightRadius, int damage, float offsetAngle)
{
this.bombRadius = bombRadius;
this.sightRadius = sightRadius;
this.damage = damage;
this.offsetAngle = offsetAngle;
}
static readonly Dictionary<Tuple<float, float, int, float>, ThrowAttack> instances = new Dictionary<Tuple<float, float, int, float>, ThrowAttack>();
public static ThrowAttack Instance(float bombRadius, float sightRadius, int damage, float offsetAngle = 0)
{
var key = new Tuple<float, float, int, float>(bombRadius, sightRadius, damage, offsetAngle);
ThrowAttack ret;
if (!instances.TryGetValue(key, out ret))
ret = instances[key] = new ThrowAttack(bombRadius, sightRadius, damage, offsetAngle);
return ret;
}
Random rand = new Random();
protected override bool TickCore(RealmTime time)
{
if (Host.Self.HasConditionEffect(ConditionEffects.Stunned)) return false;
float dist = sightRadius;
Entity player = GetNearestEntity(ref dist, null);
if (player != null)
{
var distance = Vector2.Distance(new Vector2(Host.Self.X, Host.Self.Y), new Vector2(player.X, player.Y));
var chr = Host as Character;
var angle = Math.Atan2(player.Y - chr.Y, player.X - chr.X)
+ offsetAngle;
Position target = new Position()
{
X = Host.Self.X,
Y = Host.Self.Y
};
target.X += (float)Math.Cos(angle) * distance;
target.Y += (float)Math.Sin(angle) * distance;
chr.Owner.BroadcastPacket(new ShowEffectPacket()
{
EffectType = EffectType.Throw,
Color = new ARGB(0xffff0000),
TargetId = Host.Self.Id,
PosA = target
}, null);
chr.Owner.Timers.Add(new WorldTimer(1500, (world, t) =>
{
world.BroadcastPacket(new AOEPacket()
{
Position = target,
Radius = bombRadius,
Damage = (ushort)damage,
EffectDuration = 0,
Effects = 0,
OriginType = Host.Self.ObjectType
}, null);
AOE(world, target, bombRadius, true, p =>
{
(p as IPlayer).Damage(damage, Host.Self as Character);
});
}));
return true;
}
return false;
}
}
}
The default offset is set to 0, so you don't have to go around changing all your existing ThrowAttacks; They'll still work the same.
Usage:
Code:
ThrowAttack.Instance(bombRadius, sightRadius, damage, offsetAngle)
Example:
Code:
ThrowAttack.Instance(3, 5, 150, 180 * (float)Math.PI / 180)
Credits:
@ProHackBot999 for some code