Jump to content

Geck script problems


jmathgun

Recommended Posts

*I have updated some of the code and im just checking for errors so i might have fixed it myself*

 

 

hi guys

 

I have been looking around for an auto looting mod for new vegas and have had trouble finding one with all the features I wanted.

 

I was hoping to find one that came up with a message in the corner telling you what you picked up otherwise I find myself constantly checking if its working or not and also not knowing what I have picked up is a pain.
I also wanted it to automatically pick plants.

 

I could not find anything with those features for new vegas. I did find auto loot enhanced (https://www.nexusmods.com/newvegas/mods/42631) but again it does not have the feature I want. So I figured if it does not have it then I will add it (the creator of the mod has stated in the comments of his mod that he is ok with anyone trying to improve it).

 

I would like to state though that I have never created a mod or edited one before beyond changing textures in a mod, never touched coding so this is a first for me though I do know a little about coding.

 

anyway the problem I have bumped into is that the auto harvest mod is now not collecting from npc bodies and I cannot figure out why. it collects items dropped on the floor and I managed to successfully get it to collect plants (turns out the code was in there but only one plant was added) and I also added messageex commands than it works fine.

 

I have noticed that it will not collect items when im standing next to the bodies so it seems to be stuck trying to collect from the bodies. there is also a code that will tell you with messageex if there is a gun nearby without picking it up

 

here is a section of the code for bodies. im pretty sure its actually a problem with all containers but bodies were the ones I was testing with and im presume if I can fix this code I can fix the others.

Ref NPCR             ;npc body
Ref InvPos           ;Inventory position in the body
Ref Invcount         ;number of unique items in body
Ref Lootr            ;current selected item
Ref Lootname         ;Ref I added to store the in game name of the current item selected
Ref Lootcount        ;Ref I added to store the amount of current item selected
short XChem          ;variables to indicate item is various items if >= 0 pick up item
short XAlchC
short XDrink
short XAlch
short XFood
short XHunger
short XMag
short XAlchM
short XThirst
short XVeno
short XEW
short XExpl
short XGun
short XAmmoM
short XBook
short XEPlace
short XEThrow
short XCMNY
short XMsc
short XMscEW
short XMscExpl
short XMscGun
short XMscC
short XMscQ
set NPCR to GetFirstRef 42 1 0              ;targets npc body
	Label 42                            ;loop 42 start
	if IsFormValid NPCR                 ;validity check
		if (Player.GetDistance NPCR < 201) && (NPCR.GetDisabled == 0) &&  (NPCR.GetDead == 1)            ;if player under a certain distance and body not disabled and body dead then:
			if ALEnhGKey          ;toggle option in mcm?
				NPCR.RemoveAllTypedItems player 1 1 46
			endif
			if ALEnhGNote
				NPCR.RemoveAllTypedItems player 1 1 49
			endif
			if ALEnhGIMOD
				NPCR.RemoveAllTypedItems player 1 1 103
			endif                 ;removes items and gives to player?
			set InvPos to 0        ;initial inventory position
			Label 210                ;loop 210 start
			set InvCount to NPCR.GetNumItems     ;sets inv count to inv size
			if InvPos < InvCount        ;if selected item position less than inv size then
				set LootR to NPCR.GetInventoryObject InvPos    ;sets current selected item as the item of the current position
				Set Lootname to LootR.getbaseobject         ;I added to get item name
				Set Lootcount to Lootr.getrefcount          ;I added to get item amount
				if ALEnhGChem             ;global variable to indicate mcm menu checkbox is ticked? (pick up chems)?
					set XChem to ListGetFormIndex ALEnhLChem LootR  ;checks if loot is in the chems list else returns -1
				else
					set XChem to -1     ;if the chems checkbox is unticked automatically sets not to pick up
				endif                         ;below is a repeat of the previous but for different lists and items
				if ALEnhGAlchC
					set XAlchC to ListGetFormIndex ALEnhLAlchC LootR
				else
					set XAlchC to -1
				endif
				if ALEnhGDrink
					set XDrink to ListGetFormIndex ALEnhLDrink LootR
				else
					set XDrink to -1
				endif
				set XAlch to ListGetFormIndex ALEnhLAlch LootR
				if ALEnhGFood
					set XFood to ListGetFormIndex ALEnhLFood LootR
				else
					set XFood to -1
				endif
				set XMag to ListGetFormIndex ALEnhLMag LootR
				if ALEnhGAlchM
					set XAlchM to ListGetFormIndex ALEnhLAlchM LootR
				else
					set XAlchM to -1
				endif
				if ALEnhGVenom
					set XVeno to ListGetFormIndex ALEnhLVenom LootR
				else
					set XVeno to -1
				endif
				if ALEnhGEW
					set XEW to ListGetFormIndex ALEnhLEW LootR
					set XMscEW to ListGetFormIndex ALEnhLMiscEW LootR
				else
					set XEW to -1
					set XMscEW to -1
				endif
				if ALEnhGExpl
					set XExpl to ListGetFormIndex ALEnhLExpl LootR
					set XMscExpl to ListGetFormIndex ALEnhLMiscExpl LootR
					set XEPlace to ListGetFormIndex ALEnhLExplPlace LootR
					set XEThrow to ListGetFormIndex ALEnhLExplThrow LootR
				else
					set XExpl to -1
					set XMscExpl to -1
					set XEPlace to -1
					set XEThrow to -1
				endif
				if ALEnhGGun
					set XGun to ListGetFormIndex ALEnhLGun LootR
					set XMscGun to ListGetFormIndex ALEnhLMiscGun LootR
				else
					set XGun to -1
					set XMscGun to -1
				endif
				if ALEnhGAmmoM
					set XAmmoM to ListGetFormIndex ALEnhLAmmoM LootR
				else
					set XAmmoM to -1
				endif
				set XBook to ListGetFormIndex ALEnhLBook LootR
				set XCMNY to ListGetFormIndex ALEnhLCMNY LootR
				set XMsc to ListGetFormIndex ALEnhLMisc LootR
				if ALEnhGMiscC
					set XMscC to ListGetFormIndex ALEnhLMiscC LootR
				else
					set XMscC to -1
				endif
				if ALEnhGMiscQ
					set XMscQ to ListGetFormIndex ALEnhLMiscQ LootR
				else
					set XMscQ to -1
				endif
				if ALEnhGCons
					set XHunger to ListGetFormIndex ALEnhLHunger LootR
					set XThirst to ListGetFormIndex ALEnhLThirst LootR
				else
					set XHunger to -1
					set XThirst to -1
				endif
				if ALEnhGPros
					if (GetType LootR == 40) && (GetWeight LootR != 0) 
						if (ListGetFormIndex ALEnhLExplPlace LootR < 0) && (ListGetFormIndex ALEnhLExplThrow LootR < 0) && (GetValue LootR / GetWeight LootR >= ALEnhGRatio)     ;this works fine, checks weapon weight and rather than pick it up it notifies that there is a weapon
							MessageEx "Weapon available."
						endif
					endif
				endif
				if (XChem >= 0) || (XAlchC >= 0) || (XDrink >= 0) || (XAlch >= 0) || (XFood >= 0) || (XMag >= 0) || (XAlchM >= 0) || (XVeno >= 0) || (XEW >= 0) || (XExpl >= 0) || (XGun >= 0) || (XAmmoM >= 0) || (XBook >= 0) || (XCMNY >= 0) || (XMsc >= 0) || (XMscEW >= 0) || (XMscExpl >= 0) || (XMscGun >= 0) || (XMscC >= 0) || (XMscQ >= 0) || (XEPlace >= 0) || (XEThrow >= 0) ;if the current item scored greater than -1 then
					NPCR.RemoveItem LootR 1  ; removes item from body
					Player.AddItem LootR 1 1   ;adds item to player
					Messageex "you took %.0f %n's" Lootcount Lootname  ;I added this to indicate when picking things up
				elseif (XHunger >= 0) && (Player.IsHardcore == 1) && (Player.GetAV Hunger >= ALEnhGHunger) && (Player.HasMagicEffect RestoreStarvationLevel == 0)   ;checks if player is in hardcore and feeds them if hunger is above certain amount
					NPCR.RemoveItem LootR 1        ;repeat of above
					Player.AddItem LootR 1 1
					Player.CastImmediateOnSelf LootR       ;consumes item instead
					messageex "you consumed %n" Lootname    ;message i added to indicat consumption
					Player.RemoveItem LootR 1 1           ;removes item from player inventory
				elseif (XThirst >= 0) && (Player.IsHardcore == 1) && (Player.GetAV Dehydration >= ALEnhGThirst) && (Player.HasMagicEffect RestoreDehydrationLevel == 0)
					NPCR.RemoveItem LootR 1              ;repeat of above for thirst
					Player.AddItem LootR 1 1
					Player.CastImmediateOnSelf LootR
					messageex "you consumed %n" Lootname
					Player.RemoveItem LootR 1 1
				else
					set InvPos to InvPos + 1       ;adds one to counter (possibility of missing items as item count will change? though code repeats so may not matter)
				endif
				Goto 210  ;end loop
			endif
		endif
		set NPCR to Pencil01    ;out of date fix to problem according to wiki its been patched. see no need to change it as it should have no effect
		set NPCR to GetNextRef    ; go to next body
		Goto 42 ;loop code again
	endif

	

I added all the comments on the code as there were none before, it was very difficult to figure out exactly what everything meant. any help would be appreciated, if needed I can upload the script in so people can troubleshoot it themselves.

Link to comment
Share on other sites

All "Actors" (NPCs and Creatures) are actually "containers". (Unlike "clutter" which are items lying around on the ground.) Which means you have to "open" them first, and then "walk through" their inventory contents. Take a look at how "Loot Menu for FNV" handles the issues surrounding them. (Gribbleshnibit8 knows his stuff.)

 

-Dubious-

Edited by dubiousintent
Link to comment
Share on other sites

All "Actors" (NPCs and Creatures) are actually "containers". (Unlike "clutter" which are items lying around on the ground.) Which means you have to "open" them first, and then "walk through" their inventory contents. Take a look at how "Loot Menu for FNV" handles the issues surrounding them. (Gribbleshnibit8 knows his stuff.)

 

-Dubious-

Ah, Thanks for the assistance.

 

Luckily since most of the code was already written most of that was already handled, I just could not get the count to work. But knowing that now seemed to have sorted it out.

 

I then had the problem of rather than telling me how many items it was picking up it was counting down from the amount instead. Luckily that was just a IF function loop problem so it was a matter of ensuring it was in the right place in the loop.

 

I have since managed to also add a Weight/Value ratio so now it will pick up any item that matches the setting you can set in the mcm, all i gotta do now is actually put details of what each option is in the mcm because the original author only posted the details on the mod comments.

Link to comment
Share on other sites

ok so now I have a new problem with a small section of code....

if ALEnhgItemval && (lootr.gettype == 24) || (lootr.gettype == 25) || (lootr.gettype == 26) || (lootr.gettype == 29) || (lootr.gettype == 31) || (lootr.gettype == 40) || (lootr.gettype == 41) || (lootr.gettype == 47) || (lootr.gettype == 52) || (lootr.gettype == 103) ;This is the bit thats broken.
	   set itemcheck to listgetformindex ALEnhbanneditems LootR
       If Itemcheck <= 0
           If (GetValue LootR / GetWeight LootR >= ALEnhGRatioitems)
	        Set XItemval to 1
	   else
		Set XItemval to -1
           endif
      else
	   set Xitemval to -1
      endif
endif

A couple of notes.

ALEnhgItemval is a mcm option so it will always be 1 in this case
LootR is the item in the container

ItemCheck was put in to ensure the item was one the player was supposed to have and ALEnhbanneditems is the list that it checks against (I had a moment earlier where I stole ED-e's electric zap)

and the itemvalue stuff already works by itself

 

When I added the lootr.gettype section it just stopped items from being picked, I know the script is looking at the items as I put in a rudimentary debug to print to console each time it selected a different item.

in this particular case it refused to pick up a fission battery and a hat (cant remember which type) from two different containers) even though it had before I put the code in.

 

I was hoping to put in something that would check if the item was one that would usually be picked up because it had picked up something called technical armor 1, and im pretty sure it should not have, though feel free to correct me if im wrong. so all of those are the form types of regular items

24, 0x18:Armor
25, 0x19:Book
26, 0x1A:Clothing
29, 0x1D:Ingredient
40, 0x28:Weapon
41, 0x29:Ammo
47, 0x2F:Ingestible
103, 0x67:Weapon Mods

If any of these should not be there please say as that would be a great help.

Link to comment
Share on other sites

Compound conditionals get tricky to debug. I would restructure that code to have the "gettype" function return to a new variable on a separate line preceding the block (much more efficient) and everything after the "ALEnhgItemval" condition to be on separate lines comparing that new variable to the desired values, at least while debugging.

 

The way it is now is not going to make that "and" condition apply to all the other "or" checks unless you group them together in parens: e.g. "ALEnhgItemval" condition AND (all the "OR" conditions).

 

Your other "or" conditions are determining which items get "set Itemcheck to listgetformindex ALEnhbanneditems LootR" applied. And then everything else only applies if "Itemcheck" is "not set" (meaning not in the "excluded" list). It's more efficient and clearer logic to find matches in the list and "drop out" of the condition block (as in "do nothing") when they are to be excluded. Why does the remainder need to then be nested under the "or" determination condition block? Making it it's own conditional block at the same level once the exclusion determination takes place makes it easier to debug.

 

-Dubious-

Edited by dubiousintent
Link to comment
Share on other sites

Well I should probably explain that. The preceding code does exactly as you say, there are various lists with items that are to be picked up so each item gets checked against that and then results in a variable to state whether any of those applies

 

if (XChem >= 0) || (XAlchC >= 0) || (XDrink >= 0) || ect....

 

This is the check that is made at that point on, so if the item is a chemical in the chems list Xchem gets checked and then picked up.

 

The section of code I place in is basically to pick up things that are not in those lists based on a value/weight slider, so while it is more efficient to add things to a list to pick up I instead want this to check every item against the form type.

 

So the or block there is checking against each accepted form type, essentially using the formtype as the list to find matches in.

 

I already looked up as many non player items that need to be on the banned list as I can and the Print to console bit that I mentioned allows me to spot things that need to be added as i playtest it.

I should also probably say that I was experimenting alot with the if function as im not really used to coding so I was just trying to see what works. So I apologise if it is not done very well or is difficult to understand.

Link to comment
Share on other sites

"Efficiency" is something you learn, and not expected of anyone new to the process. But having it pointed out early makes it easier to develop the proper habits.

A simple comparison operator (e.g. "<", "==") is more efficient than a compound operator (i.e. "<=", meaning LT "OR" EQ). Almost any comparison can be recast from needing a compound operator to a simple operator. Ex: "< 1" instead of "<= 0" (when dealing with booleans or integers). Also, it is a better practice to place constants on the left hand side of the equation, as in "(1 > variable)", though this is not really a concern in GECK scripting. (I'll admit to being more used to placing the variable first.)

"Pseudo-code" is a way of expressing code that is not "syntax specific" to a particular language. It's a way of discussing code logic in abstract terms, without worrying about details of implementation. You just have to maintain an internal consistency to your terminology in that instance.

So basically you are checking:

gettype of current "item"
If (itemtype in exclusion list) Then
  Don't do anything (or set flag 'XItemval' to 0) and exit from this process block to get next "item"
Else ; not in exclusions, so "everything else"
  If (formtype1 matches itemtype) Then
    Do something generic like place in a container (or set flag 'XItemval' to 1)
  ElseIf (formtype2 matches itemtype) Then ; because it can only match one type
    Do the same generic thing
  ElseIf (formtype3 matches itemtype) Then
    Repeat the same generic thing
  ; repeat ElseIf condition as needed
  Else ; no formtype match to itemtype
    Do whatever (such as set flag 'XItemval' to -1) but at least spit out a debug message.
  EndIf
EndIf
If (XItemval > 0) Then
  Do 'matched' processing
Else
  Do 'not matched' processing
EndIf
; get next "item"

Rather than repeating the "generic thing" line(s) for each conditional test, set a "flag variable" and after the IF block make another that just checks if the "flag is set and then performs that "generic thing". (Which is what you are doing; just pointing it out for others.) Any processing specific to a particular type should be done once that type has been identified in the "Then" portion.

This way you are taking advantage of the list comparison early, and only when that fails are you progressing to the more labor intensive checking of particular formtypes for "everything else".

The separate "IF/ELSEIF" tests are doing the same thing as the "OR" statements, but now it is easier to determine exactly which one is having a problem. "Checking everything" is very inefficient and can cause your script to become a bottleneck in the game if it runs too often (i.e. in "gamemode" blocks). But "IF/ELSEIF" tests between constant values and a variable are the most efficient "logical" thing the script does. A compound statement has to be completely evaluated (from left to right) before it determines if the result is "true". When each condition consists of a function call (e.g. "gettype") then each call adds to the overhead, slowing things down even more and introducing another potential point of "unexpected result".

As for your "experiments" with conditional blocks: suggest you read over the "Best Practices" ad other genral tips under the scripting section of the wiki "Getting started creating mods using GECK" article.

-Dubious-

Link to comment
Share on other sites

  • Recently Browsing   0 members

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