⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 objects.cpp

📁 2002年
💻 CPP
📖 第 1 页 / 共 3 页
字号:
				DoLog(LOG_UPDATE,"Predict other kick at %.0f",(float)last_seen_time);
			}else if(selfcoll){
				//wait for estimate
				DoLog(LOG_UPDATE,"Error because Self coll");
			}else if(last_seench_time < last_seen_time-1 ){
				ApplyPosbased_vel(last_seen_time, t, sqrconf );
				DoLog(LOG_UPDATE,"Error maybe too old vel");
			}else if(seen_distance(t) < CP_collision_maxdis){
				Collisionvel(t,sqrconf);
				DoLog(LOG_UPDATE,"It must be coll");
			}else{
				ApplyPosbased_vel(last_seen_time, t, sqrconf);
				DoLog(LOG_UPDATE,"Unknown reason");
			}
		}else if(postime_gap == 2){
			if(OtherKick(last_seen_time)){
				ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay);
				DoLog(LOG_UPDATE,"Predict other kick2 at%d", last_seen_time);
			}else if(OtherKick(last_seen_time + 1)){
				ApplyPosbased_vel(last_seen_time + 1, t, sqrconf * conf_decay);
				DoLog(LOG_UPDATE,"Predict other kick3 at%d", last_seen_time+1);
			}else if(selfcoll){
				//wait for estimate
				DoLog(LOG_UPDATE,"Error because Self coll");
			}else if(last_seench_time<last_seen_time-1){
				ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay );
				DoLog(LOG_UPDATE,"Error maybe too old vel");
			}else{
				if(seen_distance(t) > ServerParam::feel_distance){
					DoLog(LOG_UPDATE,"too far ,see wrong");
				}else{
					float dis1 = (Pos(t) - Self.Pos(t)).mod() ;
					float dis2 = (Pos(t-1) - Self.Pos(t-1)).mod();
					DoLog(LOG_UPDATE,"t%d dis%.2f, t%d dis%.2f", t-1, dis2, t,dis1);
					if(dis1 < dis2 && dis1 < CP_collision_maxdis){
						Collisionvel(t, sqrconf * conf_decay);
						DoLog(LOG_UPDATE,"find coll at t%d", t);
					}else if(dis2 < dis1 && dis2 < CP_collision_maxdis){
						Collisionvel(t - 1, sqrconf * conf_decay);
						DoLog(LOG_UPDATE,"find coll at t%d", t-1);
					}else{
						if(Skill::action.KickEffect(last_seen_time).mod() > 0 && ball.Pos(last_seen_time).dist2(Self.Pos(last_seen_time)) > 1.0f){
							DoLog(LOG_UPDATE,"maybe kick%d invalid", last_seen_time+1);
							Skill::action.ResetKickEffect(last_seen_time+1);
						}else{
							DoLog(LOG_UPDATE,"maybe unfound kick %d", t);
						}

						ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay );
						//invalid kick not be clear out. or other Skill::kick haven't been found
					}
				}
			}
		}else if(!gpos.IsDataKnown(last_seen_time)){
			//wait for estimate
		}else if(postime_gap<6){
			ApplyPosbased_vel(last_seen_time, t, sqrconf * conf_decay);
		}else{
			ApplyPosbased_vel(last_seen_time, t, ClientParam::min_valid_conf * conf_decay);
		}
	}
}

void Ball::ApplyPosbased_vel(Time prevtime,Time latestime,float conf){
	bool valid;
	Vector evel_posbased;
	evel_posbased = posbased_vel_estimate(prevtime, latestime, valid);
	if(valid){
		gvel.Setdata(evel_posbased, latestime);
		vel_time = latestime;
		speed_conf = conf;
		DoLog(LOG_UPDATE,"t%d, Posbased vel applied", latestime);
	}else{
		DoLog(LOG_UPDATE,"Why posbased_vel Invalid (%.2f %.2f)", evel_posbased.x, evel_posbased.y);
	}
	velgap.Setdata(posgap.ChkData(prevtime) + posgap.ChkData(latestime), latestime);
	velgap_time = latestime;
	DoLog(LOG_UPDATE, "reset velgap (%.2f, %.2f)",velgap.Data(latestime).x, velgap.Data(latestime).y);
}

