Jump to content

Photo

Broken custom function


  • Please log in to reply
12 replies to this topic

#1
Karma

Karma
  • Members
  • 391 posts
I made a series of custom functions that places followers in the various camps. Three of the custom functions are almost identical; they take the creature object and spit out a location for that object for three different areas. The second custom function uses that location to place the creatures in the various camps. The scripts compile, but when entering camp, I get a CTD. I'm including the relevant bits of script below. Maybe someone could take a look and tell me what I'm doing wrong. Commenting out the various AddCommand() lines keeps the CTD from happening, so....


CREATURE --> LOCATION:
location kcGetCampLocation(object oFollower)
{
    string sTag = GetTag(oFollower);
    location lLocation;

    if(sTag == GEN_FL_CULLEN) lLocation = Location(GetArea(GetHero()), Vector(138.564f, 111.815f, -1.08586f), 180.0f);
    else if(sTag == GEN_FL_JOWAN) lLocation = Location(GetArea(GetHero()), Vector(187.728f, 117.281f, -0.187108f), 180.0f);
    else if(sTag == GEN_FL_GORIM) lLocation = Location(GetArea(GetHero()), Vector(144.716f, 122.112f, -0.523375f), 0.0f) ;
    else if(sTag == GEN_FL_GILMORE) lLocation = Location(GetArea(GetHero()), Vector(130.438f, 118.121f, -0.43786f), 180.0f);
    else if(sTag == GEN_FL_TAMLEN) lLocation = Location(GetArea(GetHero()), Vector(162.725f, 112.49f, -1.9237f), -88.5f);
    else if(sTag == GEN_FL_SORIS) lLocation = Location(GetArea(GetHero()), Vector(170.45f, 114.992f, -1.97934f), -84.2f);
    else if(sTag == GEN_FL_LESKE) lLocation = Location(GetArea(GetHero()), Vector(171.912f, 115.0f, -1.8909f), 106.7f);
    else if(sTag == GEN_FL_ADELA && WR_GetPlotFlag(PLT_KCPT_MISC_PARTY, SAAREBAS_HIRED) == TRUE) lLocation = Location(GetArea(GetHero()), Vector(170.786f, 111.907f, -2.03677f), 29.1f);
    else if(sTag == GEN_FL_ADELA && WR_GetPlotFlag(PLT_KCPT_MISC_PARTY, SAAREBAS_HIRED) == FALSE) lLocation = Location(GetArea(GetHero()), Vector(169.855f, 109.97f, -1.94591f), 90.0f);
    else if(sTag == GEN_FL_TEAGAN) lLocation = Location(GetArea(GetHero()), Vector(135.424f, 124.962f, -0.253687f), -49.8f);
    else if(sTag == GEN_FL_SAAREBAS && WR_GetPlotFlag(PLT_KCPT_MISC_PARTY, ADELA_HIRED) == TRUE) lLocation = Location(GetArea(GetHero()), Vector(169.855f, 109.97f, -1.94591f), -163.4f);
    else if(sTag == GEN_FL_SAAREBAS && WR_GetPlotFlag(PLT_KCPT_MISC_PARTY, ADELA_HIRED) == FALSE) lLocation = Location(GetArea(GetHero()), Vector(169.855f, 109.97f, -1.94591f), 90.0f);

    return lLocation;
}

