Jump to content

Creating a campfire with a healing area effect


gigantibyte

Recommended Posts

just what I found with the practice. What in theory had to work, it wasn't under certain conditions (i.e. modded environments). To solve it, I followed the suggestion of old ones, avoid to make operations inside the scanner loop. Instead I fill a table with the found references (now I fill an array) and then I walk it in a different moment. Basically I stage the script in more frames, reducing the operations per frame, especially when it's slow operations like getdistance

Link to comment
Share on other sites

To be honest, I'm not a fan of multi-level nests in any case. I reconfigured the script as you suggested, and you can view the new campfire script below, verified as working. I also uploaded the latest version of my mod which contains this here:

 

http://www.nexusmods.com/newvegas/mods/57418/?

scn UltmSCampfireScript

Ref  User
ref rActor
int MenuChoice
int awaitingInput
int LightFire
Short Burning
float timer
ref FireSmall01ref
ref MPSFireSmall01ref
ref Fire420ref
ref FXFireSmallFortSummit02ref
ref FXSmokeSmall01ref
ref Light
short doonce
int count
int rCount
int BurnTime
int NewHealth
int Healing
array_var rActorArray


Begin OnActivate

     Set User to GetActionRef
     If GetActionRef != Player
          User.Activate
     Elseif GetActionRef == Player
        if Burning
            player.showrecipemenu CampfireRecipes
        else
            let awaitingInput := 1
            messageboxEX "Scavenger Campire options:|Light campfire|Reclaim wood|Cancel"
        endif
     Endif
End

Begin MenuMode
    if awaitingInput == 1
        Let MenuChoice := GetButtonPressed
        if MenuChoice == -1
            return
        endif
        let awaitingInput := -0
        if MenuChoice == 0
            let LightFire := 1
        elseif MenuChoice == 1
            player.additem UltmScrapWood UltmSMainQuest.ScrapWoodCount
            disable
            markfordelete
        endif
    endif
end


Begin GameMode

    if LightFire
        let LightFire := 0
        PMS Smoke01
        set FireSmall01ref to placeatme FireSmall01 1
        set MPSFireSmall01ref to placeatme MPSFireSmall01 1
        set Fire420ref to placeatme Fire420 1
        set FXFireSmallFortSummit02ref to placeatme FXFireSmallFortSummit02 1
        set FXSmokeSmall01ref to placeatme FXSmokeSmall01 1
        set Light to placeatme FireBrightOrangeAmb 1
        set Burning to 1
        let BurnTime := 10 * UltmSMainQuest.ScrapWoodCount
    endif

    if Burning && Healing == 0
        if timer < BurnTime
            let timer += GetSecondsPassed
            if count <= timer
                let count += 1 ; make sure a full second passes, not a fraction
                let Healing := 1
            endif
        else
            sms Smoke01
            FireSmall01ref.disable
            FireSmall01ref.markfordelete
            MPSFireSmall01ref.Disable
            MPSFireSmall01ref.MarkForDelete
            Fire420ref.Disable
            Fire420ref.MarkForDelete
            FXFireSmallFortSummit02ref.Disable
            FXFireSmallFortSummit02ref.MarkForDelete
            FXSmokeSmall01ref.Disable
            FXSmokeSmall01ref.MarkForDelete
            Light.Disable
            Light.MarkForDelete
            Disable
            MarkForDelete
            set burning to 0
            set timer to 0
        endif
    endif

    if Healing

        if GetDistance player <= 150
            player.CastImmediateOnSelf UltmSCampFireSpell
        endif    

        ;look for other actors in the same cell
            
        let rActorArray := Ar_Construct "array"
        set rActor to GetFirstRef 200 1 ; * 200 == actors
        while rActor != 0
             if rActor.GetDead || rActor.GetDisabled || rActor.GetIsCreature
                 ; skip
               else
                let rActorArray[rCount] := rActor
                let rCount += 1
            endif
              set rActor to GetNextRef ; * make sure this is within the loop or CTD
        loop

        ;heal found actors who are close enough to campfire
        while rCount > 0
            let rCount -=1
            let rActor := rActorArray[rCount]
            if GetDistance rActor <= 150
                rActor.CastImmediateOnSelf UltmSCampFireSpell
            endif
        loop
        let Healing := 0
    endif

end

Begin Onload
    if DoOnce && Burning ;player left the scene before the campire expired
        FireSmall01ref.disable
        FireSmall01ref.markfordelete
        MPSFireSmall01ref.Disable
        MPSFireSmall01ref.MarkForDelete
        Fire420ref.Disable
        Fire420ref.MarkForDelete
        FXFireSmallFortSummit02ref.Disable
        FXFireSmallFortSummit02ref.MarkForDelete
        FXSmokeSmall01ref.Disable
        FXSmokeSmall01ref.MarkForDelete
        sms Smoke01
    elseif DoOnce == 0
        let DoOnce := 1
    endif
end

One strange result though. An effect magnitude of 10 on limbs now restores 10 units of limb health, on both the player and actors. I had to reduce it down to 1 to get 1 unit of health a second while the campfire is burning. No idea why that happened.

Link to comment
Share on other sites

Thanks. I just got back into playing NV because of mods like Tales of Two Wastelands and Project Nevada. I felt an alternative to instant heal stations were needed to go with my hardcore mode.

 

Btw, I think I figured out the mystery additional health points awarded to other actors. It may have had something to do with setting the duration to 0 on the effects. Setting them to 1 second seems to have prevented the spell from awarding more than it should... within a few decimal points at least.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...