OXYGENHUB
◆ main openmsx / share / scripts / _osd_nemesis.tcl
3.4 KiB · Tcl · last changed chore(): initial commit 1 month ago source blame history raw
1
set_help_text toggle_nemesis_1_shield \
2
{This command (de)activates some Nemesis 1 toys:
3
 - A shield around the players ship: enemy bullets will bounce off this shield.
4
 - Allow to move the ship with the mouse (click right mouse button to activate, click again to disable).
5
}
6
7
namespace eval osd_nemesis {
8
9
variable move_active false
10
variable after_frame_id
11
variable after_mouse_button_id
12
13
proc toggle_nemesis_1_shield {} {
14
	if {[osd exists "nemesis1"]} {
15
		disable_nemesis_1_shield
16
		message "Nemesis 1 shield deactivated" info
17
	} else {
18
		enable_nemesis_1_shield
19
		message "Nemesis 1 shield activated" info
20
	}
21
	return ""
22
}
23
namespace export toggle_nemesis_1_shield
24
25
proc disable_nemesis_1_shield {} {
26
	variable after_frame_id
27
	variable after_mouse_button_id
28
29
	osd destroy "nemesis1"
30
	after cancel $after_frame_id
31
	after cancel $after_mouse_button_id
32
}
33
34
proc enable_nemesis_1_shield {} {
35
	variable move_active
36
	variable after_frame_id
37
	variable after_mouse_button_id
38
39
	osd_widgets::msx_init "nemesis1"
40
	osd create rectangle "nemesis1.shield" \
41
		-fadeCurrent 0 -fadeTarget 0 -fadePeriod 2 \
42
		-image [data_file scripts/shield.png]
43
44
	set move_active false
45
46
	set after_frame_id [after time 0.1 osd_nemesis::after_frame]
47
	set after_mouse_button_id [after "mouse button1 down" osd_nemesis::after_mouse]
48
}
49
50
proc after_mouse {} {
51
	# click to capture and click again to release
52
	variable move_active
53
	variable after_mouse_button_id
54
	set move_active [expr {!$move_active}]
55
	set after_mouse_button_id [after "mouse button1 down" osd_nemesis::after_mouse]
56
}
57
58
proc after_frame {} {
59
	variable move_active
60
	variable after_frame_id
61
62
	osd_widgets::msx_update "nemesis1"
63
64
	if {$move_active} {
65
		# move vic viper to mouse position
66
		lassign [osd info "nemesis1" -mousecoord] x y
67
		catch { ;# when the cursor is hidden, -mousecoord won't give sane values
68
			poke 0xe206 [utils::clip 0 255 [expr {int($x)}]]
69
			poke 0xe204 [utils::clip 0 212 [expr {int($y)}]]
70
		}
71
	}
72
73
	# vic viper location
74
	set x [utils::clip 9 255 [peek 0xe206]]
75
	set y [utils::clip 0 192 [peek 0xe204]]
76
	osd configure "nemesis1.shield" -relx [expr {$x - 9}] -rely [expr {$y - 9}]
77
78
	for {set i 0} {$i < 32} {incr i} {
79
		# set base address
80
		set addr [expr {0xe300 + ($i * 0x20)}]
81
82
		# get enemy id
83
		set id [peek $addr]
84
85
		# enegry pod / flash pod / life pod / score pod /
86
		# endless score pod / explosion / end brain connections
87
		if {(17 <= $id) && ($id <= 26) && ($id != 20)} continue
88
89
		set a [peek [expr {$addr + 6}]]
90
		set b [peek [expr {$addr + 4}]]
91
92
		# Not in contact with shield? Then do nothing.
93
		if {((($a - $x + 6) ** 2) + (($b - $y + 7) ** 2)) >= 961} continue
94
95
		# ground turrets change into razor discs :)
96
		if {$id == 1 && $i < 16} {poke $addr 2}
97
98
		# homing ships and walkers
99
		if {$id == 4 || $id == 5} {poke $addr 21}
100
101
		# change color of sprite when in contact with shield
102
		# poke [expr {$addr + 13}] 15
103
104
		# Shield routine (hit front/back/top/bottom)
105
		set shieldstrength 2
106
		set dx [expr {($x > $a) ? -$shieldstrength : $shieldstrength}]
107
		set dy [expr {($y > $b) ? -$shieldstrength : $shieldstrength}]
108
		set xn [expr {$a + $dx}]
109
		set yn [expr {$b + $dy}]
110
		poke [expr {$addr +  6}] [utils::clip 0 255 $xn]
111
		poke [expr {$addr +  4}] [utils::clip 0 255 $yn]
112
		poke [expr {$addr +  8}] [expr {$dy & 255}]
113
		poke [expr {$addr + 10}] [expr {$dx & 255}]
114
115
		# make shield visible
116
		osd configure "nemesis1.shield" -fadeCurrent 0.5
117
	}
118
	set after_frame_id [after frame osd_nemesis::after_frame]
119
}
120
121
} ;# namespace osd_nemesis
122
123
namespace import osd_nemesis::*