OXYGENHUB
◆ main openmsx / share / scripts / _metal_gear_overlay.tcl
6.1 KiB · Tcl · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
# This script is based on:
2
# openMSX metal gear overlay script 2014/12/07
3
# By Dunnius / Bifi / Vampier 
4
5
namespace eval metal_gear_overlay {
6
7
variable num_enemies 11
8
variable max_hp
9
variable punch_max_hp
10
variable currentfield
11
# the map feature is disabled here in code, because it isn't very useful yet
12
variable map_feature_enabled false
13
variable metal_gear_overlay_active false
14
15
variable enemy_names [list \
16
	"" "01" "Bridge Segment" "Ellen Screaming 'help me'" "Soldier - Pattern 1" \
17
	"Soldier - Pattern 2" "Camera" "Landmine" "Gas cloud" "Enemy - Tank" \
18
	"Soldier - (Alert)" "Soldier - Red (Alert)" "Tank Shell" \
19
	"Soldier - Shooting" "Soldier - Guard" "Roller" "Trap Floor" "Metal Gear" \
20
	"Enemy - Bulldozer" "Soldier - Truck" "Soldier - Flying" \
21
	"Soldier - Fly to the Switch" "Soldier - Flying (Alert)" "Unknown3" \
22
	"Soldier - Run to the Switch" "Guard Dog" "Mr. Arnold" "Basement Guard Dogs" \
23
	"Soldier - Guard to building 3" "Event - Dogs will appear" "Soldier - Pattern 3" \
24
	"Scorpion" "Big Boss" "Shoot Gunner" "Machine Gun Kid" "Laser fence" \
25
	"Fire Trooper" "Fire ball" "Hind-D" "Event - Incoming tank shells" \
26
	"Event - Guards will switch shifts" "Coward Duck" "Unknown8" \
27
	"Shoot Gunner - Bullet" "Power Switch" "Event - Snake Gets Captured" \
28
	"Event - Access to building 2" "Bullet 1" "Soldier - Stationary Guard" \
29
	"POW" "Ellen" "Grey Fox" "Dr. Petrovich" "Laser Camera" "36" "Fake Dr. Petrovich" \
30
	"Unknown9" "Soldier - Silencer Guards" "Unknown11" "Bullet 2" \
31
	"Machine Gun Kid - Bullet" "Bullet 3" "Tank - Bullet" "Boomerang" "Zzz" \
32
	"Unknown13" "Unknown14" "Unknown15" "44" "45" "46" "47" "48" "49" "4A" \
33
	"4B" "4C" "4D" "4E" "4F" "50" "51" "52" "53" "54" "55" "56" "57" "58" \
34
	"59" "5A" "5B" "5C" "5D" "5E" "5F" "60" "61" "62" "63" "64" "65" "66" ]
35
36
set_help_text toggle_metal_gear_overlay \
37
"Shows OSD widgets that help you play Metal Gear. Only useful if you
38
are actually running this game... If you are not, you may get a lot of weird
39
stuff on your screen :) It mostly shows Snake and enemy properties on screen
40
and events that will happen."
41
42
proc init {} {
43
	variable num_enemies
44
	variable max_hp
45
	variable punch_max_hp
46
	variable currentfield
47
	variable map_feature_enabled
48
49
	# Create OSD elements
50
	osd_widgets::msx_init metal_gear
51
52
	for {set i 0} {$i < $num_enemies} {incr i} {
53
		osd_widgets::create_power_bar metal_gear.powerbar$i 16 2 0xff0080b0 0x00000080 0xffffffC0
54
		osd_widgets::create_power_bar metal_gear.punchbar$i 16 2 0x0080ffb0 0x00000080 0xffffffC0
55
		set max_hp($i) 0
56
		set punch_max_hp($i) 0
57
	}
58
59
	osd_widgets::create_power_bar metal_gear.powerbarsnake 24 2 0x00ff00b0 0x00000080 0xffffffC0
60
	osd_widgets::create_power_bar metal_gear.boss  24 8 0x00ff00b0 0x00000080 0xffffffC0
61
62
	set currentfield 0
63
	
64
	if {$map_feature_enabled} {
65
		for {set y 0} {$y < 16} {incr y} {
66
			for {set x 0} {$x < 16} {incr x} {
67
				set field [expr {$x + ($y * 16)}]
68
				osd create rectangle metal_gear.field$field -x [expr {($x * 3) + 1}] -y [expr {($y * 3) + 1}] -relw 2 -relh 2 -rgba 0x0000ff80
69
			}
70
		}
71
	}
72
73
	# Start the overlay refresh
74
	update_overlay
75
}
76
77
proc update_impl {} {
78
	variable max_hp
79
	variable punch_max_hp
80
	variable num_enemies
81
	variable enemy_names
82
	variable currentfield
83
	variable map_feature_enabled
84
85
	# check for field change
86
	set newfield [peek 0xC130]
87
	if {$currentfield != $newfield} {
88
		set previousfield $currentfield
89
		set currentfield $newfield
90
91
		# clear out old HP values if field has changed
92
		for {set i 0} {$i < $num_enemies} {incr i} {
93
			set punch_max_hp($i) 0
94
			set max_hp($i) 0
95
		}
96
		if {$map_feature_enabled} {
97
			osd configure metal_gear.field$previousfield -rgba 0x00ff0080
98
			osd configure metal_gear.field$currentfield -rgba 0xffffff80
99
		}
100
	}
101
102
	for {set i 0; set addr 0xD000} {$i < $num_enemies} {incr i; incr addr 0x80} {
103
		set enemy_type [peek $addr]
104
		set enemy_hp [peek [expr {$addr + 0x0D}]]
105
		if {$enemy_type > 0 && $enemy_hp > 0} {
106
			set pos_x [peek [expr {$addr + 5}]]
107
			set pos_y [peek [expr {$addr + 3}]]
108
109
			if {$enemy_hp > $max_hp($i)} {
110
				set max_hp($i) $enemy_hp
111
			}
112
			set power [expr {1.00 * $enemy_hp / $max_hp($i)}]
113
			set text "HP: $enemy_hp $i [lindex $enemy_names $enemy_type] - #$enemy_type"
114
			osd_widgets::update_power_bar metal_gear.powerbar$i $pos_x $pos_y $power $text
115
								
116
			# only show the punch bar when the enemy can be punched
117
			set enemy_punch_hp [expr {3 - [peek [expr {$addr + 0x7A}]]}]
118
			if {$enemy_punch_hp > 0} {
119
				if {$enemy_punch_hp > $punch_max_hp($i)} {
120
					set punch_max_hp($i) $enemy_punch_hp
121
				}
122
				set punch_power [expr {1.00 * $enemy_punch_hp / $punch_max_hp($i)}]
123
				osd_widgets::update_power_bar metal_gear.punchbar$i $pos_x [expr {$pos_y + 5}] $punch_power ""
124
			} else {
125
				osd_widgets::update_power_bar metal_gear.punchbar$i -50 -50 0 ""
126
			}
127
		} else {
128
			osd_widgets::update_power_bar metal_gear.powerbar$i -50 -50 0 ""
129
			osd_widgets::update_power_bar metal_gear.punchbar$i -50 -50 0 ""
130
		}
131
        }
132
133
	# get stats for snake
134
	set snake_hp [peek 0xC131]
135
	set power [expr {$snake_hp / 48.0}]
136
	set poisoned [peek 0xC139]
137
	set pos_x [peek 0xC184]
138
	set pos_y [peek 0xc182]
139
140
	set text ""
141
	if {$poisoned == 1} {
142
		set power 0
143
		set text "POISONED "
144
	}
145
	append text "($pos_x,$pos_y)  HP: $snake_hp"
146
147
	osd_widgets::update_power_bar metal_gear.powerbarsnake [expr {$pos_x - 13}] [expr {$pos_y + 20}] $power $text
148
}
149
150
proc update_overlay {} {
151
	variable metal_gear_overlay_active
152
	if {!$metal_gear_overlay_active} return
153
154
	# check if not in demo or weapon/item screen
155
	set c012 [peek 0xC012]
156
	if {$c012 == 0x00 || $c012 == 0x47 || $c012 == 0x50 || [peek 0xC151] != 0} {
157
		osd configure metal_gear -y 999
158
	} else {
159
		osd configure metal_gear -y 0
160
		update_impl
161
	}
162
	after frame [namespace code update_overlay]
163
}
164
165
proc toggle_metal_gear_overlay {} {
166
	variable metal_gear_overlay_active
167
	set metal_gear_overlay_active [expr {!$metal_gear_overlay_active}]
168
	if {$metal_gear_overlay_active} {
169
		init
170
		set text "Metal Gear overlay activated!"
171
	} else {
172
		osd destroy metal_gear
173
		set text "Metal Gear overlay deactivated."
174
	}
175
	message $text info
176
	return $text
177
}
178
179
namespace export toggle_metal_gear_overlay
180
181
};# namespace metal_gear_overlay
182
183
namespace import metal_gear_overlay::*