Lol, I think that's because Beerdude didn't like me badmouthing his beloved pizza. :p It's not my fault the man has no taste...
Yeah ok Code: bool CEmpGameRules::CompleteWalls( Vector vecEngWallStart, Vector vecEngWallEnd, CEmpPlayer *pOwner ) { if ( vecEngWallStart == vec3_origin || vecEngWallEnd == vec3_origin ) return false; if ( vecEngWallStart == vecEngWallEnd ) return false; if ( !pOwner ) return false; bool bCommander = pOwner->IsCommander(); int defaultHealth = 25; int iWallsBuilt = 0; CEngineerWalls *pEngWall; //find the angle between each point, find the number of walls to go between each point, find the height of each wall float x,y,a; int quad; float dunno; Vector vecMins, vecMax; x = vecEngWallEnd.x - vecEngWallStart.x; y = vecEngWallEnd.y - vecEngWallStart.y; dunno = (fabs(x)/fabs(y)); a = atan(dunno); a *= 180/M_PI; //the result is in radians and needs to be converted to degrees if (x >= 0) { if (y >= 0) quad = 1; else quad = 2; } else { if (y >= 0) quad = 4; else quad = 3; } //get the angle that the walls should be if (quad == 1) a *= -1; else if (quad == 2) a -= 180; else if (quad == 3) a = -1*(a+180); else {}; //create the first wall to get the mins and maxs bounds of the model pEngWall = (CEngineerWalls*)CreateEntityByName( "emp_eng_walls" ); QAngle wallAngle; wallAngle.x = 0; wallAngle.z = 0; wallAngle.y = a; CEmpPlayer *pPlayer = pOwner; if ( !pEngWall ) return false; pEngWall->ChangeTeam(pPlayer->GetTeamNumber()); if (!bCommander) pEngWall->SetOwner( pPlayer->entindex() ); else pEngWall->SetOwner( 0 ); pEngWall->SetAbsOrigin( vecEngWallStart ); pEngWall->SetAbsAngles( wallAngle ); pEngWall->Spawn(); vecMins = pEngWall->CollisionProp()->OBBMins(); vecMax = pEngWall->CollisionProp()->OBBMaxs(); Vector newEndPos; float flWidth = vecMax.y-2; Vector vel; vel.x = x; vel.y = y; float flTotalWallWidth = vel.Length2D(); float reqWalls = flTotalWallWidth/flWidth; if (reqWalls < 1) reqWalls = 1; int wallRemainder = (int) reqWalls; reqWalls -= wallRemainder; Vector nextWallPoint; nextWallPoint.x = 0; nextWallPoint.y = flWidth; nextWallPoint.z = 0; Vector nextWallPointOut; VectorYawRotate(nextWallPoint, a, nextWallPointOut); trace_t tr, tr2; Vector vecSrc, vecSrc2, vecEnd, vecEnd2; if (reqWalls >= 0.75) { wallRemainder++; reqWalls = 0; } int engWallsAllotted = pPlayer->m_iEngineerWallsAllotted; int engWallsBuilt = pPlayer->m_iEngineerWallsBuilt; if ( bCommander && CEmpParams::GetSingletonPtr() ) { int iResAvailable = CEmpParams::GetSingleton().GetResources( pOwner->GetTeamNumber() ); int iWallCost = wallRemainder*COST_WALLS; //check if there are enough resources to build these walls if (iWallCost > iResAvailable) { pEngWall->Remove(); pEngWall = NULL; ClientPrint(pPlayer, HUD_PRINTCENTER, "Insufficient resources", NULL, NULL, NULL, NULL); return false; } //check if we'll go over this team's wall limit if built if ((pOwner->GetTeamNumber() == EMP_TEAM_NF) || (pOwner->GetTeamNumber() == EMP_TEAM_BE)) { int team = pOwner->GetTeamNumber(); if (wallRemainder + CEmpParams::GetSingleton().GetWallLimit(team) > emp_sv_max_walls.GetInt()) { pEngWall->Remove(); pEngWall = NULL; ClientPrint(pPlayer, HUD_PRINTCENTER, "Team has reached maximum wall limit.", NULL, NULL, NULL, NULL); return false; } } } if ((wallRemainder*3) > (engWallsAllotted - engWallsBuilt) && !bCommander) { pEngWall->Remove(); pEngWall = NULL; char cLimitMsg[128]; Q_snprintf( cLimitMsg,sizeof(cLimitMsg), "You've reached your maximum allotted number of walls or would've exceeded your limit with this wall length. (%i / %i)\n", pPlayer->m_iEngineerWallsBuilt, pPlayer->m_iEngineerWallsAllotted ); ClientPrint( pPlayer, HUD_PRINTCENTER, cLimitMsg ); return false; } //draw two tracelines down from the initial and end points of the wall, find the lower height of the ground and set our wall to rest on that vecSrc = vecEngWallStart; vecSrc2 = vecSrc; vecSrc.z += 300; vecSrc2.z -= 300; vecEnd = vecEngWallStart + nextWallPointOut; vecEnd2 = vecEnd; vecEnd.z += 300; vecEnd2.z -= 300; UTIL_TraceLine( vecSrc, vecSrc2, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_EMP_WALL_PREVIEW, &tr ); UTIL_TraceLine( vecEnd, vecEnd2, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_EMP_WALL_PREVIEW, &tr2 ); if ( tr.DidHitWorld() && tr2.DidHitWorld() && tr.m_pEnt->IsBSPModel() && tr2.m_pEnt->IsBSPModel() && tr.plane.normal.z >= 0.7 && tr2.plane.normal.z >= 0.7) { if (tr.endpos.z > tr2.endpos.z) { if (tr2.fraction < 1) { newEndPos = vecEngWallStart; newEndPos.z = tr2.endpos.z; pEngWall->initialOrigin = newEndPos; if( pEngWall->GetTeamNumber() == TEAM_IMP ) newEndPos.z -= IMP_WALL_OFFSET; // BE wall models are a bit larger, allow them to fire over pEngWall->SetAbsOrigin( newEndPos ); pEngWall->SetHealth(defaultHealth); } else { pEngWall->Remove(); pEngWall = NULL; return false; } } else { if (tr.fraction < 1) { newEndPos = vecEngWallStart; newEndPos.z = tr.endpos.z; if( pEngWall->GetTeamNumber() == TEAM_IMP ) newEndPos.z -= IMP_WALL_OFFSET; // BE wall models are a bit larger, allow them to fire over pEngWall->initialOrigin = newEndPos; pEngWall->SetAbsOrigin( newEndPos ); pEngWall->SetHealth(defaultHealth); } else { pEngWall->Remove(); pEngWall = NULL; return false; } } } else { pEngWall->Remove(); pEngWall = NULL; return false; } //check if the wall hits any non-world entities Vector vecMaxCube, vecMinsNew, vecMaxNew; vecMinsNew = vecMins; vecMinsNew.y = vecMins.x; vecMaxNew = vecMax; vecMaxNew.y = vecMax.x; trace_t coll_tr; CTraceFilterEntities traceFilter(pOwner, COLLISION_GROUP_EMP_WALL_PREVIEW); ITraceFilter *pFilter = &traceFilter; Vector vecTraceSrc = vecEngWallStart; Vector vecTraceEnd = vecEnd; vecTraceEnd.z = vecTraceSrc.z; UTIL_TraceHull(vecTraceSrc, vecTraceEnd, vecMinsNew, vecMaxNew, MASK_SOLID, pFilter, &coll_tr ); if (coll_tr.DidHitNonWorldEntity()) { pEngWall->Remove(); pEngWall = NULL; } //wall was ok, add to our total if (pEngWall) iWallsBuilt+=3; //create all the other walls for (int i=1;i <= wallRemainder;i++) { Vector vecOrigin = vecEngWallStart + nextWallPointOut*i; //check if the build location is within friendly unit distance as the commander if ( bCommander && !CEmpGameRules::CanBuildAt( vecOrigin, pOwner->GetTeamNumber() )) continue; pEngWall = (CEngineerWalls*)CreateEntityByName( "emp_eng_walls" ); Vector newSizeMins, newSizeMax; newSizeMins = vecMins; newSizeMax = vecMax; newSizeMax.y *= 2; if (pEngWall) { if (i < wallRemainder || reqWalls >= 0.75) { pEngWall->ChangeTeam(pPlayer->GetTeamNumber()); if (!bCommander) pEngWall->SetOwner( pPlayer->entindex() ); else pEngWall->SetOwner( 0 ); pEngWall->SetAbsOrigin( vecOrigin ); pEngWall->SetAbsAngles( wallAngle ); pEngWall->Spawn(); vecSrc = vecOrigin; vecSrc2 = vecSrc; vecSrc.z += 300; vecSrc2.z -= 300; vecEnd = vecEngWallStart + nextWallPointOut*(i+1); vecEnd2 = vecEnd; vecEnd.z += 300; vecEnd2.z -= 300; UTIL_TraceLine( vecSrc, vecSrc2, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_EMP_WALL_PREVIEW, &tr ); UTIL_TraceLine( vecEnd, vecEnd2, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_EMP_WALL_PREVIEW, &tr2 ); //if ( tr.fraction == 1.0f && tr2.fraction == 1.0f ) {} if ( tr.DidHitWorld() && tr2.DidHitWorld() && tr.m_pEnt->IsBSPModel() && tr2.m_pEnt->IsBSPModel() && tr.plane.normal.z >= 0.7 && tr2.plane.normal.z >= 0.7) { if (tr.endpos.z > tr2.endpos.z) { //Vector newEndPos; newEndPos = vecOrigin; newEndPos.z = tr2.endpos.z; if( pEngWall->GetTeamNumber() == TEAM_IMP ) newEndPos.z -= IMP_WALL_OFFSET; // BE wall models are a bit larger, allow them to fire over pEngWall->initialOrigin = newEndPos; pEngWall->SetAbsOrigin( newEndPos ); pEngWall->SetHealth(defaultHealth); } else { //Vector newEndPos; newEndPos = vecOrigin; newEndPos.z = tr.endpos.z; (See next reply for the rest)
Code: if( pEngWall->GetTeamNumber() == TEAM_IMP ) newEndPos.z -= IMP_WALL_OFFSET; // BE wall models are a bit larger, allow them to fire over pEngWall->initialOrigin = newEndPos; pEngWall->SetAbsOrigin( newEndPos ); pEngWall->SetHealth(defaultHealth); } } else { newEndPos = vecOrigin; newEndPos.z = tr.endpos.z; pEngWall->Remove(); pEngWall = NULL; } if (pEngWall) { //check if the wall hits any non-world entities Vector vecMaxCube, vecMinsNew, vecMaxNew; //check if the wall hits any non-world entities vecMinsNew = vecMins; vecMinsNew.y = vecMins.x; vecMaxNew = vecMax; vecMaxNew.y = vecMax.x; trace_t coll_tr; CTraceFilterEntities traceFilter(pOwner, COLLISION_GROUP_EMP_WALL_PREVIEW); ITraceFilter *pFilter = &traceFilter; Vector vecTraceSrc = vecOrigin; Vector vecTraceEnd = vecEngWallStart + nextWallPointOut*(i+1); vecTraceEnd.z = vecTraceSrc.z; UTIL_TraceHull(vecTraceSrc, vecTraceEnd, vecMinsNew, vecMaxNew, MASK_SOLID, pFilter, &coll_tr ); if (coll_tr.DidHitNonWorldEntity()) { pEngWall->Remove(); pEngWall = NULL; } } if (pEngWall) iWallsBuilt+=3; } else if (i == wallRemainder) { if (reqWalls > 0) { for (float i2=0;i2<reqWalls;i2+=0.333) { if (i2>0 || !pEngWall) pEngWall = (CEngineerWalls*)CreateEntityByName( "emp_eng_walls" ); pEngWall->ChangeTeam(pPlayer->GetTeamNumber()); if (!bCommander) pEngWall->SetOwner( pPlayer->entindex() ); else pEngWall->SetOwner( 0 ); pEngWall->SetAbsOrigin( (vecEngWallStart + nextWallPointOut*(i + i2)) ); pEngWall->SetAbsAngles( wallAngle ); pEngWall->Spawn(); if (pEngWall->GetTeamNumber() == 2) pEngWall->SetModel("models/NF/Buildings/Walls/nf_wallchunk.mdl"); else if (pEngWall->GetTeamNumber() == 3) pEngWall->SetModel("models/Imperial/Buildings/Walls/imp_wall1chunk.mdl"); pEngWall->m_bChunk = true; vecSrc = vecEngWallStart + nextWallPointOut*(i + i2); vecSrc2 = vecSrc; vecSrc.z += 300; vecSrc2.z -= 300; vecEnd = vecEngWallStart + nextWallPointOut*(i + i2+0.333); vecEnd2 = vecEnd; vecEnd.z += 300; vecEnd2.z -= 300; UTIL_TraceLine( vecSrc, vecSrc2, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_EMP_WALL_PREVIEW, &tr ); UTIL_TraceLine( vecEnd, vecEnd2, MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_EMP_WALL_PREVIEW, &tr2 ); if ( tr.DidHitWorld() && tr2.DidHitWorld() && tr.m_pEnt->IsBSPModel() && tr2.m_pEnt->IsBSPModel() && tr.plane.normal.z >= 0.7 && tr2.plane.normal.z >= 0.7) { if (tr.endpos.z > tr2.endpos.z) { //Vector newEndPos; newEndPos = vecEngWallStart + nextWallPointOut*(i + i2); newEndPos.z = tr2.endpos.z; if( pEngWall->GetTeamNumber() == TEAM_IMP ) newEndPos.z -= IMP_WALL_OFFSET; // BE wall models are a bit larger, allow them to fire over pEngWall->initialOrigin = newEndPos; pEngWall->SetAbsOrigin( newEndPos ); pEngWall->SetHealth(defaultHealth); } else { //Vector newEndPos; newEndPos = vecEngWallStart + nextWallPointOut*(i + i2); newEndPos.z = tr.endpos.z; if( pEngWall->GetTeamNumber() == TEAM_IMP ) newEndPos.z -= IMP_WALL_OFFSET; // BE wall models are a bit larger, allow them to fire over pEngWall->initialOrigin = newEndPos; pEngWall->SetAbsOrigin( newEndPos ); pEngWall->SetHealth(defaultHealth); } } else { newEndPos = vecEngWallStart + nextWallPointOut*(i + i2); pEngWall->Remove(); pEngWall = NULL; } if (pEngWall) { //check if the wall hits any non-world entities Vector vecMaxCube, vecMinsNew, vecMaxNew; vecMinsNew = vecMins; vecMinsNew.y = vecMins.x; vecMaxNew = vecMax; vecMaxNew.y = vecMax.x; trace_t coll_tr; CTraceFilterEntities traceFilter(pOwner, COLLISION_GROUP_EMP_WALL_PREVIEW); ITraceFilter *pFilter = &traceFilter; Vector vecTraceSrc = vecEngWallStart + nextWallPointOut*(i + i2); Vector vecTraceEnd = vecEngWallStart + nextWallPointOut*(i + i2+1); vecTraceEnd.z = vecTraceSrc.z; UTIL_TraceHull(vecTraceSrc, vecTraceEnd, vecMinsNew, vecMaxNew, MASK_SOLID, pFilter, &coll_tr ); if (pEngWall && coll_tr.DidHitNonWorldEntity()) { pEngWall->Remove(); pEngWall = NULL; } if (pEngWall) iWallsBuilt++; } } } } } } //subtract the number of walls built if (!bCommander) { if (iWallsBuilt < 0) return true; /*if (iWallsBuilt+pPlayer->m_iEngineerWallsBuilt > pPlayer->m_iEngineerWallsAllotted) { pPlayer->m_iEngineerWallsBuilt = pPlayer->m_iEngineerWallsAllotted; } else {*/ pPlayer->m_iEngineerWallsBuilt += iWallsBuilt; //} } else if ( CEmpParams::GetSingletonPtr()) { //Reduce the "number of walls" for other calculations such as costing and wall max int iWallsCharged = ceil((double)iWallsBuilt/3); //add the built walls to the wall limit and deduct resources for cost of walls CEmpParams::GetSingleton().AddWalls(pOwner->GetTeamNumber(), iWallsCharged); CEmpParams::GetSingleton().DeductResources( pOwner->GetTeamNumber(), iWallsCharged*COST_WALLS ); } return true; Tadaaa
Code: float x,y,a; int quad; float dunno; mmd edit: oh damn you grant - my post ... ove: edit2: why does the code tags have no syntax highlighting?
Well, I was right about the one gigantic function part, though I didn't think it'd be so bad as to have a variable called "dunno".
huh... there are several parts that can be cut out and replaced with a function call, due to them being the same sets of code. More CPU time wasted... easier to understand, smaller, and cleaner code. Also a few things that can be replaced. Bits and bobs to move around to be understood better too. Ya this could use some love.
you should introduce a whatever variable, which does something, sometimes, maybe ... :D Code: if (x >= 0) { if (y >= 0) quad = 1; else quad = 2; } else { if (y >= 0) quad = 4; else quad = 3; } //get the angle that the walls should be if (quad == 1) a *= -1; else if (quad == 2) a -= 180; else if (quad == 3) a = -1*(a+180); else {}; wow this is redundant³² - also the whole get angle between 2 vectors part should be a single function (is there no native one btw?) anyway. youll probably reuse it a million times. also wouldnt it be smarter to instanciate each wall segment-type once before the game starts to get its dimensions, rather then instantiate and check each and every time? or you could define it in a script ... ... i suggest rewriting rather then refactoring. probably only takes a tenth of the time, including bugfinding. also viro there is no performance gain in functions iirc - if anything pure procedural programming is a tad faster (at least thats what i was told in school), but a mess to maintain for non-trivial programs.
Never again will I complain that devs can't fix shit or that they never do anything, looking at the code for merely placing walls I'd hate to see what something like squad arty or engie camera detection looks like. I just "dunno" what to think anymore.
well it would 'seem' that squad arty would be a much more simpler function then dropping a wall. IF the code wasn't a complete fubar. Get mouse coordinates Check if clear from sky to ground play squad arty duno if that would also entail checking for local entities/targets to receive damage though. That could make it close to the same size.
1) Well that doesn't sound too difficult, there has to be an api that deals with that. 2) It isn't checking in a vertical line though, it's checking in a circle (or so I infer) so it probably has all that a = dunno stuff in it, the code might actually look quite similar to the wall placement code except instead of checking if something can be on a certain point on the ground it checks if something can come from certain point in the skybox. 3) You would still have to code "squad arty", although it would look cleaner if it was done that way.
Only 20 lines of code, with no formatting whatsoever and extremely exploitable and buggy. Coding always seems easy when it comes to thinking about how to implement a feature. Realistically though, even the simplest of functions can require extremely verbose code.
thats what i wanted to express ... ... but you most certainly dont need 393lines either - even with multiple multi-line comments. edit: well if you dont have seperate code for actually building the wall entities, as in the same you could use for any buildable, it ofc gets 393 lines for a single function. now ive read this id really be interested in how the general framework of empires works. edit2: and i now fully understand how its impossible to have faster release cycles.
its impossible due to the spaghetti code. If we turned it into lasagna code it would be easier AND taste better.
I fear I may have killed spartacus with a heart attack My mind hates vectors for some reason, I find them very hard to wrap my head around. I should probably take a course on it or something