TM Routine Line Sharing

Display players routine in tactics page

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name             TM Routine Line Sharing
// @namespace        https://greasyfork.org/it/users/150526-matteo-tomassetti
// @version          0.5.3.1
// @description      Display players routine in tactics page
// @author           Matteo Tomassetti (Polverigi FC)
// @copyright        © 2017 Matteo Tomassetti. All rights reserved.
// @iconURL          https://static.trophymanager.com/pics/icons/mini_field.png
// @supportURL       https://trophymanager.com/forum/it/general/385311/last
// @contributionURL  https://trophymanager.com/account/donate-pro/
// @include          https://trophymanager.com/*tactics/*
// @run-at           document-idle
// @grant            none
// ==/UserScript==

(function() {
    'use strict';
    // ****************************
    // *** Constants definition ***
    // ****************************
    var share_bonus = 0.25;
    var routine_cap = 40.0;
    var def_line_idx = [0, 6];   // Defensive positions are 0 to 5
    var mid_line_idx = [6, 16];  // Midfield positions are 6 to 15
    var off_line_idx = [16, 24]; // Offensive positions are 16 to 23

    // ************************
    // *** Script main code ***
    // ************************
    var players_on_field = {};
	
	initialize();

    // ****************************
    // *** Functions definition ***
    // ****************************

	function initialize() {
		if(players.length > 0) {
			addRoutineToTacticsTable();
			updateAndDisplay();
			addClickListeners();
		} else {
			setTimeout(function() {initialize();}, 100);						
		}
	}
	
	/*
	* This function updates and displays routine values of all players
	*/
	function updateAndDisplay() {
		updatePlayersRoutine();
        displayPlayersRoutine();
		listPlayers();	
	}
	
    /*
	* This function displays routine value of each player in formation
	*/
    function displayPlayersRoutine() {
		// show routine of players on field
		$("div.field_player").each(function(index, el) {
			// fix gk flag issue
			if ($(el).attr("position") === "gk") {
				var hasFlag = $(el).find("ib").length;
				var width = (hasFlag ? "130px" : "60px");
				var text_align = (hasFlag ? "left" : "center");
				$(el).find("div.field_player_name").css({
					"width": width,
					"text-align": text_align    
				});            
			}
			if ($(el).attr("player_set") === "false") {
				$(el).find("div.field_player_routine").remove();  
			} else {           
				var id = $(el).attr("player_id");
				var no = players_on_field[id]["no"];
				var routine = players_on_field[id]["routine"]; 
				var rou_div = $(el).find("div.field_player_routine");
				if (rou_div.length) {
					// div already exists
					rou_div.text(routine);
				} else {
					// create new div to display routine value
					$(this).append('<div class="field_player_routine">' + routine + '</div>');   
				}        
			}       
		}); 
		// show routine of players on bench
		$("li.bench_player").each(function(index, el) {
			var id = $(el).attr("player_id");
			var routine = players_by_id[id]["routine"];
			var rou_div = $(el).find("div.bench_player_routine");
			if (rou_div.length) {
				// div already exists
				rou_div.text(routine);
			} else {
				// create new div to display routine value
				var rec_div = $(el).find("div.rec_stars").css("line-height", "14px");
				$("<div></div>")
					.addClass("bench_player_routine")
					.css({
					"font-size": "10px",
					"text-align": "center"    
				})
					.text(routine)
					.appendTo(rec_div);
			}       
		}); 
    }

    /*
	* This function updates the routine of all players on the field 
	* applying the routine bonus
	*/
    function updatePlayersRoutine() {
        updateLineRoutine(def_line_idx);
        updateLineRoutine(mid_line_idx);
        updateLineRoutine(off_line_idx);    
    }

    /*
	* This function applies the routine bonus to the player with least routine 
	* in the given line and saves the updated routine value  
	*/
    function updateLineRoutine(line_idx) {
        var players_ar = [];
        // for each position in the line
        for (var i = line_idx[0]; i < line_idx[1]; i++) {      
            var id = formation_by_pos[i];
            // check if there is a player in that position
            if (id !== "0" && id !== null) {
                // retrieve player info
                var player = players_by_id[id];
                var name = player["name"];
                var no = player["no"];
                var routine = parseFloat(player["routine"]);           
                // create new player object and add it to the array
                var p = {"id": id, "no": no, "routine": routine};
                players_ar.push(p);
            }   
        }    
        var line_size = players_ar.length; // players in the line
        // if line consist of two or more players: apply routine bonus
        if (line_size > 1) {
			// sort players array by routine in ascending order
        	players_ar.sort(compareByRoutineAsc);
			var min = players_ar[0]["routine"];
			if (min < routine_cap) {
				var max = players_ar[line_size - 1]["routine"];            
				var min2 = players_ar[1]["routine"];
				// calculate new routine value applying routine bonus
				var bonus = max * share_bonus;
				var new_routine = min + bonus;
				new_routine = (new_routine < min2 ? new_routine : min2);
				new_routine = (new_routine < routine_cap ? new_routine : routine_cap);
				new_routine = parseFloat(new_routine.toFixed(1));
				// update player routine
				players_ar[0]["routine"] = new_routine;
			}
        }
		// insert players into players_on_field object by id
		for (i = 0; i < players_ar.length; i++) {
			var player = players_ar[i];
			var id = player["id"];
			var no = player["no"];
			var routine = player["routine"];
			players_on_field[id] = {"no": no, "routine": routine};
		}
    }

    /*
	* Compare function to sort objects by their routine property in ascending order
	*/
    function compareByRoutineAsc(a, b) {
		var rou_a = parseFloat(a.routine);
		var rou_b = parseFloat(b.routine);
        return (rou_a - rou_b);
    }

    /*
	* Compare function to sort objects by their routine property in descending order
	*/
    function compareByRoutineDesc(a, b) {
        return (b.routine - a.routine);
    }
	
	/*
	* This function sorts players array by given key and order
	* and then updates tactics table
	*/
	var sortPlayers = function(key, direction) {
	    // key = no / pos / name / rec / rou
		// direction = asc, desc
		key = key || "pos";
		direction = direction || "asc";
		if (key === "rou") {
			var comp_fun = (direction === "asc" ? compareByRoutineAsc : compareByRoutineDesc);
			players.sort(comp_fun);	
		} else {
			players = mergeSort(players, key+"_sort", direction);
		}
		listPlayers();
	};
	
	/*
	* This function adds routine column to tactics table
	*/
	function addRoutineToTacticsTable() {
		var name_col = $("#tactics_list_headers").find(".name_col.list_column").width("170px");
		var rou_col = $("<div class=\"rou_col list_column\" tooltip=\"Ordina per Routine\"" + 
						"onclick=\"tactics_sort('pos')\"; style=\"width: 34px;\">" + 
						"<div class=\"padding\" style=\"background: none;\">Rou</div></div>");
		$(rou_col).insertAfter($(name_col));
	}
	
	function addClickListeners() {
		// Attach click event handler function to the tactics table headers:
		// when the user clicks on the field, players in the table are sorted
		$("#tactics_list_headers").find(".list_column").each(function(index, el) {
			var key = $(el).attr("class").split(" ")[0].split("_")[0];
			if (key !== "col") { // do not consider empty col
				$(el).attr("order", "desc");
				//$(el).prop("onclick", null);
				$(el).click(function() {
					var order = $(el).attr("order");
					var new_order = (order === "asc" ? "desc" : "asc");
					sortPlayers(key, order);
					$(el).attr("order", new_order);
				});
			}
		});

		// Attach click event handler function to the tactics field:
		// when the user clicks on the field, routine values are updated
		$("#tactics_field").click(function() {
			updateAndDisplay();    
		});				
	}
	
	/*
	* This function populates tactics table with players data
	*/
	function listPlayers() {
		var $list = $("#tactics_list_list");
		var $ul = $("<ul>").addClass("tactics_list");
		var gk_header = false;
		for(var i in players)
		{
			var p = players[i];
			if(p)
			{
				p["on_field"] = on_field[p["player_id"]] || on_subs[p["player_id"]];
				if(tactics_filter_show(p))
				{
					var str = "<div class=\"list_column no_col align_center\">"+p["no"]+"</div>" +
					"<div class=\"vert_split\"></div>" +
					"<div class=\"list_column pos_col align_center\">"+p["favorite_position_short"]+"</div>" +
					"<div class=\"vert_split\"></div>" +
					"<div class=\"list_column name_col\" style=\"width: 170px\"><div class=\"padding\">"+ 
						"<span class='player_name' player_link='"+p["player_id"]+"' player_id='"+p["player_id"]+"'>"+p["name"]+"</span>"+
						(p["show_flag"] ? " "+p["flag"] : "" )+(p["status_no_check"] === "" ? "" : " "+p["status_no_count"] )+"</div></div>" +
					"<div class=\"vert_split\"></div>" +
					"<div class=\"list_column rou_col align_center\" style=\"width: 34px\">"+p["routine"]+"</div>" +
					"<div class=\"vert_split\"></div>" +
					"<div class=\"list_column rec_col\"><div class=\"padding\">"+p["recommendation"]+"</div></div>" +
					"<div class=\"clear\"></div>";
					var $li = $("<li>")
						.html(str)
						.appendTo($ul)
						.attr("player_id",p["player_id"])
						.attr("player_link",p["player_id"])
						.attr("i",i)
						.addClass("draggable")
						.attr("player_no",p["no"]);
					$li.mouseover(function(){$(this).addClass("hover");})
						.mouseout(function(){$(this).removeClass("hover");});
					$li.find(".favposition").removeClass("short");
					if(on_field[p["player_id"]]) {
						$li.addClass("on_field");
						$li.attr("position",on_field[p["player_id"]]);
					}
					else if(on_subs[p["player_id"]]){
						$li.attr("position",on_subs[p["player_id"]]);
						$li.addClass("on_subs");
					}
					else if(show_field_players_in_list) $li.addClass("subtle_gray");

					// Player link on CTRL+CLICK
					$li.find(".player_name").click(function(e){
						if(e.ctrlKey)
						{
							window.open("/players/"+$(this).attr("player_id")+"/"+$(this).html().replace(" ","_").replace(". ","_")+"/");
						}
					});
					make_draggable($li);
					activate_player_links($li.find("[player_link]"));
				}
			}
		} // i in players
		$list.html($ul);
		$list.verticalScroll({
			"force_scroll": true,
			"style":"dark",
			"scroll_width":25
		});
	}

    
})();