static function, out parameter and for loop problem [SOLVED]

Discussions about Coding and Scripting
Post Reply
User avatar
PrinceOfFunky
Godlike
Posts: 1200
Joined: Mon Aug 31, 2015 10:31 pm

static function, out parameter and for loop problem [SOLVED]

Post by PrinceOfFunky »

I have a function like this:

Code: Select all

static function bool hasWhatever(Actor actor, out Inventory inv) {
  local Inventory tmpInv;
  
  for (tmpInv = actor.Inventory; tmpInv != None; tmpInv = tmpInv.Inventory) {
    If (tmpInv.class == class'Whatever') {
      inv = tmpInv;
      return true;
    }
  }

  return false;
}
The problem is that the out parameter is always the penultimate checked tmpInv.
Now I must be honest saying I'm writing this from the phone and cannot check what I just wrote, so I wrote what I remember. If I'll find out that I'm wrong then I'll type it here.

Supposing this actually happens, what could be the cause?

SOLUTION
Last edited by PrinceOfFunky on Wed Jul 17, 2019 3:42 pm, edited 1 time in total.
"Your stuff is known to be buggy and unfinished/not properly tested"
User avatar
The_Cowboy
Skilled
Posts: 165
Joined: Mon Jan 24, 2011 3:22 am
Personal rank: Codezilla

Re: static function, out parameter and for loop problem

Post by The_Cowboy »

I can't see anything wrong with the code (maybe I am being silly or UE4 C++ coding making my uscript rusty) but I'd embed the log at appropriate places to see exactly what is happening. For instance this should shed some light on the execution procedure

Code: Select all

static function bool hasWhatever(Actor actor, out Inventory inv) {
  local Inventory tmpInv;
 
 Log(" Inside function hasWhatever");
  for (tmpInv = actor.Inventory; tmpInv != None; tmpInv = tmpInv.Inventory) {
   Log("Inside for loop and traversing through"@ tmplnv.class);    
   If (tmpInv.class == class'Whatever') {
      Log("Match found");
      inv = tmpInv;
      Log("Set the outgoing variable, now returning");
return true;
    }
Log("No match. Traversing to next inventory item");  
}

  return false;
}
Also I'd use

Code: Select all

tmpInv.IsA('Whatever')
for conditional check.
Feralidragon wrote:Trial and error is sometimes better than any tutorial, because we learn how it works for ourselfs, which kills any doubts about anything :tu:
Patreon: https://www.patreon.com/FreeandOpen
User avatar
sektor2111
Godlike
Posts: 6403
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: static function, out parameter and for loop problem

Post by sektor2111 »

Return True doesn't mean that "for" cycle is stopped, entire function might still have an out to be pointed and this I'm not sure will stop it just because has a return True - (log entire cycle ?), I think it will reach to the end because nothing breaks the cycle when target has been found. In such a cycle when you have found your actor target just break it, also there is no need for more iterations. In UE1 some times you will want another programing logic...
and then it will be

Code: Select all

...
return True;
break; //unless it will loop to the end
...
Also I must ask what are you doing with that "Actor actor" from parameters...
Last edited by sektor2111 on Wed Jul 17, 2019 6:14 am, edited 1 time in total.
Higor
Godlike
Posts: 1866
Joined: Sun Mar 04, 2012 6:47 pm

Re: static function, out parameter and for loop problem

Post by Higor »

Trivia: this code reduces UnrealScript iteration count, not the legible kind though.

Code: Select all

static function bool hasWhatever( Actor Actor, out Inventory Inv)
{
    for ( Inv=Actor.Inventory; Inv != None && Inv.class != class'Whatever'  ; Inv=Inv.Inventory) {}
    return Inv != None;
}
EDIT:
Any of the functions works fine, if item you're looking for is at the end of the inventory chain, it's because it was added earlier than other items.
User avatar
sektor2111
Godlike
Posts: 6403
Joined: Sun May 09, 2010 6:15 pm
Location: On the roof.

Re: static function, out parameter and for loop problem

Post by sektor2111 »

Bang ! I might what to copy Higor's solution... and using Pawn because I don't think a carcass has an Inventory...
User avatar
PrinceOfFunky
Godlike
Posts: 1200
Joined: Mon Aug 31, 2015 10:31 pm

Re: static function, out parameter and for loop problem

Post by PrinceOfFunky »

I believe I've found the bug! So I put the previous post in spoiler:
Spoiler
The_Cowboy wrote:Also I'd use

Code: Select all

tmpInv.IsA('Whatever')
for conditional check.
This would return true even for child classes :/
sektor2111 wrote:Return True doesn't mean that "for" cycle is stopped, entire function might still have an out to be pointed and this I'm not sure will stop it just because has a return True - (log entire cycle ?), I think it will reach to the end because nothing breaks the cycle when target has been found. In such a cycle when you have found your actor target just break it, also there is no need for more iterations. In UE1 some times you will want another programing logic...
and then it will be

Code: Select all

...
return True;
break; //unless it will loop to the end
...
Also I must ask what are you doing with that "Actor actor" from parameters...
I thought about the function continuing to executing, that would have sense if the out parameter was set with an inventory found after the return statement, but the problem is that the out parameter is set with an inventory found before the return statement and before the last found one. I'll still try the break statement anyway.

This was the original flow, each screenshot is a different function:
touch.jpg
touch.jpg (9.87 KiB) Viewed 687 times
hasInv.jpg
classIsRelatedTo.jpg
and these are the logs:
log.jpg
log.jpg (49.37 KiB) Viewed 687 times
I know the function I wrote in the first post looks different from "hasInv()" but the result is the same, I already tried it.


EDIT: Just logged out this:
what.jpg
Maybe classIsRelatedTo() doesn't return anything even if firstClass is equal to secondClass... That sounds strange to me .o.
EDIT 2: Nvm it does. (I would post a screenshot but I reached the limit of 5 screenshots).

EDIT 3: I changed the code like this (it even skips classIsRelatedTo()):

Code: Select all

static function bool hasInv(Actor actor, class<Inventory> invClass, out Inventory inv, optional bool bNoSubclass) {
	for (inv = actor.inventory; inv != None; inv = inv.inventory) {
		Log(1);
		Log("Before checking classes"@inv);
		Log(2);
		if (invClass == inv.Inventory.class) {
			Log("Before returning true"@inv);
			return true;
		}
	}
		
	inv = None;
	return false;
}
And these are the logs:

Code: Select all

ScriptLog: 123456789 Botpack.minigun2
ScriptLog: True False False 100 100
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.enforcer1
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.WarHeadAmmo0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.WarheadLauncher1
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.ThighPads2
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.Armor0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.RocketPack0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.UT_Eightball0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.BladeHopper0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.ripper0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.BulletBox0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.SniperRifle0
ScriptLog: 2
ScriptLog: 1
ScriptLog: Before checking classes UR-HyperBlast.Miniammo0
ScriptLog: 2
ScriptLog: Before returning true UR-HyperBlast.Miniammo0
ScriptLog: ISTHISTHELOG? Botpack.minigun2 UR-HyperBlast.Miniammo0
So now, all of a sudden, it is not printing the minigun2 log? I don't get how it is possible to pass this check "invClass == inv.Inventory.class" with invClass=Botpack.minigun2 and inv.Inventory.class=Botpack.Miniammo...
So, essentially... the bug was in "inv.Inventory.class" which should have been "inv.class". I know... a stupid bug, but don't blame me, none of you noticed it neither :roll:
"Your stuff is known to be buggy and unfinished/not properly tested"
Post Reply