bool Trace::EraseEarlierThan(const unsigned p_time) { if (p_time == 0 || empty() || GetFront().point.GetTime() >= p_time) // there will be nothing to remove return false; do { TraceDelta &td = GetFront(); td.Remove(); auto i = delta_list.find(td); assert(i != delta_list.end()); delta_list.erase(i); --cached_size; } while (!empty() && GetFront().point.GetTime() < p_time); // need to set deltas for first point, only one of these // will occur (have to search for this point) if (!empty()) EraseStart(GetFront()); ++modify_serial; return true; }
std::tuple<unsigned short, unsigned short, unsigned short> LongestCommonSubwordCyclic(CWord u, CWord v) { unsigned short max_common_prefix = 0; unsigned short u_max_begin = u.size(); unsigned short v_max_begin = v.size(); for (unsigned short current_u_begin = 0; current_u_begin < u.size(); ++current_u_begin) { for (unsigned short current_v_begin = 0; current_v_begin < v.size(); ++current_v_begin) { auto u_copy = u; auto v_copy = v; unsigned short current_common_prefix_length = 0; while (u_copy.GetFront() == v_copy.GetFront()) { ++current_common_prefix_length; u_copy.PopFront(); if (u_copy.Empty()) { break; } v_copy.PopFront(); if (v_copy.Empty()) { break; } } if (current_common_prefix_length > max_common_prefix) { u_max_begin = current_u_begin; v_max_begin = current_v_begin; max_common_prefix = current_common_prefix_length; } v.CyclicLeftShift(); } u.CyclicLeftShift(); } return std::make_tuple(u_max_begin, v_max_begin, max_common_prefix); }
static void* pthreadWriteSerial (void* arg) { PQueueNode pnode = {0}; while (1) { pnode = GetFront(g_WriteQueue); if (pnode) { if (g_hSerialDevFd > 0) { TRACE("write serial####%d\n", pnode->nlen); if (g_PrintSirial) { PrintDataBy16((unsigned char *)pnode->data, pnode->nlen); } write(g_hSerialDevFd, pnode->data, pnode->nlen); //ar9331 /dev/ttyATH0不能使用该函数,否则数据发送不完整 //tcflush(g_hSerialDevFd, TCOFLUSH); /*出队列,入队列,不能同时执行*/ pthread_mutex_lock(&g_hRdWrMutex); DeQueue(g_WriteQueue); pthread_mutex_unlock(&g_hRdWrMutex); TRACE("DeQueue !!!:%d\n", GetSize(g_WriteQueue)); } } /*30ms内不允许再次write,cc2530处理能力有限*/ usleep(50000); } return NULL; }
void Player::Turn(float longitude, float latitude){ SPADES_MARK_FUNCTION(); Vector3 o = GetFront(); float lng = atan2f(o.y, o.x); float lat = atan2f(o.z, sqrtf(o.x*o.x+o.y*o.y)); lng += longitude; lat += latitude; if(lat < -static_cast<float>(M_PI) * .49f) lat = -static_cast<float>(M_PI) * .49f; if(lat > static_cast<float>(M_PI) * .49f) lat = static_cast<float>(M_PI) * .49f; o.x = cosf(lng) * cosf(lat); o.y = sinf(lng) * cosf(lat); o.z = sinf(lat); SetOrientation(o); }
const Vect3f CSteeringEntity::GetInitialPositionToThrowRay( void ) const { Vect3f l_Pos; Vect3f l_Front; //float l_Radi = CORE->GetSteeringBehaviourSettingsManager()->GetCollisionDetectionFeelerLength(); float l_Radi = m_BoundingRadius; l_Pos = m_Position; l_Front = GetFront(); l_Front.Normalize(); /*l_Pos.x = l_Pos.x + l_Front.x * l_Radi; l_Pos.z = l_Pos.z + l_Front.z * l_Radi; l_Pos.y += m_Height;*/ l_Pos = Vect3f ( l_Pos.x + l_Front.x * l_Radi , l_Pos.y + m_Height, l_Pos.z + l_Front.z * l_Radi ); /*v = Vect3f ( (*l_It)->GetPosition().x + (*l_It)->GetFront().x, (*l_It)->GetPosition().y + (*l_It)->GetProperties()->GetHeightController(), (*l_It)->GetPosition().z + (*l_It)->GetFront().z); l_RM->DrawLine( Vect3f ( (*l_It)->GetPosition().x, (*l_It)->GetPosition().y + (*l_It)->GetProperties()->GetHeightController() , (*l_It)->GetPosition().z ), v );*/ return l_Pos; }
// パワーアーツ bool Thief::PowerArts(void) { if ( !initflag ) { artsTimer = 0; sound->PlaySE( SE::KAITO_POWER ); initflag = true; } SetMotion(THIEF::MOTION_DATA::POWERARTS); //if (obj->GetFrame() >= 277) obj->SetFrame(277); // 行列から情報取得 Vector3 front = GetFront(); Vector3 p_pos = GetPos(); SetMove(Vector3(0.0f, move.y, 0.0f)); // 情報設定 p_pos.y += 1.0f; Vector3 vec = front * 1.0f; float bulletSpeed = 0.8f; int playerNum = GetPlayerNum(); if (artsTimer == 0/* obj->GetFrame() == ○○ */) { m_BulletManager->Set(BULLET_TYPE::THIEF_02, new ThiefBullet02, p_pos, vec, bulletSpeed, playerNum); } artsTimer++; if (obj->GetFrame() == THIEF::MOTION_FRAME::POWERARTS_END) { artsTimer = 0; initflag = false; return true; } return false; }
void Player::FireWeapon() { SPADES_MARK_FUNCTION(); Vector3 muzzle = GetEye(); muzzle += GetFront() * 0.01f; // for hit-test debugging std::map<int, HitTestDebugger::PlayerHit> playerHits; std::vector<Vector3> bulletVectors; //Vector3 right = GetRight(); //Vector3 up = GetUp(); int pellets = weapon->GetPelletSize(); float spread = weapon->GetSpread(); GameMap *map = world->GetMap(); // pyspades takes destroying more than one block as a // speed hack (shotgun does this) bool blockDestroyed = false; Vector3 dir2 = GetFront(); for(int i =0 ; i < pellets; i++){ // AoS 0.75's way (dir2 shouldn't be normalized!) dir2.x += (GetRandom() - GetRandom()) * spread; dir2.y += (GetRandom() - GetRandom()) * spread; dir2.z += (GetRandom() - GetRandom()) * spread; Vector3 dir = dir2.Normalize(); bulletVectors.push_back(dir); // first do map raycast GameMap::RayCastResult mapResult; mapResult = map->CastRay2(muzzle, dir, 500); Player *hitPlayer = NULL; float hitPlayerDistance = 0.f; HitBodyPart hitPart = HitBodyPart::None; for(int i = 0; i < world->GetNumPlayerSlots(); i++){ Player *other = world->GetPlayer(i); if(other == this || other == NULL) continue; if(other == this || !other->IsAlive() || other->GetTeamId() >= 2) continue; // quickly reject players unlikely to be hit if(!other->RayCastApprox(muzzle, dir)) continue; HitBoxes hb = other->GetHitBoxes(); Vector3 hitPos; if(hb.head.RayCast(muzzle, dir, &hitPos)) { float dist = (hitPos - muzzle).GetLength(); if(hitPlayer == NULL || dist < hitPlayerDistance){ hitPlayer = other; hitPlayerDistance = dist; hitPart = HitBodyPart::Head; } } if(hb.torso.RayCast(muzzle, dir, &hitPos)) { float dist = (hitPos - muzzle).GetLength(); if(hitPlayer == NULL || dist < hitPlayerDistance){ hitPlayer = other; hitPlayerDistance = dist; hitPart = HitBodyPart::Torso; } } for(int j = 0; j < 3 ;j++){ if(hb.limbs[j].RayCast(muzzle, dir, &hitPos)) { float dist = (hitPos - muzzle).GetLength(); if(hitPlayer == NULL || dist < hitPlayerDistance){ hitPlayer = other; hitPlayerDistance = dist; switch(j) { case 0: hitPart = HitBodyPart::Limb1; break; case 1: hitPart = HitBodyPart::Limb2; break; case 2: hitPart = HitBodyPart::Arms; break; } } } } } Vector3 finalHitPos; finalHitPos = muzzle + dir * 128.f; if(hitPlayer == nullptr && !mapResult.hit) { // might hit water surface. } if(mapResult.hit && (mapResult.hitPos - muzzle).GetLength() < 128.f && (hitPlayer == NULL || (mapResult.hitPos - muzzle).GetLength() < hitPlayerDistance)){ IntVector3 outBlockCoord = mapResult.hitBlock; // TODO: set correct ray distance // FIXME: why ray casting twice? finalHitPos = mapResult.hitPos; if(outBlockCoord.x >= 0 && outBlockCoord.y >= 0 && outBlockCoord.z >= 0 && outBlockCoord.x < map->Width() && outBlockCoord.y < map->Height() && outBlockCoord.z < map->Depth()){ if(outBlockCoord.z == 63) { if(world->GetListener()) world->GetListener()->BulletHitBlock(mapResult.hitPos, mapResult.hitBlock, mapResult.normal); }else if(outBlockCoord.z == 62) { // blocks at this level cannot be damaged if(world->GetListener()) world->GetListener()->BulletHitBlock(mapResult.hitPos, mapResult.hitBlock, mapResult.normal); }else{ int x = outBlockCoord.x; int y = outBlockCoord.y; int z = outBlockCoord.z; SPAssert(map->IsSolid(x, y, z)); Vector3 blockF = {x + .5f, y + .5f, z + .5f}; float distance = (blockF - muzzle).GetLength(); uint32_t color = map->GetColor(x, y, z); int health = color >> 24; health -= weapon->GetDamage(HitTypeBlock, distance); if(health <= 0 && !blockDestroyed){ health = 0; blockDestroyed = true; //send destroy cmd if(world->GetListener() && world->GetLocalPlayer() == this) world->GetListener()->LocalPlayerBlockAction (outBlockCoord, BlockActionTool); } color = (color & 0xffffff) | ((uint32_t)health << 24); if(map->IsSolid(x, y, z)) map->Set(x, y, z, true, color); if(world->GetListener()) world->GetListener()->BulletHitBlock(mapResult.hitPos, mapResult.hitBlock, mapResult.normal); } } }else if(hitPlayer != NULL){
void Player::Update(float dt) { SPADES_MARK_FUNCTION(); auto* listener = world->GetListener(); MovePlayer(dt); if(!IsAlive()) { // do death cleanup blockCursorDragging = false; } if(tool == ToolSpade){ if(weapInput.primary){ if(world->GetTime() > nextSpadeTime){ UseSpade(); nextSpadeTime = world->GetTime() + GetToolPrimaryDelay(); } }else if(weapInput.secondary){ if(world->GetTime() > nextDigTime){ DigWithSpade(); nextDigTime = world->GetTime() + GetToolSecondaryDelay(); firstDig = false; } } }else if(tool == ToolBlock && IsLocalPlayer()){ GameMap::RayCastResult result; auto *map = GetWorld()->GetMap(); result = map->CastRay2(GetEye(), GetFront(), 12); canPending = false; if(blockCursorDragging) { // check the starting point is not floating auto start = blockCursorDragPos; if(map->IsSolidWrapped(start.x-1, start.y, start.z) || map->IsSolidWrapped(start.x, start.y-1, start.z) || map->IsSolidWrapped(start.x, start.y, start.z-1) || map->IsSolidWrapped(start.x+1, start.y, start.z) || map->IsSolidWrapped(start.x, start.y+1, start.z) || map->IsSolidWrapped(start.x, start.y, start.z+1)) { // still okay }else{ // cannot build; floating if(listener && this == world->GetLocalPlayer()) { listener-> LocalPlayerBuildError(BuildFailureReason::InvalidPosition); } blockCursorDragging = false; } } if(result.hit && (result.hitBlock + result.normal).z < 62 && (!OverlapsWithOneBlock(result.hitBlock + result.normal)) && BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f && !pendingPlaceBlock){ // Building is possible, and there's no delayed block placement. blockCursorActive = true; blockCursorPos = result.hitBlock + result.normal; }else if(pendingPlaceBlock){ // Delayed Block Placement: When player attempts to place a block while jumping and // placing block is currently impossible, building will be delayed until it becomes // possible, as long as player is airborne. if(airborne == false || blockStocks <= 0){ // player is no longer airborne, or doesn't have a block to place. pendingPlaceBlock = false; lastSingleBlockBuildSeqDone = true; if(blockStocks > 0) { // cannot build; invalid position. } }else if((!OverlapsWithOneBlock(pendingPlaceBlockPos)) && BoxDistanceToBlock(pendingPlaceBlockPos) < 3.f){ // now building became possible. SPAssert(this == world->GetLocalPlayer()); if(GetWorld()->GetListener()) GetWorld()->GetListener()->LocalPlayerBlockAction(pendingPlaceBlockPos, BlockActionCreate); pendingPlaceBlock = false; lastSingleBlockBuildSeqDone = true; // blockStocks--; decrease when created nextBlockTime = world->GetTime() + GetToolPrimaryDelay(); } }else{ // Delayed Block Placement can be activated only when the only reason making placement // impossible is that block to be placed overlaps with the player's hitbox. canPending = result.hit && (result.hitBlock + result.normal).z < 62 && BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f; blockCursorActive = false; int dist = 11; for(; dist >= 1 && BoxDistanceToBlock(result.hitBlock + result.normal) > 3.f ; dist--) { result = GetWorld()->GetMap()->CastRay2(GetEye(), GetFront(), dist); } for(; dist < 12 && BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f ; dist++) { result = GetWorld()->GetMap()->CastRay2(GetEye(), GetFront(), dist); } blockCursorPos = result.hitBlock + result.normal; } }else if(tool == ToolWeapon){ }else if(tool == ToolGrenade){ if(holdingGrenade){ if(world->GetTime() - grenadeTime > 2.9f){ ThrowGrenade(); } } } if(tool != ToolWeapon) weapon->SetShooting(false); if(weapon->FrameNext(dt)){ FireWeapon(); } if(weapon->IsReloading()) { lastReloadingTime = world->GetTime(); }else if(reloadingServerSide) { // for some reason a server didn't return // WeaponReload packet. if(world->GetTime() + lastReloadingTime + .8f) { reloadingServerSide = false; weapon->ForceReloadDone(); } } }
//============================================================================= //状態毎の処理 //============================================================================= void CPlayer::StateExec() { switch( m_eState ) { /*何もしてない状態*/ case STATE_NONE: { m_AnimID[ANIM_NOW] = ANIM_STAND; break; } /*捕獲開始*/ case STATE_CAPSTART: { static int count = 0; const int MAX_COUNT = 60 * 2; m_AnimID[ANIM_NOW] = ANIM_CAPMOVE; count++; //if( count < 60 ) //{ // m_vPos.y += 1.0f; //} // //else if( count > 60 ) //{ // m_vPos.x += ( m_pCapedEnemy->GetCatchPos().x - m_vPos.x ) * 0.01f; //} /*ブースト音の再生*/ m_vPos.x = Interpolation::Add( m_vCapedPos.x, m_pCapedEnemy->GetCatchPos().x, MAX_COUNT, count ); m_vPos.y = Interpolation::Sin( m_vCapedPos.y , m_pCapedEnemy->GetCatchPos().y + 5.0f, MAX_COUNT, count); //m_vPos.y = Interpolation::Neville( m_vCapedPos.y, m_vCapedPos.y + m_pCapedEnemy->GetCatchPos().y + 2.0, // m_pCapedEnemy->GetCatchPos().y, count ); m_vPos.z = Interpolation::Add( m_vCapedPos.z, m_pCapedEnemy->GetCatchPos().z, MAX_COUNT, count ); m_Rot.y = Math::ATan2( m_vCapedPos.y, m_vCapedPos.z ); //Interpolation::Flat( DEG_TO_ANGLE( 90 ), DEG_TO_ANGLE( -80 ), MAX_COUNT, count ); //if( count < 30 ) //{ // CCommonObject::GetSoundMgr()->Play( CSoundManager::SND_BOOST ); //} if( m_vPos.y < m_pCapedEnemy->GetCatchPos().y && count > MAX_COUNT / 2 ) { /*小さくする*/ const float fSCALE = 0.3f; SetScale( Math::Vector3D( fSCALE, fSCALE, fSCALE ) ); /*噛み付き音の再生*/ CCommonObject::GetSoundMgr()->Play( CSoundManager::SND_BITE ); SetState( STATE_CAPTURE ); m_IsCapture = true; count = 0; } break; } /*捕獲中の時*/ case STATE_CAPTURE: { m_AnimID[ANIM_NOW] = ANIM_CAPING; break; } /*解放開始*/ case STATE_RELSTART: { m_AnimID[ANIM_NOW] = ANIM_CAPSTART; const Uint32 MAX_COUNT = 60 * 3; m_RelCount++; m_vPos.y = Interpolation::Sin( m_pCapedEnemy->GetPosition().y, m_pCapedEnemy->GetPosition().y + 5.0f, MAX_COUNT, m_RelCount ); m_vPos.x = Interpolation::Flat( m_pCapedEnemy->GetPosition().x, m_pCapedEnemy->GetPosition().x - m_vFront.x, MAX_COUNT, m_RelCount ); m_vPos.z = Interpolation::Flat( m_pCapedEnemy->GetPosition().z, m_pCapedEnemy->GetPosition().z - m_vFront.z, MAX_COUNT, m_RelCount ); m_Rot.y = Interpolation::Flat( DEG_TO_ANGLE( -80 ), DEG_TO_ANGLE( 0 ), MAX_COUNT, m_RelCount ); if( m_RelCount > MAX_COUNT ) { m_eState = STATE_RELEASE; /*スケールを元に戻す*/ SetScale( m_vInitScale ); m_RelCount = 0; } break; } /*解放時*/ case STATE_RELEASE: { m_IsCapture = false; m_pCapedEnemy->SetCapdFlag( false ); m_pCapedEnemy->SetState( CEnemy::STATE_RELEASE ); m_eState = STATE_NONE; break; } /*移動中の時*/ case STATE_MOVING: { m_AnimID[ANIM_NOW] = ANIM_WALK; break; } /*停止中*/ case STATE_STOP: { break; } /*電車に当たったとき*/ case STATE_HIT_TRAIN: { static int count = 0; m_vPos.y += 1; if( ++count > 60 * 1 ) { count = 0; m_eState = STATE_NONE; } break; } /*敵に当たったとき*/ case STATE_HIT_ENEMY: { static int count = 0; //m_fSpeed = 0.0f; m_vPos += GetFront() * 0.01f; if( ++count > 30 ) { count = 0; m_eState = STATE_NONE; } break; } } }
// ハイパーアーツ bool Thief::HyperArts(void) { //空中で発動しても停止する move = Vector3(0, -GRAVITY, 0); if ( !initflag ) { sound->PlaySE( SE::HYPER_ATTACK ); sound->PlaySE( SE::KAITO_HYPER ); initflag = true; } attackInfo.power = OFFENSIVE_POWER::HYPER; attackInfo.dropPower = DROP_POWER::HYPER; attackInfo.coinDropType = DROP_TYPE::SUCTION; SetParameterState(PARAMETER_STATE::UNRIVALED); move = Vector3(0, 0 - GRAVITY, 0); //撃ってる間は静止させる SetMotion(THIEF::MOTION_DATA::HYPERARTS); // 行列から情報取得 Vector3 front = GetFront(); Vector3 right = GetRight(); Vector3 p_pos = GetPos(); SetMove(Vector3(0.0f, move.y, 0.0f)); if (obj->GetFrame() >= THIEF::MOTION_FRAME::HYPERARTS_ATTACKSTART/* && obj->GetFrame() < THIEF::MOTION_FRAME::HYPERARTS_ATTACKEND*/) { float t = GetBezier(ePrm_t::eRapid_Lv5, ePrm_t::eSlow_Lv1, attackInfo.t); Vector3 f = front * (2.0f * sinf(D3DX_PI * t)); Vector3 r = -right * (2.0f * cosf(D3DX_PI * t)); attackInfo.bottom = p_pos + f + r; switch (HyperStep) { case 0: // あたり判定のパラメータを与える attackInfo.top = attackInfo.bottom + r * HyperRate; attackInfo.r = 2.5f; HyperRate += 1.0; if (HyperRate > 20.0f) HyperStep++; break; case 1: // パラメータ加算 attackInfo.top = attackInfo.bottom + f * HyperRate + r * HyperRate; attackInfo.t += 0.03f; if (attackInfo.t >= 1.0f) { HyperStep++; } break; case 2: //attackInfo.top = attackInfo.bottom + r * rate; attackInfo.t = 0.0f; HyperRate -= 1.0f; break; } armRenderflag = true; } Vector3 v1, v2; v1 = front; v2 = attackInfo.top - attackInfo.bottom; v1.Normalize(); v2.Normalize(); float armAngle = GetAngle(v1, v2); Vector3 cross; Vector3Cross(cross, v1, v2); if (cross.y < 0) armAngle = -armAngle; arm->SetPos(pos); arm->SetAngle(angle.y + armAngle); arm->SetScale(Vector3(0.03f, 0.03f, HyperRate * 0.01f)); arm->Update(); if (HyperRate < 0) { HyperStep = 0; HyperRate = 0; armRenderflag = false; initflag = false; return true; } return false; }
void Player::FireWeapon() { SPADES_MARK_FUNCTION(); Vector3 muzzle = GetEye(); muzzle += GetFront() * 0.01f;/* muzzle += GetRight() * 0.4f; muzzle -= GetUp() * 0.3f;*/ Vector3 right = GetRight(); Vector3 up = GetUp(); int pellets = weapon->GetPelletSize(); float spread = weapon->GetSpread(); GameMap *map = world->GetMap(); // pyspades takes destroying more than one block as a // speed hack (shotgun does this) bool blockDestroyed = false; Vector3 dir2 = GetFront(); for(int i =0 ; i < pellets; i++){ // AoS 0.75's way (dir2 shouldn't be normalized!) dir2.x += (GetRandom() * 2.f - 1.f) * spread; dir2.y += (GetRandom() * 2.f - 1.f) * spread; dir2.z += (GetRandom() * 2.f - 1.f) * spread; Vector3 dir = dir2.Normalize(); // first do map raycast GameMap::RayCastResult mapResult; mapResult = map->CastRay2(muzzle, dir, 500); Player *hitPlayer = NULL; float hitPlayerDistance = 0.f; int hitFlag = 0; for(int i = 0; i < world->GetNumPlayerSlots(); i++){ Player *other = world->GetPlayer(i); if(other == this || other == NULL) continue; if(other == this || !other->IsAlive() || other->GetTeamId() >= 2) continue; if(!other->RayCastApprox(muzzle, dir)) continue; HitBoxes hb = other->GetHitBoxes(); Vector3 hitPos; if(hb.head.RayCast(muzzle, dir, &hitPos)) { float dist = (hitPos - muzzle).GetLength(); if(hitPlayer == NULL || dist < hitPlayerDistance){ if(hitPlayer != other){ hitPlayer = other; hitFlag = 0; } hitPlayerDistance = dist; hitFlag = 1; // head } } if(hb.torso.RayCast(muzzle, dir, &hitPos)) { float dist = (hitPos - muzzle).GetLength(); if(hitPlayer == NULL || dist < hitPlayerDistance){ if(hitPlayer != other){ hitPlayer = other; hitFlag = 0; } hitPlayerDistance = dist; hitFlag = 2; // torso } } for(int j = 0; j < 3 ;j++){ if(hb.limbs[j].RayCast(muzzle, dir, &hitPos)) { float dist = (hitPos - muzzle).GetLength(); if(hitPlayer == NULL || dist < hitPlayerDistance){ if(hitPlayer != other){ hitPlayer = other; hitFlag = 0; } hitPlayerDistance = dist; if(j == 2) hitFlag = 8; // arms else hitFlag = 4; // leg } } } } Vector3 finalHitPos; finalHitPos = muzzle + dir * 128.f; if(mapResult.hit && (mapResult.hitPos - muzzle).GetLength() < 128.f && (hitPlayer == NULL || (mapResult.hitPos - muzzle).GetLength() < hitPlayerDistance)){ IntVector3 outBlockCoord = mapResult.hitBlock; // TODO: set correct ray distance // FIXME: why ray casting twice? finalHitPos = mapResult.hitPos; if(outBlockCoord.x >= 0 && outBlockCoord.y >= 0 && outBlockCoord.z >= 0 && outBlockCoord.x < map->Width() && outBlockCoord.y < map->Height() && outBlockCoord.z < map->Depth()){ if(outBlockCoord.z < 62){ int x = outBlockCoord.x; int y = outBlockCoord.y; int z = outBlockCoord.z; SPAssert(map->IsSolid(x, y, z)); Vector3 blockF = {x + .5f, y + .5f, z + .5f}; float distance = (blockF - muzzle).GetLength(); uint32_t color = map->GetColor(x, y, z); int health = color >> 24; health -= weapon->GetDamage(HitTypeBlock, distance); if(health <= 0 && !blockDestroyed){ health = 0; blockDestroyed = true; //send destroy cmd if(world->GetListener() && world->GetLocalPlayer() == this) world->GetListener()->LocalPlayerBlockAction (outBlockCoord, BlockActionTool); } color = (color & 0xffffff) | ((uint32_t)health << 24); if(map->IsSolid(x, y, z)) map->Set(x, y, z, true, color); if(world->GetListener()) world->GetListener()->BulletHitBlock(mapResult.hitPos, mapResult.hitBlock, mapResult.normal); } } }else if(hitPlayer != NULL){
void Player::Update(float dt) { SPADES_MARK_FUNCTION(); MovePlayer(dt); if(tool == ToolSpade){ if(weapInput.primary){ if(world->GetTime() > nextSpadeTime){ UseSpade(); nextSpadeTime = world->GetTime() + GetToolPrimaryDelay(); } }else if(weapInput.secondary){ if(world->GetTime() > nextDigTime){ DigWithSpade(); nextDigTime = world->GetTime() + GetToolSecondaryDelay(); firstDig = false; } } }else if(tool == ToolBlock){ GameMap::RayCastResult result; result = GetWorld()->GetMap()->CastRay2(GetEye(), GetFront(), 12); canPending = false; if(result.hit && (result.hitBlock + result.normal).z < 62 && (!OverlapsWithOneBlock(result.hitBlock + result.normal)) && BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f && !pendingPlaceBlock){ blockCursorActive = true; blockCursorPos = result.hitBlock + result.normal; }else if(pendingPlaceBlock){ if(airborne == false || blockStocks <= 0){ pendingPlaceBlock = false; }else if((!OverlapsWithOneBlock(pendingPlaceBlockPos)) && BoxDistanceToBlock(pendingPlaceBlockPos) < 3.f){ SPAssert(this == world->GetLocalPlayer()); if(GetWorld()->GetListener()) GetWorld()->GetListener()->LocalPlayerBlockAction(pendingPlaceBlockPos, BlockActionCreate); pendingPlaceBlock = false; // blockStocks--; decrease when created nextBlockTime = world->GetTime() + GetToolPrimaryDelay(); } }else{ canPending = result.hit && (result.hitBlock + result.normal).z < 62 && BoxDistanceToBlock(result.hitBlock + result.normal) < 3.f; blockCursorActive = false; blockCursorPos = result.hitBlock + result.normal; } }else if(tool == ToolWeapon){ }else if(tool == ToolGrenade){ if(holdingGrenade){ if(world->GetTime() - grenadeTime > 2.9f){ ThrowGrenade(); } } } if(tool != ToolWeapon) weapon->SetShooting(false); if(weapon->FrameNext(dt)){ FireWeapon(); } if(weapon->IsReloading()) { lastReloadingTime = world->GetTime(); }else if(reloadingServerSide) { // for some reason a server didn't return // WeaponReload packet. if(world->GetTime() + lastReloadingTime + .8f) { reloadingServerSide = false; weapon->ForceReloadDone(); } } }
const Vect3f CSteeringEntity::GetFinalPositionToThrowRay( float _DegresOfRotation ) const { /*SCollisionInfo sInfo; uint32 l_Mask; l_Mask |= 1 << ECG_ESCENE;*/ float l_ObstacleDistanceRay = CORE->GetSteeringBehaviourSettingsManager()->GetCollisionDetectionFeelerLength(); Vect3f l_Front = GetFront(); if ( _DegresOfRotation != 0 ) l_Front.RotateY(mathUtils::Deg2Rad( 360 - _DegresOfRotation)); Vect3f l_OriginalFront = l_Front; l_Front.Normalize(); Vect3f l_InitialPosition = GetInitialPositionToThrowRay(); Vect3f l_FinalPosition; Vect3f l_DirNormal; // Lanzo un rayo para interceptar con el terreno y me de la altura del terreno a esa distancia de colision //CPhysicUserData * l_Data = CORE->GetPhysicsManager()->RaycastClosestActor( l_InitialPosition, l_Front, l_Mask, sInfo ); //// Si ha colisionado con el suelo es que seguramente hay una pendiente //if ( l_Data ) //{ // sInfo.m_CollisionPoint.y += m_Height; // l_DirNormal = sInfo.m_CollisionPoint - l_InitialPosition; // l_DirNormal.Normalize(); // l_FinalPosition = + l_DirNormal * l_ObstacleDistanceRay; //} //else //{ // Compruebo si estamos en bajada //l_Front = l_OriginalFront; //float l_DifY = m_PreviousPosition.y - m_Position.y; //Vect3f l_Direction = m_PreviousPosition - m_Position; //float l_Angle = l_Front.Dot( l_Direction ); // //// Es menor de 90º //if ( l_Angle > 0.f ) // && ( l_DifY > m_Height ) ) //{ // l_Front = m_Position + l_OriginalFront; // //l_Front.y = m_Position.y + // //l_DirNormal = m // //// Lanzo otro rayo hacia el suelo // //CPhysicUserData * l_Data = CORE->GetPhysicsManager()->RaycastClosestActor( l_InitialPosition, l_Front, l_Mask, sInfo ); //} //// Es mayor de 90º //else if ( l_Angle > 0.f ) //{ // l_Front = m_Position + l_OriginalFront; // // //} //// Caso en que no colisiona devuelvo un punto final de rayo horizontal //else //{ l_FinalPosition = Vect3f ( l_InitialPosition.x + l_Front.x * l_ObstacleDistanceRay, l_InitialPosition.y, l_InitialPosition.z + l_Front.z * l_ObstacleDistanceRay); //} // } //l_FinalPosition = Vect3f ( l_InitialPosition.x + l_Front.x * l_ObstacleDistanceRay, l_InitialPosition.y, l_InitialPosition.z + l_Front.z * l_ObstacleDistanceRay); return l_FinalPosition; }
mat3 Orientation::GetMatrix() { return mat3(-GetRight(), GetUp(), GetFront()); }