コード例 #1
0
 void LevelComponent::update(float)
 {
     if(!_loadBroadcasted)
     {
         unload();
         getRootParent()->broadcastMessage(_unloadedMessage);
         load();
         getRootParent()->broadcastMessage(_loadedMessage);
         _loadBroadcasted = true;
     }
 }
コード例 #2
0
void SceneObjectImplementation::broadcastDestroyPrivate(SceneObject* object, SceneObject* selfObject) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = getRootParent().get();

		if (grandParent != NULL) {
			grandParent->broadcastDestroyPrivate(object, selfObject);

			return;
		} else {
			return;
		}
	}

	if (zone == NULL)
		return;

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	int maxInRangeObjectCount = 0;

	if (closeobjects == NULL) {
		info("Null closeobjects vector in SceneObjectImplementation::broadcastDestroyPrivate", true);
		zone->getInRangeObjects(getPositionX(), getPositionY(), 256, &closeSceneObjects, true);

		maxInRangeObjectCount = closeSceneObjects.size();
	} else {

		CloseObjectsVector* vec = (CloseObjectsVector*) closeobjects;
		closeSceneObjects.removeAll(vec->size(), 10);

		vec->safeCopyTo(closeSceneObjects);

		maxInRangeObjectCount = closeSceneObjects.size();

	}

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno = static_cast<SceneObject*>(closeSceneObjects.get(i).get());

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount()) {
			object->sendDestroyTo(scno);
		}
	}
}
コード例 #3
0
Vector3 SceneObjectImplementation::getWorldPosition() {
	if (parent.get() == NULL)
		return getPosition();

	ManagedReference<SceneObject*> root = getRootParent().castTo<SceneObject*>();

	if (root == NULL || !root->isBuildingObject())
		return getPosition();

	float length = Math::sqrt(getPositionX() * getPositionX() + getPositionY() * getPositionY());
	float angle = root->getDirection()->getRadians() + atan2(getPositionX(), getPositionY());

	float posX = root->getPositionX() + (sin(angle) * length);
	float posY = root->getPositionY() + (cos(angle) * length);
	float posZ = root->getPositionZ() + getPositionZ();

	Vector3 position(posX, posY, posZ);

	return position;
}
コード例 #4
0
ファイル: Object.cpp プロジェクト: schizix/mmoserver
glm::vec3 Object::getWorldPosition() const
{
    const Object* root_parent = getRootParent();

    // Is this object the root? If so it's position is the world position.
    if (this == root_parent) {
        return mPosition;
    }

    // Get the length of the object's vector inside the root parent (generally a building).
    float length = glm::length(mPosition);

    // Determine the translation angle.
    float theta = glm::angle(root_parent->mDirection) - glm::atan(mPosition.x, mPosition.z);

    // Calculate and return the object's position relative to root parent's position in the world.
    return glm::vec3(
               root_parent->mPosition.x + (sin(theta) * length),
               root_parent->mPosition.y + mPosition.y,
               root_parent->mPosition.z - (cos(theta) * length)
           );
}
コード例 #5
0
int PlantObjectImplementation::handleObjectMenuSelect(CreatureObject* player, byte selectedID) {
	ManagedReference<SceneObject*> rootParent = getRootParent();
	ManagedReference<SceneObject*> parent = getParent();

	if (rootParent == NULL || parent == NULL) {
		return 0;
	}

	ManagedReference<BuildingObject*> building = cast<BuildingObject*>( rootParent.get());

	if ((building == NULL || !building->isOnAdminList(player) || !parent->isCellObject()) && selectedID >= 69 && selectedID <= 74) {
		player->sendSystemMessage("@plant_grow:must_be_in_building"); // The plant must be in a building which you administrate.
		return 0;
	}

	if (selectedID == 69) { // Add Nutrients
		sendResourceSUI(player, 1);
	} else if (selectedID == 72) { // Add Water
		sendResourceSUI(player, 2);
	} else if (selectedID == 70) { // Remove Nutrients
		nutrientLevel -= 5;

		if (nutrientLevel < 0)
			nutrientLevel = 0;

		player->sendSystemMessage("@plant_grow:remove_nutrients");
	} else if (selectedID == 73) { // Remove Water
		waterLevel -= 5;

		if (waterLevel < 0)
			waterLevel = 0;

		player->sendSystemMessage("@plant_grow:remove_water");
	} else if (selectedID == 74) { // Pick Fruit
		if (fruitCount < 1)
			return 0;

		ManagedReference<SceneObject*> inventory = player->getSlottedObject("inventory");

		if(inventory->isContainerFullRecursive()){
			player->sendSystemMessage("@plant_grow:no_inventory"); // You do not have any inventory space.
			return 0;
		}

		ZoneServer* zserv = player->getZoneServer();

		fruitCount--;

		String fruitTemplate = "object/tangible/item/plant/force_melon.iff";
		Reference<SceneObject*> fruit = zserv->createObject(fruitTemplate.hashCode(), 1);

		if(fruit == NULL) {
			return 0;
		}

		if (!inventory->transferObject(fruit, -1, false, false) ) {
			fruit->destroyObjectFromDatabase(true);
			return 0;
		}

		inventory->broadcastObject(fruit, true);
		player->sendSystemMessage("@plant_grow:pick_fruit"); // You pick a piece of fruit from the plant.

	}

	return 1;
}
コード例 #6
0
void SceneObjectImplementation::broadcastMessagesPrivate(Vector<BasePacket*>* messages, SceneObject* selfObject) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get());

		if (grandParent != NULL) {
			grandParent->broadcastMessagesPrivate(messages, selfObject);

			return;
		} else {
			while (!messages->isEmpty()) {
				delete messages->remove(0);
			}

			return;
		}
	}


	if (zone == NULL) {
		while (!messages->isEmpty()) {
			delete messages->remove(0);
		}

		return;
	}

	//getZone()->rlock();
	//Locker zoneLocker(zone);

	bool readlock = !zone->isLockedByCurrentThread();

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	int maxInRangeObjectCount = 0;

	//	zone->rlock(readlock);

	try {

		if (closeobjects == NULL) {
			info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagesPrivate", true);
			zone->getInRangeObjects(getPositionX(), getPositionY(), 192, &closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects.size();
		} else {
			maxInRangeObjectCount = closeobjects->size();

			closeSceneObjects.removeAll(maxInRangeObjectCount, 10);
			//closeSceneObjects.addAll(*closeobjects);
			closeobjects->safeCopyTo(closeSceneObjects);

			maxInRangeObjectCount = closeSceneObjects.size();

		}

	} catch (Exception& e) {

	}

	//getZone()->runlock();
	//zoneLocker.release();
	//	zone->runlock(readlock);

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get());

		if (selfObject == scno)
			continue;

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount()) {
			for (int j = 0; j < messages->size(); ++j) {
				BasePacket* msg = messages->get(j);
				scno->sendMessage(msg->clone());
			}
		}
	}

	while (!messages->isEmpty()) {
		delete messages->remove(0);
	}
}
コード例 #7
0
void SceneObjectImplementation::broadcastMessagePrivate(BasePacket* message, SceneObject* selfObject, bool lockZone) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get());

		if (grandParent != NULL) {
			grandParent->broadcastMessagePrivate(message, selfObject, lockZone);

			return;
		} else {
			delete message;

			return;
		}
	}

	if (zone == NULL) {
		delete message;

		return;
	}

	//Locker zoneLocker(zone);

	//getZone()->rlock(lockZone);

	//	bool readlock = lockZone && !zone->isLockedByCurrentThread();

	SortedVector<ManagedReference<QuadTreeEntry*> >* closeSceneObjects = NULL;
	SortedVector<ManagedReference<QuadTreeEntry*> >* closeNoneReference = NULL;
	int maxInRangeObjectCount = 0;
	bool deleteVector = true;

	try {
		//		zone->rlock(readlock);

		if (closeobjects == NULL) {
			info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagePrivate", true);
			closeSceneObjects = new SortedVector<ManagedReference<QuadTreeEntry*> >();
			zone->getInRangeObjects(getPositionX(), getPositionY(), 192, closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects->size();
			deleteVector = true;
		} else {
			//			maxInRangeObjectCount = closeobjects->size();
			//closeSceneObjects = closeobjects;

			closeNoneReference = new SortedVector<ManagedReference<QuadTreeEntry*> >(maxInRangeObjectCount, 50);


			/*			for (int i = 0; i < closeobjects->size(); ++i) {
				closeNoneReference->add(closeobjects->get(i).get());
			}
			 */

			closeobjects->safeCopyTo(*closeNoneReference);
			maxInRangeObjectCount = closeNoneReference->size();

			//closeSceneObjects.removeAll(maxInRangeObjectCount, 10);
			//closeSceneObjects.addAll(*closeobjects);
		}
		/*
		for (int i = 0; i < maxInRangeObjectCount; ++i) {
			SceneObject* scno = cast<SceneObject*>(closeSceneObjects->get(i).get());

			if (selfObject == scno)
				continue;

			ManagedReference<ZoneClientSession*> client = scno->getClient();

			if (client != NULL || scno->isVehicleObject()) {
				scno->sendMessage(message->clone());
			}

		}
		 */

		//zone->runlock(readlock);

	} catch (...) {
		//		zone->runlock(readlock);

		delete message;

		throw;

	}

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno;

		if (closeSceneObjects != NULL)
			scno  = cast<SceneObject*>(closeSceneObjects->get(i).get());
		else
			scno = cast<SceneObject*>(closeNoneReference->get(i).get());

		if (selfObject == scno)
			continue;

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if ((dynamic_cast<VehicleObject*>(scno) != NULL) || client != NULL || scno->isMount())
			scno->sendMessage(message->clone());
	}

	delete message;

	if (closeSceneObjects != NULL)
		delete closeSceneObjects;	
	else
		delete closeNoneReference;
}
コード例 #8
0
void SceneObjectImplementation::broadcastDestroyPrivate(SceneObject* object, SceneObject* selfObject) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = cast<SceneObject*>(getRootParent().get().get());

		if (grandParent != NULL) {
			grandParent->broadcastDestroyPrivate(object, selfObject);

			return;
		} else {
			return;
		}
	}

	if (zone == NULL)
		return;

	//Locker zoneLocker(zone);

	//	bool readlock = !zone->isLockedByCurrentThread();

	SortedVector<ManagedReference<QuadTreeEntry*> > closeSceneObjects;
	int maxInRangeObjectCount = 0;

	//	zone->rlock(readlock);

	try {
		if (closeobjects == NULL) {
			info("Null closeobjects vector in SceneObjectImplementation::broadcastDestroyPrivate", true);
			zone->getInRangeObjects(getPositionX(), getPositionY(), 256, &closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects.size();
		} else {

			CloseObjectsVector* vec = (CloseObjectsVector*) closeobjects;
			closeSceneObjects.removeAll(vec->size(), 10);
			//			closeSceneObjects.addAll(*closeobjects);
			vec->safeCopyTo(closeSceneObjects);

			maxInRangeObjectCount = closeSceneObjects.size();//closeobjects->size();

		}


	} catch (...) {
		//zone->runlock(readlock);

		throw;
	}

	//	zone->runlock(readlock);

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno = cast<SceneObject*>(closeSceneObjects.get(i).get());

		if (selfObject == scno)
			continue;

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount()) {
			object->sendDestroyTo(scno);
		}
	}
}
コード例 #9
0
void SceneObjectImplementation::broadcastMessagePrivate(BasePacket* message, SceneObject* selfObject, bool lockZone) {
	ZoneServer* zoneServer = getZoneServer();

	if (zoneServer != NULL && zoneServer->isServerLoading())
		return;

	if (parent.get() != NULL) {
		ManagedReference<SceneObject*> grandParent = getRootParent().get();

		if (grandParent != NULL) {
			grandParent->broadcastMessagePrivate(message, selfObject, lockZone);

			return;
		} else {
			delete message;

			return;
		}
	}

	if (zone == NULL) {
		delete message;

		return;
	}

	SortedVector<ManagedReference<QuadTreeEntry*> >* closeSceneObjects = NULL;
	SortedVector<ManagedReference<QuadTreeEntry*> >* closeNoneReference = NULL;
	int maxInRangeObjectCount = 0;
	bool deleteVector = true;

	try {
		if (closeobjects == NULL) {
			info(String::valueOf(getObjectID()) + " Null closeobjects vector in SceneObjectImplementation::broadcastMessagePrivate", true);
			closeSceneObjects = new SortedVector<ManagedReference<QuadTreeEntry*> >();
			zone->getInRangeObjects(getPositionX(), getPositionY(), 192, closeSceneObjects, true);

			maxInRangeObjectCount = closeSceneObjects->size();
			deleteVector = true;
		} else {
			closeNoneReference = new SortedVector<ManagedReference<QuadTreeEntry*> >(maxInRangeObjectCount, 50);

			closeobjects->safeCopyTo(*closeNoneReference);
			maxInRangeObjectCount = closeNoneReference->size();
		}


	} catch (Exception& e) {
		error(e.getMessage());
		e.printStackTrace();

		delete message;

		throw;
	} catch (...) {
		delete message;

		throw;
	}

	for (int i = 0; i < maxInRangeObjectCount; ++i) {
		SceneObject* scno;

		if (closeSceneObjects != NULL)
			scno = static_cast<SceneObject*>(closeSceneObjects->get(i).get());
		else
			scno = static_cast<SceneObject*>(closeNoneReference->get(i).get());

		ManagedReference<ZoneClientSession*> client = scno->getClient();

		if (scno->isVehicleObject() || client != NULL || scno->isMount())
			scno->sendMessage(message->clone());
	}

	delete message;

	if (closeSceneObjects != NULL)
		delete closeSceneObjects;	
	else
		delete closeNoneReference;
}
コード例 #10
0
int ContainerImplementation::canAddObject(SceneObject* object, int containmentType, String& errorDescription) {
	//	if (locked)
	//	return TransferErrorCode::CONTAINERLOCKED;

	if ((object->isIntangibleObject() && getContainerType() != 3)
			|| (getContainerType() == 3 && !object->isIntangibleObject())) {
		errorDescription = "@container_error_message:container07"; // You cannot put that kind of item in that kind of container.

		return TransferErrorCode::INVALIDTYPE;
	}

	if (containmentType == -1) {
		if ((gameObjectType == SceneObjectType::WEARABLECONTAINER && object->getGameObjectType() == SceneObjectType::WEARABLECONTAINER)) {
			errorDescription = "@container_error_message:container12"; // This item is too bulky to fit inside this container.

			return TransferErrorCode::CANTNESTOBJECT;
		}

		if (object->isContainerObject() && getArrangementDescriptorSize() == 0) {
			errorDescription = "@container_error_message:container12"; // This item is too bulky to fit inside this container.

			return TransferErrorCode::CANTNESTOBJECT;
		}

		// Find out how much room we need
		int objectSize;

		if (object->isContainerObject())
			objectSize = object->getContainerObjectsSize() + 1;
		else
			objectSize = 1;

		// Return if there's not enough room in the container
		if (getContainerVolumeLimit() < getCountableObjectsRecursive() + objectSize) {
			errorDescription = "@container_error_message:container03"; // This container is full.

			return TransferErrorCode::CONTAINERFULL;
		}

		ManagedReference<SceneObject*> wearableParent = getParentRecursively(SceneObjectType::WEARABLECONTAINER);
		ManagedReference<SceneObject*> playerParent = getParentRecursively(SceneObjectType::PLAYERCREATURE);

		// If there's a wearable container parent, return if it doesn't have enough room
		if (wearableParent != NULL) {
			if (wearableParent->getContainerVolumeLimit() < wearableParent->getCountableObjectsRecursive() + objectSize) {
				errorDescription = "@container_error_message:container03"; // This container is full.

				return TransferErrorCode::CONTAINERFULL;
			}

			// It has room. Check if it's not equipped and on a player.
			ManagedReference<WearableContainerObject*> wearable = cast<WearableContainerObject*>(wearableParent.get());
			if (!wearable->isEquipped() && playerParent != NULL) {
				SceneObject* inventory = playerParent->getSlottedObject("inventory");
				SceneObject* bank = playerParent->getSlottedObject("bank");
				SceneObject* parentOfWearableParent = wearable->getParent().get();

				// Return if it's in a player inventory which doesn't have room
				if (parentOfWearableParent == inventory) {
					if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) {
						errorDescription = "@error_message:inv_full"; // Your inventory is full.

						return TransferErrorCode::CONTAINERFULL;
					}
				// Return if it's in a player bank that doesn't have room
				} else if (parentOfWearableParent == bank) {
					if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) {
						errorDescription = "@container_error_message:container03"; // This container is full.

						return TransferErrorCode::CONTAINERFULL;
					}
				}
			}
		} else {
			// There's no parent that's a wearable container. Check if this is
			if (gameObjectType == SceneObjectType::WEARABLECONTAINER) {
				WearableContainerObject* pack = cast<WearableContainerObject*>(_this.getReferenceUnsafeStaticCast());

				if (pack != NULL && !pack->isEquipped()) {
				// This is a wearable container, and it's not equipped.
					if (playerParent != NULL ) {
						SceneObject* inventory = playerParent->getSlottedObject("inventory");
						SceneObject* bank = playerParent->getSlottedObject("bank");
						SceneObject* thisParent = getParent().get();

						// Return if the container is in a player inventory without room
						if (thisParent == inventory) {
							if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) {
								errorDescription = "@error_message:inv_full"; // Your inventory is full.

								return TransferErrorCode::CONTAINERFULL;
							}
						// Return if it's in a player bank that doesn't have room
						} else if (thisParent == bank) {
							if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) {
								errorDescription = "@container_error_message:container03"; // This container is full.

								return TransferErrorCode::CONTAINERFULL;
							}
						}
					}
				}
			} else {
				// This is a non-wearable container.
				if (playerParent != NULL ) {
					SceneObject* inventory = playerParent->getSlottedObject("inventory");
					SceneObject* bank = playerParent->getSlottedObject("bank");
					SceneObject* thisParent = getParent().get();

					// Return if the container is in a player inventory without room
					if (thisParent == inventory) {
						if (inventory->getContainerVolumeLimit() < inventory->getCountableObjectsRecursive() + objectSize) {
							errorDescription = "@error_message:inv_full"; // Your inventory is full.

							return TransferErrorCode::CONTAINERFULL;
						}
					// Return if it's in a player bank that doesn't have room
					} else if (thisParent == bank) {
						if (bank->getContainerVolumeLimit() < bank->getCountableObjectsRecursive() + objectSize) {
							errorDescription = "@container_error_message:container03"; // This container is full.
								return TransferErrorCode::CONTAINERFULL;
						}
					}
				}
			}
		}

		// Check if the container is in a building or factory ingredient hopper
		if (playerParent == NULL) {
			ManagedReference<SceneObject*> rootParent = getRootParent();

			if (rootParent != NULL) {
				if (rootParent->isBuildingObject()) {
					BuildingObject* building = rootParent.castTo<BuildingObject*>();

					if (!building->isStaticBuilding() && (building->getCurrentNumberOfPlayerItems() + objectSize > building->getMaximumNumberOfPlayerItems())) {
						errorDescription = "@container_error_message:container13"; // This house has too many items in it

						return TransferErrorCode::TOOMANYITEMSINHOUSE;
					}
				} else if (rootParent->isFactory()) {
					FactoryObject* factory = rootParent.castTo<FactoryObject*>();
					SceneObject* hopper = factory->getSlottedObject("ingredient_hopper");

					if (hopper->getContainerVolumeLimit() < hopper->getCountableObjectsRecursive() + objectSize) {
						errorDescription = "@container_error_message:container03"; // This container is full.
							return TransferErrorCode::CONTAINERFULL;
					}
				}
			}
		}

		ManagedReference<SceneObject*> myParent = getParent();
		ManagedReference<SceneObject*> otherParent = object->getParent();

		if (myParent != NULL && otherParent != NULL) {
			if (otherParent->isCreatureObject()) {
				AiAgent* ai = dynamic_cast<AiAgent*>(otherParent.get());

				if (ai != NULL) {
					SceneObject* creatureInventory = ai->getSlottedObject("inventory");

					if (creatureInventory != NULL) {
						uint64 lootOwnerID = creatureInventory->getContainerPermissions()->getOwnerID();

						if (lootOwnerID != myParent->getObjectID()) {
							errorDescription = "@group:no_loot_permission";

							return TransferErrorCode::NOLOOTPERMISSION;
						}
					}

				}
			}
		}

	}

	return TangibleObjectImplementation::canAddObject(object, containmentType, errorDescription);
}
コード例 #11
0
    void PlayerComponent::jump(JumpSource::Enum source, float scale)
    {
        gameplay::Vector3 const characterOriginalVelocity = _character->getCurrentVelocity();
        gameplay::Vector3 preJumpVelocity;
        bool jumpAllowed = characterOriginalVelocity.y == 0;
        float jumpHeight = (_jumpHeight * scale);
        bool resetVelocityState = true;

        switch(source)
        {
            case JumpSource::Input:
            {
                preJumpVelocity.x = _state != State::Swimming || characterOriginalVelocity.x == 0 ? characterOriginalVelocity.x :
                    (_movementSpeed * _swimSpeedScale) * (!(_flipFlags & Sprite::Flip::Horizontal) ? 1.0f : -1.0f);
#ifndef _FINAL
                if(getConfig()->getBool("multi_jump"))
                {
                    if(characterOriginalVelocity.y < 0)
                    {
                        jumpHeight += -characterOriginalVelocity.y / 2.0f;
                    }

                    resetVelocityState = false;
                    jumpAllowed = true;
                }
#endif
                break;
            }
            case JumpSource::EnemyCollision:
            {
                preJumpVelocity.x = characterOriginalVelocity.x;
                float const verticalModifier = 1.5f;
                jumpHeight *= verticalModifier;
                jumpAllowed = true;
                break;
            }
            default:
                GAME_ASSERTFAIL("Unhandled JumpSource %d", source);
                break;
        }

        if(jumpAllowed)
        {
            if(_kinematicNode && _character->getCurrentVelocity().isZero())
            {
                gameplay::PhysicsRigidBody * kinematic = static_cast<gameplay::PhysicsRigidBody *>(_kinematicNode->getCollisionObject());
                preJumpVelocity.y = kinematic->getLinearVelocity().y;
            }

            _state = State::Jumping;
            _character->setPhysicsEnabled(true);

            if(resetVelocityState)
            {
                _character->resetVelocityState();
            }

            _character->setVelocity(preJumpVelocity);
            _character->jump(jumpHeight, !resetVelocityState);
            if(source != JumpSource::EnemyCollision)
            {
                getRootParent()->broadcastMessage(_jumpMessage);
            }
            _verticalMovementScale = 0.0f;
        }
    }