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

📄 positioning.cpp

📁 2002年
💻 CPP
字号:
#include "positioning.h"
#include "worldmodel.h"
#include "skill.h"
#include "agent.h"
#include "log.h"

/**************	PositionAction	**************/
PositionAction::PositionAction(){
}
bool PositionAction::InvalidZoneAdjust(Vector& point)
{
	if (!FieldInfo.IsInvalidZone(point))
		return true;
	Line Runline;
	Vector projectpoint;
	switch (situation.playmode){
	case PM_My_Kick_Off:
	case PM_Their_Kick_Off:
		return false;
		break;
	case PM_Their_Goal_Kick :
		point.x = ServerParam::semi_pitch_length - ServerParam::penalty_area_length - 1.0f;
		return true;
		break;
	case PM_Their_Kick_In :
		point = ball.pos + Polar2Vector(ServerParam::free_kick_buffer + 0.5f,(point - ball.pos).Angle());
		return true;
		break;
	case PM_Their_Corner_Kick :
	case PM_Their_Free_Kick :
	case PM_Their_Offside_Kick :
		Runline.LineFromTwoPoints(Self.pos,point);
		if (!Runline.InBetween(ball.pos,Self.pos,point))
		{
			point = ball.pos + Polar2Vector(ServerParam::free_kick_buffer + 0.5f,(point - ball.pos).Angle());
		}
		else
		{
			projectpoint = Runline.ProjectPoint(ball.pos);
			if (projectpoint.dist(ball.pos) > 0.001f)
			{
				point = ball.pos + Polar2Vector(ServerParam::free_kick_buffer + 0.5f,(projectpoint - ball.pos).Angle());
			}
			else
			{
				point = ball.pos + Polar2Vector(ServerParam::free_kick_buffer + 0.5f,(projectpoint - ball.pos).Angle()+90.0f);
			}
		}
		return true;
		break;
	default :
		return false;
		break;
	}
}

void PositionAction::position(){
	Command command;

	if(actiontype == Action_positioning_offside){
	}else{
		float controlspeed = rapidness;
		Agent::motion.go_to(point,  controlspeed, command);
	}
	Agent::mediator.enroll(command, actiontype, priority);
}

void PositionAction::SetPositioningInfo(Vector point, float rapidness, float max_deviation, float priority, ActionType actiontype){
	this->point = point;
	this->rapidness = rapidness;
	this->max_deviation = max_deviation;
	this->priority = priority;
	this->actiontype = actiontype;
}
/**************	Positioning	**************************/
Positioning::Positioning(){
	sens_pos_factor.Interpolation(0.05f,0.2f, 0.7f,0.5f, 0.9f,0.7f, 1.0f,0.95f);
}

void Positioning::Defense(){
	if(!Self.IsBack() && !ball.pos_valid()) return;
	if (Self.IsForward() && FieldInfo.IsOffside())
	{
		arrangement.df_type = DF_Formation;
		arrangement.df_point = Vector(FieldInfo.GetOffsideLine() - 1.5f, Self.pos.y);
		arrangement.valid = true;
		DoLog(LOG_OFFSIDE,"offside %.2f", FieldInfo.GetOffsideLine());
	}
	else if(Self.IsForward() && FieldInfo.Maybeoffside()){
		arrangement.df_type = DF_Formation;
		arrangement.df_point = Self.pos;
		arrangement.valid = true;
		DoLog(LOG_OFFSIDE,"suspicous offside %d", FieldInfo.Susoffsideopp.Data(situation.CurrentTime));
	}
	else
	{
		if (!MakeDefenseDecision()) return;
		 arrangement = GetAssignment();
	}
	
	if (!arrangement.valid)
		return;

	ActionType actiontype;

	switch(arrangement.df_type){
	case DF_Block:
		actiontype = Action_positioning_block;
		CloseBlock(arrangement);
		break;
	case DF_Mark:
		actiontype = Action_positioning_mark;
		break;
	case DF_Formation:
		actiontype = Action_positioning_defense;
		break;
	case DF_Press:
		actiontype = Action_press; 
		break;
	default:
		actiontype = Action_none;
	}
	logdefense.Setdata(arrangement, situation.CurrentTime);
	
	DoLog(LOG_POSITIONING, "DF point(%.2f %.2f)", arrangement.df_point.x, arrangement.df_point.y);
	SetPositioningInfo(arrangement.df_point, GetDefenseSpeed(arrangement), 0.5f, PriorityA, actiontype);
	position();
}

void Positioning::Offense(){
	if (Self.attackness <= 0.3f && situation.playmode == PM_Play_On)
		DefensiveFormation();
	else
		OffensiveFormation();
}

void Positioning::DefensiveFormation(){
	if(ball.pos_conf < 0.8f) return;//check if the information of ball is sufficient to make the decision
	Vector defensive_pos;
	defensive_pos = formation.GetDefensivePoint(Self.attackness, Self.leftness, situation.NextControlBallPos());
	
	SetPositioningInfo(defensive_pos, CP_slow_formation_speed, ClientParam::pos_deviation_max, PriorityB, Action_positioning_defense);

	position();
}

