void RogueSkill4::HandleNodeCollisionStart(StringHash eventType, VariantMap& eventData) { using namespace NodeCollisionStart; SharedPtr<Node> otherNode = SharedPtr<Node>(static_cast<Node*>(eventData[P_OTHERNODE].GetPtr())); RigidBody* rb = static_cast<RigidBody*>(eventData[P_BODY].GetPtr()); Node* noed = rb->GetNode(); if (!otherNode->HasComponent<Health>()) { noed->Remove(); return; } if (otherNode->GetVar("npcType").GetInt() == 1)//terry { otherNode->GetComponent<Health>()->ModifyHealth(10, -1, false); if (otherNode->GetComponent<Health>()->health_ <= 0) { otherNode->GetComponent<Health>()->ModifyHealth(100, 0, false); otherNode->GetScene()->GetComponent<TerrySpawner>()->RespawnTerry(otherNode); return; } //otherNode->AddComponent(new Stunned(context_, main_, 2.0f), 0, LOCAL); noed->Remove(); } }
void TerrySpawner::HandleNodeCollisionEnd(StringHash eventType, VariantMap& eventData) { using namespace NodeCollisionEnd; SharedPtr<Node> otherNode = SharedPtr<Node>(static_cast<Node*>(eventData[P_OTHERNODE].GetPtr())); RigidBody* rb = static_cast<RigidBody*>(eventData[P_BODY].GetPtr()); Node* noed = rb->GetNode(); MoveByTouch* mbt = noed->GetComponent<MoveByTouch>(); mbt->MoveTo(tent_->GetWorldPosition(), mbt->moveToSpeed_,mbt->speedRamp_,mbt->gravity_,mbt->gravityRamp_,false,true,true); if (!otherNode->HasComponent<Health>()) { return; } if (otherNode->GetVar("npcType").GetInt() == 0)//hero { int collisionCount = noed->GetVar("collisionCount").GetInt(); collisionCount--; noed->SetVar("collisionCount", collisionCount); if (collisionCount == 0) { VariantMap vm; vm[AnimateSceneNode::P_NODE] = noed; if (noed->GetVar("sex").GetBool()) { vm[AnimateSceneNode::P_ANIMATION] = "runF"; } else { vm[AnimateSceneNode::P_ANIMATION] = "runM"; } vm[AnimateSceneNode::P_LOOP] = false; vm[AnimateSceneNode::P_LAYER] = 0; SendEvent(E_ANIMATESCENENODE, vm); } } }
void Pickup::HandleTriggerStart(StringHash eventType, VariantMap &eventData) { PODVector<RigidBody*> collidingBodies; triggerBody_->GetCollidingBodies(collidingBodies); for (int i = 0; i < collidingBodies.Size(); i++) { RigidBody* collider = collidingBodies[i]; if (collider->GetNode()->GetNameHash() == N_PLAYER) { masterControl_->player_->Pickup(pickupType_); masterControl_->spawnMaster_->SpawnHitFX(GetPosition(), false); switch (pickupType_){ case PT_MULTIX: case PT_CHAOBALL: Deactivate(); break; case PT_APPLE: case PT_HEART: Respawn(); break; default: break; } } } }
void PhysicsWorld::SendCollisionEvents() { ATOMIC_PROFILE(SendCollisionEvents); currentCollisions_.Clear(); physicsCollisionData_.Clear(); nodeCollisionData_.Clear(); int numManifolds = collisionDispatcher_->getNumManifolds(); if (numManifolds) { physicsCollisionData_[PhysicsCollision::P_WORLD] = this; for (int i = 0; i < numManifolds; ++i) { btPersistentManifold* contactManifold = collisionDispatcher_->getManifoldByIndexInternal(i); // First check that there are actual contacts, as the manifold exists also when objects are close but not touching if (!contactManifold->getNumContacts()) continue; const btCollisionObject* objectA = contactManifold->getBody0(); const btCollisionObject* objectB = contactManifold->getBody1(); RigidBody* bodyA = static_cast<RigidBody*>(objectA->getUserPointer()); RigidBody* bodyB = static_cast<RigidBody*>(objectB->getUserPointer()); // If it's not a rigidbody, maybe a ghost object if (!bodyA || !bodyB) continue; // Skip collision event signaling if both objects are static, or if collision event mode does not match if (bodyA->GetMass() == 0.0f && bodyB->GetMass() == 0.0f) continue; if (bodyA->GetCollisionEventMode() == COLLISION_NEVER || bodyB->GetCollisionEventMode() == COLLISION_NEVER) continue; if (bodyA->GetCollisionEventMode() == COLLISION_ACTIVE && bodyB->GetCollisionEventMode() == COLLISION_ACTIVE && !bodyA->IsActive() && !bodyB->IsActive()) continue; WeakPtr<RigidBody> bodyWeakA(bodyA); WeakPtr<RigidBody> bodyWeakB(bodyB); // First only store the collision pair as weak pointers and the manifold pointer, so user code can safely destroy // objects during collision event handling Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> > bodyPair; if (bodyA < bodyB) { bodyPair = MakePair(bodyWeakA, bodyWeakB); currentCollisions_[bodyPair].manifold_ = contactManifold; } else { bodyPair = MakePair(bodyWeakB, bodyWeakA); currentCollisions_[bodyPair].flippedManifold_ = contactManifold; } } for (HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair>::Iterator i = currentCollisions_.Begin(); i != currentCollisions_.End(); ++i) { RigidBody* bodyA = i->first_.first_; RigidBody* bodyB = i->first_.second_; if (!bodyA || !bodyB) continue; Node* nodeA = bodyA->GetNode(); Node* nodeB = bodyB->GetNode(); WeakPtr<Node> nodeWeakA(nodeA); WeakPtr<Node> nodeWeakB(nodeB); bool trigger = bodyA->IsTrigger() || bodyB->IsTrigger(); bool newCollision = !previousCollisions_.Contains(i->first_); physicsCollisionData_[PhysicsCollision::P_NODEA] = nodeA; physicsCollisionData_[PhysicsCollision::P_NODEB] = nodeB; physicsCollisionData_[PhysicsCollision::P_BODYA] = bodyA; physicsCollisionData_[PhysicsCollision::P_BODYB] = bodyB; physicsCollisionData_[PhysicsCollision::P_TRIGGER] = trigger; contacts_.Clear(); // "Pointers not flipped"-manifold, send unmodified normals btPersistentManifold* contactManifold = i->second_.manifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } // "Pointers flipped"-manifold, flip normals also contactManifold = i->second_.flippedManifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(-ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } physicsCollisionData_[PhysicsCollision::P_CONTACTS] = contacts_.GetBuffer(); // Send separate collision start event if collision is new if (newCollision) { SendEvent(E_PHYSICSCOLLISIONSTART, physicsCollisionData_); // Skip rest of processing if either of the nodes or bodies is removed as a response to the event if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; } // Then send the ongoing collision event SendEvent(E_PHYSICSCOLLISION, physicsCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; nodeCollisionData_[NodeCollision::P_BODY] = bodyA; nodeCollisionData_[NodeCollision::P_OTHERNODE] = nodeB; nodeCollisionData_[NodeCollision::P_OTHERBODY] = bodyB; nodeCollisionData_[NodeCollision::P_TRIGGER] = trigger; nodeCollisionData_[NodeCollision::P_CONTACTS] = contacts_.GetBuffer(); if (newCollision) { nodeA->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; } nodeA->SendEvent(E_NODECOLLISION, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; // Flip perspective to body B contacts_.Clear(); contactManifold = i->second_.manifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(-ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } contactManifold = i->second_.flippedManifold_; if (contactManifold) { for (int j = 0; j < contactManifold->getNumContacts(); ++j) { btManifoldPoint& point = contactManifold->getContactPoint(j); contacts_.WriteVector3(ToVector3(point.m_positionWorldOnB)); contacts_.WriteVector3(ToVector3(point.m_normalWorldOnB)); contacts_.WriteFloat(point.m_distance1); contacts_.WriteFloat(point.m_appliedImpulse); } } nodeCollisionData_[NodeCollision::P_BODY] = bodyB; nodeCollisionData_[NodeCollision::P_OTHERNODE] = nodeA; nodeCollisionData_[NodeCollision::P_OTHERBODY] = bodyA; nodeCollisionData_[NodeCollision::P_CONTACTS] = contacts_.GetBuffer(); if (newCollision) { nodeB->SendEvent(E_NODECOLLISIONSTART, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; } nodeB->SendEvent(E_NODECOLLISION, nodeCollisionData_); } } // Send collision end events as applicable { physicsCollisionData_[PhysicsCollisionEnd::P_WORLD] = this; for (HashMap<Pair<WeakPtr<RigidBody>, WeakPtr<RigidBody> >, ManifoldPair>::Iterator i = previousCollisions_.Begin(); i != previousCollisions_.End(); ++i) { if (!currentCollisions_.Contains(i->first_)) { RigidBody* bodyA = i->first_.first_; RigidBody* bodyB = i->first_.second_; if (!bodyA || !bodyB) continue; bool trigger = bodyA->IsTrigger() || bodyB->IsTrigger(); // Skip collision event signaling if both objects are static, or if collision event mode does not match if (bodyA->GetMass() == 0.0f && bodyB->GetMass() == 0.0f) continue; if (bodyA->GetCollisionEventMode() == COLLISION_NEVER || bodyB->GetCollisionEventMode() == COLLISION_NEVER) continue; if (bodyA->GetCollisionEventMode() == COLLISION_ACTIVE && bodyB->GetCollisionEventMode() == COLLISION_ACTIVE && !bodyA->IsActive() && !bodyB->IsActive()) continue; Node* nodeA = bodyA->GetNode(); Node* nodeB = bodyB->GetNode(); WeakPtr<Node> nodeWeakA(nodeA); WeakPtr<Node> nodeWeakB(nodeB); physicsCollisionData_[PhysicsCollisionEnd::P_BODYA] = bodyA; physicsCollisionData_[PhysicsCollisionEnd::P_BODYB] = bodyB; physicsCollisionData_[PhysicsCollisionEnd::P_NODEA] = nodeA; physicsCollisionData_[PhysicsCollisionEnd::P_NODEB] = nodeB; physicsCollisionData_[PhysicsCollisionEnd::P_TRIGGER] = trigger; SendEvent(E_PHYSICSCOLLISIONEND, physicsCollisionData_); // Skip rest of processing if either of the nodes or bodies is removed as a response to the event if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; nodeCollisionData_[NodeCollisionEnd::P_BODY] = bodyA; nodeCollisionData_[NodeCollisionEnd::P_OTHERNODE] = nodeB; nodeCollisionData_[NodeCollisionEnd::P_OTHERBODY] = bodyB; nodeCollisionData_[NodeCollisionEnd::P_TRIGGER] = trigger; nodeA->SendEvent(E_NODECOLLISIONEND, nodeCollisionData_); if (!nodeWeakA || !nodeWeakB || !i->first_.first_ || !i->first_.second_) continue; nodeCollisionData_[NodeCollisionEnd::P_BODY] = bodyB; nodeCollisionData_[NodeCollisionEnd::P_OTHERNODE] = nodeA; nodeCollisionData_[NodeCollisionEnd::P_OTHERBODY] = bodyA; nodeB->SendEvent(E_NODECOLLISIONEND, nodeCollisionData_); } } } previousCollisions_ = currentCollisions_; }
void TerrySpawner::HandleNodeCollision(StringHash eventType, VariantMap& eventData) { using namespace NodeCollision; RigidBody* rb = static_cast<RigidBody*>(eventData[P_BODY].GetPtr()); Node* noed = rb->GetNode(); if (!noed->GetVar("canAttack").GetBool()) { return; } if (noed->GetComponent<Blind>()) { return; } noed->SetVar("canAttack", false); SharedPtr<Node> otherNode = SharedPtr<Node>(static_cast<Node*>(eventData[P_OTHERNODE].GetPtr())); if (!otherNode->HasComponent<Health>()) { return; } bool enemy = false; if (otherNode->GetVar("npcType").GetInt() == 0)//hero { enemy = true; } if (enemy || noed->HasComponent<Enchanted>()) { int healthMod = noed->GetVar("attack").GetInt(); if (otherNode->HasComponent<Armor>()) { healthMod = noed->GetVar("attack").GetInt() - otherNode->GetComponent<Armor>()->armor_; if (healthMod < 0) { healthMod = 0; } } otherNode->GetComponent<Health>()->ModifyHealth(healthMod, -1, false); if (otherNode->GetComponent<Health>()->health_ <= 0) { if (!enemy && noed->HasComponent<Enchanted>()) { otherNode->GetComponent<Health>()->ModifyHealth(100, 0, false); otherNode->GetScene()->GetComponent<TerrySpawner>()->RespawnTerry(otherNode); } else if (otherNode->GetName() != "tent") { if (!otherNode->HasComponent<Dead>()) { otherNode->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); } } else { SpriteSheetPlayer* ssp = main_->mySceneNode_->GetComponent<SpriteSheetPlayer>(); for (int x = 0; x < ssp->sprites_.Size(); x++) { if (!ssp->sprites_[x]->noed_->HasComponent<Dead>()) { ssp->sprites_[x]->noed_->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); Node* particleStartNode_ = ssp->sprites_[x]->noed_->GetScene()->CreateChild(0,LOCAL); particleStartNode_->SetPosition(ssp->sprites_[x]->noed_->GetPosition()); particleStartNode_->AddComponent(new TimedRemove(context_, main_, 2.0f), 0, LOCAL); particleStartNode_->AddComponent(new SoundSource3D(context_), 0, LOCAL); particleStartNode_->GetComponent<SoundSource3D>()->SetGain(0.1f); particleStartNode_->GetComponent<SoundSource3D>()->Play(main_->cache_->GetResource<Sound>("Sounds/319071__mishicu__v8.ogg")); } } } return; } /*if (!noed->HasComponent<Stunned>()) { noed->AddComponent(new Stunned(context_, main_, 2.0f), 0, LOCAL); }*/ } }
void TerrySpawner::HandleNodeCollisionStart(StringHash eventType, VariantMap& eventData) { using namespace NodeCollisionStart; SharedPtr<Node> otherNode = SharedPtr<Node>(static_cast<Node*>(eventData[P_OTHERNODE].GetPtr())); RigidBody* rb = static_cast<RigidBody*>(eventData[P_BODY].GetPtr()); Node* noed = rb->GetNode(); if (otherNode->GetName() == "safetyNet") { RespawnTerry(noed); return; } if (!otherNode->HasComponent<Health>()) { return; } if (otherNode->GetVar("npcType").GetInt() == 0)//hero { MoveByTouch* mbt = noed->GetComponent<MoveByTouch>(); mbt->MoveTo(otherNode->GetWorldPosition(), mbt->moveToSpeed_,mbt->speedRamp_,mbt->gravity_,mbt->gravityRamp_,false,true,true); int collisionCount = noed->GetVar("collisionCount").GetInt(); collisionCount++; noed->SetVar("collisionCount", collisionCount); if (collisionCount == 1) { VariantMap vm; vm[AnimateSceneNode::P_NODE] = noed; if (noed->GetVar("sex").GetBool()) { vm[AnimateSceneNode::P_ANIMATION] = "attackF"; } else { vm[AnimateSceneNode::P_ANIMATION] = "attackM"; } vm[AnimateSceneNode::P_LOOP] = false; vm[AnimateSceneNode::P_LAYER] = 0; SendEvent(E_ANIMATESCENENODE, vm); } if (noed->GetComponent<Blind>() || noed->GetComponent<Stunned>()) { return; } int healthMod = noed->GetVar("attack").GetInt(); if (otherNode->HasComponent<Armor>()) { healthMod = noed->GetVar("attack").GetInt() - otherNode->GetComponent<Armor>()->armor_; if (healthMod < 0) { healthMod = 0; } } otherNode->GetComponent<Health>()->ModifyHealth(healthMod, -1, false); if (otherNode->GetComponent<Health>()->health_ <= 0) { if (otherNode->GetName() != "tent") { if (!otherNode->HasComponent<Dead>()) { otherNode->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); } } else { SpriteSheetPlayer* ssp = main_->mySceneNode_->GetComponent<SpriteSheetPlayer>(); for (int x = 0; x < ssp->sprites_.Size(); x++) { if (!ssp->sprites_[x]->noed_->HasComponent<Dead>()) { ssp->sprites_[x]->noed_->AddComponent(new Dead(context_, main_, -1.0f), 0, LOCAL); Node* particleStartNode_ = ssp->sprites_[x]->noed_->GetScene()->CreateChild(0,LOCAL); particleStartNode_->SetPosition(ssp->sprites_[x]->noed_->GetPosition()); particleStartNode_->AddComponent(new TimedRemove(context_, main_, 2.0f), 0, LOCAL); particleStartNode_->AddComponent(new SoundSource3D(context_), 0, LOCAL); particleStartNode_->GetComponent<SoundSource3D>()->SetGain(0.1f); particleStartNode_->GetComponent<SoundSource3D>()->Play(main_->cache_->GetResource<Sound>("Sounds/319071__mishicu__v8.ogg")); } } } //otherNode->GetComponent<Health>()->ModifyHealth(100, 0, false); //otherNode->GetScene()->GetComponent<TerrySpawner>()->RespawnTerry(otherNode); return; } /*if (!noed->HasComponent<Stunned>()) { noed->AddComponent(new Stunned(context_, main_, 2.0f), 0, LOCAL); }*/ } }
void WizardSkill0::HandleNodeCollisionStart(StringHash eventType, VariantMap& eventData) { using namespace NodeCollisionStart; SharedPtr<Node> otherNode = SharedPtr<Node>(static_cast<Node*>(eventData[P_OTHERNODE].GetPtr())); RigidBody* otherRB = static_cast<RigidBody*>(eventData[P_OTHERBODY].GetPtr()); RigidBody* rb = static_cast<RigidBody*>(eventData[P_BODY].GetPtr()); Node* noed = rb->GetNode(); if (!otherNode->HasComponent<Health>()) { /*Node* particleStartNode_ = noed->GetScene()->CreateChild(0,LOCAL); ParticleEmitter* emitterStartFX_ = particleStartNode_->CreateComponent<ParticleEmitter>(LOCAL); emitterStartFX_->SetEffect(main_->cache_->GetResource<ParticleEffect>("Particle/dustCloud.xml")); emitterStartFX_->SetViewMask(1); particleStartNode_->SetPosition(noed->GetPosition() + (Vector3::UP)); emitterStartFX_->SetEmitting(true); particleStartNode_->AddComponent(new TimedRemove(context_, main_, 2.0f), 0, LOCAL);*/ /*Node* lightNode = noed->GetScene()->CreateChild(0,LOCAL); lightNode->SetPosition(noed->GetPosition() + (Vector3::UP)); Light* light = lightNode->CreateComponent<Light>(LOCAL); light->SetBrightness(2.0f); light->SetPerVertex(true); light->SetRange(5.0f); lightNode->AddComponent(new TimedRemove(context_, main_, 0.1f), 0, LOCAL);*/ //noed->Remove(); return; } if (otherNode->GetVar("npcType").GetInt() == 1)//terry { otherNode->GetComponent<Health>()->ModifyHealth(50, -1, false); if (otherNode->GetComponent<Health>()->health_ <= 0) { otherNode->GetComponent<Health>()->ModifyHealth(100, 0, false); otherNode->GetScene()->GetComponent<TerrySpawner>()->RespawnTerry(otherNode); } Vector3 victoria = otherNode->GetPosition(); Vector3 dir = (victoria - noed->GetPosition()).Normalized(); dir.y_ = 1.0f; dir *= 10.0f; otherNode->AddComponent(new Stunned(context_, main_, 4.0f), 0, LOCAL); otherRB->ApplyImpulse(dir); /*Node* particleStartNode_ = noed->GetScene()->CreateChild(0,LOCAL); ParticleEmitter* emitterStartFX_ = particleStartNode_->CreateComponent<ParticleEmitter>(LOCAL); emitterStartFX_->SetEffect(main_->cache_->GetResource<ParticleEffect>("Particle/dustCloud.xml")); emitterStartFX_->SetViewMask(1); particleStartNode_->SetPosition(noed->GetPosition() + (Vector3::UP)); emitterStartFX_->SetEmitting(true); particleStartNode_->AddComponent(new TimedRemove(context_, main_, 2.0f), 0, LOCAL);*/ /*Node* lightNode = noed->GetScene()->CreateChild(0,LOCAL); lightNode->SetPosition(noed->GetPosition() + (Vector3::UP)); Light* light = lightNode->CreateComponent<Light>(LOCAL); light->SetBrightness(2.0f); light->SetPerVertex(true); light->SetRange(5.0f); lightNode->AddComponent(new TimedRemove(context_, main_, 0.1f), 0, LOCAL);*/ //noed->Remove(); } }