📄 positioning.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 + -