//decide whether the hear info is useful
bool Ball::Isupdate_heard(){
	//no hear info
	if(!heard_pos) return false;
	
	if(IsValidObject()){
		if(pos.dist(heardpos_info.data.mean) > heardpos_info.data.delta + pos_delta + 2.7f){
			DoLog(LOG_HEAR, "Hearbug %d known pos(%.1f, %.1f), delta%.1f while hearing pos(%.1f, %.1f), delta%.1f",
				heardpos_info.time, pos.x, pos.y, pos_delta,
				heardpos_info.data.mean.x, heardpos_info.data.mean.y, heardpos_info.data.delta);
		}
	}
	DoLog(LOG_HEAR, "ball heard pos(%.1f, %.1f, delta%.1f), delay%d old_delta%.1f", 
		heardpos_info.data.mean.x, heardpos_info.data.mean.y, heardpos_info.data.delta,
		situation.CurrentTime - heardpos_info.time, pos_deltas.Data(pos_delta_time));
	if(heardpass.time == heardpos_info.time){
		DoLog(LOG_HEAR, "heard passing");
	} 
	//old info is not valid
	if(!pos_valid() || !IsValidObject() || Isforgot()){		
		find_kick = true;
		return true;
	}
	//I have newer info already
	if(Last_seen_time() > heardpos_info.time){
		if(heardpass.time != heardpos_info.time || seenchinfo.IsDataKnown(Last_seen_time())){
			return false;
		}else{
			//but ball's vel isn't be seen for too far.			
			find_kick = true;
			return true;
		}
	}
	
	//hear pass info
	if(heardpass.time == heardpos_info.time && heardpos_info.time >= Last_seen_time()){
		find_kick = true;
		return true;
	}
	//old decision by criver
	if (pos_conf > 0.9f || distance < 2.0f){
		//it is critical for me, if the confidence of ball is greater than 0.8f and it ball is within 2 meter of my reach
		if (heardvel_info.time != heardpos_info.time)	return false;
		if (ball.global_vel.dist2(heardvel_info.data.mean) < Sqr(0.6f)) return false;
	}


	//my info is clear enough
	if(IsLastSeen() && !OtherKick(update_seen_time)) return false;

	if(!IsLastSeen() && (heardvel_info.time - heardvel_info.data.delta)  > update_seen_time && IscplayerKnown(update_seen_time)){
		//可能刚被人踢过
		Vector rel_ball_pos = ball.Pos(update_seen_time) - Self.Pos(update_seen_time);
		if(closestrpos(update_seen_time).mod() - rel_ball_pos.mod() * ServerParam::dist_qstep * 0.6f < ServerParam::kickable_area){
			if(!find_kick){
				estimate(heardvel_info.time);
				find_kick = heardvel_info.data.mean.dist2(ball.Vel(heardvel_info.time)) > Sqr(0.6f);
			}
			return true;
		}
	}
	//convert hear delta to pos gap in my system
	float relateive_delta = heardpos_info.data.delta + CP_coordinate_gap_between_agents;

	estimategap(heardpos_info.time);
	if(Sqr(relateive_delta) < posgap.Data(heardpos_info.time).mod2()){
		//rude deal
		find_kick = true;
		return true;
	}else{
		return false;
	}
	//有一点还没有判断清楚, 如果听到的位置时间比自己已知的新, 虽然delta>posgap, 
	//但如果中间曾被人踢过,应尽量采用听到的.
}

void Ball::update_heard(Time time){
	MobileObject::update_heard(time); 

	if(isupdateheard){
		//take care, here we set player's iscontrolball		
		int No;
		for(No = 1; No <= SP_team_size; No++){
			MyPlayer(No).Set_Iscontrolball_Fromheard(heardpos_info.time);
			TheirPlayer(No).Set_Iscontrolball_Fromheard(heardpos_info.time);
			UnknownTheirPlayerList.Set_IsControlball_FromHeard(heardpos_info.time);
			UnknownMyPlayerList.Set_IsControlball_FromHeard(heardpos_info.time);
			TeamlessPlayerList.Set_IsControlball_FromHeard(heardpos_info.time);
		}
		updated_holder = true;
		if (heard_vel && heardvel_info.data.delta <= VelDelay() ){
			//如果听到的位置精确度更高,不妨认为速度的也更高
			gvel.Setdata(heardvel_info.data.mean, heardvel_info.time);
			vel_time = heardvel_info.time;
			speed_conf = (float)pow(conf_decay, int(heardvel_info.data.delta));

			original_veltime = heardvel_info.time - int(heardvel_info.data.delta);
			newvel = true;
			DoLog(LOG_HEAR, "ball vel %d, (%.1f,%.1f)", heardvel_info.time, 
				heardvel_info.data.mean.x, heardvel_info.data.mean.y);
		}
	}
}

