/** * Sets a creature into the "Flee" state where he runs away from another object. * * @param env Java environment * @param self class calling this function * @param mob id of creature to access * @param target target id of creature to flee * * @return JNI_TRUE if the creature stopped, or false if there was an error */ jboolean JNICALL ScriptMethodsActionStatesNamespace::flee(JNIEnv *env, jobject self, jlong mob, jlong target, jfloat minDistance, jfloat maxDistance) { UNREF(self); if (mob == 0 || target == 0) return JNI_FALSE; CreatureObject * object = 0; AICreatureController * controller = 0; jboolean result=JNI_FALSE; if (!JavaLibrary::getObjectController(mob, object, controller)) return result; NetworkId mobId = object->getNetworkId(); NetworkId targetId(target); if(mobId == targetId) { JavaLibrary::throwInternalScriptError("ScriptMethodsActionStatesNamespace::flee - Creature is trying to flee from itself\n"); return JNI_FALSE; } if (controller->flee(NetworkId(target), minDistance, maxDistance)) result = JNI_TRUE; return result; }
bool CellPermissions::isOnList(PermissionList const &permList, CreatureObject const &who) // static { const int guildId = who.getGuildId(); // if either their name or their guild is on the list, consider them on the list for (PermissionList::const_iterator i = permList.begin(); i != permList.end(); ++i) { const std::string& name = (*i).getName(); // objectId if (name == who.getNetworkId().getValueString()) return true; // first name if (!_stricmp(name.c_str(), Unicode::wideToNarrow(who.getAssignedObjectFirstName()).c_str())) return true; // guilds if (guildId && !_strnicmp(name.c_str(), "Guild:", 6)) { std::string checkStr(Unicode::getTrim((name).substr(6))); if ( !_stricmp(checkStr.c_str(), GuildInterface::getGuildAbbrev(guildId).c_str()) || !_stricmp(checkStr.c_str(), GuildInterface::getGuildName(guildId).c_str())) return true; } } return false; }
/** * Sets a creature into the "Follow" state where he follows someone else around. * * @param env Java environment * @param self class calling this function * @param mob id of creature to access * @param target target id of creature to follow * @param minDist closest to get to creature * @param maxDist farthest to get from target * * @return JNI_TRUE if the creature stopped, or false if there was an error */ jboolean JNICALL ScriptMethodsActionStatesNamespace::followOffset(JNIEnv *env, jobject self, jlong mob, jlong target, jobject offset) { UNREF(self); if (mob == 0 || target == 0) return JNI_FALSE; CreatureObject * object = 0; AICreatureController * controller = 0; jboolean result=JNI_FALSE; if (!JavaLibrary::getObjectController(mob, object, controller)) return result; Vector location; NetworkId cell; ScriptConversion::convert(offset, location, cell, object->getPosition_w()); NetworkId mobId = object->getNetworkId(); NetworkId targetId(target); if(mobId == targetId) { JavaLibrary::throwInternalScriptError("ScriptMethodsActionStatesNamespace::followOffset - Creature is trying to follow itself\n"); return JNI_FALSE; } if (controller->follow(NetworkId(target), location)) result = JNI_TRUE; return result; }
void MoveSimManager::checkApplySimulation (CreatureObject & creature) { if (!ConfigServerGame::getMoveSimEnabled ()) return; int isMoveSim = 0; if (creature.getObjVars ().getItem (ObjVars::moveSim, isMoveSim) && isMoveSim != 0) { const NetworkId & id = creature.getNetworkId (); int isPlayer = 0; if (creature.getObjVars ().getItem (ObjVars::moveSimPlayer, isPlayer)) creature.setPlayerControlled (isPlayer != 0); Vector pos_w; if (!creature.getObjVars ().getItem (ObjVars::moveSimPosX, pos_w.x)) WARNING (true, ("MoveSimManager no x from objvar for [%s]", id.getValueString ().c_str ())); if (!creature.getObjVars ().getItem (ObjVars::moveSimPosZ, pos_w.z)) WARNING (true, ("MoveSimManager no z from objvar for [%s]", id.getValueString ().c_str ())); float radius = 0.0f; if (!creature.getObjVars ().getItem (ObjVars::moveSimRadius, radius)) WARNING (true, ("MoveSimManager no radius from objvar for [%s]", id.getValueString ().c_str ())); MoveSimController * const msc = new MoveSimController (&creature, pos_w, radius); creature.setController (msc); creature.scheduleForAlter (); if (std::find (s_moveSimCreatures.begin (), s_moveSimCreatures.end (), id) != s_moveSimCreatures.end()) s_moveSimCreatures.push_back (id); REPORT_LOG_PRINT (true, ("MoveSimManager [%ld] applied simulation to [%s]\n", GameServer::getInstance ().getProcessId (), id.getValueString ().c_str ())); } }
/** * Adds a value to a creature's mental state. * * @param env Java environment * @param self class calling this function * @param mob id of creature to access * @param mentalState mental state we are interested in * @param value value to add to the mental state * * @return true on success, false on fail */ jboolean JNICALL ScriptMethodsMentalStatesNamespace::addToMentalStateTowardClampBehavior(JNIEnv *env, jobject self, jlong mob, jlong target, jint mentalState, jfloat value, jint behavior) { UNREF(self); if (target == 0 || mentalState < 0 || mentalState >= MentalStates::NumberOfMentalStates) return JNI_FALSE; CreatureObject * creature = 0; if (!JavaLibrary::getObject(mob, creature)) return JNI_FALSE; NetworkId targetId(target); if (!targetId) return JNI_FALSE; MentalStates::Value current = creature->getMentalStateToward(targetId, static_cast<MentalStates::Enumerator>(mentalState)); LOGC(ConfigServerGame::isAiLoggingEnabled(), "debug_ai", ("ScriptMethodsMentalStates::addToMentalStateTowardClampBehavior() %s->%s state(%s) value(%.0f+%.0f) behavior(%s)", creature->getNetworkId().getValueString().c_str(), targetId.getValueString().c_str(), CreatureObject::getMentalStateString(mentalState), current, value, CreatureObject::getBehaviorString(behavior))); creature->setMentalStateTowardClampBehavior(targetId, static_cast<MentalStates::Enumerator>(mentalState), static_cast<MentalStates::Value>(current + value), static_cast<Behaviors::Enumerator>(behavior)); return JNI_TRUE; } // JavaLibrary::addToMentalState
void GroupMissionCriticalObjectsBuilderNamespace::buildGroupMissionCriticalObjects(CreatureObject const & creatureObject, CreatureObject::GroupMissionCriticalObjectSet & groupMissionCriticalObjects) { CreatureObject::MissionCriticalObjectSet const & missionCriticalObjects = creatureObject.getMissionCriticalObjects(); for (CreatureObject::MissionCriticalObjectSet::const_iterator missionCriticalObjectsIter = missionCriticalObjects.begin(); missionCriticalObjectsIter != missionCriticalObjects.end(); ++missionCriticalObjectsIter) groupMissionCriticalObjects.insert(std::make_pair(creatureObject.getNetworkId(), *missionCriticalObjectsIter)); }
bool CreatureObject::mountCreature(CreatureObject &mountObject) { //-- Ensure mounts are enabled. if (!ConfigServerGame::getMountsEnabled()) { LOG(cs_mountInfoChannelName, ("CreatureObject::mountCreature() called on rider object id=[%s] when mounts are disabled, ignoring call.", getNetworkId().getValueString().c_str())); return false; } //-- Ensure we (the rider) are not already mounted. if (getState(States::RidingMount)) { DEBUG_FATAL(true, ("mountCreature(): rider id=[%s] template=[%s] is already riding a mount.", getNetworkId().getValueString().c_str(), getObjectTemplateName())); return false; } //-- Ensure the mount is mountable. if (!mountObject.isMountable()) { DEBUG_FATAL(true, ("mountCreature(): specified mountObject id=[%s] template=[%s] is not mountable.", mountObject.getNetworkId().getValueString().c_str(), mountObject.getObjectTemplateName())); return false; } //-- Ensure both the mount and the rider are authoritative on this server. // (They should be by design of how this function gets called.) if (!isAuthoritative() || !mountObject.isAuthoritative()) { DEBUG_WARNING(true, ("mountCreature(): rider id=[%s] or mount id=[%s] was not authoritative on this server, mounting aborted.", getNetworkId().getValueString().c_str(), mountObject.getNetworkId().getValueString().c_str())); return false; } //-- Reject if the player is not in the world cell if (!isInWorldCell()) { DEBUG_WARNING(true, ("mountCreature(): rider id=[%s] is not in the world cell, mounting aborted.", getNetworkId().getValueString().c_str())); return false; } //-- Reject if the mount is not in the world cell if (!mountObject.isInWorldCell()) { DEBUG_WARNING(true, ("mountCreature(): mount id=[%s] is not in the world cell, mounting aborted.", mountObject.getNetworkId().getValueString().c_str())); return false; } // ... set the new mount-related states on the rider and mount. This is necessary // so that I can efficiently handle CreatureObject::onContainerTransferComplete, // which is called before transferItemToSlottedContainer() completes. setState(States::RidingMount, true); mountObject.setState(States::MountedCreature, true); Container::ContainerErrorCode errorCode = Container::CEC_Success; bool transferSuccess = false; // transfer into the first available slot int const maxSlots = getSaddleSeatingCapacity(&mountObject); for (int i = 0; i < maxSlots; ++i) { if (ContainerInterface::canTransferToSlot(mountObject, *this, s_riderSlotId[i], NULL, errorCode)) { transferSuccess = ContainerInterface::transferItemToSlottedContainer(mountObject, *this, s_riderSlotId[i], NULL, errorCode); if ((transferSuccess) && (errorCode == Container::CEC_Success)) { break; } } } DEBUG_FATAL(transferSuccess && (errorCode != Container::CEC_Success), ("mountCreature(): transferItemToSlottedContainer() returned success but container error code returned error %d.", static_cast<int>(errorCode))); if (!transferSuccess) { // Clear these states so that the objects are not in a funky bad state. setState(States::RidingMount, false); if (mountObject.getPrimaryMountingRider() == 0) { // clear state if empty mount mountObject.setState(States::MountedCreature, false); } return transferSuccess; } //-- Take the rider out of CollisionWorld. // @todo: add all object non-auto-delta change info to another function // that can be called via controller message to proxies, end baselines // on proxies and from here. if (isInWorld()) CollisionWorld::removeObject(this); CollisionProperty *const collisionProperty = getCollisionProperty(); if (collisionProperty) collisionProperty->setDisableCollisionWorldAddRemove(true); //-- Set the mount's AlterScheduler phase to 1 so that it gets an alter after the rider. // The rider will count on this so that the rider can update the mount's server position // prior to the mount getting altered that frame. AlterScheduler::setObjectSchedulePhase(mountObject, 1); //-- Tell rider to update movement info so it pulls walk/run speed from the mount. updateMovementInfo(); //-- Indicate transfer success. return transferSuccess; }
void MoveSimManager::start (const NetworkId & userId, int numNpcToSpawn, int numPcToSpawn, float radius, float moveSpeed) { if (!ConfigServerGame::getMoveSimEnabled ()) return; const ServerObject * const player = safe_cast<ServerObject *>(NetworkIdManager::getObjectById (userId)); if (!player) return; float halfMapWidth = 1000.0f; TerrainObject * const terrainObject = TerrainObject::getInstance (); if (terrainObject) { //- subtract a 512 meter invalid band around the edge of the map halfMapWidth = (terrainObject->getMapWidthInMeters () * 0.5f) - 512.0f; } const Vector & player_pos_w = player->getPosition_w (); const int numToSpawn = numPcToSpawn + numNpcToSpawn; const float randomRadiusArea = std::min (halfMapWidth * 2.0f, radius * 0.7f); for (int i = 0; i < numToSpawn; ++i) { Vector pos = player_pos_w; pos.x += Random::randomReal (-randomRadiusArea, randomRadiusArea); pos.z += Random::randomReal (-randomRadiusArea, randomRadiusArea); pos.x = std::min (halfMapWidth, std::max (-halfMapWidth, pos.x)); pos.z = std::min (halfMapWidth, std::max (-halfMapWidth, pos.z)); float angle = Random::randomReal (0.0f, PI * 2.0f); Transform tr; tr.setPosition_p(pos); tr.yaw_l(angle); CreatureObject * creature = 0; if (numPcToSpawn-- > 0) { creature = dynamic_cast<CreatureObject *>(ServerWorld::createNewObject(templateName_pc, tr, 0, false)); creature->setPlayerControlled (true); ServerWorld::createNewObject (ConfigServerGame::getPlayerObjectTemplate (), *creature, false); } else { creature = dynamic_cast<CreatureObject *>(ServerWorld::createNewObject(templateName_npc, tr, 0, false)); } if (!creature) return; creature->addToWorld (); const float naturalRunSpeed = safe_cast<const SharedCreatureObjectTemplate *>(creature->getSharedTemplate())->getSpeed(SharedCreatureObjectTemplate::MT_run); const float moveScale = moveSpeed / naturalRunSpeed; creature->setMovementScale (moveScale); MoveSimController * const msc = new MoveSimController (creature, player_pos_w, radius); creature->setController (msc); creature->scheduleForAlter (); setCreatureObjVars (*creature, player_pos_w, radius); s_moveSimCreatures.push_back (creature->getNetworkId ()); } }