//Interrupt Response to Manage our Control Feedback loop to the motors void CannonControl_PeriodicInterruptResponse(void){ // start by clearing the source of the interrupt clearPeriodicInterrupt(CANNON_CONTROL_INTERRUPT_PARAMATERS); //Calculate RPM static float currentRPM; currentRPM = CalculateRPM(); // If we're supposed to get the cannon up to speed if (Revving) { // If the cannon is at its target speed, post it if (SpeedCheck(currentRPM)) { ES_Event NewEvent; NewEvent.EventType = ES_CANNON_READY; PostMasterSM(NewEvent); Revving = false; SpeedCheckTimeoutCounter = 0; } else { // Otherwise, increment a timeout counter SpeedCheckTimeoutCounter++; if (SpeedCheckTimeoutCounter > SPEED_CHECK_LIMIT) { ES_Event NewEvent; NewEvent.EventType = ES_CANNON_READY; PostMasterSM(NewEvent); Revving = false; SpeedCheckTimeoutCounter = 0; } } } //Calculate Control Response calculateControlResponse(currentRPM); }
bool PaladinJr::ValidateMovement(Client* client, gemActor* actor, psDRMessage& currUpdate) { if (!enabled) return true; // Don't check GMs/Devs //if(client->GetSecurityLevel()) // return; // Speed check always enabled if (!SpeedCheck(client, actor, currUpdate)) return false; // DON'T USE THIS CLIENT POINTER AGAIN checkClient = false; if (target && (csGetTicks() - started > watchTime)) { checked.Add(target->GetClientNum()); target = NULL; started = csGetTicks(); } if (checked.In(client->GetClientNum())) { if (!target && csGetTicks() - started > PALADIN_MAX_SWITCH_TIME) { // We have checked every client online started = csGetTicks(); target = client; lastUpdate = currUpdate; #ifdef PALADIN_DEBUG CPrintf(CON_DEBUG, "Now checking client %d\n", target->GetClientNum()); #endif checked.DeleteAll(); } return true; } if (!target) { started = csGetTicks(); target = client; lastUpdate = currUpdate; #ifdef PALADIN_DEBUG CPrintf(CON_DEBUG, "Now checking client %d\n", target->GetClientNum()); #endif return true; } else if (target != client) return true; float yrot; iSector* sector; actor->SetDRData(lastUpdate); origPos = lastUpdate.pos; vel = lastUpdate.vel; angVel = lastUpdate.ang_vel; //if (vel.x == 0 && vel.z == 0) //{ // // Minimum speed to cope with client-side timing discrepancies // vel.x = vel.z = -1; //} // Paladin Jr needs CD enabled on the entity. //kwf client->GetActor()->pcmove->UseCD(true); actor->pcmove->SetVelocity(vel); // TODO: Assuming maximum lag, need to add some kind of lag prediction here. // Note this ignores actual DR packet time interval because we cannot rely // on it so must assume a maximal value. // // Perform the extrapolation here: actor->pcmove->UpdateDRDelta(2000); // Find the extrapolated position actor->pcmove->GetLastPosition(predictedPos,yrot,sector); #ifdef PALADIN_DEBUG CPrintf(CON_DEBUG, "Predicted: pos.x = %f, pos.y = %f, pos.z = %f\n",predictedPos.x,predictedPos.y,predictedPos.z); #endif maxmove = predictedPos-origPos; // No longer need CD checking actor->pcmove->UseCD(false); lastUpdate = currUpdate; checkClient = true; return true; }