bool Tile::isFullGround() { ItemPtr ground = getGround(); if(ground && ground->isFullGround()) return true; return false; }
int Tile::getGroundSpeed() { int groundSpeed = 100; if(ItemPtr ground = getGround()) groundSpeed = ground->getGroundSpeed(); return groundSpeed; }
CommandX* CommandEffect::clrGroundEffect(float _duration) { m_eCommandType = E_CMD_CLR_GROUND_EFFECT; m_pkOwnerNode = getGround(); m_fDuration = _duration; return this; }
CommandX* CommandEffect::delGroundEffect(float _duration, const char* _title) { m_eCommandType = E_CMD_DEL_GROUND_EFFECT; m_pkOwnerNode = getGround(); m_strTitle = _title; m_fDuration = _duration; return this; }
CommandX* CommandEffect::addGroundEffect(float _duration, const char* _title) { m_eCommandType = E_CMD_ADD_GROUND_EFFECT; m_pkOwnerNode = getGround(); m_strTitle = _title; setDurationAni(_duration, _title); return this; }
void Contact::output(const TaskInfo& taskInfo) { if (nonZeroIntersection(taskInfo.getSampleTimeSet(), SampleTime::PerTimestep)) { Log(Model, Debug) << "Contact::output(): \"" << getName() << "\" computing ground plane below" << endl; getGround(taskInfo.getTime()); } // Transform the plane equation to the local frame. Plane lp = mMountFrame->planeFromRef(mGroundVal.plane); // Get the intersection length. real_type compressLength = lp.getDist(Vector3::zeros()); // Don't bother if we do not intersect the ground. if (compressLength < 0) { setForce(Vector6::zeros()); return; } // The velocity of the ground patch in the current frame. Vector6 groundVel(mMountFrame->rotFromRef(mGroundVal.vel.getAngular()), mMountFrame->rotFromRef(mGroundVal.vel.getLinear())); groundVel -= mMountFrame->getRefVel(); // Now get the relative velocity of the ground wrt the contact point Vector3 relVel = - groundVel.getLinear(); // The velocity perpandicular to the plane. // Positive when the contact spring is compressed, // negative when decompressed. real_type compressVel = - lp.scalarProjectToNormal(relVel); // The in plane velocity. Vector3 sVel = lp.projectToPlane(relVel); // Get the plane normal force. real_type normForce = computeNormalForce(compressLength, compressVel); // The normal force cannot get negative here. normForce = max(static_cast<real_type>(0), normForce); // Get the friction force. Vector3 fricForce = computeFrictionForce(normForce, sVel, lp.getNormal(), mGroundVal.friction); // The resulting force is the sum of both. // The minus sign is because of the direction of the surface normal. Vector3 force = fricForce - normForce*lp.getNormal(); // We don't have an angular moment. setForce(Vector6(Vector3::zeros(), force)); }
bool Tile::isWalkable(bool ignoreCreatures) { if(!getGround()) return false; for(const ThingPtr& thing : m_things) { if(thing->isNotWalkable()) return false; if(!ignoreCreatures) { if(thing->isCreature()) { CreaturePtr creature = thing->static_self_cast<Creature>(); if(!creature->isPassable() && creature->canBeSeen()) return false; } } } return true; }
void ProtocolSpectator::syncKnownCreatureSets() { const auto& casterKnownCreatures = client->getKnownCreatures(); const auto playerPos = player->getPosition(); const auto tile = player->getTile(); if (!tile || !tile->getGround()) { disconnectSpectator("A sync error has occured."); return; } sendEmptyTileOnPlayerPos(tile, playerPos); bool known; uint32_t removedKnown; for (const auto creatureID : casterKnownCreatures) { if (knownCreatureSet.find(creatureID) != knownCreatureSet.end()) { continue; } NetworkMessage msg; const auto creature = g_game.getCreatureByID(creatureID); if (creature && !creature->isRemoved()) { msg.addByte(0x6A); msg.addPosition(playerPos); msg.addByte(1); //stackpos checkCreatureAsKnown(creature->getID(), known, removedKnown); AddCreature(msg, creature, known, removedKnown); RemoveTileThing(msg, playerPos, 1); } else if (operatingSystem <= CLIENTOS_FLASH) { // otclient freeze with huge amount of creature add, but do not debug if there are unknown creatures, best solution for now :( addDummyCreature(msg, creatureID, playerPos); RemoveTileThing(msg, playerPos, 1); } writeToOutputBuffer(msg); } sendUpdateTile(tile, playerPos); }
void SegmentedShotStrategy::makeSegments(ObstacleEffect e) { // compute segments of shot until total length of segments exceeds the // lifetime of the shot. const ShotPath& path = getPath(); const float* v = path.getVelocity(); TimeKeeper startTime = path.getStartTime(); float timeLeft = path.getLifetime(); float minTime = BZDB.eval(StateDatabase::BZDB_MUZZLEFRONT) / hypotf(v[0], hypotf(v[1], v[2])); // if all shots ricochet and obstacle effect is stop, then make it ricochet if (e == Stop && World::getWorld()->allShotsRicochet()) e = Reflect; // prepare first segment float o[3], d[3]; d[0] = v[0]; d[1] = v[1]; d[2] = v[2]; // use v[2] to have jumping affect shot velocity o[0] = path.getPosition()[0]; o[1] = path.getPosition()[1]; o[2] = path.getPosition()[2]; segments.clear(); ShotPathSegment::Reason reason = ShotPathSegment::Initial; int i; const int maxSegment = 100; for (i = 0; (i < maxSegment) && (timeLeft > Epsilon); i++) { // construct ray and find the first building, teleporter, or outer wall float o2[3]; o2[0] = o[0] - minTime * d[0]; o2[1] = o[1] - minTime * d[1]; o2[2] = o[2] - minTime * d[2]; Ray r(o2, d); Ray rs(o, d); float t = timeLeft + minTime; int face; bool hitGround = getGround(r, Epsilon, t); Obstacle* building = (Obstacle*)((e != Through) ? getFirstBuilding(r, Epsilon, t) : NULL); const Teleporter* teleporter = getFirstTeleporter(r, Epsilon, t, face); t -= minTime; minTime = 0.0f; // if hit outer wall with ricochet and hit is above top of wall // then ignore hit. if (!teleporter && building && e == Reflect && building->getType() == WallObstacle::getClassName() && o[2] + t * d[2] > building->getHeight()) t = timeLeft; // construct next shot segment and add it to list TimeKeeper endTime(startTime); if (t < 0.0f) endTime += Epsilon; else endTime += t; ShotPathSegment segment(startTime, endTime, rs, reason); segments.push_back(segment); startTime = endTime; // used up this much time in segment if (t < 0.0f) timeLeft -= Epsilon; else timeLeft -= t; // check in reverse order to see what we hit first reason = ShotPathSegment::Through; if (teleporter) { // entered teleporter -- teleport it int source = World::getWorld()->getTeleporter(teleporter, face); int target = World::getWorld()->getTeleportTarget(source); if (target == randomTeleporter) { unsigned int tmp = path.getShotId() + i; tmp = (tmp * 1103515245 + 12345) >> 8; // from POSIX rand() example tmp = tmp % (2 * World::getWorld()->getTeleporters().size()); target = tmp; } int outFace; const Teleporter* outTeleporter = World::getWorld()->getTeleporter(target, outFace); o[0] += t * d[0]; o[1] += t * d[1]; o[2] += t * d[2]; teleporter->getPointWRT(*outTeleporter, face, outFace, o, d, 0.0f, o, d, NULL); reason = ShotPathSegment::Teleport; } else if (building) {
void Launchbar::output(const TaskInfo& taskInfo) { if (nonZeroIntersection(taskInfo.getSampleTimeSet(), SampleTime::PerTimestep)) { Log(Model, Debug) << "Launchbar::output(): \"" << getName() << "\" computing ground plane below" << std::endl; getGround(taskInfo.getTime()); } // The launchbar angle mAngle = computeCurrentLaunchbarAngle(); // Ok, apply the tension at the launchbar and have the holdback if (mState != Mounted && mState != Launching) { setForce(Vector6::zeros()); return; } // Query the catapult, write the result into the attached frame // ... yes this function works through sideffects ... :-/ real_type catLen; if (!computeCatFrame(taskInfo.getTime(), catLen)) { setForce(Vector6::zeros()); return; } // The catapult direction vector Vector3 catPos0 = mCatFrame->posToParent(Vector3::zeros()); Vector3 catDir = mCatFrame->rotToParent(Vector3::unit(0)); // The launchbar's tip position Vector3 lbTip(cos(mAngle)*mLength, 0, -sin(mAngle)*mLength); // The tension applied over the launchbar // allways pulls the aircraft back to the cat ... // project the launchbar tip to the catpult line ... Vector3 lbTipOnCat = catPos0 + dot(lbTip - catPos0, catDir)*catDir; Vector6 force = Vector6::zeros(); if (mState == Mounted) { force.setLinear(mLaunchForce/5*normalize(lbTipOnCat)); } else { force.setLinear(mLaunchForce*normalize(lbTipOnCat)); } if (mState == Mounted) { // the position of the holdback's deck mount Vector3 hbDeckMount = mCatFrame->posToParent(mPosOnCat*Vector3::unit(0)); // ok, for now the holback is a stiff spring, will model that different // when loop closure contranits are availble ... Vector3 hbDir = mHoldbackMount - hbDeckMount; real_type hbLen = norm(hbDir); if (mHoldbackLength < hbLen) { Vector3 hbForce = (2*mLaunchForce*(mHoldbackLength - hbLen)/hbLen)*hbDir; force += forceFrom(mHoldbackMount, hbForce); } // Some damping force, just at the position the launchbar applies its force force += mLaunchForce/2*mCatFrame->motionToParent(mCatFrame->getRelVel()); } setForce(force); }