player1 pointer: 0x00541318
---
Code:
00494D97 > A1 18135400 MOV EAX,DWORD PTR DS:[541318]
00494D9C . 05 1C020000 ADD EAX,21C ;21C is probably the name offset, 260 byte long char array(unless that changed since assaultcube)
00494DA1 . 50 PUSH EAX ; /Arg3
00494DA2 . 68 BC3C4F00 PUSH sauerbra.004F3CBC ; |Arg2 = 004F3CBC ASCII "rs"
00494DA7 . 6A 5F PUSH 5F ; |Arg1 = 0000005F
00494DA9 . E8 310E0000 CALL sauerbra.00495BDF ; \sauerbra.00495BDF
00494DAE . 83C4 0C ADD ESP,0C
00494DB1 . 5E POP ESI
00494DB2 . C3 RETN
00494DB3 > 68 61964E00 PUSH sauerbra.004E9661
00494DB8 . 33C0 XOR EAX,EAX
00494DBA . E8 2F610000 CALL sauerbra.0049AEEE
00494DBF . 50 PUSH EAX
00494DC0 . 68 C03C4F00 PUSH sauerbra.004F3CC0 ; ASCII "your name is: %s"
---
vector<playerent*> players pointer: 0x005C0768
---
Code:
00496E2B |. 68 48394F00 |PUSH sauerbra.004F3948 ; ASCII "connected: %s"
00496E30 |. E8 8F6CFEFF |CALL sauerbra.0047DAC4
00496E35 |. 8365 F0 00 |AND DWORD PTR SS:[EBP-10],0
00496E39 |. 833D 70075C00 >|CMP DWORD PTR DS:[5C0770],0
00496E40 |. 59 |POP ECX
00496E41 |. 59 |POP ECX
00496E42 |. 7E 24 |JLE SHORT sauerbra.00496E68
00496E44 |> A1 68075C00 |/MOV EAX,DWORD PTR DS:[5C0768] ;<--players!
00496E49 |. 8B4D F0 ||MOV ECX,DWORD PTR SS:[EBP-10] ;index of player we're looking for
00496E4C |. 8B3C88 ||MOV EDI,DWORD PTR DS:[EAX+ECX*4] ;get the addy
00496E4F |. 81C7 04020000 ||ADD EDI,204
00496E55 |. E8 14A6F7FF ||CALL sauerbra.0041146E
00496E5A |. FF45 F0 ||INC DWORD PTR SS:[EBP-10]
00496E5D |. 8B45 F0 ||MOV EAX,DWORD PTR SS:[EBP-10]
00496E60 |. 3B05 70075C00 ||CMP EAX,DWORD PTR DS:[5C0770]
00496E66 |.^7C DC |\JL SHORT sauerbra.00496E44
---
raycubelos(visibility check):
Code:
float viewdist(int x)
{
int fog = getvar("fog");// <-- our string
return x <= 100 ? clamp((SIGHTMIN+(SIGHTMAX-SIGHTMIN))/100.f*float(x), float(SIGHTMIN), float(fog)) : float(fog);
}
float viewfieldx(int x)
{
return x <= 100 ? clamp((VIEWMIN+(VIEWMAX-VIEWMIN))/100.f*float(x), float(VIEWMIN), float(VIEWMAX)) : float(VIEWMAX);
}
float viewfieldy(int x)
{
return viewfieldx(x)*3.f/4.f;
}
bool canmove(fpsent *d)
{
return d->state != CS_DEAD && !intermission;
}
bool targetable(fpsent *d, fpsent *e, bool anyone)
{
if(d == e || !canmove(d)) return false;
aistate &b = d->ai->getstate();
if(b.type != AI_S_WAIT)
return e->state == CS_ALIVE && (!anyone || !isteam(d->team, e->team));
return false;
}
bool getsight(vec &o, float yaw, float pitch, vec &q, vec &v, float mdist, float fovx, float fovy)
{
float dist = o.dist(q);
if(dist <= mdist)
{
float x = fabs((asin((q.z-o.z)/dist)/RAD)-pitch);
float y = fabs((-(float)atan2(q.x-o.x, q.y-o.y)/PI*180+180)-yaw);
if(x <= fovx && y <= fovy) return raycubelos(o, q, v); //our call to raycubelos
}
return false;
}
fog takes you here:
Code:
0048D032 /$ 55 PUSH EBP
0048D033 |. 8BEC MOV EBP,ESP
0048D035 |. 51 PUSH ECX
0048D036 |. 57 PUSH EDI
0048D037 |. 8D7D FC LEA EDI,DWORD PTR SS:[EBP-4]
0048D03A |. C745 FC D8D14E>MOV DWORD PTR SS:[EBP-4],sauerbra.004ED1>; ASCII "fog"
0048D041 |. E8 A005FFFF CALL sauerbra.0047D5E6
Scroll down, since viewfieldy and canmove are small, they are probably optimized away.
Leaving viewfieldx and targetable there, so skip two functions after the one you found fog in and you should now be in getsight:
Code:
0048D163 /$ 55 PUSH EBP
0048D164 |. 8BEC MOV EBP,ESP
0048D166 |. 83EC 0C SUB ESP,0C
0048D169 |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
0048D16C |. 8BCE MOV ECX,ESI
0048D16E |. 8BD7 MOV EDX,EDI
0048D170 |. E8 0779F8FF CALL sauerbra.00414A7C
0048D175 |. D945 10 FLD DWORD PTR SS:[EBP+10]
0048D178 |. D8D9 FCOMP ST(1)
0048D17A |. DFE0 FSTSW AX
0048D17C |. F6C4 01 TEST AH,1
0048D17F |. 75 7D JNZ SHORT sauerbra.0048D1FE
0048D181 |. D946 08 FLD DWORD PTR DS:[ESI+8]
0048D184 |. 51 PUSH ECX
0048D185 |. D867 08 FSUB DWORD PTR DS:[EDI+8]
0048D188 |. 51 PUSH ECX
0048D189 |. DEF1 FDIVRP ST(1),ST
0048D18B |. DD1C24 FSTP QWORD PTR SS:[ESP]
0048D18E |. E8 2D8A0200 CALL sauerbra.004B5BC0
0048D193 |. D80D CC5E4F00 FMUL DWORD PTR DS:[4F5ECC]
0048D199 |. D865 0C FSUB DWORD PTR SS:[EBP+C]
0048D19C |. DD1C24 FSTP QWORD PTR SS:[ESP]
0048D19F |. E8 29810200 CALL sauerbra.004B52CD
0048D1A4 |. D95D 10 FSTP DWORD PTR SS:[EBP+10]
0048D1A7 |. D946 04 FLD DWORD PTR DS:[ESI+4]
0048D1AA |. D867 04 FSUB DWORD PTR DS:[EDI+4]
0048D1AD |. D95C24 04 FSTP DWORD PTR SS:[ESP+4]
0048D1B1 |. D906 FLD DWORD PTR DS:[ESI]
0048D1B3 |. D827 FSUB DWORD PTR DS:[EDI]
0048D1B5 |. D91C24 FSTP DWORD PTR SS:[ESP]
0048D1B8 |. E8 ED25F9FF CALL sauerbra.0041F7AA
0048D1BD |. D80D EC5E4F00 FMUL DWORD PTR DS:[4F5EEC]
0048D1C3 |. D82D F45D4F00 FSUBR DWORD PTR DS:[4F5DF4]
0048D1C9 |. D865 08 FSUB DWORD PTR SS:[EBP+8]
0048D1CC |. DD1C24 FSTP QWORD PTR SS:[ESP]
0048D1CF |. E8 F9800200 CALL sauerbra.004B52CD
0048D1D4 |. D945 14 FLD DWORD PTR SS:[EBP+14]
0048D1D7 |. 59 POP ECX
0048D1D8 |. D85D 10 FCOMP DWORD PTR SS:[EBP+10]
0048D1DB |. 59 POP ECX
0048D1DC |. DFE0 FSTSW AX
0048D1DE |. F6C4 01 TEST AH,1
0048D1E1 |. 75 1B JNZ SHORT sauerbra.0048D1FE
0048D1E3 |. D85D 18 FCOMP DWORD PTR SS:[EBP+18]
0048D1E6 |. DFE0 FSTSW AX
0048D1E8 |. F6C4 41 TEST AH,41
0048D1EB |. 7A 13 JPE SHORT sauerbra.0048D200
0048D1ED |. 68 8C155400 PUSH sauerbra.0054158C
0048D1F2 |. 8BCE MOV ECX,ESI
0048D1F4 |. 8BC7 MOV EAX,EDI
0048D1F6 |. E8 28DFF8FF CALL sauerbra.0041B123 ; RayCubeLOS
0048D1FB |. 59 POP ECX
0048D1FC |. C9 LEAVE
0048D1FD |. C3 RETN
0048D1FE |> DDD8 FSTP ST
0048D200 |> 32C0 XOR AL,AL
0048D202 |. C9 LEAVE
0048D203 \. C3 RETN
Follow that call, now you should end up at 0x0041B123
For the sake of clarifying I have the right function, I use Hex rays plugin for IDA.
Hex rays turned it into this:
Code:
bool __usercall sub_41B123<eax>(int a1<eax>, int a2<ecx>, int a3)
{
double v3; // st7@1
double v4; // st7@1
float v6; // [sp+14h] [bp-10h]@1
float v7; // [sp+18h] [bp-Ch]@1
float v8; // [sp+1Ch] [bp-8h]@1
float v9; // [sp+20h] [bp-4h]@1
LODWORD(v6) = *(_DWORD *)a2;
LODWORD(v7) = *(_DWORD *)(a2 + 4);
LODWORD(v8) = *(_DWORD *)(a2 + 8);
v6 = v6 - *(float *)a1;
v7 = v7 - *(float *)(a1 + 4);
v8 = v8 - *(float *)(a1 + 8);
v9 = sub_4576C0();
v3 = 1.0 / v9;
v6 = v6 * v3;
v7 = v7 * v3;
v8 = v3 * v8;
v4 = sub_41B0CD(&v6, a3, LODWORD(v9), 19);
return v4 >= v9;
}
Original is:
Code:
bool raycubelos(const vec &o, const vec &dest, vec &hitpos)
{
vec ray(dest);
ray.sub(o);
float mag = ray.magnitude();
ray.mul(1/mag);
float distance = raycubepos(o, ray, hitpos, mag, RAY_CLIPMAT|RAY_POLY);
return distance >= mag;
}
Yep, definatly the right function

vector<playerent *>:

ointer players to get pointer to vector