From e7721811ddc14f49dd4639e2b44ec6376476dd47 Mon Sep 17 00:00:00 2001 From: GreYFoXGTi Date: Sat, 21 Aug 2010 04:20:01 +0200 Subject: [PATCH] Added Fluxid's HookThrough Signed-off-by: GreYFoXGTi --- src/game/collision.cpp | 66 +++++++++++++++++++++++-- src/game/collision.h | 3 +- src/game/gamecore.cpp | 4 +- src/game/gamecore.h | 1 + src/game/server/entities/character.cpp | 3 +- src/game/server/entities/gun.cpp | 2 +- src/game/server/entities/gun.h | 2 +- src/game/server/entities/laser.cpp | 2 +- src/game/server/entities/projectile.cpp | 2 +- 9 files changed, 73 insertions(+), 12 deletions(-) diff --git a/src/game/collision.cpp b/src/game/collision.cpp index 246a42470..016d9a456 100644 --- a/src/game/collision.cpp +++ b/src/game/collision.cpp @@ -162,7 +162,8 @@ int CCollision::GetCollisionDDRace(int Index) int CCollision::GetCollisionDDRace2(int Index) { /*dbg_msg("GetCollisionDDRace2","m_pFront[%d].m_Index = %d",Index,m_pFront[Index].m_Index);//Remove*/ - if(Index < 0) + + if(Index < 0 || !m_pFront) return 0; return m_pFront[Index].m_Index; } @@ -194,22 +195,61 @@ void CCollision::SetCollisionAt(float x, float y, int flag) } // TODO: rewrite this smarter! -int CCollision::IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision) +void ThroughOffset(vec2 Pos0, vec2 Pos1, int *Ox, int *Oy) +{ + float x = Pos0.x - Pos1.x; + float y = Pos0.y - Pos1.y; + if (fabs(x) > fabs(y)) + { + if (x < 0) + { + *Ox = -32; + *Oy = 0; + } + else + { + *Ox = 32; + *Oy = 0; + } + } + else + { + if (y < 0) + { + *Ox = 0; + *Oy = -32; + } + else + { + *Ox = 0; + *Oy = 32; + } + } +} + +int CCollision::IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision, bool AllowThrough) { float d = distance(Pos0, Pos1); vec2 Last = Pos0; - + int ix, iy; // Temporary position for checking collision + int dx, dy; // Offset for checking the "through" tile + if (AllowThrough) + { + ThroughOffset(Pos0, Pos1, &dx, &dy); + } for(float f = 0; f < d; f++) { float a = f/d; vec2 Pos = mix(Pos0, Pos1, a); - if(CheckPoint(Pos.x, Pos.y)) + ix = round(Pos.x); + iy = round(Pos.y); + if(CheckPoint(ix, iy) && !(AllowThrough && IsThrough(ix + dx, iy + dy))) { if(pOutCollision) *pOutCollision = Pos; if(pOutBeforeCollision) *pOutBeforeCollision = Last; - return GetCollisionAt(Pos.x, Pos.y); + return GetCollisionAt(ix, iy); } Last = Pos; } @@ -391,6 +431,22 @@ int CCollision::IsSolid(int x, int y) return (GetTile(x,y)&COLFLAG_SOLID); } +int CCollision::IsThrough(int x, int y) +{ + int nx = clamp(x/32, 0, m_Width-1); + int ny = clamp(y/32, 0, m_Height-1); + int Index = m_pTiles[ny*m_Width+nx].m_Index; + int Findex; + if (m_pFront) + Findex = m_pFront[ny*m_Width+nx].m_Index; + if (Index == TILE_THROUGH) + return Index; + else if (Findex == TILE_THROUGH) + return Findex; + else + return 0; +} + int CCollision::IsNoLaser(int x, int y) { return (CCollision::GetTile(x,y) & COLFLAG_NOLASER); diff --git a/src/game/collision.h b/src/game/collision.h index 098ec05b8..6fbbf986d 100644 --- a/src/game/collision.h +++ b/src/game/collision.h @@ -27,7 +27,7 @@ public: int GetCollisionAt(float x, float y) { return GetTile(round(x), round(y)); } int GetWidth() { return m_Width; }; int GetHeight() { return m_Height; }; - int IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision); + int IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision, bool AllowThrough); int IntersectNoLaser(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision); int IntersectAir(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision); void MovePoint(vec2 *pInoutPos, vec2 *pInoutVel, float Elasticity, int *Bpounces); @@ -47,6 +47,7 @@ public: bool IsFront(int x, int y); int IsSolid(int x, int y); + int IsThrough(int x, int y); int IsNoLaser(int x, int y); int IsCp(int x, int y); diff --git a/src/game/gamecore.cpp b/src/game/gamecore.cpp index fa7c3c84e..be31fc7d6 100644 --- a/src/game/gamecore.cpp +++ b/src/game/gamecore.cpp @@ -192,18 +192,20 @@ void CCharacterCore::Tick(bool UseInput) { m_HookState = HOOK_RETRACT_START; NewPos = m_Pos + normalize(NewPos-m_Pos) * m_pWorld->m_Tuning.m_HookLength; + m_pReset = true; } // make sure that the hook doesn't go though the ground bool GoingToHitGround = false; bool GoingToRetract = false; - int Hit = m_pCollision->IntersectLine(m_HookPos, NewPos, &NewPos, 0); + int Hit = m_pCollision->IntersectLine(m_HookPos, NewPos, &NewPos, 0,true); if(Hit) { if(Hit&CCollision::COLFLAG_NOHOOK) GoingToRetract = true; else GoingToHitGround = true; + m_pReset = true; } // Check against other players first diff --git a/src/game/gamecore.h b/src/game/gamecore.h index 816e1771c..c3bfa2356 100644 --- a/src/game/gamecore.h +++ b/src/game/gamecore.h @@ -190,6 +190,7 @@ public: int m_Angle; CNetObj_PlayerInput m_Input; + bool m_pReset; int m_TriggeredEvents; void Init(CWorldCore *pWorld, CCollision *pCollision); diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index b1cfaeb42..8aeba0bd8 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -898,11 +898,12 @@ void CCharacter::TickDefered() m_Core.Write(&Current); // only allow dead reackoning for a top of 3 seconds - if(m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0) + if(m_Core.m_pReset || m_ReckoningTick+Server()->TickSpeed()*3 < Server()->Tick() || mem_comp(&Predicted, &Current, sizeof(CNetObj_Character)) != 0) { m_ReckoningTick = Server()->Tick(); m_SendCore = m_Core; m_ReckoningCore = m_Core; + m_Core.m_pReset = false; } } } diff --git a/src/game/server/entities/gun.cpp b/src/game/server/entities/gun.cpp index d86414593..6503a418b 100644 --- a/src/game/server/entities/gun.cpp +++ b/src/game/server/entities/gun.cpp @@ -35,7 +35,7 @@ void CGun::fire() CCharacter *target = ents[i]; int res=0; vec2 coltile; - res = GameServer()->Collision()->IntersectLine(m_Pos, target->m_Pos,0,0); + res = GameServer()->Collision()->IntersectLine(m_Pos, target->m_Pos,0,0,false); if (!res) { int len=length(ents[i]->m_Pos - m_Pos); diff --git a/src/game/server/entities/gun.h b/src/game/server/entities/gun.h index a3eea2093..b6b3a902b 100644 --- a/src/game/server/entities/gun.h +++ b/src/game/server/entities/gun.h @@ -26,4 +26,4 @@ public: }; -#endif \ No newline at end of file +#endif diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp index e654e19e3..122cc068a 100644 --- a/src/game/server/entities/laser.cpp +++ b/src/game/server/entities/laser.cpp @@ -56,7 +56,7 @@ void CLaser::DoBounce() vec2 Coltile; int res; - res = GameServer()->Collision()->IntersectLine(m_Pos, To, &Coltile, &To); + res = GameServer()->Collision()->IntersectLine(m_Pos, To, &Coltile, &To,false); if(res) { diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp index 5e9b54990..b2fe5a5ce 100644 --- a/src/game/server/entities/projectile.cpp +++ b/src/game/server/entities/projectile.cpp @@ -68,7 +68,7 @@ void CProjectile::Tick() vec2 ColPos; vec2 NewPos; vec2 Speed = CurPos - PrevPos; - int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &ColPos, &NewPos); + int Collide = GameServer()->Collision()->IntersectLine(PrevPos, CurPos, &ColPos, &NewPos,false); CCharacter *OwnerChar;