A complicated script problem involving GetDistance

Post » Fri Sep 06, 2013 3:25 am

As the title says, I'm getting complicated with a bunch of scripted (non-unique) misc objects that are supposed to trigger sensors when placed on a series of circles on a floor. Here is the map for the sensors: http://img62.imageshack.us/img62/6756/1u6i.jpg

Player is easy: it detects whether the player is standing on the circle or not. Flags 0 or 1.

Center is easy: it detects if a quill is placed in the center. The quill is scripted, not the sensor, because using GetDistance on a non-unique, non-persistent item is bad scripting.

The lettered sensors are where things get complicated. It would be easy if I had six unique objects, each to be placed in only one specific spot. However, the way the quest is written, these items are (fake) soul gems and I had a limited selection of creatures that work for *~lore~* reasons. Therefore there's two of each kind of gem. No, I'm not willing to budge on this until I've tried everything possible to make it work.

Here's an example of the scripts on the soul gems:

Begin DHM_Ritual_SoulGem_DShort stateFloat timerIf ( GetDisabled )    SetDelete 1    ReturnEndifIf ( state == -9 )    Cast Uvi_dummy_enchant Player    Set state to -10    ReturnElseif ( state == -10 )    Set timer to ( timer + GetSecondsPassed )    If ( timer > 2 )        Disable    Endif    ReturnEndifIf ( uvi_ritual_marker_OA.state == 10 )    If ( state > 0 )        Set state to -9    Endif    ReturnElseif ( uvi_ritual_marker_PC.state == 10 )    If ( state > 0 )        Set state to -9    Endif    ReturnEndifIf ( GetDistance uvi_ritual_marker_OA < 20 )    Set uvi_ritual_marker_OA.state to 1    Set state to 1    ReturnElseif ( state == 1 )    Set uvi_ritual_marker_OA.state to 0    Set state to 0EndifIf ( GetDistance uvi_ritual_marker_PC < 20 )    Set uvi_ritual_marker_PC.state to 1    Set state to 1    ReturnElseif ( state == 1 )    Set uvi_ritual_marker_PC.state to 0    Set state to 0EndifIf ( GetDistance uvi_ritual_marker_AM < 20 )    Set uvi_ritual_marker_AM.state to -1    Set state to -1Elseif ( uvi_ritual_marker_AM.state == -1 )    If ( state == -1 )        Set uvi_ritual_marker_AM.state to 0        Set state to 0    EndifEndifIf ( GetDistance uvi_ritual_marker_EI < 20 )    Set uvi_ritual_marker_EI.state to -1    Set state to -1Elseif ( uvi_ritual_marker_EI.state == -1 )    If ( state == -1 )        Set uvi_ritual_marker_EI.state to 0        Set state to 0    EndifEndifIf ( GetDistance uvi_ritual_marker_RD < 20 )    Set uvi_ritual_marker_RD.state to -1    Set state to -1Elseif ( uvi_ritual_marker_RD.state == -1 )    If ( state == -1 )        Set uvi_ritual_marker_RD.state to 0        Set state to 0    EndifEndifIf ( GetDistance uvi_ritual_marker_SR < 20 )    Set uvi_ritual_marker_SR.state to -1    Set state to -1Elseif ( uvi_ritual_marker_RD.state == -1 )    If ( state == -1 )        Set uvi_ritual_marker_SR.state to 0        Set state to 0    EndifEndifSet state to 0End

There are two more types of soul gems and each with two possible "correct" orientations, depending on which ritual you're performing. Here's an example of the ritual script:

