Massassi Forums Logo

This is the static archive of the Massassi Forums. The forums are closed indefinitely. Thanks for all the memories!

You can also download Super Old Archived Message Boards from when Massassi first started.

"View" counts are as of the day the forums were archived, and will no longer increase.

ForumsCog Forum → Difficult cog problem ( Experienced coggers needed )
Difficult cog problem ( Experienced coggers needed )
2002-01-24, 11:20 PM #1
Alright I have my self a cog that will at the start of a game find and compress all the floor surfaces in the level into a large set of vectors comprised of 3x3 spaces for a three didget surface ref.

i.e X= 000 000 000 || Y= 000 000 000 || Z= 000 000 000

surf1=20
surf2=200
surf3=999
surf4=2
and so on ...

Equals

X= 020200999 || Y= 002000000

Now thats all fine and good... but when it becomes time to decompile it again so you get 9 surface refs from one vector ... thats when the problems arise ...

Code:
startup:

num=0;
newcount=1;
for(i=0; i<GetSurfaceCount(); i=i+1)
{
 if(GetSurfaceFlags(i) & 0x1 && newcount < 15 && i < 1000)
 {
  num=num+1;
  if(num > 9)
  {
  num=1;
  newcount=newcount+1;
  }
  if(num == 1) surf0[newcount]=VectorSet(VectorX(surf0[newcount]) + i*n1, VectorY(surf0[newcount]), VectorZ(surf0[newcount]));
  if(num == 2) surf0[newcount]=VectorSet(VectorX(surf0[newcount]) + i*n2, VectorY(surf0[newcount]), VectorZ(surf0[newcount]));
  if(num == 3) surf0[newcount]=VectorSet(VectorX(surf0[newcount]) + i*n3, VectorY(surf0[newcount]), VectorZ(surf0[newcount]));
  if(num == 4) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]) + i*n1, VectorZ(surf0[newcount]));
  if(num == 5) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]) + i*n2, VectorZ(surf0[newcount]));
  if(num == 6) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]) + i*n3, VectorZ(surf0[newcount]));
  if(num == 7) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]), VectorZ(surf0[newcount]) + i*n1);
  if(num == 8) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]), VectorZ(surf0[newcount]) + i*n2);
  if(num == 9) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]), VectorZ(surf0[newcount]) + i*n3);
 }
}

for(i=0; i<newcount; i=i+1)
{
close=9999;
for(e=0; e<GetSurfaceCount(); e=e+1)
{
 dist=VectorDist(GetSectorCenter(e), GetThingPos(player));
 if(dist < close && GetSurfaceFlags(e) & 0x1)
 {
 close=dist;
 closesurf=e;
 }
}

jkStringClear();
jkStringConcatAsciiString("Current Vector= ");
jkStringConcatVector(surf0);
jkStringOutput(-3, -1);

jkStringClear();
jkStringConcatAsciiString("Close Surf= ");
jkStringConcatInt(closesurf);
jkStringOutput(-3, -1);

first=VectorX(surf0)/n1;
surf=first;
if(surf == closesurf) call found;
third=VectorX(surf0)%n2;
surf=third;
if(surf == closesurf) call found;
temp=VectorX(surf0)%n1;
temp2=temp-third;
second=temp2/1000;
surf=second;
if(surf == closesurf) call found;

jkStringClear();
jkStringConcatAsciiString("VectorX Surface1 Vector= ");
jkStringConcatInt(first);
jkStringConcatAsciiString(" VectorX Surface2 Vector= ");
jkStringConcatInt(second);
jkStringConcatAsciiString(" VectorX Surface3 Vector= ");
jkStringConcatInt(third);
jkStringOutput(-3, -1);

first=VectorY(surf0)/n1;
surf=first;
if(surf == closesurf) call found;
third=VectorY(surf0)%n2;
surf=third;
if(surf == closesurf) call found;
temp=VectorY(surf0)%n1;
temp2=temp-third;
second=temp2/1000;
surf=second;
if(surf == closesurf) call found;


jkStringClear();
jkStringConcatAsciiString("VectorY Surface1 Vector= ");
jkStringConcatInt(first);
jkStringConcatAsciiString(" VectorY Surface2 Vector= ");
jkStringConcatInt(second);
jkStringConcatAsciiString(" VectorY Surface3 Vector= ");
jkStringConcatInt(third);
jkStringOutput(-3, -1);

first=VectorZ(surf0)/n1;
surf=first;
if(surf == closesurf) call found;
third=VectorZ(surf0)%n2;
surf=third;
if(surf == closesurf) call found;
temp=VectorZ(surf0)%n1;
temp2=temp-third;
second=temp2/1000;
surf=second;
if(surf == closesurf) call found;


jkStringClear();
jkStringConcatAsciiString("VectorZ Surface1 Vector= ");
jkStringConcatInt(first);
jkStringConcatAsciiString(" VectorZ Surface2 Vector= ");
jkStringConcatInt(second);
jkStringConcatAsciiString(" VectorZ Surface3 Vector= ");
jkStringConcatInt(third);
jkStringOutput(-3, -1);
Sleep(5);
}

