Modding:Activated Abilities

From Caves of Qud Wiki
Jump to navigation Jump to search
This page is about modding. See the modding overview for an abstract on modding.
This page is about modding. See the modding overview for an abstract on modding.
For best results, it's recommended to have read the following topics before this one:

Any part can add activated abilities, including mutations, skills, or even equipment (see: Hologram Bracelet and Rocket Skates for examples). All parts add abilities through the same interface.

Registering your Ability

To start, you must register your event in 2 ways. For an example, let's look at Cudgel_Slam.cs, which adds the Slam ability:

    public override bool AddSkill(GameObject GO)
    {
      ActivatedAbilities part = GO.GetPart("ActivatedAbilities") as ActivatedAbilities;
      if (part != null)
      {
        this.ActivatedAbilityID = part.AddAbility("Slam [&Wattack&y]", "CommandCudgelSlam", "Skill", -1, false, false, "You make an attack with a cudgel at an adjacent opponent at +1 penetration. If you hit, you slam your opponent backwards up to 3 spaces, pushing other creatures and breaking through walls if their AVs are less than 5 times your strength modifier. Opponents who get pushed are stunned for 1 round plus an additional round for each space pushed. Opponents who are pushed through or against walls take extra weapon damage for each wall. Colossal opponents don't get pushed but are still stunned for 1 round.", "-", false, false);
        this.Ability = part.AbilityByGuid[this.ActivatedAbilityID];
      }
      return true;
    }

    public override bool RemoveSkill(GameObject GO)
    {
      if (this.ActivatedAbilityID != Guid.Empty)
        (GO.GetPart("ActivatedAbilities") as ActivatedAbilities).RemoveAbility(this.ActivatedAbilityID);
      return true;
    }

The important fields to note in the AddAbility function call are the first 3. This tells the game object to add a new ability called "Slam[attack]", and to fire the "CommandCudgelSlam" event when it is used. This ability will show up under the "Skill" category in the ability menu. This function returns a Guid, which can be used to identify the ability when you need to reference or remove it, as seen in the RemoveSkill function.

Note that the AddSkill and RemoveSkill functions are unique to skills. For mutations, you would add your ability in the Mutate and UnMutate functions, and on equipment, you would listen for the OnEquipped and OnUnequipped messages.

However, this only tells the parent object to send an event, to receive the event, you must sign up to listen for the event as shown below:

    public override void Register(GameObject Object)
    {
      Object.RegisterPartEvent((IPart) this, "CommandCudgelSlam");
      Object.RegisterPartEvent((IPart) this, "AIGetOffensiveMutationList");
      base.Register(Object);
    }

In addition to registering for the activated ability event, this class also registers for "AIGetOffensiveMutationList". This event allows you to implement logic for AI to use this activated ability as an attack in combat.

Activating Abilities

Finally, let's look at some of the details of how the ability is activated.

    public override bool FireEvent(Event E)
    {
      if (E.ID == "AIGetOffensiveMutationList")
      {
        int intParameter = E.GetIntParameter("Distance");
        if (E.GetGameObjectParameter("Target") == null || !this.IsPrimaryCudgelEquipped() || this.ParentObject.pPhysics != null && this.ParentObject.pPhysics.IsFrozen())
          return true;
        List<AICommandList> parameter = (List<AICommandList>) E.GetParameter("List");
        if (this.Ability != null && this.Ability.Cooldown <= 0 && intParameter <= 1)
          parameter.Add(new AICommandList("CommandCudgelSlam", 1));
        return true;
      }

The above section implements the logic for when AI will attempt to use this ability.

      if (E.ID == "CommandCudgelSlam")
      {
        if (!this.IsPrimaryCudgelEquipped())
        {
          if (this.ParentObject.IsPlayer())
            Popup.Show("You must have a cudgel equipped in order to use slam.", true);
          return true;
        }
        if (this.ParentObject.pPhysics != null && this.ParentObject.pPhysics.IsFrozen())
        {
          if (this.ParentObject.IsPlayer())
            Popup.Show("You are frozen solid!", true);
          return true;
        }
        string str = this.PickDirectionS();
        Cell cellFromDirection = this.ParentObject.GetCurrentCell().GetCellFromDirection(str, true);
        if (cellFromDirection == null)
          return true;

The above section shows some of the checks the skill performs to validate that the player can use the attack. It also gets an attacking direction.

          this.ParentObject.UseEnergy(1000, "Skill Cudgel Slam");
          if (!this.ParentObject.HasEffect("Cudgel_SmashingUp"))
            (this.ParentObject.GetPart("ActivatedAbilities") as ActivatedAbilities).AbilityByGuid[this.ActivatedAbilityID].Cooldown = 510;

The UseEnergy call sets the amount of time the ability takes to activate. 1000 energy is equivalent to 1 turn, and should be used for most regular skills. 2000 energy would be 2 turns, and 500 would be half a turn. Free actions do not need to call this function.

To set a cooldown, you simply set the cooldown property on the ability. 10 cooldown is equivalent to 1 turn (at 16 willpower). Cudgel adds 10 to its cooldown counter, because the cooldown will count down by 1 in the time it takes to use the ability.

Further Reading

You can find the full original source code for FlamingHands.cs at: Modding: Creating New Mutations. You can also see how any ability was implemented by decompiling your game and looking at the decompiled code. For more information on decompiling your game, see: Modding: C Sharp Scripting.