virtual void ProcessEvent( EFlowEvent event, SActivationInfo *pActInfo ) { switch (event) { case eFE_Activate: { IActor* pActor = GetAIActor(pActInfo); if (!pActor) break; IEntity* pEnt = pActor->GetEntity(); if (!pEnt) break; HSCRIPTFUNCTION func = 0; int ret = 0; IScriptTable* pTable = pEnt->GetScriptTable(); if (!pTable) break; if (IsPortActive(pActInfo, 1) && pTable->GetValue("GrabObject", func)) { IEntity* pObj = gEnv->pEntitySystem->GetEntity( GetPortEntityId(pActInfo, 0) ); if (pObj) { IScriptTable* pObjTable = pObj->GetScriptTable(); Script::CallReturn(gEnv->pScriptSystem, func, pTable, pObjTable, ret); } ActivateOutput(pActInfo, 0, ret); } else if (IsPortActive(pActInfo, 2) && pTable->GetValue("DropObject", func)) { bool bThrow = GetPortBool(pActInfo, 3); Script::CallReturn(gEnv->pScriptSystem, func, pTable, bThrow, ret); ActivateOutput(pActInfo, 0, ret); } if (pTable->GetValue("GetGrabbedObject", func)) { ScriptHandle sH(0); Script::CallReturn(gEnv->pScriptSystem, func, pTable, sH); ActivateOutput(pActInfo, 1, EntityId(sH.n)); } if(func) gEnv->pScriptSystem->ReleaseFunc(func); break; } } }
void loop() { lBreak(); sM(); sE(); sR(); sR(); sY(); wBreak(); sC(); sH(); sR(); sI(); sS(); sT(); sM(); sA(); sS(); lBreak(); }
/** Calculates the segments joining nav polygons at a link. For example, the walk link between two polygons will contain the edge segment where they meet. Note that this function implicitly calculates whether there is a link between two polygons, since that is dependent on whether or not an appropriate edge segment can be found. @param s1 One of the 2D endpoints of the source edge in the plane @param s2 The other 2D endpoint of the source edge in the plane @param d1 One of the 2D endpoints of the destination edge in the plane @param d2 The other 2D endpoint of the destination edge in the plane @param xOverlap The horizontal overlap interval between the 2D edges in the plane */ NavMeshGenerator::LinkSegments NavMeshGenerator::calculate_link_segments(const Vector2d& s1, const Vector2d& s2, const Vector2d& d1, const Vector2d& d2, const Interval& xOverlap) const { LinkSegments linkSegments; // Calculate the line equations yS = mS.x + cS and yD = mD.x + cD. assert(fabs(s2.x - s1.x) > EPSILON); assert(fabs(d2.x - d1.x) > EPSILON); double mS = (s2.y - s1.y) / (s2.x - s1.x); double mD = (d2.y - d1.y) / (d2.x - d1.x); double cS = s1.y - mS * s1.x; double cD = d1.y - mD * d1.x; double deltaM = mD - mS; double deltaC = cD - cS; if(fabs(deltaM) > EPSILON) { // If the gradients of the source and destination edges are different, then we get // a combination of step up/step down links. // We want to find: // (a) The point walkX at which yD = yS // (b) The point stepUpX at which yD - yS = MAX_HEIGHT_DIFFERENCE (this is the furthest point at which you can step up) // (c) The point stepDownX at which yS - yD = MAX_HEIGHT_DIFFERENCE (this is the furthest point at which you can step down) // (a) deltaM . walkX + deltaC = 0 double walkX = -deltaC / deltaM; // (b) deltaM . stepUpX + deltaC = MAX_HEIGHT_DIFFERENCE double stepUpX = (m_maxHeightDifference - deltaC) / deltaM; // (c) deltaM . stepDownX + deltaC = -MAX_HEIGHT_DIFFERENCE double stepDownX = (-m_maxHeightDifference - deltaC) / deltaM; // Now construct the link intervals and clip them to the known x overlap interval. Interval stepDownInterval(std::min(walkX,stepDownX), std::max(walkX,stepDownX)); Interval stepUpInterval(std::min(walkX,stepUpX), std::max(walkX,stepUpX)); stepDownInterval = stepDownInterval.intersect(xOverlap); stepUpInterval = stepUpInterval.intersect(xOverlap); // Finally, construct the link segments from the link intervals. if(!stepDownInterval.empty()) { Vector2d sL(stepDownInterval.low(), mS*stepDownInterval.low()+cS); Vector2d sH(stepDownInterval.high(), mS*stepDownInterval.high()+cS); linkSegments.stepDownSourceToDestSegment.reset(new LineSegment2d(sL,sH)); Vector2d dL(stepDownInterval.low(), mD*stepDownInterval.low()+cD); Vector2d dH(stepDownInterval.high(), mD*stepDownInterval.high()+cD); linkSegments.stepUpDestToSourceSegment.reset(new LineSegment2d(dL,dH)); } if(!stepUpInterval.empty()) { Vector2d sL(stepUpInterval.low(), mS*stepUpInterval.low()+cS); Vector2d sH(stepUpInterval.high(), mS*stepUpInterval.high()+cS); linkSegments.stepUpSourceToDestSegment.reset(new LineSegment2d(sL,sH)); Vector2d dL(stepUpInterval.low(), mD*stepUpInterval.low()+cD); Vector2d dH(stepUpInterval.high(), mD*stepUpInterval.high()+cD); linkSegments.stepDownDestToSourceSegment.reset(new LineSegment2d(dL,dH)); } } else { // If the gradients of the source and destination edges are the same (i.e. the edges are parallel), // then we either get a step up/step down combination, or a walk link in either direction. if(fabs(deltaC) <= m_maxHeightDifference) { Vector2d s1(xOverlap.low(), mS*xOverlap.low()+cS); Vector2d s2(xOverlap.high(), mS*xOverlap.high()+cS); Vector2d d1(xOverlap.low(), mD*xOverlap.low()+cD); Vector2d d2(xOverlap.high(), mD*xOverlap.high()+cD); // There's a link between the lines, but we need to check the sign of deltaC to see which type. if(deltaC > SMALL_EPSILON) { // The destination is higher than the source: step up. linkSegments.stepUpSourceToDestSegment.reset(new LineSegment2d(s1,s2)); linkSegments.stepDownDestToSourceSegment.reset(new LineSegment2d(d1,d2)); } else if(deltaC < -SMALL_EPSILON) { // The destination is lower than the source: step down. linkSegments.stepDownSourceToDestSegment.reset(new LineSegment2d(s1,s2)); linkSegments.stepUpDestToSourceSegment.reset(new LineSegment2d(d1,d2)); } else // |deltaC| < SMALL_EPSILON { // The destination and source are at the same level: just walk across. linkSegments.walkSegment.reset(new LineSegment2d(s1,s2)); } } } return linkSegments; }