Skip to content

Commit 2701c9c

Browse files
committed
Updated examples, switched to normalized enums, fixed problem in timer
1 parent 14e2eee commit 2701c9c

File tree

14 files changed

+159
-43
lines changed

14 files changed

+159
-43
lines changed

.vscode/settings.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"css.lint.unknownProperties": "ignore"
3+
}

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# ModDota template
22

3-
A template for Dota 2 Custom Games built with modern technologies. It includes
3+
A template for Dota 2 Custom Games built with modern technologies.
4+
5+
[This tutorial](https://moddota.com/scripting/Typescript/typescript-introduction/) explains how to set up and use the template.
6+
7+
The template includes:
48

59
- [TypeScript for Panorama](https://moddota.com/panorama/introduction-to-panorama-ui-with-typescript)
610
- [TypeScript for VScripts](https://typescripttolua.github.io/)
68.3 KB
Loading
Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,31 @@
11
<root>
22
<scripts>
3+
<!-- Included JS script files go here -->
34
<include src="file://{resources}/scripts/custom_game/hud.js" />
45
</scripts>
6+
57
<styles>
8+
<!-- Included css style files go here -->
69
<include src="s2r://panorama/styles/dotastyles.css" />
710
<include src="file://{resources}/styles/custom_game/hud.css" />
811
</styles>
9-
<snippets>
1012

13+
<snippets>
14+
<!-- Snippets go here -->
1115
</snippets>
16+
1217
<Panel hittest="false" class="MainHud">
18+
<Panel id="ExamplePanel">
19+
20+
<Image id="BannerImage" src="file://{resources}/images/custom_game/tstl.png" />
21+
22+
<Label class="ExampleTitle" text="TypeScript Dota Addon template" />
23+
24+
<Label class="ExampleParagraph" text="This is an example text box! Close it to apply the 'panic' modifier to your hero. You can remove this panel in content/panorama/layout/custom_game/hud.xml" />
1325

26+
<Button id="CloseButton" onactivate="OnCloseButtonClicked()">
27+
<Label text="Close" />
28+
</Button>
29+
</Panel>
1430
</Panel>
1531
</root>

content/panorama/styles/custom_game/hud.css

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,57 @@
22
width: 100%;
33
height: 100%;
44
}
5+
6+
#ExamplePanel {
7+
width: 500px;
8+
height: 500px;
9+
/* Using a background image already in dota */
10+
background-image: url("s2r://panorama/images/compendium/international2020/compendium/dashboard_panel_bg_psd.vtex");
11+
12+
horizontal-align: center;
13+
vertical-align: center;
14+
}
15+
16+
#ExamplePanel #BannerImage {
17+
width: 200px;
18+
height: 200px;
19+
horizontal-align: center;
20+
y: 40px;
21+
}
22+
23+
#ExamplePanel .ExampleTitle {
24+
horizontal-align: center;
25+
font-size: 30px;
26+
y: 260px;
27+
}
28+
29+
#ExamplePanel .ExampleParagraph {
30+
y: 320px;
31+
margin-left: 30px;
32+
margin-right: 30px;
33+
}
34+
35+
#ExamplePanel #CloseButton {
36+
width: 100px;
37+
height: 50px;
38+
background-color: rgb(228, 228, 228);
39+
horizontal-align: center;
40+
vertical-align: bottom;
41+
y: -30px;
42+
}
43+
44+
#ExamplePanel #CloseButton Label {
45+
horizontal-align: center;
46+
vertical-align: center;
47+
color: black;
48+
}
49+
50+
#ExamplePanel #CloseButton:hover {
51+
background-color: rgb(0, 135, 245);
52+
}
53+
54+
#ExamplePanel #CloseButton:hover Label {
55+
color: white;
56+
}
57+
58+

src/common/events.d.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,17 @@
1313

1414
// To declare an event for use, add it to this table with the type of its data
1515
interface CustomGameEventDeclarations {
16-
example_event: ExampleEventData
16+
example_event: ExampleEventData,
17+
ui_panel_closed: UIPanelClosedEventData
1718
}
1819

1920
// Define the type of data sent by the example_event event
2021
interface ExampleEventData {
2122
myNumber: number;
2223
myBoolean: boolean;
23-
myString: string[];
24+
myString: string;
2425
myArrayOfNumbers: number[]
25-
}
26+
}
27+
28+
// This event has no data
29+
interface UIPanelClosedEventData {}

src/panorama/hud.ts

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
$.Msg("Hud panorama loaded");
22

