/* Determine the polygon normal and project vertices onto the plane * of the polygon. */ void __gl_projectPolygon( GLUtesselator *tess ) { GLUvertex *v, *vHead = &tess->mesh->vHead; GLdouble norm[3]; GLdouble *sUnit, *tUnit; int i, computedNormal = FALSE; norm[0] = tess->normal[0]; norm[1] = tess->normal[1]; norm[2] = tess->normal[2]; if( norm[0] == 0 && norm[1] == 0 && norm[2] == 0 ) { ComputeNormal( tess, norm ); computedNormal = TRUE; } sUnit = tess->sUnit; tUnit = tess->tUnit; i = LongAxis( norm ); #if defined(FOR_TRITE_TEST_PROGRAM) || defined(TRUE_PROJECT) /* Choose the initial sUnit vector to be approximately perpendicular * to the normal. */ Normalize( norm ); sUnit[i] = 0; sUnit[(i+1)%3] = S_UNIT_X; sUnit[(i+2)%3] = S_UNIT_Y; /* Now make it exactly perpendicular */ w = Dot( sUnit, norm ); sUnit[0] -= w * norm[0]; sUnit[1] -= w * norm[1]; sUnit[2] -= w * norm[2]; Normalize( sUnit ); /* Choose tUnit so that (sUnit,tUnit,norm) form a right-handed frame */ tUnit[0] = norm[1]*sUnit[2] - norm[2]*sUnit[1]; tUnit[1] = norm[2]*sUnit[0] - norm[0]*sUnit[2]; tUnit[2] = norm[0]*sUnit[1] - norm[1]*sUnit[0]; Normalize( tUnit ); #else /* Project perpendicular to a coordinate axis -- better numerically */ sUnit[i] = 0; sUnit[(i+1)%3] = S_UNIT_X; sUnit[(i+2)%3] = S_UNIT_Y; tUnit[i] = 0; tUnit[(i+1)%3] = (norm[i] > 0) ? -S_UNIT_Y : S_UNIT_Y; tUnit[(i+2)%3] = (norm[i] > 0) ? S_UNIT_X : -S_UNIT_X; #endif /* Project the vertices onto the sweep plane */ for( v = vHead->next; v != vHead; v = v->next ) { v->s = Dot( v->coords, sUnit ); v->t = Dot( v->coords, tUnit ); } if( computedNormal ) { CheckOrientation( tess ); } }
bool Equipable::UseWeapon(Object * Target) { if (m_ItemBase->SubCategory() == 99) // TODO: check for this weapon properly { if (m_Player->FireEnergyCannon(&m_ItemInstance)) { m_ReadyTime = GetNet7TickCount() + (unsigned long)(m_ItemInstance.WeaponReload * 1000.0f); return true; } else { return false; } } if (Target && Target->ObjectType() == OT_MOB && !m_Player->ShipIndex()->GetIsIncapacitated()) { if (!CheckRange(Target)) { m_Player->SendPriorityMessageString("Out of range","MessageLine",2000,4); return false; } if (!CheckOrientation(Target)) { m_Player->SendPriorityMessageString("You must face target","MessageLine",2000,4); return false; } if (m_Player->GetEnergyValue() < m_ItemInstance.EnergyUse) { m_Player->SendPriorityMessageString("Not enough energy!","MessageLine",2000,4); return false; } // Make sure we have ammo if ((m_ItemBase->SubCategory() == 101 || m_ItemBase->SubCategory() == 102)) { if (m_AuxAmmoItem->GetItemTemplateID() < 0) { AddItemStateFlag(ITEM_STATE_NO_AMMO); AddItemStateFlag(ITEM_STATE_NO_TARGETING); AddItemStateFlag(ITEM_STATE_DISABLED); m_Player->SendPriorityMessageString("Out of ammo","MessageLine",2000,4); return false; } } //see if we are prospecting, if so, cancel prospect. m_Player->AbortProspecting(false, false); //see if we are cloaked, if so, interrupt if(m_Player->ShipIndex()->GetIsCloaked()) { m_Player->m_AbilityList[CLOAK]->InterruptSkillOnAction(SHOOTING); } /* Use the energy */ m_Player->RemoveEnergy(m_ItemInstance.EnergyUse); /*If autofire is on item, autofire */ if (m_AuxEquipItem->GetItemState() & ITEM_STATE_AUTO_FIRE_ENABLE) { AddItemStateFlag(ITEM_STATE_AUTO_FIRE); } /* Calculate ready time */ unsigned long myTime = GetNet7TickCount(); m_ReadyTime = myTime + ((unsigned long)(m_ItemInstance.WeaponReload * 1000.0f)); int AmmoShots = m_ItemBase->Fields(22)->iData; m_Target = m_Player->ShipIndex()->GetTargetGameID(); // Calculate delay long Delay = (int)(m_ItemInstance.WeaponReload/(float)AmmoShots/2.0f) * 1000; if (Delay > 400) { Delay = 400; } // Send out # of ammo used if (m_ItemBase->SubCategory() != 100) { if (AmmoShots > 1) { // Calculate delay ShootAmmo(Target->GameID()); // No delay for first one for(int x=1;x<AmmoShots;x++) { // Have it call a timer to shoot off each peice of ammo m_Player->m_SectorMgr->AddTimedCall(m_Player, B_SHOOT_AMMO,(long)(Delay * (float) x), NULL, m_Slot, Target->GameID()); } } else { // No need for timer on single ammo ShootAmmo(Target->GameID()); } } else { // No need for timer on beams ShootAmmo(Target->GameID()); } return true; } else { //LogMessage("Weapon use failed\n"); return false; } }
//You will perform your per-object physics integration, here! //I've added in a bit that will set the transform of the //graphical representation of this object, too. void PhysicsNode::Update(float msec) { if(!sleep) { if(msec > 150) msec = 16; float dt = msec * 0.01f; //FUN GOES HERE //LINEAR m_accel = calculateAcceleration(); if(doDamp) { m_linearVelocity *= DAMPING_FACTOR; m_angularVelocity *= ANG_DAMPING; } if(gravity) m_linearVelocity+= Vector3(0.0f,GRAVITY_Y,0.0f) * dt; Vector3 n_vel= m_linearVelocity + m_accel * dt; m_position = m_position + n_vel * dt; m_linearVelocity = n_vel; //ANGULAR m_angleaccel = calculateAngleAcc(); //if(m_angularVelocity.LengthSq() < MIN_VELOCITY) {m_angularVelocity.ToZero();} //Next angular velocity Vector3 n_avel = m_angularVelocity + m_angleaccel * dt; m_angularVelocity = n_avel; //Q is orientation W is angular Velocity //Qnew = Qold + (Qold * w*dt/2); m_orientation = m_orientation + (m_orientation * (n_avel * dt * 0.5f)); CheckOrientation(); m_orientation.Normalise(); m_force.ToZero(); m_torque.ToZero(); CheckMinVelocity(); } if(cv!=NULL) cv->SetPos(m_position); UpdateTransform(); }
void UpdateAI(uint32 diff) { if (!pInstance || !UpdateVictim()) return; events.Update(diff); if (me->HasUnitState(UNIT_STATE_CASTING)) return; if (me->GetVictim()) if (me->GetVictim()->GetDistance2d(me->GetHomePosition().GetPositionX(), me->GetHomePosition().GetPositionY()) > 55.0f) { DoCastVictim(SPELL_LIGHTNING_BLAST); return; } while (uint32 eventId = events.ExecuteEvent()) { switch (eventId) { case EVENT_CHILLING_BREATH: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true)) DoCast(target, SPELL_CHILLING_BREATH); events.ScheduleEvent(EVENT_CHILLING_BREATH, urand(10000, 16000)); break; case EVENT_RESET_WIND: if (_aircurrent) _aircurrent->DespawnOrUnsummon(); events.DelayEvents(1000); events.ScheduleEvent(EVENT_CALL_OF_WIND, 800); break; case EVENT_CALL_OF_WIND: _aircurrent = me->SummonCreature(NPC_AIR_CURRENT, me->GetPositionX(), me->GetPositionY(), me->GetPositionZ(), orientations[urand(0, 3)]); events.ScheduleEvent(EVENT_RESET_WIND, 18000); break; case EVENT_CHECK_FACING: if (me->GetMap()->GetPlayers().isEmpty() || !_aircurrent) break; for (Map::PlayerList::const_iterator itr = me->GetMap()->GetPlayers().begin(); itr != me->GetMap()->GetPlayers().end(); ++itr) { if (CheckOrientation(itr->GetSource()->GetOrientation(), _aircurrent->GetOrientation())) { itr->GetSource()->RemoveAurasDueToSpell(SPELL_DOWNWIND_OF_ALTAIRUS); me->AddAura(SPELL_UPWIND_OF_ALTAIRUS, itr->GetSource()); } else { itr->GetSource()->RemoveAurasDueToSpell(SPELL_UPWIND_OF_ALTAIRUS); me->AddAura(SPELL_DOWNWIND_OF_ALTAIRUS, itr->GetSource()); } } events.ScheduleEvent(EVENT_CHECK_FACING, 3000); break; } } DoMeleeAttackIfReady(); }