void Missile::LoadFromJson(const Json::Value &jsonObj, Space *space) { DynamicBody::LoadFromJson(jsonObj, space); Propulsion::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("missile")) throw SavedGameCorruptException(); Json::Value missileObj = jsonObj["missile"]; if (!missileObj.isMember("index_for_body")) throw SavedGameCorruptException(); if (!missileObj.isMember("power")) throw SavedGameCorruptException(); if (!missileObj.isMember("armed")) throw SavedGameCorruptException(); if (!missileObj.isMember("ai_message")) throw SavedGameCorruptException(); if (!missileObj.isMember("ship_type_id")) throw SavedGameCorruptException(); m_type = &ShipType::types[missileObj["ship_type_id"].asString()]; SetModel(m_type->modelName.c_str()); m_curAICmd = 0; m_curAICmd = AICommand::LoadFromJson(missileObj); m_aiMessage = AIError(missileObj["ai_message"].asInt()); m_ownerIndex = missileObj["index_for_body"].asUInt(); m_power = missileObj["power"].asInt(); m_armed = missileObj["armed"].asBool(); Propulsion::Init( this, GetModel(), m_type->fuelTankMass, m_type->effectiveExhaustVelocity, m_type->linThrust, m_type->angThrust ); }
void Ship::Load(Serializer::Reader &rd, Space *space) { DynamicBody::Load(rd, space); // needs fixups m_angThrusters = rd.Vector3d(); m_thrusters = rd.Vector3d(); m_wheelTransition = rd.Int32(); m_wheelState = rd.Float(); m_launchLockTimeout = rd.Float(); m_testLanded = rd.Bool(); m_flightState = FlightState(rd.Int32()); m_alertState = AlertState(rd.Int32()); m_lastFiringAlert = rd.Double(); m_hyperspace.dest = SystemPath::Unserialize(rd); m_hyperspace.countdown = rd.Float(); for (int i=0; i<ShipType::GUNMOUNT_MAX; i++) { m_gunState[i] = rd.Int32(); m_gunRecharge[i] = rd.Float(); m_gunTemperature[i] = rd.Float(); } m_ecmRecharge = rd.Float(); m_shipFlavour.Load(rd); m_type = &ShipType::types[m_shipFlavour.id]; m_dockedWithPort = rd.Int32(); m_dockedWithIndex = rd.Int32(); m_equipment.InitSlotSizes(m_shipFlavour.id); m_equipment.Load(rd); Init(); m_stats.hull_mass_left = rd.Float(); // must be after Init()... m_stats.shield_mass_left = rd.Float(); if(rd.Int32()) m_curAICmd = AICommand::Load(rd); else m_curAICmd = 0; m_aiMessage = AIError(rd.Int32()); SetFuel(rd.Double()); m_stats.fuel_tank_mass_left = GetShipType().fuelTankMass * GetFuel(); m_reserveFuel = rd.Double(); UpdateStats(); // this is necessary, UpdateStats() in Ship::Init has wrong values of m_thrusterFuel after Load m_controller = 0; const ShipController::Type ctype = static_cast<ShipController::Type>(rd.Int32()); if (ctype == ShipController::PLAYER) SetController(new PlayerShipController()); else SetController(new ShipController()); m_controller->Load(rd); m_equipment.onChange.connect(sigc::mem_fun(this, &Ship::OnEquipmentChange)); }
uint32 AIRegion::EngineMessageFn(uint32 messageID, void *pv, LTFLOAT fData) { switch(messageID) { case MID_PRECREATE: { uint32 dwRet = BaseClass::EngineMessageFn(messageID, pv, fData); if ( (int)fData == PRECREATE_WORLDFILE || (int)fData == PRECREATE_STRINGPROP ) { ReadProp((ObjectCreateStruct*)pv); } return dwRet; } break; case MID_INITIALUPDATE: { // Don't eat ticks please... SetNextUpdate(m_hObject, UPDATE_NEVER); } break; case MID_ALLOBJECTSCREATED: if( m_cSearchNodes == 0 ) { AIError( "Region \"%s\" has zero seach nodes!", GetName() ); } break; case MID_SAVEOBJECT: { Save((ILTMessage_Write*)pv); } break; case MID_LOADOBJECT: { Load((ILTMessage_Read*)pv); } break; } return BaseClass::EngineMessageFn(messageID, pv, fData); }
void Alarm::CreateRegionLists() { LTVector vPos; LTFLOAT fSearchY = 64.f; g_pLTServer->GetObjectPos( m_hObject, &vPos ); AIVolume* pContainingVolume = g_pAIVolumeMgr->FindContainingVolume( LTNULL, vPos, eAxisAll, fSearchY, LTNULL ); if( pContainingVolume ) { AITRACE( AIShowAlarms, ( m_hObject, "In AIVolume: %s", pContainingVolume->GetName() ) ); } else { char szName[64]; g_pLTServer->GetObjectName( m_hObject, szName, sizeof(szName) ); AIError( "INVALID ALARM: Alarm '%s' is not in an AIVolume!", szName ); } AITRACE( AIShowAlarms, ( m_hObject, "Setting Alert Regions: %s", ::ToString( m_hstrAlertRegions ) ) ); AITRACE( AIShowAlarms, ( m_hObject, "Setting Respond Regions: %s", ::ToString( m_hstrRespondRegions ) ) ); AITRACE( AIShowAlarms, ( m_hObject, "Setting Search Regions: %s", ::ToString( m_hstrSearchRegions ) ) ); CreateRegionList( m_hstrAlertRegions, &m_lstAlertRegions ); CreateRegionList( m_hstrRespondRegions, &m_lstRespondRegions ); CreateRegionList( m_hstrSearchRegions, &m_lstSearchRegions ); }
LTBOOL CAIGoalGuard::HandleNameValuePair(const char *szName, const char *szValue) { AIASSERT(szName && szValue, m_pAI->m_hObject, "CAIGoalGuard::HandleNameValuePair: Name or value is NULL."); if( super::HandleNameValuePair(szName, szValue) ) { return LTTRUE; } if ( !_stricmp(szName, "NODE") ) { // If Goal was already active (walking to previous guard node) // Reset the goal. if( m_pGoalMgr->IsCurGoal( this ) ) { m_pAI->SetState( kState_HumanIdle ); } AINode* pNode = g_pAINodeMgr->GetNode(szValue); if( pNode ) { SetGuardNode( pNode ); RecalcImportance(); AITRACE( AIShowGoals, ( m_pAI->m_hObject, "CAIGoal%s: NODE=%s", s_aszGoalTypes[GetGoalType()], ::ToString( pNode->GetName() ) ) ); } else { AIError( "%s Cannot find node! CAIGoal%s: NODE=%s", m_pAI->GetName(), s_aszGoalTypes[GetGoalType()], szValue ); } return LTTRUE; } return LTFALSE; }
void AINavMeshLinkAbstract::HandleRemoveMsg( HOBJECT hSender, const CParsedMsg &crParsedMsg ) { AIError( "Attempting to remove AINavMeshLink \"%s\"! Disabling instead.", GetName() ); HandleDisableMsg( hSender, crParsedMsg ); }
void Ship::LoadFromJson(const Json::Value &jsonObj, Space *space) { DynamicBody::LoadFromJson(jsonObj, space); if (!jsonObj.isMember("ship")) throw SavedGameCorruptException(); Json::Value shipObj = jsonObj["ship"]; if (!shipObj.isMember("ang_thrusters")) throw SavedGameCorruptException(); if (!shipObj.isMember("thrusters")) throw SavedGameCorruptException(); if (!shipObj.isMember("wheel_transition")) throw SavedGameCorruptException(); if (!shipObj.isMember("wheel_state")) throw SavedGameCorruptException(); if (!shipObj.isMember("launch_lock_timeout")) throw SavedGameCorruptException(); if (!shipObj.isMember("test_landed")) throw SavedGameCorruptException(); if (!shipObj.isMember("flight_state")) throw SavedGameCorruptException(); if (!shipObj.isMember("alert_state")) throw SavedGameCorruptException(); if (!shipObj.isMember("last_firing_alert")) throw SavedGameCorruptException(); if (!shipObj.isMember("hyperspace_destination")) throw SavedGameCorruptException(); if (!shipObj.isMember("hyperspace_countdown")) throw SavedGameCorruptException(); if (!shipObj.isMember("guns")) throw SavedGameCorruptException(); if (!shipObj.isMember("ecm_recharge")) throw SavedGameCorruptException(); if (!shipObj.isMember("ship_type_id")) throw SavedGameCorruptException(); if (!shipObj.isMember("docked_with_port")) throw SavedGameCorruptException(); if (!shipObj.isMember("index_for_body_docked_with")) throw SavedGameCorruptException(); if (!shipObj.isMember("hull_mass_left")) throw SavedGameCorruptException(); if (!shipObj.isMember("shield_mass_left")) throw SavedGameCorruptException(); if (!shipObj.isMember("shield_cooldown")) throw SavedGameCorruptException(); if (!shipObj.isMember("ai_message")) throw SavedGameCorruptException(); if (!shipObj.isMember("thruster_fuel")) throw SavedGameCorruptException(); if (!shipObj.isMember("reserve_fuel")) throw SavedGameCorruptException(); if (!shipObj.isMember("controller_type")) throw SavedGameCorruptException(); if (!shipObj.isMember("name")) throw SavedGameCorruptException(); m_skin.LoadFromJson(shipObj); m_skin.Apply(GetModel()); // needs fixups JsonToVector(&m_angThrusters, shipObj, "ang_thrusters"); JsonToVector(&m_thrusters, shipObj, "thrusters"); m_wheelTransition = shipObj["wheel_transition"].asInt(); m_wheelState = StrToFloat(shipObj["wheel_state"].asString()); m_launchLockTimeout = StrToFloat(shipObj["launch_lock_timeout"].asString()); m_testLanded = shipObj["test_landed"].asBool(); m_flightState = static_cast<FlightState>(shipObj["flight_state"].asInt()); m_alertState = static_cast<AlertState>(shipObj["alert_state"].asInt()); Properties().Set("flightState", EnumStrings::GetString("ShipFlightState", m_flightState)); Properties().Set("alertStatus", EnumStrings::GetString("ShipAlertStatus", m_alertState)); m_lastFiringAlert = StrToDouble(shipObj["last_firing_alert"].asString()); Json::Value hyperspaceDestObj = shipObj["hyperspace_destination"]; m_hyperspace.dest = SystemPath::FromJson(hyperspaceDestObj); m_hyperspace.countdown = StrToFloat(shipObj["hyperspace_countdown"].asString()); m_hyperspace.duration = 0; Json::Value gunArray = shipObj["guns"]; if (!gunArray.isArray()) throw SavedGameCorruptException(); assert(ShipType::GUNMOUNT_MAX == gunArray.size()); for (unsigned int i = 0; i < ShipType::GUNMOUNT_MAX; i++) { Json::Value gunArrayEl = gunArray[i]; if (!gunArrayEl.isMember("state")) throw SavedGameCorruptException(); if (!gunArrayEl.isMember("recharge")) throw SavedGameCorruptException(); if (!gunArrayEl.isMember("temperature")) throw SavedGameCorruptException(); m_gun[i].state = gunArrayEl["state"].asUInt(); m_gun[i].recharge = StrToFloat(gunArrayEl["recharge"].asString()); m_gun[i].temperature = StrToFloat(gunArrayEl["temperature"].asString()); } m_ecmRecharge = StrToFloat(shipObj["ecm_recharge"].asString()); SetShipId(shipObj["ship_type_id"].asString()); // XXX handle missing thirdparty ship m_dockedWithPort = shipObj["docked_with_port"].asInt(); m_dockedWithIndex = shipObj["index_for_body_docked_with"].asUInt(); Init(); m_stats.hull_mass_left = StrToFloat(shipObj["hull_mass_left"].asString()); // must be after Init()... m_stats.shield_mass_left = StrToFloat(shipObj["shield_mass_left"].asString()); m_shieldCooldown = StrToFloat(shipObj["shield_cooldown"].asString()); m_curAICmd = 0; m_curAICmd = AICommand::LoadFromJson(shipObj); m_aiMessage = AIError(shipObj["ai_message"].asInt()); SetFuel(StrToDouble(shipObj["thruster_fuel"].asString())); m_stats.fuel_tank_mass_left = GetShipType()->fuelTankMass * GetFuel(); m_reserveFuel = StrToDouble(shipObj["reserve_fuel"].asString()); PropertyMap &p = Properties(); p.Set("hullMassLeft", m_stats.hull_mass_left); p.Set("hullPercent", 100.0f * (m_stats.hull_mass_left / float(m_type->hullMass))); p.Set("shieldMassLeft", m_stats.shield_mass_left); p.Set("fuelMassLeft", m_stats.fuel_tank_mass_left); p.PushLuaTable(); lua_State *l = Lua::manager->GetLuaState(); lua_getfield(l, -1, "equipSet"); m_equipSet = LuaRef(l, -1); lua_pop(l, 2); UpdateLuaStats(); m_controller = 0; const ShipController::Type ctype = static_cast<ShipController::Type>(shipObj["controller_type"].asInt()); if (ctype == ShipController::PLAYER) SetController(new PlayerShipController()); else SetController(new ShipController()); m_controller->LoadFromJson(shipObj); m_navLights->LoadFromJson(shipObj); m_shipName = shipObj["name"].asString(); Properties().Set("shipName", m_shipName); }
LTBOOL AISpatialNeighbor::Init(AISpatialRepresentation* pThis, AISpatialRepresentation* pNeighbor) { m_pVolume = pNeighbor; // Compute the 2d intersection of the two volumes, and compute important // things about the geometry of the connection LTVector vFrontLeft(0,0,0); LTVector vFrontRight(0,0,0); LTVector vBackLeft(0,0,0); LTVector vBackRight(0,0,0); vFrontLeft.x = Max<LTFLOAT>(pThis->GetFrontTopLeft().x, pNeighbor->GetFrontTopLeft().x); vFrontLeft.z = Min<LTFLOAT>(pThis->GetFrontTopLeft().z, pNeighbor->GetFrontTopLeft().z); vFrontRight.x = Min<LTFLOAT>(pThis->GetFrontTopRight().x, pNeighbor->GetFrontTopRight().x); vFrontRight.z = Min<LTFLOAT>(pThis->GetFrontTopRight().z, pNeighbor->GetFrontTopRight().z); vBackLeft.x = Max<LTFLOAT>(pThis->GetBackTopLeft().x, pNeighbor->GetBackTopLeft().x); vBackLeft.z = Max<LTFLOAT>(pThis->GetBackTopLeft().z, pNeighbor->GetBackTopLeft().z); vBackRight.x = Min<LTFLOAT>(pThis->GetBackTopRight().x, pNeighbor->GetBackTopRight().x); vBackRight.z = Max<LTFLOAT>(pThis->GetBackTopRight().z, pNeighbor->GetBackTopRight().z); // We know connection position (the center of the intersection) easily. m_vConnectionPos = (vFrontLeft+vFrontRight+vBackLeft+vBackRight)/4.0f; // We need y for vertical movement #define _A_b pThis->GetFrontBottomRight().y #define _A_t pThis->GetFrontTopRight().y #define _B_b pNeighbor->GetFrontBottomRight().y #define _B_t pNeighbor->GetFrontTopRight().y if ( (_A_t >= _B_t) && (_A_t >= _B_b) && (_A_b >= _B_t) && (_A_b >= _B_b) ) { m_vConnectionPos.y = _A_b; // or _B_t } else if ( (_A_t <= _B_t) && (_A_t <= _B_b) && (_A_b <= _B_t) && (_A_b <= _B_b) ) { m_vConnectionPos.y = _A_t; // or _B_b } else if ( (_A_t >= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b >= _B_b) ) { m_vConnectionPos.y = (_A_b + _B_t)/2.0f; } else if ( (_A_t <= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b <= _B_b) ) { m_vConnectionPos.y = (_A_t + _B_b)/2.0f; } else if ( (_A_t >= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b <= _B_b) ) { m_vConnectionPos.y = (_B_b + _B_t)/2.0f; } else if ( (_A_t <= _B_t) && (_A_t >= _B_b) && (_A_b <= _B_t) && (_A_b >= _B_b) ) { m_vConnectionPos.y = (_A_b + _A_t)/2.0f; } else { m_vConnectionPos.y = -float(INT_MAX); DANGER(g_pLTServer, blong); } // Find the endpoints of the line across the connection, and the vector perpendicular to this if ( pThis->InsideMasked(pNeighbor->GetFrontTopLeft(), eAxisAll) || pThis->InsideMasked(pNeighbor->GetBackTopRight(), eAxisAll) || pThis->InsideMasked(pNeighbor->GetFrontBottomLeft(), eAxisAll) || pThis->InsideMasked(pNeighbor->GetBackBottomRight(), eAxisAll) ) { m_avConnectionEndpoints[0] = vFrontRight + LTVector(0, m_vConnectionPos.y, 0); m_avConnectionEndpoints[1] = vBackLeft + LTVector(0, m_vConnectionPos.y, 0); m_vConnectionPerpDir = vFrontRight - vBackLeft; m_vConnectionDir = m_avConnectionEndpoints[1] - m_avConnectionEndpoints[0]; m_vConnectionDir.y = 0.0f; m_fConnectionLength = VEC_MAG(m_vConnectionDir); m_vConnectionDir.Normalize(); } else { m_avConnectionEndpoints[0] = vFrontLeft + LTVector(0, m_vConnectionPos.y, 0); m_avConnectionEndpoints[1] = vBackRight + LTVector(0, m_vConnectionPos.y, 0); m_vConnectionPerpDir = vFrontLeft - vBackRight; m_vConnectionDir = m_avConnectionEndpoints[1] - m_avConnectionEndpoints[0]; m_vConnectionDir.y = 0.0f; m_fConnectionLength = VEC_MAG(m_vConnectionDir); m_vConnectionDir.Normalize(); } m_vConnectionMidpoint = m_avConnectionEndpoints[0] + ( m_vConnectionDir * ( m_fConnectionLength * 0.5f ) ); LTFLOAT fTemp = m_vConnectionPerpDir[0]; m_vConnectionPerpDir[0] = m_vConnectionPerpDir[2]; m_vConnectionPerpDir[2] = fTemp; m_vConnectionPerpDir.Normalize(); // Ensure that perp dir is axis-aligned. RoundVector( m_vConnectionPerpDir ); // Make sure it points into this volume LTVector vThisCenter = (pThis->GetFrontTopLeft()+pThis->GetBackTopRight())/2.0f; LTVector vThisCenterDir = vThisCenter - m_vConnectionPos; vThisCenterDir.y = 0; vThisCenterDir.Normalize(); if ( vThisCenterDir.Dot(m_vConnectionPerpDir) < 0.0f ) { m_vConnectionPerpDir = -m_vConnectionPerpDir; } m_cGates = (uint32)(m_fConnectionLength/48.0f); // Check for invalid neighbors. if(m_cGates == 0) { AIError("Volume has Invalid Neighbor %s -> %s. Connection < 48 units!", pThis->GetName(), pNeighbor->GetName() ); return LTFALSE; } m_vecfGateOccupancy.resize(m_cGates); for ( uint32 iGate = 0 ; iGate < m_cGates ; iGate++ ) { m_vecfGateOccupancy[iGate] = 0.0f; } if( m_avConnectionEndpoints[0].z == m_avConnectionEndpoints[1].z ) { m_eVolumeConnectionType = eVolumeConnectionTypeHorizontal; if( m_pVolume->GetCenter().z < m_vConnectionPos.z ) { m_eVolumeConnectionLocation = eVolumeConnectionLocationFront; } else { m_eVolumeConnectionLocation = eVolumeConnectionLocationBack; } } else { m_eVolumeConnectionType = eVolumeConnectionTypeVertical; if( m_pVolume->GetCenter().x < m_vConnectionPos.x ) { m_eVolumeConnectionLocation = eVolumeConnectionLocationRight; } else { m_eVolumeConnectionLocation = eVolumeConnectionLocationLeft; } } //g_pLTServer->CPrint("cxn @ %f,%f,%f in %f,%f,%f : %f,%f,%f", // EXPANDVEC(m_vConnectionPos), EXPANDVEC(vThisCenter), EXPANDVEC(m_vConnectionPerpDir)); return LTTRUE; }
LTBOOL CAIMovement::Update() { // Clear any past movement. m_pAI->Stop(); m_pAI->SetCheapMovement(LTTRUE); LTVector vNewPos; LTBOOL bMove = LTTRUE; // Bound a new path to the volume. if( ( m_eState == eStateSet ) && m_bNewPathSet ) { BoundPathToVolume( m_pDestVolume ); m_bNewPathSet = LTFALSE; m_iBoundPt = 0; } EnumAnimMovement eMovementType = m_pAI->GetAnimationContext()->GetAnimMovementType(); switch( eMovementType ) { case kAM_None: // Safety mechanism to pop AI up if they fall thru the level. if( m_bMoved && ( m_pAI->GetLastVolume() ) && ( m_pAI->GetPosition().y + Max( 16.f, m_pAI->GetDims().y ) < m_pAI->GetLastVolume()->GetBackBottomLeft().y ) ) { LTVector vPos = m_pAI->GetPosition(); vPos = ConvertToDEditPos( vPos ); AIError( "AI '%s' fell thru the level at pos(%.2f %.2f %.2f )!! Popping back up.", m_pAI->GetName(), vPos.x, vPos.y, vPos.z ); LTVector vDir = m_pAI->GetPosition() - m_vLastValidVolumePos; vDir.y = 0.f; if( vDir.MagSqr() == 0.f ) { vDir = LTVector( 1.f, 0.f, 0.f ); } vDir.Normalize(); vNewPos = m_pAI->GetPosition() + vDir; vNewPos.y = m_pAI->GetLastVolume()->GetBackBottomLeft().y + m_pAI->GetDims().y; m_pAI->Move( vNewPos ); m_bMoved = LTFALSE; return LTTRUE; } // Ensure AI stays in volumes. bMove = LTFALSE; m_bMoved = LTFALSE; if( m_pAI->GetCurrentVolume() ) { m_vLastValidVolumePos = m_pAI->GetPosition(); } else if( ( !m_bIgnoreVolumes ) && m_pAI->GetLastVolume() ) { vNewPos = m_vLastValidVolumePos; bMove = LTTRUE; } break; case kAM_Set: case kAM_Walk: case kAM_Run: case kAM_JumpUp: case kAM_JumpOver: case kAM_Fall: case kAM_Climb: case kAM_Swim: case kAM_Hover: if( (m_eState != eStateSet) || (!UpdateConstantVelocity( eMovementType, &vNewPos ) ) ) { bMove = LTFALSE; } break; case kAM_Encode_NG: case kAM_Encode_G: case kAM_Encode_GB: case kAM_Encode_V: if( LTFALSE == UpdateMovementEncoding( eMovementType, &vNewPos ) ) { bMove = LTFALSE; } break; default: AIASSERT( 0, m_pAI->GetHOBJECT(), "Unknown Movement type!" ); break; } m_pAI->ClearLastHintTransform(); m_eLastMovementType = eMovementType; if( bMove && ( m_pAI->GetPosition() != vNewPos ) ) { // Make sure new position is inside an AI volume. // This NEEDS to check eAxisAll with the vertical threshold. AIVolume* pVolume = g_pAIVolumeMgr->FindContainingVolume( LTNULL, vNewPos, eAxisAll, m_pAI->GetVerticalThreshold(), m_pAI->GetLastVolume() ); if( ( pVolume && pVolume->IsVolumeEnabled() ) || m_bIgnoreVolumes ) { if( m_eState != eStateSet ) { // If an AI is playing a movement encoded animation with // gravity, and does not have a destination, do not allow // him to move over a large verticle drop. // (For example, do not let ninjas fall off roofs while // drawing a sword and taking a step). if( ( ( eMovementType == kAM_Encode_G ) || ( eMovementType == kAM_Encode_GB ) ) && pVolume && ( m_vLastValidVolumePos.y > pVolume->GetBackTopLeft().y + m_pAI->GetVerticalThreshold() ) ) { return LTFALSE; } // If an AI does not have a destination do not allow // him to move into a JumpOver volume. if( pVolume && ( pVolume->GetVolumeType() == AIVolume::kVolumeType_JumpOver ) ) { return LTFALSE; } } // Adjust the height for a parabola. if( m_bDoParabola ) { m_pAI->SetCheapMovement( LTFALSE ); vNewPos.y = m_vParabolaOrigin.y + UpdateParabola(); } // Do not allow any elevation changes in door volumes. // Keeps AI from popping onto doors. if( pVolume && pVolume->HasDoors() ) { m_pAI->SetCheapMovement(LTFALSE); } // Avoid characters if AI has a destination, and movement // is not locked, and AI is in volumes. if( ( m_eState == eStateSet ) && ( m_pDestVolume ) && ( !m_bNoDynamicPathfinding ) && ( !m_bIgnoreVolumes ) && ( !m_bMovementLocked ) && ( !m_bRotationLocked ) && ( eMovementType != kAM_Encode_V ) ) { AvoidDynamicObstacles( &vNewPos, eMovementType ); } // Move us - tells the AI where to move to m_pAI->Move(vNewPos); m_bMoved = LTTRUE; // Record last valid volume position. if( pVolume ) { m_vLastValidVolumePos = vNewPos; } // If we reached an intermediate bound point, move on // to the next one. if( ( m_eState == eStateDone ) && ( m_iBoundPt + 1 < m_cBoundPts ) ) { ++m_iBoundPt; m_vDest = m_vBoundPts[m_iBoundPt]; m_eState = eStateSet; } return LTTRUE; } // Destination is unreachable by volumes. // Put us somewhere valid. else if( m_eState == eStateSet ) { m_pAI->Move(m_vLastValidVolumePos); m_eState = eStateDone; m_bMoved = LTTRUE; } } return LTFALSE; }
int TTowers::ProblemJednotky (int Unit) { int i, ix, shot, weapon; TObject *Target; double hmax; if (Unit < 0 || Unit >= UNITS_TOP) { #ifdef DEBUG fprintf (dbgOutput, "Error: ProblemJednotky Unit = %i \n",Unit); #endif AIError (); return TRUE; } if (Units [Unit] == NULL) { #ifdef DEBUG fprintf (dbgOutput, "Error: ProblemJednotky Unit %i (=NULL) \n",Unit); #endif AIError (); return TRUE; } UnlockDraw (); // HORIZONT - nutno vyzkouset if (Units [Unit] -> Type % BADLIFE == unHorizont) { Target = NULL; do { if (DeleteKilled () == FALSE) return FALSE; MakeDangerArray (); hmax = 0; for (i = 0; i < nofGoodLife; i++) { // Pro vsechny GL ProcessMapAnim (); weapon = ChooseWeapon (Unit, GL [i]); if (weapon == -1) continue; if ((AttackStatus (Unit, weapon, GL [i], 1) > hmax) // Vyberu nejlepsi cil && (((TUnit *)Units [Unit]) -> Weapons [weapon] -> IsInRange (Units [Unit], Units [Unit] -> X, Units [Unit] -> Y , Units [GL[i]] -> X, Units [GL[i]] -> Y))) { hmax = AttackStatus (Unit, weapon, GL [i], 1); Target = Units [GL[i]]; ix = i; } } if (hmax > 0) { // Nasel jsem cil a de se strilet Units [Unit] -> Select (); shot = Units [Unit] -> Attack (Target -> X, Target -> Y); if (DeleteKilled () == FALSE) { RedrawMap (); LockDraw (); // Konec hry return FALSE; } if (Units [Unit] == NULL) { RedrawMap (); LockDraw (); // vez znicena return TRUE; } } } while ((Units [Unit] -> TimeUnits >= ((TUnit *)Units [Unit]) -> Weapons[0] -> TimeLost) && (hmax > 0)); // hraju si dokud je cas na strelbu a je na co strilet } // THOR - komplet if (Units [Unit] -> Type % BADLIFE == unThor) { Target = NULL; do { if (DeleteKilled () == FALSE) return FALSE; MakeDangerArray (); hmax = 0; for (i = 0; i < nofGoodLife; i++) { // pro vsechny GL ProcessMapAnim (); weapon = ChooseWeapon (Unit, GL [i]); if (weapon == -1) continue; if ((AttackStatus (Unit, weapon, GL [i], 1) > hmax) // vybereme nejlepsi cil && (((TThor *)Units [Unit]) -> Weapons [weapon] -> IsInRange (Units [Unit] , Units [Unit] -> X, Units [Unit] -> Y , Units [GL[i]] -> X, Units [GL[i]] -> Y))) { hmax = AttackStatus (Unit, weapon, GL [i], 1); Target = Units [GL[i]]; ix = i; } } if ((hmax <= 0) || (((TThor *)Units [Unit]) -> Weapons [0] -> Ammo <= 0)) { // zalezeme, protoze neni na co strilet, nebo dosli naboje if (((TThor *)Units [Unit]) -> IsOverground) { Units [Unit] -> Select (); ((TThor *)Units [Unit]) -> GoOverground (0); } } if (hmax > 0) { // Tady se bude strilet!!! if (((TThor *)Units [Unit]) -> IsOverground) { // je-li venku - pal! Units [Unit] -> Select (); shot = ((TThor *)Units [Unit]) -> Attack (Target -> X, Target -> Y); if (DeleteKilled () == FALSE) { LockDraw (); return FALSE; } } else { //neni-li venku - vyleze Units [Unit] -> Select (); ((TThor *)Units [Unit]) -> GoOverground (1); } } } while ((((TThor *)Units [Unit]) -> TimeUnits >= ((TThor *)Units [Unit]) -> Weapons[0] -> TimeLost) && (hmax > 0)); // hraju si dokud je cas na strelbu a je na co strilet } // PAGODA, MINOTAURUS a SPEKTRUM - komplet if ((Units [Unit] -> Type % BADLIFE == unPagoda) || (Units [Unit] -> Type % BADLIFE == unMinotaurus) || (Units [Unit] -> Type % BADLIFE == unSpektrum)) { Target = NULL; do { if (DeleteKilled () == FALSE) return FALSE; MakeDangerArray (); hmax = 0; for (i = 0; i < nofGoodLife; i++) { // Pro vsechny GL ProcessMapAnim (); weapon = ChooseWeapon (Unit, GL [i]); if (weapon == -1) continue; if ((AttackStatus (Unit, weapon, GL [i], 1) > hmax) // Vyberu nejlepsi cil && (((TUnit *)Units [Unit]) -> Weapons [weapon] -> IsInRange (Units [Unit] , Units [Unit] -> X, Units [Unit] -> Y , Units [GL[i]] -> X, Units [GL[i]] -> Y))) { hmax = AttackStatus (Unit, weapon, GL [i], 1); Target = Units [GL[i]]; ix = i; } } if (hmax > 0) { // Nasel jsem cil a de se strilet Units [Unit] -> Select (); shot = ((TUnit *)Units [Unit]) -> Attack (Target -> X, Target -> Y); if (DeleteKilled () == FALSE) { RedrawMap (); LockDraw (); return FALSE; } if (Units [Unit] == NULL) { RedrawMap (); LockDraw (); return TRUE; } } } while ((((TUnit *)Units [Unit]) -> TimeUnits >= ((TUnit *)Units [Unit]) -> Weapons[0] -> TimeLost) && (hmax > 0)); // hraju si dokud je cas na strelbu a je na co strilet } RedrawMap (); LockDraw (); return TRUE; }