Esempio n. 1
0
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 );

}
Esempio n. 2
0
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));
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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 );
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
void AINavMeshLinkAbstract::HandleRemoveMsg( HOBJECT hSender, const CParsedMsg &crParsedMsg )
{
	AIError( "Attempting to remove AINavMeshLink \"%s\"! Disabling instead.", GetName() );
	HandleDisableMsg( hSender, crParsedMsg );
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
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;
}