BOOL obj_ItemSpawnPoint::Update() { static int delayCheckSpawnPointsInAir = 100; if(delayCheckSpawnPointsInAir) --delayCheckSpawnPointsInAir; if(g_bEditMode && m_bEditorCheckSpawnPointAtStart && delayCheckSpawnPointsInAir ==0) { m_bEditorCheckSpawnPointAtStart = false; for(ITEM_SPAWN_POINT_VECTOR::iterator it=m_SpawnPointsV.begin(); it!=m_SpawnPointsV.end(); ++it) { PxVec3 from(it->pos.x, it->pos.y+1.0f, it->pos.z); PxRaycastHit hit; PxSceneQueryFilterData filter(PxFilterData(COLLIDABLE_STATIC_MASK,0,0,0), PxSceneQueryFilterFlags(PxSceneQueryFilterFlag::eSTATIC)); if(g_pPhysicsWorld->raycastSingle(from, PxVec3(0,-1,0), 10000, PxSceneQueryFlags(PxSceneQueryFlag::eIMPACT), hit, filter)) { r3dPoint3D hitPos(hit.impact.x, hit.impact.y, hit.impact.z); if(R3D_ABS(it->pos.y - hitPos.y) > 2.0f) { r3dArtBug("Item CP Spawn at %.2f, %.2f, %.2f has spawn position(s) in the air. Please select it and use Check Locations button\n", GetPosition().x, GetPosition().y, GetPosition().z); break; } } } r3dShowArtBugs(); } return parent::Update(); }
void GOCCharacterController::ReceiveMessage(Msg &msg) { GOComponent::ReceiveMessage(msg); if (msg.typeID == GlobalMessageIDs::PHYSICS_SUBSTEP && !mFreezed) { GameObjectPtr owner = mOwnerGO.lock(); float time = msg.params.GetFloat("TIME"); Ogre::Vector3 finalDir = Ogre::Vector3(0,0,0); Ogre::Vector3 userDir = owner->GetGlobalOrientation() * mDirection; if (mActor.getPxActor()->isSleeping()) mActor.getPxActor()->wakeUp(); //Gravity fix Ogre::Vector3 playerHalfSize = mDimensions * 0.5f; PxTransform transform(OgrePhysX::toPx(owner->GetGlobalPosition()), OgrePhysX::toPx(owner->GetGlobalOrientation())); transform.p.y += playerHalfSize.y; //sweep filter data - only check against shapes with filter data DYNAMICBODY or STATICBODY PxSceneQueryFilterData filterData; filterData.data.word0 = CollisionGroups::DYNAMICBODY|CollisionGroups::STATICBODY; filterData.flags = PxSceneQueryFilterFlag::eDYNAMIC|PxSceneQueryFilterFlag::eSTATIC; //touches ground check PxBoxGeometry playerGeometry(playerHalfSize.x, playerHalfSize.y+0.1f, playerHalfSize.z); PxShape *outShape; mTouchesGround = Main::Instance().GetPhysXScene()->getPxScene()->overlapAny(playerGeometry, transform, outShape, filterData); //stair maxStepHeight float maxStepHeight = 0.6f; PxVec3 currPos = OgrePhysX::Convert::toPx(owner->GetGlobalPosition()); //feet capsule PxBoxGeometry feetVolume(playerHalfSize.x, maxStepHeight*0.5f, playerHalfSize.z); //body capsule float bodyHeight = mDimensions.y-maxStepHeight; PxBoxGeometry bodyVolume(playerHalfSize.x, bodyHeight*0.5f, playerHalfSize.z); PxVec3 sweepDirection = OgrePhysX::toPx(userDir); float userDirLength = sweepDirection.normalize(); /* We perform two sweeps: O ==> bodyHit? | ==> bodyHit? / \ ==> feetHit? If there are no hits character can walk in the desired direction. If there is a feetHit but no bodyHit player can climb stairs (we add an y-Offset). If there is a bodyHit the player can not move. */ PxSweepHit sweepHit; transform.p.y = owner->GetGlobalPosition().y + maxStepHeight + bodyHeight*0.5f; bool bodyHit = Main::Instance().GetPhysXScene()->getPxScene()->sweepSingle(bodyVolume, transform, sweepDirection, time*userDirLength, PxSceneQueryFlags(), sweepHit, filterData); transform.p.y = owner->GetGlobalPosition().y + maxStepHeight*0.5f; bool feetHit = Main::Instance().GetPhysXScene()->getPxScene()->sweepSingle(feetVolume, transform, sweepDirection, time*userDirLength, PxSceneQueryFlags(), sweepHit, filterData); if (!bodyHit) { finalDir += userDir; //add player movement if (feetHit) finalDir += Ogre::Vector3(0,3,0); //climb stairs } if (finalDir != Ogre::Vector3(0,0,0)) mActor.getPxActor()->setGlobalPose(PxTransform(currPos + OgrePhysX::Convert::toPx(finalDir*time))); if (mJumping && mTouchesGround && (timeGetTime() - mJumpStartTime > 400)) { mJumping = false; Msg jump_response; jump_response.typeID = ObjectMessageIDs::END_JUMP; BroadcastObjectMessage(jump_response); } } if (msg.typeID == GlobalMessageIDs::PHYSICS_END && !mFreezed) { SetOwnerPosition(mActor.getGlobalPosition()); //SetOwnerOrientation(mActor->getGlobalOrientation()); } if (msg.typeID == ObjectMessageIDs::UPDATE_CHARACTER_MOVEMENTSTATE) { mDirection = Ogre::Vector3(0,0,0); int movementFlags = msg.params.GetInt("CharacterMovementState"); if (movementFlags & CharacterMovement::FORWARD) mDirection.z += 1; if (movementFlags & CharacterMovement::BACKWARD) mDirection.z -= 1; if (movementFlags & CharacterMovement::LEFT) mDirection.x += 1; if (movementFlags & CharacterMovement::RIGHT) mDirection.x -= 1; mDirection.normalise(); mDirection*=(mMovementSpeed*mSpeedFactor); } if (msg.typeID == ObjectMessageIDs::INPUT_START_JUMP) { if (mTouchesGround && !mJumping) { mJumping = true; mJumpStartTime = timeGetTime(); mActor.getPxActor()->addForce(PxVec3(0, mActor.getPxActor()->getMass()*8, 0), PxForceMode::eIMPULSE); Msg startJumpMsg; startJumpMsg.typeID = ObjectMessageIDs::START_JUMP; BroadcastObjectMessage(startJumpMsg); } } if (msg.typeID == ObjectMessageIDs::CHARACTER_KILL) { mFreezed = true; } }
float obj_ItemSpawnPoint::DrawPropertyEditor(float scrx, float scry, float scrw, float scrh, const AClass* startClass, const GameObjects& selected) { float starty = scry; starty += parent::DrawPropertyEditor(scrx, scry, scrw,scrh, startClass, selected ); if( IsParentOrEqual( &ClassData, startClass ) ) { starty += imgui_Static ( scrx, starty, "Item Spawn Point Parameters" ); starty += imgui_Value_Slider(scrx, starty, "Tick Period (sec)", &m_TickPeriod, 1.0f, 50000.0f, "%.2f"); starty += imgui_Value_Slider(scrx, starty, "Cooldown (sec)", &m_Cooldown, 1.0f, 50000.0f, "%.2f"); starty += imgui_Value_Slider(scrx, starty, "De-spawn (sec)", &m_DestroyItemTimer, 0.0f, 50000.0f, "%.2f"); int isOneItemSpawn = m_OneItemSpawn?1:0; starty += imgui_Checkbox(scrx, starty, "One Item Spawn", &isOneItemSpawn, 1); m_OneItemSpawn = isOneItemSpawn?true:false; if(!m_OneItemSpawn) { static stringlist_t lootBoxNames; static int* lootBoxIDs = NULL; static int numLootBoxes = 0; if(numLootBoxes == 0) { struct tempS { char* name; uint32_t id; }; std::vector<tempS> lootBoxes; { tempS holder; holder.name = "EMPTY"; holder.id = 0; lootBoxes.push_back(holder); } g_pWeaponArmory->startItemSearch(); while(g_pWeaponArmory->searchNextItem()) { uint32_t itemID = g_pWeaponArmory->getCurrentSearchItemID(); const BaseItemConfig* cfg = g_pWeaponArmory->getConfig(itemID); if( cfg->category == storecat_LootBox ) { tempS holder; holder.name = cfg->m_StoreName; holder.id = cfg->m_itemID; lootBoxes.push_back(holder); } } numLootBoxes = (int)lootBoxes.size(); lootBoxIDs = new int[numLootBoxes]; for(int i=0; i<numLootBoxes; ++i) { lootBoxNames.push_back(lootBoxes[i].name); lootBoxIDs[i] = lootBoxes[i].id; } } int sel = 0; static float offset = 0; for(int i=0; i<numLootBoxes; ++i) if(m_LootBoxID == lootBoxIDs[i]) sel = i; starty += imgui_Static ( scrx, starty, "Loot box:" ); if(imgui_DrawList(scrx, starty, 360, 122, lootBoxNames, &offset, &sel)) { m_LootBoxID = lootBoxIDs[sel]; PropagateChange( m_LootBoxID, &obj_ItemSpawnPoint::m_LootBoxID, this, selected ) ; } starty += 122; } else { starty += imgui_Value_SliderI(scrx, starty, "ItemID", (int*)&m_LootBoxID, 0, 1000000, "%d", false); PropagateChange( m_LootBoxID, &obj_ItemSpawnPoint::m_LootBoxID, this, selected ) ; } // don't allow multi edit of this if( selected.Count() <= 1 ) { { if(imgui_Button(scrx, starty, 200, 25, "Check locations")) { for(ITEM_SPAWN_POINT_VECTOR::iterator it=m_SpawnPointsV.begin(); it!=m_SpawnPointsV.end(); ++it) { PxVec3 from(it->pos.x, it->pos.y+1.0f, it->pos.z); PxRaycastHit hit; PxSceneQueryFilterData filter(PxFilterData(COLLIDABLE_STATIC_MASK,0,0,0), PxSceneQueryFilterFlags(PxSceneQueryFilterFlag::eSTATIC)); if(g_pPhysicsWorld->raycastSingle(from, PxVec3(0,-1,0), 10000, PxSceneQueryFlags(PxSceneQueryFlag::eIMPACT), hit, filter)) { r3dPoint3D hitPos(hit.impact.x, hit.impact.y, hit.impact.z); if(R3D_ABS(it->pos.y - hitPos.y) > 2.0f) { gCam = it->pos + r3dPoint3D(0,1,0); break; } } } } starty += 30; } if(imgui_Button(scrx+110, starty, 100, 25, "Add Location")) { ItemSpawn itemSpawn; itemSpawn.pos = GetPosition() + r3dPoint3D(2, 0, 2); m_SpawnPointsV.push_back(itemSpawn); m_SelectedSpawnPoint = m_SpawnPointsV.size()-1; } starty += 25; int i=0; for(ITEM_SPAWN_POINT_VECTOR::iterator it=m_SpawnPointsV.begin(); it!=m_SpawnPointsV.end(); ) { // selection button char tempStr[32]; sprintf(tempStr, "Location %d", i+1); if(imgui_Button(scrx, starty, 100, 25, tempStr, i==m_SelectedSpawnPoint)) { // shift click on location will set camera to it if(Keyboard->IsPressed(kbsLeftShift)) { extern BaseHUD* HudArray[6]; extern int CurHUDID; HudArray[CurHUDID]->FPS_Position = m_SpawnPointsV[i].pos; HudArray[CurHUDID]->FPS_Position.y += 0.1f; } m_SelectedSpawnPoint = i; } // delete button if(m_SpawnPointsV.size() > 1) { if(imgui_Button(scrx + 110, starty, 100, 25, "DEL")) { it = m_SpawnPointsV.erase(it); continue; } m_SelectedSpawnPoint = R3D_CLAMP(m_SelectedSpawnPoint, 0, (int)m_SpawnPointsV.size()-1); } starty += 25; ++it; ++i; } extern r3dPoint3D UI_TargetPos; if((Mouse->IsPressed(r3dMouse::mLeftButton)) && Keyboard->IsPressed(kbsLeftControl)) m_SpawnPointsV[m_SelectedSpawnPoint].pos = UI_TargetPos; } } return starty-scry; }