3-
GameEvents.Subscribe("my_custom_event", event => {
4-
$.Msg("Received custom event", event);
5-
});
3+
function OnCloseButtonClicked() {
4+
$.Msg("Example close button clicked");
5+
6+
// Find panel by id
7+
const examplePanel = $("#ExamplePanel");
68

7-
GameEvents.SendCustomGameEventToServer<{}>("ui_loaded", {});
9+
// Remove panel
10+
examplePanel.DeleteAsync(0);
11+
12+
// Send event to server
13+
GameEvents.SendCustomGameEventToServer("ui_panel_closed", {});
14+
}
815

916
GameEvents.Subscribe("example_event", (data: NetworkedData<ExampleEventData>) => {
1017
const myNumber = data.myNumber;
@@ -16,6 +23,8 @@ GameEvents.Subscribe("example_event", (data: NetworkedData<ExampleEventData>) =>
1623

1724
const myArray = toArray(myArrayObject); // We can turn it back into an array ourselves.
1825

26+
$.Msg("Received example event", myNumber, myString, myBoolean, myArrayObject, myArray);
27+
1928
});
2029

2130
/**

src/panorama/manifest.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1 @@
1-
GameUI.SetDefaultUIEnabled(DotaDefaultUIElement_t.DOTA_DEFAULT_UI_ACTION_PANEL, false);
2-
GameUI.SetDefaultUIEnabled(DotaDefaultUIElement_t.DOTA_DEFAULT_UI_ACTION_MINIMAP, false);
3-
GameUI.SetDefaultUIEnabled(DotaDefaultUIElement_t.DOTA_DEFAULT_UI_INVENTORY_PANEL, false);
4-
GameUI.SetDefaultUIEnabled(DotaDefaultUIElement_t.DOTA_DEFAULT_UI_INVENTORY_SHOP, false);
5-
GameUI.SetDefaultUIEnabled(DotaDefaultUIElement_t.DOTA_DEFAULT_UI_FLYOUT_SCOREBOARD, false);
6-
GameUI.SetDefaultUIEnabled(DotaDefaultUIElement_t.DOTA_DEFAULT_UI_TOP_BAR_BACKGROUND, false);
7-
GameUI.SetDefaultUIEnabled(DotaDefaultUIElement_t.DOTA_DEFAULT_UI_TOP_HEROES, false);
8-
9-
const hudRoot = $.GetContextPanel().GetParent()!.GetParent()!;
10-
hudRoot.FindChildTraverse("quickstats")!.style.visibility = "collapse";
1+
$.Msg("ui manifest loaded");

src/vscripts/GameMode.ts

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,33 @@ export class GameMode {
2323

2424
constructor() {
2525
this.configure();
26+
27+
// Register event listeners for dota engine events
2628
ListenToGameEvent("game_rules_state_change", () => this.OnStateChange(), undefined);
2729
ListenToGameEvent("npc_spawned", event => this.OnNpcSpawned(event), undefined);
30+
31+
// Register event listeners for events from the UI
32+
CustomGameEventManager.RegisterListener("ui_panel_closed", (_, data) => {
33+
print(`Player ${data.PlayerID} has closed their UI panel.`);
34+
35+
// Respond by sending back an example event
36+
const player = PlayerResource.GetPlayer(data.PlayerID)!;
37+
CustomGameEventManager.Send_ServerToPlayer(player, "example_event", {
38+
myNumber: 42,
39+
myBoolean: true,
40+
myString: "Hello!",
41+
myArrayOfNumbers: [1.414, 2.718, 3.142]
42+
});
43+
44+
// Also apply the panic modifier to the sending player's hero
45+
const hero = player.GetAssignedHero();
46+
hero.AddNewModifier(hero, undefined, modifier_panic.name, { duration: 5 });
47+
});
2848
}
2949

3050
private configure(): void {
31-
GameRules.SetCustomGameTeamMaxPlayers(DOTATeam_t.DOTA_TEAM_GOODGUYS, 3);
32-
GameRules.SetCustomGameTeamMaxPlayers(DOTATeam_t.DOTA_TEAM_BADGUYS, 3);
51+
GameRules.SetCustomGameTeamMaxPlayers(DotaTeam.GOODGUYS, 3);
52+
GameRules.SetCustomGameTeamMaxPlayers(DotaTeam.BADGUYS, 3);
3353

3454
GameRules.SetShowcaseTime(0);
3555
GameRules.SetHeroSelectionTime(heroSelectionTime);
@@ -39,13 +59,13 @@ export class GameMode {
3959
const state = GameRules.State_Get();
4060

4161
// Add 4 bots to lobby in tools
42-
if (IsInToolsMode() && state == DOTA_GameState.DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP) {
62+
if (IsInToolsMode() && state == GameState.CUSTOM_GAME_SETUP) {
4363
for (let i = 0; i < 4; i++) {
4464
Tutorial.AddBot("npc_dota_hero_lina", "", "", false);
4565
}
4666
}
4767

48-
if (state === DOTA_GameState.DOTA_GAMERULES_STATE_CUSTOM_GAME_SETUP) {
68+
if (state === GameState.CUSTOM_GAME_SETUP) {
4969
// Automatically skip setup in tools
5070
if (IsInToolsMode()) {
5171
Timers.CreateTimer(3, () => {
@@ -55,7 +75,7 @@ export class GameMode {
5575
}
5676

5777
// Start game once pregame hits
58-
if (state === DOTA_GameState.DOTA_GAMERULES_STATE_PRE_GAME) {
78+
if (state === GameState.PRE_GAME) {
5979
Timers.CreateTimer(0.2, () => this.StartGame());
6080
}
6181
}
@@ -76,11 +96,8 @@ export class GameMode {
7696
private OnNpcSpawned(event: NpcSpawnedEvent) {
7797
// After a hero unit spawns, apply modifier_panic for 8 seconds
7898
const unit = EntIndexToHScript(event.entindex) as CDOTA_BaseNPC; // Cast to npc since this is the 'npc_spawned' event
99+
// Give all real heroes (not illusions) the meepo_earthbind_ts_example spell
79100
if (unit.IsRealHero()) {
80-
Timers.CreateTimer(1, () => {
81-
unit.AddNewModifier(unit, undefined, modifier_panic.name, { duration: 8 });
82-
});
83-
84101
if (!unit.HasAbility("meepo_earthbind_ts_example")) {
85102
// Add lua ability to the unit
86103
unit.AddAbility("meepo_earthbind_ts_example");

src/vscripts/abilities/heroes/meepo/earthbind_ts_example.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export class meepo_earthbind_ts_example extends BaseAbility {
4040
const radius = this.GetSpecialValueFor("radius");
4141
this.particle = ParticleManager.CreateParticle(
4242
"particles/units/heroes/hero_meepo/meepo_earthbind_projectile_fx.vpcf",
43-
ParticleAttachment_t.PATTACH_CUSTOMORIGIN,
43+
ParticleAttachment.CUSTOMORIGIN,
4444
caster,
4545
);
4646

@@ -57,9 +57,9 @@ export class meepo_earthbind_ts_example extends BaseAbility {
5757
fEndRadius: radius,
5858
Source: caster,
5959
bHasFrontalCone: false,
60-
iUnitTargetTeam: DOTA_UNIT_TARGET_TEAM.DOTA_UNIT_TARGET_TEAM_NONE,
61-
iUnitTargetFlags: DOTA_UNIT_TARGET_FLAGS.DOTA_UNIT_TARGET_FLAG_NONE,
62-
iUnitTargetType: DOTA_UNIT_TARGET_TYPE.DOTA_UNIT_TARGET_NONE,
60+
iUnitTargetTeam: UnitTargetTeam.NONE,
61+
iUnitTargetFlags: UnitTargetFlags.NONE,
62+
iUnitTargetType: UnitTargetType.NONE,
6363
vVelocity: (direction * projectileSpeed) as Vector,
6464
bProvidesVision: true,
6565
iVisionRadius: radius,
@@ -77,9 +77,9 @@ export class meepo_earthbind_ts_example extends BaseAbility {
7777
location,
7878
undefined,
7979
radius,
80-
DOTA_UNIT_TARGET_TEAM.DOTA_UNIT_TARGET_TEAM_ENEMY,
81-
DOTA_UNIT_TARGET_TYPE.DOTA_UNIT_TARGET_BASIC | DOTA_UNIT_TARGET_TYPE.DOTA_UNIT_TARGET_HERO,
82-
DOTA_UNIT_TARGET_FLAGS.DOTA_UNIT_TARGET_FLAG_NONE,
80+
UnitTargetTeam.ENEMY,
81+
UnitTargetType.BASIC | UnitTargetType.HERO,
82+
UnitTargetFlags.NONE,
8383
0,
8484
false,
8585
);

0 commit comments

Comments
 (0)