@sjtdev/koishi-plugin-dota2tracker 2.5.9 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.md +18 -0
- package/lib/index.js +408 -237
- package/lib/templates/hero/hero_1/base.css +1 -1
- package/lib/templates/hero/hero_1.ejs +3 -28
- package/lib/templates/player/player_1.ejs +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
html,body{background-color:#000;color:#fff;width:800px}.wrapper>*:not(.skills){margin:5px;box-shadow:0 0 5px #fff;display:flex}img{width:100%;vertical-align:middle}p{margin:0}.hero{position:relative}.hero img{width:25%}.hero .pri_attr{position:absolute;width:48px;left:25%}.hero .info{display:flex;width:75%;flex-direction:column;justify-content:space-around;align-items:center;padding:4px}.hero .info .name{font-size:24px}.hero .info .roles .role{font-size:14px}.hero .info .roles .role:not(:last-child){margin-right:12px}.hero .info .roles .role:after{margin-left:3px;font-size:22px}.hero .info .roles .role.level1:after{content:"\25a0\25a1\25a1"}.hero .info .roles .role.level2:after{content:"\25a0\25a0\25a1"}.hero .info .roles .role.level3:after{content:"\25a0\25a0\25a0"}.hero .info .attrs{height:16px;font-size:16px;line-height:1}.hero .info .attrs>span{margin:0 8px;vertical-align:middle}.hero .info .attrs>span:before{display:inline-block;content:"";background-size:100%;width:16px;height:16px;vertical-align:top}.hero .info .attrs>span.str:before{background-image:url("<%= getImageUrl('hero_strength', ImageType.Icons) %>")}.hero .info .attrs>span.agi:before{background-image:url("<%= getImageUrl('hero_agility', ImageType.Icons) %>")}.hero .info .attrs>span.int:before{background-image:url("<%= getImageUrl('hero_intelligence', ImageType.Icons) %>")}.details{flex-direction:row}.details>*{width:50%}.wrapper .hype{display:block;padding:8px;line-height:1.25}.wrapper .hype .npe{color:#a5e0f3;font-weight:700;line-height:1.25;margin-bottom:8px}.talents{display:grid;grid-template-rows:repeat(4,35px);gap:10px;border:#444 10px solid;box-sizing:border-box;position:relative}.talents:before{content:"";position:absolute;inset:0;background:#444;pointer-events:none;box-sizing:border-box;width:395px;transform:translate(-10px,-10px)}.talents .talent{width:375px;text-align:center;display:flex;align-items:center;background:#000;position:relative}.talents .talent .left,.talents .talent .right{width:170px;font-size:12px}.talents .talent .level{flex:0 0 auto;width:35px;height:35px;font-size:18px;line-height:35px;text-align:center;box-sizing:border-box;border-radius:100%;color:#e7d292;text-shadow:0px 0px 8px #ff531c;background-color:#444}.details .list table td{width:50%;text-align:center}.details .list table tr:nth-child(2n){background-color:#333}.details .list{display:flex;flex-direction:column;padding:6px}.details .list>*{flex-grow:1}.details .bars{height:64px;flex-grow:0}.details .bars>div{height:28px;margin-bottom:4px;border-radius:5px;box-shadow:inset 0 0 2px #00000080,0 0 2px #0000004d;position:relative;display:flex;align-items:center}.details .bars .health{background:linear-gradient(to top,#279027,#27a329 56%,#96e891 83%,#366a35)}.details .bars .mana{background:linear-gradient(to top,#4676c4,#2b76d5 56%,#95cdff)}.details .bars .mana.zero{background:none}.details .bars span{text-shadow:#000 1px 1px 4px}.details .bars .number{font-size:18px;position:absolute;left:50%;transform:translate(-50%)}.details .bars .suffix{margin-left:auto;font-size:14px;padding-right:10px}.details .stats{display:flex;justify-content:space-around;line-height:1.3}.details .stats>.column>p{padding:4px;color:#b2b2b2}.details .stats .stat img{width:20px}.facets{display:flex;flex-wrap:wrap;gap:10px}.facets>.facet,.skill>.facet{flex:1 1 calc(50% - 10px);box-sizing:border-box;background-color:#181f24;position:relative;border:1px solid #2b2f33}.facets>.facet:nth-child(odd):last-child{flex-basis:100%}.facets>.facet>.name_back,.skill>.facet>.name_back{position:absolute;height:50px;width:100%}.facet>.name_back.type_0{background:linear-gradient(to right,#9f3c3c,#4a2026)}.facet>.name_line.type_0{filter:invert(22%) sepia(100%) saturate(100%) hue-rotate(316deg) brightness(98%) contrast(100%)}.facet>.name_back.type_1{background:linear-gradient(to right,#c8a45c,#6f3d21)}.facet>.name_line.type_1{filter:invert(54%) sepia(99%) saturate(100%) hue-rotate(0deg) brightness(97%) contrast(100%)}.facet>.name_back.type_2{background:linear-gradient(to right,#a2b23e,#2d5a18)}.facet>.name_line.type_2{filter:invert(57%) sepia(100%) saturate(100%) hue-rotate(32deg) brightness(93%) contrast(100%)}.facet>.name_back.type_3{background:linear-gradient(to right,#547ea6,#2a385e)}.facet>.name_line.type_3{filter:invert(39%) sepia(100%) saturate(99%) hue-rotate(167deg) brightness(99%) contrast(100%)}.facet>.name_back.type_4{background:linear-gradient(to right,#675cae,#261c44)}.facet>.name_line.type_4{filter:invert(33%) sepia(100%) saturate(100%) hue-rotate(207deg) brightness(99%) contrast(100%)}.facet>.name_back.type_5{background:linear-gradient(to right,#adb6be,#4e5557)}.facet>.name_line.type_5{filter:invert(73%) sepia(23%) saturate(99%) hue-rotate(166deg) brightness(93%) contrast(94%)}.facet>.name_line{position:absolute;background-size:cover;height:50px;width:100%;background-image:url(https://cdn.akamai.steamstatic.com/apps/dota2/images/dota_react/icons/facets/ripple_texture.png)}.facet>.name{height:50px;line-height:50px;z-index:1;position:relative;display:flex}.facet>.name>img{width:24px;padding:13px;background-color:#0003}.facet>.name>span{margin-left:16px;letter-spacing:2px;text-shadow:2px 2px 3px rgba(0,0,0,.3),4px 4px 6px rgba(0,0,0,.2),6px 6px 9px rgba(0,0,0,.1)}.facet>.content{padding:12px;display:flex;flex-direction:column;gap:12px}.facet>.content>.ability{display:flex;flex-direction:column;gap:12px}.facet>.content>.ability>.name{background:linear-gradient(to right,#9bcdff17,#9bcdff09 30%,#d0e8ff00);line-height:1}.facet>.content>.ability>.name>img{width:30px}.facet>.content>.ability>.name>span{margin-left:10px;font-size:14px}.facet>.content .description{color:#9ab0cd}.facet>.content>.ability>.attributes{font-size:12px;display:flex;flex-direction:column;gap:5px}.facet>.content>.ability>.attributes .item{color:#737373}.facet>.content .value{color:#fff}.skills{width:800px;display:flex;flex-wrap:wrap}.skill{background-color:#141b1f;margin:5px;box-shadow:0 0 5px #fff;width:390px}.skill>*:not(:nth-child(2)){padding:0 8px}.skill>.title{position:relative;background-color:#1f272b;padding:8px;font-weight:100;height:auto;width:auto}.skill>.title>.name{font-family:KaiTi,\6977\4f53,\6977\4f53_GB2312,STKaiti,serif}.skill>.title>.is_innate{font-size:14px;line-height:18px;width:auto;display:inline;padding:2px 8px;box-sizing:content-box;background-color:#5b93d1}.skill>.title.name_back>img{width:16px}.skill img.scepter,.skill img.shard{position:absolute;width:24px;right:8px;top:50%;transform:translateY(-50%)}.skill .img_stats{display:flex;color:#546780;margin-bottom:16px;border-top:#2a363c 1px solid;border-bottom:#2a363c 1px solid}.skill .img_stats img{width:128px}.skill .img_stats .stats{padding:8px}.skill .stats .dmg_type.Physical span{color:#ae2f28}.skill .stats .dmg_type.Magical span{color:#5b93d1}.skill .stats .dmg_type.Pure span{color:#c29c4a}.skill .stats .dispellable.No span{color:red}.skill .stats .dispellable.Strong span{color:#9828ae}.skill .stats .bkbpierce.Yes span{color:#6add71}.skill>.description{color:#9bb1ce;margin-bottom:32px}.skill>.facet{padding-left:0;margin-bottom:16px}.skill .value{color:#fff}.skill .aghanim_description{padding:0;color:#9bb1ce;margin-bottom:16px;border:#263945 solid 3px;box-sizing:border-box}.skill .aghanim_description .title{display:block;font-size:20px;background-color:#263945;padding:12px}.skill .aghanim_description .desc{margin:12px;display:block}.skill .aghanim_description img{position:unset;transform:none;margin-right:8px}.skill .notes{padding:12px;margin-bottom:12px;color:#9fb7c6;background-color:#263945}.skill .attributes{line-height:1.2em;margin-bottom:12px}.skill .attributes .heading{color:#546780}.skill .attributes .values{color:#4b525d}.skill .attributes .values img{width:16px}.skill .attributes .facet{display:inline-flex;font-size:1em;align-items:center;line-height:1.2em;position:unset;color:#fff}.skill .attributes .facet span{height:auto;width:auto;position:unset;padding:0 2px}.skill .attributes .facet img{width:auto;height:1em;padding-right:.2em}.skill .attributes .alternative .plus{display:none}.skill .attributes .primary~.alternative .plus{display:inline}.skill .attributes .primary~.alternative:before{content:"("}.skill .attributes .primary~.alternative:after{content:")"}.skill .cooldown{padding-right:12px}.skill .cooldown:before,.skill .mana_cost:before{content:"";background-size:100%;width:21px;height:21px;display:inline-block;vertical-align:middle}.skill .cooldown:before{background-image:url(data:image/webp;base64,UklGRnABAABXRUJQVlA4TGMBAAAvE8AEEE2QTdqmkI5pRP/DS2wBEIT/bw8R/U8Ddq1NipSvGnd3eXJ3d3kmEM+GTDwBciCBTQCd7qpCeokBQdu2cc6f8tcQEBT5P9oEIGiwYuMBECqAbCUVIIAa19Py1I/AQMrJVGEABACe+DRqcl2GUxeOwIAzQkAAMCBxyi3BRcbSkzAKyIDTciQOAAgwyx43JA4CWRkeQXAAQKkGEs5+/siARwFHAHCUiAGwPwAEAGQSDgCAoCQUQc7OkwMbhgAAJBIKEAtkE9enBgcABEUxAIwyZ6cOx/lTkPiHsX+mqCQTMQRwcmAszPLUoTiCkVAAbDKEAWWUjWlGMYyEAR4n4wMeiBk8W9M1lphIQmAsmWxBJ1vfAJZIBMAoJwNQ0JTN04/yRaCCftofwWBkAMAjQ6BILaWMsEkFFVTTk/qEETyQlYFXnh9jmABKbkgzNQgemYwnTOKFEgAAOGJAeUbyhQIAAA==)}.skill .mana_cost:before{background-image:url(data:image/webp;base64,UklGRsYAAABXRUJQVlA4TLkAAAAvE8AEEIfBOIDbtEmdpEDhS8G2kSTF0eteuLOebJz/0KDREgwBAGEu/89yqe5LCyEaDT03NBcLpEXnJgkZKS2dmlqAlNSCgJXURBoNCHAY2bbSvEP0fxzi7sGh//rslRDR/xQxS0bXRkRMmr5Ho8iISY5523Ztr2vabBuaZZLVE99wRqWAUgGFAv4K+Cngo4CXAp4KeCjgroCbAi4KVv7pOnFwF8aP9+fRXeAaMZ63GbXWiIhxGJ0bEQA=)}.skill .lore{font-size:13px;color:#3e4f5b;padding:8px;line-height:1.25}body .wrapper>.lore{display:block;line-height:1.25;padding:8px;font-family:KaiTi,\6977\4f53,\6977\4f53_GB2312,STKaiti,serif;color:#aaa}
|
|
1
|
+
html,body{background-color:#000;color:#fff;width:800px}.wrapper>*:not(.skills){margin:5px;box-shadow:0 0 5px #fff;display:flex}img{width:100%;vertical-align:middle}p{margin:0}.hero{position:relative}.hero img{width:25%}.hero .pri_attr{position:absolute;width:48px;left:25%}.hero .info{display:flex;width:75%;flex-direction:column;justify-content:space-around;align-items:center;padding:4px}.hero .info .name{font-size:24px}.hero .info .roles .role{font-size:14px}.hero .info .roles .role:not(:last-child){margin-right:12px}.hero .info .roles .role:after{margin-left:3px;font-size:22px}.hero .info .roles .role.level1:after{content:"\25a0\25a1\25a1"}.hero .info .roles .role.level2:after{content:"\25a0\25a0\25a1"}.hero .info .roles .role.level3:after{content:"\25a0\25a0\25a0"}.hero .info .attrs{height:16px;font-size:16px;line-height:1}.hero .info .attrs>span{margin:0 8px;vertical-align:middle}.hero .info .attrs>span:before{display:inline-block;content:"";background-size:100%;width:16px;height:16px;vertical-align:top}.hero .info .attrs>span.str:before{background-image:url("<%= getImageUrl('hero_strength', ImageType.Icons) %>")}.hero .info .attrs>span.agi:before{background-image:url("<%= getImageUrl('hero_agility', ImageType.Icons) %>")}.hero .info .attrs>span.int:before{background-image:url("<%= getImageUrl('hero_intelligence', ImageType.Icons) %>")}.details{flex-direction:row}.details>*{width:50%}.wrapper .hype{display:block;padding:8px;line-height:1.25}.wrapper .hype .npe{color:#a5e0f3;font-weight:700;line-height:1.25;margin-bottom:8px}.talents{display:grid;grid-template-rows:repeat(4,35px);gap:10px;border:#444 10px solid;box-sizing:border-box;position:relative}.talents:before{content:"";position:absolute;inset:0;background:#444;pointer-events:none;box-sizing:border-box;width:395px;transform:translate(-10px,-10px)}.talents .talent{width:375px;text-align:center;display:flex;align-items:center;background:#000;position:relative}.talents .talent .left,.talents .talent .right{width:170px;font-size:12px}.talents .talent .level{flex:0 0 auto;width:35px;height:35px;font-size:18px;line-height:35px;text-align:center;box-sizing:border-box;border-radius:100%;color:#e7d292;text-shadow:0px 0px 8px #ff531c;background-color:#444}.details .list table td{width:50%;text-align:center}.details .list table tr:nth-child(2n){background-color:#333}.details .list{display:flex;flex-direction:column;padding:6px}.details .list>*{flex-grow:1}.details .bars{height:64px;flex-grow:0}.details .bars>div{height:28px;margin-bottom:4px;border-radius:5px;box-shadow:inset 0 0 2px #00000080,0 0 2px #0000004d;position:relative;display:flex;align-items:center}.details .bars .health{background:linear-gradient(to top,#279027,#27a329 56%,#96e891 83%,#366a35)}.details .bars .mana{background:linear-gradient(to top,#4676c4,#2b76d5 56%,#95cdff)}.details .bars .mana.zero{background:none}.details .bars span{text-shadow:#000 1px 1px 4px}.details .bars .number{font-size:18px;position:absolute;left:50%;transform:translate(-50%)}.details .bars .suffix{margin-left:auto;font-size:14px;padding-right:10px}.details .stats{display:flex;justify-content:space-around;line-height:1.3}.details .stats>.column>p{padding:4px;color:#b2b2b2}.details .stats .stat img{width:20px}.facets{display:flex;flex-wrap:wrap;gap:10px}.facets>.facet,.skill>.facet{flex:1 1 calc(50% - 10px);box-sizing:border-box;background-color:#181f24;position:relative;border:1px solid #2b2f33}.facets>.facet:nth-child(odd):last-child{flex-basis:100%}.facets>.facet>.name_back,.skill>.facet>.name_back{position:absolute;height:50px;width:100%}.facet>.name_back.type_0{background:linear-gradient(to right,#9f3c3c,#4a2026)}.facet>.name_line.type_0{filter:invert(22%) sepia(100%) saturate(100%) hue-rotate(316deg) brightness(98%) contrast(100%)}.facet>.name_back.type_1{background:linear-gradient(to right,#c8a45c,#6f3d21)}.facet>.name_line.type_1{filter:invert(54%) sepia(99%) saturate(100%) hue-rotate(0deg) brightness(97%) contrast(100%)}.facet>.name_back.type_2{background:linear-gradient(to right,#a2b23e,#2d5a18)}.facet>.name_line.type_2{filter:invert(57%) sepia(100%) saturate(100%) hue-rotate(32deg) brightness(93%) contrast(100%)}.facet>.name_back.type_3{background:linear-gradient(to right,#547ea6,#2a385e)}.facet>.name_line.type_3{filter:invert(39%) sepia(100%) saturate(99%) hue-rotate(167deg) brightness(99%) contrast(100%)}.facet>.name_back.type_4{background:linear-gradient(to right,#675cae,#261c44)}.facet>.name_line.type_4{filter:invert(33%) sepia(100%) saturate(100%) hue-rotate(207deg) brightness(99%) contrast(100%)}.facet>.name_back.type_5{background:linear-gradient(to right,#adb6be,#4e5557)}.facet>.name_line.type_5{filter:invert(73%) sepia(23%) saturate(99%) hue-rotate(166deg) brightness(93%) contrast(94%)}.facet>.name_line{position:absolute;background-size:cover;height:50px;width:100%;background-image:url(https://cdn.akamai.steamstatic.com/apps/dota2/images/dota_react/icons/facets/ripple_texture.png)}.facet>.name{height:50px;line-height:50px;z-index:1;position:relative;display:flex}.facet>.name>img{width:24px;padding:13px;background-color:#0003}.facet>.name>span{margin-left:16px;letter-spacing:2px;text-shadow:2px 2px 3px rgba(0,0,0,.3),4px 4px 6px rgba(0,0,0,.2),6px 6px 9px rgba(0,0,0,.1)}.facet>.content{padding:12px;display:flex;flex-direction:column;gap:12px}.facet>.content>.ability{display:flex;flex-direction:column;gap:12px}.facet>.content>.ability>.name{background:linear-gradient(to right,#9bcdff17,#9bcdff09 30%,#d0e8ff00);line-height:1}.facet>.content>.ability>.name>img{width:30px}.facet>.content>.ability>.name>span{margin-left:10px;font-size:14px}.facet>.content .description{color:#9ab0cd}.facet>.content>.ability>.attributes{font-size:12px;display:flex;flex-direction:column;gap:5px}.facet>.content>.ability>.attributes .item{color:#737373}.facet>.content .value{color:#fff}.skills{width:800px;display:flex;flex-wrap:wrap}.skill{background-color:#141b1f;margin:5px;box-shadow:0 0 5px #fff;width:390px}.skill>*:not(:nth-child(2)){padding:0 8px}.skill>.title{position:relative;background-color:#1f272b;padding:8px;font-weight:100;height:auto;width:auto}.skill>.title>.name{font-family:KaiTi,\6977\4f53,\6977\4f53_GB2312,STKaiti,serif}.skill>.title>.is_innate{font-size:14px;line-height:18px;width:auto;display:inline;padding:2px 8px;box-sizing:content-box;background-color:#5b93d1}.skill>.title.name_back>img{width:16px}.skill img.scepter,.skill img.shard{position:absolute;width:24px;right:8px;top:50%;transform:translateY(-50%)}.skill .img_stats{display:flex;color:#546780;margin-bottom:16px;border-top:#2a363c 1px solid;border-bottom:#2a363c 1px solid}.skill .img_stats img{width:128px}.skill .img_stats .stats{padding:8px}.skill .stats .dmg_type.Physical span{color:#ae2f28}.skill .stats .dmg_type.Magical span{color:#5b93d1}.skill .stats .dmg_type.Pure span{color:#c29c4a}.skill .stats .dispellable.No span{color:red}.skill .stats .dispellable.Strong span{color:#9828ae}.skill .stats .bkbpierce.Yes span{color:#6add71}.skill>.description{color:#9bb1ce;margin-bottom:32px}.skill>.facet{padding-left:0;margin-bottom:16px}.skill .value{color:#fff}.skill .aghanim_description{padding:0;color:#9bb1ce;margin-bottom:16px;border:#263945 solid 3px;box-sizing:border-box}.skill .aghanim_description .title{display:block;font-size:20px;background-color:#263945;padding:12px}.skill .aghanim_description .desc{margin:12px;display:block}.skill .aghanim_description img{position:unset;transform:none;margin-right:8px}.skill .notes{padding:12px;margin-bottom:12px;color:#9fb7c6;background-color:#263945}.skill .attributes{line-height:1.2em;margin-bottom:12px}.skill .attributes .heading{color:#546780}.skill .attributes .values{color:#4b525d}.skill .attributes .values img{width:16px}.skill .attributes .facet{display:inline-flex;font-size:1em;align-items:center;line-height:1.2em;position:unset;color:#fff}.skill .attributes .facet span{height:auto;width:auto;position:unset;padding:0 2px}.skill .attributes .facet img{width:auto;height:1em;padding-right:.2em}.skill .attributes .alternative .plus{display:none}.skill .attributes .primary~.alternative .plus{display:inline}.skill .attributes .primary~.alternative:before{content:"("}.skill .attributes .primary~.alternative:after{content:")"}.skill .cooldown{padding-right:12px}.skill .cooldown:before,.skill .mana_cost:before{content:"";background-size:100%;width:21px;height:21px;display:inline-block;vertical-align:middle}.skill .cooldown:before{background-image:url(data:image/webp;base64,UklGRnABAABXRUJQVlA4TGMBAAAvE8AEEE2QTdqmkI5pRP/DS2wBEIT/bw8R/U8Ddq1NipSvGnd3eXJ3d3kmEM+GTDwBciCBTQCd7qpCeokBQdu2cc6f8tcQEBT5P9oEIGiwYuMBECqAbCUVIIAa19Py1I/AQMrJVGEABACe+DRqcl2GUxeOwIAzQkAAMCBxyi3BRcbSkzAKyIDTciQOAAgwyx43JA4CWRkeQXAAQKkGEs5+/siARwFHAHCUiAGwPwAEAGQSDgCAoCQUQc7OkwMbhgAAJBIKEAtkE9enBgcABEUxAIwyZ6cOx/lTkPiHsX+mqCQTMQRwcmAszPLUoTiCkVAAbDKEAWWUjWlGMYyEAR4n4wMeiBk8W9M1lphIQmAsmWxBJ1vfAJZIBMAoJwNQ0JTN04/yRaCCftofwWBkAMAjQ6BILaWMsEkFFVTTk/qEETyQlYFXnh9jmABKbkgzNQgemYwnTOKFEgAAOGJAeUbyhQIAAA==)}.skill .mana_cost:before{background-image:url(data:image/webp;base64,UklGRsYAAABXRUJQVlA4TLkAAAAvE8AEEIfBOIDbtEmdpEDhS8G2kSTF0eteuLOebJz/0KDREgwBAGEu/89yqe5LCyEaDT03NBcLpEXnJgkZKS2dmlqAlNSCgJXURBoNCHAY2bbSvEP0fxzi7sGh//rslRDR/xQxS0bXRkRMmr5Ho8iISY5523Ztr2vabBuaZZLVE99wRqWAUgGFAv4K+Cngo4CXAp4KeCjgroCbAi4KVv7pOnFwF8aP9+fRXeAaMZ63GbXWiIhxGJ0bEQA=)}.skill .lore{font-size:13px;color:#3e4f5b;padding:8px;line-height:1.25}body .wrapper>.lore{display:block;line-height:1.25;padding:8px;font-family:KaiTi,\6977\4f53,\6977\4f53_GB2312,STKaiti,serif;color:#aaa}.patches{display:flex;flex-direction:column;gap:12px;.patch_number{color:#887d4f;margin-bottom:4px;.patch_time{color:#555}}}.wrapper>.patches{padding:12px}.skill .patches{padding:9px;background-color:#19222b;font-size:14px;color:#888}.wrapper>.game_version{display:block;box-shadow:none;text-align:right;color:#888;font-size:12px;padding:15px 0}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const base_damage = Math.floor((hero.str_base+hero.agi_base+hero.int_base)*0.45);
|
|
3
3
|
hero.damage_max+=base_damage;
|
|
4
4
|
hero.damage_min+=base_damage;
|
|
5
|
-
} %> <% const primary_attrs = { "3": "hero_universal", "0": "hero_strength", "1": "hero_agility", "2": "hero_intelligence" }; %> <% const hero_dc = dotaconstants.heroes[hero.id]; %> <div class="wrapper"><div class="hero" id="<%= hero.id %>"><img src="<%= getImageUrl(hero["name"].match(/^npc_dota_hero_(.+)$/)[1], ImageType.Heroes) %>"/> <img class="pri_attr" src="<%= getImageUrl(primary_attrs[hero.primary_attr], ImageType.Icons) %>"/><div class="info"><p class="name"><%= hero.name_loc %></p><p class="roles"> <% hero.role_levels.forEach((item, index) => { %> <% if (item > 0) { %> <span class="role level<%= item %>"><%= $t("dota2tracker.template.roles."+index) %></span> <% } %> <% }); %> </p><p class="attrs"><span class="str"><%= hero.str_base %> <span class="gain">+<%= hero.str_gain.toFixed(1) %></span></span><span class="agi"><%= hero.agi_base %> <span class="gain">+<%= hero.agi_gain.toFixed(1) %></span></span><span class="int"><%= hero.int_base %> <span class="gain">+<%= hero.int_gain.toFixed(1) %></span></span></p></div></div><div class="hype"><p class="npe"><%= hero.npe_desc_loc %></p> <%- hero.hype_loc %> </div><div class="details"><div class="talents"><div class="talent"><div class="left"><%= hero.talents[7].name_loc %></div><div class="level">25</div><div class="right"><%= hero.talents[6].name_loc %></div></div><div class="talent"><div class="left"><%= hero.talents[5].name_loc %></div><div class="level">20</div><div class="right"><%= hero.talents[4].name_loc %></div></div><div class="talent"><div class="left"><%= hero.talents[3].name_loc %></div><div class="level">15</div><div class="right"><%= hero.talents[2].name_loc %></div></div><div class="talent"><div class="left"><%= hero.talents[1].name_loc %></div><div class="level">10</div><div class="right"><%= hero.talents[0].name_loc %></div></div></div><div class="list"><div class="bars"><div class="health"><span class="number"><%= hero.max_health %></span><span class="suffix">+<%= hero.health_regen.toFixed(1) %></span></div><div class="mana<%= !hero.max_mana ? ' zero' : '' %>"><span class="number"><%= hero.max_mana %></span><span class="suffix">+<%= hero.mana_regen.toFixed(1) %></span></div></div><div class="stats"><div class="column"><p><%= $t("dota2tracker.template.attack") %></p><div class="stat"><img src="<%= getImageUrl("icon_damage", ImageType.HeroStats) %>"/> <span><%= hero.damage_min %>~<%= hero.damage_max %></span></div><div class="stat"><img src="<%= getImageUrl("icon_attack_time", ImageType.HeroStats) %>"/> <span><%= hero.attack_rate.toFixed(1) %></span></div><div class="stat"><img src="<%= getImageUrl("icon_attack_range", ImageType.HeroStats) %>"/> <span><%= hero.attack_range %></span></div> <% if (hero_dc.attack_type !== "Melee") { %> <div class="stat"><img src="<%= getImageUrl("icon_projectile_speed", ImageType.HeroStats) %>"/> <span><%= hero.projectile_speed %></span></div> <% } %> </div><div class="column"><p><%= $t("dota2tracker.template.defense") %></p><div class="stat"><img src="<%= getImageUrl("icon_armor", ImageType.HeroStats) %>"/> <span><%= hero.armor.toFixed(1) %></span></div><div class="stat"><img src="<%= getImageUrl("icon_magic_resist", ImageType.HeroStats) %>"/> <span><%= hero.magic_resistance %>%</span></div></div><div class="column"><p><%= $t("dota2tracker.template.mobility") %></p><div class="stat"><img src="<%= getImageUrl("icon_movement_speed", ImageType.HeroStats) %>"/> <span><%= hero.movement_speed %></span></div><div class="stat"><img src="<%= getImageUrl("icon_turn_rate", ImageType.HeroStats) %>"/> <span><%= hero.turn_rate.toFixed(1) %></span></div><div class="stat"><img src="<%= getImageUrl("icon_vision", ImageType.HeroStats) %>"/> <span><%= hero.sight_range_day %> / <%= hero.sight_range_night %></span></div></div></div></div></div><div class="skills"> <% hero.abilities.forEach((item) => {
|
|
5
|
+
} %> <% const primary_attrs = { "3": "hero_universal", "0": "hero_strength", "1": "hero_agility", "2": "hero_intelligence" }; %> <% const hero_dc = dotaconstants.heroes[hero.id]; %> <div class="wrapper"><div class="hero" id="<%= hero.id %>"><img src="<%= getImageUrl(hero["name"].match(/^npc_dota_hero_(.+)$/)[1], ImageType.Heroes) %>"/> <img class="pri_attr" src="<%= getImageUrl(primary_attrs[hero.primary_attr], ImageType.Icons) %>"/><div class="info"><p class="name"><%= hero.name_loc %></p><p class="roles"> <% hero.role_levels.forEach((item, index) => { %> <% if (item > 0) { %> <span class="role level<%= item %>"><%= $t("dota2tracker.template.roles."+index) %></span> <% } %> <% }); %> </p><p class="attrs"><span class="str"><%= hero.str_base %> <span class="gain">+<%= hero.str_gain.toFixed(1) %></span></span><span class="agi"><%= hero.agi_base %> <span class="gain">+<%= hero.agi_gain.toFixed(1) %></span></span><span class="int"><%= hero.int_base %> <span class="gain">+<%= hero.int_gain.toFixed(1) %></span></span></p></div></div><div class="hype"><p class="npe"><%= hero.npe_desc_loc %></p> <%- hero.hype_loc %> </div><div class="details"><div class="talents"><div class="talent"><div class="left"><%= hero.talents[7].name_loc %></div><div class="level">25</div><div class="right"><%= hero.talents[6].name_loc %></div></div><div class="talent"><div class="left"><%= hero.talents[5].name_loc %></div><div class="level">20</div><div class="right"><%= hero.talents[4].name_loc %></div></div><div class="talent"><div class="left"><%= hero.talents[3].name_loc %></div><div class="level">15</div><div class="right"><%= hero.talents[2].name_loc %></div></div><div class="talent"><div class="left"><%= hero.talents[1].name_loc %></div><div class="level">10</div><div class="right"><%= hero.talents[0].name_loc %></div></div></div><div class="list"><div class="bars"><div class="health"><span class="number"><%= hero.max_health %></span><span class="suffix">+<%= hero.health_regen.toFixed(1) %></span></div><div class="mana<%= !hero.max_mana ? ' zero' : '' %>"><span class="number"><%= hero.max_mana %></span><span class="suffix">+<%= hero.mana_regen.toFixed(1) %></span></div></div><div class="stats"><div class="column"><p><%= $t("dota2tracker.template.attack") %></p><div class="stat"><img src="<%= getImageUrl("icon_damage", ImageType.HeroStats) %>"/> <span><%= hero.damage_min %>~<%= hero.damage_max %></span></div><div class="stat"><img src="<%= getImageUrl("icon_attack_time", ImageType.HeroStats) %>"/> <span><%= hero.attack_rate.toFixed(1) %></span></div><div class="stat"><img src="<%= getImageUrl("icon_attack_range", ImageType.HeroStats) %>"/> <span><%= hero.attack_range %></span></div> <% if (hero_dc.attack_type !== "Melee") { %> <div class="stat"><img src="<%= getImageUrl("icon_projectile_speed", ImageType.HeroStats) %>"/> <span><%= hero.projectile_speed %></span></div> <% } %> </div><div class="column"><p><%= $t("dota2tracker.template.defense") %></p><div class="stat"><img src="<%= getImageUrl("icon_armor", ImageType.HeroStats) %>"/> <span><%= hero.armor.toFixed(1) %></span></div><div class="stat"><img src="<%= getImageUrl("icon_magic_resist", ImageType.HeroStats) %>"/> <span><%= hero.magic_resistance %>%</span></div></div><div class="column"><p><%= $t("dota2tracker.template.mobility") %></p><div class="stat"><img src="<%= getImageUrl("icon_movement_speed", ImageType.HeroStats) %>"/> <span><%= hero.movement_speed %></span></div><div class="stat"><img src="<%= getImageUrl("icon_turn_rate", ImageType.HeroStats) %>"/> <span><%= hero.turn_rate.toFixed(1) %></span></div><div class="stat"><img src="<%= getImageUrl("icon_vision", ImageType.HeroStats) %>"/> <span><%= hero.sight_range_day %> / <%= hero.sight_range_night %></span></div></div></div></div></div> <% if (hero.patch_notes && hero.patch_notes.length > 0) { %> <div class="patches"> <% hero.patch_notes.forEach(patch => { %> <div class="patch_group"><p class="patch_number"><%= patch.patch_number %> <span class="patch_time">(<%= new Date(patch.patch_timestamp * 1000).toISOString().split('T')[0] %>)</span>:</p> <% patch.notes.forEach(note => { %> <p data-indent="<%= note.indent_level %>"><%- note.note %></p> <% }); %> </div> <% }); %> </div> <% } %> <div class="skills"> <% hero.abilities.forEach((item) => {
|
|
6
6
|
const ability_dc = dotaconstants.abilities[item.name];
|
|
7
7
|
|
|
8
8
|
// 预先查找冷却和耗蓝数据,避免在HTML中反复find
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// 预先计算是否需要显示冷却/耗蓝 (非空 且 不全为0)
|
|
13
13
|
const hasCd = cdStats?.values_float.length && !(cdStats.values_float.length === 1 && cdStats.values_float[0] === 0);
|
|
14
14
|
const hasMana = manaStats?.values_float.length && !(manaStats.values_float.length === 1 && manaStats.values_float[0] === 0);
|
|
15
|
-
%> <div class="skill" data-innate="<%= item.ability_is_innate %>"><p class="title"><span class="name font-serif"><%= item.name_loc %></span> <% if (item.ability_is_innate) { %> <span class="is_innate"><%= $t("dota2tracker.template.innate") %></span> <% } %> <% if (item.ability_is_granted_by_scepter) { %> <img src="<%= getImageUrl("scepter") %>" class="scepter"> <% } %> <% if (item.ability_is_granted_by_shard) { %> <img src="<%= getImageUrl("shard") %>" class="shard"> <% } %> </p><div class="img_stats"><img src="<%= getImageUrl(item.name, ImageType.Abilities) %>" onerror="this.onerror=null; this.src='<%= getImageUrl(`innate_icon`, ImageType.Icons) %>';"/><div class="stats"><p class="behavior"> <%= $t("dota2tracker.template.ability") %> <%= [].concat(ability_dc?.behavior)
|
|
15
|
+
%> <div class="skill" data-innate="<%= item.ability_is_innate %>"><p class="title"><span class="name font-serif"><%= item.name_loc %></span> <% if (item.ability_is_innate) { %> <span class="is_innate"><%= $t("dota2tracker.template.innate") %></span> <% } %> <% if (item.ability_is_granted_by_scepter) { %> <img src="<%= getImageUrl("scepter") %>" class="scepter"> <% } %> <% if (item.ability_is_granted_by_shard) { %> <img src="<%= getImageUrl("shard") %>" class="shard"> <% } %> </p><div class="img_stats"><img src="<%= getImageUrl(item.name, ImageType.Abilities) %>" onerror="this.onerror=null; this.src='<%= getImageUrl(`innate_icon`, ImageType.Icons) %>'; if(this.closest('.skill').dataset.innate === 'true') { this.closest('.skill').style.order = -1; this.closest('.skill').style.flexBasis = '100%'; }"/><div class="stats"><p class="behavior"> <%= $t("dota2tracker.template.ability") %> <%= [].concat(ability_dc?.behavior)
|
|
16
16
|
.filter((beh) => beh !== "Hidden" || !(item.ability_is_granted_by_shard || item.ability_is_granted_by_scepter))
|
|
17
17
|
.map((beh) => $t("dota2tracker.template.behavior." + beh)).join("/") %> </p> <% if (ability_dc?.target_team) { %> <p class="target_team"> <%= $t("dota2tracker.template.affects") %> <%= [].concat(ability_dc?.target_team).map((tt) => $t("dota2tracker.template.target_team." + tt)).join("/") %> </p> <% } %> <% if (!Array.isArray(ability_dc?.dmg_type) && ability_dc?.dmg_type) { %> <p class="dmg_type <%= ability_dc?.dmg_type %>"> <%= $t("dota2tracker.template.damage_type") %> <span><%= $t("dota2tracker.template.damage_type_" + ability_dc?.dmg_type) %></span></p> <% } %> <% if (ability_dc?.dispellable) { %> <p class="dispellable <%= ability_dc?.dispellable == 'Strong Dispels Only' ? 'Strong' : ability_dc?.dispellable %>"> <%= $t("dota2tracker.template.dispellable") %> <span><%= $t("dota2tracker.template." + (ability_dc?.dispellable == "Strong Dispels Only" ? "dispellable_Strong" : ability_dc?.dispellable)) %></span></p> <% } %> <% if (!Array.isArray(ability_dc?.bkbpierce) && ability_dc?.bkbpierce) { %> <p class="bkbpierce <%= ability_dc?.bkbpierce %>"> <%= $t("dota2tracker.template.bkbpierce") %> <span><%= $t("dota2tracker.template." + ability_dc?.bkbpierce) %></span></p> <% } %> </div></div><p class="description"><%- item.desc_loc %></p> <% if (item.ability_has_scepter && !item.ability_is_granted_by_scepter && item.scepter_loc) { %> <p class="aghanim_description"><span class="title"><img src="<%= getImageUrl("scepter") %>" class="scepter"><%= $t("dota2tracker.template.scepter") %></span><span class="desc"><%- item.scepter_loc %></span></p> <% } %> <% if (item.ability_has_shard && !item.ability_is_granted_by_shard && item.shard_loc) { %> <p class="aghanim_description"><span class="title"><img src="<%= getImageUrl("shard") %>" class="shard"><%= $t("dota2tracker.template.shard") %></span><span class="desc"><%- item.shard_loc %></span></p> <% } %> <% if (item.notes_loc && item.notes_loc.length > 0) { %> <div class="notes"> <% item.notes_loc.forEach((note) => { %> <p><%- note %></p> <% }); %> </div> <% } %> <div class="attributes"> <%
|
|
18
18
|
item.special_values.filter(sv => sv.heading_loc).forEach((sv) => {
|
|
@@ -21,29 +21,4 @@
|
|
|
21
21
|
const hasScepterVal = sv.values_scepter && sv.values_scepter.length;
|
|
22
22
|
const hasShardVal = sv.values_shard && sv.values_shard.length;
|
|
23
23
|
const hasTalentVal = sv.bonuses.length > 0;
|
|
24
|
-
%> <% if (!isAllZero || hasScepterVal || hasShardVal || hasTalentVal) { %> <p><span class="heading"><%- sv.heading_loc %></span><span class="values"> <% if (!isAllZero || (isAllZero && (hasScepterVal || hasShardVal))) { %> <span class="primary<%= isAllZero ? ' empty' : '' %>"> <% if (!isAllZero) { %> <%= sv.values_float.map(value => value + (sv.is_percentage ? "%" : "")).join(" / ") %> <% } %> </span> <% } %> <% if (hasScepterVal) { %> <span class="alternative scepter"><img src="<%= getImageUrl("scepter") %>"/> <%- sv.values_scepter.map(value => (value > 0 ? '<span class="plus">+</span>' : "") + value + (sv.is_percentage ? "%" : "")).join(" / ") %> </span> <% } %> <% if (hasShardVal) { %> <span class="alternative shard"><img src="<%= getImageUrl("shard") %>"/> <%- sv.values_shard.map(value => (value > 0 ? '<span class="plus">+</span>' : "") + value + (sv.is_percentage ? "%" : "")).join(" / ") %> </span> <% } %> <% if (hasTalentVal) { %> <span class="alternative talent"> <% sv.bonuses.forEach(bonus => { %> <img src="<%= getImageUrl("talents", "icons", "svg") %>"/> <%- (bonus.value > 0 ? '<span class="plus">+</span>' : "") + bonus.value + (sv.is_percentage ? "%" : "") %> <% }); %> </span> <% } %> </span></p> <% } %> <% }); %> </div><p> <% if (hasCd) { %> <span class="cooldown"> <%= cdStats.values_float.join(" / ") %> </span> <% } %> <% if (hasMana) { %> <span class="mana_cost"> <%= manaStats.values_float.join(" / ") %> </span> <% } %> </p> <% if (item.lore_loc) { %> <p class="lore"><%= item.lore_loc %></p> <% } %> </div> <% }); %> </div><div class="lore"> <%- hero.bio_loc %> </div></div></body
|
|
25
|
-
const items = document.querySelectorAll('.skills > .skill');
|
|
26
|
-
items.forEach(item => {
|
|
27
|
-
// const name = item.getAttribute('data-name');
|
|
28
|
-
const abilityIsInnate = item.getAttribute('data-innate') === 'true';
|
|
29
|
-
const img = item.querySelector('.img_stats > img');
|
|
30
|
-
const imageUrl = img.src;
|
|
31
|
-
|
|
32
|
-
// Check if image exists
|
|
33
|
-
const image = new Image();
|
|
34
|
-
image.src = imageUrl;
|
|
35
|
-
image.onload = function() {
|
|
36
|
-
// Image exists, do nothing
|
|
37
|
-
};
|
|
38
|
-
image.onerror = function() {
|
|
39
|
-
// Image doesn't exist
|
|
40
|
-
if (abilityIsInnate) {
|
|
41
|
-
item.style.order = -1;
|
|
42
|
-
item.style.flexBasis = "100%";
|
|
43
|
-
img.src = '<%- getImageUrl("innate_icon",ImageType.Icons) %>'; // Set backup image URL
|
|
44
|
-
// item.querySelector(".cooldown").style.display = "none";
|
|
45
|
-
// item.querySelector(".mana_cost").style.display = "none";
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
});
|
|
49
|
-
});</script></html>
|
|
24
|
+
%> <% if (!isAllZero || hasScepterVal || hasShardVal || hasTalentVal) { %> <p><span class="heading"><%- sv.heading_loc %></span><span class="values"> <% if (!isAllZero || (isAllZero && (hasScepterVal || hasShardVal))) { %> <span class="primary<%= isAllZero ? ' empty' : '' %>"> <% if (!isAllZero) { %> <%= sv.values_float.map(value => value + (sv.is_percentage ? "%" : "")).join(" / ") %> <% } %> </span> <% } %> <% if (hasScepterVal) { %> <span class="alternative scepter"><img src="<%= getImageUrl("scepter") %>"/> <%- sv.values_scepter.map(value => (value > 0 ? '<span class="plus">+</span>' : "") + value + (sv.is_percentage ? "%" : "")).join(" / ") %> </span> <% } %> <% if (hasShardVal) { %> <span class="alternative shard"><img src="<%= getImageUrl("shard") %>"/> <%- sv.values_shard.map(value => (value > 0 ? '<span class="plus">+</span>' : "") + value + (sv.is_percentage ? "%" : "")).join(" / ") %> </span> <% } %> <% if (hasTalentVal) { %> <span class="alternative talent"> <% sv.bonuses.forEach(bonus => { %> <img src="<%= getImageUrl("talents", "icons", "svg") %>"/> <%- (bonus.value > 0 ? '<span class="plus">+</span>' : "") + bonus.value + (sv.is_percentage ? "%" : "") %> <% }); %> </span> <% } %> </span></p> <% } %> <% }); %> </div><p> <% if (hasCd) { %> <span class="cooldown"> <%= cdStats.values_float.join(" / ") %> </span> <% } %> <% if (hasMana) { %> <span class="mana_cost"> <%= manaStats.values_float.join(" / ") %> </span> <% } %> </p> <% if (item.lore_loc) { %> <p class="lore"><%= item.lore_loc %></p> <% } %> <% if (item.patch_notes && item.patch_notes.length > 0) { %> <div class="patches"> <% item.patch_notes.forEach(patch => { %> <div class="patch_group"><p class="patch_number"><%= patch.patch_number %> <span class="patch_time">(<%= new Date(patch.patch_timestamp * 1000).toISOString().split('T')[0] %>)</span>:</p> <% patch.notes.forEach(note => { %> <p data-indent="<%= note.indent_level %>"><%- note.note %></p> <% }); %> </div> <% }); %> </div> <% } %> </div> <% }); %> </div><div class="lore"> <%- hero.bio_loc %> </div><p class="game_version"><%= $t("dota2tracker.template.generated_at") %> <%= hero.game_version %></p></div></body></html>
|
|
@@ -75,4 +75,4 @@
|
|
|
75
75
|
const impAvg = posMatches.length > 0 ? Math.round(posMatches.reduce((acc, m) => acc + m.players.find(ip => ip.steamAccount.id == p.steamAccount.id).imp, 0) / posMatches.length) : "-";
|
|
76
76
|
p.positionPerformance.push({ pos: i + 1, icon: posIcons[i], matchCount: posMatches.length, winCount: wins, imp: impAvg });
|
|
77
77
|
}
|
|
78
|
-
%> <% const posScale = getScale(p.positionPerformance.filter(pos => pos.matchCount > 1), true); %> <!DOCTYPE html><html lang="<%= languageTag %>"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Player</title> <%- `<style>` %> <%- include("../common/styles/normalize.min.css") %> <%- include(`./player_1/base.css`) %> <%- `</style>` %> </head><body><div class="wrapper"><div class="player"><div class="avatar"><img src="<%= p.steamAccount?.avatar %>" alt=""/></div><div class="info"><p class="name"> <%= p.steamAccount.name %> <% if (p.guildMember) { %> <span class="guild <%= getGuildClass(p.guildMember.guild.currentPercentile) %>"><%= p.guildMember.guild.tag %></span> <% } %> <% if (p.genHero) { %> <span class="hero_name"><%= p.genHero.name %></span> <% } %> </p><p class="matches"> <%= $t("dota2tracker.template.match_count_") %><%= p.matchCount %> (<span class="win"><%= p.winCount %></span>/<span class="lose"><%= p.matchCount - p.winCount %></span>) <%= $t("dota2tracker.template.winrate_") %> <span <%- `style="color:${getWinRateColor(p.winCount / p.matchCount)};"` %>><%= ((p.winCount / p.matchCount) * 100).toFixed(2) %>%</span></p><p class="matches<%= isAnon ? " blur" : "" %>"><span><%= $t("dota2tracker.template.last25matches_") %> <span class="win"><%= nearWin %></span>/<span class="lose"><%= nearCount - nearWin %></span></span> <span><%= $t("dota2tracker.template.winrate_") %> <span <%- `style="color:${getWinRateColor(nearWin / nearCount)};"` %>><%= ((nearWin / nearCount) * 100).toFixed(2) %>%</span> </span> <span><%= $t("dota2tracker.template.imp_") %><%= isAnon ? "?" : ((p.performance?.imp > 0 ? "+" : "") + p.performance?.imp) %></span></p><p class="matches<%= isAnon ? " blur" : "" %>"><span><%= $t("dota2tracker.template.lane") %> <span class="victory"><%= outcomes.victory + outcomes.stomp %>(<span class="stomp"><%= outcomes.stomp %></span>)</span>-<span class="tie"><%= outcomes.tie %></span>-<span class="fail"><%= outcomes.fail + outcomes.stomped %>(<span class="stomped"><%= outcomes.stomped %></span>)</span> </span> <% const laneTotal = outcomes.victory + outcomes.stomp + outcomes.tie + outcomes.fail + outcomes.stomped; %> <% const laneScore = (outcomes.victory + outcomes.stomp + outcomes.tie / 2) / laneTotal; %> <span><%= $t("dota2tracker.template.lane_advantage_rate_") %> <span <%- `style="color:${getWinRateColor(laneScore)};"` %>><%= isAnon ? "?" : (laneScore * 100).toFixed(2) %>%</span></span></p></div><div class="rank<%= p.isEstimatedRank ? " estimated" : "" %>"><img class="medal" src="<%= getImageUrl('medal_' + (p.rank.inTop100 ?? p.rank.medal)) %>" alt=""/> <img class="star" src="<%= getImageUrl('star_' + p.rank.star) %>" alt=""/><p><%= p.steamAccount.seasonLeaderboardRank ?? "" %></p></div></div><div class="hero_winrate"><div class="heroes"><p class="tip row total"><%= p.genHero ? $t("dota2tracker.template.all_matches_") : $t("dota2tracker.template.top10_") %></p><span class="tip"><%= $t("dota2tracker.template.hero") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.match_count") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.winrate") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.imp") %></span><span class="tip win_count" style="justify-self:end;margin-right:2px"><%= $t("dota2tracker.template.win_count") %></span><span class="tip lose_count" style="justify-self:start;margin-left:2px"><%= $t("dota2tracker.template.lose_count") %></span> <% heroList.forEach(hero => { %> <span><img alt="" src="<%= getImageUrl(hero.hero.shortName, ImageType.HeroIcons) %>"/></span><span class="count"><%= hero.matchCount %></span><span class="win_rate"><%= ((hero.winCount / hero.matchCount) * 100).toFixed(0) %>%</span> <span class="imp"><%= (hero.imp > 0 ? "+" : "") + hero.imp %></span><span class="win" <%- `style="${hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${hero.winCount * heroScale}px"` %>><%= hero.winCount %></span><span class="lose" <%- `style="${hero.matchCount - hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${(hero.matchCount - hero.winCount) * heroScale}px"` %>><%= hero.matchCount - hero.winCount %></span> <% }); %> <p class="tip row near"><%= $t("dota2tracker.template.recently_positions") %></p><span class="tip"><%= $t("dota2tracker.template.position") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.match_count") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.winrate") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.imp") %></span><span class="tip win_count" style="justify-self:end;margin-right:2px"><%= $t("dota2tracker.template.win_count") %></span><span class="tip lose_count" style="justify-self:start;margin-left:2px"><%= $t("dota2tracker.template.lose_count") %></span> <% p.positionPerformance.forEach(pos => { %> <span><img src="<%= getImageUrl(pos.icon,
|
|
78
|
+
%> <% const posScale = getScale(p.positionPerformance.filter(pos => pos.matchCount > 1), true); %> <!DOCTYPE html><html lang="<%= languageTag %>"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Player</title> <%- `<style>` %> <%- include("../common/styles/normalize.min.css") %> <%- include(`./player_1/base.css`) %> <%- `</style>` %> </head><body><div class="wrapper"><div class="player"><div class="avatar"><img src="<%= p.steamAccount?.avatar %>" alt=""/></div><div class="info"><p class="name"> <%= p.steamAccount.name %> <% if (p.guildMember) { %> <span class="guild <%= getGuildClass(p.guildMember.guild.currentPercentile) %>"><%= p.guildMember.guild.tag %></span> <% } %> <% if (p.genHero) { %> <span class="hero_name"><%= p.genHero.name %></span> <% } %> </p><p class="matches"> <%= $t("dota2tracker.template.match_count_") %><%= p.matchCount %> (<span class="win"><%= p.winCount %></span>/<span class="lose"><%= p.matchCount - p.winCount %></span>) <%= $t("dota2tracker.template.winrate_") %> <span <%- `style="color:${getWinRateColor(p.winCount / p.matchCount)};"` %>><%= ((p.winCount / p.matchCount) * 100).toFixed(2) %>%</span></p><p class="matches<%= isAnon ? " blur" : "" %>"><span><%= $t("dota2tracker.template.last25matches_") %> <span class="win"><%= nearWin %></span>/<span class="lose"><%= nearCount - nearWin %></span></span> <span><%= $t("dota2tracker.template.winrate_") %> <span <%- `style="color:${getWinRateColor(nearWin / nearCount)};"` %>><%= ((nearWin / nearCount) * 100).toFixed(2) %>%</span> </span> <span><%= $t("dota2tracker.template.imp_") %><%= isAnon ? "?" : ((p.performance?.imp > 0 ? "+" : "") + p.performance?.imp) %></span></p><p class="matches<%= isAnon ? " blur" : "" %>"><span><%= $t("dota2tracker.template.lane") %> <span class="victory"><%= outcomes.victory + outcomes.stomp %>(<span class="stomp"><%= outcomes.stomp %></span>)</span>-<span class="tie"><%= outcomes.tie %></span>-<span class="fail"><%= outcomes.fail + outcomes.stomped %>(<span class="stomped"><%= outcomes.stomped %></span>)</span> </span> <% const laneTotal = outcomes.victory + outcomes.stomp + outcomes.tie + outcomes.fail + outcomes.stomped; %> <% const laneScore = (outcomes.victory + outcomes.stomp + outcomes.tie / 2) / laneTotal; %> <span><%= $t("dota2tracker.template.lane_advantage_rate_") %> <span <%- `style="color:${getWinRateColor(laneScore)};"` %>><%= isAnon ? "?" : (laneScore * 100).toFixed(2) %>%</span></span></p></div><div class="rank<%= p.isEstimatedRank ? " estimated" : "" %>"><img class="medal" src="<%= getImageUrl('medal_' + (p.rank.inTop100 ?? p.rank.medal)) %>" alt=""/> <img class="star" src="<%= getImageUrl('star_' + p.rank.star) %>" alt=""/><p><%= p.steamAccount.seasonLeaderboardRank ?? "" %></p></div></div><div class="hero_winrate"><div class="heroes"><p class="tip row total"><%= p.genHero ? $t("dota2tracker.template.all_matches_") : $t("dota2tracker.template.top10_") %></p><span class="tip"><%= $t("dota2tracker.template.hero") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.match_count") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.winrate") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.imp") %></span><span class="tip win_count" style="justify-self:end;margin-right:2px"><%= $t("dota2tracker.template.win_count") %></span><span class="tip lose_count" style="justify-self:start;margin-left:2px"><%= $t("dota2tracker.template.lose_count") %></span> <% heroList.forEach(hero => { %> <span><img alt="" src="<%= getImageUrl(hero.hero.shortName, ImageType.HeroIcons) %>"/></span><span class="count"><%= hero.matchCount %></span><span class="win_rate"><%= ((hero.winCount / hero.matchCount) * 100).toFixed(0) %>%</span> <span class="imp"><%= (hero.imp > 0 ? "+" : "") + hero.imp %></span><span class="win" <%- `style="${hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${hero.winCount * heroScale}px"` %>><%= hero.winCount %></span><span class="lose" <%- `style="${hero.matchCount - hero.winCount == 0 ? "visibility:hidden;" : ""}width: ${(hero.matchCount - hero.winCount) * heroScale}px"` %>><%= hero.matchCount - hero.winCount %></span> <% }); %> <p class="tip row near"><%= $t("dota2tracker.template.recently_positions") %></p><span class="tip"><%= $t("dota2tracker.template.position") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.match_count") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.winrate") %></span><span class="tip" style="margin:0 4px"><%= $t("dota2tracker.template.imp") %></span><span class="tip win_count" style="justify-self:end;margin-right:2px"><%= $t("dota2tracker.template.win_count") %></span><span class="tip lose_count" style="justify-self:start;margin-left:2px"><%= $t("dota2tracker.template.lose_count") %></span> <% p.positionPerformance.forEach(pos => { %> <span><img src="<%= getImageUrl(pos.icon, "icons/facets") %>"></span><span class="count"><%= pos.matchCount %></span><span class="win_rate"><%= pos.matchCount > 0 ? ((pos.winCount / pos.matchCount) * 100).toFixed(0) : "-" %>%</span> <span class="imp"><%= (pos.imp > 0 ? "+" : "") + pos.imp %></span><span class="win" <%- `style="${pos.winCount == 0 ? "visibility:hidden;" : ""}width: ${pos.winCount * posScale}px"` %>><%= pos.winCount %></span><span class="lose" <%- `style="${pos.matchCount - pos.winCount == 0 ? "visibility:hidden;" : ""}width: ${(pos.matchCount - pos.winCount) * posScale}px"` %>><%= pos.matchCount - pos.winCount %></span> <% }); %> </div> <% if (isAnon) { %> <%- include("player_1/private", {$t, player: p}) %> <% } %> </div> <% if (Math.abs(p.streak) > 1 && !isAnon) { %> <div class="streak" <%- `style="box-shadow:none;color:${getWinRateColor((p.streak + 10) / 20)};"` %>> <%= Math.abs(p.streak) + (p.streak > 0 ? $t("dota2tracker.template.winning_streak") : $t("dota2tracker.template.losing_streak")) %> </div> <% } %> <div><table class="matches"><colgroup><col style="width:auto"/><col style="width:auto"/><col style="width:40px"/><col style="width:auto"/><col style="width:40px"/><col style="width:auto"/><col style="width:auto"/><col style="width:auto"/><col style="width:40px"/></colgroup><thead><tr><th><%= $t("dota2tracker.template.id") %></th><th><%= $t("dota2tracker.template.mode") %></th><th><%= $t("dota2tracker.template.hero") %></th><th><%= $t("dota2tracker.template.kda_kc") %></th><th><%= $t("dota2tracker.template.lane") %></th><th><%= $t("dota2tracker.template.time") %></th><th><%= $t("dota2tracker.template.duration") %></th><th><%= $t("dota2tracker.template.imp") %></th><th><%= $t("dota2tracker.template.rank") %></th></tr></thead><tbody> <% matchesData.forEach(m => { %> <tr class="match <%= m.didWin ? "win" : "lose" %>"><td><%- m.parsedDateTime ? m.id : `<p>${m.id}</p><p>${$t("dota2tracker.template.un_parsed")}</p>` %></td><td><p><%= $t("dota2tracker.template.lobby_types." + m.lobbyType) || m.lobbyType %></p><p><%= $t("dota2tracker.template.game_modes." + m.gameMode) || m.gameMode %></p></td><td><img alt="" src="<%= getImageUrl(m.inner.hero.shortName, ImageType.HeroIcons) %>"/></td><td style="line-height:20px"><p><%= m.kda %> (<%= (m.parsedDateTime ? "" : "≈") + m.kp %>%)</p><p><%= m.inner.kills %>/<%= m.inner.deaths %>/<%= m.inner.assists %></p></td><td><div class="player_lane <%= m.laneRes %>"><img src="<%- getImageUrl("lane_" + m.laneRes, undefined, ImageFormat.svg) %>"/></div></td><td style="line-height:20px"><%= m.timeStr %></td><td><%= m.durationTime %></td><td><%= m.inner.imp != null ? ((m.inner.imp >= 0 ? "+" : "") + m.inner.imp) : "?" %></td><td><img class="medal" src="<%= getImageUrl("medal_" + m.rank?.toString().split("")[0]) %>" style="width:100%"/></td></tr> <% }); %> </tbody></table> <% if (isAnon) { %> <%- include("player_1/private", {$t, player: p}) %> <% } %> </div><div class="plus"> <% p.dotaPlus.forEach(hero => { %> <div class="hero"><img src="<%= getImageUrl(hero.shortName, ImageType.Heroes) %>" alt=""/><div class="level"><img src="<%= getImageUrl("hero_badge_" + Math.ceil((hero.level + 1) / 6)) %>" alt=""/><span><%= hero.level %></span></div><span><%= ((hero.winCount / hero.matchCount) * 100).toFixed(2) %>%</span> <span><%= hero.matchCount %></span></div> <% }); %> <% if (isAnon) { %> <%- include("player_1/private", {$t, player: p}) %> <% } %> </div></div></body></html>
|
package/package.json
CHANGED