1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//! SC2 Score interface.

use crate::{FromProto, IntoSC2};
use sc2_proto::score::{CategoryScoreDetails, Score as ProtoScore, Score_ScoreType, VitalScoreDetails};

#[variant_checkers]
#[derive(Clone)]
pub enum ScoreType {
	Curriculum,
	Melee,
}
impl FromProto<Score_ScoreType> for ScoreType {
	fn from_proto(score_type: Score_ScoreType) -> Self {
		match score_type {
			Score_ScoreType::Curriculum => ScoreType::Curriculum,
			Score_ScoreType::Melee => ScoreType::Melee,
		}
	}
}
impl Default for ScoreType {
	fn default() -> Self {
		ScoreType::Curriculum
	}
}

#[derive(Default, Clone)]
pub struct Category {
	pub none: f32,
	pub army: f32,
	pub economy: f32,
	pub technology: f32,
	pub upgrade: f32,
}
impl FromProto<&CategoryScoreDetails> for Category {
	fn from_proto(category: &CategoryScoreDetails) -> Self {
		Self {
			none: category.get_none(),
			army: category.get_army(),
			economy: category.get_economy(),
			technology: category.get_technology(),
			upgrade: category.get_upgrade(),
		}
	}
}

#[derive(Default, Clone)]
pub struct Vital {
	pub life: f32,
	pub shields: f32,
	pub energy: f32,
}
impl FromProto<&VitalScoreDetails> for Vital {
	fn from_proto(vital: &VitalScoreDetails) -> Self {
		Self {
			life: vital.get_life(),
			shields: vital.get_shields(),
			energy: vital.get_energy(),
		}
	}
}

/// All kinds of scores stored here.
///
/// Can be accessed through [state.observation.score](crate::game_state::Observation::score).
#[derive(Default, Clone)]
pub struct Score {
	pub score_type: ScoreType,
	pub total_score: i32,
	// score details
	pub idle_production_time: f32,
	pub idle_worker_time: f32,
	pub total_value_units: f32,
	pub total_value_structures: f32,
	pub killed_value_units: f32,
	pub killed_value_structures: f32,
	pub collected_minerals: f32,
	pub collected_vespene: f32,
	pub collection_rate_minerals: f32,
	pub collection_rate_vespene: f32,
	pub spent_minerals: f32,
	pub spent_vespene: f32,
	pub food_used: Category,
	pub killed_minerals: Category,
	pub killed_vespene: Category,
	pub lost_minerals: Category,
	pub lost_vespene: Category,
	pub friendly_fire_minerals: Category,
	pub friendly_fire_vespene: Category,
	pub used_minerals: Category,
	pub used_vespene: Category,
	pub total_used_minerals: Category,
	pub total_used_vespene: Category,
	pub total_damage_dealt: Vital,
	pub total_damage_taken: Vital,
	pub total_healed: Vital,
	pub current_apm: f32,
	pub current_effective_apm: f32,
}
impl FromProto<&ProtoScore> for Score {
	fn from_proto(score: &ProtoScore) -> Self {
		let details = score.get_score_details();
		Self {
			score_type: score.get_score_type().into_sc2(),
			total_score: score.get_score(),
			idle_production_time: details.get_idle_production_time(),
			idle_worker_time: details.get_idle_worker_time(),
			total_value_units: details.get_total_value_units(),
			total_value_structures: details.get_total_value_structures(),
			killed_value_units: details.get_killed_value_units(),
			killed_value_structures: details.get_killed_value_structures(),
			collected_minerals: details.get_collected_minerals(),
			collected_vespene: details.get_collected_vespene(),
			collection_rate_minerals: details.get_collection_rate_minerals(),
			collection_rate_vespene: details.get_collection_rate_vespene(),
			spent_minerals: details.get_spent_minerals(),
			spent_vespene: details.get_spent_vespene(),
			food_used: details.get_food_used().into_sc2(),
			killed_minerals: details.get_killed_minerals().into_sc2(),
			killed_vespene: details.get_killed_vespene().into_sc2(),
			lost_minerals: details.get_lost_minerals().into_sc2(),
			lost_vespene: details.get_lost_vespene().into_sc2(),
			friendly_fire_minerals: details.get_friendly_fire_minerals().into_sc2(),
			friendly_fire_vespene: details.get_friendly_fire_vespene().into_sc2(),
			used_minerals: details.get_used_minerals().into_sc2(),
			used_vespene: details.get_used_vespene().into_sc2(),
			total_used_minerals: details.get_total_used_minerals().into_sc2(),
			total_used_vespene: details.get_total_used_vespene().into_sc2(),
			total_damage_dealt: details.get_total_damage_dealt().into_sc2(),
			total_damage_taken: details.get_total_damage_taken().into_sc2(),
			total_healed: details.get_total_healed().into_sc2(),
			current_apm: details.get_current_apm(),
			current_effective_apm: details.get_current_effective_apm(),
		}
	}
}