public static void ProcessUseSkill(ClientConnection client, UseSkill message) { var avatar = client.Avatar as MobileAvatar; if (avatar == null) { client.LogMessage("Requested a skill, but doesn't have an avatar."); return; } Schema.EnumSkillRow esr = Global.ModelSchema.EnumSkill.FindByEnumSkillID(message.SkillId); if (esr == null) { client.LogMessage("Requested an invalid skill " + message.SkillId); return; } // If already performing a skill invocation, just queue the request for later. if (avatar.ActivatingSkill != null) { avatar.SkillQueue.Enqueue(message); return; } if (esr.LeadTime <= 0) { // process it now UseSkillNow(avatar, message); } else { // process it later, after lead-time has elapsed avatar.ActivatingSkill = message; avatar.ActivatingSkillTimestamp = Global.Now; avatar.ActivatingSkillLeadTime = TimeSpan.FromSeconds(esr.LeadTime); } }
public static void ProcessUseSkill(this World world, ClientConnection client, UseSkill message) { var source = client.Avatar as CombatantModel; if (source == null) { client.LogMessage("Requested a skill without an avatar."); return; } Schema.EnumSkillRow esr = Global.Schema.EnumSkill.FindByEnumSkillID((int)message.Skill); if (esr == null) { client.LogMessage("Requested an invalid skill " + message.Skill); return; } EntityModel target; switch ((EnumTargetType)esr.EnumTargetTypeID) { case EnumTargetType.TargetSelf: target = source; break; case EnumTargetType.TargetMobile: if (message.TargetPhysicalObjectIDs.Length == 0) { world.LogMessage(source, "No target specified, this skill may only be used on Mobiles."); return; } target = world.History.Head.Entities.ValueOrDefault(message.TargetPhysicalObjectIDs[0]); if (target == null) { world.LogMessage(source, "Target " + message.TargetPhysicalObjectIDs[0] + " not found."); return; } break; default: world.LogMessage(source, "That skill has an unsupported target type " + esr.EnumTargetTypeID); Log.Error("Unhandled target type " + esr.EnumTargetTypeID + " for skill " + esr.EnumSkillID + " " + esr.EnumSkillName); return; } if (source.ActivatingSkill != EnumSkill.None) // queue the request for later. world.Apply(new EntityUpdateEvent( source.EnqueueSkill(message.Skill, target), "Enqueuing Skill " + message.Skill)); else if (esr.LeadTime <= 0) // process it now world.UseSkillNow(source, esr, target); else // process it later, after lead-time has elapsed world.Apply(new EntityUpdateEvent( source.StartSkill(message.Skill, target, Global.Now, TimeSpan.FromSeconds(esr.LeadTime)), "Activating Skill " + message.Skill)); }
public static void UseSkillNow(MobileAvatar caster, UseSkill message) { Schema.EnumSkillRow esr = Global.ModelSchema.EnumSkill.FindByEnumSkillID(message.SkillId); if (esr == null) { caster.SendLog("Requested an invalid skill " + message.SkillId); return; } if (esr.EnergyCost > caster.Energy) { caster.SendLog("Not enough energy to use " + esr.EnumSkillName + ", require " + esr.EnergyCost + "."); return; } // TODO: make this work /* if ( esr.EnumMobileState > caster.MobileState ) { caster.SendLog( "Not while " + caster.MobileState.Name ); } */ MobileAvatar target; switch ((EnumTargetType)esr.EnumTargetTypeID) { case EnumTargetType.TargetSelf: target = caster; break; case EnumTargetType.TargetMobile: if (message.TargetPhysicalObjectIDs.Length == 0) { caster.SendLog("No target specified, this skill may only be used on Mobiles."); return; } target = (MobileAvatar)Global.World.PhysicalObjects[message.TargetPhysicalObjectIDs[0]]; if (target == null) { caster.SendLog("Target " + message.TargetPhysicalObjectIDs[0] + " not found."); return; } if ((caster.Position - target.Position).Length > esr.Range) { // target is out of range caster.SendLog(target.TemplateObjectName + " is out of range"); return; } break; default: caster.SendLog("That skill does not work yet, contact admin."); Log.Error("Unhandled target type " + esr.EnumTargetTypeID + " for skill " + esr.EnumSkillID); return; } if (TargetSkill(caster, target, esr)) { // successful casting affects affinity with the elements caster.AffinityAir += esr.AirAffinity / 1000f; caster.AffinityEarth += esr.EarthAffinity / 1000f; caster.AffinityFire += esr.FireAffinity / 1000f; caster.AffinityLife += esr.LifeAffinity / 1000f; caster.AffinityWater += esr.WaterAffinity / 1000f; } // deduct energy regardless caster.Energy -= esr.EnergyCost; }
void ProcessMessage(ClientConnection client, UseSkill message) { World.ProcessUseSkill(client, message); }