PLACES CREATURES IN CAMP USING LOCATION FROM PREVIOUS SCRIPT:
void kcPlaceFollowersInCamp()
{
    object oArea = GetArea(GetHero());
    object [] arParty = GetPartyPoolList();
    int nSize = GetArraySize(arParty);
    int i;
    object oCurrent;
    for(i = 0; i < nSize; i++)
    {
        oCurrent = arParty[i];

        if(!IsHero(oCurrent) && !IsSummoned(oCurrent) && IsFollowerKC(oCurrent))
        {
            SetFollowerState(oCurrent, FOLLOWER_STATE_AVAILABLE);
            WR_SetObjectActive(oCurrent, TRUE);
            SetImmortal(oCurrent, TRUE);
            RW_CatchUpToPlayer(oCurrent);

            if (GetTag(oArea) == "cam100ar_camp_plains" || GetTag(oArea) == "cam110ar_camp_arch3" || GetTag(oArea) == "cam104ar_camp_arch1")
            {
                AddCommand(oCurrent, CommandJumpToLocation(kcGetCampLocation(oCurrent)));
                kcFollowerCampAmbient(oCurrent, TRUE);
            }
            else if (GetTag(oArea) == "cli300ar_redcliffe_castle")
            {
                AddCommand(oCurrent, CommandJumpToLocation(kcGetRedcliffeLocation(oCurrent)));
                kcFollowerCampAmbient(oCurrent, FALSE); //Change to TRUE after ambient is updated

                //setting Adela and Tamlen inactive because they are upstairs
                if(GetTag(oCurrent) == GEN_FL_TAMLEN || GetTag(oCurrent) == GEN_FL_ADELA)
                {
                    WR_SetObjectActive(oCurrent, FALSE);
                }
            }
            else if (GetTag(oArea) == "cli310ar_redcliffe_castle_2")
            {
                WR_SetObjectActive(oCurrent, FALSE);
                AddCommand(oCurrent, CommandJumpToLocation(kcGetRedcliffeLocation(oCurrent)));
                kcFollowerCampAmbient(oCurrent, FALSE); //Change to TRUE after ambient is updated

                //setting Adela and Tamlen active because they are placed here
                if(GetTag(oCurrent) == GEN_FL_TAMLEN || GetTag(oCurrent) == GEN_FL_ADELA)
                {
                    WR_SetObjectActive(oCurrent, TRUE);
                }
            }
            else if (GetTag(oArea) == "den211ar_arl_eamon_estate_1")
            {
                AddCommand(oCurrent, CommandJumpToLocation(kcGetDenerimLocation(oCurrent)));
                kcFollowerCampAmbient(oCurrent, FALSE); //Change to TRUE after ambient is updated
            }

            WR_SetPlotFlag(PLT_KCPT_MISC_PARTY, kcGetFollowerInPartyFlag(kcGetFollowerApprovalIndex(oCurrent)), FALSE, FALSE);
            ------>>>WR_SetPlotFlag(PLT_KCPT_MISC_PARTY, kcGetFollowerInCampFlag(kcGetFollowerApprovalIndex(oCurrent)), TRUE, FALSE);
        }
    }
}

Edited by satans_karma, 19 January 2014 - 12:07 AM.


#2
MerAnne

MerAnne
  • Members
  • 1,157 posts
I used more simplistic logic (more typing, but the same number of lines executed), but I don't see an immediate problem that would cause a CTD for you. A few things I would do....
1) I would use a 'display floaty' to make sure that the correct location is being returned by kcGetxxxxLocation() I know it sounds trivial, but... I've made enough mistakes in my life that I look for the simplest thing that I might have done wrong first! (I'm guessing that there are multiple Camps each identified by their names)

2) I would confirm that the first and second floor of Redcliffe Castle are different areas/area lists

3) I would add an 'else default location' concept in case the function is called for the 'wrong' Companion.

That's all I can think of off the top of my head....

#3
Karma

Karma
  • Members
  • 391 posts
1) I can't even enter the area to see the floaty. It CTDs before the area loads.
2) Already confirmed. Level 1 is in an AL, and level 2 is an area in no area list.
3) Already tried. No go.

I guess it really doesn't matter that much. I used another method to place them in camp that uses even less code and is more accessible to other modders. I'm just getting really annoyed by the number of inexplicable bugs I've found lately. This is only one of many...

The line I added a red arrow to is randomly setting the fired flag for some companions. Something else is also causing one of my companions to be un-hired but not fired. The generated VO for one conversation plays in the .fsb and .fev but won't play in-game. Oh yeah, and the toolset keeps freezing for 5 seconds every 2 minutes making my frustration grow.

