void PlayerBehaviourGround::resolve(const sf::Vector3f& manifold, CollisionWorld::Body* other) { switch (other->getType()) { case CollisionWorld::Body::Type::Water: setBehaviour<PlayerBehaviourWater>(); break; case CollisionWorld::Body::Type::Block: if (manifold.x != 0.f) //prevents shifting vertically { move(sf::Vector2f(manifold.x, manifold.y) * manifold.z); float yVel = std::min(0.f, getVelocity().y); setVelocity({ 0.f, yVel }); int cat = other->getParentCategory(); if ((cat & (Category::CarriedOne | Category::CarriedTwo)) == 0 //don't take damage from blocks being carried, && other->getSpeed() > 10.f) //or if they aren't moving { float damageAmount = std::fabs(manifold.z * (damageMultiplier / getFootSenseCount()));//always take same damage regardless of blocks touching damage(damageAmount, other); //std::cerr << damageAmount<< ": block damage " << std::endl; } else if ((cat & (Category::GrabbedOne | Category::GrabbedTwo)) == 0 && hasChild(CollisionWorld::Body::Block)) { //drop block Event e; e.type = Event::Player; e.player.action = Event::PlayerEvent::Released; e.player.playerId = getParentCategory(); auto pos = getBody()->getCentre(); e.player.positionX = pos.x; e.player.positionY = pos.y; raiseEvent(e); std::cerr << "release block in collision" << std::endl; } //std::cerr << manifold.z << std::endl; } break; case CollisionWorld::Body::Type::Solid: move(sf::Vector2f(manifold.x, manifold.y) * manifold.z); if (manifold.x == 0) { setVelocity({ getVelocity().x, 0.f }); //carry on moving if we hit ground } else if (manifold.y == 0) //don't die falling, just when crushed against wall { float damageAmount = std::fabs(manifold.z /** damageMultiplier*/); damage(damageAmount, other); setVelocity({}); if (hasChild(CollisionWorld::Body::Block)) { //drop block Event e; e.type = Event::Player; e.player.action = Event::PlayerEvent::Released; e.player.playerId = getParentCategory(); auto pos = getBody()->getCentre(); e.player.positionX = pos.x; e.player.positionY = pos.y; raiseEvent(e); std::cerr << "release block in collision" << std::endl; } } break; case CollisionWorld::Body::Type::Player: //move away if side collision if (manifold.x != 0) { move(sf::Vector2f(manifold.x, manifold.y) * manifold.z); setVelocity({}); } break; case CollisionWorld::Body::Type::Npc: //always die kill(); break; case CollisionWorld::Body::Item: { Event e; e.node.action = Event::NodeEvent::KilledNode; e.node.type = getParentCategory(); e.node.target = Category::Item; e.type = Event::Node; raiseEvent(e); } break; case CollisionWorld::Body::FreeForm: { if (other->getParentCategory() == Category::HatCarried) break; sf::Vector2f normal(manifold.x, manifold.y); move(normal * manifold.z); setVelocity(getVelocity() * 0.8f); } default: break; } }
btVector3 Leaf::getPosition() { btVector3 positionFall = getBody()->getCenterOfMassPosition(); return positionFall; }
void Leaf::setPosition(const btVector3& newPos){ position = newPos; getBody()->translate(btVector3(position)); }
void TalkToClient(ODSocket *socket_,char* clientIp){ for (;;) { MqHead head = getHead(socket_); if (head.type == 0) { return; } switch (head.type) { case Register::type: Register register_; if (getBody(socket_,register_) > 0){ ++p::playerMaxId; int result = p::account.DoUserRegister(register_,p::db,p::playerMaxId); if (result == kSucess) { UserRecord userRecord; userRecord.user_id = p::playerMaxId; userRecord.age = register_.age; memcpy(userRecord.nick.name,register_.nick.name,register_.nick.len); userRecord.odSocket = *socket_; memcpy(userRecord.ip,clientIp,strlen(clientIp)); memcpy(userRecord.address1,register_.address1,strlen(register_.address1)); if (register_.address1_len > 0) { userRecord.address1_len = register_.address1_len; memcpy(userRecord.address1,register_.address1,register_.address1_len); } if (register_.address2_len > 0) { userRecord.address2_len = register_.address2_len; memcpy(userRecord.address2,register_.address2,register_.address2_len); } if (register_.address3_len > 0) { userRecord.address3_len = register_.address3_len; memcpy(userRecord.address3,register_.address3,register_.address3_len); } p::g_user[userRecord.user_id] = userRecord; } head.type = RegisterResult::type; head.aid = p::playerMaxId; RegisterResult registerResult; registerResult.result = result; socket_->SendMsg(head,(char*)®isterResult,sizeof(registerResult)); break; } case Login::type: Login login_; if (getBody(socket_,login_)) { UserRecord userRecord; int result = p::account.DoUserLogin(login_,p::db,userRecord); if (result == kSucess) { userRecord.odSocket = *socket_; memcpy(userRecord.ip,clientIp,strlen(clientIp)); p::g_user[userRecord.user_id] = userRecord; } head.type = LoginResult::type; head.aid = userRecord.user_id; LoginResult loginResult; loginResult.result = result; socket_->SendMsg(head,(char*)&loginResult,sizeof(loginResult)); } break; case GetPlayerInfo::type: GetPlayerInfo info_; if (getBody(socket_,info_)){ PlayerInfoResult playerInfoResult; UserRecord userRecord; Login login_; login_.phone_len = info_.phone_len; memcpy(login_.phone,info_.phone,login_.phone_len); int result = p::account.DoUserLogin(login_,p::db,userRecord); if (result == kSucess) { userRecord.odSocket = *socket_; memcpy(userRecord.ip,clientIp,strlen(clientIp)); p::g_user[userRecord.user_id] = userRecord; } head.type = PlayerInfoResult::type; head.aid = userRecord.user_id; playerInfoResult.result = result; if (playerInfoResult.result == kSucess){ playerInfoResult.nick.len =userRecord.nick.len; memcpy(playerInfoResult.nick.name, userRecord.nick.name,userRecord.nick.len); playerInfoResult.address1_len = userRecord.address1_len; memcpy(playerInfoResult.address1, userRecord.address1,playerInfoResult.address1_len); playerInfoResult.address2_len = userRecord.address2_len; memcpy(playerInfoResult.address2, userRecord.address2,playerInfoResult.address2_len); playerInfoResult.address3_len = userRecord.address3_len; memcpy(playerInfoResult.address3, userRecord.address3,playerInfoResult.address3_len); } socket_->SendMsg(head,(char*)&playerInfoResult,sizeof(playerInfoResult)); } break; case LoginOut::type: LoginOut loginOut_; if (getBody(socket_,loginOut_)){ cleanPlayerInfo(socket_); } break; default: break; } std::this_thread::sleep_for(std::chrono::milliseconds(50)); } }
/** Virtual function called when the plunger hits something. * The plunger is special in that it is not deleted when hitting an object. * Instead it stays around (though not as a graphical or physical object) * till the rubber band expires. * \param kart Pointer to the kart hit (NULL if not a kart). * \param obj Pointer to PhysicalObject object if hit (NULL otherwise). * \returns True if there was actually a hit (i.e. not owner, and target is * not immune), false otherwise. */ bool Plunger::hit(AbstractKart *kart, PhysicalObject *obj) { if(isOwnerImmunity(kart)) return false; RaceGUIBase* gui = World::getWorld()->getRaceGUI(); irr::core::stringw hit_message; // pulling back makes no sense in battle mode, since this mode is not a race. // so in battle mode, always hide view if( m_reverse_mode || race_manager->isBattleMode() ) { if(kart) { kart->blockViewWithPlunger(); if (kart->getController()->isPlayerController()) sfx_manager->quickSound("plunger"); hit_message += StringUtils::insertValues(getHitString(kart), core::stringw(kart->getName()), core::stringw(m_owner->getName()) ).c_str(); gui->addMessage(translations->fribidize(hit_message), NULL, 3.0f, video::SColor(255, 255, 255, 255), false); } m_keep_alive = 0; // Make this object invisible. getNode()->setVisible(false); World::getWorld()->getPhysics()->removeBody(getBody()); } else { m_keep_alive = m_owner->getKartProperties()->getRubberBandDuration(); // Make this object invisible by placing it faaar down. Not that if this // objects is simply removed from the scene graph, it might be auto-deleted // because the ref count reaches zero. scene::ISceneNode *node = getNode(); if(node) { node->setVisible(false); } World::getWorld()->getPhysics()->removeBody(getBody()); if(kart) { m_rubber_band->hit(kart); return false; } else if(obj) { Vec3 pos(obj->getBody()->getWorldTransform().getOrigin()); m_rubber_band->hit(NULL, &pos); } else { m_rubber_band->hit(NULL, &(getXYZ())); } } // Rubber band attached. return false; } // hit
Vector Object::getVelocity() { return getBody()->GetVelocity(); }
int Object::getHeight(bool rotated) { return getBody()->GetHeight(rotated); }
bool Warrior::think(Game *game){ if(alertCooldown>0)alertCooldown--; if(attackCooldown>0)attackCooldown--; if(isDead() && this->getCurrentState()==DEATH_STATE && justStartedState()) return true; else if(isDead() && this->getCurrentState()!=DEATH_STATE){ this->setCurrentState((wstring)DEATH_STATE); body->SetActive(false); } else if (isDead()) return false; if(isDisturbed<=0){ b2Vec2 vel=getBody()->GetLinearVelocity(); //vel.Normalize(); vel*=-this->getVelocityDampener()*movementImpulse; getBody()->ApplyForceToCenter(vel); }else{ if(order.type!=ATTACKUNITORDER)untargetUnit(); if(isDisturbed>0)isDisturbed--; return false; } if(targetUnit!=NULL&&(targetUnit->isDead()||targetUnit->birthID!=birthIDTarget)){ untargetUnit(); if(order.type==ATTACKUNITORDER) order.type=STOPORDER; } if(targetUnit!=NULL&&state==attacking&& attackCooldown<=0){ if(justStartedState()){ this->onAttack(game,targetUnit,strengthBase*strengthFactor+strengthIncrease); state=standby; attackCooldown=attackSpeedBase*attackSpeedFactor; } } if(lastThink--<=0){ Physics* p =game->getGSM()->getPhysics(); b2World* w=p->getWorld(); if(order.type!=MOVEORDER) if(targetUnit==NULL){ targetArea.upperBound-=targetArea.lowerBound; targetArea.lowerBound.x=getBody()->GetPosition().x-targetArea.upperBound.x/2.0f; targetArea.lowerBound.y=getBody()->GetPosition().y-targetArea.upperBound.y/2.0f; targetArea.upperBound+=targetArea.lowerBound; w->QueryAABB((&callback),targetArea); if(targetUnit!=NULL)lastWaypointGeneration=0; } if(targetUnit!=NULL){ closeArea.upperBound-=closeArea.lowerBound; closeArea.lowerBound.x=getBody()->GetPosition().x-closeArea.upperBound.x/2.0f; closeArea.lowerBound.y=getBody()->GetPosition().y-closeArea.upperBound.y/2.0f; closeArea.upperBound+=closeArea.lowerBound; if(b2TestOverlap(targetUnit->getAABB(),closeArea)){ attackTargetedUnit(); b2Vec2 vel=getBody()->GetLinearVelocity(); vel*=.3f; getBody()->SetLinearVelocity(vel); } else{ state=standby; if(order.type!=ATTACKUNITORDER){ AABBCallback<CloseRange> range; CloseRange c; range.f=&c; range.self=this; w->QueryAABB((&range),closeArea); } } } lastThink=10; } if(!waypoints.empty()){ pair<float,float> coord=waypoints.back(); float dx =(coord.first-getWorldX()); float dy = (coord.second-getWorldY()); b2Vec2 displacement(dx,dy); if(displacement.Length()<2){ waypoints.pop_back(); } displacement.Normalize(); displacement*=this->getMovementImpulse(); body->ApplyForceToCenter(displacement); } if(lastWaypointGeneration--<=0){ handleOrders(game); } return false; }
value caml_getBody(value e) { CAMLparam1(e); CAMLreturn(alloc_Expr(getBody(Expr_val(e)))); }
void MonsterTortoise::checkPosSchedule() { Vec2 newPos = getPosition(); b2Body * body = getBody(); b2Vec2 oldVelocity = body->GetLinearVelocity(); if (newPos.x - m_lastPos.x >= -0.01f && newPos.x - m_lastPos.x <= 0.01f) { //转向处理 if (!m_bIsDefend || (m_bIsDefend && m_bIsRoll)) { changeVelocityDirection(); } } else { if (m_bLeft) { if (!m_bIsDefend) body->SetLinearVelocity(b2Vec2(-MMSpeed_Tortoise, oldVelocity.y)); //else if (oldVelocity.x < -0.00001f) // getBody()->SetLinearVelocity(b2Vec2(-MMSpeed_TortoiseDefense, oldVelocity.y)); } else { if (!m_bIsDefend) body->SetLinearVelocity(b2Vec2(MMSpeed_Tortoise, oldVelocity.y)); //else if (oldVelocity.x > 0.00001f) // getBody()->SetLinearVelocity(b2Vec2(MMSpeed_TortoiseDefense, oldVelocity.y)); } } ////防守非滚动状态x轴速度更改 //if (m_bIsDefend && !m_bIsRoll && (oldVelocity.x < -0.00001f || oldVelocity.x > 0.00001f)) //{ // body->SetAwake(false); // body->SetLinearVelocity(b2Vec2(0.0f, oldVelocity.y)); //} m_lastPos.set(newPos); //空中校验,是否踩着物体,光线投射 if (!m_bIsDefend) { m_bStepObject = false; float fPtm = getPTMRatio(); b2Vec2 beginPoint1(newPos.x / fPtm, newPos.y / fPtm); //投射起点 b2Vec2 endPoint1(beginPoint1.x, beginPoint1.y - getContentSize().height / fPtm); //投射终点 b2World * pWorld = GameScene::getInstance()->getWorld(); pWorld->RayCast(this, beginPoint1, endPoint1); if (!m_bStepObject) { //由于可能透过细小缝隙,故而执行二次投射 b2Vec2 beginPoint2(beginPoint1.x + (m_bLeft ? -1 : 1) * getContentSize().width / 4 / fPtm, beginPoint1.y); b2Vec2 endPoint2(beginPoint2.x, endPoint1.y); pWorld->RayCast(this, beginPoint2, endPoint2); } if (!m_bStepObject) { //再走将会掉下,掉头 changeVelocityDirection(); } } }
void MonsterTortoise::resetVelocityX() { b2Body * body = getBody(); body->SetLinearVelocity(b2Vec2(0.0f, body->GetLinearVelocity().y)); }
void MonsterTortoise::marioContact(MarioSprite * pMario) { if (pMario == nullptr) { CC_ASSERT(false); return; } if (getMonsterStatus() == MonsterStatus_Invalid) { return; } else if (m_bIsDefend) { //重置弹力系数 b2Fixture * fixture = getBody()->GetFixtureList(); b2Vec2 oldVelocity = getBody()->GetLinearVelocity(); enMarioStatus marioStatus = pMario->getMarioStatus(); if (m_bIsRoll) { if (marioStatus == MarioSt_LJump || marioStatus == MarioSt_LDown || marioStatus == MarioSt_RJump || marioStatus == MarioSt_RDown) { //马里奥空中状态,停止防守龟滚动 getBody()->SetLinearVelocity(b2Vec2(0.0f, oldVelocity.y)); stopAllActions(); m_bIsRoll = false; if (marioStatus == MarioSt_LDown || marioStatus == MarioSt_RDown) { //回弹马里奥 b2Vec2 marioVelocity = pMario->getBody()->GetLinearVelocity(); pMario->getBody()->SetLinearVelocity(b2Vec2(marioVelocity.x, -marioVelocity.y)); } } else { //马里奥地上状态,杀死马里奥 GameScene::getInstance()->reduceLife(); } } else { if ((pMario->getMarioStatus() & 0x1000) == 0) { //左向滚动 m_bLeft = true; getBody()->SetLinearVelocity(b2Vec2(-MMSpeed_TortoiseDefense, oldVelocity.y)); } else { //右向滚动 m_bLeft = false; getBody()->SetLinearVelocity(b2Vec2(MMSpeed_TortoiseDefense, oldVelocity.y)); } m_bIsRoll = true; stopAllActions(); Animation * animation = AnimationCache::getInstance()->getAnimation("tortoiseDefend"); runAction(Animate::create(animation)); if (marioStatus == MarioSt_LDown || marioStatus == MarioSt_RDown) { //回弹马里奥 b2Vec2 marioVelocity = pMario->getBody()->GetLinearVelocity(); pMario->getBody()->SetLinearVelocity(b2Vec2(marioVelocity.x, -marioVelocity.y)); } } } else { if (pMario->getMarioStatus() == MarioSt_LDown || pMario->getMarioStatus() == MarioSt_RDown || pMario->getMarioStatus() == MarioSt_LTumble || pMario->getMarioStatus() == MarioSt_RTumble) { const Size & monsterSize = getMonsterSize(); const Size & marioSize = pMario->getMarioSize(); Vec2 pos = getPosition(); Vec2 posM = pMario->getPosition(); bool bMarioTumble = (pMario->getMarioStatus() == MarioSt_LTumble || pMario->getMarioStatus() == MarioSt_RTumble); if ((pos.y <= posM.y) && (pos.x - posM.x > -monsterSize.width / 2 - marioSize.width / 2) && (pos.x - posM.x < monsterSize.width / 2 + marioSize.width / 2)) { //乌龟变为防守状态 if (!bMarioTumble) { stopAllActions(); getBody()->SetLinearVelocity(b2Vec2(0.0f, 0.0f)); m_bIsDefend = true; m_bIsRoll = false; SpriteFrame * frame = SpriteFrameCache::getInstance()->getSpriteFrameByName( "monster/tortoise_defend/tortoise_defend1.png"); setSpriteFrame(frame); updateFixStatus = UpdateTortoise_Defend; playEffect(Effect_KillMonster); //回弹马里奥 b2Vec2 marioVelocity = pMario->getBody()->GetLinearVelocity(); pMario->getBody()->SetLinearVelocity(b2Vec2(marioVelocity.x, -marioVelocity.y)); } else { if (posM.x >= pos.x) { //左向滚动 m_bLeft = true; getBody()->SetLinearVelocity(b2Vec2(-MMSpeed_TortoiseDefense, 0.0f)); } else { //右向滚动 m_bLeft = false; getBody()->SetLinearVelocity(b2Vec2(MMSpeed_TortoiseDefense, 0.0f)); } m_bIsDefend = true; m_bIsRoll = true; m_lastPos.set(getPosition()); updateFixStatus = UpdateTortoise_Defend; stopAllActions(); Animation * animation = AnimationCache::getInstance()->getAnimation("tortoiseDefend"); runAction(Animate::create(animation)); } } else { GameScene::getInstance()->reduceLife(); } } else { GameScene::getInstance()->reduceLife(); } } }
void PhysicsGeom::changed(ConstFieldMaskArg whichField, UInt32 origin, BitVector details) { Inherited::changed(whichField, origin, details); //Do not respond to changes that have a Sync origin if(origin & ChangedOrigin::Sync) { return; } if(whichField & BodyFieldMask) { if(getBody() != NULL) { dGeomSetBody(_GeomID, getBody()->getBodyID()); } else { dGeomSetBody(_GeomID, 0); } } if(whichField & PositionFieldMask) { dGeomSetPosition(_GeomID, getPosition().x(),getPosition().y(),getPosition().z()); } if(whichField & RotationFieldMask) { dMatrix3 rotation; Vec4f v1 = getRotation()[0]; Vec4f v2 = getRotation()[1]; Vec4f v3 = getRotation()[2]; rotation[0] = v1.x(); rotation[1] = v1.y(); rotation[2] = v1.z(); rotation[3] = 0; rotation[4] = v2.x(); rotation[5] = v2.y(); rotation[6] = v2.z(); rotation[7] = 0; rotation[8] = v3.x(); rotation[9] = v3.y(); rotation[10] = v3.z(); rotation[11] = 0; dGeomSetRotation(_GeomID, rotation); } if(whichField & QuaternionFieldMask) { dQuaternion q; q[0]=getQuaternion().w(); q[1]=getQuaternion().x(); q[2]=getQuaternion().y(); q[3]=getQuaternion().z(); dGeomSetQuaternion(_GeomID,q); } if(whichField & OffsetPositionFieldMask && getBody() != NULL) { dGeomSetOffsetPosition(_GeomID, getOffsetPosition().x(),getOffsetPosition().y(),getOffsetPosition().z()); } if(whichField & OffsetRotationFieldMask && getBody() != NULL) { dMatrix3 rotation; Vec4f v1 = getOffsetRotation()[0]; Vec4f v2 = getOffsetRotation()[1]; Vec4f v3 = getOffsetRotation()[2]; rotation[0] = v1.x(); rotation[1] = v1.y(); rotation[2] = v1.z(); rotation[3] = 0; rotation[4] = v2.x(); rotation[5] = v2.y(); rotation[6] = v2.z(); rotation[7] = 0; rotation[8] = v3.x(); rotation[9] = v3.y(); rotation[10] = v3.z(); rotation[11] = 0; dGeomSetOffsetRotation(_GeomID, rotation); } if(whichField & OffsetQuaternionFieldMask && getBody() != NULL) { dQuaternion q; q[0]=getOffsetQuaternion().w(); q[1]=getOffsetQuaternion().x(); q[2]=getOffsetQuaternion().y(); q[3]=getOffsetQuaternion().z(); dGeomSetOffsetQuaternion(_GeomID,q); } if(whichField & CategoryBitsFieldMask) { dGeomSetCategoryBits(_GeomID, getCategoryBits()); } if(whichField & CollideBitsFieldMask) { dGeomSetCollideBits(_GeomID, getCollideBits()); } if(whichField & SpaceFieldMask) { dSpaceID CurSpace(dGeomGetSpace(_GeomID)); if(CurSpace != 0 && (getSpace() == NULL || CurSpace != getSpace()->getSpaceID())) { dSpaceRemove(CurSpace,_GeomID); } if(getSpace() != NULL) { dSpaceAdd(getSpace()->getSpaceID(), _GeomID); } } if(whichField & EnableFieldMask) { if(getEnable()) { dGeomEnable(_GeomID); } else { dGeomDisable(_GeomID); } } }
void ParseFile_Recurse(FILE* fd, Settings& settings,int& lineCount){ std::string key,value; char lastCharParsed; do{ lastCharParsed = getKey(fd,key); removeTrailingSpaces(key); if(lastCharParsed == '=' && key.size()>0){ lastCharParsed = getBody(fd,value); removeTrailingSpaces(value); settings.values[key] = value; //Now lets add a new nested tree of if statements //sorry future me about this mess if(lastCharParsed=='#'){ readRestOfLine(fd); lineCount++; }else if(lastCharParsed=='}'){ return; //unwind the stack to be done with this group }else if(lastCharParsed=='\n'){ //nothing special lineCount++; }else if(lastCharParsed=='{'){ printf("ERROR: CONFIG:%d: Opening new group ( { ) while specifing value\n",lineCount); }else if(lastCharParsed=='='){ printf("ERROR: CONFIG:%d: Value specifing ( = ) while specifing value\n",lineCount); }else if( !feof(fd) ){ printf("ERROR: CONFIG:%d: Reached EOF Unexpectedly (value parsing)\n",lineCount); } }else if(lastCharParsed == '{' && key.size()>0){ //found a named group, so recurse down to get everything inside of it ParseFile_Recurse(fd,settings.groups[key],lineCount); }else if(lastCharParsed == '}' && key.size()==0){ //found that we are closing the group we are currently in return; // unwind the stack }else if(lastCharParsed == '\n' && key.size()==0){ //just ignore blank lines lineCount++; }else if(lastCharParsed == '#' && key.size()==0){ //ignore lines that only have comments readRestOfLine(fd); lineCount++; } // end of good states, following are bad states else if( lastCharParsed=='#' && key.size()>0 ){ readRestOfLine(fd); lineCount++; printf("ERROR: CONFIG:%d: found a comment token ( # ) while parsing label\n",lineCount); }else if( lastCharParsed=='=' && key.size()==0 ){ readRestOfLine(fd); lineCount++; printf("ERROR: CONFIG:%d: found a ( = ) token with an empty label\n",lineCount); }else if( lastCharParsed=='}' && key.size()>0 ){ printf("ERROR: CONFIG:%d: found a ( } ) token with a non-empty label\n",lineCount); }else if( lastCharParsed=='\n' && key.size()>0 ){ printf("ERROR: CONFIG:%d: reached end of line with a non-empty label\n",lineCount); lineCount++; }else if( lastCharParsed=='{' && key.size()>0 ){ printf("ERROR: CONFIG:%d: found a ( { ) token with an empty label\n",lineCount); }else if( feof(fd) ){ if(key.size()>0) printf("ERROR: CONFIG:%d: Reached EOF Unexpectedly (key parsing)\n",lineCount); //else no-one cares as we are not losing any information } }while(!feof(fd)); }
void Object::rotate(float rotate) { getBody()->Rotate(rotate); }
/** Creates a bullet physics body for the flyable item. * \param forw_offset How far ahead of the kart the flyable should be * positioned. Necessary to avoid exploding a rocket inside of the * firing kart. * \param velocity Initial velocity of the flyable. * \param shape Collision shape of the flyable. * \param gravity Gravity to use for this flyable. * \param rotates True if the item should rotate, otherwise the angular factor * is set to 0 preventing rotations from happening. * \param turn_around True if the item is fired backwards. * \param custom_direction If defined the initial heading for this item, * otherwise the kart's heading will be used. */ void Flyable::createPhysics(float forw_offset, const Vec3 &velocity, btCollisionShape *shape, float restitution, const btVector3& gravity, const bool rotates, const bool turn_around, const btTransform* custom_direction) { // Get Kart heading direction btTransform trans = ( !custom_direction ? m_owner->getAlignedTransform() : *custom_direction ); // Apply offset btTransform offset_transform; offset_transform.setIdentity(); assert(!std::isnan(m_average_height)); assert(!std::isnan(forw_offset)); offset_transform.setOrigin(Vec3(0,m_average_height,forw_offset)); // turn around if(turn_around) { btTransform turn_around_trans; //turn_around_trans.setOrigin(trans.getOrigin()); turn_around_trans.setIdentity(); turn_around_trans.setRotation(btQuaternion(btVector3(0, 1, 0), M_PI)); trans *= turn_around_trans; } trans *= offset_transform; m_shape = shape; createBody(m_mass, trans, m_shape, restitution); m_user_pointer.set(this); Physics::getInstance()->addBody(getBody()); m_body->setGravity(gravity); // Rotate velocity to point in the right direction btVector3 v=trans.getBasis()*velocity; if(m_mass!=0.0f) // Don't set velocity for kinematic or static objects { #ifdef DEBUG // Just to get some additional information if the assert is triggered if(std::isnan(v.getX()) || std::isnan(v.getY()) || std::isnan(v.getZ())) { Log::debug("[Flyable]", "vel %f %f %f v %f %f %f", velocity.getX(),velocity.getY(),velocity.getZ(), v.getX(),v.getY(),v.getZ()); } #endif assert(!std::isnan(v.getX())); assert(!std::isnan(v.getY())); assert(!std::isnan(v.getZ())); m_body->setLinearVelocity(v); if(!rotates) m_body->setAngularFactor(0.0f); // prevent rotations } m_body->setCollisionFlags(m_body->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE); m_saved_transform = getTrans(); m_saved_lv = m_body->getLinearVelocity(); m_saved_av = m_body->getAngularVelocity(); m_saved_gravity = gravity; } // createPhysics
void Object::setRotationAxis(Vector axis) { getBody()->GetShape()->setRotationAxis(axis); }
//----------------------------------------------------------------------------- Flyable::~Flyable() { if(m_shape) delete m_shape; Physics::getInstance()->removeBody(getBody()); } // ~Flyable
int Object::getWidth(bool rotated) { return getBody()->GetWidth(rotated); }
/** Updates this flyable. It calls Moveable::update. If this function returns * true, the flyable will be deleted by the projectile manager. * \param dt Time step size. * \returns True if this object can be deleted. */ bool Flyable::updateAndDelete(int ticks) { if (m_undo_creation) return false; if (hasAnimation()) { if (!RewindManager::get()->isRewinding()) { m_animation->update(ticks); Moveable::update(ticks); } return false; } // if animation m_ticks_since_thrown += ticks; if(m_max_lifespan > -1 && m_ticks_since_thrown > m_max_lifespan) hit(NULL); if(m_has_hit_something) return true; //Vec3 xyz=getBody()->getWorldTransform().getOrigin(); const Vec3 &xyz=getXYZ(); // Check if the flyable is outside of the track. If so, explode it. const Vec3 *min, *max; Track::getCurrentTrack()->getAABB(&min, &max); // I have seen that the bullet AABB can be slightly different from the // one computed here - I assume due to minor floating point errors // (e.g. 308.25842 instead of 308.25845). To avoid a crash with a bullet // assertion (see bug 3058932) I add an epsilon here - but admittedly // that does not really explain the bullet crash, since bullet tests // against its own AABB, and should therefore not cause the assertion. // But since we couldn't reproduce the problem, and the epsilon used // here does not hurt, I'll leave it in. float eps = 0.1f; assert(!std::isnan(xyz.getX())); assert(!std::isnan(xyz.getY())); assert(!std::isnan(xyz.getZ())); if(xyz[0]<(*min)[0]+eps || xyz[2]<(*min)[2]+eps || xyz[1]<(*min)[1]+eps || xyz[0]>(*max)[0]-eps || xyz[2]>(*max)[2]-eps || xyz[1]>(*max)[1]-eps ) { hit(NULL); // flyable out of track boundary return true; } if (m_do_terrain_info) { Vec3 towards = getBody()->getGravity(); towards.normalize(); // Add the position offset so that the flyable can adjust its position // (usually to do the raycast from a slightly higher position to avoid // problems finding the terrain in steep uphill sections). // Towards is a unit vector. so we can multiply -towards to offset the // position by one unit. TerrainInfo::update(xyz + m_position_offset*(-towards), towards); // Make flyable anti-gravity when the it's projected on such surface const Material* m = TerrainInfo::getMaterial(); if (m && m->hasGravity()) { getBody()->setGravity(TerrainInfo::getNormal() * -70.0f); } else { getBody()->setGravity(Vec3(0, 1, 0) * -70.0f); } } if(m_adjust_up_velocity) { float hat = (xyz - getHitPoint()).length(); // Use the Height Above Terrain to set the Z velocity. // HAT is clamped by min/max height. This might be somewhat // unphysical, but feels right in the game. float delta = m_average_height - std::max(std::min(hat, m_max_height), m_min_height); Vec3 v = getVelocity(); assert(!std::isnan(v.getX())); assert(!std::isnan(v.getX())); assert(!std::isnan(v.getX())); float heading = atan2f(v.getX(), v.getZ()); assert(!std::isnan(heading)); float pitch = getTerrainPitch(heading); float vel_up = m_force_updown*(delta); if (hat < m_max_height) // take into account pitch of surface vel_up += v.length_2d()*tanf(pitch); assert(!std::isnan(vel_up)); v.setY(vel_up); setVelocity(v); } // if m_adjust_up_velocity Moveable::update(ticks); return false; } // updateAndDelete
float Object::getRotation() { return getBody()->GetRotation(); }
void iPhysics::destroyBody(uint64 bodyID) { destroyBody(getBody(bodyID)); }