public virtual void InitTurretMotes(Vector3 loc, float angle) { if (!VerbProps.motes.NullOrEmpty()) { foreach (AnimationProperties moteProps in VerbProps.motes) { Vector3 moteLoc = loc; if (loc.ShouldSpawnMotesAt(caster.Map)) { try { float altitudeLayer = Altitudes.AltitudeFor(moteProps.moteDef.altitudeLayer); moteLoc += new Vector3(VerbProps.shootOffset.x + moteProps.offset.x, altitudeLayer + moteProps.offset.y, VerbProps.shootOffset.y + moteProps.offset.z).RotatedBy(angle); Mote mote = (Mote)ThingMaker.MakeThing(moteProps.moteDef); mote.exactPosition = moteLoc; mote.exactRotation = moteProps.exactRotation.RandomInRange; mote.instanceColor = moteProps.color; mote.rotationRate = moteProps.rotationRate; mote.Scale = moteProps.scale; if (mote is MoteThrown thrownMote) { float thrownAngle = angle + moteProps.angleThrown.RandomInRange; thrownMote.SetVelocity(thrownAngle, moteProps.speedThrown.RandomInRange); if (thrownMote is MoteThrownExpand expandMote) { if (expandMote is MoteThrownSlowToSpeed accelMote) { accelMote.SetDecelerationRate(moteProps.deceleration.RandomInRange, moteProps.fixedAcceleration, thrownAngle); } expandMote.growthRate = moteProps.growthRate.RandomInRange; } } if (mote is Mote_CannonPlume cannonMote) { cannonMote.cyclesLeft = moteProps.cycles; cannonMote.animationType = moteProps.animationType; cannonMote.angle = angle; } mote.def = moteProps.moteDef; mote.PostMake(); GenSpawn.Spawn(mote, moteLoc.ToIntVec3(), caster.Map, WipeMode.Vanish); } catch (Exception ex) { SmashLog.Error($"Failed to spawn mote at {loc}. MoteDef = <field>{moteProps.moteDef?.defName ?? "Null"}</field> Exception = {ex.Message}"); } } } } }