Begin DHM_Ritual_Scroll_DShort OnPCEquipShort PCSkipEquipShort ActionFlagShort StateFloat TimerIf ( ActionFlag == 1 )    If ( uvi_ritualcircle.state != -3 )        MessageBox "You need to pour the right ink into the circle."    Elseif ( uvi_ritual_marker_Player.state == 0 )        MessageBox "You need to stand in the southermost circle."    Elseif ( uvi_ritual_marker_Center.state == 0 )        MessageBox "You need to place a prepared quill in the center circle."    Elseif ( uvi_ritual_marker_RD.state != 1 )        Set ActionFlag to -1        Return    Else        Set ActionFlag to 2        Return    Endif    Set ActionFlag to 0    ReturnElseif ( ActionFlag == 2 )    If ( uvi_ritual_marker_AM.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_EI.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_OA.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_PC.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_SR.state != 0 )        Set State to 10    Else        Set State to 1    Endif    MessageBox "You recite the ritual invocation."    Set ActionFlag to 0Elseif ( ActionFlag == -1 )    If ( uvi_ritual_marker_AM.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_EI.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_OA.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_PC.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_RD.state != 0 )        Set State to 10    Elseif ( uvi_ritual_marker_SR.state != 0 )        Set State to 10    Else        MessageBox "You need to place a prepared soul gem in the right place on the circle."        Set ActionFlag to 0        Return    Endif    MessageBox "You recite the ritual invocation."    Set ActionFlag to 0Endif; PCSkipEquip is set to 1 every time the book is equipped from your inventory.If ( PCSkipEquip == 1 )    Set PCSkipEquip To 0    If ( GetPCCell "Master Llapp's Training Room" == 1 )        If ( State == 0 )            Set ActionFlag To 1        Endif    EndifEndIf; These lines are important, otherwise the book cannot be picked up from the ground.If ( MenuMode )    ReturnEndIf; For activating the book when it is placed in the game world.If ( OnActivate )    ActivateEndIfIf ( State < 1 )    ReturnElseif ( State == 1 )    PlaySound "spellmake success"    uvi_ritualcircle_ruby->Disable    Set State to 2Elseif ( State == 2 )    Set Timer To ( Timer + GetSecondsPassed )    If ( Timer > 0.25 )        uvi_ritualcircle_ruby->Enable        Set State to 3    EndifElseif ( State == 3 )    Set Timer To ( Timer + GetSecondsPassed )    If ( Timer > 0.5 )        uvi_ritualcircle_ruby->Disable        Set State to 4    EndifElseif ( State == 4 )    Set uvi_ritual_marker_RD.state to 10    Set state to 5Elseif ( State == 5 )    Set Timer To ( Timer + GetSecondsPassed )    If ( Timer > 0.75 )        uvi_ritualcircle_ruby->Enable        Set State to 6    EndifElseif ( State == 6 )    Set Timer To ( Timer + GetSecondsPassed )    If ( Timer > 1 )        uvi_ritualcircle_ruby->Disable        Set State to 7    EndifElseif ( State == 7 )    Set Timer To 0    uvi_ritual_mist->Enable    Set uvi_ritual_marker_Center.state to 10    Set State to 8Elseif ( State == 8 )    Set Timer To ( Timer + GetSecondsPassed )    If ( Timer > 3 )        uvi_ritual_mist->Disable        Set State to 9    EndifElseif ( State == 9 )    Set uvi_ritualcircle.state to 0    Set uvi_ritual_marker_RD.state to 0    Set uvi_ritual_marker_Center.state to 0    Set State to 0Elseif ( State == 10 )    PlaySound "spellmake fail"    uvi_ritualcircle_ruby->Disable    Set uvi_ritualcircle.state to 0    Set State to 0EndifEnd

Edit: Here's the script on the quill, which essentially completes the ritual. Oh, and the scripts on the sensors only define a state variable.

Begin DHM_Ritual_QuillShort stateIf ( GetDisabled )    SetDelete 1    ReturnEndifIf ( uvi_ritual_marker_Center.state == 10 )    If ( state == 1 )        If ( uvi_ritual_marker_AM.state == 10 )            PlaceAtMe DHM_quill_ench_myst 1 0 0        Elseif ( uvi_ritual_marker_EI.state == 10 )            PlaceAtMe DHM_quill_ench_illu 1 0 0        Elseif ( uvi_ritual_marker_OA.state == 10 )            PlaceAtMe DHM_quill_ench_alte 1 0 0        Elseif ( uvi_ritual_marker_PC.state == 10 )            PlaceAtMe DHM_quill_ench_conj 1 0 0        Elseif ( uvi_ritual_marker_RD.state == 10 )            PlaceAtMe DHM_quill_ench_dest 1 0 0        Elseif ( uvi_ritual_marker_SR.state == 10 )            PlaceAtMe DHM_quill_ench_rest 1 0 0        Else            Set state to 0            Return        Endif        Disable    Endif    ReturnEndifIf ( GetDistance uvi_ritual_marker_Center < 25 )    Set uvi_ritual_marker_Center.state to 1    Set state to 1Else    Set uvi_ritual_marker_Center.state to 0    Set state to 0EndifEnd

Symptoms of their interactions:

1. Doing the ritual correctly works perfectly. Everything goes as planned and is reset for the next ritual.

2. Placing the gem in the wrong sensor starts messing things up though. I end up with sensors in state -1 that do not switch back to 0 when the gem is removed.

3. Placing a gem on the correct sensor, but for the wrong ritual ends up with the sensors not flagging back to 0 when the gem is removed.

4. Results 2 & 3 are not consistent. Sometimes the sensors are reset, sometimes they're not.

Can anyone see what I'm doing wrong in the first script?

User avatar
michael danso
 
Posts: 3492
Joined: Wed Jun 13, 2007 9:21 am

Return to III - Morrowind