void Ball::Prior_update(){
	find_kick = false;
	updated_holder = false;
}

void Ball::update_end(){
	MobileObject::update_end();

	if(Last_seen_time() < Self.Last_seen_time() && distance < ServerParam::feel_distance){
		if(ball.Pos(Self.Last_seen_time()).dist(Self.Pos(Self.Last_seen_time())) + ball.posgap.ChkData(Self.Last_seen_time()).mod() < ServerParam::feel_distance){
			forget();
		}
	}
	pos_delta = posgap.ChkData(situation.CurrentTime).mod();
	if(distance > ClientParam::kickable_area || !pos_valid() || !IsValidObject()){
		kick_able = false;
	}else if(Last_seen_time() >= Self.Last_seen_time()){
		kick_able = true;
	}else if(pos_delta > 2.0f){
		kick_able = false;
	}else if(ball.Pos(Self.Last_seen_time()).dist(Self.Pos(Self.Last_seen_time())) + 
		ball.posgap.ChkData(Self.Last_seen_time()).mod() > ServerParam::feel_distance){
		kick_able = true;	
	}else{
		kick_able = false;
	}
	if(distance < ClientParam::kickable_area && !kick_able){
		if(!pos_valid()) DoLog(LOG_UPDATE, "kick disable for pos invalid");
		else if(!IsValidObject()) DoLog(LOG_UPDATE, "kick disable for Rs invalid");
		else{
			DoLog(LOG_UPDATE, "kick disable for ball( %d) is unseen at %d", Last_seen_time(), Self.Last_seen_time());
		}
	}
	theirgoalangle = (PitchInfo.theirgoal - pos).Angle();
	mygoalangle = (PitchInfo.mygoal - pos).Angle();
	DoLog(LOG_UPDATE, "ball pos(%.2f, %.2f), vel(%.2f, %.2f)", pos.x, pos.y, global_vel.x, global_vel.y);
}
 
void Ball::Collisionvel(Time time,float conf){
	Vector vel = Skill::action.SummarizeKickeffectVel(Vel(vel_time),vel_time,time,speed_decay,max_speed);
	gvel.Setdata(vel * -0.1f, time);
	vel_time = time;
	speed_conf = conf;
	DoLog(LOG_UPDATE,"coll handle t%.0f,v(%.2f,%.2f)",(float)time,Vel(time).x,Vel(time).y);
}

bool Ball::OtherKick(Time time){
	if(IscrposKnown(time)){
		if(closestrpos(time).mod() < ServerParam::kickable_area + 0.05f )
			return true;
	}
	return false;
}

 bool Ball::OtherKick(Time prevtime,Time lastime){
	for(Time t=prevtime;t<=lastime;t++){
		if(OtherKick(t)) return true;
	}
	return false;
}

bool Ball::IsposError(Vector allowposgap, Vector predictgap,float& gapmod){
	if(fabs(predictgap.x) > allowposgap.x || fabs(predictgap.y) > allowposgap.y){
		gapmod = fabs(predictgap.x) > allowposgap.x ? Sqr((float)fabs(predictgap.x)-allowposgap.x) : 0;
		gapmod += fabs(predictgap.y) > allowposgap.y ? Sqr((float)fabs(predictgap.y)-allowposgap.y) : 0;
		gapmod = (float)sqrt(gapmod / allowposgap.mod());
		return true;
	}else{
		gapmod = 0;
		return false;
	}
}