return;

found:

Print("Surface");

return;


Now the first part where it compile it into a vector works fine .... but the decompiling part stuff up ... you see to find out what the problem was I put in alot of print messages to see where things are going wrong ...

I tried the cog on Canyon Oasis and this is what it returned from the printing ...

Quote:
<font face="Verdana, Arial" size="2">
Current Vector = (012016022.000000, 024026032, 042056126)

CloseSurf = 32

VectorX Surface1 Vector = 13 VectorX Surface2 Vector = 15 VectorX Surface3 Vector = 22

VectorY Surface1 Vector = 32 VectorY Surface2 Vector = 33 VectorY Surface3 Vector = 42

VectorZ Surface1 Vector = 51 VectorZ Surface2 Vector = 53 VectorZ Surface3 Vector = 60
</font>


Note: That all the numbers from the decompiled vector do not actaly match the same as the top vector; that is done purposly as I do not have enough time to write out the real vector. But trust me it all is the same and correct

Now finnaly getting to the point you see that the closest surface to the player (that is worked out manually because i'm having trouble with the cog) is 32 and one of the numbers in the decompiled surface is 32... now in the cog I have the statments if(surf == closesurf) that should then call and print the message "Surface" if the closest surface equals one of the decompiled surfaces (which it does).

But it doesn't [http://forums.massassi.net/html/frown.gif]

Why ??? Does anyone have any answer to my problem ???

Oh BTW ... I hope I didn't confuse anyone with that last paragraph i'm kinda in a hurry to finish this message...

Thanks

*_Seifer_*
2002-01-25, 3:16 AM #2
I don't think this is your problem but some observations.

You forgot to define:

player = GetLocalPlayerThing();

or

player = GetSourceRef();

but that probably isnt the problem if your testing in LEC levels since the host is 0 anyway.

Also, your testing in a level with < 1000 surface right? It looks like your first For() wont store information on Surfaces > 1000 (obviously cause that would mess up your current vector system) but your second For() when searching for closest surface doesn't take into account the < 1000 limitation.

Unfortunately, I doubt either of those observations is your real problem.
- Wisdom is 99% experience, 1% knowledge. -
2002-01-25, 5:45 AM #3
I don't see how your cog could get the closest surface to the player when it's using GetSectorCenter(surf) instead of GetSurfaceCenter(surf).


newcount starts at one. So that means the first vector used is surf0[1]. But in your second loop, i starts at zero and will try to call surf0[0] which wasn't defined. [http://forums.massassi.net/html/confused.gif]

I look at it some more later on...

------------------
More matter with less art.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2002-01-25, 7:36 AM #4
I think I see the problem.

The dividing only sets the decimal point forward, it does not truncate the decimal portion. So a surface might be 5.106 instead of 5. When printint() or ConcatInt() run, they truncate the decimal part of a number. Print the number as a flex and you'll see the decimal part is there. -JK doesn't care what symbol type a variable is.

This is where you need integer division.

------------------
More matter with less art.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2002-01-25, 10:05 AM #5
Answers :

I have defined the player ... I just did not bother to include it in the cog .... sorry.

Indeed the second for statment does not stop surfaces being over 1000... but it doesn't matter in canyon oasis... and it doesn't matter anyway because I know that the surface is 32.

Sabermaster: Thank you ... you found my first bugs .. I was writing this cog late so I must of made some errors ... I'll fix em ... thanks ...

Also I see what your getting at sabermaster and I have also thought about that .... and I think you maybe right .... what do you mean by Integer division ?
2002-01-25, 10:53 AM #6
You're welcome. [http://forums.massassi.net/html/wink.gif]

I was referring to the DIV operator from Pascal. It returns the integer result of division with no decimal part - the opposite of MOD (%).



------------------
More matter with less art.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2002-01-25, 11:31 AM #7
Ahh... care to explain how that works ??
2002-01-25, 1:54 PM #8
Ok. Say you have the integer 599 and you want to remove the last two digits. 599 DIV 100
will return 5. DIV returns the quotient without the remainder.

And if you wanted to remove the first digit, you would use 599 MOD 100. MOD returns the
remainder of the division.

With real division, you would get the decimal number 5.99.

If you want to try DIV and MOD with your own numbers, open this. But don't
input real numbers - it will terminate the program.

[edit]Yahoo doesn't like linking to downloads. You'll have to copy the link to
the adress bar.[/edit]

AASN, that Pascal program is about 4KB, but even the small "Hello World" of C++ is at
least 75 KBs...

------------------
More matter with less art.

[This message has been edited by SaberMaster (edited January 25, 2002).]

[This message has been edited by SaberMaster (edited January 25, 2002).]
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2002-01-25, 5:07 PM #9
Dude I need some sort of way to do it in cog...
2002-01-25, 10:58 PM #10
I hope this helps/is what yer lookin for:

From CTF_Main.cog:
Code:
      // compute the score display just after startup:
      dummy = SetWallCel(limit1, score_limit / 100);
      dummy = SetWallCel(limit2, (score_limit % 100) / 10);
      dummy = SetWallCel(limit3, score_limit % 10);


SetWallCel(surface, int);

if Score limit was 426:
limit1 would be set to 4, because int(426/100) = 4

limit2 would be set to 2, because score_limit % 100 divides 426 by 100, and returns the remainder, which is 26. int(26/10) = 2

limit3 would be set to 6, because score_limit % 10 divides 426 by 10, and returns the remainder which is 6. int(6) = 6

I really hope this helps. [http://forums.massassi.net/html/smile.gif]

[This message has been edited by Hell Raiser (edited January 26, 2002).]
-Hell Raiser
2002-01-27, 12:03 AM #11
Okay. A cog using concatinated ints, combining them into one 9 digit longint, was the subject of a year and half's research on my part. I was trying to build an adventure-game-style NPC-conversation system, and I was going the super-automated, user-friendly, noncogger-friendly way. I wanted one universal cog that could be reconfigured in JED each time to support different conversations.

Now, I devised a priority tree system that will handle the lines, based on their unistring address, type, next line, and several other parameters. I tried to have every line's paramters inputted as one int in JED, and retrieve the parameters in the cog by using the modulus operator '%'. To my great dismay I discovered that JK's modulus operator is very erratic, never properly retrieving the last two digits. It would randomly change them, rendering the entire system unusable and a year's work down the drain.

So try using a different method, maybe flags.
Dreams of a dreamer from afar to a fardreamer.
2002-01-28, 4:47 AM #12
Well, modulus may not work, but this is the system to truncate a number.
Code:
intsurf=flexsurf - flexsurf%1;


I don't doubt that JK has trouble with its operators, but try it anyway.

------------------
More matter with less art.
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.
2002-01-28, 9:44 AM #13
I see what you mean Fardreamer. But modulo is reliable for so many digits.

That was a problem with the code, Seifer. The third surface could not be retrieved correctly. The last digit of the third surface was incorrectly returned by modulo.

But there is no reason to scrap the system. Make the array larger and store only 6 surfaces per vector.

Like this:
Code:
# facevector.cog
#
# Find and compress all floors in the level to a series of vectors for reference.
#
# The surf array can hold up to 126 surfaces.
# And there are only 82 floor surfaces in Canyon Oasis.
#
# [Seifer + SM]
#======================================================================#
symbols

int		num
int		newcount
int		i
flex		close
flex		dist

thing		player

surface	closesurf
surface	first
surface	second

int		n1=1000
int		n2=1

vector	surf0
vector	surf1
vector	surf2
vector	surf3
vector	surf4
vector	surf5
vector	surf6
vector	surf7
vector	surf8
vector	surf9
vector	surf10
vector	surf11
vector	surf12
vector	surf13
vector	surf14
vector	surf15
vector	surf16
vector	surf17
vector	surf18
vector	surf19
vector	surf20

material	default=dflt.mat

message	activated

end
#======================================================================#
code
#----------------------------------------------------------------
activated:
	num=0;
	newcount=0;
	for(i=0; i < 21; i=i+1) surf0=VectorSet(0, 0, 0);
	player=GetLocalPlayerThing();

	for(i=0; i<GetSurfaceCount(); i=i+1)
	{
		if(GetSurfaceFlags(i) & 0x1 && newcount < 21 && i < 1000)
		{
			num=num+1;
			if(num > 6)
			{
				num=1;
				newcount=newcount+1;
			}
			if(num == 1) surf0[newcount]=VectorSet(VectorX(surf0[newcount]) + i*n1, VectorY(surf0[newcount]), VectorZ(surf0[newcount]));
			if(num == 2) surf0[newcount]=VectorSet(VectorX(surf0[newcount]) + i*n2, VectorY(surf0[newcount]), VectorZ(surf0[newcount]));
			if(num == 3) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]) + i*n1, VectorZ(surf0[newcount]));
			if(num == 4) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]) + i*n2, VectorZ(surf0[newcount]));
			if(num == 5) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]), VectorZ(surf0[newcount]) + i*n1);
			if(num == 6) surf0[newcount]=VectorSet(VectorX(surf0[newcount]), VectorY(surf0[newcount]), VectorZ(surf0[newcount]) + i*n2);
		}
	}

	close=9999;
	for(i=0; i<GetSurfaceCount(); i=i+1)
	{
		dist=VectorDist(GetSurfaceCenter(i), GetThingPos(player));
		if(dist < close && GetSurfaceFlags(i) & 0x1)
		{
			close=dist;
			closesurf=i;
		}
	}

	for(i=0; i<newcount; i=i+1)
	{
		#-------------------- VECTOR X CODE ---------------

		first=VectorX(surf0)/n1;
		first=first - first%1;
		second=(VectorX(surf0)%n1);
		if(first == closesurf || second == closesurf) call found;

		SetSurfaceMat(first, default);
		SetSurfaceMat(second, default);

		#-------------------- VECTOR Y CODE ---------------

		first=VectorY(surf0)/n1;
		first=first - first%1;
		second=(VectorY(surf0)%n1);
		if(first == closesurf || second == closesurf) call found;

		SetSurfaceMat(first, default);
		SetSurfaceMat(second, default);

		#-------------------- VECTOR Z CODE ---------------

		first=VectorZ(surf0)/n1;
		first=first - first%1;
		second=(VectorZ(surf0)%n1);
		if(first == closesurf || second == closesurf) call found;

		SetSurfaceMat(first, default);
		SetSurfaceMat(second, default);
	}

Return;
#----------------------------------------------------------------
found:
	Print("Found Surface");
	PrintInt(closesurf);

Return;
#----------------------------------------------------------------
end

I put in the SetSurfaceMat()s so it's easy to tell what surfaces are being taken out of the vectors.

Good luck [http://forums.massassi.net/html/wink.gif]

[This message has been edited by SaberMaster (edited January 29, 2002).]
Author of the JK DataMaster, Parsec, Scribe, and the EditPlus Cog Files.

↑ Up to the top!