Edited by satans_karma, 19 January 2014 - 12:09 AM.


#4
Sunjammer

Sunjammer
  • Members
  • 925 posts
What happens if you replace the JumpTo commands with SetLocation?

#5
Karma

Karma
  • Members
  • 391 posts
That appears to have stopped the CTD, but why?

#6
Talmud

Talmud
  • Members
  • 8 posts

satans_karma wrote...

That appears to have stopped the CTD, but why?


Probably because you are running the script before the characters are completely loaded - and you were adding actions to the character's queue before the queue was available.

Which event were you firing the function on?

Edited by Talmud, 19 January 2014 - 03:24 AM.


#7
Karma

Karma
  • Members
  • 391 posts
It was part of a PRCSCR script, which had been working with the AddCommand() prior to setting up the custom function to check the location. I only changed the method of retrieving the location. The creature objects were set active before adding the command to move them. In theory, they should be already loaded, right?

#8
Talmud

Talmud
  • Members
  • 8 posts
Ah, that should probably have been OK.
Sunjammer might have a better answer for you. It's now been a couple years since I even looked at these scripts.

#9
MerAnne

MerAnne
  • Members
  • 1,157 posts
On the strange plot flags...

From the toolset wiki, the programming language is a 'C like' language. Back in the day, C compilers were very forgiving and didn't care about this kind of thing; then they became MUCH less forgiving and it would cause very very VERY strange things to happen. (I had a beautiful program that ran perfectly for 5+ years, until the compiler was updated)

arrays in C start at zero rather than 1. I don't believe that the toolset allows array size to be declared dynamically. The only place that this really matters (if you have defined your starting place is 1) is when you are defining the array variable. The array variable needs to identify the array size as "size+1" if you are starting at 1.

Now that is C from when I was programming full time. I don't know what changes are in the toolset language to make it 'C like', but I do remember vividly how incredibly strange the errors were when the compilers stopped being forgiving and I had made that mistake. :)

#10
Sunjammer

Sunjammer
  • Members
  • 925 posts
Unfortunately I don't have a better explanation: it was simply an attempt to simplify the problem (also I feel SetLocation gets a bad press in the wiki). However even if we assume JumpTo is the culprit a CTD is a very severe symptom of that problem.

As for the unreliable plot flag are you sure kcGetFollowerApprovalIndex is a) the function you intended to use and B) returns the correct literal value? I only ask because your other functions are clearly named but the name of the function implies it does something quite different.

#11
Karma

Karma
  • Members
  • 391 posts
I don't think JumpTo is the problem as that function had been working for... well... ever. I just don't know what the problem is. I have no explanation other than a malfunctioning custom function. If I didn't know better, I'd say it was probably the duplicate plot GUID bug as that's the only thing I've ever seen that causes such a seemingly random set of inexplicable bugs to occur.

The kcGetFollowerApprovalIndex() is basically the copy-paste version of Approval_GetFollowerIndex() just with my companions added at the bottom. It ought to be spitting out the integer that is specified in the approval 2da and that is unique to the companion in question. Is it? I don't know. For a long time, I assumed it was, but lately, I'm not so sure. It appears to be working only sometimes, which is why I'm utterly perplexed. I have other means of accessing that number and I'm implementing them as a test (and possibly as a permanent change), but that's just slapping a band-aid on it. I'd really like to figure out what the problem is, so that I can either fix it properly or avoid it in the future.

#12
MerAnne

MerAnne
  • Members
  • 1,157 posts
JumpTo still works in my mod (as far as I know) which makes me think that SetLocation may be more 'forgiving' about its inputs. I suspect that that the CTD when using 'JumpTo' is a symptom of a problem rather than the actual cause.

#13
Karma

Karma
  • Members
  • 391 posts
So... now I'm having trouble unequipping both weapon sets. I've tried every permutation of UnequipItem(), but it won't unequip both. I can get it to unequip one or the other but not both. Anyone have any ideas?