Exemplo n.º 1
0
void CBaseStreamControl::NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart )
{
    CAutoLock lck(&m_CritSec);

    // or we will get confused
    if (m_FilterState == new_state)
    return;

    switch (new_state)
    {
        case State_Stopped:

            DbgLog((LOG_TRACE,2,TEXT("Filter is STOPPED")));

        // execute any pending starts and stops in the right order,
        // to make sure all notifications get sent, and we end up
        // in the right state to begin next time (??? why not?)

        if (m_tStartTime != MAX_TIME && m_tStopTime == MAX_TIME) {
        ExecuteStart();
        } else if (m_tStopTime != MAX_TIME && m_tStartTime == MAX_TIME) {
        ExecuteStop();
        } else if (m_tStopTime != MAX_TIME && m_tStartTime != MAX_TIME) {
        if (m_tStartTime <= m_tStopTime) {
            ExecuteStart();
            ExecuteStop();
        } else {
            ExecuteStop();
            ExecuteStart();
        }
        }
        // always start off flowing when the graph starts streaming
        // unless told otherwise
        m_StreamState = STREAM_FLOWING;
            m_FilterState = new_state;
            break;

        case State_Running:

            DbgLog((LOG_TRACE,2,TEXT("Filter is RUNNING")));

            m_tRunStart = tStart;
            // fall-through

        default: // case State_Paused:
            m_FilterState = new_state;
    }
    // unblock!
    m_StreamEvent.Set();
}
Exemplo n.º 2
0
enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckSampleTimes
( __in const REFERENCE_TIME * pSampleStart, __in const REFERENCE_TIME * pSampleStop )
{
    CAutoLock lck(&m_CritSec);

    ASSERT(!m_bIsFlushing);
    ASSERT(pSampleStart && pSampleStop);

    // Don't ask me how I came up with the code below to handle all 19 cases
    // - DannyMi

    if (m_tStopTime >= *pSampleStart)
    {
        if (m_tStartTime >= *pSampleStop)
        return m_StreamState;		// cases  8 11 12 15 17 18 19
    if (m_tStopTime < m_tStartTime)
        ExecuteStop();			// case 10
    ExecuteStart();                         // cases 3 5 7 9 13 14
    return m_StreamState;
    }

    if (m_tStartTime >= *pSampleStop)
    {
        ExecuteStop();                          // cases 6 16
        return m_StreamState;
    }

    if (m_tStartTime <= m_tStopTime)
    {
    ExecuteStart();
    ExecuteStop();
        return m_StreamState;		// case 1
    }
    else
    {
    ExecuteStop();
    ExecuteStart();
        return m_StreamState;		// cases 2 4
    }
}
Exemplo n.º 3
0
void CCommandAI::SlowUpdate()
{
	if(gs->paused) // Commands issued may invoke SlowUpdate when paused
		return;
	if (commandQue.empty()) {
		return;
	}

	Command& c = commandQue.front();

	switch (c.GetID()) {
		case CMD_WAIT: {
			return;
		}
		case CMD_SELFD: {
			if ((owner->selfDCountdown != 0) || !owner->unitDef->canSelfD) {
				owner->selfDCountdown = 0;
			} else {
				owner->selfDCountdown = (owner->unitDef->selfDCountdown * 2) + 1;
			}
			FinishCommand();
			return;
		}
		case CMD_STOP: {
			ExecuteStop(c);
			return;
		}
		case CMD_ATTACK: {
			ExecuteAttack(c);
			return;
		}
		case CMD_MANUALFIRE: {
			ExecuteAttack(c);
			return;
		}
	}

	if (ExecuteStateCommand(c)) {
		FinishCommand();
		return;
	}

	if (luaRules && !luaRules->CommandFallback(owner, c)) {
		return; // luaRules wants the command to stay at the front
	}

	FinishCommand();
}
Exemplo n.º 4
0
void CCommandAI::SlowUpdate()
{
	if (commandQue.empty()) {
		return;
	}

	Command& c = commandQue.front();

	switch (c.id) {
		case CMD_WAIT: {
			return;
		}
		case CMD_SELFD: {
			if ((owner->selfDCountdown != 0) || !owner->unitDef->canSelfD) {
				owner->selfDCountdown = 0;
			} else {
				owner->selfDCountdown = (owner->unitDef->selfDCountdown * 2) + 1;
			}
			FinishCommand();
			return;
		}
		case CMD_STOP: {
			ExecuteStop(c);
			return;
		}
		case CMD_ATTACK: {
			ExecuteAttack(c);
			return;
		}
		case CMD_DGUN: {
			ExecuteDGun(c);
			return;
		}
	}

	if (ExecuteStateCommand(c)) {
		FinishCommand();
		return;
	}

	if (luaRules && !luaRules->CommandFallback(owner, c)) {
		return; // luaRules wants the command to stay at the front
	}

	FinishCommand();
}
Exemplo n.º 5
0
void CFactoryCAI::RemoveBuildCommand(CCommandQueue::iterator& it)
{
	Command& cmd = *it;
	map<int, BuildOption>::iterator boi = buildOptions.find(cmd.id);
	if (boi != buildOptions.end()) {
		boi->second.numQued--;
		UpdateIconName(cmd.id, boi->second);
	}
	if (!commandQue.empty() && (it == commandQue.begin())) {
		ExecuteStop(cmd);
		return;
	}
	if (cmd.id < 0) {
		cmd.id = CMD_STOP;
		cmd.tag = 0;
	}
}
Exemplo n.º 6
0
void CFactoryCAI::SlowUpdate()
{
	// Commands issued may invoke SlowUpdate when paused
	if (gs->paused)
		return;
	if (commandQue.empty() || owner->beingBuilt)
		return;

	CFactory* fac = static_cast<CFactory*>(owner);

	while (!commandQue.empty()) {
		Command& c = commandQue.front();

		const size_t oldQueueSize = commandQue.size();
		const std::map<int, BuildOption>::iterator buildOptIt = buildOptions.find(c.GetID());

		if (buildOptIt != buildOptions.end()) {
			// build-order
			switch (fac->QueueBuild(unitDefHandler->GetUnitDefByID(-c.GetID()), c, &FactoryFinishBuildCallBack)) {
				case CFactory::FACTORY_SKIP_BUILD_ORDER: {
					// order rejected and we want to skip it permanently
					DecreaseQueueCount(c, buildOptions[c.GetID()], false);
				} break;
			}
		} else {
			// regular order (move/wait/etc)
			switch (c.GetID()) {
				case CMD_STOP: {
					ExecuteStop(c);
				} break;
				default: {
					CCommandAI::SlowUpdate();
					break;
				}
			}
		}

		// exit if no command was consumed
		if (oldQueueSize == commandQue.size())
			break;
	}
}
Exemplo n.º 7
0
bool CFactoryCAI::RemoveBuildCommand(CCommandQueue::iterator& it)
{
	Command& cmd = *it;
	map<int, BuildOption>::iterator boi = buildOptions.find(cmd.GetID());
	if (boi != buildOptions.end()) {
		boi->second.numQued--;
		UpdateIconName(cmd.GetID(), boi->second);
	}
	if (!commandQue.empty() && (it == commandQue.begin())) {
		ExecuteStop(cmd);
		return true;
	}

	if (cmd.GetID() < 0) {
		// build command, convert into a stop command
		cmd = Command(CMD_STOP);
	}

	return false;
}
Exemplo n.º 8
0
void CBuilderCAI::SlowUpdate()
{
	if(gs->paused) // Commands issued may invoke SlowUpdate when paused
		return;

	if (commandQue.empty()) {
		CMobileCAI::SlowUpdate();
		return;
	}

	if (owner->beingBuilt || owner->stunned) {
		return;
	}

	Command& c = commandQue.front();

	if (OutOfImmobileRange(c)) {
		FinishCommand();
		return;
	}

	switch (c.GetID()) {
		case CMD_STOP:      { ExecuteStop(c);      return; }
		case CMD_REPAIR:    { ExecuteRepair(c);    return; }
		case CMD_CAPTURE:   { ExecuteCapture(c);   return; }
		case CMD_GUARD:     { ExecuteGuard(c);     return; }
		case CMD_RECLAIM:   { ExecuteReclaim(c);   return; }
		case CMD_RESURRECT: { ExecuteResurrect(c); return; }
		case CMD_PATROL:    { ExecutePatrol(c);    return; }
		case CMD_FIGHT:     { ExecuteFight(c);     return; }
		case CMD_RESTORE:   { ExecuteRestore(c);   return; }
		default: {
			if (c.GetID() < 0) {
				ExecuteBuildCmd(c);
			} else {
				CMobileCAI::SlowUpdate();
			}
			return;
		}
	}
}
Exemplo n.º 9
0
void CBuilderCAI::SlowUpdate()
{
	if(commandQue.empty()){
		CMobileCAI::SlowUpdate();
		return;
	}

	Command& c=commandQue.front();
	CBuilder* fac=(CBuilder*)owner;
	float3 curPos=owner->pos;

	map<int,string>::iterator boi;
	if((boi=buildOptions.find(c.id))!=buildOptions.end()){
		const UnitDef* ud = unitDefHandler->GetUnitByName(boi->second);
		const float radius = GetUnitRadius(ud, c.id);
		if (inCommand) {
			if (building) {
				if (build.pos.distance2D(fac->pos) > fac->buildDistance+radius-8.0f) {
					owner->moveType->StartMoving(build.pos, fac->buildDistance*0.5f+radius);
				} else {
					StopMove();
					owner->moveType->KeepPointingTo(build.pos, (fac->buildDistance+radius)*0.6f, false);	//needed since above startmoving cancels this
				}
				if(!fac->curBuild && !fac->terraforming){
					building=false;
					StopMove();				//cancel the effect of KeepPointingTo
					FinishCommand();
				}
			} else {
				build.Parse(c);
				const float dist = build.pos.distance2D(fac->pos);
				if ((dist < (fac->buildDistance * 0.6f + radius)) ||
				    (!owner->unitDef->canmove && (dist <= (fac->buildDistance+radius-8.0f)))) {
					StopMove();
					if(uh->unitsType[owner->team][build.def->id]>=build.def->maxThisUnit){ //unit restricted
						ENTER_MIXED;
						if(owner->team == gu->myTeam){
							logOutput.Print("%s: Build failed, unit type limit reached",owner->unitDef->humanName.c_str());
							logOutput.SetLastMsgPos(owner->pos);
						}
						ENTER_SYNCED;
						FinishCommand();
					}
					else if(uh->maxUnits>(int)gs->Team(owner->team)->units.size()){ //max unitlimit reached
						buildRetries++;
						owner->moveType->KeepPointingTo(build.pos, fac->buildDistance*0.7f+radius, false);
						if(fac->StartBuild(build) || buildRetries>20){
							building=true;
						} else {
							ENTER_MIXED;
							if(owner->team==gu->myTeam && !(buildRetries&7)){
								logOutput.Print("%s: Build pos blocked",owner->unitDef->humanName.c_str());
								logOutput.SetLastMsgPos(owner->pos);
							}
							ENTER_SYNCED;
							helper->BuggerOff(build.pos,radius);
							NonMoving();
						}
					}
				} else {
					if(owner->moveType->progressState==CMoveType::Failed){
						if(++buildRetries>5){
							StopMove();
							FinishCommand();
						}
					}
					SetGoal(build.pos,owner->pos, fac->buildDistance*0.4f+radius);
				}
			}
		} else {		//!inCommand
			BuildInfo bi;
			bi.pos.x=floor(c.params[0]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
			bi.pos.z=floor(c.params[2]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
			bi.pos.y=c.params[1];
			CFeature* f=0;
			if (c.params.size()==4)
				bi.buildFacing = int(c.params[3]);
			bi.def = unitDefHandler->GetUnitByName(boi->second);

			uh->TestUnitBuildSquare(bi,f,owner->allyteam);
			if(f){
				if (!owner->unitDef->canReclaim || !f->def->destructable) {
					// FIXME user shouldn't be able to queue buildings on top of features
					// in the first place (in this case).
					StopMove();
					FinishCommand();
				} else {
					Command c2;
					c2.id=CMD_RECLAIM;
					c2.options=0;
					c2.params.push_back(f->id+MAX_UNITS);
					commandQue.push_front(c2);
					SlowUpdate(); //this assumes that the reclaim command can never return directly without having reclaimed the target
				}
			} else {
				inCommand=true;
				SlowUpdate();
			}
		}
		return;
	}

	switch (c.id) {
		case CMD_STOP:      { ExecuteStop(c);      return; }
		case CMD_REPAIR:    { ExecuteRepair(c);    return; }
		case CMD_CAPTURE:   { ExecuteCapture(c);   return; }
		case CMD_GUARD:     { ExecuteGuard(c);     return; }
		case CMD_RECLAIM:   { ExecuteReclaim(c);   return; }
		case CMD_RESURRECT: { ExecuteResurrect(c); return; }
		case CMD_PATROL:    { ExecutePatrol(c);    return; }
		case CMD_FIGHT:     { ExecuteFight(c);     return; }
		case CMD_RESTORE:   { ExecuteRestore(c);   return; }
		default: {
			CMobileCAI::SlowUpdate();
			return;
		}
	}
}
Exemplo n.º 10
0
bool CTAAirMoveType::Update()
{
    float3& pos = owner->pos;
    float3& speed = owner->speed;

    // This is only set to false after the plane has finished constructing
    if (useHeading) {
        useHeading = false;
        SetState(AIRCRAFT_TAKEOFF);
    }

    if (owner->stunned || owner->beingBuilt) {
        wantedSpeed = ZeroVector;
        wantToStop = true;
    }

    // Allow us to stop if wanted
    if (wantToStop) {
        ExecuteStop();
    }

    const float3 lastSpeed = speed;

    if (owner->fpsControlPlayer != NULL) {
        SetState(AIRCRAFT_FLYING);

        const FPSUnitController& con = owner->fpsControlPlayer->fpsController;

        const float3 forward = con.viewDir;
        const float3 right = forward.cross(UpVector);
        const float3 nextPos = pos + speed;

        float3 flatForward = forward;
        flatForward.y = 0.0f;
        flatForward.Normalize();

        wantedSpeed = ZeroVector;

        if (con.forward) wantedSpeed += flatForward;
        if (con.back   ) wantedSpeed -= flatForward;
        if (con.right  ) wantedSpeed += right;
        if (con.left   ) wantedSpeed -= right;

        wantedSpeed.Normalize();
        wantedSpeed *= maxSpeed;

        if (!nextPos.IsInBounds()) {
            speed = ZeroVector;
        }

        UpdateAirPhysics();
        wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
    } else {

        if (reservedPad) {
            CUnit* unit = reservedPad->GetUnit();
            const float3 relPos = unit->script->GetPiecePos(reservedPad->GetPiece());
            const float3 pos = unit->pos + unit->frontdir * relPos.z
                               + unit->updir * relPos.y + unit->rightdir * relPos.x;

            if (padStatus == 0) {
                if (aircraftState != AIRCRAFT_FLYING && aircraftState != AIRCRAFT_TAKEOFF)
                    SetState(AIRCRAFT_FLYING);

                goalPos = pos;

                if (pos.SqDistance2D(owner->pos) < 400*400) {
                    padStatus = 1;
                }
            } else if (padStatus == 1) {
                if (aircraftState != AIRCRAFT_FLYING) {
                    SetState(AIRCRAFT_FLYING);
                }
                flyState = FLY_LANDING;

                goalPos = pos;
                reservedLandingPos = pos;
                wantedHeight = pos.y - ground->GetHeightAboveWater(pos.x, pos.z);

                if (owner->pos.SqDistance(pos) < 9 || aircraftState == AIRCRAFT_LANDED) {
                    padStatus = 2;
                }
            } else {
                if (aircraftState != AIRCRAFT_LANDED)
                    SetState(AIRCRAFT_LANDED);

                owner->pos = pos;
                owner->AddBuildPower(unit->unitDef->buildSpeed / 30, unit);
                owner->currentFuel = std::min(owner->unitDef->maxFuel,
                                              owner->currentFuel + (owner->unitDef->maxFuel
                                                      / (GAME_SPEED * owner->unitDef->refuelTime)));

                if (owner->health >= owner->maxHealth - 1
                        && owner->currentFuel >= owner->unitDef->maxFuel) {
                    airBaseHandler->LeaveLandingPad(reservedPad);
                    reservedPad = NULL;
                    padStatus = 0;
                    goalPos = oldGoalPos;
                    SetState(AIRCRAFT_TAKEOFF);
                }
            }
        }

        // Main state handling
        switch (aircraftState) {
        case AIRCRAFT_LANDED:
            UpdateLanded();
            break;
        case AIRCRAFT_TAKEOFF:
            UpdateTakeoff();
            break;
        case AIRCRAFT_FLYING:
            UpdateFlying();
            break;
        case AIRCRAFT_LANDING:
            UpdateLanding();
            break;
        case AIRCRAFT_HOVERING:
            UpdateHovering();
            break;
        case AIRCRAFT_CRASHING:
            break;
        }
    }


    // Banking requires deltaSpeed.y = 0
    deltaSpeed = speed - lastSpeed;
    deltaSpeed.y = 0.0f;

    // Turn and bank and move; update dirs
    UpdateHeading();
    UpdateBanking(aircraftState == AIRCRAFT_HOVERING);

    owner->UpdateMidPos();
    return (HandleCollisions());
}
Exemplo n.º 11
0
bool CHoverAirMoveType::Update()
{
	const float3 lastPos = owner->pos;
	const float4 lastSpd = owner->speed;

	AAirMoveType::Update();

	if ((owner->IsStunned() && !owner->IsCrashing()) || owner->beingBuilt) {
		wantedSpeed = ZeroVector;

		UpdateAirPhysics();
		return (HandleCollisions(collide && !owner->beingBuilt && (padStatus == PAD_STATUS_FLYING) && (aircraftState != AIRCRAFT_TAKEOFF)));
	}

	// allow us to stop if wanted (changes aircraft state)
	if (wantToStop)
		ExecuteStop();

	if (aircraftState != AIRCRAFT_CRASHING) {
		if (owner->UnderFirstPersonControl()) {
			SetState(AIRCRAFT_FLYING);

			const FPSUnitController& con = owner->fpsControlPlayer->fpsController;

			const float3 forward = con.viewDir;
			const float3 right = forward.cross(UpVector);
			const float3 nextPos = lastPos + owner->speed;

			float3 flatForward = forward;
			flatForward.Normalize2D();

			wantedSpeed = ZeroVector;

			if (con.forward) wantedSpeed += flatForward;
			if (con.back   ) wantedSpeed -= flatForward;
			if (con.right  ) wantedSpeed += right;
			if (con.left   ) wantedSpeed -= right;

			wantedSpeed.Normalize();
			wantedSpeed *= maxSpeed;

			if (!nextPos.IsInBounds()) {
				owner->SetVelocityAndSpeed(ZeroVector);
			}

			UpdateAirPhysics();
			wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
		}

		if (reservedPad != NULL) {
			MoveToRepairPad();

			if (padStatus >= PAD_STATUS_LANDING) {
				flyState = FLY_LANDING;
			}
		}
	}

	switch (aircraftState) {
		case AIRCRAFT_LANDED:
			UpdateLanded();
			break;
		case AIRCRAFT_TAKEOFF:
			UpdateTakeoff();
			break;
		case AIRCRAFT_FLYING:
			UpdateFlying();
			break;
		case AIRCRAFT_LANDING:
			UpdateLanding();
			break;
		case AIRCRAFT_HOVERING:
			UpdateHovering();
			break;
		case AIRCRAFT_CRASHING: {
			UpdateAirPhysics();

			if ((CGround::GetHeightAboveWater(owner->pos.x, owner->pos.z) + 5.0f + owner->radius) > owner->pos.y) {
				owner->ClearPhysicalStateBit(CSolidObject::PSTATE_BIT_CRASHING);
				owner->KillUnit(NULL, true, false);
			} else {
				#define SPIN_DIR(o) ((o->id & 1) * 2 - 1)
				wantedHeading = GetHeadingFromVector(owner->rightdir.x * SPIN_DIR(owner), owner->rightdir.z * SPIN_DIR(owner));
				wantedHeight = 0.0f;
				#undef SPIN_DIR
			}

			new CSmokeProjectile(owner, owner->midPos, gs->randVector() * 0.08f, 100 + gs->randFloat() * 50, 5, 0.2f, 0.4f);
		} break;
	}

	if (lastSpd == ZeroVector && owner->speed != ZeroVector) { owner->script->StartMoving(false); }
	if (lastSpd != ZeroVector && owner->speed == ZeroVector) { owner->script->StopMoving(); }

	// Banking requires deltaSpeed.y = 0
	deltaSpeed = owner->speed - lastSpd;
	deltaSpeed.y = 0.0f;

	// Turn and bank and move; update dirs
	UpdateHeading();
	UpdateBanking(aircraftState == AIRCRAFT_HOVERING);

	return (HandleCollisions(collide && !owner->beingBuilt && (padStatus == PAD_STATUS_FLYING) && (aircraftState != AIRCRAFT_TAKEOFF)));
}
Exemplo n.º 12
0
void CHoverAirMoveType::UpdateFlying()
{
	const float3& pos = owner->pos;
	// const float4& spd = owner->speed;

	// Direction to where we would like to be
	float3 goalVec = goalPos - pos;

	owner->restTime = 0;

	// don't change direction for waypoints we just flew over and missed slightly
	if (flyState != FLY_LANDING && owner->commandAI->HasMoreMoveCommands()) {
		float3 goalDir = goalVec;

		if ((goalDir != ZeroVector) && (goalVec.dot(goalDir.UnsafeANormalize()) < 1.0f)) {
			goalVec = owner->frontdir;
		}
	}

	const float goalDistSq2D = goalVec.SqLength2D();
	const float gHeight = UseSmoothMesh()?
		std::max(smoothGround->GetHeight(pos.x, pos.z), CGround::GetApproximateHeight(pos.x, pos.z)):
		CGround::GetHeightAboveWater(pos.x, pos.z);

	const bool closeToGoal = (flyState == FLY_ATTACKING)?
		(goalDistSq2D < (             400.0f)):
		(goalDistSq2D < (maxDrift * maxDrift)) && (math::fabs(gHeight + wantedHeight - pos.y) < maxDrift);

	if (closeToGoal) {
		switch (flyState) {
			case FLY_CRUISING: {
				// NOTE: should CMD_LOAD_ONTO be here?
				const bool isTransporter = (dynamic_cast<CTransportUnit*>(owner) != NULL);
				const bool hasLoadCmds = isTransporter &&
					!owner->commandAI->commandQue.empty() &&
					(owner->commandAI->commandQue.front().GetID() == CMD_LOAD_ONTO ||
					 owner->commandAI->commandQue.front().GetID() == CMD_LOAD_UNITS);
				// [?] transport aircraft need some time to detect that they can pickup
				const bool canLoad = isTransporter && (++waitCounter < ((GAME_SPEED << 1) - 5));
				const bool isBusy = IsUnitBusy(owner);

				if (!CanLand(isBusy) || (canLoad && hasLoadCmds)) {
					wantedSpeed = ZeroVector;

					if (isTransporter) {
						if (waitCounter > (GAME_SPEED << 1)) {
							wantedHeight = orgWantedHeight;
						}

						SetState(AIRCRAFT_HOVERING);
						return;
					} else {
						if (!isBusy) {
							wantToStop = true;

							// NOTE:
							//   this is not useful, next frame UpdateFlying()
							//   will change it to _LANDING because wantToStop
							//   is now true
							SetState(AIRCRAFT_HOVERING);
							return;
						}
					}
				} else {
					wantedHeight = orgWantedHeight;

					SetState(AIRCRAFT_LANDING);
					return;
				}
			} break;

			case FLY_CIRCLING: {
				if ((++waitCounter) > ((GAME_SPEED * 3) + 10)) {
					if (airStrafe) {
						float3 relPos = pos - circlingPos;

						if (relPos.x < 0.0001f && relPos.x > -0.0001f) {
							relPos.x = 0.0001f;
						}

						static CMatrix44f rot(0.0f, fastmath::PI / 4.0f, 0.0f);

						// make sure the point is on the circle, go there in a straight line
						goalPos = circlingPos + (rot.Mul(relPos.Normalize2D()) * goalDistance);
					}
					waitCounter = 0;
				}
			} break;

			case FLY_ATTACKING: {
				if (airStrafe) {
					float3 relPos = pos - circlingPos;

					if (relPos.x < 0.0001f && relPos.x > -0.0001f) {
						relPos.x = 0.0001f;
					}

					CMatrix44f rot;

					if (gs->randFloat() > 0.5f) {
						rot.RotateY(0.6f + gs->randFloat() * 0.6f);
					} else {
						rot.RotateY(-(0.6f + gs->randFloat() * 0.6f));
					}

					// Go there in a straight line
					goalPos = circlingPos + (rot.Mul(relPos.Normalize2D()) * goalDistance);
				}
			} break;

			case FLY_LANDING: {
			} break;
		}
	}

	// not "close" to goal yet, so keep going
	// use 2D math since goal is on the ground
	// but we are not
	goalVec.y = 0.0f;

	// if we are close to our goal, we should
	// adjust speed st. we never overshoot it
	// (by respecting current brake-distance)
	const float curSpeed = owner->speed.Length2D();
	const float brakeDist = (0.5f * curSpeed * curSpeed) / decRate;
	const float goalDist = goalVec.Length() + 0.1f;
	const float goalSpeed =
		(maxSpeed          ) * (goalDist >  brakeDist) +
		(curSpeed - decRate) * (goalDist <= brakeDist);

	if (goalDist > goalSpeed) {
		// update our velocity and heading so long as goal is still
		// further away than the distance we can cover in one frame
		// we must use a variable-size "dead zone" to avoid freezing
		// in mid-air or oscillation behavior at very close distances
		// NOTE:
		//   wantedSpeed is a vector, so even aircraft with turnRate=0
		//   are coincidentally able to reach any goal by side-strafing
		wantedHeading = GetHeadingFromVector(goalVec.x, goalVec.z);
		wantedSpeed = (goalVec / goalDist) * goalSpeed;
	} else {
		// switch to hovering (if !CanLand()))
		if (flyState != FLY_ATTACKING) {
			ExecuteStop();
		}
	}

	// redundant, done in Update()
	// UpdateHeading();
	UpdateAirPhysics();

	// Point toward goal or forward - unless we just passed it to get to another goal
	if ((flyState == FLY_ATTACKING) || (flyState == FLY_CIRCLING)) {
		goalVec = circlingPos - pos;
	} else {
		const bool b0 = (flyState != FLY_LANDING && (owner->commandAI->HasMoreMoveCommands()));
		const bool b1 = (goalDist < brakeDist && goalDist > 1.0f);

		if (b0 && b1) {
			goalVec = owner->frontdir;
		} else {
			goalVec = goalPos - pos;
		}
	}

	if (goalVec.SqLength2D() > 1.0f) {
		// update heading again in case goalVec changed
		wantedHeading = GetHeadingFromVector(goalVec.x, goalVec.z);
	}
}
Exemplo n.º 13
0
void CBuilderCAI::SlowUpdate()
{
	if (commandQue.empty()) {
		CMobileCAI::SlowUpdate();
		return;
	}

	if (owner->stunned) {
		return;
	}

	CBuilder* fac = (CBuilder*)owner;
	Command& c = commandQue.front();

	if (OutOfImmobileRange(c)) {
		FinishCommand();
		return;
	}

	map<int, string>::iterator boi = buildOptions.find(c.id);
	if (!owner->beingBuilt && boi != buildOptions.end()) {
		const UnitDef* ud = unitDefHandler->GetUnitByName(boi->second);
		const float radius = GetUnitDefRadius(ud, c.id);
		if (inCommand) {
			if (building) {
				if (f3SqDist(build.pos, fac->pos) > Square(fac->buildDistance + radius - 8.0f)) {
					owner->moveType->StartMoving(build.pos, fac->buildDistance * 0.5f + radius);
				} else {
					StopMove();
					// needed since above startmoving cancels this
					owner->moveType->KeepPointingTo(build.pos, (fac->buildDistance + radius) * 0.6f, false);
				}
				if (!fac->curBuild && !fac->terraforming) {
					building = false;
					StopMove();				//cancel the effect of KeepPointingTo
					FinishCommand();
				}
				// This can only be true if two builders started building
				// the restricted unit in the same simulation frame
				else if (uh->unitsByDefs[owner->team][build.def->id].size() > build.def->maxThisUnit) {
					// unit restricted
					building = false;
					fac->StopBuild();
					CancelRestrictedUnit(boi->second);
				}
			} else {
				build.Parse(c);

				if (uh->unitsByDefs[owner->team][build.def->id].size() >= build.def->maxThisUnit) {
					// unit restricted, don't bother moving all the way
					// to the construction site first before telling us
					// (since greyed-out icons can still be clicked etc,
					// would be better to prevent that but doesn't cover
					// case where limit reached while builder en-route)
					CancelRestrictedUnit(boi->second);
					StopMove();
				} else {
					build.pos = helper->Pos2BuildPos(build);
					const float sqdist = f3SqDist(build.pos, fac->pos);

					if ((sqdist < Square(fac->buildDistance * 0.6f + radius)) ||
						(!owner->unitDef->canmove && (sqdist <= Square(fac->buildDistance + radius - 8.0f)))) {
						StopMove();

						if (luaRules && !luaRules->AllowUnitCreation(build.def, owner, &build.pos)) {
							FinishCommand();
						}
						else if (uh->maxUnits > (int) teamHandler->Team(owner->team)->units.size()) {
							// max unitlimit reached
							buildRetries++;
							owner->moveType->KeepPointingTo(build.pos, fac->buildDistance * 0.7f + radius, false);

							if (fac->StartBuild(build) || (buildRetries > 20)) {
								building = true;
							} else {
								ENTER_MIXED;
								if ((owner->team == gu->myTeam) && !(buildRetries & 7)) {
									logOutput.Print("%s: Build pos blocked", owner->unitDef->humanName.c_str());
									logOutput.SetLastMsgPos(owner->pos);
								}
								ENTER_SYNCED;
								helper->BuggerOff(build.pos, radius);
								NonMoving();
							}
						}
					} else {
						if (owner->moveType->progressState == AMoveType::Failed) {
							if (++buildRetries > 5) {
								StopMove();
								FinishCommand();
							}
						}
						SetGoal(build.pos, owner->pos, fac->buildDistance * 0.4f + radius);
					}
				}
			}
		} else {		//!inCommand
			BuildInfo bi;
			bi.pos.x=floor(c.params[0]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
			bi.pos.z=floor(c.params[2]/SQUARE_SIZE+0.5f)*SQUARE_SIZE;
			bi.pos.y=c.params[1];
			CFeature* f=0;
			if (c.params.size()==4)
				bi.buildFacing = int(c.params[3]);
			bi.def = unitDefHandler->GetUnitByName(boi->second);

			uh->TestUnitBuildSquare(bi,f,owner->allyteam);
			if (f) {
				if (!owner->unitDef->canReclaim || !f->def->reclaimable) {
					// FIXME user shouldn't be able to queue buildings on top of features
					// in the first place (in this case).
					StopMove();
					FinishCommand();
				} else {
					Command c2;
					c2.id=CMD_RECLAIM;
					c2.options=0;
					c2.params.push_back(f->id+MAX_UNITS);
					commandQue.push_front(c2);
					SlowUpdate(); //this assumes that the reclaim command can never return directly without having reclaimed the target
				}
			} else {
				inCommand=true;
				SlowUpdate();
			}
		}
		return;
	}

	switch (c.id) {
		case CMD_STOP:      { ExecuteStop(c);      return; }
		case CMD_REPAIR:    { ExecuteRepair(c);    return; }
		case CMD_CAPTURE:   { ExecuteCapture(c);   return; }
		case CMD_GUARD:     { ExecuteGuard(c);     return; }
		case CMD_RECLAIM:   { ExecuteReclaim(c);   return; }
		case CMD_RESURRECT: { ExecuteResurrect(c); return; }
		case CMD_PATROL:    { ExecutePatrol(c);    return; }
		case CMD_FIGHT:     { ExecuteFight(c);     return; }
		case CMD_RESTORE:   { ExecuteRestore(c);   return; }
		default: {
			CMobileCAI::SlowUpdate();
			return;
		}
	}
}
Exemplo n.º 14
0
bool CHoverAirMoveType::Update()
{
	float3& pos = owner->pos;
	float3& speed = owner->speed;

	AAirMoveType::Update();

	if (owner->stunned || owner->beingBuilt) {
		wantedSpeed = ZeroVector;
		wantToStop = true;
	}

	// Allow us to stop if wanted
	if (wantToStop) {
		ExecuteStop();
	}

	const float3 lastSpeed = speed;

	if (owner->fpsControlPlayer != NULL) {
		SetState(AIRCRAFT_FLYING);

		const FPSUnitController& con = owner->fpsControlPlayer->fpsController;

		const float3 forward = con.viewDir;
		const float3 right = forward.cross(UpVector);
		const float3 nextPos = pos + speed;

		float3 flatForward = forward;
		flatForward.y = 0.0f;
		flatForward.Normalize();

		wantedSpeed = ZeroVector;

		if (con.forward) wantedSpeed += flatForward;
		if (con.back   ) wantedSpeed -= flatForward;
		if (con.right  ) wantedSpeed += right;
		if (con.left   ) wantedSpeed -= right;

		wantedSpeed.Normalize();
		wantedSpeed *= maxSpeed;

		if (!nextPos.IsInBounds()) {
			speed = ZeroVector;
		}

		UpdateAirPhysics();
		wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
	} else {
		if (reservedPad != NULL) {
			MoveToRepairPad();

			if (padStatus >= 1) {
				flyState = FLY_LANDING;
			}
		}

		// Main state handling
		switch (aircraftState) {
			case AIRCRAFT_LANDED:
				UpdateLanded();
				break;
			case AIRCRAFT_TAKEOFF:
				UpdateTakeoff();
				break;
			case AIRCRAFT_FLYING:
				UpdateFlying();
				break;
			case AIRCRAFT_LANDING:
				UpdateLanding();
				break;
			case AIRCRAFT_HOVERING:
				UpdateHovering();
				break;
			case AIRCRAFT_CRASHING:
				break;
		}
	}


	// Banking requires deltaSpeed.y = 0
	deltaSpeed = speed - lastSpeed;
	deltaSpeed.y = 0.0f;

	// Turn and bank and move; update dirs
	UpdateHeading();
	UpdateBanking(aircraftState == AIRCRAFT_HOVERING);

	return (HandleCollisions());
}
Exemplo n.º 15
0
void CTAAirMoveType::Update()
{
	float3& pos = owner->pos;
	float3& speed = owner->speed;

	// This is only set to false after the plane has finished constructing
	if (useHeading) {
		useHeading = false;
		SetState(AIRCRAFT_TAKEOFF);
	}

	// Allow us to stop if wanted
	if (wantToStop)
		ExecuteStop();

	float3 lastSpeed = speed;

	if (owner->stunned) {
		wantedSpeed = ZeroVector;
		UpdateAirPhysics();
	} else {
		if (owner->directControl) {
			DirectControlStruct* dc = owner->directControl;
			SetState(AIRCRAFT_FLYING);

			float3 forward = dc->viewDir;
			float3 flatForward = forward;
			flatForward.y = 0;
			flatForward.Normalize();
			float3 right = forward.cross(UpVector);
			float3 nextPos = pos + speed;
			wantedSpeed = ZeroVector;

			if (dc->forward)
				wantedSpeed += flatForward;
			if (dc->back)
				wantedSpeed -= flatForward;
			if (dc->right)
				wantedSpeed += right;
			if (dc->left)
				wantedSpeed -= right;
			wantedSpeed.Normalize();
			wantedSpeed *= maxSpeed;

			if (!nextPos.CheckInBounds()) {
				speed = ZeroVector;
			}

			UpdateAirPhysics();
			wantedHeading = GetHeadingFromVector(flatForward.x, flatForward.z);
		} else
		{

			if (reservedPad) {
				CUnit* unit = reservedPad->GetUnit();
				float3 relPos = unit->script->GetPiecePos(reservedPad->GetPiece());
				float3 pos = unit->pos + unit->frontdir * relPos.z
						+ unit->updir * relPos.y + unit->rightdir * relPos.x;

				if (padStatus == 0) {
					if (aircraftState != AIRCRAFT_FLYING && aircraftState != AIRCRAFT_TAKEOFF)
						SetState(AIRCRAFT_FLYING);

					goalPos = pos;

					if (pos.SqDistance2D(owner->pos) < 400*400) {
						padStatus = 1;
					}
				} else if (padStatus == 1) {
					if (aircraftState != AIRCRAFT_FLYING)
						SetState(AIRCRAFT_FLYING);
					flyState = FLY_LANDING;

					goalPos = pos;
					reservedLandingPos = pos;
					wantedHeight = pos.y - ground->GetHeight(pos.x, pos.z);

					if (owner->pos.SqDistance(pos) < 9 || aircraftState == AIRCRAFT_LANDED) {
						padStatus = 2;
					}
				} else {
					if (aircraftState != AIRCRAFT_LANDED)
						SetState(AIRCRAFT_LANDED);

					owner->pos = pos;
					owner->AddBuildPower(unit->unitDef->buildSpeed / 30, unit);
					owner->currentFuel = std::min(owner->unitDef->maxFuel,
							owner->currentFuel + (owner->unitDef->maxFuel
									/ (GAME_SPEED * owner->unitDef->refuelTime)));

					if (owner->health >= owner->maxHealth - 1
							&& owner->currentFuel >= owner->unitDef->maxFuel) {
						airBaseHandler->LeaveLandingPad(reservedPad);
						reservedPad = 0;
						padStatus = 0;
						goalPos = oldGoalPos;
						SetState(AIRCRAFT_TAKEOFF);
					}
				}
			}

			// Main state handling
			switch (aircraftState) {
				case AIRCRAFT_LANDED:
					UpdateLanded();
					break;
				case AIRCRAFT_TAKEOFF:
					UpdateTakeoff();
					break;
				case AIRCRAFT_FLYING:
					UpdateFlying();
					break;
				case AIRCRAFT_LANDING:
					UpdateLanding();
					break;
				case AIRCRAFT_HOVERING:
					UpdateHovering();
					break;
				case AIRCRAFT_CRASHING:
					break;
			}
		}
	}

	// Banking requires deltaSpeed.y = 0
	deltaSpeed = speed - lastSpeed;
	deltaSpeed.y = 0;

	// Turn and bank and move
	UpdateHeading();
	UpdateBanking(aircraftState == AIRCRAFT_HOVERING);			// updates dirs
	owner->UpdateMidPos();

	// Push other units out of the way
	if (pos != oldpos && aircraftState != AIRCRAFT_TAKEOFF && padStatus == 0) {
		oldpos = pos;

		if (!dontCheckCol && collide) {
			vector<CUnit*> nearUnits = qf->GetUnitsExact(pos, owner->radius + 6);
			vector<CUnit*>::iterator ui;

			for (ui = nearUnits.begin(); ui != nearUnits.end(); ++ui) {
				if ((*ui)->transporter)
					continue;

				float sqDist = (pos-(*ui)->pos).SqLength();
				float totRad = owner->radius + (*ui)->radius;
				if (sqDist < totRad * totRad && sqDist != 0) {
					float dist = sqrt(sqDist);
					float3 dif = pos - (*ui)->pos;

					if (dist > 0.0f) {
						dif /= dist;
					}

					if ((*ui)->mass >= 100000 || (*ui)->immobile) {
						pos -= dif * (dist - totRad);
						owner->UpdateMidPos();
						owner->speed *= 0.99f;
					} else {
						float part = owner->mass / (owner->mass + (*ui)->mass);
						pos -= dif * (dist - totRad) * (1 - part);
						owner->UpdateMidPos();
						CUnit* u = (CUnit*) (*ui);
						u->pos += dif * (dist - totRad) * (part);
						u->UpdateMidPos();
						float colSpeed = -owner->speed.dot(dif) + u->speed.dot(dif);
						owner->speed += dif * colSpeed * (1 - part);
						u->speed -= dif * colSpeed * (part);
					}
				}
			}
		}
		if (pos.x < 0) {
			pos.x += 0.6f;
			owner->midPos.x += 0.6f;
		} else if (pos.x > float3::maxxpos) {
			pos.x -= 0.6f;
			owner->midPos.x -= 0.6f;
		}

		if (pos.z < 0) {
			pos.z += 0.6f;
			owner->midPos.z += 0.6f;
		} else if (pos.z > float3::maxzpos) {
			pos.z -= 0.6f;
			owner->midPos.z -= 0.6f;
		}
	}
}
Exemplo n.º 16
0
void CFactoryCAI::SlowUpdate()
{
	if (commandQue.empty() || owner->beingBuilt) {
		return;
	}

	CFactory* fac=(CFactory*)owner;

	unsigned int oldSize;
	do {
		Command& c=commandQue.front();
		oldSize=commandQue.size();
		map<int,BuildOption>::iterator boi;
		if((boi=buildOptions.find(c.id))!=buildOptions.end()){
			const UnitDef *def = unitDefHandler->GetUnitByName(boi->second.name);
			if(building){
				if(!fac->curBuild && !fac->quedBuild){
					building=false;
					if(owner->group)
						owner->group->CommandFinished(owner->id,commandQue.front().id);
					if(!repeatOrders || c.options & DONT_REPEAT)
						boi->second.numQued--;
					UpdateIconName(c.id,boi->second);
					FinishCommand();
				}
				// This can only be true if two factories started building
				// the restricted unit in the same simulation frame
				else if(uh->unitsByDefs[owner->team][def->id].size() > def->maxThisUnit){ //unit restricted?
					CFactory* fac=(CFactory*)owner;
					building = false;
					fac->StopBuild();
					CancelRestrictedUnit(c, boi->second);
				}
			} else {
				const UnitDef *def = unitDefHandler->GetUnitByName(boi->second.name);
				if(luaRules && !luaRules->AllowUnitCreation(def, owner, NULL)) {
					if(!repeatOrders || c.options & DONT_REPEAT){
						boi->second.numQued--;
					}
					UpdateIconName(c.id,boi->second);
					FinishCommand();
				}
				else if(uh->unitsByDefs[owner->team][def->id].size() >= def->maxThisUnit){ //unit restricted?
					CancelRestrictedUnit(c, boi->second);
				}
				else if(uh->maxUnits>gs->Team(owner->team)->units.size()){  //max unitlimit reached?
					fac->StartBuild(boi->second.fullName);
					building=true;
				}
			}
		}
		else {
			switch(c.id){
				case CMD_STOP: {
					ExecuteStop(c);
					break;
				}
				default: {
					CCommandAI::SlowUpdate();
					return;
				}
			}
		}
	} while ((oldSize != commandQue.size()) && !commandQue.empty());

	return;
}
Exemplo n.º 17
0
void CTAAirMoveType::Update()
{
	//Handy stuff. Wonder if there is a better way?
	float3 &pos=owner->pos;
	SyncedFloat3 &rightdir = owner->rightdir;
	SyncedFloat3 &frontdir = owner->frontdir;
	SyncedFloat3 &updir = owner->updir;
	float3 &speed = owner->speed;

	//This is only set to false after the plane has finished constructing
	if (useHeading){
		useHeading = false;
		SetState(AIRCRAFT_TAKEOFF);
	}

	//Allow us to stop if wanted
	if (wantToStop)
		ExecuteStop();

	float3 lastSpeed = speed;

	if(owner->stunned){
		wantedSpeed=ZeroVector;
		UpdateAirPhysics();
	} else {
#ifdef DIRECT_CONTROL_ALLOWED
		if(owner->directControl){
			DirectControlStruct* dc=owner->directControl;
			SetState(AIRCRAFT_FLYING);

			float3 forward=dc->viewDir;
			float3 flatForward=forward;
			flatForward.y=0;
			flatForward.Normalize();
			float3 right=forward.cross(UpVector);

			wantedSpeed=ZeroVector;
			if(dc->forward)
				wantedSpeed+=flatForward;
			if(dc->back)
				wantedSpeed-=flatForward;
			if(dc->right)
				wantedSpeed+=right;
			if(dc->left)
				wantedSpeed-=right;
			wantedSpeed.Normalize();
			wantedSpeed*=maxSpeed;
			UpdateAirPhysics();
			wantedHeading=GetHeadingFromVector(flatForward.x,flatForward.z);

		} else 
#endif
		{

			if(reservedPad){
				CUnit* unit=reservedPad->unit;
				float3 relPos=unit->localmodel->GetPiecePos(reservedPad->piece);
				float3 pos=unit->pos + unit->frontdir*relPos.z + unit->updir*relPos.y + unit->rightdir*relPos.x;
				if(padStatus==0){
					if(aircraftState!=AIRCRAFT_FLYING && aircraftState!=AIRCRAFT_TAKEOFF)
						SetState(AIRCRAFT_FLYING);

					goalPos=pos;

					if(pos.distance(owner->pos)<400){
						padStatus=1;
					}
					//geometricObjects->AddLine(owner->pos,pos,1,0,1);
				} else if(padStatus==1){
					if(aircraftState!=AIRCRAFT_FLYING)
						SetState(AIRCRAFT_FLYING);
					flyState=FLY_LANDING;

					goalPos=pos;
					reservedLandingPos=pos;
					wantedHeight=pos.y-ground->GetHeight(pos.x,pos.z);

					if(owner->pos.distance(pos)<3 || aircraftState==AIRCRAFT_LANDED){
						padStatus=2;
					}
					//geometricObjects->AddLine(owner->pos,pos,10,0,1);
				} else {
					if(aircraftState!=AIRCRAFT_LANDED)
						SetState(AIRCRAFT_LANDED);
					
					owner->pos=pos;

					owner->AddBuildPower(unit->unitDef->buildSpeed/30,unit);
					owner->currentFuel = min (owner->unitDef->maxFuel, owner->currentFuel + (owner->unitDef->maxFuel / (GAME_SPEED * owner->unitDef->refuelTime)));

					if(owner->health>=owner->maxHealth-1 && owner->currentFuel >= owner->unitDef->maxFuel){
						airBaseHandler->LeaveLandingPad(reservedPad);
						reservedPad=0;
						padStatus=0;
						goalPos=oldGoalPos;
						SetState(AIRCRAFT_TAKEOFF);
					}
				}
			}

			//Main state handling
			switch (aircraftState) {
				case AIRCRAFT_LANDED:
					UpdateLanded();
					break;
				case AIRCRAFT_TAKEOFF:
					UpdateTakeoff();
					break;
				case AIRCRAFT_FLYING:
					UpdateFlying();
					break;
				case AIRCRAFT_LANDING:
					UpdateLanding();
					break;
				case AIRCRAFT_HOVERING:
					UpdateHovering();
					break;
			}
		}
	}
	deltaSpeed = speed - lastSpeed;
	deltaSpeed.y = 0;					//Banking requires this

	//Turn and bank and move
	UpdateHeading();
	UpdateBanking(aircraftState == AIRCRAFT_HOVERING);			//updates dirs
	owner->midPos=pos+frontdir*owner->relMidPos.z + updir*owner->relMidPos.y + rightdir*owner->relMidPos.x;

	//Push other units out of the way
	if(pos!=oldpos && aircraftState!=AIRCRAFT_TAKEOFF && padStatus==0){
		oldpos=pos;
		if(!dontCheckCol){
			vector<CUnit*> nearUnits=qf->GetUnitsExact(pos,owner->radius+6);
			vector<CUnit*>::iterator ui;
			for(ui=nearUnits.begin();ui!=nearUnits.end();++ui){
				if((*ui)->transporter)
					continue;
				float sqDist=(pos-(*ui)->pos).SqLength();
				float totRad=owner->radius+(*ui)->radius;
				if(sqDist<totRad*totRad && sqDist!=0){
					float dist=sqrt(sqDist);
					float3 dif=pos-(*ui)->pos;
					dif/=dist;
					if((*ui)->mass>=100000 || (*ui)->immobile){
						pos-=dif*(dist-totRad);
						owner->midPos=pos+owner->frontdir*owner->relMidPos.z + owner->updir*owner->relMidPos.y + owner->rightdir*owner->relMidPos.x;	
						owner->speed*=0.99f;
//						float damage=((*ui)->speed-owner->speed).SqLength();		//dont think they should take damage when they dont try to avoid it
//						owner->DoDamage(DamageArray()*damage,0,ZeroVector);
//						(*ui)->DoDamage(DamageArray()*damage,0,ZeroVector);
					} else {
						float part=owner->mass/(owner->mass+(*ui)->mass);
						pos-=dif*(dist-totRad)*(1-part);
						owner->midPos=pos+owner->frontdir*owner->relMidPos.z + owner->updir*owner->relMidPos.y + owner->rightdir*owner->relMidPos.x;	
						CUnit* u=(CUnit*)(*ui);
						u->pos+=dif*(dist-totRad)*(part);
						u->midPos=u->pos+u->frontdir*u->relMidPos.z + u->updir*u->relMidPos.y + u->rightdir*u->relMidPos.x;
						float colSpeed=-owner->speed.dot(dif)+u->speed.dot(dif);
						owner->speed+=dif*colSpeed*(1-part);
						u->speed-=dif*colSpeed*(part);
//						float damage=(((*ui)->speed-owner->speed)*0.1f).SqLength();
//						owner->DoDamage(DamageArray()*damage,0,ZeroVector);
//						(*ui)->DoDamage(DamageArray()*damage,0,ZeroVector);
//						owner->speed*=0.99f;
					}
				}
			}
		}
		if(pos.x<0){
			pos.x+=0.6f;
			owner->midPos.x+=0.6f;
		}	else if(pos.x>float3::maxxpos){
			pos.x-=0.6f;
			owner->midPos.x-=0.6f;
		}

		if(pos.z<0){
			pos.z+=0.6f;
			owner->midPos.z+=0.6f;
		}else if(pos.z>float3::maxzpos){
			pos.z-=0.6f;
			owner->midPos.z-=0.6f;
		}
	}
}