public InteractiveNPC(World world, int actorSNO, Vector3D position) : base(world, actorSNO, position) { this.Attributes[GameAttribute.NPC_Has_Interact_Options, 0] = true; this.Attributes[GameAttribute.NPC_Is_Operatable] = true; this.Attributes[GameAttribute.Buff_Visual_Effect, 0x00FFFFF] = true; }
public Projectile(PowerContext context, int actorSNO, Vector3D position) : base(context.World, actorSNO) { this.Field2 = 0x8; this.Scale = 1.35f; // just use default? GBHandle.Projectile is 10, but most projectiles I see use 17 //this.GBHandle.Type = (int)GBHandleType.Projectile; this.GBHandle.GBID = 1; this.Field7 = 0x00000001; // these no longer needed? //this.Field10 = 0x1; //this.Field11 = 0x1; //this.Field12 = 0x1; //this.Field13 = 0x1; //this.CollFlags = 0x4; this.Context = context; this.Position = new Vector3D(position); this.Timeout = new SecondsTickTimer(context.World.Game, 2f); // 2 second default timeout for projectiles // copy in important effect params from user this.Attributes[GameAttribute.Rune_A, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_A, context.PowerSNO]; this.Attributes[GameAttribute.Rune_B, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_B, context.PowerSNO]; this.Attributes[GameAttribute.Rune_C, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_C, context.PowerSNO]; this.Attributes[GameAttribute.Rune_D, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_D, context.PowerSNO]; this.Attributes[GameAttribute.Rune_E, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_E, context.PowerSNO]; _arrivalTime = null; _lastUpdateTick = 0; _prevUpdatePosition = null; _onArrivalCalled = false; // offset position by mpq collision data this.Position.Z += this.ActorData.Cylinder.Ax1 - this.ActorData.Cylinder.Position.Z; }
/// <summary> /// Parses AABB from given GameBitBuffer. /// </summary> /// <param name="buffer">The GameBitBuffer to parse from.</param> public void Parse(GameBitBuffer buffer) { Min = new Vector3D(); Min.Parse(buffer); Max = new Vector3D(); Max.Parse(buffer); }
public Living(World world, int actorSNO, Vector3D position, Dictionary<int, TagMapEntry> tags) : base(world, world.NewActorID, position, tags ) { this.SNOId = actorSNO; // FIXME: This is hardcoded crap this.Field3 = 0x0; this.RotationAmount = (float)(RandomHelper.NextDouble() * 2.0f * Math.PI); this.RotationAxis.X = 0f; this.RotationAxis.Y = 0f; this.RotationAxis.Z = 1f; this.GBHandle.Type = -1; this.GBHandle.GBID = -1; this.Field7 = 0x00000001; this.Field8 = this.SNOId; this.Field10 = 0x0; this.Field11 = 0x0; this.Field12 = 0x0; this.Field13 = 0x0; this.AnimationSNO = 0x11150; this.CollFlags = 1; this.Attributes[GameAttribute.Hitpoints_Max_Total] = 4.546875f; this.Attributes[GameAttribute.Hitpoints_Max] = 4.546875f; this.Attributes[GameAttribute.Hitpoints_Total_From_Level] = 0f; this.Attributes[GameAttribute.Hitpoints_Cur] = 4.546875f; this.Attributes[GameAttribute.Level] = 1; }
public static Vector3D TranslateDirection2D(Vector3D source, Vector3D destination, Vector3D point, float amount) { Vector3D norm = Normalize(new Vector3D(destination.X - source.X, destination.Y - source.Y, 0f)); return new Vector3D(point.X + norm.X * amount, point.Y + norm.Y * amount, point.Z); }
public override void Parse(GameBitBuffer buffer) { ActorId = buffer.ReadInt(32); if (buffer.ReadBool()) { Position = new Vector3D(); Position.Parse(buffer); } if (buffer.ReadBool()) { Angle = buffer.ReadFloat32(); } if (buffer.ReadBool()) { TurnImmediately = buffer.ReadBool(); } if (buffer.ReadBool()) { Speed = buffer.ReadFloat32(); } if (buffer.ReadBool()) { Field5 = buffer.ReadInt(25); } if (buffer.ReadBool()) { AnimationTag = buffer.ReadInt(21) + (-1); } if (buffer.ReadBool()) { Field7 = buffer.ReadInt(32); } }
/// <summary> /// Reads PRTransform from given GameBitBuffer. /// </summary> /// <param name="buffer">The GameBitBuffer to parse from.</param> public void Parse(GameBitBuffer buffer) { Quaternion = new Quaternion(); Quaternion.Parse(buffer); Vector3D = new Vector3D(); Vector3D.Parse(buffer); }
public Vendor(World world, int actorSNO, Vector3D position, Dictionary<int, TagMapEntry> tags) : base(world, actorSNO, position, tags) { this.Attributes[GameAttribute.MinimapActive] = true; _vendorGrid = new InventoryGrid(this, 1, 20, (int) EquipmentSlotId.Vendor); PopulateItems(); }
public bool RunPower(Actor user, PowerScript power, Actor target = null, Vector3D targetPosition = null, TargetMessage targetMessage = null) { // replace power with existing channel instance if one exists if (power is ChanneledSkill) { var existingChannel = _FindChannelingSkill(user, power.PowerSNO); if (existingChannel != null) { power = existingChannel; } else // new channeled skill, add it to the list { _channeledSkills.Add((ChanneledSkill)power); } } // copy in context params power.User = user; power.Target = target; power.World = user.World; power.TargetPosition = targetPosition; power.TargetMessage = targetMessage; _StartScript(power); return true; }
protected void InFrontPostion() // spawn actor in front of user { float userFacing = (float)Math.Acos(this.User.RotationW) * 2f; this.SpawnPosition = new Vector3D(User.Position.X + 8 * (float)Math.Cos(userFacing), User.Position.Y + 8 * (float)Math.Sin(userFacing), User.Position.Z); }
private bool _spawned; // using my own spawn flag cause Actor.Spawned isn't being used right now public Projectile(PowerContext context, int actorSNO, Vector3D position) : base(context.World, actorSNO) { this.Field2 = 0x8; this.Field7 = 0x00000001; // TODO: test if this is necessary if (this.Scale == 0f) this.Scale = 1.00f; this.Context = context; this.Position = new Vector3D(position); // offset position by mpq collision data this.Position.Z += this.ActorData.Cylinder.Ax1 - this.ActorData.Cylinder.Position.Z; // 2 second default timeout for projectiles this.Timeout = new SecondsTickTimer(context.World.Game, 2f); // copy in important effect params from user this.Attributes[GameAttribute.Rune_A, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_A, context.PowerSNO]; this.Attributes[GameAttribute.Rune_B, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_B, context.PowerSNO]; this.Attributes[GameAttribute.Rune_C, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_C, context.PowerSNO]; this.Attributes[GameAttribute.Rune_D, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_D, context.PowerSNO]; this.Attributes[GameAttribute.Rune_E, context.PowerSNO] = context.User.Attributes[GameAttribute.Rune_E, context.PowerSNO]; _prevUpdatePosition = null; _mover = new ActorMover(this); _spawned = false; }
public static Actor Create(World world, int snoId, Vector3D position, TagMap tagMap) { if (!MPQStorage.Data.Assets[SNOGroup.Actor].ContainsKey(snoId)) return null; var actorAsset = MPQStorage.Data.Assets[SNOGroup.Actor][snoId]; var actorData = actorAsset.Data as Mooege.Common.MPQ.FileFormats.Actor; if (actorData == null) return null; if (actorData.Type == ActorType.Invalid) return null; // read tagMapEntries and put them into a dictionary var tags = tagMap.TagMapEntries.ToDictionary(entry => entry.Int1); // see if we have an implementation for actor. if (SNOHandlers.ContainsKey(snoId)) return (Actor) Activator.CreateInstance(SNOHandlers[snoId], new object[] {world, snoId, position, tags}); switch (actorData.Type) { case ActorType.Monster: return new Monster(world, snoId, position, tags); case ActorType.Gizmo: return CreateGizmo(world, snoId, position, tags); } return null; }
private static Actor CreateGizmo(World world, int snoId, Vector3D position, Dictionary<int,TagMapEntry> tags) { if (tags.ContainsKey((int)MarkerTagTypes.DestinationWorld)) return new Portal(world, snoId, position, tags); return new Gizmo(world, snoId, position, tags); }
public void Spawn(float facingAngle = 0) { FacingAngle = (float)Math.Cos(facingAngle / 2f); RotationAxis = new Vector3D(0, 0, (float)Math.Sin(facingAngle / 2f)); this.World.Enter(this); }
/// <summary> /// Returns 2D angle to face the target position. /// </summary> /// <param name="lookerPosition">The looker.</param> /// <param name="targetPosition">The target.</param> /// <returns></returns> public static float GetFacingAngle(Vector3D lookerPosition, Vector3D targetPosition) { if ((lookerPosition == null) || (targetPosition == null)) return 0f; return (float) Math.Atan2((targetPosition.Y - lookerPosition.Y), (targetPosition.X - lookerPosition.X)); }
public static Vector3D GetMovementPosition(Vector3D position, float speed, float facingAngle, int ticks = 6) { var xDelta = (speed * ticks) * (float)Math.Cos(facingAngle); var yDelta = (speed * ticks) * (float)Math.Sin(facingAngle); return new Vector3D(position.X + xDelta, position.Y + yDelta, position.Z); }
protected WorldObject(World world, uint dynamicID) : base(dynamicID) { this._world = world; // Specifically avoid calling the potentially overridden setter for this.World /komiga. this._world.Game.StartTracking(this); this._rotationAxis = new Vector3D(); this._position = new Vector3D(); }
public MoveToPointWithPathfindAction(Actor owner, Vector3D heading) : base(owner) { // Sending a request for a Path to the Pathing thread. _pathRequestTask = owner.World.Game.Pathfinder.GetPath(owner, owner.Position, heading); this.Heading = heading; }
public override void Parse(GameBitBuffer buffer) { Field0 = buffer.ReadInt(32); Field1 = new Vector3D(); Field1.Parse(buffer); Field2 = new Vector3D(); Field2.Parse(buffer); }
//This submits a request for a path to the pathfinder thread. This is the main point of entry for usage. - DarkLotus public PathRequestTask GetPath(Actor owner, Vector3D vector3D, Vector3D heading) { if (aipather == null) aipather = new Pathfinder(); var pathRequestTask = new PathRequestTask(aipather, owner, owner.Position, heading); _queuedPathTasks.TryAdd(owner.DynamicID, pathRequestTask); return pathRequestTask; }
public bool IsWithin(Vector3D v) { if (v >= this.Min && v <= this.Max) { return true; } return false; }
public Gizmo(World world, int actorSNO, Vector3D position, Dictionary<int, TagMapEntry> tags) : base(world, world.NewActorID, position, tags) { this.SNOId = actorSNO; this.Field2 = 16; this.Field3 = 0x0; this.Field7 = 0x00000001; this.Field8 = this.SNOId; }
public override void Parse(GameBitBuffer buffer) { Field0 = buffer.ReadInt(32); Field1 = new Vector3D(); Field1.Parse(buffer); Field2 = buffer.ReadFloat32(); Field3 = buffer.ReadBool(); Field4 = buffer.ReadInt(25); }
public static Vector3D ProjectAndTranslate2D(Vector3D a, Vector3D b, Vector3D position, float amount) { Vector3D r = new Vector3D(position); Vector3D ab_norm = Normalize(new Vector3D(b.X - a.X, b.Y - a.Y, 0/*b.Z - a.Z*/)); // 2D r.X += ab_norm.X * amount; r.Y += ab_norm.Y * amount; //r.Z += ab_norm.Z * amount; return r; }
public NPC(World world, int actorSNO, Vector3D position, Dictionary<int, TagMapEntry> tags) : base(world, actorSNO, position, tags) { this.Field2 = 0x9; this.Field7 = 1; this.Field8 = actorSNO; //TODO check if this is not true for every actor / living? /fasbat this.Attributes[GameAttribute.TeamID] = 1; this.Attributes[GameAttribute.Is_NPC] = true; }
public static Vector3D VectorRotateZ(Vector3D v, float radians) { float cosRad = (float)Math.Cos(radians); float sinRad = (float)Math.Sin(radians); return new Vector3D(v.X * cosRad - v.Y * sinRad, v.X * sinRad + v.Y * cosRad, v.Z); }
public PowerProjectile(World world, int actorSNO, Vector3D position, Vector3D aimPosition, float speed, float timetolive, float scale = 1.35f, float collisionError = 3f, float heightOffset = 0, float distanceOffset = 0, bool handleTranslation = false) : base(world, actorSNO) { this.startingPosition = new Vector3D(position); this.startingPosition.Z += heightOffset; this.speed = speed; this.timetolive = timetolive; this.collisionError = collisionError + heightOffset; //Timeout = new TickSecondsTimer(this.World.Game, timetolive / 1000f); //Save projectile creation tick this.creationTick = this.World.Game.TickCounter; // FIXME: This is hardcoded crap this.Field2 = 0x8; this.Field3 = 0x0; this.Scale = 1f; this.GBHandle.Type = (int)GBHandleType.Monster; this.GBHandle.GBID = 1; this.Field7 = 0x00000001; //this.Field8 = this.SNOId; this.Field10 = 0x1; this.Field11 = 0x1; this.Field12 = 0x1; this.Field13 = 0x1; this.CollFlags = 0x4; //Calculate Quaternion info this.radianAngle = PowerMath.AngleLookAt(startingPosition, aimPosition); //Assign quaternion info this.RotationAmount = (float)Math.Cos(this.radianAngle / 2); this.RotationAxis.X = 0f; this.RotationAxis.Y = 0f; this.RotationAxis.Z = (float)Math.Sin(this.radianAngle / 2); //Normalize position / aimPosition Vector Vector3D vel_normal = PowerMath.Normalize(new Vector3D(aimPosition.X - startingPosition.X, aimPosition.Y - startingPosition.Y, 0f)); this.velocity = new Vector3D(vel_normal.X * speed, vel_normal.Y * speed, vel_normal.Z * speed); //Adjust projectile distance from player this.startingPosition.X += this.velocity.X * distanceOffset; this.startingPosition.Y += this.velocity.Y * distanceOffset; this.Position = this.startingPosition; this.World.Enter(this); // Enter only once all fields have been initialized to prevent a run condition //If the creator dont specify he want to manipulate the projectil itself, launch it if (!handleTranslation) this.launch(); }
public override IEnumerable<TickTimer> Run() { UsePrimaryResource(ScriptFormula(8)); // cast effect User.PlayEffectGroup(RuneSelect(71141, 71141, 71141, 92222, 217377, 217461)); // HACK: mooege's 100ms update rate is a little to slow for the impact to appear right on time so // an 100ms is shaved off the wait time TickTimer waitForImpact = WaitSeconds(ScriptFormula(4) - 0.1f); List<Vector3D> impactPositions = new List<Vector3D>(); int meteorCount = Rune_B > 0 ? (int)ScriptFormula(9) : 1; // pending effect + meteor for (int n = 0; n < meteorCount; ++n) { Vector3D impactPos; if (meteorCount > 1) impactPos = new Vector3D(TargetPosition.X + ((float)Rand.NextDouble() - 0.5f) * 25, TargetPosition.Y + ((float)Rand.NextDouble() - 0.5f) * 25, TargetPosition.Z); else impactPos = TargetPosition; SpawnEffect(RuneSelect(86790, 215853, 91440, 92030, 217142, 217457), impactPos, 0, WaitSeconds(5f)); impactPositions.Add(impactPos); if (meteorCount > 1) yield return WaitSeconds(0.1f); } // wait for meteor impact(s) yield return waitForImpact; // impact effects foreach (var impactPos in impactPositions) { // impact SpawnEffect(RuneSelect(86769, 215809, 91441, 92031, 217139, 217458), impactPos); WeaponDamage(GetEnemiesInRadius(impactPos, ScriptFormula(3)), ScriptFormula(0), RuneSelect(DamageType.Fire, DamageType.Fire, DamageType.Fire, DamageType.Cold, DamageType.Arcane, DamageType.Fire)); // pool effect if (Rune_B == 0) { SpawnEffect(RuneSelect(90364, 90364, -1, 92032, 217307, 217459), impactPos, 0, WaitSeconds(ScriptFormula(5))); } if (meteorCount > 1) yield return WaitSeconds(0.1f); } }
public Environment(World world, int actorSNO, Vector3D position) : base(world, world.NewActorID) { this.ActorSNO = actorSNO; this.Field2 = 16; this.Field3 = 0x0; this.Field7 = 0x00000001; this.Field8 = this.ActorSNO; this.Scale = 1.35f; this.Position.Set(position); }
public override IEnumerable<TickTimer> Main() { GeneratePrimaryResource(ScriptFormula(17)); // fire projectile normally, or find targets in arc if RuneB Vector3D[] targetDirs; if (Rune_B > 0) { targetDirs = new Vector3D[(int)ScriptFormula(24)]; int takenPos = 0; foreach (Actor actor in GetEnemiesInArcDirection(User.Position, TargetPosition, 75f, ScriptFormula(12)).Actors) { targetDirs[takenPos] = actor.Position; ++takenPos; if (takenPos >= targetDirs.Length) break; } // generate any extra positions using generic spread if (takenPos < targetDirs.Length) { PowerMath.GenerateSpreadPositions(User.Position, TargetPosition, 10f, targetDirs.Length - takenPos) .CopyTo(targetDirs, takenPos); } } else { targetDirs = new Vector3D[] { TargetPosition }; } foreach (Vector3D position in targetDirs) { var proj = new Projectile(this, RuneSelect(77569, 153864, 153865, 153866, 153867, 153868), User.Position); proj.Position.Z += 5f; // fix height proj.OnCollision = (hit) => { // hit effect hit.PlayEffectGroup(RuneSelect(77577, 153870, 153872, 153873, 153871, 153869)); if (Rune_B > 0) WeaponDamage(hit, ScriptFormula(9), DamageType.Poison); else AddBuff(hit, new ExplosionBuff()); proj.Destroy(); }; proj.Launch(position, ScriptFormula(2)); if (Rune_B > 0) yield return WaitSeconds(ScriptFormula(13)); } }