void Positioning::OffensiveFormation(){
	if(!ball.pos_valid() ) return;
	if(ball.Isforgot() && situation.playmode != PM_Play_On){
		DoLog("find ball first");
		return;
	}

	float offensespeed, deviation;
	Vector offensepos,basepos,rbasepos;
	//FieldState* s = &situation.CurState(); 
	if (FieldInfo.IsOffside()) 
	{
		offensepos = Vector(FieldInfo.GetOffsideLine() - 2.0f, Self.pos.y);
		offensespeed =  CP_fast_formation_speed;
		deviation = 0.5f;
		DoLog(LOG_OFFSIDE,"offside %.2f", FieldInfo.GetOffsideLine());
		
		SetPositioningInfo(offensepos, offensespeed, deviation, PriorityB, Action_positioning_offside);
	}else if(FieldInfo.Maybeoffside()){
		offensepos = Self.pos;
		deviation = 1.0f;
		DoLog(LOG_OFFSIDE,"suspicous offside %d", FieldInfo.Susoffsideopp.Data(situation.CurrentTime));
		
		SetPositioningInfo(offensepos, CP_slow_formation_speed, deviation, PriorityB, Action_positioning_offense);
	}
	else{
		offensepos = formation.GetOffensivePoint(Self.attackness, Self.leftness, situation.NextControlBallPos());		
		if (offensepos.x > FieldInfo.GetOffsideLine()){
			Line l;
			l.LineFromTwoPoints(Self.pos, offensepos);
			offensepos.x = FieldInfo.GetOffsideLine() - 0.5f;
			offensepos.y = l.get_y(offensepos.x); 
		}
		
		if (situation.gamestate != GS_Playing){//ciwp
			offensespeed = CP_slow_formation_speed;
		}
		else if (Self.attackness >= 0.8f){//yf
			offensespeed = CP_fast_formation_speed * 0.9f;
		}
		else if (Self.attackness > 0.5f){//ciwp
			offensespeed = CP_mid_offense_speed;
		}
		else{
			offensespeed = CP_slow_formation_speed;
		}
		//patch, 前锋回跑,保存体力
		if(Self.IsForward() && offensespeed > CP_slow_formation_speed && offensepos.x < Self.pos.x - 3.0f ){
			offensespeed = CP_slow_formation_speed;
		}
		deviation = ClientParam::pos_deviation_max;
		SetPositioningInfo(offensepos, offensespeed, deviation, PriorityB, Action_positioning_offense);
	} 
	position();
}

float Positioning::GetDefenseSpeed(const DF_Arrangement & arrangement){
	switch(arrangement.df_type){
	case DF_Formation:
		if (situation.gamestate != GS_Playing)
			return CP_slow_formation_speed;
		
		if (MyPlayer(arrangement.defender).IsBack())
		{
			Vector df_action = arrangement.df_point - Self.pos;
			df_action.Normalize();
			if (df_action.x > 0){
			// Backs don't need to move forward too fast 
				df_action.x *= 0.6f;
			}
			else{
			// Formation speed don't need to be too fast 
				df_action *= 0.85f;
			}
			return df_action.mod() * CP_fast_formation_speed;
			/*
			if ( fabs((Self.pos - arrangement.df_point).Angle()) > 150 && arrangement.df_point.x > -10)
				return CP_mid_formation_speed;
			else	
				return CP_fast_formation_speed;*/
		}
		else if (MyPlayer(arrangement.defender).IsMidFielder())
			return CP_mid_formation_speed;
		else
		{
			if (FieldInfo.IsOffside())
				return CP_fast_formation_speed;
			else
				return CP_slow_formation_speed;
		}
		break;
	case DF_Block:
	case DF_Press:
		return CP_fast_formation_speed;
		break;
	case DF_Mark:
		if (arrangement.threat >= 0.85f){
			return CP_fast_formation_speed;
		}
		else {
			if (TheirPlayer(arrangement.defendee).balldist < 25.0f){
				return CP_fast_formation_speed;
			}
			return CP_mid_formation_speed;
		}
		break;
	}
		
	return CP_fast_formation_speed;
}

void Positioning::Position(){
	bool self_is_attack;
	if (situation.gamestate == GS_My_SetPlay)
	{
		self_is_attack = true;
	}
	else
	if (situation.IsAttack){
		if(Self.IsBack() && FieldInfo.GetDefensiveSensitivity(situation.NextControlBallPos()) > 0.7f){
			self_is_attack = false;
		}else{
			self_is_attack = true;
		}
	}
	else{
		self_is_attack = false;
	}
	
	if (self_is_attack){
		Offense();
	}
	else{
		Defense();
	}
}



void Positioning::CloseBlock(DF_Arrangement &arrangement){
	if (TheirPlayer(arrangement.defendee).distance > ClientParam::block_dist)
		return;
	if (TheirPlayer(arrangement.defendee).ActiveRadius(situation.CurrentTime) > 0.6f)
		return;
	Vector Opos = TheirPlayer(arrangement.defendee).pos;
	if (Self.pos.x > Opos.x - 0.1f) return;
	Line opp_me;
	opp_me.LineFromTwoPoints(Self.pos,Opos);
	if (opp_me.dist(ball.pos) > 0.6f)
		return;
	Vector sectgoal = opp_me.intersection(PitchInfo.SideLines[SL_Left]);
	if (sectgoal.x > -ServerParam::semi_pitch_length+0.01f)
		return;
	if (fabs(sectgoal.y) > ServerParam::goal_width/2)
		return;
	DoLog(LOG_POSITIONING,"Close Block");
	arrangement.df_point = Self.pos + Polar2Vector(0.7f,(Opos - Self.pos).Angle());
}

⌨️ 快捷键说明

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