Vector Ball::posbased_vel_estimate(Time prev_time, Time last_time, bool& valid){
	/* estimate by postion difference */
	valid = false;
	Vector gap = Pos(last_time) - Pos(prev_time);
	Vector evel;
	gap -= Self.SummarizePosGap(prev_time, last_time);

	DoLog(LOG_UPDATE,"prev pos (%.2f %.2f) last pos (%.2f %.2f) gap (%.2f %.2f)", Pos(prev_time).x, Pos(prev_time).y,
		Pos(last_time).x, Pos(last_time).y, gap.x, gap.y);
	//if (gap.mod() < (float)fabs(last_time - prev_time) * max_speed){
	Vector kickeffectpos = Skill::action.SummarizeKickeffectPos(prev_time, last_time, speed_decay);
	evel = (gap - kickeffectpos) * (1 - speed_decay) / (1 - Exp(speed_decay, (float)(last_time - prev_time)));
	//evel is now that at time prev_time
	if(evel.mod() > max_speed){
		evel = evel / evel.mod() * max_speed;
	}
	evel = Skill::action.SummarizeKickeffectVel(evel, prev_time, last_time, speed_decay, max_speed);
	valid = true;
	return evel;
}

void Ball::estimate(Time time){
	MobileObject::estimate(time);
	estimategap(time);
}

void Ball::estimate_pos(Time time){
	MobileObject::estimate_pos(time);
}

void Ball::CollisionHandle(Time time){
	DoLog(LOG_UPDATE,"Coolisionhandle");
	estimate_pos(time);
	if (speed_valid()){
		Vector rpos = Pos(time) - Self.Pos(time);
		float r = ServerParam::ball_size + ServerParam::player_size;
		float d = rpos.mod();
		if (d>=r) return; 
		AngleDeg th = float(fabs(NormalizeAngle(rpos.Angle() - Self.Bodyfacing(time -1) - 180.0f)));
		float l1 = d * Cos(th);
		float h = d * Sin(th);
		float cosp = h / r;
		float sinp = (float)sqrt(1.0 - Sqr(cosp));
		float l2 = r * sinp;
		gpos.Data(time) += Vel(time) *float( speed_decay * (-(l1+l2) / Max(Vel(time).mod() * speed_decay, 0.000001f)));
		gvel.Data(time) *= -0.1f;
		vel_time = time;
		speed_conf = min_valid_conf / Sqr(conf_decay);
	}
}

bool Ball::catchable(){
	if(Self.Is_goalie)
		return bool(pos_conf > 0.8f && distance < ServerParam::catch_area_l && PitchInfo.my_penaltyarea.IsWithin(Self.pos) && Skill::action.cancatch(situation.CurrentTime));
	else
		return bool(pos_conf > 0.8f && distance < ServerParam::catch_area_l && PitchInfo.my_penaltyarea.IsWithin(pos) && Skill::action.cancatch(situation.CurrentTime));
}

bool Ball::shootable(){
	return bool(FieldInfo.shootablearea.IsWithin(pos) && kickable());
}

bool Ball::kickable(const Vector& selfpos){
	return bool(pos_valid() && ball.pos.dist2(selfpos) < Sqr(Self.kickable_area ));
}

bool Ball::catchable(const Vector& selfpos){
	return bool(pos_valid() && pos.dist2(selfpos) < Sqr(ServerParam::catch_area_l) && PitchInfo.my_penaltyarea.IsWithin(selfpos) && Skill::action.cancatch(situation.CurrentTime));
}

bool Ball::shootable(const Vector& ballpos){
	return FieldInfo.shootablearea.IsWithin(ballpos);
}

void Ball::Setball_CPlayer(UNum idx,Vector pos,Time time){
	if(idx > 0 && idx <= 2*SP_team_size)
		ClosestPlayer.Setdata(idx, time);
	else
		ClosestPlayer.Setdata(idx, time-1);
	ClosestRPos.Setdata(pos-Pos(time),time);
}

bool Ball::IsOtherKick(){
	if(IsOtherKick(situation.CurrentTime) || IsOtherKick(situation.CurrentTime - 1)){
		return true;
	}else
		return false;
}

bool Ball::IsOtherKick(Time t){
	if(error_idx.IsDataKnown(t) && error_idx.Data(t) > 0.01f )
		return true;
	else
		return false;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -