#include <physical_obj.h>
Inheritance diagram for PhysicalObj:
Public Member Functions | |
PhysicalObj (const std::string &name, const std::string &xml_config="") | |
virtual | ~PhysicalObj () |
void | SetX (int x) |
void | SetY (int y) |
void | SetXY (const Point2i &position) |
int | GetX () const |
int | GetY () const |
const Point2i | GetPosition () const |
void | SetSize (const Point2i &newSize) |
int | GetWidth () const |
int | GetHeight () const |
Point2i | GetSize () const |
void | SetTestRect (uint left, uint right, uint top, uint bottom) |
const Rectanglei | GetTestRect () const |
int | GetTestWidth () const |
int | GetTestHeight () const |
virtual const std::string & | GetName () const |
int | GetCenterX () const |
int | GetCenterY () const |
const Point2i | GetCenter () const |
const Rectanglei | GetRect () const |
bool | GoesThroughWall () const |
void | UpdatePosition () |
bool | PutOutOfGround () |
bool | PutOutOfGround (double direction) |
void | SetCollisionModel (bool goes_through_wall, bool collides_with_characters, bool collides_with_objects) |
void | SetOverlappingObject (PhysicalObj *obj) |
virtual bool | IsOverlapping (const PhysicalObj *obj) const |
bool | IsInVacuumXY (const Point2i &position, bool check_objects=true) const |
bool | IsInVacuum (const Point2i &offset, bool check_objects=true) const |
PhysicalObj * | CollidedObjectXY (const Point2i &position) const |
PhysicalObj * | CollidedObject (const Point2i &offset) const |
bool | FootsInVacuumXY (const Point2i &position) const |
bool | FootsInVacuum () const |
bool | FootsOnFloor (int y) const |
bool | IsInWater () const |
bool | IsOutsideWorldXY (Point2i position) const |
bool | IsOutsideWorld (const Point2i &offset) const |
virtual void | Refresh ()=0 |
virtual void | Draw ()=0 |
void | AddDamage (uint damage_points) |
void | Init () |
void | Ghost () |
void | Drown () |
void | GoOutOfWater () |
virtual bool | IsImmobile () const |
bool | IsDead () const |
bool | IsGhost () const |
bool | IsDrowned () const |
bool | ObjTouche (const PhysicalObj &b) const |
bool | ObjTouche (const Point2i &p) const |
bool | PutRandomly (bool on_top_of_world, double min_dst_with_characters) |
Protected Member Functions | |
virtual void | CheckOverlapping () |
virtual void | SignalRebound () |
virtual void | SignalObjectCollision (PhysicalObj *obj) |
virtual void | SignalGroundCollision () |
virtual void | SignalCollision () |
virtual void | SignalOutOfMap () |
Protected Attributes | |
PhysicalObj * | m_overlapping_object |
std::string | m_name |
uint | m_test_left |
uint | m_test_right |
uint | m_test_top |
uint | m_test_bottom |
uint | m_width |
uint | m_height |
std::string | m_rebound_sound |
alive_t | m_alive |
int | life_points |
bool | m_allow_negative_y |
Private Member Functions | |
bool | ContactPoint (int &x, int &y) |
void | NotifyMove (Point2d oldPos, Point2d newPos) |
void | DirectFall () |
void | CheckRebound () |
Private Attributes | |
bool | m_goes_through_wall |
bool | m_collides_with_characters |
bool | m_collides_with_objects |
Point2i | m_rebound_position |
Definition at line 47 of file physical_obj.h.
PhysicalObj::PhysicalObj | ( | const std::string & | name, | |
const std::string & | xml_config = "" | |||
) |
Definition at line 54 of file physical_obj.cpp.
00054 : 00055 m_name(name), 00056 m_width(0), 00057 m_height(0) 00058 { 00059 life_points = -1; // Disable lifepoints 00060 m_goes_through_wall = false; 00061 m_collides_with_characters = false; 00062 m_collides_with_objects = false; 00063 00064 // No collision with this object until we have gone out of his collision rectangle 00065 m_overlapping_object = NULL; 00066 00067 m_allow_negative_y = false; 00068 m_alive = ALIVE; 00069 00070 m_rebound_sound = ""; 00071 00072 m_test_left = 0; 00073 m_test_right = 0; 00074 m_test_top = 0; 00075 m_test_bottom = 0; 00076 00077 m_rebound_position = Point2i(-1, -1); 00078 00079 m_cfg.LoadXml(m_name,xml_config); // Load physics constants from the xml file 00080 ResetConstants(); // Set physics constants from the xml file 00081 }
Here is the call graph for this function:
PhysicalObj::~PhysicalObj | ( | ) | [virtual] |
void PhysicalObj::AddDamage | ( | uint | damage_points | ) |
Definition at line 225 of file physical_obj.cpp.
00226 { 00227 if(life_points == -1) 00228 return; 00229 life_points -= damage_points; 00230 if(life_points <= 0 && !IsGhost()) 00231 { 00232 Ghost(); 00233 life_points = -1; 00234 } 00235 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::CheckOverlapping | ( | ) | [protected, virtual] |
Definition at line 177 of file physical_obj.cpp.
00178 { 00179 if(m_overlapping_object == NULL) 00180 return; 00181 00182 // Check if we are still overlapping with this object 00183 if (!m_overlapping_object->GetTestRect().Intersect( GetTestRect() )) 00184 { 00185 MSG_DEBUG( "physic.overlapping", "\"%s\" just stopped overlapping with \"%s\"", GetName().c_str(), m_overlapping_object->GetName().c_str()); 00186 m_overlapping_object = NULL; 00187 } 00188 else 00189 { 00190 MSG_DEBUG( "physic.overlapping", "\"%s\" is overlapping with \"%s\"", GetName().c_str(), m_overlapping_object->GetName().c_str()); 00191 } 00192 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::CheckRebound | ( | ) | [private] |
Definition at line 571 of file physical_obj.cpp.
00572 { 00573 // If we bounce twice in a row at the same place, stop bouncing 00574 // cause it's almost sure this object is stuck bouncing indefinitely 00575 if( m_rebound_position != Point2i( -1, -1) ) 00576 { 00577 if ( m_rebound_position == GetPosition() ) 00578 { 00579 MSG_DEBUG("physic.state", "%s seems to be stuck in ground. Stop moving!", m_name.c_str()); 00580 StopMoving(); 00581 } 00582 } 00583 m_rebound_position = GetPosition(); 00584 }
Here is the call graph for this function:
Here is the caller graph for this function:
PhysicalObj * PhysicalObj::CollidedObject | ( | const Point2i & | offset | ) | const |
Definition at line 642 of file physical_obj.cpp.
00643 { 00644 return CollidedObjectXY(GetPosition() + offset); 00645 }
Here is the call graph for this function:
PhysicalObj * PhysicalObj::CollidedObjectXY | ( | const Point2i & | position | ) | const |
Definition at line 647 of file physical_obj.cpp.
00648 { 00649 if( IsOutsideWorldXY(position) ) 00650 return NULL; 00651 00652 Rectanglei rect(position.x + m_test_left, position.y + m_test_top, 00653 m_width - m_test_right - m_test_left, m_height - m_test_bottom - m_test_top); 00654 00655 if (m_collides_with_characters) 00656 { 00657 FOR_ALL_LIVING_CHARACTERS(team,character) 00658 { 00659 // We check both objet if one overlapse the other 00660 if (&(*character) != this && !IsOverlapping(&(*character)) && !character->IsOverlapping(this) 00661 && character->GetTestRect().Intersect( rect )) 00662 return (PhysicalObj*) &(*character); 00663 } 00664 } 00665 00666 if (m_collides_with_objects) 00667 { 00668 FOR_EACH_OBJECT(it) 00669 { 00670 PhysicalObj * object=*it; 00671 // We check both objet if one overlapse the other 00672 if (object != this && !IsOverlapping(object) && !object->IsOverlapping(this) 00673 && object->m_collides_with_objects 00674 && object->GetTestRect().Intersect(rect) ) 00675 return object; 00676 } 00677 } 00678 return NULL; 00679 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::ContactPoint | ( | int & | x, | |
int & | y | |||
) | [private] |
Definition at line 730 of file physical_obj.cpp.
00731 { 00732 int x1, x2, y1, y2; 00733 00734 // On cherche un point de contact en bas de l'objet: 00735 y1 = (GetY()+m_height-m_test_bottom); 00736 y2 = y1-1; 00737 for (uint x=GetX()+ m_test_left; x<=(GetX()+m_width)-m_test_right; x++) 00738 { 00739 if(!world.EstHorsMonde(Point2i(x,y1)) && !world.EstHorsMonde(Point2i(x,y2)) 00740 && world.ground.IsEmpty(Point2i(x,y2)) && !world.ground.IsEmpty(Point2i(x,y1))) 00741 { 00742 contact_x = x; 00743 contact_y = GetY() +m_height-m_test_bottom; 00744 return true; 00745 } 00746 } 00747 00748 // On cherche un point de contact �gauche de l'objet: 00749 x1 = GetX()+m_test_left; 00750 x2 = x1+1; 00751 for(uint y=GetY()+m_test_top;y<=GetY()+m_height-m_test_bottom;y++) 00752 { 00753 if(!world.EstHorsMonde(Point2i(x1,y)) && !world.EstHorsMonde(Point2i(x2,y)) 00754 && !world.ground.IsEmpty(Point2i(x1,y)) && world.ground.IsEmpty(Point2i(x2,y))) 00755 { 00756 contact_x = GetX() +m_test_left; 00757 contact_y = y; 00758 return true; 00759 } 00760 } 00761 00762 // On cherche un point de contact �droite de l'objet: 00763 x1 = (GetX()+m_width-m_test_right); 00764 x2 = x1-1; 00765 for(uint y=GetY()+m_test_top;y<=GetY()+m_height-m_test_bottom;y++) 00766 { 00767 if(!world.EstHorsMonde(Point2i(x1, y)) && !world.EstHorsMonde(Point2i(x2, y)) 00768 && !world.ground.IsEmpty(Point2i(x1, y)) && world.ground.IsEmpty(Point2i(x2, y))) 00769 { 00770 contact_x = GetX() + m_width - m_test_right; 00771 contact_y = y; 00772 return true; 00773 } 00774 } 00775 00776 // On cherche un point de contact en haut de l'objet: 00777 y1 = GetY()+m_test_top; 00778 y2 = y1 - 1; 00779 for(uint x=GetX()+m_test_left;x<=GetX()+m_width-m_test_right;x++) 00780 { 00781 if(!world.EstHorsMonde(Point2i(x,y1)) && !world.EstHorsMonde(Point2i(x,y2)) 00782 && !world.ground.IsEmpty(Point2i(x, y1)) && world.ground.IsEmpty(Point2i(x, y2))) 00783 { 00784 contact_x =x; 00785 contact_y = GetY() +m_test_top; 00786 return true; 00787 } 00788 } 00789 return false; 00790 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::DirectFall | ( | ) | [private] |
Definition at line 724 of file physical_obj.cpp.
00725 { 00726 while (!IsGhost() && !IsInWater() && FootsInVacuum()) 00727 SetY(GetY()+1); 00728 }
Here is the call graph for this function:
Here is the caller graph for this function:
virtual void PhysicalObj::Draw | ( | ) | [pure virtual] |
Implemented in Character, WindParticle, PetrolBarrel, BonusBox, ExplosionSmoke, FireParticle, IllBubble, Particle, Plane, WeaponProjectile, and ObjMine.
void PhysicalObj::Drown | ( | ) |
Definition at line 497 of file physical_obj.cpp.
00498 { 00499 assert (m_alive != DROWNED); 00500 MSG_DEBUG("physic.state", "%s - Drowned...", m_name.c_str()); 00501 m_alive = DROWNED; 00502 00503 // Set the air grab to water resist factor. 00504 SetAirResistFactor(WATER_RESIST_FACTOR * GetAirResistFactor()); 00505 StopMoving(); 00506 StartMoving(); 00507 SignalDrowning(); 00508 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::FootsInVacuum | ( | ) | const |
Definition at line 681 of file physical_obj.cpp.
00682 { 00683 return FootsInVacuumXY(GetPosition()); 00684 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::FootsInVacuumXY | ( | const Point2i & | position | ) | const |
Definition at line 686 of file physical_obj.cpp.
00687 { 00688 if( IsOutsideWorldXY(position) ){ 00689 MSG_DEBUG("physical", "%s - physobj is outside the world", m_name.c_str()); 00690 return Config::GetInstance()->GetExterieurMondeVide(); 00691 } 00692 00693 if( FootsOnFloor(position.y) ){ 00694 MSG_DEBUG("physical", "%s - physobj is on floor", m_name.c_str()); 00695 return false; 00696 } 00697 00698 int y_test = position.y + m_height - m_test_bottom; 00699 00700 Rectanglei rect( position.x + m_test_left, y_test, 00701 m_width - m_test_right - m_test_left, 1); 00702 00703 if( m_allow_negative_y && rect.GetPositionY() < 0){ 00704 int b = rect.GetPositionY() + rect.GetSizeY(); 00705 00706 rect.SetPositionY( 0 ); 00707 rect.SetSizeY( ( b > 0 ) ? b - rect.GetPositionY() : 0 ); 00708 } 00709 00710 if(CollidedObjectXY( position + Point2i(0, 1)) != NULL ) 00711 return false; 00712 00713 return world.RectEstDansVide (rect); 00714 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::FootsOnFloor | ( | int | y | ) | const |
Definition at line 606 of file physical_obj.cpp.
00607 { 00608 // If outside is empty, the object can't hit the ground ! 00609 if ( Config::GetInstance()->GetExterieurMondeVide() ) return false; 00610 00611 const int y_max = world.GetHeight()-m_height +m_test_bottom; 00612 return (y_max <= y); 00613 }
Here is the call graph for this function:
Here is the caller graph for this function:
const Point2i PhysicalObj::GetCenter | ( | ) | const |
Definition at line 142 of file physical_obj.cpp.
00143 { 00144 return Point2i(GetCenterX(), GetCenterY()); 00145 }
Here is the call graph for this function:
Here is the caller graph for this function:
int PhysicalObj::GetCenterX | ( | ) | const |
Definition at line 132 of file physical_obj.cpp.
00133 { 00134 return GetX() +m_test_left +GetTestWidth()/2; 00135 }
Here is the call graph for this function:
Here is the caller graph for this function:
int PhysicalObj::GetCenterY | ( | ) | const |
Definition at line 137 of file physical_obj.cpp.
00138 { 00139 return GetY() +m_test_top +GetTestHeight()/2; 00140 }
Here is the call graph for this function:
Here is the caller graph for this function:
int PhysicalObj::GetHeight | ( | ) | const |
virtual const std::string& PhysicalObj::GetName | ( | ) | const [inline, virtual] |
Reimplemented in Character.
Definition at line 104 of file physical_obj.h.
00104 { return m_name; }
Here is the caller graph for this function:
const Point2i PhysicalObj::GetPosition | ( | ) | const |
Definition at line 117 of file physical_obj.cpp.
Here is the call graph for this function:
Here is the caller graph for this function:
const Rectanglei PhysicalObj::GetRect | ( | ) | const |
Definition at line 212 of file physical_obj.cpp.
00213 { 00214 return Rectanglei( GetX(), GetY(), m_width, m_height); 00215 }
Here is the call graph for this function:
Here is the caller graph for this function:
Point2i PhysicalObj::GetSize | ( | ) | const |
int PhysicalObj::GetTestHeight | ( | ) | const |
Definition at line 207 of file physical_obj.cpp.
00208 { 00209 return m_height -m_test_top -m_test_bottom; 00210 }
Here is the caller graph for this function:
const Rectanglei PhysicalObj::GetTestRect | ( | ) | const |
Definition at line 217 of file physical_obj.cpp.
00218 { 00219 return Rectanglei(GetX()+m_test_left, 00220 GetY()+m_test_top, 00221 m_width-m_test_right-m_test_left, 00222 m_height-m_test_bottom-m_test_top); 00223 }
Here is the call graph for this function:
Here is the caller graph for this function:
int PhysicalObj::GetTestWidth | ( | ) | const |
Definition at line 202 of file physical_obj.cpp.
00203 { 00204 return m_width -m_test_left -m_test_right; 00205 }
Here is the caller graph for this function:
int PhysicalObj::GetWidth | ( | ) | const |
int PhysicalObj::GetX | ( | ) | const |
Definition at line 122 of file physical_obj.cpp.
00123 { 00124 return (int)round(GetPhysX() * PIXEL_PER_METER); 00125 }
Here is the call graph for this function:
Here is the caller graph for this function:
int PhysicalObj::GetY | ( | ) | const |
Definition at line 127 of file physical_obj.cpp.
00128 { 00129 return (int)round(GetPhysY() * PIXEL_PER_METER); 00130 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::Ghost | ( | ) |
Definition at line 482 of file physical_obj.cpp.
00483 { 00484 if (m_alive == GHOST) 00485 return; 00486 00487 bool was_dead = IsDead(); 00488 m_alive = GHOST; 00489 MSG_DEBUG("physic.state", "%s - Ghost, was_dead = %d", m_name.c_str(), was_dead); 00490 00491 // The object became a gost 00492 StopMoving(); 00493 00494 SignalGhostState(was_dead); 00495 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::GoesThroughWall | ( | ) | const [inline] |
Definition at line 109 of file physical_obj.h.
00109 { return m_goes_through_wall; }
Here is the caller graph for this function:
void PhysicalObj::GoOutOfWater | ( | ) |
Definition at line 510 of file physical_obj.cpp.
00511 { 00512 assert (m_alive == DROWNED); 00513 MSG_DEBUG("physic.state", "%s - Go out of water!...", m_name.c_str()); 00514 m_alive = ALIVE; 00515 00516 // Set the air grab to normal air resist factor. 00517 SetAirResistFactor(m_cfg.m_air_resist_factor); 00518 00519 StartMoving(); 00520 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::Init | ( | ) |
Definition at line 473 of file physical_obj.cpp.
00474 { 00475 if (m_alive != ALIVE) 00476 MSG_DEBUG( "physic.state", "%s - Init.", m_name.c_str()); 00477 m_alive = ALIVE; 00478 m_overlapping_object = NULL; 00479 StopMoving(); 00480 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::IsDead | ( | ) | const |
bool PhysicalObj::IsDrowned | ( | ) | const |
bool PhysicalObj::IsGhost | ( | ) | const |
bool PhysicalObj::IsImmobile | ( | ) | const [virtual] |
Reimplemented in WeaponProjectile, and ObjMine.
Definition at line 522 of file physical_obj.cpp.
00523 { 00524 return (!IsMoving() && !FootsInVacuum())||(m_alive == GHOST); 00525 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::IsInVacuum | ( | const Point2i & | offset, | |
bool | check_objects = true | |||
) | const |
Definition at line 620 of file physical_obj.cpp.
00621 { 00622 return IsInVacuumXY(GetPosition() + offset, check_object); 00623 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::IsInVacuumXY | ( | const Point2i & | position, | |
bool | check_objects = true | |||
) | const |
Definition at line 625 of file physical_obj.cpp.
00626 { 00627 if( IsOutsideWorldXY(position) ) 00628 return Config::GetInstance()->GetExterieurMondeVide(); 00629 00630 if( FootsOnFloor(position.y - 1) ) 00631 return false; 00632 00633 if( check_object && CollidedObjectXY(position) ) 00634 return false; 00635 00636 Rectanglei rect(position.x + m_test_left, position.y + m_test_top, 00637 m_width - m_test_right - m_test_left, m_height -m_test_bottom - m_test_top); 00638 00639 return world.RectEstDansVide (rect); 00640 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::IsInWater | ( | ) | const |
Definition at line 716 of file physical_obj.cpp.
00717 { 00718 assert (!IsGhost()); 00719 if (!world.water.IsActive()) return false; 00720 int x = BorneLong(GetCenterX(), 0, world.GetWidth()-1); 00721 return (int)world.water.GetHeight(x) < GetCenterY(); 00722 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::IsOutsideWorld | ( | const Point2i & | offset | ) | const |
Definition at line 601 of file physical_obj.cpp.
00602 { 00603 return IsOutsideWorldXY( GetPosition() + offset ); 00604 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::IsOutsideWorldXY | ( | Point2i | position | ) | const |
Definition at line 586 of file physical_obj.cpp.
00586 { 00587 int x = position.x + m_test_left; 00588 int y = position.y + m_test_top; 00589 00590 if( world.EstHorsMondeXlarg(x, GetTestWidth()) ) 00591 return true; 00592 if( world.EstHorsMondeYhaut(y, GetTestHeight()) ){ 00593 if( m_allow_negative_y ) 00594 if( (Y_OBJET_MIN <= y) && (y + GetTestHeight() - 1 < 0) ) 00595 return false; 00596 return true; 00597 } 00598 return false; 00599 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::IsOverlapping | ( | const PhysicalObj * | obj | ) | const [virtual] |
Reimplemented in ShotgunBuckshot.
Definition at line 615 of file physical_obj.cpp.
00616 { 00617 return m_overlapping_object == obj; 00618 }
Here is the caller graph for this function:
Implements Physics.
Definition at line 238 of file physical_obj.cpp.
00239 { 00240 if (IsGhost()) return; 00241 Point2d pos, offset; 00242 PhysicalObj* collided_obj = NULL; 00243 00244 typedef enum { 00245 NO_COLLISION = 0, 00246 COLLISION_ON_GROUND, 00247 COLLISION_ON_OBJECT 00248 } collision_t; 00249 collision_t collision = NO_COLLISION; 00250 00251 if(IsGhost()) 00252 return; 00253 00254 // Convert meters to pixels. 00255 oldPos *= PIXEL_PER_METER; 00256 newPos *= PIXEL_PER_METER; 00257 00258 // Compute distance between old and new position. 00259 double lg = oldPos.Distance( newPos); 00260 00261 if (lg == 0) 00262 return; 00263 00264 // Compute increments to move the object step by step from the old 00265 // to the new position. 00266 offset = (newPos - oldPos) / lg; 00267 00268 // First iteration position. 00269 pos = oldPos + offset; 00270 00271 if (m_goes_through_wall || IsInWater()) 00272 { 00273 Point2i tmpPos( lround(newPos.x), lround(newPos.y) ); 00274 SetXY(tmpPos); 00275 return; 00276 } 00277 00278 do 00279 { 00280 Point2i tmpPos( lround(pos.x), lround(pos.y) ); 00281 00282 // Check if we exit the world. If so, we stop moving and return. 00283 if( IsOutsideWorldXY(tmpPos) ){ 00284 00285 if( !Config::GetInstance()->GetExterieurMondeVide() ){ 00286 tmpPos.x = BorneLong(tmpPos.x, 0, world.GetWidth() - GetWidth() - 1); 00287 tmpPos.y = BorneLong(tmpPos.y, 0, world.GetHeight() - GetHeight() - 1); 00288 MSG_DEBUG( "physic.state", "%s - DeplaceTestCollision touche un bord : %d, %d", m_name.c_str(), tmpPos.x, tmpPos.y ); 00289 collision = COLLISION_ON_GROUND; 00290 break; 00291 } 00292 00293 SetXY( tmpPos ); 00294 return; 00295 } 00296 00297 // Test if we collide... 00298 collided_obj = CollidedObjectXY(tmpPos); 00299 if( collided_obj != NULL) 00300 MSG_DEBUG( "physic.state", "%s collide on %s", m_name.c_str(), collided_obj->GetName().c_str() ); 00301 00302 if( collided_obj != NULL) 00303 collision = COLLISION_ON_OBJECT; 00304 else 00305 if( ! IsInVacuumXY(tmpPos, false) ) 00306 collision = COLLISION_ON_GROUND; 00307 00308 if( collision != NO_COLLISION ) // Nothing more to do! 00309 { 00310 MSG_DEBUG( "physic.state", "%s - Collision at %d,%d : %s", m_name.c_str(), tmpPos.x, tmpPos.y, 00311 collision == COLLISION_ON_GROUND ? "on ground" : "on an object"); 00312 00313 // Set the object position to the current position. 00314 SetXY( Point2i( lround(pos.x - offset.x), lround(pos.y - offset.y)) ); 00315 break; 00316 } 00317 00318 // Next motion step 00319 pos += offset; 00320 lg -= 1.0 ; 00321 } while (0 < lg); 00322 00323 00324 // Only for ninja rope... TO REMOVE!! 00325 if (ActiveTeam().GetWeaponType() == Weapon::WEAPON_NINJA_ROPE && 00326 ActiveTeam().GetWeapon().IsActive()) { 00327 Weapon& tmp = ActiveTeam().AccessWeapon(); 00328 NinjaRope * ninjarope = (NinjaRope *)(&tmp); 00329 ninjarope->NotifyMove(collision) ; 00330 } 00331 00332 if ( collision == NO_COLLISION ) // Nothing more to do! 00333 return; 00334 if ( collision == COLLISION_ON_GROUND ) { 00335 // Find the contact point and collision angle. 00336 // // !!! ContactPoint(...) _can_ return false when CollisionTest(...) is true !!! 00337 // // !!! WeaponProjectiles collide on objects, so computing the tangeante to the ground leads 00338 // // !!! uninitialised values of cx and cy!! 00339 // if( ContactPoint(cx, cy) ){ 00340 int cx, cy; 00341 Point2d contactPos; 00342 double ground_angle; 00343 00344 if (ContactPoint(cx, cy)) { 00345 ground_angle = world.ground.Tangeante(cx, cy); 00346 contactPos.x = (double)cx / PIXEL_PER_METER; 00347 contactPos.y = (double)cy / PIXEL_PER_METER; 00348 } else { 00349 ground_angle = - GetSpeedAngle(); 00350 contactPos = pos; 00351 } 00352 00353 SignalGroundCollision(); 00354 SignalCollision(); 00355 // Make it rebound on the ground !! 00356 Rebound(contactPos, ground_angle); 00357 CheckRebound(); 00358 } else if ( collision == COLLISION_ON_OBJECT ) { 00359 SignalObjectCollision(collided_obj); 00360 collided_obj->SignalObjectCollision(this); 00361 00362 // Get the current speed 00363 double v1, v2, mass1, angle1, angle2, mass2; 00364 collided_obj->GetSpeed(v1, angle1); 00365 GetSpeed(v2, angle2); 00366 mass1 = GetMass(); 00367 mass2 = collided_obj->GetMass(); 00368 00369 // Give speed to the other object 00370 // thanks to physic and calculations about chocs, we know that : 00371 // 00372 // v'1 = ((m1 - m2) * v1 + 2m1 *v2) / (m1 + m2) 00373 // v'2 = ((m2 - m1) * v2 + 2m1 *v1) / (m1 + m2) 00374 SignalCollision(); 00375 00376 collided_obj->SetSpeed(((mass1 - mass2) * v1 + 2 * mass1 *v2 * m_cfg.m_rebound_factor) / (mass1 + mass2), 00377 angle1); 00378 SetSpeed(((mass2 - mass1) * v2 + 2 * mass1 *v1 * m_cfg.m_rebound_factor) / (mass1 + mass2), angle2); 00379 00380 // Rebound on the object 00381 double contact_angle = - GetSpeedAngle(); 00382 Point2d contactPos = pos; 00383 Rebound(contactPos, contact_angle); 00384 CheckRebound(); 00385 } 00386 return; 00387 }
Here is the call graph for this function:
bool PhysicalObj::ObjTouche | ( | const Point2i & | p | ) | const |
Definition at line 799 of file physical_obj.cpp.
00800 { 00801 return GetTestRect().Contains( p ); 00802 }
Here is the call graph for this function:
bool PhysicalObj::ObjTouche | ( | const PhysicalObj & | b | ) | const |
Definition at line 793 of file physical_obj.cpp.
00794 { 00795 return GetTestRect().Intersect( b.GetTestRect() ); 00796 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::PutOutOfGround | ( | double | direction | ) |
Definition at line 421 of file physical_obj.cpp.
00422 { 00423 if(IsOutsideWorld(Point2i(0, 0))) 00424 return false; 00425 00426 const int max_step = 30; 00427 00428 if( IsInVacuum(Point2i(0, 0), false) ) 00429 return true; 00430 00431 double dx = cos(direction); 00432 double dy = sin(direction); 00433 00434 int step=1; 00435 while(step<max_step && !IsInVacuum( 00436 Point2i((int)(dx * (double)step),(int)(dy * (double)step)), false )) 00437 step++; 00438 00439 if(step<max_step) 00440 SetXY( Point2i((int)(dx * (double)step)+GetX(),(int)(dy * (double)step)+GetY()) ); 00441 else 00442 return false; //Can't put the object out of the ground 00443 00444 return true; 00445 }
Here is the call graph for this function:
bool PhysicalObj::PutOutOfGround | ( | ) |
Definition at line 447 of file physical_obj.cpp.
00448 { 00449 if(IsOutsideWorld(Point2i(0, 0))) 00450 return false; 00451 00452 if( IsInVacuum(Point2i(0, 0)) ) 00453 return true; 00454 00455 bool left,right,top,bottom; 00456 left = world.IsInVacuum_left(*this, 0, 0); 00457 right = world.IsInVacuum_right(*this, 0, 0); 00458 top = world.EstDansVide_haut(*this, 0, 0); 00459 bottom = world.EstDansVide_bas(*this, 0, 0); 00460 00461 int dx = (int)GetTestRect().GetSizeX() * (right-left); 00462 int dy = (int)GetTestRect().GetSizeY() * (top-bottom); 00463 00464 if( dx == 0 && dy == 0 ) 00465 return false; //->Don't know in which direction we should go... 00466 00467 Point2i b(dx, dy); 00468 00469 double dir = b.ComputeAngle(); 00470 return PutOutOfGround(dir); 00471 }
Here is the call graph for this function:
Here is the caller graph for this function:
bool PhysicalObj::PutRandomly | ( | bool | on_top_of_world, | |
double | min_dst_with_characters | |||
) |
Definition at line 804 of file physical_obj.cpp.
00805 { 00806 uint bcl=0; 00807 uint NB_MAX_TRY = 60; 00808 bool ok; 00809 Point2i position; 00810 00811 MSG_DEBUG("physic.position", "%s - Search a position...", m_name.c_str()); 00812 00813 do 00814 { 00815 bcl++; 00816 ok = true; 00817 Init(); 00818 00819 if (bcl >= NB_MAX_TRY) { 00820 MSG_DEBUG("physic.position", "%s - Impossible to find an initial position !!", m_name.c_str()); 00821 return false; 00822 } 00823 00824 if (on_top_of_world) { 00825 // Placement au hasard en X 00826 position.x = randomSync.GetLong(0, world.GetWidth() - GetWidth()); 00827 position.y = -GetHeight()+1; 00828 } else { 00829 position = randomSync.GetPoint(world.GetSize() - GetSize() + 1); 00830 } 00831 SetXY(position); 00832 MSG_DEBUG("physic.position", "%s - Test in %d, %d", m_name.c_str(), position.x, position.y); 00833 00834 // Check physical object is not in the ground 00835 ok &= !IsGhost() && world.ParanoiacRectIsInVacuum(GetTestRect()) && IsInVacuum( Point2i(0, 1) ); 00836 if (!ok) { 00837 MSG_DEBUG("physic.position", "%s - Put it in the ground -> try again !", m_name.c_str()); 00838 continue; 00839 } 00840 00841 // Check object does not go in water or outside the map 00842 DirectFall(); 00843 ok &= !IsGhost() && !IsInWater() && (GetY() < static_cast<int>(world.GetHeight() - (WATER_INITIAL_HEIGHT + 30))); 00844 00845 if (!ok) { 00846 MSG_DEBUG("physic.position", "%s - Put in outside the map or in water -> try again", m_name.c_str()); 00847 continue; 00848 } 00849 00850 // Check distance with characters 00851 FOR_ALL_LIVING_CHARACTERS(equipe, ver) if (&(*ver) != this) 00852 { 00853 if (min_dst_with_characters == 0) { 00854 00855 if( ObjTouche(*ver) ) { 00856 MSG_DEBUG("physic.position", "%s - Object is too close from character %s", m_name.c_str(), (*ver).m_name.c_str()); 00857 ok = false; 00858 } 00859 } else { 00860 Point2i p1 = ver->GetCenter(); 00861 Point2i p2 = GetCenter(); 00862 double dst = p1.Distance( p2 ); 00863 00864 // ok this test is not perfect but quite efficient ;-) 00865 // else we need to check each distance between each "corner" 00866 if (dst < min_dst_with_characters) ok = false; 00867 } 00868 } 00869 00870 if (ok && on_top_of_world) SetXY(position); 00871 } while (!ok); 00872 00873 MSG_DEBUG("physic.position", "Putted after %d try", m_name.c_str(), bcl); 00874 00875 return true; 00876 }
Here is the call graph for this function:
Here is the caller graph for this function:
virtual void PhysicalObj::Refresh | ( | ) | [pure virtual] |
Implemented in Character, WindParticle, PetrolBarrel, BonusBox, BodyMemberParticle, BulletParticle, ExplosionSmoke, FireParticle, GroundParticle, MagicStarParticle, Particle, TeleportMemberParticle, Plane, Anvil, RPG, BazookaRocket, BounceBall, Cluster, ClusterBomb, DiscoGrenade, DynamiteStick, Gnu, Grenade, WeaponProjectile, WeaponBullet, ObjMine, Polecat, RiotBombRocket, and SuperTux.
void PhysicalObj::SetCollisionModel | ( | bool | goes_through_wall, | |
bool | collides_with_characters, | |||
bool | collides_with_objects | |||
) |
Definition at line 551 of file physical_obj.cpp.
00554 { 00555 m_goes_through_wall = goes_through_wall; 00556 m_collides_with_characters = collides_with_characters; 00557 m_collides_with_objects = collides_with_objects; 00558 00559 // Check boolean values 00560 { 00561 if (m_collides_with_characters || m_collides_with_objects) 00562 assert(m_goes_through_wall == false); 00563 00564 if (m_goes_through_wall) { 00565 assert(m_collides_with_characters == false); 00566 assert(m_collides_with_objects == false); 00567 } 00568 } 00569 }
Here is the caller graph for this function:
void PhysicalObj::SetOverlappingObject | ( | PhysicalObj * | obj | ) |
Definition at line 170 of file physical_obj.cpp.
00171 { 00172 m_overlapping_object = obj; 00173 MSG_DEBUG( "physic.overlapping", "\"%s\" doesn't check any collision with \"%s\" anymore", GetName().c_str(), obj->GetName().c_str()); 00174 CheckOverlapping(); 00175 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::SetSize | ( | const Point2i & | newSize | ) |
Definition at line 147 of file physical_obj.cpp.
00147 { 00148 if( newSize == Point2i(0, 0) ) 00149 Error( "New size of (0, 0) !"); 00150 m_width = newSize.x; 00151 m_height = newSize.y; 00152 SetPhysSize( (double)newSize.x / PIXEL_PER_METER, (double)newSize.y/PIXEL_PER_METER ); 00153 }
Here is the call graph for this function:
Here is the caller graph for this function:
Definition at line 194 of file physical_obj.cpp.
00195 { 00196 m_test_left = left; 00197 m_test_right = right; 00198 m_test_top = top; 00199 m_test_bottom = bottom; 00200 }
Here is the caller graph for this function:
void PhysicalObj::SetX | ( | int | x | ) |
Definition at line 90 of file physical_obj.cpp.
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::SetXY | ( | const Point2i & | position | ) |
Definition at line 98 of file physical_obj.cpp.
00099 { 00100 CheckOverlapping(); 00101 00102 if( IsOutsideWorldXY( position ) ) 00103 { 00104 Point2d physPos(position.x, position.y); 00105 SetPhysXY( physPos / PIXEL_PER_METER ); 00106 Ghost(); 00107 SignalOutOfMap(); 00108 } 00109 else 00110 { 00111 Point2d physPos(position.x, position.y); 00112 SetPhysXY( physPos / PIXEL_PER_METER ); 00113 if( FootsInVacuum() ) StartMoving(); 00114 } 00115 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::SetY | ( | int | y | ) |
Definition at line 94 of file physical_obj.cpp.
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::SignalCollision | ( | ) | [protected, virtual] |
Reimplemented in Character, BonusBox, and WeaponProjectile.
Definition at line 547 of file physical_obj.cpp.
Here is the caller graph for this function:
void PhysicalObj::SignalGroundCollision | ( | ) | [protected, virtual] |
Reimplemented in Anvil, WeaponProjectile, and WeaponBullet.
Definition at line 545 of file physical_obj.cpp.
Here is the caller graph for this function:
void PhysicalObj::SignalObjectCollision | ( | PhysicalObj * | obj | ) | [protected, virtual] |
Reimplemented in PolecatFart, Anvil, WeaponProjectile, and WeaponBullet.
Definition at line 543 of file physical_obj.cpp.
Here is the caller graph for this function:
void PhysicalObj::SignalOutOfMap | ( | ) | [protected, virtual] |
Reimplemented in FireParticle, RPG, BazookaRocket, BounceBall, Cluster, ClusterBomb, DiscoGrenade, DynamiteStick, Gnu, Grenade, WeaponProjectile, WeaponBullet, Polecat, RiotBombRocket, and SuperTux.
Definition at line 549 of file physical_obj.cpp.
Here is the caller graph for this function:
void PhysicalObj::SignalRebound | ( | ) | [protected, virtual] |
Reimplemented from Physics.
Reimplemented in BulletParticle.
Definition at line 536 of file physical_obj.cpp.
00537 { 00538 // TO CLEAN... 00539 if (!m_rebound_sound.empty()) 00540 jukebox.Play("share", m_rebound_sound) ; 00541 }
Here is the call graph for this function:
Here is the caller graph for this function:
void PhysicalObj::UpdatePosition | ( | ) |
Definition at line 389 of file physical_obj.cpp.
00390 { 00391 // No ghost allowed here ! 00392 if (IsGhost()) return; 00393 00394 if ( !m_goes_through_wall ) 00395 { 00396 // object is not moving and has no reason to move 00397 if ( !IsMoving() && !FootsInVacuum() && !IsInWater() ) return; 00398 00399 // object is not moving BUT it should fall ! 00400 if ( !IsMoving() && FootsInVacuum() ) StartMoving(); 00401 } 00402 00403 // Compute new position. 00404 RunPhysicalEngine(); 00405 00406 // Test if object is still inside the world 00407 if( IsOutsideWorldXY(GetPosition()) ) 00408 Ghost(); 00409 00410 if (IsGhost()) return; 00411 00412 // Classical object sometimes sinks in water and sometimes goes out of water! 00413 if ( !m_goes_through_wall ) 00414 { 00415 if ( IsInWater() && m_alive != DROWNED ) Drown(); 00416 else if ( !IsInWater() && m_alive == DROWNED ) GoOutOfWater(); 00417 } 00418 00419 }
Here is the call graph for this function:
Here is the caller graph for this function:
int PhysicalObj::life_points [protected] |
Definition at line 73 of file physical_obj.h.
alive_t PhysicalObj::m_alive [protected] |
Definition at line 72 of file physical_obj.h.
bool PhysicalObj::m_allow_negative_y [protected] |
Definition at line 75 of file physical_obj.h.
bool PhysicalObj::m_collides_with_characters [private] |
Definition at line 52 of file physical_obj.h.
bool PhysicalObj::m_collides_with_objects [private] |
Definition at line 53 of file physical_obj.h.
bool PhysicalObj::m_goes_through_wall [private] |
Definition at line 51 of file physical_obj.h.
uint PhysicalObj::m_height [protected] |
Definition at line 68 of file physical_obj.h.
std::string PhysicalObj::m_name [protected] |
Definition at line 62 of file physical_obj.h.
PhysicalObj* PhysicalObj::m_overlapping_object [protected] |
Definition at line 57 of file physical_obj.h.
Point2i PhysicalObj::m_rebound_position [private] |
Definition at line 55 of file physical_obj.h.
std::string PhysicalObj::m_rebound_sound [protected] |
Definition at line 70 of file physical_obj.h.
uint PhysicalObj::m_test_bottom [protected] |
Definition at line 65 of file physical_obj.h.
uint PhysicalObj::m_test_left [protected] |
Definition at line 65 of file physical_obj.h.
uint PhysicalObj::m_test_right [protected] |
Definition at line 65 of file physical_obj.h.
uint PhysicalObj::m_test_top [protected] |
Definition at line 65 of file physical_obj.h.
uint PhysicalObj::m_width [protected] |
Definition at line 68 of file physical_obj.h.