- diff -Naur /home/toil/teeworlds/src/game/client/components/players.cpp src/game/client/components/players.cpp
- --- /home/toil/teeworlds/src/game/client/components/players.cpp 2012-06-26 16:53:53.368860821 +1000
- +++ src/game/client/components/players.cpp 2012-07-07 23:49:37.941683878 +1000
- @@ -272,7 +272,7 @@
- }
- bool Stationary = Player.m_VelX <= 1 && Player.m_VelX >= -1;
- - bool InAir = !Collision()->CheckPoint(Player.m_X, Player.m_Y+16);
- + bool InAir = !(Collision()->CheckPoint(Player.m_X-14, Player.m_Y+16) || Collision()->CheckPoint(Player.m_X+14, Player.m_Y+16));
- bool WantOtherDir = (Player.m_Direction == -1 && Vel.x > 0) || (Player.m_Direction == 1 && Vel.x < 0);
- // evaluate animation
- diff -Naur /home/toil/teeworlds/src/game/collision.cpp src/game/collision.cpp
- --- /home/toil/teeworlds/src/game/collision.cpp 2012-06-26 16:53:53.376860790 +1000
- +++ src/game/collision.cpp 2012-07-08 15:06:05.856569985 +1000
- @@ -26,14 +26,14 @@
- m_Width = m_pLayers->GameLayer()->m_Width;
- m_Height = m_pLayers->GameLayer()->m_Height;
- m_pTiles = static_cast<CTile *>(m_pLayers->Map()->GetData(m_pLayers->GameLayer()->m_Data));
- -
- +
- for(int i = 0; i < m_Width*m_Height; i++)
- {
- int Index = m_pTiles[i].m_Index;
- -
- +
- if(Index > 128)
- continue;
- -
- +
- switch(Index)
- {
- case TILE_DEATH:
- @@ -45,35 +45,64 @@
- case TILE_NOHOOK:
- m_pTiles[i].m_Index = COLFLAG_SOLID|COLFLAG_NOHOOK;
- break;
- + case TILE_SLOPE:
- + {
- + m_pTiles[i].m_Index = COLFLAG_SLOPE;
- + m_pTiles[i].m_Flags = OrientationTile(m_pTiles[i].m_Flags, 1);
- + }
- + break;
- + case TILE_SLOPE_NH:
- + {
- + m_pTiles[i].m_Index = COLFLAG_SLOPE|COLFLAG_NOHOOK;
- + m_pTiles[i].m_Flags = OrientationTile(m_pTiles[i].m_Flags, 1);
- + }
- + break;
- default:
- m_pTiles[i].m_Index = 0;
- }
- }
- }
- -int CCollision::GetTile(int x, int y)
- +int CCollision::GetTile(int x, int y, int *pFlags, int *pDx, int *pDy)
- {
- - int Nx = clamp(x/32, 0, m_Width-1);
- - int Ny = clamp(y/32, 0, m_Height-1);
- + int Address = clamp(y/32, 0, m_Height-1)*m_Width + clamp(x/32, 0, m_Width-1);
- + int Index = m_pTiles[Address].m_Index;
- +
- + if(Index&COLFLAG_SLOPE)
- + {
- + int Flags = m_pTiles[Address].m_Flags;
- + int Dx = x < 0 ? 31-abs(x)%32 : x%32;
- + int Dy = y < 0 ? 31-abs(y)%32 : y%32;
- +
- + if((Flags == 1 && Dy >= Dx) || (Flags == 3 && Dy+Dx <= 31) || (Flags == 5 && Dy <= Dx) || (Flags == 7 && Dy+Dx >= 31))
- + Index |= COLFLAG_SOLID;
- + else if(Index&COLFLAG_NOHOOK)
- + Index ^= COLFLAG_NOHOOK;
- +
- + if(pDx) *pDx = Dx;
- + if(pDy) *pDy = Dy;
- + if(pFlags) *pFlags = Flags;
- +}
- +
- +return Index > 128 ? 0 : Index;
- - return m_pTiles[Ny*m_Width+Nx].m_Index > 128 ? 0 : m_pTiles[Ny*m_Width+Nx].m_Index;
- }
- bool CCollision::IsTileSolid(int x, int y)
- {
- - return GetTile(x, y)&COLFLAG_SOLID;
- + return GetTile(x,y)&COLFLAG_SOLID;
- }
- // TODO: rewrite this smarter!
- int CCollision::IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision)
- {
- - float Distance = distance(Pos0, Pos1);
- - int End(Distance+1);
- + float d = distance(Pos0, Pos1);
- + int End(d+1);
- vec2 Last = Pos0;
- -
- +
- for(int i = 0; i < End; i++)
- {
- - float a = i/Distance;
- + float a = i/d;
- vec2 Pos = mix(Pos0, Pos1, a);
- if(CheckPoint(Pos.x, Pos.y))
- {
- @@ -97,52 +126,127 @@
- {
- if(pBounces)
- *pBounces = 0;
- -
- +
- vec2 Pos = *pInoutPos;
- - vec2 Vel = *pInoutVel;
- - if(CheckPoint(Pos + Vel))
- + vec2 NewPos = Pos + *pInoutVel;
- + int Flags, Index = GetTile(round(NewPos.x), round(NewPos.y), &Flags);
- +
- + if(Index&COLFLAG_SOLID)
- {
- int Affected = 0;
- - if(CheckPoint(Pos.x + Vel.x, Pos.y))
- +
- + if(Index&COLFLAG_SLOPE)
- + {
- + if(round(NewPos.x)/32 == round(Pos.x)/32 && round(NewPos.y)/32 == round(Pos.y)/32)//not correct, only approximative
- + {
- + vec2 Reflex = vec2(pInoutVel->y, pInoutVel->x); //inverting axisses values
- + if(Flags == 3 || Flags == 7)
- + Reflex *= -1; //inverting sings
- +
- + *pInoutVel = Elasticity? Reflex*Elasticity : (*pInoutVel+Reflex)*0.5f;
- + if(pBounces)
- + (*pBounces)++;
- + Affected++;
- +
- + return;
- + }
- + }
- +
- + if(CheckPoint(NewPos.x, Pos.y))
- {
- pInoutVel->x *= -Elasticity;
- if(pBounces)
- - (*pBounces)++;
- + (*pBounces)++;
- Affected++;
- }
- - if(CheckPoint(Pos.x, Pos.y + Vel.y))
- + if(CheckPoint(Pos.x, NewPos.y))
- {
- pInoutVel->y *= -Elasticity;
- if(pBounces)
- - (*pBounces)++;
- + (*pBounces)++;
- Affected++;
- }
- -
- +
- if(Affected == 0)
- - {
- - pInoutVel->x *= -Elasticity;
- - pInoutVel->y *= -Elasticity;
- - }
- + *pInoutVel *= -Elasticity;
- }
- else
- {
- - *pInoutPos = Pos + Vel;
- + *pInoutPos = NewPos;
- }
- }
- -bool CCollision::TestBox(vec2 Pos, vec2 Size)
- +int CCollision::TestBox(vec2 Pos, vec2 Size)
- {
- - Size *= 0.5f;
- - if(CheckPoint(Pos.x-Size.x, Pos.y-Size.y))
- - return true;
- - if(CheckPoint(Pos.x+Size.x, Pos.y-Size.y))
- - return true;
- - if(CheckPoint(Pos.x-Size.x, Pos.y+Size.y))
- - return true;
- - if(CheckPoint(Pos.x+Size.x, Pos.y+Size.y))
- - return true;
- - return false;
- + Pos -= Size*0.5f;
- + int Flags, Dx, Dy, Index = GetTile(round(Pos.x), round(Pos.y), &Flags, &Dx, &Dy);
- + if(Index&COLFLAG_SOLID)
- + {
- + if(Index&COLFLAG_SLOPE && Flags == 3)
- + return 3;
- + else
- + return 64;
- + }
- + else if(Index&COLFLAG_SLOPE)
- + {
- + if(Flags == 1 && Dy+Size.y > Dx)
- + return 64; //16|8
- + else if(Flags == 5 && Dy < Dx+Size.x)
- + return 64; //32|2
- + }
- +
- + Pos.x += Size.x;
- + Index = GetTile(round(Pos.x), round(Pos.y), &Flags, &Dx, &Dy);
- + if(Index&COLFLAG_SOLID)
- + {
- + if(Index&COLFLAG_SLOPE && Flags == 5)
- + return 5;
- + else
- + return 64;
- + }
- + else if(Index&COLFLAG_SLOPE)
- + {
- + if(Flags == 3 && Dy+Dx < 31+Size.x)
- + return 64; // 32|1
- + else if(Flags == 7 && Dy+Size.y+Dx > 31)
- + return 64; // 16|4
- + }
- +
- + Pos.y += Size.y;
- + Index = GetTile(round(Pos.x), round(Pos.y), &Flags, &Dx, &Dy);
- + if(Index&COLFLAG_SOLID)
- + {
- + if(Index&COLFLAG_SLOPE && Flags == 7)
- + return 7;
- + else
- + return 64;
- + }
- + else if(Index&COLFLAG_SLOPE)
- + {
- + if(Flags == 1 && Dy+Size.x > Dx)
- + return 64; // 32|8
- + else if(Flags == 5 && Dy-Size.y < Dx)
- + return 64; // 16|2
- + }
- + Pos.x -= Size.x;
- + Index = GetTile(round(Pos.x), round(Pos.y), &Flags, &Dx, &Dy);
- + if(Index&COLFLAG_SOLID)
- + {
- + if(Index&COLFLAG_SLOPE && Flags == 1)
- + return 1;
- + else
- + return 64;
- + }
- + else if(Index&COLFLAG_SLOPE)
- + {
- + if(Flags == 3 && Dy+Dx-Size.y < 31)
- + return 64; // 16|1
- + else if(Flags == 7 && Dy+Dx > 31-Size.x)
- + return 64; // 32|4
- + }
- +
- + return 0;
- }
- void CCollision::MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity)
- @@ -150,10 +254,10 @@
- // do the move
- vec2 Pos = *pInoutPos;
- vec2 Vel = *pInoutVel;
- -
- +
- float Distance = length(Vel);
- int Max = (int)Distance;
- -
- +
- if(Distance > 0.00001f)
- {
- //vec2 old_pos = pos;
- @@ -163,42 +267,107 @@
- //float amount = i/(float)max;
- //if(max == 0)
- //amount = 0;
- -
- +
- vec2 NewPos = Pos + Vel*Fraction; // TODO: this row is not nice
- -
- - if(TestBox(vec2(NewPos.x, NewPos.y), Size))
- +
- + if(TestBox(NewPos, Size))
- {
- int Hits = 0;
- - if(TestBox(vec2(Pos.x, NewPos.y), Size))
- + int Colliding = TestBox(vec2(NewPos.x, Pos.y), Size);
- + if(Colliding)
- {
- - NewPos.y = Pos.y;
- - Vel.y *= -Elasticity;
- + if(Colliding == 64)
- + Vel.x *= -Elasticity;
- + else if(IntersectSlope(Colliding, &Vel, Elasticity))
- + Pos = vec2(round(Pos.x), round(Pos.y));
- +
- Hits++;
- }
- -
- - if(TestBox(vec2(NewPos.x, Pos.y), Size))
- +
- + Colliding = TestBox(vec2(Pos.x, NewPos.y), Size);
- + if(Colliding)
- {
- - NewPos.x = Pos.x;
- - Vel.x *= -Elasticity;
- + if(Colliding == 64)
- + Vel.y *= -Elasticity;
- + else if(IntersectSlope(Colliding, &Vel, Elasticity))
- + Pos = vec2(round(Pos.x), round(Pos.y));
- +
- Hits++;
- }
- -
- +
- // neither of the tests got a collision.
- // this is a real _corner case_!
- if(Hits == 0)
- - {
- - NewPos.y = Pos.y;
- - Vel.y *= -Elasticity;
- - NewPos.x = Pos.x;
- - Vel.x *= -Elasticity;
- - }
- - }
- + Vel *= -Elasticity;
- - Pos = NewPos;
- + }
- + else
- + Pos = NewPos;
- }
- }
- -
- +
- *pInoutPos = Pos;
- *pInoutVel = Vel;
- }
- +
- +int CCollision::OrientationTile(int Flags, int Dir)
- +{ //Converts tiles flags to get effective direction drawn in the map editor
- + // Examples Dir(values)[axisses reference]: (0)=to down[x=0:y=1]; (1)=to bottom-right[x=1:y=1]; (2)=to right[x=1:y=0];...
- + if(Dir == 1)
- + {
- + if(Flags&TILEFLAG_ROTATE)
- + {
- + if(Flags&TILEFLAG_HFLIP)
- + Dir = Flags&TILEFLAG_VFLIP? 7 : 5;
- + else
- + Dir = Flags&TILEFLAG_VFLIP? 1 : 3;
- + }
- + else
- + {
- + if(Flags&TILEFLAG_HFLIP)
- + Dir = Flags&TILEFLAG_VFLIP? 5 : 3;
- + else
- + Dir = Flags&TILEFLAG_VFLIP? 7 : 1;
- + }
- + }
- + else if(Dir == 4)//this variant is useless now, but in future coulbe be used
- + {
- + if(Flags&TILEFLAG_ROTATE)
- + Dir = Flags&TILEFLAG_HFLIP? 6 : 2;
- + else
- + Dir = Flags&TILEFLAG_HFLIP? 0 : 4;
- + }
- +
- + return Dir;
- +}
- +
- +bool CCollision::IntersectSlope(int Flags, vec2 *pVel, int Elasticity)
- +{
- + vec2 Vel = *pVel;
- + if((Flags==1 && Vel.y > Vel.x) || (Flags==3 && Vel.y+Vel.x < 0) || (Flags==5 && Vel.y < Vel.x) || (Flags==7 && Vel.y+Vel.x > 0))
- + {
- + vec2 Reaction = vec2(Vel.y, Vel.x); //inverting axisses values
- + if(Flags == 3 || Flags == 7)
- + Reaction *= -1; //inverting sings
- +
- + *pVel = Elasticity? Reaction*Elasticity : (Vel+Reaction)*0.5f;
- + return true;
- + }
- + else
- + return false;
- +
- +//more general intersection function: maybe useful in future (not formatted)
- +/* //equation of the line(AB) in implicit form (ax+by+c=0) analytic geometry
- +float a1= Vel.y-Corner.y, b1= Corner.x-Vel.x, c1= -Corner.x*Vel.y; //1 first line: player movement
- +float a2= B.y-A.y, b2= A.x-B.x, c2= -A.x*B.y; //2 second line: slope segment
- +
- +float d = a1*b2-a2*b1;
- +
- +if(d)//lines are not parallel
- +{
- +vec2 HitPoint = vec2((b1*c2-b2*c1)/d, (a2*c1-a1*c2)/d);
- +}
- +else
- +return false*/
- +}
- diff -Naur /home/toil/teeworlds/src/game/collision.h src/game/collision.h
- --- /home/toil/teeworlds/src/game/collision.h 2012-06-26 16:53:53.376860790 +1000
- +++ src/game/collision.h 2012-07-07 23:49:37.953689524 +1000
- @@ -13,14 +13,16 @@
- class CLayers *m_pLayers;
- bool IsTileSolid(int x, int y);
- - int GetTile(int x, int y);
- -
- + int GetTile(int x, int y, int *pFlags=0, int *pDx=0, int *pDy=0);
- + int OrientationTile(int Flags, int Dir);
- + bool IntersectSlope(int Flags, vec2 *pVel, int Elasticity);
- public:
- enum
- {
- COLFLAG_SOLID=1,
- COLFLAG_DEATH=2,
- COLFLAG_NOHOOK=4,
- + COLFLAG_SLOPE=8,
- };
- CCollision();
- @@ -33,7 +35,7 @@
- int IntersectLine(vec2 Pos0, vec2 Pos1, vec2 *pOutCollision, vec2 *pOutBeforeCollision);
- void MovePoint(vec2 *pInoutPos, vec2 *pInoutVel, float Elasticity, int *pBounces);
- void MoveBox(vec2 *pInoutPos, vec2 *pInoutVel, vec2 Size, float Elasticity);
- - bool TestBox(vec2 Pos, vec2 Size);
- + int TestBox(vec2 Pos, vec2 Size);
- };
- #endif
- diff -Naur /home/toil/teeworlds/src/game/editor/layer_tiles.cpp src/game/editor/layer_tiles.cpp
- --- /home/toil/teeworlds/src/game/editor/layer_tiles.cpp 2012-06-26 16:53:53.380861019 +1000
- +++ src/game/editor/layer_tiles.cpp 2012-07-08 14:44:12.416572514 +1000
- @@ -219,7 +219,6 @@
- m_pTiles[y*m_Width+x] = m_pTiles[y*m_Width+m_Width-1-x];
- m_pTiles[y*m_Width+m_Width-1-x] = Tmp;
- }
- -
- if(!m_Game)
- for(int y = 0; y < m_Height; y++)
- for(int x = 0; x < m_Width; x++)
- @@ -244,13 +243,13 @@
- void CLayerTiles::BrushRotate(float Amount)
- {
- - int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0°, 1=90°, 2=180°, 3=270°
- + int Rotation = (round(360.0f*Amount/(pi*2))/90)%4; // 0=0ᅵ, 1=90ᅵ, 2=180ᅵ, 3=270ᅵ
- if(Rotation < 0)
- Rotation +=4;
- if(Rotation == 1 || Rotation == 3)
- {
- - // 90° rotation
- + // 90ᅵ rotation
- CTile *pTempData = new CTile[m_Width*m_Height];
- mem_copy(pTempData, m_pTiles, m_Width*m_Height*sizeof(CTile));
- CTile *pDst = m_pTiles;
- @@ -258,7 +257,7 @@
- for(int y = m_Height-1; y >= 0; --y, ++pDst)
- {
- *pDst = pTempData[y*m_Width+x];
- - if(!m_Game)
- + if(!m_Game || pDst->m_Index == TILE_SLOPE || pDst->m_Index == TILE_SLOPE_NH)
- {
- if(pDst->m_Flags&TILEFLAG_ROTATE)
- pDst->m_Flags ^= (TILEFLAG_HFLIP|TILEFLAG_VFLIP);
- diff -Naur /home/toil/teeworlds/src/game/generated/nethash.c src/game/generated/nethash.c
- --- /home/toil/teeworlds/src/game/generated/nethash.c 1970-01-01 10:00:00.000000000 +1000
- +++ src/game/generated/nethash.c 2012-07-07 23:45:54.225177199 +1000
- @@ -0,0 +1 @@
- +#define GAME_NETVERSION_HASH "b67d1f1a1eea234e"
- diff -Naur /home/toil/teeworlds/src/game/mapitems.h src/game/mapitems.h
- --- /home/toil/teeworlds/src/game/mapitems.h 2012-06-26 16:53:53.384860969 +1000
- +++ src/game/mapitems.h 2012-07-08 14:44:12.416572514 +1000
- @@ -46,6 +46,8 @@
- TILE_SOLID,
- TILE_DEATH,
- TILE_NOHOOK,
- + TILE_SLOPE=17,
- + TILE_SLOPE_NH,
- TILEFLAG_VFLIP=1,
- TILEFLAG_HFLIP=2,
- diff -Naur /home/toil/teeworlds/src/game/server/gamemodes/ctf.cpp src/game/server/gamemodes/ctf.cpp
- --- /home/toil/teeworlds/src/game/server/gamemodes/ctf.cpp 2012-06-26 16:53:53.396862075 +1000
- +++ src/game/server/gamemodes/ctf.cpp 2012-07-07 23:49:37.969176549 +1000
- @@ -287,6 +287,9 @@
- {
- F->m_Vel.y += GameServer()->m_World.m_Core.m_Tuning.m_Gravity;
- GameServer()->Collision()->MoveBox(&F->m_Pos, &F->m_Vel, vec2(F->ms_PhysSize, F->ms_PhysSize), 0.5f);
- +
- + if(GameServer()->Collision()->CheckPoint(F->m_Pos.x, F->m_Pos.y+F->ms_PhysSize/2+5))
- + F->m_Vel.x *= GameServer()->m_World.m_Core.m_Tuning.m_GroundFriction;
- }
- }
- }