Author Topic: An NPC or placeable to exchange one type of item for another.  (Read 963 times)

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« on: September 02, 2011, 12:58:02 am »


               I am looking to set up some sort of an NPC or a placeable (like a workbench) that can exchange one type of gem (or shard as the case may be) for another at a cost (say 2 of the original for 1 of the new), and I was wondering if there already is such a system I could just plug the appropiate tags into that someone could point me to? And if not if anyone would be willing to help me make one? I imagine it would need to preform some sort of check to see if the PC has the item(s), and then be able to take it and give the other.
Thank you,
Laz
               
               

               


                     Modifié par Lazarus Magni, 01 septembre 2011 - 11:59 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #1 on: September 02, 2011, 01:46:46 am »


               Well if there is no prefab version of this, this is what I have so far:
// Checks if a player has 2 Red Shards

#include "nw_i0_plot"
int StartingConditional()
{
    object oPC = GetPCSpeaker();
    //Checks if the PC has 2 Red Shards
    if ( HasItem (oPC, "laz_redqpshard") && HasItem(oPC, "laz_redqpshard") ) return TRUE;
    return FALSE;
}

This compiles, but I am not sure if it will check twice the same red shard.

I also have been working on this for the exchange:

// Script that exchanges 2 Red Shards into an Orange one  for 100k gp
//  This function was created by  AgedAlchemist on the Bioware forums
//  Link: http://nwn.bioware.c...723351&forum=47
//  Searches oTarget's inventory for items tagged sTag, and destroys nToDestroy of them.
//  It does not search for items equipped by Creatures.
void DestroyNumItems(object oTarget, string sTag, int nToDestroy = 2);
void DestroyNumItems(object oTarget, string sTag, int nToDestroy = 2)
{
    float fDelay;
    int nStackSize;
    object oItem = GetFirstItemInInventory(oTarget);
    while (GetIsObjectValid(oItem) && nToDestroy > 1)
    {
        if(GetTag(oItem) == sTag)
        {
            nStackSize = GetItemStackSize(oItem);
            if (nStackSize <= nToDestroy)
            {
                fDelay += 0.03;
                nToDestroy -= nStackSize;
                DestroyObject(oItem, fDelay);
            }
            else
            {
                SetItemStackSize(oItem, nStackSize - nToDestroy);
                nToDestroy = 0;
            }
        }
        oItem = GetNextItemInInventory(oTarget);
    }
}
#include "nw_i0_plot"
#include "tal_qp_include"
void main()
{
    object oPC = GetPCSpeaker();
    object oMerchant = GetLastSpeaker();
    //Checks if the PC 2 Red shards.
    if ( HasItem(oPC, "laz_redqpshard") && HasItem(oPC, "laz_redqpshard") && GetGold(oPC) > 100000)
    {
        //Remove 2 Red shards
        int nStackSize;
        int nQPs;
        object oShardStack;
        string sStackTag;
        oShardStack = GetItemPossessedBy(oPC, "laz_redqpshard");
        sStackTag = GetTag(oShardStack);
        DestroyNumItems(oPC, sStackTag);
        oShardStack = GetItemPossessedBy(oPC, "laz_redqpshard");
        sStackTag = GetTag(oShardStack);
        DestroyNumItems(oPC, sStackTag);
        //Exports character
        DelayCommand(0.5,ExportSingleCharacter(oPC));
        //Give QP and take gold
        TakeGold(100000, oPC);
        ActionGiveItem("laz_orangeqpshrd", oPC);
    }
    else AssignCommand(oMerchant, ActionSpeakString("You don't have 100,000 gold."));
}
This however does not compile, and I get this error message:
laz_shardexchang.nss(66): ERROR: DECLARATION DOES NOT MATCH PARAMETERS

Any help would be appreciated.
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #2 on: September 02, 2011, 02:30:59 am »


               //========================================
//Script 1:

#include "nw_i0_plot"
#include "tal_qp_include"

//This will tell us how many shards they have on them right now
int GetItemCount(object oPC, string sTag);

void main()
{
    object oPC = GetPCSpeaker();
    object oMerchant = OBJECT_SELF;
    string sStackTag = "laz_redqpshard";
    object oShardStack = GetItemPossessedBy(oPC, sStackTag);
    int nStackSize;
    int nShards = GetItemCount(oPC, sStackTag);

    int nQPs;
    object oTarget = oPC;

    if(GetGold(oPC)<100000)
    {
     AssignCommand(oMerchant, ActionSpeakString("You don't have 100,000 gold."));
     return;
    }
    //If they don't have enough (2 or more)...
    if(nShards < 2)
    {
     AssignCommand(oMerchant, ActionSpeakString("You need at least 2 shards."));
     return;
    }

    //Obviously we are continuing if they have enough shards..

        //Take 2 of them from the PC  (You must set how many you wish to take here!)
        DestroyNumItems(oPC, sStackTag, 2);

        //Give QP and take gold
        AssignCommand(oTarget, TakeGold(100000, oPC, TRUE));

        //Exports character
        DelayCommand(0.5,ExportSingleCharacter(oPC));

        //Give the PC 1 of these items (NOTE: This is the RESREF name not tagname!)
        CreateItemOnObject("laz_orangeqpshrd", oPC, 1);

//End main script
}

//Prototype Defined
int GetItemCount(object oPC, string sTag)
{
  int iCount = 0;
  string sIT;
  int nStackSize;

  object oItem = GetFirstItemInInventory(oPC);
    //Continue till there are 0 left to destroy...
    while (GetIsObjectValid(oItem))
    {

      sIT = GetTag(oItem);

      if (sIT == sTag)
      {
        nStackSize = GetItemStackSize(oItem);

        iCount += nStackSize;
      }

        oItem = GetNextItemInInventory(oPC);
    }

  //Tell the script how many "shards" they have (included all stacked count)
  return iCount;
}

//=================================================
//Script 2:

// Script Name:  tal_qp_include

// Script that exchanges 2 Red Shards into an Orange one  for 100k gp
//  This function was created by  AgedAlchemist on the Bioware forums
//  Link: http://nwn.bioware.c...723351&forum=47
//  Searches oTarget's inventory for items tagged sTag, and destroys nToDestroy of them.
//  It does not search for items equipped by Creatures.

void DestroyNumItems(object oTarget, string sTag, int nToDestroy);

void DestroyNumItems(object oTarget, string sTag, int nToDestroy)
{
    float fDelay;
    int nStackSize;
    int nAdj;
    string sIT; // Item Tagname
    object oItem = GetFirstItemInInventory(oTarget);
    //Continue till there are 0 left to destroy...
    while (GetIsObjectValid(oItem) && nToDestroy >= 1)
    {

            sIT = GetTag(oItem);
            nStackSize = GetItemStackSize(oItem);

            //If they have 2 Shards & This is indeed a Shard (item)
            if (sIT == sTag) //Obviously they have at least 1 stack size
            {
                fDelay += 0.03;
                if(nStackSize >= nToDestroy)
                {
                 nAdj = nStackSize - nToDestroy;
                 SetItemStackSize(oItem, nAdj);
                 nToDestroy = 0; //(no more needed now!)
                 //Stop here!
                 break;
                }

                //Take 2 shards from the PC
                if(nStackSize == 1)
                {
                 DestroyObject(oItem, fDelay);
                 nToDestroy -= 1;
                }

            }

        oItem = GetNextItemInInventory(oTarget);
    }
}

//=======================================
//Script 3:

#include "nw_i0_plot"

//This will tell us how many shards they have on them right now
int GetItemCount(object oPC, string sTag);

int StartingConditional()
{
    object oPC = GetPCSpeaker();
    //Checks if the PC has 2 Red Shards
    string sStackTag = "laz_redqpshard";
    int nShards = GetShardNum(oPC, sStackTag);

    if (nShards >=2 )
    { return TRUE; }
    else
    { return FALSE; }
}


//Prototype Defined
int GetItemCount(object oPC, string sTag)
{
  int iCount = 0;
  string sIT;
  int nStackSize;

  object oItem = GetFirstItemInInventory(oPC);
    //Continue till there are 0 left to destroy...
    while (GetIsObjectValid(oItem))
    {

      sIT = GetTag(oItem);

      if (sIT == sTag)
      {
        nStackSize = GetItemStackSize(oItem);

        iCount += nStackSize;
      }

        oItem = GetNextItemInInventory(oPC);
    }

  //Tell the script how many "shards" they have (included all stacked count)
  return iCount;
}

//---------------------------------

Those should work for you, compiled them, though I didn't test them, pretty sure they are good..
               
               

               


                     Modifié par _Guile, 02 septembre 2011 - 02:15 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #3 on: September 02, 2011, 02:52:29 am »


               Thank you Guile! I will give these a try. I am just a lil confused though about why there are 3? Are 1 and 2, just alternate versions of the same thing?
               
               

               


                     Modifié par Lazarus Magni, 02 septembre 2011 - 01:56 .
                     
                  


            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #4 on: September 02, 2011, 02:57:39 am »


               Did a triple check, those are the final editions, should be all good.

Script 1 is the main script that actually does the taking of the shards & gold,
             This script goes in the ActionTaken event of a conversation line that will take the Shards & Gold
Script 2 is an Include to Script 1 (hence the #include "scriptname" part found in script 1)
Script 3 is a starting conditional for the line (in red by NPC) that will show if the PC is allowed to trade in for the item desired.

If the PC fails to meet the requirements, the PC will see the next line in the conversation instead..(Again the red NPC Conversation line, not the PC's conversation lines)

If you use the PC's line as the Starting conditional then the option will not appear (to trade shards & gold for item) until they do meet the requirements.   However if you use the Starting Conditional under the NPC, the next line should inform the PC why they are not qualified to get the desired item, and should tell them what they need.

Technically you could merge Script 2 with script one, placing the delclared prototype below GetItemCount();
and placing the actual defined prototype below void main() { }  (and below GetItemCount() still)
If I was to redo these scripts it would be with constants settings to allow the user to use these scripts for other conversations etc...  (let me have a crack that and I'll post that in the last post I made)

    //Note this is really not needed because we are working from a conversation!
    //The starting conditional script will prevent the PC from getting this far!
    /*
     if(GetGold(oPC)< nGoldRequired)
     {
      AssignCommand(oMerchant, ActionSpeakString("You don't have 100,000 gold."));
      return;
     }
     //If they don't have enough (2 or more)...
     if(nShards < nRequired)
     {
      AssignCommand(oMerchant, ActionSpeakString("You need at least 2 shards."));
      return;
     }
    */

Hope that helps more..
               
               

               


                     Modifié par _Guile, 02 septembre 2011 - 02:32 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #5 on: September 02, 2011, 03:04:54 am »


               @Guile.    GetLastSpeaker(); is for use in OnConversation event scripts, not conversation scripts.  If the conversation is always started via the OnConversation event there is no porblem using it in the conversation scripts.  however since not all conversations are started by the OnConversation Event using it in a conversation script is a bad practice.

@Lazarous:   No Getting the item possed by the PC twice will not check to see if the PC has two of the items.  

_Guiles scripts look like they will work, as long as the shards are stackable and they are in the same stack.   Of cource you will want to change his check in the second script for the stack size from if(nStackSize < 2) to if(nStackSize <= 2)

and also change in the first script the line object oMerchant = GetLastSpeaker(); to object oMerchant = OBJECT_SELF;

So let me try and get a better Idea of what you are wanting.   I am guesing that you have a gem monitary system.   With each gem have a montary value.   If this is true I just do not get the 1000K + 2 red gems = one Orange gem.   Can you clarify your system a little better for me?
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #6 on: September 02, 2011, 03:06:58 am »


               Thanks for catching that, turned oMerchant to OBJECT_SELF (from a conversation)

Those should work, unless I missed something else..
               
               

               


                     Modifié par _Guile, 02 septembre 2011 - 02:12 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #7 on: September 02, 2011, 03:19:22 am »


               Thank you Guile, that does clarify things, and thank you both for the input.

Most likely it would be as I believe Guile was guessing an on conversation event script. Just a simple conversation saying do you want to convert 2 reds into an orange, and than an action taken event on the yes choice, or something to that effect.

Light, I kinda figured I was way off, which is why I am glad to get some help here. To clarify, no there is basically the standard GP based economy on Av3 with the exception of things called Quest Points (QPs) which can be gained from DM events, or forged (so to speak, it's actually credited to the PC account in the DB) from things called QP shards which drop from bosses. There are 7 types of shards, and on collecting all seven (plus 1 mil gold) you can convert them into a QP. QP are used to buy special items and DM services. This would just allow players to convert 1 shard type into another which I have heard alot of players ask for since some are quite difficult to obtain (especially for newer players.)
               
               

               


                     Modifié par Lazarus Magni, 02 septembre 2011 - 02:21 .
                     
                  


            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #8 on: September 02, 2011, 03:24:56 am »


               Did you want to check for the 100,000 Gold in the Starting Conditional too?
               
               

               
            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #9 on: September 02, 2011, 03:30:18 am »


               I honestly don't really know what a starting conditional is.
*looks sheepish*
But I can intuit that it is a condition that must be met before the script is run? If so, yes that would prolly be good.
               
               

               
            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #10 on: September 02, 2011, 03:43:57 am »


               

    //Note this is really not needed because we are working from a conversation!
    //The starting conditional script will prevent the PC from getting this far!
    /*
     if(GetGold(oPC)< nGoldRequired)
     {
      AssignCommand(oMerchant, ActionSpeakString("You don't have 100,000 gold."));
      return;
     }
     //If they don't have enough (2 or more)...
     if(nShards < nRequired)
     {
      AssignCommand(oMerchant, ActionSpeakString("You need at least 2 shards."));
      return;
     }
    */
 


Really it is needed.   It stops the PC's from cheating the conversation.  ie.  starting the conversation, having the line displayed,  Dumping there gold and shards on the ground and then selecting the conversation line to get the new shard for nothing.   
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #11 on: September 02, 2011, 03:50:40 am »


               A starting conditional is a script that goes in the paceholder (white box) of a line... in the TextAppearsWhen Tab, so if you click a line and look down to the right, you will see you are usually on the TextAppearsWhen Tab, in that white box, select edit, and paste script 1 there... save it under a name...


For the sake of saving you some time & frustrations, as you may need this script for other shards colors, etc...   I made a more versatile version for you, which you could always use scripts 1 & 2 (Just save it under a new name FIRST, and then make alterations to the settings to configure it to a different item). Script 3 however would never change (the include)...

EDITED: Fixed as Lightfoot8 Prescribed below, thanks Lightfoot8
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Script 1 (This goes in the TextAppearWhen Tab for the line you wish to check to see if the PC has enough of the required items &/or Gold )  This line will NOT show if they are NOT qualified!
(This should be the NPC's line in red, as an option, and it should be above line #2 that the NPC speaks)

//----------------------------------------------------------------
//Script Name =  ??????

//Required Include (Don't remove)
#include "item_conv_inc"

int StartingConditional()
{
     // ***SETTINGS***

   //Set this to the # of the Item they must have
    int nRequired = 2;

    //Set this to 0 if they DO NOT require gold
    int nGoldRequired = 100000; //Amount of gold they need

    //Set the tagname of the item they must have to get the item given
    string sItemTagName = "tagname";

/////////////////////////////////////////////////////////////////
//WARNING: Don't touch anything below!
/////////////////////////////////////////////////////////////////
   
     object oPC = GetPCSpeaker();

    // Custom Function that returns the # of a particular item
    // (included stack counts) that the PC has on them
    int nCount = GetIemCount(oPC, sItemTagName);

    if (nCount >= nRequired && GetGold(oPC) >= nGoldRequired)
    { return TRUE; }
    else
    { return FALSE; }

}

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Script 2: This goes on the line where the PC will select the option to actually trade in the required items &/or gold to get the item, it will actually end the conversation and they should recieve the item if they are indeed qualified, otherwise they will get a message instead!

//-----------------------------------------------
//-----------------------------------------------
// Script Name = ?????

//Required Includes DONT TOUCH
#include "item_conv_inc"

void main()
{
   // ***SETTINGS***

    //Set this to the # of the Item they must have
    int nRequired = 2;

    //Set this to 0 if they DO NOT require gold
    int nGoldRequired = 100000; //Amount of gold they need

    //Set the tagname of the item they must have to get the item given
    string sItemTagName = "tagname";

    string sName = "Name of Item Goes Here";

    //Set this to the resref of the item they will recieve (if qualified)
    //this is NOT the tagname!
    string sItemResRef = "resref";

    //Set this to the # of the item you wish to give
    //(If the item given is stackable it will be stacked!)
    int nGivenTotal = 1; //Default = 1; (Give only one by default)



/////////////////////////////////////////////////////////////////
//WARNING: Don't Alter Anything below!!!
/////////////////////////////////////////////////////////////////

    object oPC = GetPCSpeaker();
    int nStackSize;
    int nCount = GetIemCount(oPC, sItemTagName);

   //This part will prevent exploits (like dropping gold to prevent losing it etc)
   if(nCount < nRequired)
   {
     FloatingTextStringOnCreature("You must have " +
     IntToString(nRequired) + sName +"!", oPC, FALSE);
     return;
   }
   if(GetGold(oPC) < nGoldRequired)
   {
     FloatingTextStringOnCreature("You don't have " +
     IntToString(nGoldRequired) + " gold on you!", oPC, FALSE);
     return;
   }

   //Obviously we are continuing if they have enough shards..

   //Take 2 of them from the PC
   DestroyNumItems(oPC, sItemTagName, nRequired);

   //take gold
   TakeGoldFromCreature(nGoldRequired, oPC, TRUE);

   //Give the PC X of the item to be given
   object oItem;
   int nMaxStack;
   do
   {
     oItem = CreateItemOnObject(sItemResRef, oPC,nGivenTotal);
     // if nMaxStack is 0 we need to get is value.
     if(!nMaxStack) Get2DAString("baseitems","Stacking",GetBaseItemType(oItem));

     nGivenTotal-= nMaxStack;
     // if nGiveTotal is postive we still need to give some items.
    }while (nGivenTotal>0);
 

//End main script
}

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Script 3: This script should just be pasted into the script editor, and saved...  (DO NOT ALTER IT!)
               This script is only used by Script 1 & 2, it's only for saving space in Script 1 & 2

//-------------------------------------------------------------------------------------------------
//  Include Script Name =   item_conv_inc      (Save it Under THIS Name!)

//  This is an include script, it's saved under the name (item_conv_inc)
//  This script has 2 Custom Fucntions which...
//  a) Return How many of a particular item the PC Has (GetItemCount)
//  'B)' Destroys X of a given item by tagname, (can reduce Item StackSize)

//////////////////////////////////////////////////////////////////////////////
//Declare All Prototypes
int GetIemCount(object oPC, string sTag);
void DestroyNumItems(object oTarget, string sTag, int nToDestroy);

////////////////////////////////////////////////////////////////////////////
//Prototypes Defined

//Define Prototype
int GetIemCount(object oPC, string sTag)
{
  int i = 0;
  string sIT;
  int nStackSize;

  object oItem = GetFirstItemInInventory(oPC);
    //Continue till there are 0 left to destroy...
    while (GetIsObjectValid(oItem))
    {

      sIT = GetTag(oItem);

      if (sIT == sTag)
      {
        nStackSize = GetItemStackSize(oItem);

        i += nStackSize;
      }

        oItem = GetNextItemInInventory(oPC);
    }

  //Tell the script how many "shards" they have (included all stacked count)
  return i;
}

//Define Prototype
void DestroyNumItems(object oTarget, string sTag, int nToDestroy)
{
    float fDelay;
    int nStackSize;
    int nAdj;
    string sIT; // Item Tagname
    object oItem = GetFirstItemInInventory(oTarget);
    //Continue till there are 0 left to destroy...
    while (GetIsObjectValid(oItem) && nToDestroy >= 1)
    {

            sIT = GetTag(oItem);
            nStackSize = GetItemStackSize(oItem);

            //If they have 2 Shards & This is indeed a Shard (item)
            if (sIT == sTag) //Obviously they have at least 1 stack size
            {
                fDelay += 0.03;
                if(nStackSize <= nToDestroy)
                {
                  DestroyObject(oItem, fDelay);
                  nToDestroy -= nStackSize;
                  if(!nToDestroy) break;
                }
                else
                {
                  SetItemStackSize(oItem,nStackSize - nToDestroy);
                  break;
                }
            }
        oItem = GetNextItemInInventory(oTarget);
    }
}
               
               

               


                     Modifié par _Guile, 05 septembre 2011 - 03:21 .
                     
                  


            

Legacy_Lazarus Magni

  • Hero Member
  • *****
  • Posts: 1837
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #12 on: September 02, 2011, 04:13:11 am »


               Thank you Guile, that helps alot, and was very clear. I will try these ASAP.
               
               

               
            

Legacy__Guile

  • Hero Member
  • *****
  • Posts: 1308
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #13 on: September 02, 2011, 04:24:28 am »


               

Lazarus Magni wrote...

Thank you Guile, that helps alot, and was very clear. I will try these ASAP.


Your very welcome, I aim to please, always.. '<img'>

Lightfoot8 wrote...

Really it is needed.   It stops the PC's from cheating the conversation.  ie.  starting the conversation, having the line displayed,  Dumping there gold and shards on the ground and then selecting the conversation line to get the new shard for nothing.   


Technically they really aren't, if you were smart, you would put the
starting conditional on the line of the NPC where the NPC tells the PC, "There
you go" (giving them the item), & on that same line you would give
them the stuff with the 2nd script...  If they didn't qualify to see the
line that gives them the item, then they would read the next line which
would explain to them that they still need X to get the item... 
(But that's just my 2 cents, so I'm not really wrong, technically.)

Though you are correct in a sense, they are needed to prevent exploiting if you aren't using a 2nd check, so I corrected it in my second version, thank you for your comments though.
               
               

               


                     Modifié par _Guile, 02 septembre 2011 - 03:26 .
                     
                  


            

Legacy_Lightfoot8

  • Hero Member
  • *****
  • Posts: 4797
  • Karma: +0/-0
An NPC or placeable to exchange one type of item for another.
« Reply #14 on: September 02, 2011, 06:28:42 am »


               There are a few problems in _Guile's  scripts.   I don't have time to give the fixes right now, I will try to get them tomorow evening after work, I someone else or Guile does not fix them first.