void ShipModulesControllerSystem::drop(Entity* p_parent, unsigned int p_slot) { if (p_slot < 0) return; //Module is dropped based on damage it sustains ConnectionPointSet* connected = static_cast<ConnectionPointSet*>( p_parent->getComponent(ComponentType::ConnectionPointSet) ); Entity* toDrop = m_world->getEntity(connected->m_connectionPoints[p_slot].cpConnectedEntity); ShipModule* m = static_cast<ShipModule*>(toDrop->getComponent(ComponentType::ShipModule)); NetworkSynced* networkSynced = static_cast<NetworkSynced*>( toDrop->getComponent(ComponentType::NetworkSynced)); ConnectionPointSet* toDropConnected = static_cast<ConnectionPointSet*>( m_world->getComponentManager()->getComponent(toDrop, ComponentType::getTypeFor(ComponentType::ConnectionPointSet))); if (toDropConnected) { for (unsigned int i = 0; i < toDropConnected->m_connectionPoints.size(); i++) { int e = toDropConnected->m_connectionPoints[i].cpConnectedEntity; if (e >= 0 && m->m_parentEntity != e) drop(toDrop, i); else if (m->m_parentEntity == e) { toDropConnected->m_connectionPoints[i].cpConnectedEntity = -1; } } } //Perform the drop connected->m_connectionPoints[p_slot].cpConnectedEntity = -1; m->m_parentEntity = -1; PhysicsBody* b = static_cast<PhysicsBody*>(toDrop->getComponent(ComponentType::PhysicsBody)); PhysicsSystem* ps = static_cast<PhysicsSystem*>(m_world->getSystem(SystemType::PhysicsSystem)); Body* body = ps->getController()->getBody(b->m_id); ps->getController()->DetachBodyFromCompound((RigidBody*)body); b->setParentId(-1); // =========================== // Update module data // =========================== m->m_health = m->getMaxHealth(); m->m_value = ModuleHelper::changeModuleValueOnDetach(m->m_value); m->deactivate(); m->m_lastShipEntityWhenAttached = -1; // send status effect updates updateModuleHealthEffect(networkSynced->getNetworkOwner(), m->m_health/m->getMaxHealth()); updateModuleValueEffect(networkSynced->getNetworkOwner(), m->m_value/m->getMaxValue()); //Change particle effects on slots if (true) //m_editMode { Entity* parentShip = p_parent; ShipModule* parentModule = static_cast<ShipModule*>(parentShip->getComponent(ComponentType::ShipModule)); Entity* firstChild = toDrop; while (parentModule) { firstChild = parentShip; parentShip = m_world->getEntity(parentModule->m_parentEntity); parentModule = static_cast<ShipModule*>(parentShip->getComponent(ComponentType::ShipModule)); } int shipSlot = -1; if (firstChild == toDrop) shipSlot = p_slot; else { ConnectionPointSet* shipcps = static_cast<ConnectionPointSet*>( m_world->getComponentManager()->getComponent(parentShip, ComponentType::getTypeFor(ComponentType::ConnectionPointSet))); for (unsigned int i = 0; i < shipcps->m_connectionPoints.size(); i++) { if (shipcps->m_connectionPoints[i].cpConnectedEntity == firstChild->getIndex()) { shipSlot = i; break; } } } NetworkSynced* parentNetworkSynced = static_cast<NetworkSynced*>( p_parent->getComponent(ComponentType::NetworkSynced)); NetworkSynced* shipNetworkSynced = static_cast<NetworkSynced*>( parentShip->getComponent(ComponentType::NetworkSynced)); //Remove particle effects from the slot for (unsigned int i = 0; i < toDropConnected->m_connectionPoints.size(); i++) { if (toDropConnected->m_connectionPoints[i].cpConnectedEntity < 0) { SlotParticleEffectPacket slotPacket; slotPacket.translationOffset = AglVector3(0, 0, 0); slotPacket.forwardDirection = AglVector3(0, 0, 0); slotPacket.slot = i; slotPacket.networkIdentity = networkSynced->getNetworkIdentity(); slotPacket.active = false; slotPacket.inEditMode = m_editMode; m_server->unicastPacket(slotPacket.pack(), shipNetworkSynced->getNetworkOwner() ); } } //Add back the parent slot SlotParticleEffectPacket slotPacket; slotPacket.translationOffset = connected->m_connectionPoints[p_slot].cpTransform.GetTranslation(); slotPacket.forwardDirection = connected->m_connectionPoints[p_slot].cpTransform.GetForward(); slotPacket.slot = p_slot; slotPacket.networkIdentity = parentNetworkSynced->getNetworkIdentity(); slotPacket.active = true; slotPacket.inEditMode = m_editMode; slotPacket.moduleType = networkSynced->getNetworkType(); slotPacket.shipSlot = shipSlot; m_server->unicastPacket(slotPacket.pack(), shipNetworkSynced->getNetworkOwner() ); //Send a packet back to the client telling him how the edit sphere should be oriented ShipManagerSystem* sms = static_cast<ShipManagerSystem*>(m_world->getSystem(SystemType::ShipManagerSystem)); EditSphereUpdatePacket editSphereUpdate; AglBoundingSphere bs = sms->findEditSphere(shipNetworkSynced->getNetworkOwner()); editSphereUpdate.m_offset = bs.position; editSphereUpdate.m_radius = bs.radius; m_server->unicastPacket(editSphereUpdate.pack(), shipNetworkSynced->getNetworkOwner()); } }