gigantibyte Posted November 20, 2014 Share Posted November 20, 2014 (edited) If this has already been created, let me know. Actually, any mod item with a semi-persistent proximity effect on actor values would be useful to learn from. Is there anything that works like radiation in reverse? I've updated my mod to make gathering scrap wood a thing. With 5 scraps of wood the player can build a campfire. (Well, at this point, it's just a copy of the campfire activator model, bound to a static object.) Adding activate options, such access to recipe menu won't be a problem, but I rather not have the campfire act as a quick healing station. Instead, the campfire when lit will emit a healing field that the player must be inside to gradually benefit from. If I can get this working, it should be like the Radiation Limb Regeneration perk from FO3. I think I may be able to accomplish the regeneration aspect through use of the GetFirstRef / GetNextRef / GetRefs functions. I've just never used them, so I'm unsure of the parameters I need to confine the search for actor references in a world space. I don't want the campfire to heal everyone in the Mojave! The healing field should be restricted to actors within a few arm lengths of the campfire. The campfire will have flame visuals and eventually burn out of course, and I hope to add other features such as using action points to heal faster, and an added danger of attracting hostiles. For now though, I certainly would be grateful if anyone could help with the script needed to get the actor references that meet the campfire's proximity condition. Edited November 20, 2014 by gigantibyte Link to comment Share on other sites More sharing options...
Ladez Posted November 20, 2014 Share Posted November 20, 2014 Do you want this healing effect to work for all actors or only for the player? If it's only the player, you just need a script attached to the campfire form to check the players distance and apply healing by casting a spell or by modifying the actor value directly. If it's for all actors, then you need to do the same thing, but you need to get the references of all nearby actors before you can do something with them. That's where GetFirstRef/GetNextRef comes in. Link to comment Share on other sites More sharing options...
gigantibyte Posted November 20, 2014 Author Share Posted November 20, 2014 If it's for all actors, then you need to do the same thing, but you need to get the references of all nearby actors before you can do something with them. That's where GetFirstRef/GetNextRef comes in. All actors. The aim is for the healing effect to work on companions too. It should work on enemies as well, so that the player must be careful where they build it. For GetFirstRef/GetNextRef, I think I have a handle on the example script given in the wiki. I just need a proper distance number to the actor from the campfire and include if ActorRef.GetDistance <= ValidDistancein the loop to validate the actors. But what do I set GetNextRef's cell depth parameter to? And what's the scale with GetDistance? Link to comment Share on other sites More sharing options...
Ladez Posted November 20, 2014 Share Posted November 20, 2014 I think a cell depth of 1 should be fine, that will get you all the actors in the player's current cell as well as the 8 surrounding cells. If I remember correctly, an NPC has a default height of about 128 units, so you can use that to work out how large the distance should be. Link to comment Share on other sites More sharing options...
gigantibyte Posted November 20, 2014 Author Share Posted November 20, 2014 (edited) Thanks! A related question if you know. To create a campfire players need to drop some scrap wood and activate it. In case the player just leaves the scrap wood on the ground, I'd like it to be eventually deleted. According to the page for MarkForDelete "With items that can be dropped from inventory but work on their own, every drop and every pickup is a disable." Does this mean I don't need to include Disable in the scrap wood's object script? My intention is do a MarkForDelete on the scrap wood as soon as it is dropped, but obviously it can't be disabled right away. It would just be a fail safe, because under normal use the scrapwood will be disabled upon building a campfire, and the campfire will be diabled once it burns out. Edit: Nevermind. I setup the object script to disable/markfordelete in the Onload block, after it has loaded at least once normally. So mostly everything is working as envisioned. Drop some wood, then activate it to assemble the wood into a campfire form. Click on the assembled wood again to light the fire. Once the fire is lit, the GetFirstRef/GetNextRef loop runs, and it does indeed find actors. (I scripted a popup to appear each time one was found.) It just doesn't seem to be finding the player, and there isn't any distance condition yet. I set the loop to award a cap to each actor found, but my wallet never grew. Not sure what's up... Maybe the player is not supposed to be found? Edited November 21, 2014 by gigantibyte Link to comment Share on other sites More sharing options...
Ladez Posted November 21, 2014 Share Posted November 21, 2014 (edited) Wait, I'm confused. You drop the wood from your inventory and then you activate it to build the campfire, right? But if you run disable/markfordelete in the OnLoad block of the wood, doesn't it disappear immediately? As for the rest, yes, the player is a special condition, since he isn't returned by those functions. I completely forgot about that. This is, of course, trivial to set up, just do things as you would normally if it was to only work for the player, as I described in the first post. Edited November 21, 2014 by Ladez Link to comment Share on other sites More sharing options...
gigantibyte Posted November 21, 2014 Author Share Posted November 21, 2014 (edited) Wait, I'm confused. You drop the wood from your inventory and then you activate it to build the campfire, right? But if you run disable/markfordelete in the OnLoad block of the wood, doesn't it disappear immediately? It doesn't hopefully through the use of a control variable, but maybe my script is configured incorrectly and the scrap wood will never disappear. Could you review the following? scn UltmScrapWoodScript ref User int awaitingInput int MenuChoice int DoOnce Begin onActivate let UltmSMainQuest.ScrapWoodCount := GetRefCount Set User to GetActionRef If GetActionRef != Player User.Activate Elseif GetActionRef == Player let awaitingInput := 1 messageboxEX "What would you like to do?|Assemble wood for campfire|Take|Cancel" endif end Begin MenuMode if awaitingInput == 1 Let MenuChoice := GetButtonPressed if MenuChoice == -1 return endif let awaitingInput := -0 if MenuChoice == 0 if GetRefCount >= 5 let UltmSMainQuest.CamfireRef := placeatme UltmSCampfire 1 let UltmSMainQuest.ScrapWoodCount := GetRefCount disable markfordelete else messageboxEX "Not enough wood" endif elseif MenuChoice == 1 player.additem UltmScrapWood UltmSMainQuest.ScrapWoodCount disable markfordelete endif endif end Begin Onload if DoOnce disable markfordelete else let DoOnce := 1 endif end Right now though, I'm having fun trying modify health and body parts gradually. Using a Setav can make a body part health go over the base of 100, and since Setav affects base, I can't use it on Health. RestoreAV on the other hand seems to restore up to the value given, so I can't do a RestoreAV Heath 1 every second to restore 1 unit of health. Maybe something like this: if (rActor.GetBaseAV Health) > (rActor.GetAV Health) let NewHealth := (rActor.GetAV Health) + 1 rActor.RestoreAV Heath NewHealth endif then repeat for each body part, like PerceptionCondition, but with 100 instead of GetBaseAV. Edit: "let UltmSMainQuest.CamfireRef := placeatme UltmSCampfire 1" above is actually useless. It turns out I didn't need to pass the reference anywhere. Edited November 21, 2014 by gigantibyte Link to comment Share on other sites More sharing options...
Ladez Posted November 21, 2014 Share Posted November 21, 2014 It doesn't hopefully through the use of a control variable, but maybe my script is configured incorrectly and the scrap wood will never disappear. Could you review the following? Ah, that makes sense. The wood will disappear the second time the 3d art is loaded, since by that time the variable is set. Right now though, I'm having fun trying modify health and body parts gradually. Using a Setav can make a body part health go over the base of 100, and since Setav affects base, I can't use it on Health. RestoreAV on the other hand seems to restore up to the value given, so I can't do a RestoreAV Heath 1 every second to restore 1 unit of health. Maybe something like this: Maybe using an actor effect will simplify things a bit. That way you don't have to do all these calculations in order to heal over time. Just apply it on actors that are within range and remove it when they leave. Link to comment Share on other sites More sharing options...
gigantibyte Posted November 21, 2014 Author Share Posted November 21, 2014 (edited) Woohoo! I finally got the effect functioning as desired. Maybe using an actor effect will simplify things a bit. That way you don't have to do all these calculations in order to heal over time. Just apply it on actors that are within range and remove it when they leave. ^ This is indeed the best solution. Modifying the health values in a controlled fashion through script alone is tricky. So I created a new "spell" that used several effects. There is an inherent effect called 'Restore Health Stimpak' effect, which modifies both health and conditions, but the magnitude value works on different scales for health and limbs. A magnitude of 1 for instance restores 1 unit of health, but only 0.1 units of limb condition. Here's what the "spell" looks like: http://i.imgur.com/7UrXjbU.jpg There's also a separate restore effect for all limbs, but without checks to prevent condition values over 100. I had to add that condition myself for each limb like this: http://i.imgur.com/KGl2IEu.jpg Finally, although 'Restore Health' didn't allow the player's health to go over the maximum, it did set the companion's health over the limit. Since each companion would have a different maximum health value, I had to add a check for this in my script, and "damage" the health back down to normal. Here's the script section for regeneration: if Burning == 1 if timer < BurnTime let timer += GetSecondsPassed if count <= timer let count += 1 ; make sure a full second passes, not a fraction if GetDistance player <= 150 player.CastImmediateOnSelf UltmSCampFireSpell endif set rActor to GetFirstRef 200 1 ; * 200 == actors while rActor != 0 if rActor.GetDead || rActor.GetDisabled || rActor.GetIsCreature ; skip else if GetDistance rActor <= 150 rActor.CastImmediateOnSelf UltmSCampFireSpell if rActor.GetBaseActorValue Health < rActor.GetAV Health rActor.DamageAV Health 1 endif endif endif set rActor to GetNextRef ; * make sure this is within the loop or CTD loop endif elseRestoration is slow, but a distance of 150 seems reasonable in-game. Move too far away, and the regeneration stops. As for the speed, I think I'll leave it the way it is, and wait for comments. At present it takes 100 seconds to fully restore a limb from a condition of 0, give-or-take a few decimal points. Also, my companion ended up with a Health value of 1 over the base. An acceptable result I think. No limbs went over 100 which is great. Edited November 21, 2014 by gigantibyte Link to comment Share on other sites More sharing options...
Fallout2AM Posted November 22, 2014 Share Posted November 22, 2014 I now tend to avoid to put a scanner and x nested conditions inside the same frame, especially when it uses a function like getdistance, I would suggest to stage it. anyway, when I've seen this amazing campfire idea, I thought to a solution I personally never tried but I've read people were using it in the past... a fake explosion. no sound or graphic, only its radius and eventually some spell casted on those affected by this fake explosion Link to comment Share on other sites More sharing options...
Recommended Posts