Compare commits
42
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06de4534da | ||
|
|
23284b18b0 | ||
|
|
62dc0952b1 | ||
|
|
9a9f2d0df2 | ||
|
|
cd2fe73c88 | ||
|
|
3f2d79a038 | ||
|
|
c3d82d78c9 | ||
|
|
17ca966473 | ||
|
|
7852269dc7 | ||
|
|
76121f1c68 | ||
|
|
c33465611f | ||
|
|
fccdc2dee4 | ||
|
|
0344418aae | ||
|
|
520a860414 | ||
|
|
5813aeb6e9 | ||
|
|
840bc96cc1 | ||
|
|
72e1e59d8e | ||
|
|
b591bae273 | ||
|
|
a712002fec | ||
|
|
f76dc05f46 | ||
|
|
16fca6c4f1 | ||
|
|
c768f7c46b | ||
|
|
24825ff396 | ||
|
|
0ceba9c778 | ||
|
|
55b9bfc521 | ||
|
|
106bb5b59f | ||
|
|
e45a67a8fe | ||
|
|
456e197822 | ||
|
|
a45be8044c | ||
|
|
9f3a50443a | ||
|
|
47000d6cf2 | ||
|
|
195db56b1e | ||
|
|
b98cb87ef3 | ||
|
|
92aaedfcbb | ||
|
|
af416960fa | ||
|
|
eaa5fd3bbe | ||
|
|
ab24aace11 | ||
|
|
ef82366132 | ||
|
|
6f630c777e | ||
|
|
87e25677b5 | ||
|
|
7e6b457745 | ||
|
|
e5c4993436 |
Vendored
+13
@@ -0,0 +1,13 @@
|
||||
{
|
||||
// Legacy source files use CP949 (Korean Windows encoding, superset of EUC-KR).
|
||||
// VS Code defaults to UTF-8, which silently corrupts the Korean comment bytes
|
||||
// on save. Setting encoding to cp949 here preserves them exactly.
|
||||
"files.encoding": "cp949",
|
||||
|
||||
// Let VS Code try to detect encoding per-file, falling back to cp949 above.
|
||||
"files.autoGuessEncoding": true,
|
||||
|
||||
// Preserve the original Windows CRLF line endings (Git's * -text in
|
||||
// .gitattributes also prevents conversion, but this keeps VS Code consistent).
|
||||
"files.eol": "\r\n"
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,575 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Automatic Config File Specification ? Firestorm Console Load File</title>
|
||||
<style>
|
||||
body { font-family: Calibri, Arial, sans-serif; font-size: 11pt; margin: 60px 72px; color: #1a1a1a; max-width: 900px; }
|
||||
h1 { font-size: 20pt; color: #1F3864; border-bottom: 3px solid #1F3864; padding-bottom: 8px; margin-top: 0; }
|
||||
h2 { font-size: 14pt; color: #1F3864; border-bottom: 1px solid #BDD7EE; padding-bottom: 4px; margin-top: 28px; }
|
||||
h3 { font-size: 12pt; color: #2E4D7B; margin-top: 20px; margin-bottom: 4px; }
|
||||
h4 { font-size: 11pt; color: #2E4D7B; margin-top: 16px; margin-bottom: 2px; font-style: italic; }
|
||||
.meta { color: #555; font-size: 10pt; margin-bottom: 28px; }
|
||||
code, .code { font-family: Consolas, "Courier New", monospace; font-size: 10pt; background: #F4F7FB; padding: 1px 4px; border-radius: 2px; color: #1a1a1a; }
|
||||
pre { font-family: Consolas, "Courier New", monospace; font-size: 10pt; background: #F4F7FB; border: 1px solid #BDD7EE; border-left: 4px solid #2E4D7B; padding: 12px 16px; border-radius: 0 4px 4px 0; overflow-x: auto; line-height: 1.5; }
|
||||
pre .section { color: #7B2D8B; font-weight: bold; }
|
||||
pre .key { color: #1F6A8F; }
|
||||
pre .value { color: #2D6A2D; }
|
||||
pre .comment { color: #888; font-style: italic; }
|
||||
table { border-collapse: collapse; width: 100%; margin: 10px 0 18px 0; font-size: 10.5pt; }
|
||||
th { background: #1F3864; color: white; padding: 7px 12px; text-align: left; font-weight: bold; font-size: 10pt; }
|
||||
tr:nth-child(even) td { background: #EFF4FB; }
|
||||
td { padding: 5px 12px; border-bottom: 1px solid #D0D9E8; vertical-align: top; }
|
||||
td code { background: #E8EFF9; }
|
||||
.warn { background: #FFF3CD; border: 1px solid #FFEAA0; border-left: 4px solid #F0B429; padding: 10px 14px; border-radius: 0 4px 4px 0; margin: 14px 0; font-size: 10.5pt; }
|
||||
.warn strong { color: #7A4F00; }
|
||||
.note { background: #E7F3FD; border: 1px solid #B8D9F5; border-left: 4px solid #1F3864; padding: 10px 14px; border-radius: 0 4px 4px 0; margin: 14px 0; font-size: 10.5pt; }
|
||||
.optional { color: #666; font-size: 9.5pt; font-style: italic; }
|
||||
ul, ol { margin: 6px 0 10px 0; padding-left: 24px; }
|
||||
li { margin-bottom: 4px; }
|
||||
hr { border: none; border-top: 1px solid #D0D9E8; margin: 30px 0; }
|
||||
.key-block { background: #F0F4FA; border: 1px solid #C5D5E8; padding: 8px 12px; border-radius: 4px; margin: 8px 0 12px 0; }
|
||||
.key-block .kname { font-family: Consolas, monospace; font-size: 10.5pt; font-weight: bold; color: #1F6A8F; }
|
||||
.key-block .ktype { color: #888; font-size: 9.5pt; margin-left: 8px; }
|
||||
.default-tag { background: #D4EDDA; color: #155724; font-size: 9pt; padding: 1px 6px; border-radius: 3px; margin-left: 6px; font-weight: bold; }
|
||||
.ignored-tag { background: #F8D7DA; color: #721C24; font-size: 9pt; padding: 1px 6px; border-radius: 3px; margin-left: 6px; }
|
||||
.mech-table td:first-child { font-family: Consolas, monospace; font-size: 10pt; white-space: nowrap; }
|
||||
@media print { body { margin: 40px; } h2 { page-break-before: auto; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Automatic Config File Format Specification</h1>
|
||||
<div class="meta">
|
||||
Feature: Console Lobby “Load File” button |
|
||||
Commit: <code>c3346561</code> (branch <code>5.1.0b-in-progress</code>) |
|
||||
Date: 2026-07-24, updated 2026-07-24 (commit <code>cd2fe73c</code>)
|
||||
</div>
|
||||
|
||||
<h2>1. Overview</h2>
|
||||
<p>
|
||||
The system operates with <strong>two separate files</strong>:
|
||||
</p>
|
||||
<ol>
|
||||
<li>
|
||||
<strong><code>options.ini</code></strong> — machine-level one-time configuration, read once at game startup.
|
||||
Contains the path to the config file. Never changed by the game.
|
||||
</li>
|
||||
<li>
|
||||
<strong>The config file</strong> (path specified in <code>options.ini</code>) —
|
||||
written by the external application before each match.
|
||||
Read by the game when the operator clicks <strong>Load File</strong> in the console lobby.
|
||||
<strong>Not consumed</strong> — the game leaves it on disk. Overwrite it to set the next match.
|
||||
</li>
|
||||
</ol>
|
||||
<p>
|
||||
When <strong>Load File</strong> is clicked, the game:
|
||||
</p>
|
||||
<ol>
|
||||
<li>Checks that <code>automaticmode=1</code> and the file path is configured.</li>
|
||||
<li>Checks that the config file exists on disk (<code>GetFileAttributes</code>). If not, does nothing.</li>
|
||||
<li>Reads the file, applies game options, clears all current lobby slots, then fills slots from the file.</li>
|
||||
<li>Leaves the file on disk unchanged.</li>
|
||||
</ol>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>2. <code>options.ini</code> Setup (One-Time, Per Machine)</h2>
|
||||
<p>Add the following section to the game’s <code>options.ini</code> in the game working directory.</p>
|
||||
|
||||
<pre><span class="section">[automaticmode]</span>
|
||||
<span class="key">automaticmode</span>=<span class="value">1</span>
|
||||
<span class="key">automaticfile</span>=<span class="value">c:\mw4files\nextmatch.ini</span></pre>
|
||||
|
||||
<table>
|
||||
<tr><th>Key</th><th>Type</th><th>Description</th></tr>
|
||||
<tr><td><code>automaticmode</code></td><td>integer</td><td><code>1</code> = enabled. <code>0</code> = disabled; Load File button does nothing.</td></tr>
|
||||
<tr><td><code>automaticfile</code></td><td>string</td><td>Full absolute Windows path to the config file. Max 259 characters. Can be any local drive letter.</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="note">
|
||||
<strong>Read at startup only.</strong> Changing <code>options.ini</code> requires a game restart.
|
||||
If the <code>[automaticmode]</code> section is absent, or <code>automaticmode=0</code>, or
|
||||
<code>automaticfile</code> is empty, Load File always does nothing regardless of what config file exists.
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>3. Config File Format Rules</h2>
|
||||
<p>The config file uses <strong>standard Windows INI format</strong>, parsed by <code>NotationFile::Standard</code>.</p>
|
||||
<ul>
|
||||
<li><strong>Encoding:</strong> ANSI / ASCII only. No Unicode, no UTF-8 BOM.</li>
|
||||
<li><strong>Line endings:</strong> CRLF or LF — both accepted.</li>
|
||||
<li><strong>Section headers:</strong> <code>[sectionname]</code> — <strong>case-sensitive, must be all lowercase exactly as shown.</strong></li>
|
||||
<li><strong>Key names:</strong> Case-sensitive. Must match exactly as documented below.</li>
|
||||
<li><strong>String values:</strong> Everything after <code>=</code> to end of line. Do <strong>not</strong> wrap in quotes. Example: <code>MissionName=ScarabStronghold - Attrition</code></li>
|
||||
<li><strong>Integer values:</strong> Raw decimal integer only. No quotes, no sign unless negative. Example: <code>GameType=2</code></li>
|
||||
<li><strong>Do not use comments</strong> (<code>//</code> or <code>;</code>). Parser behavior is not guaranteed. Keep the file clean.</li>
|
||||
<li><strong>Missing key:</strong> If a key is absent from its section, the corresponding lobby value stays at its current setting. No error is raised.</li>
|
||||
<li><strong>Missing section:</strong> If <code>[mission]</code> is absent, no game options are changed. If <code>[slot0]</code> is absent, no slots are changed.</li>
|
||||
</ul>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>4. Section: <code>[mission]</code></h2>
|
||||
<p>Sets all game lobby parameters. This section is <span class="optional">optional</span> — omit it to leave game options unchanged and only configure slots.</p>
|
||||
|
||||
<pre><span class="section">[mission]</span>
|
||||
<span class="key">MissionName</span>=<span class="value">ScarabStronghold - Attrition</span>
|
||||
<span class="key">GameType</span>=<span class="value">2</span>
|
||||
<span class="key">TeamAllowed</span>=<span class="value">0</span>
|
||||
<span class="key">Visibility</span>=<span class="value">0</span>
|
||||
<span class="key">Weather</span>=<span class="value">0</span>
|
||||
<span class="key">TimeOfDay</span>=<span class="value">0</span>
|
||||
<span class="key">TimeLimit</span>=<span class="value">7</span>
|
||||
<span class="key">Radar</span>=<span class="value">0</span>
|
||||
<span class="key">HeatOn</span>=<span class="value">0</span>
|
||||
<span class="key">FriendlyFire</span>=<span class="value">0</span>
|
||||
<span class="key">SplashDamage</span>=<span class="value">0</span>
|
||||
<span class="key">UnlimitedAmmo</span>=<span class="value">1</span>
|
||||
<span class="key">WeaponJam</span>=<span class="value">0</span>
|
||||
<span class="key">AdvanceMode</span>=<span class="value">0</span>
|
||||
<span class="key">ArmorMode</span>=<span class="value">0</span></pre>
|
||||
|
||||
<h3>4.1 <code>MissionName</code> — string, max 255 characters</h3>
|
||||
<p>
|
||||
The scenario name, <strong>exactly as it appears in the mission list dropdown in the console lobby.</strong>
|
||||
Match is exact string equality, case-sensitive. Trailing/leading spaces are stripped by the parser.
|
||||
</p>
|
||||
<div class="warn">
|
||||
<strong>If the name is not found</strong> in the list for the selected <code>GameType</code>,
|
||||
mission selection silently fails — the dropdown stays at its previous value.
|
||||
No error is logged. All other parameters (Visibility, Weather, etc.) are still applied.
|
||||
The available mission names depend on what scenario files are installed on the machine;
|
||||
there is no static guaranteed list.
|
||||
</div>
|
||||
|
||||
<h3>4.2 <code>GameType</code> — integer (dropdown index, 0-based)</h3>
|
||||
<div class="warn">
|
||||
<strong>This is the position in the game type dropdown, NOT the internal game type ID number.</strong>
|
||||
The dropdown is built dynamically at lobby startup — only game types that have at least
|
||||
one installed scenario are shown. If a game type has no installed maps it is skipped and all
|
||||
subsequent indices shift down by one.
|
||||
</div>
|
||||
<p>For a <strong>standard full installation</strong> with all game types present, the order is fixed:</p>
|
||||
<table>
|
||||
<tr><th>Index</th><th>Display Name</th><th>Mode</th></tr>
|
||||
<tr><td><code>0</code></td><td>Destruction</td><td>FFA</td></tr>
|
||||
<tr><td><code>1</code></td><td>Team Destruction</td><td>Team</td></tr>
|
||||
<tr><td><code>2</code></td><td>Attrition</td><td>FFA — <strong>default</strong> <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>3</code></td><td>Team Attrition</td><td>Team</td></tr>
|
||||
<tr><td><code>4</code></td><td>Capture the Flag</td><td>FFA</td></tr>
|
||||
<tr><td><code>5</code></td><td>King of the Hill</td><td>FFA</td></tr>
|
||||
<tr><td><code>6</code></td><td>Team King of the Hill</td><td>Team</td></tr>
|
||||
<tr><td><code>7</code></td><td>Steal the Bacon</td><td>FFA</td></tr>
|
||||
<tr><td><code>8</code></td><td>Master Trial</td><td>Special</td></tr>
|
||||
<tr><td><code>9</code></td><td>Siege Assault</td><td>Special</td></tr>
|
||||
<tr><td><code>10+</code></td><td>Custom map variants</td><td>Varies (if custom content installed)</td></tr>
|
||||
</table>
|
||||
<p><strong>Team vs. FFA is important:</strong> it determines whether the <code>Team</code> or <code>Skin</code> field is applied to each slot. See Section 5 for details.</p>
|
||||
|
||||
<h3>4.3 <code>Visibility</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Display Name</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Default</td><td>Same as Clear <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>Clear</td><td>Full visibility range</td></tr>
|
||||
<tr><td><code>2</code></td><td>Light Fog</td><td>Reduced visibility range</td></tr>
|
||||
<tr><td><code>3</code></td><td>Heavy Fog</td><td>Heavily reduced visibility range</td></tr>
|
||||
<tr><td><code>4</code></td><td>Pea Soup Fog</td><td>Near-zero visibility range</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.4 <code>Weather</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Display</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>On (rain or snow depending on map)</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.5 <code>TimeOfDay</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Display</th></tr>
|
||||
<tr><td><code>0</code></td><td>Day <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>Night</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.6 <code>TimeLimit</code> — integer (<strong>actual minutes</strong>, not a list index)</h3>
|
||||
<p>
|
||||
Specify the desired match length in <strong>real minutes</strong>.
|
||||
Valid values that appear in the lobby dropdown:
|
||||
</p>
|
||||
<p>
|
||||
<code>1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20, 25, 30</code>
|
||||
</p>
|
||||
<p>
|
||||
Other integers are accepted and applied to the network parameter but will not match a dropdown item
|
||||
(the visual display may show the nearest value).
|
||||
</p>
|
||||
<p>
|
||||
Special value <code>-1</code>: use the server’s current default time (7 minutes unless changed separately).
|
||||
</p>
|
||||
<p>Default if key absent: server current default (equivalent to <code>-1</code>).</p>
|
||||
|
||||
<h3>4.7 <code>Radar</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Display</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Novice</td><td>All mechs visible, no range limit <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>Normal</td><td>Standard radar with range cutoff</td></tr>
|
||||
<tr><td><code>2</code></td><td>Team Only</td><td>Only your own team visible on radar</td></tr>
|
||||
<tr><td><code>3</code></td><td>No Radar</td><td>Radar completely disabled for all players</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.8 <code>HeatOn</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off — heat never builds, weapons never overheat <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>On — standard heat management enabled</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.9 <code>FriendlyFire</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off — friendly fire disabled <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>On — 100% damage to teammates</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.10 <code>SplashDamage</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>On — area/splash damage from missiles and explosions</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.11 <code>UnlimitedAmmo</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off — ammo is finite</td></tr>
|
||||
<tr><td><code>1</code></td><td>On — unlimited ammo <span class="default-tag">DEFAULT (console/arcade)</span></td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.12 <code>WeaponJam</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>On — weapons can randomly jam</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.13 <code>AdvanceMode</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>On</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.14 <code>ArmorMode</code> — integer</h3>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Off <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>On</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.15 <code>TeamAllowed</code> — integer <span class="optional">(required for correct team/FFA slot display on first click)</span></h3>
|
||||
<p>Must match the <code>GameType</code> selected. Controls whether <code>Team</code> or <code>Skin</code> is applied to slots, and whether team dropdowns are shown.</p>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>FFA mode ? slot <code>Skin</code> field is used <span class="default-tag">DEFAULT</span></td></tr>
|
||||
<tr><td><code>1</code></td><td>Team game ? slot <code>Team</code> field is used</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>4.16 <code>TeamCount</code> — integer <span class="optional">(optional, only when TeamAllowed=1)</span></h3>
|
||||
<p>Number of teams. Valid range: 2–8. Default: <code>2</code>.</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>5. Sections: <code>[slot0]</code> through <code>[slot15]</code></h2>
|
||||
|
||||
<p>One section per roster slot, numbered starting from <strong>zero</strong>.</p>
|
||||
|
||||
<div class="warn">
|
||||
<strong>Slots must be contiguous starting from <code>[slot0]</code>.</strong>
|
||||
The parser stops at the first missing slot number. If <code>[slot2]</code> is absent,
|
||||
<code>[slot3]</code> through <code>[slot15]</code> are never read, even if present in the file.
|
||||
Do not skip numbers.
|
||||
</div>
|
||||
|
||||
<p>Maximum: <strong>16 slots</strong> (indices 0–15). All slots are cleared before applying file data, so slots not defined in the file will be empty in the lobby after Load File is clicked.</p>
|
||||
|
||||
<pre><span class="section">[slot0]</span>
|
||||
<span class="key">Type</span>=<span class="value">1</span>
|
||||
<span class="key">PilotName</span>=<span class="value">Alpha One</span>
|
||||
<span class="key">Mech</span>=<span class="value">Atlas</span>
|
||||
<span class="key">Team</span>=<span class="value">0</span>
|
||||
<span class="key">Skin</span>=<span class="value">0</span>
|
||||
<span class="key">Decal</span>=<span class="value">3</span></pre>
|
||||
|
||||
<h3>5.1 <code>Type</code> — integer, required</h3>
|
||||
<p>Determines what occupies this slot. All other fields are ignored when <code>Type=0</code>.</p>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Description</th></tr>
|
||||
<tr><td><code>0</code></td><td>Empty — slot skipped, left empty in lobby</td></tr>
|
||||
<tr><td><code>1</code></td><td>Player slot — a human pilot can connect to this seat</td></tr>
|
||||
<tr><td><code>2</code></td><td>Bot, difficulty level 1 (easiest)</td></tr>
|
||||
<tr><td><code>3</code></td><td>Bot, difficulty level 2</td></tr>
|
||||
<tr><td><code>4</code></td><td>Bot, difficulty level 3</td></tr>
|
||||
<tr><td><code>5</code></td><td>Bot, difficulty level 4</td></tr>
|
||||
<tr><td><code>6</code></td><td>Bot, difficulty level 5</td></tr>
|
||||
<tr><td><code>7</code></td><td>Bot, difficulty level 6</td></tr>
|
||||
<tr><td><code>8</code></td><td>Bot, difficulty level 7</td></tr>
|
||||
<tr><td><code>9</code></td><td>Bot, difficulty level 8 (hardest)</td></tr>
|
||||
</table>
|
||||
<p>If <code>Type</code> key is absent, it defaults to <code>0</code> (empty) due to zero-initialization.</p>
|
||||
|
||||
<h3>5.2 <code>PilotName</code> — string, max 63 characters</h3>
|
||||
<p>Only meaningful when <code>Type=1</code> (player slot). Sets the callsign shown in the lobby pilot editbox. The connecting player can override this after they connect.</p>
|
||||
<p>For bots (<code>Type=2–9</code>), this field is read from the file but ignored by the script.</p>
|
||||
<p>Set to empty value or omit key to leave the name blank: <code>PilotName=</code></p>
|
||||
<p>Strings longer than 63 characters are silently truncated.</p>
|
||||
|
||||
<h3>5.3 <code>Mech</code> — string (chassis name, exact and case-sensitive)</h3>
|
||||
<p>Must match <strong>exactly</strong> one of the chassis names from <code>MechTable.tbl</code>. The lookup is case-sensitive exact string comparison. If the name is not found, the mech dropdown for that slot stays at its previous value. No error is raised.</p>
|
||||
|
||||
<div class="warn">
|
||||
<strong>These are the table key strings, not display labels.</strong>
|
||||
Pay close attention to capitalization, spacing, and special characters (hyphens, Roman numerals).
|
||||
</div>
|
||||
|
||||
<table class="mech-table">
|
||||
<tr><th>Exact <code>Mech=</code> value</th><th>Notes</th></tr>
|
||||
<tr><td>Annihilator</td><td></td></tr>
|
||||
<tr><td>Archer</td><td></td></tr>
|
||||
<tr><td>Arctic Wolf</td><td>space between words</td></tr>
|
||||
<tr><td>Ares</td><td></td></tr>
|
||||
<tr><td>Argus</td><td></td></tr>
|
||||
<tr><td>AssassinII</td><td>no spaces; capital I</td></tr>
|
||||
<tr><td>Atlas</td><td></td></tr>
|
||||
<tr><td>Avatar</td><td></td></tr>
|
||||
<tr><td>Awesome</td><td></td></tr>
|
||||
<tr><td>Battlemaster</td><td></td></tr>
|
||||
<tr><td>BattlemasterIIC</td><td>no spaces</td></tr>
|
||||
<tr><td>Behemoth</td><td></td></tr>
|
||||
<tr><td>BehemothII</td><td>no space; capital I</td></tr>
|
||||
<tr><td>Black Hawk</td><td>space between words</td></tr>
|
||||
<tr><td>Black Knight</td><td>space between words</td></tr>
|
||||
<tr><td>Black Lanner</td><td>space between words</td></tr>
|
||||
<tr><td>Brigand</td><td></td></tr>
|
||||
<tr><td>Bushwacker</td><td></td></tr>
|
||||
<tr><td>Catapult</td><td></td></tr>
|
||||
<tr><td>Cauldron-Born</td><td>hyphen between words</td></tr>
|
||||
<tr><td>Chimera</td><td></td></tr>
|
||||
<tr><td>Commando</td><td></td></tr>
|
||||
<tr><td>Cougar</td><td></td></tr>
|
||||
<tr><td>Cyclops</td><td></td></tr>
|
||||
<tr><td>Daishi</td><td></td></tr>
|
||||
<tr><td>Deimos</td><td></td></tr>
|
||||
<tr><td>Dragon</td><td></td></tr>
|
||||
<tr><td>Fafnir</td><td></td></tr>
|
||||
<tr><td>Flea</td><td></td></tr>
|
||||
<tr><td>Gladiator</td><td></td></tr>
|
||||
<tr><td>Grizzly</td><td></td></tr>
|
||||
<tr><td>Hauptmann</td><td></td></tr>
|
||||
<tr><td>Hellhound</td><td></td></tr>
|
||||
<tr><td>Hellspawn</td><td></td></tr>
|
||||
<tr><td>Highlander</td><td></td></tr>
|
||||
<tr><td>HollanderII</td><td>no space; capital I</td></tr>
|
||||
<tr><td>Hunchback</td><td></td></tr>
|
||||
<tr><td>Kodiak</td><td></td></tr>
|
||||
<tr><td>Loki</td><td></td></tr>
|
||||
<tr><td>Longbow</td><td></td></tr>
|
||||
<tr><td>Mad Cat</td><td>space between words</td></tr>
|
||||
<tr><td>Mad Cat MKII</td><td>space + "MKII" all caps, no period</td></tr>
|
||||
<tr><td>Masakari</td><td></td></tr>
|
||||
<tr><td>Mauler</td><td></td></tr>
|
||||
<tr><td>Nova Cat</td><td>space between words</td></tr>
|
||||
<tr><td>Osiris</td><td></td></tr>
|
||||
<tr><td>Owens</td><td></td></tr>
|
||||
<tr><td>Puma</td><td></td></tr>
|
||||
<tr><td>Raven</td><td></td></tr>
|
||||
<tr><td>Rifleman</td><td></td></tr>
|
||||
<tr><td>Ryoken</td><td></td></tr>
|
||||
<tr><td>Shadow Cat</td><td>space between words</td></tr>
|
||||
<tr><td>Solitaire</td><td></td></tr>
|
||||
<tr><td>Sunder</td><td></td></tr>
|
||||
<tr><td>Templar</td><td></td></tr>
|
||||
<tr><td>Thanatos</td><td></td></tr>
|
||||
<tr><td>Thor</td><td></td></tr>
|
||||
<tr><td>Uller</td><td></td></tr>
|
||||
<tr><td>Urbanmech</td><td></td></tr>
|
||||
<tr><td>Uziel</td><td></td></tr>
|
||||
<tr><td>Victor</td><td></td></tr>
|
||||
<tr><td>Vulture</td><td></td></tr>
|
||||
<tr><td>Warhammer</td><td></td></tr>
|
||||
<tr><td>Wolfhound</td><td></td></tr>
|
||||
<tr><td>Zeus</td><td></td></tr>
|
||||
</table>
|
||||
|
||||
<h3>5.4 <code>Team</code> — integer</h3>
|
||||
<p>
|
||||
<strong>Only applied in team game modes</strong> (game types marked “Team” in Section 4.2 table).
|
||||
<strong class="ignored-tag">IGNORED in FFA modes.</strong>
|
||||
</p>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Team</th><th>Default Color</th></tr>
|
||||
<tr><td><code>0</code></td><td>Team 1</td><td>Blue</td></tr>
|
||||
<tr><td><code>1</code></td><td>Team 2</td><td>Red</td></tr>
|
||||
<tr><td><code>2</code></td><td>Team 3</td><td>Yellow</td></tr>
|
||||
<tr><td><code>3</code></td><td>Team 4</td><td>Green</td></tr>
|
||||
<tr><td><code>4</code></td><td>Team 5</td><td>Purple</td></tr>
|
||||
<tr><td><code>5</code></td><td>Team 6</td><td>Light Blue</td></tr>
|
||||
<tr><td><code>6</code></td><td>Team 7</td><td>Orange</td></tr>
|
||||
<tr><td><code>7</code></td><td>Team 8</td><td>Charcoal</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>5.5 <code>Skin</code> — integer (FFA camo, dropdown index 0-based)</h3>
|
||||
<p>
|
||||
<strong>Only applied in FFA game modes.</strong>
|
||||
<strong class="ignored-tag">IGNORED in team modes.</strong>
|
||||
</p>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Camo Color/Pattern</th></tr>
|
||||
<tr><td><code>0</code></td><td>Blue</td></tr>
|
||||
<tr><td><code>1</code></td><td>Red</td></tr>
|
||||
<tr><td><code>2</code></td><td>Yellow</td></tr>
|
||||
<tr><td><code>3</code></td><td>Green</td></tr>
|
||||
<tr><td><code>4</code></td><td>Purple</td></tr>
|
||||
<tr><td><code>5</code></td><td>Light Blue</td></tr>
|
||||
<tr><td><code>6</code></td><td>Orange</td></tr>
|
||||
<tr><td><code>7</code></td><td>Charcoal</td></tr>
|
||||
<tr><td><code>8</code>–<code>15</code></td><td>Additional camo patterns</td></tr>
|
||||
</table>
|
||||
|
||||
<h3>5.6 <code>Decal</code> — integer (faction emblem, 0–63)</h3>
|
||||
<p>
|
||||
Applied in <strong>both team and FFA modes.</strong>
|
||||
Valid range: <code>0</code>–<code>63</code>. All values in range are accepted. Common values:
|
||||
</p>
|
||||
<table>
|
||||
<tr><th>Value</th><th>Faction</th></tr>
|
||||
<tr><td><code>0</code></td><td>None</td></tr>
|
||||
<tr><td><code>2</code></td><td>Davion</td></tr>
|
||||
<tr><td><code>3</code></td><td>Steiner</td></tr>
|
||||
<tr><td><code>4</code></td><td>Kurita</td></tr>
|
||||
<tr><td><code>5</code></td><td>Liao</td></tr>
|
||||
<tr><td><code>6</code></td><td>Marik</td></tr>
|
||||
<tr><td><code>9</code></td><td>ComStar</td></tr>
|
||||
<tr><td><code>10</code></td><td>Star League</td></tr>
|
||||
<tr><td><code>11</code></td><td>Wolf Clan</td></tr>
|
||||
<tr><td><code>12</code></td><td>Jade Falcon</td></tr>
|
||||
<tr><td><code>16</code></td><td>Ghost Bear</td></tr>
|
||||
<tr><td><code>20</code></td><td>Hell Horses</td></tr>
|
||||
<tr><td><code>21</code></td><td>Coyote</td></tr>
|
||||
<tr><td><code>22</code></td><td>Blood Spirit</td></tr>
|
||||
<tr><td><code>24</code></td><td>Ice Hellion</td></tr>
|
||||
<tr><td><code>27</code></td><td>Goliath Scorpion</td></tr>
|
||||
<tr><td><code>46</code></td><td>BKG</td></tr>
|
||||
<tr><td><code>47</code></td><td>FSA</td></tr>
|
||||
<tr><td><code>48</code></td><td>331st</td></tr>
|
||||
<tr><td><code>49</code></td><td>DDC</td></tr>
|
||||
<tr><td><code>50</code></td><td>VGL</td></tr>
|
||||
</table>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>6. Complete Example File</h2>
|
||||
|
||||
<pre><span class="section">[mission]</span>
|
||||
<span class="key">MissionName</span>=<span class="value">ScarabStronghold - Attrition</span>
|
||||
<span class="key">GameType</span>=<span class="value">2</span>
|
||||
<span class="key">Visibility</span>=<span class="value">0</span>
|
||||
<span class="key">Weather</span>=<span class="value">0</span>
|
||||
<span class="key">TimeOfDay</span>=<span class="value">0</span>
|
||||
<span class="key">TimeLimit</span>=<span class="value">7</span>
|
||||
<span class="key">Radar</span>=<span class="value">0</span>
|
||||
<span class="key">HeatOn</span>=<span class="value">0</span>
|
||||
<span class="key">FriendlyFire</span>=<span class="value">0</span>
|
||||
<span class="key">SplashDamage</span>=<span class="value">0</span>
|
||||
<span class="key">UnlimitedAmmo</span>=<span class="value">1</span>
|
||||
<span class="key">WeaponJam</span>=<span class="value">0</span>
|
||||
<span class="key">AdvanceMode</span>=<span class="value">0</span>
|
||||
<span class="key">ArmorMode</span>=<span class="value">0</span>
|
||||
|
||||
<span class="section">[slot0]</span>
|
||||
<span class="key">Type</span>=<span class="value">1</span>
|
||||
<span class="key">PilotName</span>=<span class="value">Blackjack</span>
|
||||
<span class="key">Mech</span>=<span class="value">Atlas</span>
|
||||
<span class="key">Team</span>=<span class="value">0</span>
|
||||
<span class="key">Skin</span>=<span class="value">0</span>
|
||||
<span class="key">Decal</span>=<span class="value">3</span>
|
||||
|
||||
<span class="section">[slot1]</span>
|
||||
<span class="key">Type</span>=<span class="value">1</span>
|
||||
<span class="key">PilotName</span>=<span class="value">Viper</span>
|
||||
<span class="key">Mech</span>=<span class="value">Mad Cat</span>
|
||||
<span class="key">Team</span>=<span class="value">0</span>
|
||||
<span class="key">Skin</span>=<span class="value">1</span>
|
||||
<span class="key">Decal</span>=<span class="value">4</span>
|
||||
|
||||
<span class="section">[slot2]</span>
|
||||
<span class="key">Type</span>=<span class="value">2</span>
|
||||
<span class="key">PilotName</span>=
|
||||
<span class="key">Mech</span>=<span class="value">Thor</span>
|
||||
<span class="key">Team</span>=<span class="value">1</span>
|
||||
<span class="key">Skin</span>=<span class="value">1</span>
|
||||
<span class="key">Decal</span>=<span class="value">4</span>
|
||||
|
||||
<span class="section">[slot3]</span>
|
||||
<span class="key">Type</span>=<span class="value">2</span>
|
||||
<span class="key">PilotName</span>=
|
||||
<span class="key">Mech</span>=<span class="value">Warhammer</span>
|
||||
<span class="key">Team</span>=<span class="value">1</span>
|
||||
<span class="key">Skin</span>=<span class="value">1</span>
|
||||
<span class="key">Decal</span>=<span class="value">4</span></pre>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2>7. Known Constraints and Caveats</h2>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
<strong>Slots must be numbered contiguously from <code>[slot0]</code>.</strong>
|
||||
The parser uses a loop that breaks on the first missing section. Defining <code>[slot0]</code>
|
||||
and <code>[slot2]</code> without <code>[slot1]</code> means only slot 0 is processed.
|
||||
</li>
|
||||
<li>
|
||||
<strong>All current slots are cleared before file slots are applied.</strong>
|
||||
Any slot not defined in the file (or defined with <code>Type=0</code>) will be empty in the lobby.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Team vs. FFA display is correct on the first click</strong> provided <code>TeamAllowed=</code> is set correctly in the file.
|
||||
The game updates <code>team_allowed</code> synchronously from this field before processing slots.
|
||||
If <code>TeamAllowed</code> is absent, it defaults to <code>0</code> (FFA) regardless of <code>GameType</code>.
|
||||
</li>
|
||||
<li>
|
||||
<strong><code>MissionName</code> and <code>Mech</code> matches are case-sensitive.</strong>
|
||||
<code>atlas</code> will not match <code>Atlas</code>.
|
||||
</li>
|
||||
<li>
|
||||
<strong>The file is never deleted by the game.</strong>
|
||||
Write it before the match, overwrite it before the next match. No locking is performed.
|
||||
</li>
|
||||
<li>
|
||||
<strong><code>options.ini</code> is read only at game startup.</strong>
|
||||
Changing the <code>automaticfile</code> path or enabling/disabling the feature requires a restart.
|
||||
The config file itself is re-read fresh on every Load File button click.
|
||||
</li>
|
||||
<li>
|
||||
<strong>Buffer limits:</strong> <code>PilotName</code> ≤ 63 chars (truncated silently);
|
||||
<code>MissionName</code> ≤ 255 chars;
|
||||
<code>automaticfile</code> path ≤ 259 chars (<code>MAX_PATH − 1</code>).
|
||||
</li>
|
||||
<li>
|
||||
<strong>Mech names are sourced from <code>MechTable.tbl</code>.</strong>
|
||||
If the game installation has custom mechs added or some mechs removed, the valid name list
|
||||
changes accordingly. The table above reflects the standard Firestorm build.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<hr>
|
||||
<p style="font-size:9pt; color:#888; text-align:center; margin-top:30px;">
|
||||
Generated from source: <code>MW4Shell.cpp</code> — <code>CTCL_LoadAutoFile</code>,
|
||||
<code>CTCL_GetAutoSlotName/Mech/Int</code> |
|
||||
<code>ConLobby.script</code> — <code>o_load_file</code> handler |
|
||||
<code>ConLobbyMission.script</code> — <code>MAIL_LOAD_AUTO_MISSION</code> |
|
||||
Commit cd2fe73c | 2026-07-24
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate special_weapon_locations.csv and rear_facing_weapons.csv from stock mech subsystems."""
|
||||
import csv
|
||||
from pathlib import Path
|
||||
|
||||
BASE = Path("Gameleap/mw4/Content")
|
||||
MECH_TABLE = BASE / "Tables" / "MechTable.tbl"
|
||||
OUT_DIR = Path("BTFrstrm")
|
||||
|
||||
def parse_ini(path):
|
||||
sections, cur_sec, cur_dict = [], None, {}
|
||||
with open(path, 'r', encoding='latin-1', errors='replace') as f:
|
||||
for raw in f:
|
||||
line = raw.strip()
|
||||
if line.startswith('[') and line.endswith(']'):
|
||||
if cur_sec is not None:
|
||||
sections.append((cur_sec, cur_dict))
|
||||
cur_sec, cur_dict = line[1:-1], {}
|
||||
elif '=' in line and cur_sec is not None:
|
||||
k, _, v = line.partition('=')
|
||||
cur_dict[k.strip()] = v.strip()
|
||||
if cur_sec is not None:
|
||||
sections.append((cur_sec, cur_dict))
|
||||
return sections
|
||||
|
||||
def find_dir_ci(parent, name):
|
||||
"""Case-insensitive directory lookup for Linux."""
|
||||
exact = parent / name
|
||||
if exact.exists():
|
||||
return exact
|
||||
name_lower = name.lower()
|
||||
for child in parent.iterdir():
|
||||
if child.is_dir() and child.name.lower() == name_lower:
|
||||
return child
|
||||
return None
|
||||
|
||||
def weapon_model(model_path):
|
||||
return Path(model_path.replace('\\', '/')).stem
|
||||
|
||||
# Read chassis list from MechTable.tbl
|
||||
chassis_list = []
|
||||
with open(MECH_TABLE, 'r', encoding='latin-1') as f:
|
||||
for raw in f:
|
||||
line = raw.strip()
|
||||
if not line or line.startswith('//') or line.startswith('[') or '=' not in line:
|
||||
continue
|
||||
name, _, rel = line.partition('=')
|
||||
# rel is like "Mechs\Atlas\Atlas.instance"
|
||||
parts = rel.strip().replace('\\', '/').split('/')
|
||||
chassis_list.append((name.strip(), parts)) # parts = ['Mechs', 'Atlas', 'Atlas.instance']
|
||||
|
||||
print(f"Found {len(chassis_list)} chassis in MechTable.tbl")
|
||||
|
||||
HDR = ['Chassis', 'InternalLocation', 'Model', 'Site', 'AmmoCount', 'GroupIndex', 'WeaponFacing']
|
||||
special_rows, rear_rows, missing = [], [], []
|
||||
|
||||
mechs_dir = BASE / "Mechs"
|
||||
|
||||
for chassis_name, path_parts in chassis_list:
|
||||
# path_parts[1] is the mech directory name (e.g. 'Atlas', 'MadCat_MkII', 'Urbanmech')
|
||||
if len(path_parts) < 2:
|
||||
missing.append(chassis_name)
|
||||
continue
|
||||
|
||||
mech_dir = find_dir_ci(mechs_dir, path_parts[1])
|
||||
if not mech_dir:
|
||||
missing.append(f"{chassis_name} (dir not found: {path_parts[1]})")
|
||||
continue
|
||||
|
||||
subs = [f for f in mech_dir.glob('*.subsystems') if f.suffix == '.subsystems']
|
||||
if not subs:
|
||||
missing.append(f"{chassis_name} (no .subsystems in {mech_dir.name})")
|
||||
continue
|
||||
|
||||
subsys_file = subs[0]
|
||||
sections = parse_ini(subsys_file)
|
||||
|
||||
for sec_name, fields in sections:
|
||||
if 'WeaponSubsystem' not in fields.get('Model', ''):
|
||||
continue
|
||||
|
||||
loc = fields.get('InternalLocation', '')
|
||||
model = weapon_model(fields.get('Model', ''))
|
||||
site = fields.get('Site', '')
|
||||
ammo = fields.get('AmmoCount', '')
|
||||
group = fields.get('GroupIndex', '')
|
||||
facing = fields.get('WeaponFacing', '')
|
||||
|
||||
if loc in ('Special1', 'Special2'):
|
||||
special_rows.append([chassis_name, loc, model, site, ammo, group, facing])
|
||||
|
||||
if facing and facing != '0':
|
||||
rear_rows.append([chassis_name, loc, model, site, ammo, group, facing])
|
||||
|
||||
# Write CSVs
|
||||
out1 = OUT_DIR / 'special_weapon_locations.csv'
|
||||
with open(out1, 'w', newline='') as f:
|
||||
w = csv.writer(f)
|
||||
w.writerow(HDR)
|
||||
w.writerows(special_rows)
|
||||
|
||||
out2 = OUT_DIR / 'rear_facing_weapons.csv'
|
||||
with open(out2, 'w', newline='') as f:
|
||||
w = csv.writer(f)
|
||||
w.writerow(HDR)
|
||||
w.writerows(rear_rows)
|
||||
|
||||
print(f"Spreadsheet 1 ? Special1/2 weapon locations: {len(special_rows)} rows -> {out1}")
|
||||
print(f"Spreadsheet 2 ? Non-forward WeaponFacing: {len(rear_rows)} rows -> {out2}")
|
||||
if missing:
|
||||
print(f"\nSkipped: {missing}")
|
||||
@@ -0,0 +1,88 @@
|
||||
Mech,In_game_playable,Tech,Chassis_Tonnage,Max_Loadout_Tonnage,Armor_Type,Internal_Type,Heatsinks,Heatsink_Type,JumpJets_Installed,CanLoad_JJ,CanLoad_ECM,CanLoad_BAP,CanLoad_AMS,OmniSlots,Equipment,Armor_LeftArm,Armor_RightArm,Armor_LeftLeg,Armor_RightLeg,Armor_LeftFrontTorso,Armor_RightFrontTorso,Armor_CenterFrontTorso,Armor_CenterRearTorso,Armor_Head,Total_Armor_Multiplier,Weapon_Count,Weapons_Summary,Weapons_With_Locations,Default_Installed_Locations,Available_Slot_Capacity_By_Zone,Available_Hardpoints,notes
|
||||
Annihilator,Yes,IS,23.000000,100.000000,Reflective,EndoSteel,17,Single,0,No,Yes,Yes,Yes,43,,1.8,1.8,1.8,1.8,1.85,1.85,2.0,0.8,0.3,14,10,"4x ClanERSmallLaser, 2x ClanMachineGun, 4x ClanUltraAC5",ClanERSmallLaser@LeftTorso(Front) G1 | ClanERSmallLaser@CenterTorso(Front) G1 | ClanERSmallLaser@CenterTorso(Front) G1 | ClanERSmallLaser@RightTorso(Front) G1 | ClanMachineGun@LeftTorso(Front) G1 | ClanMachineGun@RightTorso(Front) G1 | ClanUltraAC5@LeftArm(Front) G1 | ClanUltraAC5@LeftArm(Front) G1 | ClanUltraAC5@RightArm(Front) G1 | ClanUltraAC5@RightArm(Front) G1,LeftTorsox2 | CenterTorsox2 | RightTorsox2 | LeftArmx2 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Front) | Head(Unknown),
|
||||
Archer,Yes,IS,17.000000,70.000000,Standard,Standard,20,Single,1,Yes,Yes,Yes,Yes,43,,1.1,1.1,1.2,1.2,1.4,1.4,1.5,0.5,0.3,9.7,9,"4x MediumPulseLaser, 2x SSRM2, 2x LRM15, NarcBeacon",MediumPulseLaser@LeftArm(Front) G1 | MediumPulseLaser@CenterTorso(Front) G1 | MediumPulseLaser@CenterTorso(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | SSRM2@LeftArm(Front) G2 | SSRM2@RightArm(Front) G2 | LRM15@LeftTorso(Side) G2 | LRM15@RightTorso(Side) G2 | NarcBeacon@LeftTorso(Front) G3,LeftArmx2 | CenterTorsox2 | RightArmx2 | LeftTorsox2 | RightTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front+Side) | RightTorso(Side) | CenterTorso(Front) | Head(Unknown),
|
||||
ArcticWolf,Yes,Clan,9.500000,40.000000,FerroFiberus,EndoSteel,8,Single,1,Yes,Yes,Yes,Yes,43,,0.7,0.7,0.95,0.95,0.85,0.85,1.0,0.2,0.3,6.5,6,"2x ClanSmallPulseLaser, 4x ClanSSRM4",ClanSmallPulseLaser@RightTorso(Front) G1 | ClanSmallPulseLaser@RightTorso(Front) G1 | ClanSSRM4@leftarm(Front) G2 | ClanSSRM4@special1(Front) G2 | ClanSSRM4@special2(Front) G2 | ClanSSRM4@rightarm(Front) G2,RightTorsox2 | leftarmx1 | special1x1 | special2x1 | rightarmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O8) | RightTorso(M0/P0/B0/O8) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4) | Special2(M0/P0/B0/O4),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown) | Special1(Unknown) | Special2(Unknown),
|
||||
Ares,Yes,Clan,15.500000,60.000000,FerroFiberus,Standard,15,Single,0,Yes,Yes,Yes,Yes,46,,0.9,0.9,1.15,1.15,1.1,1.1,1.45,0.9,0.25,8.9,9,"2x ClanERSmallLaser, 3x ClanERMediumLaser, ClanERLargeLaser, 3x ClanLRM10",ClanERSmallLaser@Special1(Front) G1 | ClanERSmallLaser@Special1(Front) G1 | ClanERMediumLaser@LeftArm(Front) G1 | ClanERMediumLaser@RightArm(Front) G1 | ClanERMediumLaser@RightArm(Front) G1 | ClanERLargeLaser@LeftArm(Front) G1 | ClanLRM10@Special2(Side) G2 | ClanLRM10@Special2(Side) G2 | ClanLRM10@Special2(Side) G2,Special1x2 | LeftArmx2 | RightArmx2 | Special2x3,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2) | Special2(M0/P0/B0/O3),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | Head(Unknown) | Special1(Front) | Special2(Side),
|
||||
Argus,Yes,IS,14.500000,60.000000,Standard,Standard,13,Single,0,No,Yes,Yes,Yes,43,,0.7,0.7,1.15,1.15,0.85,0.85,1.45,0.9,0.3,8.05,9,"3x MediumLaser, PPC, 4x MachineGun, LRM10",MediumLaser@Lefttorso(Front) G1 | MediumLaser@Righttorso(Front) G1 | MediumLaser@RightArm(Front) G1 | PPC@RightArm(Front) G1 | MachineGun@LeftTorso(Front) G1 | MachineGun@CenterTorso(Front) G1 | MachineGun@CenterTorso(Front) G1 | MachineGun@RightTorso(Front) G1 | LRM10@LeftArm(Front) G2,Lefttorsox1 | Righttorsox1 | RightArmx2 | LeftTorsox1 | CenterTorsox2 | RightTorsox1 | LeftArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Front) | Head(Unknown),
|
||||
Assassin2,Yes,IS,12.000000,45.000000,FerroFiberus,EndoSteel,6,Single,0,Yes,Yes,Yes,Yes,40,,0.85,0.85,0.85,0.85,0.9,0.9,1.05,0.45,0.25,6.95,7,"2x SmallLaser, 2x MediumLaser, 2x SRM4, LRM5",SmallLaser@LeftArm(Front) G1 | SmallLaser@RightArm(Front) G1 | MediumLaser@LeftArm(Front) G1 | MediumLaser@RightArm(Front) G1 | SRM4@LeftTorso(Front) G2 | SRM4@RightTorso(Front) G2 | LRM5@Special1(Side) G2,LeftArmx2 | RightArmx2 | LeftTorsox1 | RightTorsox1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O10) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | Special1(Side),
|
||||
Atlas,Yes,IS,28.000000,100.000000,Standard,Standard,17,Single,0,No,Yes,Yes,Yes,43,,1.95,1.95,2.15,2.15,2.45,2.45,2.2,1.1,0.3,16.7,9,"4x MediumLaser, AC20, 2x SSRM2, SRM6, LRM20",MediumLaser@LeftArm(Front) G1 | MediumLaser@Head(Front) G1 | MediumLaser@CenterTorso(Front) G1 | MediumLaser@RightArm(Front) G1 | AC20@Special1(Front) G1 | SSRM2@LeftTorso(Front) G2 | SSRM2@RightTorso(Front) G2 | SRM6@Special2(Front) G2 | LRM20@LeftTorso(Side) G2,LeftArmx1 | Headx1 | CenterTorsox1 | RightArmx1 | Special1x1 | LeftTorsox2 | RightTorsox1 | Special2x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O10) | RightTorso(M0/P0/B0/O8) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4) | Special2(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front+Side) | RightTorso(Front) | CenterTorso(Front) | Head(Front) | Special1(Front) | Special2(Front),
|
||||
Avatar,Yes,IS,17.000000,70.000000,Reactive,EndoSteel,12,Single,0,Yes,Yes,Yes,Yes,43,,1.3,1.3,1.5,1.5,1.6,1.6,1.75,0.5,0.3,11.35,10,"4x MachineGun, 2x LargeLaser, 2x LRM5, 2x LRM10",MachineGun@LeftArm(Front) G1 | MachineGun@Special1(Front) G1 | MachineGun@Special1(Front) G1 | MachineGun@RightArm(Front) G1 | LargeLaser@LeftArm(Front) G1 | LargeLaser@RightArm(Front) G1 | LRM5@LeftTorso(Side) G2 | LRM5@RightTorso(Side) G2 | LRM10@LeftTorso(Side) G2 | LRM10@RightTorso(Side) G2,LeftArmx2 | Special1x2 | RightArmx2 | LeftTorsox2 | RightTorsox2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Side) | RightTorso(Side) | Head(Unknown) | Special1(Front),
|
||||
Awesome,Yes,IS,23.000000,80.000000,Standard,Standard,28,Single,0,No,Yes,Yes,Yes,43,,1.45,1.45,1.55,1.55,1.65,1.65,1.75,1.25,0.3,12.6,6,"SmallPulseLaser, 3x ERPPC, UltraAC5, LRM5",SmallPulseLaser@Head(Front) G1 | ERPPC@Lefttorso(Front) G1 | ERPPC@righttorso(Front) G1 | ERPPC@RightArm(Front) G1 | UltraAC5@LeftArm(Front) G1 | LRM5@CenterTorso(Side) G2,Headx1 | Lefttorsox1 | righttorsox1 | RightArmx1 | LeftArmx1 | CenterTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Side) | Head(Front),
|
||||
Battlemaster,Yes,IS,20.500000,85.000000,Standard,EndoSteel,25,Single,0,No,Yes,Yes,Yes,43,,1.45,1.45,1.6,1.6,1.8,1.8,2.05,0.95,0.3,13,10,"PPC, 6x MediumLaser, 2x MachineGun, SRM6",PPC@Special2(Front) G1 | MediumLaser@RightTorso(Front) G1 | MediumLaser@RightTorso(Front) G1 | MediumLaser@RightTorso(Rear) G1 | MediumLaser@LeftTorso(Front) G1 | MediumLaser@LeftTorso(Front) G1 | MediumLaser@LeftTorso(Rear) G1 | MachineGun@LeftArm(Front) G1 | MachineGun@LeftArm(Front) G1 | SRM6@Special1(Front) G2,Special2x1 | RightTorsox3 | LeftTorsox3 | LeftArmx2 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O4) | LeftTorso(M0/P0/B0/O9) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O3) | Special2(M0/P0/B0/O4),LeftArm(Front) | RightArm(Unknown) | LeftTorso(Front+Rear) | RightTorso(Front+Rear) | CenterTorso(Unknown) | Head(Unknown) | Special1(Front) | Special2(Front),
|
||||
Battlemaster2c,Yes,Clan,15.500000,85.000000,Standard,EndoSteel,25,Single,0,No,Yes,Yes,Yes,39,,1.45,1.45,1.6,1.6,1.8,1.8,2.05,0.95,0.3,13,10,"ClanERPPC, 6x ClanERMediumLaser, 2x ClanGaussRifle, ClanSSRM6",ClanERPPC@RightArm(Front) G1 | ClanERMediumLaser@RightTorso(Front) G1 | ClanERMediumLaser@RightTorso(Front) G1 | ClanERMediumLaser@RightTorso(Rear) G1 | ClanERMediumLaser@LeftTorso(Front) G1 | ClanERMediumLaser@LeftTorso(Front) G1 | ClanERMediumLaser@LeftTorso(Rear) G1 | ClanGaussRifle@LeftArm(Front) G1 | ClanGaussRifle@LeftArm(Front) G1 | ClanSSRM6@Special1(Front) G2,RightArmx1 | RightTorsox3 | LeftTorsox3 | LeftArmx2 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O4) | LeftTorso(M0/P0/B0/O9) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O3),LeftArm(Front) | RightArm(Front) | LeftTorso(Front+Rear) | RightTorso(Front+Rear) | CenterTorso(Unknown) | Head(Unknown) | Special1(Front),
|
||||
Behemoth,Yes,Clan,22.000000,100.000000,Standard,Standard,21,Single,1,Yes,Yes,Yes,Yes,43,,1.95,1.95,2.15,2.15,2.45,2.45,2.2,1.1,0.3,16.7,7,"4x ClanLargePulseLaser, 2x ClanGaussRifle, LargeLaser",ClanLargePulseLaser@LeftTorso(Front) G1 | ClanLargePulseLaser@LeftTorso(Front) G1 | ClanLargePulseLaser@RightTorso(Front) G1 | ClanLargePulseLaser@RightTorso(Front) G1 | ClanGaussRifle@LeftArm(Front) G1 | ClanGaussRifle@RightArm(Front) G1 | LargeLaser@Special1(Front) G1,LeftTorsox2 | RightTorsox2 | LeftArmx1 | RightArmx1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | Head(Unknown) | Special1(Front),
|
||||
Behemoth2,Yes,Clan,22.000000,100.000000,Standard,Standard,21,Single,1,Yes,Yes,Yes,Yes,43,,1.95,1.95,2.15,2.15,2.45,2.45,2.2,1.1,0.3,16.7,7,"4x ClanLargePulseLaser, 2x ClanGaussRifle, LargeLaser",ClanLargePulseLaser@LeftTorso(Front) G1 | ClanLargePulseLaser@LeftTorso(Front) G1 | ClanLargePulseLaser@RightTorso(Front) G1 | ClanLargePulseLaser@RightTorso(Front) G1 | ClanGaussRifle@LeftArm(Front) G1 | ClanGaussRifle@RightArm(Front) G1 | LargeLaser@Special1(Front) G1,LeftTorsox2 | RightTorsox2 | LeftArmx1 | RightArmx1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | Head(Unknown) | Special1(Front),
|
||||
Blackhawk,Yes,Clan,10.000000,50.000000,FerroFiberus,EndoSteel,12,Single,0,Yes,Yes,Yes,Yes,43,,0.9,0.9,0.95,0.95,1.05,1.05,1.2,0.55,0.25,7.8,4,"2x ClanMediumPulseLaser, 2x ClanERPPC",ClanMediumPulseLaser@LeftTorso(Front) G1 | ClanMediumPulseLaser@RightTorso(Front) G1 | ClanERPPC@LeftArm(Front) G1 | ClanERPPC@RightArm(Front) G1,LeftTorsox1 | RightTorsox1 | LeftArmx1 | RightArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O10) | RightTorso(M0/P0/B0/O10) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2) | Special2(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown) | Special1(Unknown) | Special2(Unknown),
|
||||
Blackheart,No,Clan,14.000000,70.000000,FerroFiberus,Standard,0,,0,No,Yes,No,No,6,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P3/B0/O0) | RightArm(M0/P3/B0/O0) | LeftTorso(M0/P0/B1/O2) | RightTorso(M0/P0/B1/O2) | CenterTorso(M0/P0/B0/O2),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
Blacklanner,Yes,Clan,12.500000,55.000000,FerroFiberus,EndoSteel,10,Single,0,No,Yes,Yes,Yes,40,ECM,0.9,0.9,1.0,1.0,1.05,1.05,1.15,0.75,0.25,8.05,5,"2x ClanERMediumLaser, ClanERLargeLaser, ClanSRM6, ClanLRM10",ClanERMediumLaser@LeftArm(Front) G1 | ClanERMediumLaser@LeftArm(Front) G1 | ClanERLargeLaser@RightArm(Front) G1 | ClanSRM6@Special2(Side) G2 | ClanLRM10@Special1(Side) G2,LeftArmx2 | RightArmx1 | Special2x1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | Special1(M0/P0/B0/O12) | Special2(M0/P0/B0/O12),LeftArm(Front) | RightArm(Front) | Special1(Side) | Special2(Side),
|
||||
Blacknight,Yes,IS,16.000000,75.000000,Standard,Standard,22,Single,0,Yes,Yes,Yes,Yes,43,,1.2,1.2,1.4,1.4,1.55,1.55,1.8,0.8,0.3,11.2,8,"SmallLaser, 4x MediumLaser, 2x LargeLaser, PPC",SmallLaser@Head(Front) G1 | MediumLaser@LeftArm(Front) G1 | MediumLaser@LeftTorso(Front) G1 | MediumLaser@RightTorso(Front) G1 | MediumLaser@RightArm(Front) G1 | LargeLaser@LeftTorso(Front) G1 | LargeLaser@RightTorso(Front) G1 | PPC@RightArm(Front) G1,Headx1 | LeftArmx1 | LeftTorsox2 | RightTorsox2 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Front),
|
||||
Bowman,No,Clan,16.000000,70.000000,FerroFiberus,Standard,0,,0,No,Yes,Yes,No,5,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P2/B2/O2) | RightArm(M4/P0/B0/O0) | Special1(M4/P0/B0/O0) | Special2(M0/P0/B0/O3),LeftArm(Unknown) | RightArm(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
Brigand,Yes,IS,7.000000,25.000000,FerroFiberus,Standard,10,Single,0,Yes,Yes,Yes,Yes,40,,0.45,0.45,0.45,0.45,0.55,0.55,0.55,0.4,0.25,4.1,4,"2x MediumPulseLaser, 2x MediumLaser",MediumPulseLaser@LeftArm(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | MediumLaser@Special2(Front) G1 | MediumLaser@Special1(Front) G1,LeftArmx1 | RightArmx1 | Special2x1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | Special1(M0/P0/B0/O12) | Special2(M0/P0/B0/O12),LeftArm(Front) | RightArm(Front) | Special1(Front) | Special2(Front),
|
||||
Bushwacker,Yes,IS,15.500000,55.000000,FerroFiberus,Standard,11,Single,0,No,Yes,Yes,Yes,43,,0.9,0.9,1.1,1.1,1.15,1.15,1.35,0.5,0.25,8.4,8,"2x MediumLaser, ERLargeLaser, 2x MachineGun, AC10, 2x LRM5",MediumLaser@CenterTorso(Front) G1 | MediumLaser@CenterTorso(Front) G1 | ERLargeLaser@RightArm(Front) G1 | MachineGun@LeftTorso(Front) G1 | MachineGun@RightTorso(Front) G1 | AC10@LeftArm(Front) G1 | LRM5@Special1(Side) G2 | LRM5@Special1(Side) G2,CenterTorsox2 | RightArmx1 | LeftTorsox1 | RightTorsox1 | LeftArmx1 | Special1x2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O8) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Front) | Head(Unknown) | Special1(Side),
|
||||
Canis,No,Clan,15.000000,80.000000,FerroFiberus,EndoSteel,0,,0,Yes,No,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B5/O0) | RightArm(M0/P0/B5/O0) | Special1(M0/P3/B0/O0) | Special2(M0/P3/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
Catapult,Yes,IS,15.000000,65.000000,Reactive,Standard,10,Single,1,Yes,Yes,Yes,Yes,43,BAP,1.45,1.45,1.35,1.35,1.45,1.45,1.5,0.65,0.3,10.95,4,"2x LargeLaser, 2x LRM20",LargeLaser@LeftTorso(Front) G1 | LargeLaser@RightTorso(Front) G1 | LRM20@LeftArm(Side) G2 | LRM20@RightArm(Side) G2,LeftTorsox1 | RightTorsox1 | LeftArmx1 | RightArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Side) | RightArm(Side) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
CauldronBorn,Yes,Clan,13.500000,65.000000,FerroFiberus,EndoSteel,13,Single,0,Yes,Yes,Yes,Yes,43,,0.85,0.85,0.95,0.95,1.15,1.15,1.55,0.85,0.25,8.55,6,"ClanERMediumLaser, ClanUltraAC5, ClanGaussRifle, ClanSSRM2, 2x ClanLRM10",ClanERMediumLaser@LeftTorso(Front) G1 | ClanUltraAC5@LeftArm(Front) G1 | ClanGaussRifle@RightArm(Front) G1 | ClanSSRM2@RightTorso(Front) G2 | ClanLRM10@Special1(Side) G2 | ClanLRM10@Special2(Side) G2,LeftTorsox1 | LeftArmx1 | RightArmx1 | RightTorsox1 | Special1x1 | Special2x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O8) | RightTorso(M0/P0/B0/O8) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4) | Special2(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown) | Special1(Side) | Special2(Side),
|
||||
Chimera,Yes,IS,9.500000,40.000000,Standard,EndoSteel,14,Single,1,Yes,Yes,Yes,Yes,43,BAP,0.95,0.95,1.0,1.0,1.0,1.0,1.1,0.5,0.3,7.8,7,"2x MediumPulseLaser, ERLargeLaser, 4x LRM5",MediumPulseLaser@LeftArm(Front) G1 | MediumPulseLaser@LeftArm(Front) G1 | ERLargeLaser@RightArm(Front) G1 | LRM5@RightTorso(Side) G2 | LRM5@RightTorso(Side) G2 | LRM5@RightTorso(Side) G2 | LRM5@RightTorso(Side) G2,LeftArmx2 | RightArmx1 | RightTorsox4,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Side) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Commando,Yes,IS,7.000000,25.000000,Standard,Standard,8,Single,0,Yes,Yes,Yes,Yes,43,,0.6,0.6,0.8,0.8,0.75,0.75,0.8,0.45,0.3,5.85,3,"2x MediumLaser, SRM6",MediumLaser@LeftArm(Front) G1 | MediumLaser@RightArm(Front) G1 | SRM6@CenterTorso(Front) G2,LeftArmx1 | RightArmx1 | CenterTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Front) | Head(Unknown),
|
||||
Cougar,Yes,Clan,8.500000,35.000000,FerroFiberus,EndoSteel,10,Single,1,Yes,Yes,Yes,Yes,43,BAP,0.7,0.7,0.7,0.7,0.75,0.75,0.8,0.45,0.25,5.8,5,"2x ClanMediumPulseLaser, ClanMachineGun, 2x ClanLRM10",ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanMachineGun@RightTorso(Front) G1 | ClanLRM10@LeftTorso(Side) G2 | ClanLRM10@RightTorso(Side) G2,LeftArmx1 | RightArmx1 | RightTorsox2 | LeftTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Side) | RightTorso(Front+Side) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Crab,No,IS,10.500000,50.000000,FerroFiberus,Standard,0,,0,No,No,Yes,No,1,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B4/O0) | RightArm(M0/P0/B4/O0) | CenterTorso(M0/P0/B2/O0) | Special1(M0/P0/B1/O1),LeftArm(Unknown) | RightArm(Unknown) | CenterTorso(Unknown) | Special1(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
Cyclops,Yes,IS,19.000000,90.000000,FerroFiberus,Standard,16,Single,0,No,Yes,Yes,Yes,45,BAP,1.4,1.4,1.4,1.4,1.55,1.55,1.45,0.8,0.25,11.2,8,"3x MediumPulseLaser, 2x MediumLaser, GaussRifle, SRM4, LRM10",MediumPulseLaser@LeftArm(Front) G1 | MediumPulseLaser@Special1(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | MediumLaser@LeftArm(Front) G1 | MediumLaser@RightArm(Front) G1 | GaussRifle@RightTorso(Front) G1 | SRM4@CenterTorso(Front) G2 | LRM10@LeftTorso(Side) G2,LeftArmx2 | Special1x1 | RightArmx2 | RightTorsox1 | CenterTorsox1 | LeftTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Side) | RightTorso(Front) | CenterTorso(Front) | Head(Unknown) | Special1(Front),
|
||||
Daishi,Yes,Clan,25.000000,100.000000,Standard,Standard,21,Single,0,No,Yes,Yes,Yes,43,,1.75,1.75,1.9,1.9,2.0,2.0,2.2,1.5,0.3,15.3,6,"3x ClanLargePulseLaser, ClanGaussRifle, 2x ClanSSRM6",ClanLargePulseLaser@RightArm(Front) G1 | ClanLargePulseLaser@RightArm(Front) G1 | ClanLargePulseLaser@RightArm(Front) G1 | ClanGaussRifle@LeftArm(Front) G1 | ClanSSRM6@special1(Front) G2 | ClanSSRM6@special1(Front) G2,RightArmx3 | LeftArmx1 | special1x2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O8) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown) | Head(Unknown) | Special1(Unknown),
|
||||
Deimos,Yes,Clan,18.000000,85.000000,Reactive,EndoSteel,17,Single,0,No,Yes,Yes,Yes,43,,1.55,1.55,1.65,1.65,1.75,1.75,2.05,0.7,0.3,12.95,10,"2x ClanERMediumLaser, 6x ClanUltraAC2, 2x ClanLRM15",ClanERMediumLaser@LeftTorso(Front) G1 | ClanERMediumLaser@RightTorso(Front) G1 | ClanUltraAC2@LeftArm(Front) G1 | ClanUltraAC2@LeftArm(Front) G1 | ClanUltraAC2@LeftArm(Front) G1 | ClanUltraAC2@RightArm(Front) G1 | ClanUltraAC2@RightArm(Front) G1 | ClanUltraAC2@RightArm(Front) G1 | ClanLRM15@Special1(Side) G2 | ClanLRM15@Special2(Side) G2,LeftTorsox1 | RightTorsox1 | LeftArmx3 | RightArmx3 | Special1x1 | Special2x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O9) | RightTorso(M0/P0/B0/O9) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O3) | Special2(M0/P0/B0/O3),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown) | Special1(Side) | Special2(Side),
|
||||
Dragon,Yes,Clan,17.000000,60.000000,Standard,Standard,13,Single,0,Yes,Yes,Yes,Yes,43,,1.15,1.15,1.4,1.4,1.25,1.25,1.55,0.9,0.3,10.35,5,"3x MediumLaser, ERPPC, LRM10",MediumLaser@LeftArm(Front) G1 | MediumLaser@LeftTorso(Front) G1 | MediumLaser@RightTorso(Front) G1 | ERPPC@RightArm(Front) G1 | LRM10@CenterTorso(Side) G2,LeftArmx1 | LeftTorsox1 | RightTorsox1 | RightArmx1 | CenterTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Side) | Head(Unknown),
|
||||
Duangung,No,IS,7.000000,25.000000,FerroFiberus,Standard,0,,0,Yes,No,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B2/O0) | RightArm(M0/P0/B2/O0) | CenterTorso(M2/P0/B0/O0) | Special1(M0/P0/B1/O0) | Special2(M0/P0/B1/O0),LeftArm(Unknown) | RightArm(Unknown) | CenterTorso(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
Fafnir,Yes,IS,21.000000,100.000000,FerroFiberus,Standard,7,Single,0,No,Yes,No,No,43,,1.8,1.8,1.9,1.9,2.0,2.0,2.2,1.0,0.3,14.9,7,"2x ClanGaussRifle, 2x LargeLaser, 3x MediumLaser",ClanGaussRifle@RightTorso(Front) G1 | ClanGaussRifle@LeftTorso(Front) G1 | LargeLaser@RightArm(Front) G1 | LargeLaser@LeftArm(Front) G1 | MediumLaser@RightTorso(Front) G1 | MediumLaser@CenterTorso(Front) G1 | MediumLaser@LeftTorso(Front) G1,RightTorsox2 | LeftTorsox2 | RightArmx1 | LeftArmx1 | CenterTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Front) | Head(Unknown),
|
||||
Flea,Yes,IS,7.000000,20.000000,Standard,Standard,2,Single,0,No,Yes,Yes,Yes,43,,0.4,0.4,0.4,0.4,0.5,0.5,0.65,0.3,0.3,3.85,6,"2x SmallLaser, 2x MediumLaser, 2x MachineGun",SmallLaser@LeftTorso(Rear) G1 | SmallLaser@RightTorso(Rear) G1 | MediumLaser@LeftArm(Front) G1 | MediumLaser@RightArm(Front) G1 | MachineGun@LeftArm(Front) G1 | MachineGun@RightArm(Front) G1,LeftTorsox1 | RightTorsox1 | LeftArmx2 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Rear) | RightTorso(Rear) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Gargoyle,No,Clan,15.000000,80.000000,FerroFiberus,EndoSteel,0,,0,No,Yes,No,No,6,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M1/P0/B0/O3) | RightArm(M1/P0/B0/O3) | LeftTorso(M0/P2/B2/O0) | RightTorso(M0/P2/B2/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
Gesu,No,Clan,9.750000,45.000000,FerroFiberus,EndoSteel,0,,0,No,No,Yes,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P2/B0/O0) | RightArm(M0/P2/B0/O0) | LeftTorso(M0/P0/B2/O0) | RightTorso(M0/P0/B2/O0) | Special1(M2/P0/B0/O0) | Special2(M2/P0/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
Gladiator,Yes,Clan,24.000000,95.000000,FerroFiberus,Standard,19,Single,1,Yes,Yes,Yes,Yes,43,,1.4,1.4,1.65,1.65,1.75,1.75,2.0,0.95,0.25,12.8,12,"5x ClanSmallPulseLaser, ClanERSmallLaser, 3x ClanMediumPulseLaser, ClanLargePulseLaser, 2x SRM6",ClanSmallPulseLaser@RightTorso(Front) G1 | ClanSmallPulseLaser@RightTorso(Front) G1 | ClanSmallPulseLaser@RightArm(Front) G1 | ClanSmallPulseLaser@RightArm(Front) G1 | ClanSmallPulseLaser@RightArm(Front) G1 | ClanERSmallLaser@LeftTorso(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanLargePulseLaser@LeftArm(Front) G1 | SRM6@LeftArm(Front) G2 | SRM6@LeftArm(Front) G2,RightTorsox2 | RightArmx6 | LeftTorsox1 | LeftArmx3,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Grizzly,Yes,Clan,16.000000,70.000000,FerroFiberus,Standard,11,Single,1,Yes,Yes,Yes,Yes,40,,1.2,1.2,1.1,1.1,1.4,1.4,1.5,0.5,0.25,9.65,6,"2x ClanSmallPulseLaser, ClanMediumPulseLaser, ClanLargePulseLaser, ClanGaussRifle, CLANLRM10",ClanSmallPulseLaser@LeftArm(Front) G1 | ClanSmallPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@RightTorso(Front) G1 | ClanLargePulseLaser@LeftArm(Front) G1 | ClanGaussRifle@RightArm(Front) G1 | CLANLRM10@LeftTorso(Side) G2,LeftArmx3 | RightTorsox1 | RightArmx1 | LeftTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12),LeftArm(Front) | RightArm(Front) | LeftTorso(Side) | RightTorso(Front),
|
||||
Hauptmann,Yes,Clan,21.000000,95.000000,Standard,Standard,20,Single,0,Yes,Yes,Yes,Yes,43,ECM,1.7,1.7,1.8,1.8,1.9,1.9,2.1,1.1,0.3,14.3,8,"ClanERSmallLaser, 2x ClanMediumPulseLaser, 2x ClanLargePulseLaser, ClanUltraAC20, 2x ClanSSRM2",ClanERSmallLaser@Head(Front) G1 | ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanLargePulseLaser@LeftArm(Front) G1 | ClanLargePulseLaser@RightArm(Front) G1 | ClanUltraAC20@Special1(Front) G1 | ClanSSRM2@LeftTorso(Front) G2 | ClanSSRM2@RightTorso(Front) G2,Headx1 | LeftArmx2 | RightArmx2 | Special1x1 | LeftTorsox1 | RightTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O8) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Front) | Special1(Front),
|
||||
Hellhound,Yes,Clan,10.500000,50.000000,FerroFiberus,EndoSteel,12,Single,1,Yes,Yes,Yes,Yes,43,,0.9,0.9,0.95,0.95,1.05,1.05,1.2,0.55,0.25,7.8,6,"3x ClanMediumPulseLaser, ClanUltraAC2, ClanUltraAC5, ClanLRM10",ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanUltraAC2@RightTorso(Front) G1 | ClanUltraAC5@RightTorso(Front) G1 | ClanLRM10@LeftTorso(Side) G2,LeftArmx2 | RightArmx1 | RightTorsox2 | LeftTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Side) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Hellspawn,Yes,IS,10.000000,45.000000,Standard,Standard,9,Single,1,Yes,Yes,Yes,Yes,43,ECM,0.5,0.5,0.8,0.8,0.85,0.85,1.15,0.5,0.3,6.25,6,"2x MediumPulseLaser, LargePulseLaser, 2x SSRM2, LRM10",MediumPulseLaser@LeftArm(Front) G1 | MediumPulseLaser@LeftArm(Front) G1 | LargePulseLaser@LeftArm(Front) G1 | SSRM2@RightArm(Front) G2 | SSRM2@Special1(Front) G2 | LRM10@LeftTorso(Front) G2,LeftArmx3 | RightArmx1 | Special1x1 | LeftTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O8) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Unknown) | CenterTorso(Unknown) | Head(Unknown) | Special1(Front),
|
||||
Highlander,Yes,IS,21.500000,90.000000,Standard,Standard,17,Single,1,Yes,Yes,Yes,Yes,43,,1.75,1.45,1.7,1.7,1.8,1.8,2.0,0.85,0.3,13.35,7,"4x MediumPulseLaser, GaussRifle, 2x SRM6",MediumPulseLaser@RightTorso(Front) G1 | MediumPulseLaser@RightTorso(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | GaussRifle@LeftArm(Front) G1 | SRM6@LeftTorso(Front) G2 | SRM6@LeftTorso(Front) G2,RightTorsox2 | RightArmx2 | LeftArmx1 | LeftTorsox2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Hollander,Yes,IS,10.000000,45.000000,FerroFiberus,EndoSteel,12,Single,0,No,Yes,Yes,Yes,42,,0.85,0.85,0.85,0.85,0.9,0.9,1.05,0.45,0.25,6.95,6,"2x SmallPulseLaser, 3x MediumPulseLaser, GaussRifle",SmallPulseLaser@Special2(Front) G1 | SmallPulseLaser@Special2(Front) G1 | MediumPulseLaser@LeftArm(Front) G1 | MediumPulseLaser@LeftTorso(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | GaussRifle@Special1(Front) G1,Special2x2 | LeftArmx1 | LeftTorsox1 | RightArmx1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | Special1(M0/P0/B0/O12) | Special2(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | Special1(Front) | Special2(Front),
|
||||
Hunchback,Yes,IS,13.500000,50.000000,Standard,Standard,10,Single,0,Yes,Yes,Yes,Yes,43,ECM,1.0,1.0,1.1,1.1,1.2,1.2,1.5,0.5,0.3,8.9,6,"SmallLaser, 4x MediumLaser, AC10",SmallLaser@Head(Front) G1 | MediumLaser@LeftArm(Front) G1 | MediumLaser@LeftArm(Front) G1 | MediumLaser@RightArm(Front) G1 | MediumLaser@RightArm(Front) G1 | AC10@Special1(Front) G1,Headx1 | LeftArmx2 | RightArmx2 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O8) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown) | Head(Front) | Special1(Front),
|
||||
Kodiak,Yes,IS,22.000000,100.000000,Standard,EndoSteel,20,Single,1,Yes,Yes,Yes,Yes,43,,1.5,1.5,1.9,1.9,1.5,1.5,2,1.1,0.3,13.2,7,"4x ClanERMediumLaser, ClanUltraAC20, 2x ClanSSRM6",ClanERMediumLaser@leftArm(Front) G1 | ClanERMediumLaser@leftArm(Front) G1 | ClanERMediumLaser@rightarm(Front) G1 | ClanERMediumLaser@rightarm(Front) G1 | ClanUltraAC20@RightTorso(Front) G1 | ClanSSRM6@LeftTorso(Front) G2 | ClanSSRM6@LeftTorso(Front) G2,leftArmx2 | rightarmx2 | RightTorsox1 | LeftTorsox2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Loki,Yes,Clan,17.500000,65.000000,Standard,Standard,13,Single,0,No,Yes,Yes,Yes,43,ECM,1.3,1.3,1.4,1.4,1.5,1.5,1.55,0.6,0.3,10.85,7,"2x ClanERMediumLaser, 2x ClanMachineGun, 2x ClanUltraAC5, ClanSSRM6",ClanERMediumLaser@LeftArm(Front) G1 | ClanERMediumLaser@RightArm(Front) G1 | ClanMachineGun@LeftTorso(Front) G1 | ClanMachineGun@RightTorso(Front) G1 | ClanUltraAC5@LeftArm(Front) G1 | ClanUltraAC5@RightArm(Front) G1 | ClanSSRM6@Special1(Front) G2,LeftArmx2 | RightArmx2 | LeftTorsox1 | RightTorsox1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O10) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown) | Special1(Front),
|
||||
Longbow,Yes,IS,20.500000,85.000000,Standard,Standard,11,Single,0,No,Yes,Yes,Yes,43,,1.6,1.6,1.65,1.65,1.2,1.2,1.85,1.0,0.3,12.05,6,"2x MediumLaser, 2x LRM5, 2x LRM20",MediumLaser@LeftTorso(Front) G1 | MediumLaser@RightTorso(Front) G1 | LRM5@LeftTorso(Front) G2 | LRM5@RightTorso(Front) G2 | LRM20@LeftArm(Front) G2 | LRM20@RightArm(Front) G2,LeftTorsox2 | RightTorsox2 | LeftArmx1 | RightArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
MadCat_MkII,Yes,Clan,18.500000,90.000000,Reflective,EndoSteel,17,Single,1,Yes,Yes,Yes,Yes,43,,1.8,1.8,1.8,1.8,1.85,1.85,2.0,0.8,0.3,14,12,"4x ClanERSmallLaser, 2x ClanMachineGun, 4x ClanUltraAC5, 2x ClanLRM15",ClanERSmallLaser@LeftTorso(Front) G1 | ClanERSmallLaser@CenterTorso(Front) G1 | ClanERSmallLaser@CenterTorso(Front) G1 | ClanERSmallLaser@RightTorso(Front) G1 | ClanMachineGun@LeftTorso(Front) G1 | ClanMachineGun@RightTorso(Front) G1 | ClanUltraAC5@LeftArm(Front) G1 | ClanUltraAC5@LeftArm(Front) G1 | ClanUltraAC5@RightArm(Front) G1 | ClanUltraAC5@RightArm(Front) G1 | ClanLRM15@Special2(Side) G2 | ClanLRM15@Special1(Side) G2,LeftTorsox2 | CenterTorsox2 | RightTorsox2 | LeftArmx2 | RightArmx2 | Special2x1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O8) | RightTorso(M0/P0/B0/O8) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4) | Special2(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Front) | Head(Unknown) | Special1(Side) | Special2(Side),
|
||||
Madcat,Yes,Clan,16.500000,75.000000,FerroFiberus,EndoSteel,17,Single,0,Yes,Yes,Yes,Yes,43,,1.1,1.1,1.2,1.2,1.4,1.4,1.5,0.5,0.25,9.65,8,"2x ClanMediumPulseLaser, 2x ClanERLargeLaser, 2x ClanMachineGun, 2x ClanLRM10",ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanERLargeLaser@LeftArm(Front) G1 | ClanERLargeLaser@RightArm(Front) G1 | ClanMachineGun@LeftTorso(Front) G1 | ClanMachineGun@RightTorso(Front) G1 | ClanLRM10@Special1(Side) G2 | ClanLRM10@Special2(Side) G2,LeftArmx2 | RightArmx2 | LeftTorsox1 | RightTorsox1 | Special1x1 | Special2x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O9) | RightTorso(M0/P0/B0/O9) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O3) | Special2(M0/P0/B0/O3),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown) | Special1(Side) | Special2(Side),
|
||||
Masakari,Yes,Clan,18.000000,85.000000,FerroFiberus,Standard,15,Single,0,Yes,Yes,Yes,Yes,43,,1.25,1.25,1.4,1.4,1.45,1.45,1.8,0.85,0.25,11.1,7,"2x ClanERMediumLaser, 2x ClanUltraAC2, ClanGaussRifle, 2x ClanLRM10",ClanERMediumLaser@RightTorso(Front) G1 | ClanERMediumLaser@RightTorso(Front) G1 | ClanUltraAC2@RightArm(Front) G1 | ClanUltraAC2@RightArm(Front) G1 | ClanGaussRifle@LeftArm(Front) G1 | ClanLRM10@LeftTorso(Side) G2 | ClanLRM10@LeftTorso(Side) G2,RightTorsox2 | RightArmx2 | LeftArmx1 | LeftTorsox2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Side) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Mauler,Yes,IS,26.000000,90.000000,FerroFiberus,Standard,11,Single,0,No,Yes,Yes,Yes,43,,1.4,1.4,1.4,1.4,1.55,1.55,1.45,0.8,0.25,11.2,10,"2x GaussRifle, 2x SSRM4, 6x LRM5",GaussRifle@LeftArm(Front) G1 | GaussRifle@RightArm(Front) G1 | SSRM4@LeftTorso(Front) G2 | SSRM4@RightTorso(Front) G2 | LRM5@LeftTorso(Side) G2 | LRM5@LeftTorso(Side) G2 | LRM5@LeftTorso(Side) G2 | LRM5@RightTorso(Side) G2 | LRM5@RightTorso(Side) G2 | LRM5@RightTorso(Side) G2,LeftArmx1 | RightArmx1 | LeftTorsox4 | RightTorsox4,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front+Side) | RightTorso(Front+Side) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Novacat,Yes,Clan,16.000000,70.000000,Reactive,EndoSteel,17,Single,1,Yes,Yes,Yes,Yes,43,ECM,1.55,1.55,1.45,1.45,1.5,1.5,1.7,0.75,0.3,11.75,7,"5x ClanMediumPulseLaser, 2x ClanERLargeLaser",ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@LeftTorso(Front) G1 | ClanMediumPulseLaser@RightTorso(Front) G1 | ClanERLargeLaser@RightArm(Front) G1 | ClanERLargeLaser@RightArm(Front) G1,LeftArmx3 | LeftTorsox1 | RightTorsox1 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Osiris,Yes,IS,9.500000,30.000000,FerroFiberus,EndoSteel,11,Single,1,Yes,Yes,Yes,Yes,43,,0.6,0.6,0.6,0.6,0.65,0.65,0.75,0.3,0.25,5,5,"SmallPulseLaser, 2x MediumPulseLaser, SSRM2, NarcBeacon",SmallPulseLaser@special2(Front) G1 | MediumPulseLaser@special1(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | SSRM2@LeftArm(Front) G2 | NarcBeacon@LeftArm(Front) G3,special2x1 | special1x1 | RightArmx1 | LeftArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O1) | Special2(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | Head(Unknown) | Special1(Unknown) | Special2(Unknown),
|
||||
Owens,Yes,IS,9.750000,35.000000,Standard,Standard,5,Single,0,No,Yes,Yes,Yes,39,ECM,0.9,0.9,0.8,0.8,0.8,0.8,1.05,0.35,0.3,6.7,5,"2x SmallLaser, MediumLaser, 2x SRM6",SmallLaser@CenterTorso(Front) G1 | SmallLaser@CenterTorso(Front) G1 | MediumLaser@Head(Front) G1 | SRM6@LeftArm(Front) G2 | SRM6@RightArm(Front) G2,CenterTorsox2 | Headx1 | LeftArmx1 | RightArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O8) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Front) | Head(Front),
|
||||
Puma,Yes,Clan,7.500000,35.000000,FerroFiberus,EndoSteel,10,Single,1,Yes,Yes,Yes,Yes,43,,0.8,0.8,0.6,0.6,0.6,0.6,0.85,0.45,0.25,5.55,4,"2x ClanSmallPulseLaser, 2x ClanLRM20",ClanSmallPulseLaser@LeftTorso(Front) G1 | ClanSmallPulseLaser@RightTorso(Front) G1 | ClanLRM20@LeftArm(Front) G2 | ClanLRM20@RightArm(Front) G2,LeftTorsox1 | RightTorsox1 | LeftArmx1 | RightArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Raven,Yes,IS,10.250000,35.000000,FerroFiberus,Standard,7,Single,0,No,Yes,Yes,Yes,43,"BAP, ECM",0.6,0.65,0.65,0.65,0.7,0.7,0.75,0.25,0.25,5.2,5,"2x MediumLaser, SRM6, LRM5, NarcBeacon",MediumLaser@RightArm(Front) G1 | MediumLaser@RightArm(Front) G1 | SRM6@RightTorso(Front) G2 | LRM5@RightTorso(Side) G2 | NarcBeacon@LeftArm(Front) G3,RightArmx2 | RightTorsox2 | LeftArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Front+Side) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Rifleman,Yes,IS,12.500000,60.000000,FerroFiberus,EndoSteel,17,Single,0,Yes,Yes,Yes,Yes,43,,0.9,0.9,1.0,1.0,1.5,1.5,1.3,0.7,0.25,9.05,6,"2x MediumLaser, 2x LargeLaser, 2x PPC",MediumLaser@Special1(Front) G1 | MediumLaser@Special1(Front) G1 | LargeLaser@LeftArm(Front) G1 | LargeLaser@RightArm(Front) G1 | PPC@LeftArm(Front) G1 | PPC@RightArm(Front) G1,Special1x2 | LeftArmx2 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | Head(Unknown) | Special1(Front),
|
||||
Ryoken,Yes,IS,12.500000,55.000000,FerroFiberus,EndoSteel,10,Single,1,Yes,Yes,Yes,Yes,43,ECM,0.9,0.9,1.0,1.0,1.05,1.05,1.15,0.75,0.25,8.05,6,"4x ClanMediumPulseLaser, 2x ClanSSRM6",ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@LeftArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanSSRM6@LeftTorso(Front) G2 | ClanSSRM6@RightTorso(Front) G2,LeftArmx2 | RightArmx2 | LeftTorsox1 | RightTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Shadowcat,Yes,Clan,9.750000,45.000000,FerroFiberus,EndoSteel,10,Single,1,Yes,Yes,Yes,Yes,43,BAP,0.85,0.85,0.85,0.85,0.9,0.9,1.05,0.45,0.25,6.95,5,"2x ClanMediumPulseLaser, ClanGaussRifle, 2x ClanSSRM4",ClanMediumPulseLaser@RightTorso(Front) G1 | ClanMediumPulseLaser@RightArm(Front) G1 | ClanGaussRifle@LeftArm(Front) G1 | ClanSSRM4@LeftTorso(Front) G2 | ClanSSRM4@RightTorso(Front) G2,RightTorsox2 | RightArmx1 | LeftArmx1 | LeftTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Solitaire,Yes,Clan,7.000000,25.000000,FerroFiberus,EndoSteel,10,Single,0,Yes,Yes,Yes,Yes,46,,0.6,0.6,0.6,0.6,0.55,0.55,0.8,0.4,0.25,4.95,4,"ClanERSmallLaser, 2x ClanERMediumLaser, ClanERLargeLaser",ClanERSmallLaser@LeftTorso(Front) G1 | ClanERMediumLaser@LeftTorso(Front) G1 | ClanERMediumLaser@CenterTorso(Front) G1 | ClanERLargeLaser@Special1(Front) G1,LeftTorsox2 | CenterTorsox1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O3),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Front) | RightTorso(Unknown) | CenterTorso(Front) | Head(Unknown) | Special1(Front),
|
||||
Sunder,Yes,IS,17.500000,90.000000,Standard,Standard,17,Single,0,Yes,Yes,Yes,Yes,43,,1.35,1.35,1.55,1.55,1.65,1.65,2.0,1.0,0.3,12.4,10,"6x MediumLaser, PPC, 2x MachineGun, SRM6",MediumLaser@LeftTorso(Front) G1 | MediumLaser@LeftTorso(Front) G1 | MediumLaser@LeftTorso(Rear) G1 | MediumLaser@RightTorso(Rear) G1 | MediumLaser@RightTorso(Front) G1 | MediumLaser@RightTorso(Front) G1 | PPC@LeftArm(Front) G1 | MachineGun@RightArm(Front) G1 | MachineGun@RightArm(Front) G1 | SRM6@CenterTorso(Front) G2,LeftTorsox3 | RightTorsox3 | LeftArmx1 | RightArmx2 | CenterTorsox1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front+Rear) | RightTorso(Front+Rear) | CenterTorso(Front) | Head(Unknown),
|
||||
Templar,Yes,IS,20.500000,85.000000,Standard,EndoSteel,25,Single,1,Yes,Yes,Yes,Yes,43,,1.45,1.45,1.6,1.6,1.8,1.8,2.05,0.95,0.3,13,11,"6x MediumPulseLaser, PPC, 2x MachineGun, AC20, SRM4",MediumPulseLaser@LeftArm(Front) G1 | MediumPulseLaser@LeftTorso(Front) G1 | MediumPulseLaser@RightTorso(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | MediumPulseLaser@LeftTorso(Rear) G1 | MediumPulseLaser@RightTorso(Rear) G1 | PPC@LeftArm(Front) G1 | MachineGun@LeftTorso(Front) G1 | MachineGun@RightTorso(Front) G1 | AC20@RightArm(Front) G1 | SRM4@RightTorso(Front) G2,LeftArmx2 | LeftTorsox3 | RightTorsox4 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front+Rear) | RightTorso(Front+Rear) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Thanatos,Yes,IS,18.000000,75.000000,FerroFiberus,EndoSteel,20,Single,1,Yes,Yes,Yes,Yes,43,,0.9,0.9,1.3,1.3,1.2,1.2,1.6,0.85,0.25,9.5,7,"MediumPulseLaser, 2x MediumLaser, 2x LargePulseLaser, 2x LRM10",MediumPulseLaser@LeftTorso(Front) G1 | MediumLaser@LeftArm(Front) G1 | MediumLaser@RightTorso(Front) G1 | LargePulseLaser@LeftArm(Front) G1 | LargePulseLaser@RightTorso(Front) G1 | LRM10@RightArm(Front) G2 | LRM10@RightArm(Front) G2,LeftTorsox1 | LeftArmx2 | RightTorsox2 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Thor,Yes,Clan,19.000000,70.000000,FerroFiberus,Standard,20,Single,1,Yes,Yes,Yes,Yes,43,,1.1,1.1,1.2,1.2,1.4,1.4,1.5,0.5,0.25,9.65,7,"2x ClanMediumPulseLaser, ClanERPPC, 2x ClanMachineGun, ClanUltraAC10, CLANLRM10",ClanMediumPulseLaser@LeftTorso(Front) G1 | ClanMediumPulseLaser@RightTorso(Front) G1 | ClanERPPC@RightArm(Front) G1 | ClanMachineGun@LeftTorso(Front) G1 | ClanMachineGun@RightTorso(Front) G1 | ClanUltraAC10@LeftArm(Front) G1 | CLANLRM10@Special1(Side) G2,LeftTorsox2 | RightTorsox2 | RightArmx1 | LeftArmx1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O10) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown) | Special1(Side),
|
||||
Uller,Yes,Clan,8.000000,30.000000,FerroFiberus,EndoSteel,8,Single,0,Yes,Yes,Yes,Yes,43,ECM,0.45,0.45,0.5,0.5,0.6,0.6,0.65,0.45,0.25,4.45,4,"ClanERSmallLaser, ClanERMediumLaser, ClanUltraAC5, ClanSRM6",ClanERSmallLaser@LeftArm(Front) G1 | ClanERMediumLaser@RightArm(Front) G1 | ClanUltraAC5@RightArm(Front) G1 | ClanSRM6@LeftArm(Front) G2,LeftArmx2 | RightArmx2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Uziel,Yes,IS,11.500000,50.000000,Standard,EndoSteel,10,Single,1,Yes,Yes,Yes,Yes,45,,1.2,1.2,1.05,1.05,1.15,1.15,1.0,0.45,0.3,8.55,7,"2x SmallPulseLaser, PPC, 2x MachineGun, UltraAC5, LRM10",SmallPulseLaser@LeftTorso(Front) G1 | SmallPulseLaser@RightTorso(Front) G1 | PPC@LeftArm(Front) G1 | MachineGun@LeftTorso(Front) G1 | MachineGun@RightTorso(Front) G1 | UltraAC5@RightArm(Front) G1 | LRM10@Special1(Side) G2,LeftTorsox2 | RightTorsox2 | LeftArmx1 | RightArmx1 | Special1x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O4),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | Head(Unknown) | Special1(Side),
|
||||
Victor,Yes,IS,17.000000,80.000000,Standard,EndoSteel,10,Single,1,Yes,Yes,Yes,Yes,43,ECM,1.3,1.3,1.3,1.3,1.25,1.25,1.65,1.1,0.3,10.75,7,"2x MediumLaser, 2x MachineGun, AC20, 2x SRM4",MediumLaser@LeftArm(Front) G1 | MediumLaser@LeftArm(Front) G1 | MachineGun@LeftTorso(Front) G1 | MachineGun@RightTorso(Front) G1 | AC20@RightArm(Front) G1 | SRM4@LeftTorso(Front) G2 | SRM4@RightTorso(Front) G2,LeftArmx2 | LeftTorsox2 | RightTorsox2 | RightArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Unknown) | Head(Unknown),
|
||||
Vulture,Yes,Clan,16.000000,60.000000,Reactive,EndoSteel,12,Single,0,No,Yes,Yes,Yes,43,BAP,1.3,1.3,1.5,1.5,1.6,1.6,1.75,0.5,0.3,11.35,10,"4x ClanMachineGun, 2x ClanLargePulseLaser, 2x ClanLRM5, 2x ClanLRM10",ClanMachineGun@LeftArm(Front) G1 | ClanMachineGun@Special1(Front) G1 | ClanMachineGun@Special1(Front) G1 | ClanMachineGun@RightArm(Front) G1 | ClanLargePulseLaser@LeftArm(Front) G1 | ClanLargePulseLaser@RightArm(Front) G1 | ClanLRM5@LeftTorso(Side) G2 | ClanLRM5@RightTorso(Side) G2 | ClanLRM10@LeftTorso(Side) G2 | ClanLRM10@RightTorso(Side) G2,LeftArmx2 | Special1x2 | RightArmx2 | LeftTorsox2 | RightTorsox2,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Head(M0/P0/B0/O1) | Special1(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Side) | RightTorso(Side) | Head(Unknown) | Special1(Front),
|
||||
Warhammer,Yes,IS,15.000000,70.000000,Standard,Standard,17,Single,0,Yes,Yes,Yes,Yes,43,,1.55,1.55,1.45,1.45,1.5,1.5,1.7,0.75,0.3,11.75,5,"2x MediumLaser, 2x ERPPC, SRM6",MediumLaser@RightTorso(Front) G1 | MediumLaser@LeftTorso(Front) G1 | ERPPC@RightArm(Front) G1 | ERPPC@LeftArm(Front) G1 | SRM6@special2(Front) G2,RightTorsox1 | LeftTorsox1 | RightArmx1 | LeftArmx1 | special2x1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | Special2(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | Special2(Unknown),
|
||||
Wolfhound,Yes,Clan,10.250000,35.000000,FerroFiberus,EndoSteel,14,Single,0,Yes,Yes,Yes,Yes,43,ECM,0.5,0.5,0.7,0.7,0.75,0.75,0.95,0.5,0.25,5.6,5,"3x ClanMediumPulseLaser, ClanERMediumLaser, ClanERLargeLaser",ClanMediumPulseLaser@LeftTorso(Front) G1 | ClanMediumPulseLaser@CenterTorso(Front) G1 | ClanMediumPulseLaser@RightTorso(Front) G1 | ClanERMediumLaser@CenterTorso(Rear) G1 | ClanERLargeLaser@RightArm(Front) G1,LeftTorsox1 | CenterTorsox2 | RightTorsox1 | RightArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Unknown) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front) | CenterTorso(Front+Rear) | Head(Unknown),
|
||||
Zeus,Yes,IS,22.000000,80.000000,FerroFiberus,Standard,22,Single,0,Yes,Yes,Yes,Yes,43,,1.1,1.1,1.25,1.25,1.45,1.45,1.55,0.8,0.25,10.2,7,"4x MediumPulseLaser, ERLargeLaser, ERPPC, LRM15",MediumPulseLaser@LeftTorso(Front) G1 | MediumPulseLaser@RightTorso(Front) G1 | MediumPulseLaser@RightArm(Front) G1 | MediumPulseLaser@RightTorso(Rear) G1 | ERLargeLaser@CenterTorso(Front) G1 | ERPPC@LeftArm(Front) G1 | LRM15@RightArm(Front) G2,LeftTorsox1 | RightTorsox2 | RightArmx2 | CenterTorsox1 | LeftArmx1,LeftArm(M0/P0/B0/O8) | RightArm(M0/P0/B0/O8) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2) | Head(M0/P0/B0/O1),LeftArm(Front) | RightArm(Front) | LeftTorso(Front) | RightTorso(Front+Rear) | CenterTorso(Front) | Head(Unknown),
|
||||
jenner2c,No,Clan,10.000000,35.000000,FerroFiberus,Standard,0,,0,Yes,Yes,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M2/P0/B2/O0) | RightArm(M2/P0/B2/O0) | Special1(M3/P0/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | Special1(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
koto,No,IS,7.000000,25.000000,FerroFiberus,EndoSteel,0,,0,No,Yes,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P1/B1/O0) | RightArm(M0/P1/B1/O0) | CenterTorso(M0/P0/B2/O0) | Special1(M0/P0/B3/O0),LeftArm(Unknown) | RightArm(Unknown) | CenterTorso(Unknown) | Special1(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
locust2c,No,Clan,7.000000,25.000000,FerroFiberus,EndoSteel,0,,0,No,Yes,No,No,4,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B1/O2) | RightArm(M0/P0/B1/O2) | Special1(M0/P0/B3/O0),LeftArm(Unknown) | RightArm(Unknown) | Special1(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
marauder2,No,IS,22.000000,100.000000,FerroFiberus,EndoSteel,0,,0,Yes,No,Yes,No,6,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B4/O1) | RightArm(M0/P0/B4/O1) | LeftTorso(M0/P0/B1/O1) | RightTorso(M0/P0/B1/O1) | Special1(M0/P7/B0/O0) | Special2(M0/P0/B0/O2),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
pitbull,No,Clan,15.000000,70.000000,FerroFiberus,EndoSteel,0,,0,Yes,No,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P2/B2/O0) | RightArm(M0/P2/B2/O0) | LeftTorso(M0/P0/B2/O0) | RightTorso(M0/P0/B2/O0) | Special1(M0/P4/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | Special1(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
privateer,No,IS,12.500000,55.000000,FerroFiberus,Standard,0,,0,No,No,Yes,No,2,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P1/B0/O1) | RightArm(M0/P1/B0/O1) | LeftTorso(M0/P2/B2/O0) | RightTorso(M0/P0/B1/O0) | Special1(M4/P0/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | Special1(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
razorback,No,IS,9.000000,30.000000,FerroFiberus,EndoSteel,0,,0,No,Yes,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M2/P0/B2/O0) | RightArm(M0/P0/B3/O0) | Special1(M0/P2/B0/O0) | Special2(M0/P2/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
reaper,No,Clan,16.500000,75.000000,FerroFiberus,EndoSteel,0,,0,Yes,Yes,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B3/O0) | RightArm(M0/P0/B3/O0) | LeftTorso(M0/P0/B2/O0) | RightTorso(M0/P0/B2/O0) | CenterTorso(M0/P6/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
reaver,No,Clan,10.000000,40.000000,FerroFiberus,EndoSteel,0,,0,Yes,No,Yes,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B3/O0) | RightArm(M0/P0/B3/O0) | LeftTorso(M0/P0/B1/O0) | RightTorso(M0/P0/B1/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
shadowhawk,No,IS,12.500000,55.000000,FerroFiberus,Standard,0,,0,Yes,Yes,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P1/B2/O0) | RightArm(M0/P0/B3/O0) | LeftTorso(M0/P0/B1/O0) | RightTorso(M0/P0/B1/O0) | Special1(M0/P2/B0/O0) | Special2(M2/P0/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
strider,No,IS,11.000000,40.000000,FerroFiberus,Standard,0,,0,No,No,Yes,No,4,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M2/P0/B0/O0) | RightArm(M2/P0/B0/O0) | LeftTorso(M0/P0/B0/O2) | RightTorso(M0/P0/B0/O2) | CenterTorso(M0/P0/B2/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
urbanmech,Yes,IS,5.000000,30.000000,Standard,Standard,8,Single,0,Yes,Yes,No,No,50,,0.45,0.45,0.5,0.5,0.6,0.6,0.65,0.45,0.25,4.45,2,"SmallLaser, AC20",SmallLaser@LeftArm(Front) G1 | AC20@RightArm(Front) G1,LeftArmx1 | RightArmx1,LeftArm(M0/P0/B0/O12) | RightArm(M0/P0/B0/O12) | LeftTorso(M0/P0/B0/O12) | RightTorso(M0/P0/B0/O12) | CenterTorso(M0/P0/B0/O2),LeftArm(Front) | RightArm(Front) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown),
|
||||
urbanmech_iic,No,Clan,5.000000,30.000000,FerroFiberus,Standard,0,,0,Yes,Yes,No,No,,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P2/B2/O0) | RightArm(M0/P0/B4/O0) | LeftTorso(M0/P1/B0/O0) | RightTorso(M0/P1/B0/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
ursus,No,Clan,10.500000,50.000000,FerroFiberus,Standard,0,,0,No,Yes,No,No,3,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P0/B0/O3) | RightArm(M0/P0/B4/O0) | CenterTorso(M2/P0/B0/O0) | Special1(M0/P0/B1/O0) | Special2(M0/P0/B1/O0),LeftArm(Unknown) | RightArm(Unknown) | CenterTorso(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
vulture2,No,Clan,16.500000,75.000000,FerroFiberus,EndoSteel,0,,0,No,Yes,No,No,5,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P3/B0/O0) | RightArm(M0/P0/B0/O3) | LeftTorso(M2/P0/B2/O0) | RightTorso(M2/P0/B2/O0) | Special1(M0/P0/B0/O2) | Special2(M0/P0/B2/O0),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
vulturec,No,Clan,14.000000,60.000000,FerroFiberus,Standard,0,,0,No,Yes,No,No,3,,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.1,0.9,0,,,,LeftArm(M0/P3/B0/O0) | RightArm(M0/P3/B0/O0) | LeftTorso(M2/P0/B0/O0) | RightTorso(M2/P0/B0/O0) | CenterTorso(M0/P0/B0/O1) | Special1(M0/P0/B0/O1) | Special2(M0/P0/B0/O1),LeftArm(Unknown) | RightArm(Unknown) | LeftTorso(Unknown) | RightTorso(Unknown) | CenterTorso(Unknown) | Special1(Unknown) | Special2(Unknown),"not registered in active mech tables; missing M_* mech ID defines; core mech files exist; not fully packaged (core.build, props.build, textures.build); missing display/name string IDs (IDS/DNL); no loose hsh bmp in Mechs/MFD/hud"
|
||||
|
@@ -0,0 +1,654 @@
|
||||
# mech_loadouts.csv Catch-Up Notes
|
||||
|
||||
This document is for future AI agents or maintainers who need to understand how [mech_loadouts.csv](mech_loadouts.csv) was built, where each column comes from, and what files must be updated together when mech data changes.
|
||||
|
||||
## Purpose
|
||||
|
||||
`mech_loadouts.csv` is a flattened mech audit sheet built from the FireStorm content tree. It combines:
|
||||
- mech identity and stat data
|
||||
- current in-game playability status
|
||||
- installed/default weapon loadouts
|
||||
- weapon facing and grouping metadata
|
||||
- zone hardpoint capacity
|
||||
- notes about missing registration, packaging, or asset support
|
||||
|
||||
The CSV is not a primary source of truth. It is a synthesized report built from the mech content files and several registration tables.
|
||||
|
||||
## Current CSV Column Layout
|
||||
|
||||
The important derived columns are:
|
||||
- `In_game_playable`
|
||||
- `Weapons_With_Locations`
|
||||
- `Default_Installed_Locations`
|
||||
- `Available_Slot_Capacity_By_Zone`
|
||||
- `Available_Hardpoints`
|
||||
- `notes`
|
||||
|
||||
The existing stat columns before those are mostly direct mech data fields and were not re-derived during the audit.
|
||||
|
||||
## What Each Derived Column Means
|
||||
|
||||
### `In_game_playable`
|
||||
|
||||
`Yes` if the mech is currently in the active playable roster, `No` otherwise.
|
||||
|
||||
This was determined by comparing the mech folder set against the active registration chain:
|
||||
- `Gameleap/code/mw4/Code/MW4/MechLabHeaders.h`
|
||||
- `Gameleap/mw4/Content/ShellScripts/MechLabHeaders.h`
|
||||
- `Gameleap/mw4/Content/Tables/MechChassisTable.tbl`
|
||||
- `Gameleap/mw4/Content/Tables/MechTable.tbl`
|
||||
- `Gameleap/mw4/Content/core.build`
|
||||
- plus supporting string and packaging manifests
|
||||
|
||||
Practical rule:
|
||||
- folder presence alone does not make a mech playable
|
||||
- playable mechs must have the ID/table/build registrations aligned
|
||||
|
||||
### `Weapons_With_Locations`
|
||||
|
||||
This column lists each installed weapon in the mech¡¯s default subsystem file, with:
|
||||
- the weapon name
|
||||
- the `InternalLocation`
|
||||
- the `WeaponFacing`
|
||||
- the weapon group
|
||||
|
||||
Current format:
|
||||
- `WeaponName@Location(Facing) G#`
|
||||
|
||||
Examples:
|
||||
- `MediumPulseLaser@LeftTorso(Rear) G1`
|
||||
- `SRM4@RightTorso(Front) G2`
|
||||
- `ClanLRM10@LeftTorso(Side) G2`
|
||||
|
||||
Derived from the mech¡¯s `.subsystems` file by reading weapon subsystem blocks.
|
||||
|
||||
Important notes:
|
||||
- `WeaponFacing=0` => `Front`
|
||||
- `WeaponFacing=1` => `Rear`
|
||||
- `WeaponFacing=2` => `Side`
|
||||
- if `WeaponFacing` is absent, it defaults to `Front`
|
||||
|
||||
### `Default_Installed_Locations`
|
||||
|
||||
A compact count summary of where the mech¡¯s default weapons are installed, based on `InternalLocation` in the `.subsystems` file.
|
||||
|
||||
Example:
|
||||
- `LeftArmx2 | LeftTorsox3 | RightTorsox4 | RightArmx2`
|
||||
|
||||
This is about installed weapons, not slot capacity.
|
||||
|
||||
### `Available_Slot_Capacity_By_Zone`
|
||||
|
||||
A compact summary of zone capacities from the mech¡¯s `.damage` file.
|
||||
|
||||
Current format:
|
||||
- `Zone(M# / P# / B# / O#)`
|
||||
|
||||
Where:
|
||||
- `M` = MissileSlots
|
||||
- `P` = ProjectileSlots
|
||||
- `B` = BeamSlots
|
||||
- `O` = OmniSlots
|
||||
|
||||
Example:
|
||||
- `LeftTorso(M0/P2/B2/O0)`
|
||||
|
||||
This reflects what the mech can support in that zone, not what is currently installed.
|
||||
|
||||
### `Available_Hardpoints`
|
||||
|
||||
A list of zones that have at least one positive slot count in the `.damage` file.
|
||||
|
||||
Current format:
|
||||
- `LeftArm(Front)`
|
||||
- `LeftTorso(Front+Rear)`
|
||||
- `RightTorso(Side)`
|
||||
|
||||
This column is a directional summary of where weapons can be mounted.
|
||||
|
||||
Important:
|
||||
- this is derived from slot capacity plus facing information from weapon loadouts
|
||||
- it is not a literal mechanical port map
|
||||
- if a zone has multiple facing types in the mech¡¯s default loadout, it can show a combined label such as `Front+Rear` or `Front+Side`
|
||||
|
||||
## Core Data Sources
|
||||
|
||||
### 1. Mech registration and playability
|
||||
|
||||
Primary files:
|
||||
- `Gameleap/code/mw4/Code/MW4/MechLabHeaders.h`
|
||||
- `Gameleap/mw4/Content/ShellScripts/MechLabHeaders.h`
|
||||
- `Gameleap/mw4/Content/Tables/MechChassisTable.tbl`
|
||||
- `Gameleap/mw4/Content/Tables/MechTable.tbl`
|
||||
- `Gameleap/mw4/Content/core.build`
|
||||
|
||||
What they control:
|
||||
- which mechs are actually in the active roster
|
||||
- which IDs exist in code and script space
|
||||
- which mech resources are packed into the runtime build
|
||||
|
||||
If a mech folder exists but it is not listed in these files, it is usually not playable.
|
||||
|
||||
### 2. Default weapon loadout and weapon-facing metadata
|
||||
|
||||
Primary file:
|
||||
- `Gameleap/mw4/Content/Mechs/<MechName>/<mech>.subsystems`
|
||||
|
||||
Each weapon block typically contains:
|
||||
- `Model=` weapon subsystem resource
|
||||
- `InternalLocation=` where the weapon is mounted
|
||||
- `Site=` mount port name
|
||||
- `GroupIndex=` weapon group number
|
||||
- `WeaponFacing=` optional facing metadata
|
||||
- `AmmoCount=` for ammo-using weapons
|
||||
|
||||
The `.subsystems` file is the source for:
|
||||
- `Weapons_With_Locations`
|
||||
- `Default_Installed_Locations`
|
||||
- facing annotations in the hardpoint summaries
|
||||
|
||||
### 3. Slot capacity / hardpoint support
|
||||
|
||||
Primary file:
|
||||
- `Gameleap/mw4/Content/Mechs/<MechName>/<mech>.damage`
|
||||
|
||||
Each section such as `[LeftArmInternal]` or `[RightTorsoInternal]` may contain:
|
||||
- `MissileSlots=`
|
||||
- `ProjectileSlots=`
|
||||
- `BeamSlots=`
|
||||
- `OmniSlots=`
|
||||
|
||||
These are used to derive:
|
||||
- `Available_Slot_Capacity_By_Zone`
|
||||
- `Available_Hardpoints`
|
||||
|
||||
### 4. Weapon slot type rules in code
|
||||
|
||||
Relevant code:
|
||||
- `Gameleap/code/mw4/Code/MW4/MWDamageObject.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/MWDamageObject.hpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/MechLab.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Subsystem_Tool.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon_Tool.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon.hpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/hudweapon.cpp`
|
||||
|
||||
What the code does:
|
||||
- reads slot counts from `.damage`
|
||||
- reads `InternalLocation` and `WeaponFacing` from `.subsystems`
|
||||
- maps weapon slot type and size from the weapon model
|
||||
- assigns weapons to valid locations during mechlab editing
|
||||
|
||||
## Facing Semantics
|
||||
|
||||
Weapon facing is stored per weapon instance, not as a separate hardpoint label.
|
||||
|
||||
Values seen in the data/code:
|
||||
- `0` = front
|
||||
- `1` = rear
|
||||
- `2` = side
|
||||
|
||||
Code references:
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon_Tool.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon.hpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/hudweapon.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/MechLab.cpp`
|
||||
|
||||
Important nuance:
|
||||
- a zone name like `LeftTorso` does not tell you the facing by itself
|
||||
- the facing comes from the weapon block¡¯s `WeaponFacing`
|
||||
- the same zone can contain multiple weapons with different facings
|
||||
|
||||
## Group Index Meaning
|
||||
|
||||
The `G1`, `G2`, etc. suffix in `Weapons_With_Locations` is the weapon group number from `GroupIndex` in the subsystem file.
|
||||
|
||||
This is not a location or facing field.
|
||||
|
||||
Meaning:
|
||||
- `G1` = weapon group 1
|
||||
- `G2` = weapon group 2
|
||||
- and so on
|
||||
|
||||
## How The Spreadsheet Was Built
|
||||
|
||||
The CSV was assembled by cross-referencing:
|
||||
- mech folder contents under `Gameleap/mw4/Content/Mechs/`
|
||||
- `.subsystems` weapon blocks
|
||||
- `.damage` internal zone capacities
|
||||
- active roster tables and IDs
|
||||
- string registration files
|
||||
- build manifests
|
||||
- loose UI art assets under `Gameleap/mw4/hsh/`
|
||||
|
||||
The output is a derived audit sheet, not a direct export from a single source file.
|
||||
|
||||
## Known Pitfalls
|
||||
|
||||
### 1. Folder presence does not mean playable
|
||||
|
||||
Some mech folders exist but are not in the active roster tables or headers. These need ID/table/build integration before they are usable in-game.
|
||||
|
||||
### 2. File names are not always canonical
|
||||
|
||||
Some mechs use alternate base filenames inside their folder. Do not assume `FolderName/FolderName.damage` or `FolderName/FolderName.subsystems` always exist.
|
||||
|
||||
Prefer:
|
||||
- parse the `.instance` file when present
|
||||
- otherwise detect the first matching `.subsystems` / `.damage` file by extension and content
|
||||
|
||||
### 3. `Available_Hardpoints` is a summary, not a literal port map
|
||||
|
||||
It summarizes zones with capacity and facing hints, but it does not enumerate every exact port or site name.
|
||||
|
||||
### 4. Rear-facing weapons are per-instance
|
||||
|
||||
If a mech has one rear-mounted weapon in a torso zone, that does not mean all weapons in that zone are rear-facing.
|
||||
|
||||
## Update Checklist For Future Changes
|
||||
|
||||
If a mech is added or changed, check these in order:
|
||||
1. update or verify the mech `.data`, `.instance`, `.subsystems`, and `.damage` files
|
||||
2. ensure the mech is added to the active ID header(s)
|
||||
3. update `MechChassisTable.tbl` and `MechTable.tbl`
|
||||
4. update `core.build` and any related build manifests
|
||||
5. add any needed string IDs or script references
|
||||
6. confirm the mech has the expected loose or packed art assets
|
||||
7. rebuild the CSV derived columns if the data changed
|
||||
|
||||
## Useful File Map
|
||||
|
||||
### Mech data
|
||||
- `Gameleap/mw4/Content/Mechs/<MechName>/`
|
||||
|
||||
### Roster and IDs
|
||||
- `Gameleap/code/mw4/Code/MW4/MechLabHeaders.h`
|
||||
- `Gameleap/mw4/Content/ShellScripts/MechLabHeaders.h`
|
||||
- `Gameleap/mw4/Content/Tables/MechChassisTable.tbl`
|
||||
- `Gameleap/mw4/Content/Tables/MechTable.tbl`
|
||||
|
||||
### Slot/hardpoint logic
|
||||
- `Gameleap/code/mw4/Code/MW4/MWDamageObject.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/MechLab.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Subsystem_Tool.cpp`
|
||||
|
||||
### Facing logic
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon.hpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/Weapon_Tool.cpp`
|
||||
- `Gameleap/code/mw4/Code/MW4/hudweapon.cpp`
|
||||
|
||||
### Build manifests
|
||||
- `Gameleap/mw4/Content/core.build`
|
||||
- `Gameleap/mw4/Content/props.build`
|
||||
- `Gameleap/mw4/Content/textures.build`
|
||||
|
||||
## Current State Summary
|
||||
|
||||
At the time this doc was written:
|
||||
- `mech_loadouts.csv` includes playability, default loadout, facing, hardpoint, and notes columns
|
||||
- non-playable mechs are explicitly marked `No`
|
||||
- Templar and other mechs with rear or side mounts have facing visible in the CSV
|
||||
- the file is intended to be a living audit artifact for future data cleanup and enablement work
|
||||
|
||||
---
|
||||
|
||||
## MechEditor Web App — Data Sources, Fields, and Conversions (documented 2026-07-23)
|
||||
|
||||
The MechEditor is a single-file Python HTTP server at `/home/rich/Repositories/MechEditor/mech_editor.py`.
|
||||
It runs at `localhost:8765`, parses the firestorm content tree, and presents a full mech configuration editor in the browser.
|
||||
This section documents every data field it reads, every conversion it performs, and every naming rule it enforces.
|
||||
|
||||
---
|
||||
|
||||
### Data Files Parsed Per Mech
|
||||
|
||||
All files live under `Gameleap/mw4/Content/Mechs/<MechDir>/`.
|
||||
|
||||
#### `.data` file (`parse_data()`)
|
||||
|
||||
| Field in file | Editor key | Notes |
|
||||
|---|---|---|
|
||||
| `VehicleTonnage` | `tonnage` | chassis base tonnage (float) |
|
||||
| `MaxVehicleTonnage` | `max_tonnage` | max loadout tonnage (float) |
|
||||
| `TechType` | `tech` | `$(Tech_IS)` ? `"IS"`, `$(Tech_Clan)` ? `"Clan"` |
|
||||
| `MaxHeat` | `max_heat` | heat capacity (int) |
|
||||
| `VehicleTradeValue` | `trade_value` | C-bills |
|
||||
| `DragoonValue` | `dragoon` | used in Power Rating bar scaling |
|
||||
| `MinMaxSpeed` | `min_max_speed` | base speed ceiling in **m/s** |
|
||||
| `MaxSpeed` | `max_speed` | absolute speed ceiling in **m/s** (engine upgrades may not exceed this) |
|
||||
| `FullStopTurnRate` | `full_stop_turn` | turn rate at zero speed, in **degrees/sec** |
|
||||
| `TopSpeedTurnRate` | `top_speed_turn` | turn rate at top speed, in **degrees/sec** |
|
||||
| `Acceleration` | `acceleration` | forward acceleration in **m/s²** |
|
||||
| `Decceleration` | `decceleration` | forward braking in **m/s²** — **double-c spelling is canonical in the engine source** |
|
||||
| `ReverseAccelerationMultiplier` | `rev_accel_mult` | multiplier applied to Acceleration for reverse |
|
||||
| `ReverseDeccelerationMultiplier` | `rev_decel_mult` | multiplier applied to Decceleration for reverse — double-c canonical |
|
||||
| `MinStandTransitionSpeed` | not surfaced | animation threshold only — see note below |
|
||||
| `CanLoadJumpJets` | `can_jj` | Yes/No |
|
||||
| `CanLoadECM` | `can_ecm` | Yes/No |
|
||||
| `CanLoadBeagle` | `can_bap` | Yes/No |
|
||||
| `CanLoadLightAmp` | `can_lightamp` | Yes/No |
|
||||
| `CanLoadAMS` | `can_ams` | Yes/No |
|
||||
| `CanLoadLAMS` | `can_lams` | Yes/No |
|
||||
| `CanLoadIFF_Jammer` | `can_iff` | Yes/No |
|
||||
|
||||
**MinStandTransitionSpeed** is the speed (m/s) below which the mech switches from its walking animation to its idle/standing animation.
|
||||
It is NOT a hard movement limit. It is purely an animation state machine threshold in `Mech.cpp`.
|
||||
Code path: `animStateEngine?RequestState(StandState)` when `currentSpeedMPS <= minStandTransitionSpeed`.
|
||||
Must be > 0 (validated in `Vehicle_Tool.cpp`). Argus = 12.631 m/s = 45.5 kph.
|
||||
|
||||
#### `.instance` file (`parse_instance()`)
|
||||
|
||||
| Field | Editor key | Notes |
|
||||
|---|---|---|
|
||||
| `PowerRating` | `PowerRating` | mechlab bar value, 0–100 |
|
||||
| `ArmorRating` | `ArmorRating` | mechlab bar value, 0–100 |
|
||||
| `SpeedRating` | `SpeedRating` | mechlab bar value, 0–100 |
|
||||
| `HeatRating` | `HeatRating` | mechlab bar value, 0–100 |
|
||||
| `DoesHaveLightAmp` | `has_lightamp` | 0 or 1, default 1 — whether LightAmp is currently installed |
|
||||
|
||||
#### `.subsystems` file (`parse_subsystems()`)
|
||||
|
||||
Provides: armor type + per-zone multipliers, installed heatsinks, jump jets, engine upgrades, weapons, electronics.
|
||||
|
||||
**Armor block:**
|
||||
- `ArmorType=` ? armor type string (`Standard`, `FerroFiberus`, `Reactive`, `Reflective`, `Solarian`)
|
||||
- Per-zone entries: `LeftArm=1.0`, `RightTorso=2.5`, etc. — multiplier for that zone
|
||||
|
||||
**Engine:**
|
||||
- `EngineUpgrade` blocks counted ? `engine_upgrades` (0–5)
|
||||
|
||||
**Weapons** — each weapon block contains:
|
||||
- `Model=` ? weapon subsystem resource path (name extracted)
|
||||
- `InternalLocation=` ? zone name
|
||||
- `Site=` ? mount port name (from armature)
|
||||
- `GroupIndex=` ? weapon group number
|
||||
- `WeaponFacing=` ? 0=Front, 1=Rear, 2=Side (absent = Front)
|
||||
- `AmmoCount=` ? rounds for ammo-using weapons
|
||||
- `EjectSite=` ? optional ejection site for ammo
|
||||
|
||||
**Electronics:** ECM, Beagle (BAP), AMS, LAMS, IFF_Jammer detected by subsystem model path.
|
||||
|
||||
#### `.damage` file (`parse_damage()`)
|
||||
|
||||
Per zone section `[ZoneInternal]`:
|
||||
- `BaseArmorValue` ? starting armor (float)
|
||||
- `MaxArmorValue` ? hard cap on armor pts for that zone
|
||||
- `InternalHPValue` ? internal structure HP
|
||||
- `OmniSlots`, `BeamSlots`, `MissileSlots`, `ProjectileSlots` ? weapon slot counts
|
||||
|
||||
Special zones:
|
||||
- `SpecialAttachedToZone=` ? which body section this special zone is attached to
|
||||
- `DamagePropagationZone=` ? where overflow damage propagates
|
||||
|
||||
#### `.engine` file (`parse_engine()`)
|
||||
|
||||
| Field | Editor key | Notes |
|
||||
|---|---|---|
|
||||
| `NumHeatSinks` | `NumHeatSinks` | free heatsinks from engine (not in subsystems) |
|
||||
| `TonsPerUpgrade` | `TonsPerUpgrade` | tonnage cost per engine upgrade tier |
|
||||
| `MPSPerUpgrade` | `MPSPerUpgrade` | m/s speed gain per upgrade tier |
|
||||
|
||||
#### `.torso` file (`parse_torso()`)
|
||||
|
||||
| Field | Notes |
|
||||
|---|---|
|
||||
| `TwistSpeed` | torso horizontal rotation speed — may be a macro reference |
|
||||
| `PitchSpeed` | torso vertical rotation speed — may be a macro reference |
|
||||
| `TwistRadius` | max horizontal twist angle — may be a macro reference |
|
||||
| `PitchRadius` | max vertical pitch angle — may be a macro reference |
|
||||
| `ArmRatioAngle` | ratio of arm tracking vs torso rotation — may be a macro reference |
|
||||
|
||||
All torso fields may reference macros from `Content/Defines/MechTorso.defines`.
|
||||
The editor resolves them using a preloaded `TORSO_DEFINES` dict. Notable values:
|
||||
|
||||
```
|
||||
NORMAL_RATIO = 40
|
||||
SNAIL_TSPEED = 40
|
||||
NORMAL_TSPEED = 60
|
||||
FAST_TSPEED = 80
|
||||
WIDE_TRADIUS = 160
|
||||
NORMAL_PRADIUS = 40
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Calculated Ratings and Conversions
|
||||
|
||||
#### Speed (kph)
|
||||
|
||||
```
|
||||
top_speed_kph = min(MinMaxSpeed + MPSPerUpgrade × engine_upgrades, MaxSpeed) × 3.6
|
||||
```
|
||||
|
||||
- `MinMaxSpeed` and `MaxSpeed` from `.data` (m/s)
|
||||
- `MPSPerUpgrade` from `.engine` (m/s per tier)
|
||||
- `engine_upgrades` from `.subsystems` (0–5)
|
||||
- Multiply by 3.6 to convert m/s ? kph
|
||||
- Argus example: (20.28 + 1.11 × 10) × 3.6 = 113.5 kph
|
||||
|
||||
#### Speed Rating (bar)
|
||||
|
||||
```
|
||||
speed_rating = (top_speed_mps / MaxSpeed) × 100 [capped at 100]
|
||||
```
|
||||
|
||||
#### Turn Rate — degrees to radians
|
||||
|
||||
The `.data` file stores turn rates in **degrees/sec**. The mechlab UI label was changed to show rad/sec:
|
||||
- `StringResource.rc`: `IDS_ML_CH_TURNRATE` ? `"Turn Rate (Top Speed Rad/Sec):"`
|
||||
- Conversion: `radians = degrees × ?/180` where `?/180 ? 0.017453`
|
||||
- Argus: FullStopTurn = 75° = **1.309 rad/sec**, TopSpeedTurn = 45° = **0.785 rad/sec**
|
||||
|
||||
#### Acceleration / Deceleration (m/s²)
|
||||
|
||||
Stored directly in `.data`. Reverse values are derived:
|
||||
```
|
||||
reverse_accel = Acceleration × ReverseAccelerationMultiplier
|
||||
reverse_decel = Decceleration × ReverseDeccelerationMultiplier
|
||||
```
|
||||
|
||||
**The double-c spelling (`Decceleration`, `ReverseDeccelerationMultiplier`) is canonical — it matches the engine source. Do not "fix" the spelling.**
|
||||
|
||||
#### Heat Rating (bar)
|
||||
|
||||
```
|
||||
total_hs = NumHeatSinks (engine) + installed_heatsinks (subsystems)
|
||||
effective_hs = total_hs × (2 if Double else 1)
|
||||
heat_rating = (effective_hs / MaxHeat) × 100 [capped at 100]
|
||||
```
|
||||
|
||||
#### Power Rating (bar)
|
||||
|
||||
```
|
||||
total_damage = ? (DamageAmount × NumFire) for each installed weapon
|
||||
power_rating = (total_damage / 80) × 100 [capped at 100]
|
||||
```
|
||||
|
||||
- `DamageAmount` and `NumFire` come from `WeaponSubsystems/<weapon>.data` following `!include` chains
|
||||
- Parsed by `load_weapon_damages()` at server startup, cached in `Handler.weapon_damages`
|
||||
- Argus example with default load: ~36.2 total damage ? 45 rating (stored = 42)
|
||||
|
||||
#### Armor Rating (bar)
|
||||
|
||||
```
|
||||
for each zone:
|
||||
pts = multiplier × ARMOR_PTS_PER_TON[armor_type]
|
||||
effective = min(pts, MaxArmorValue[zone])
|
||||
armor_rating = (? effective / ? MaxArmorValue) × 100
|
||||
```
|
||||
|
||||
Armor pts per ton by type (from `Adept/ResourceImagePool.cpp` and game design):
|
||||
|
||||
| Type | Pts/ton |
|
||||
|---|---|
|
||||
| Standard | 32 |
|
||||
| FerroFiberus | 38 |
|
||||
| Reactive | 30 |
|
||||
| Reflective | 30 |
|
||||
| Solarian | 60 |
|
||||
|
||||
Note: `FerroFiberus` is the canonical internal token (not player-visible). The player sees `DNL_FERROFIB = "Ferro Fibrous"` via string lookup.
|
||||
|
||||
---
|
||||
|
||||
### Active-in-Game Detection
|
||||
|
||||
Source: `Gameleap/mw4/Content/Tables/MechChassisTable.tbl`
|
||||
|
||||
Format:
|
||||
```
|
||||
DisplayKey=Mechs\DirName\FileName.data
|
||||
//CommentedKey=Mechs\DirName\FileName.data <- inactive
|
||||
```
|
||||
|
||||
- Active = entry exists AND is not prefixed with `//`
|
||||
- Currently the only inactive mech: **Dasher** (commented out)
|
||||
- The editor shows a green **ACTIVE IN GAME** or red **NOT IN GAME** banner at top of Stats tab
|
||||
|
||||
---
|
||||
|
||||
### hsh/ Image Naming Conventions
|
||||
|
||||
The `hsh/` directory under `Gameleap/mw4/` holds loose BMP files loaded at runtime (not packed into `.mw4`).
|
||||
There are four relevant subdirectories, each with a different naming authority.
|
||||
|
||||
#### `hsh/hud/` — in-game HUD damage silhouette (own mech)
|
||||
#### `hsh/MFD/` — MFD target display silhouette (target mech)
|
||||
#### `hsh/radar/hud/` — radar damage overlay
|
||||
|
||||
**All three use identical stems** sourced from `huddamage.cpp` `texturename[]` array.
|
||||
|
||||
Load path:
|
||||
- hud/MFD: `hsh\<texturename>.bmp` where texturename = `hud\<stem>` ? file = `hsh/hud/<stem>.bmp`
|
||||
- radar: `hsh\radar\<texturename>.bmp` ? file = `hsh/radar/hud/<stem>.bmp`
|
||||
|
||||
Code: `render.cpp` `CRadar_Device::LoadRadarDamageTexture()` and `huddamage.cpp` `HUDDamage`.
|
||||
|
||||
#### `hsh/Mechs/` — mw4print scorecard portrait
|
||||
|
||||
Load path: `recscore.cpp` ? `GetLocString(model->m_nameIndex)` ? `DNL_*` string from `StringResource.rc` ? lowercased filename.
|
||||
Different naming authority from the other three.
|
||||
|
||||
---
|
||||
|
||||
### Complete Canonical Name Table
|
||||
|
||||
Key: mech directory name (case-insensitive) ? canonical stem for `hsh/hud/`, `hsh/MFD/`, `hsh/radar/hud/`.
|
||||
Entries in **bold** differ from the directory name.
|
||||
|
||||
| Directory | hud/MFD/radar stem | hsh/Mechs/ portrait filename |
|
||||
|---|---|---|
|
||||
| Annihilator | annihilator | annihilator.bmp |
|
||||
| Archer | archer | archer.bmp |
|
||||
| ArcticWolf | arcticwolf | arctic wolf.bmp |
|
||||
| Ares | ares | ares.bmp |
|
||||
| Argus | argus | argus.bmp |
|
||||
| Assassin2 | assassin2 | **assassin ii.bmp** |
|
||||
| Atlas | atlas | atlas.bmp |
|
||||
| Avatar | avatar | avatar.bmp |
|
||||
| Awesome | awesome | awesome.bmp |
|
||||
| Battlemaster | battlemaster | battlemaster.bmp |
|
||||
| Battlemaster2c | **battlemasteriic** | **battlemaster iic.bmp** |
|
||||
| Behemoth | behemoth | behemoth.bmp |
|
||||
| Behemoth2 | **behemothii** | **behemoth ii.bmp** |
|
||||
| Blackhawk | blackhawk | black hawk.bmp |
|
||||
| Blacknight | **blackknight** | black knight.bmp |
|
||||
| Blacklanner | blacklanner | black lanner.bmp |
|
||||
| Brigand | brigand | brigand.bmp |
|
||||
| Bushwacker | bushwacker | bushwacker.bmp |
|
||||
| Catapult | catapult | catapult.bmp |
|
||||
| CauldronBorn | cauldronborn | **cauldronborn.bmp** (table key has hyphen; DNL does not) |
|
||||
| Chimera | chimera | chimera.bmp |
|
||||
| Commando | commando | commando.bmp |
|
||||
| Cougar | cougar | cougar.bmp |
|
||||
| Cyclops | cyclops | cyclops.bmp |
|
||||
| Daishi | daishi | daishi.bmp |
|
||||
| Deimos | deimos | deimos.bmp |
|
||||
| Dragon | dragon | dragon.bmp |
|
||||
| Fafnir | fafnir | fafnir.bmp |
|
||||
| Flea | flea | flea.bmp |
|
||||
| Gladiator | gladiator | gladiator.bmp |
|
||||
| Grizzly | grizzly | grizzly.bmp |
|
||||
| Hauptmann | hauptmann | hauptmann.bmp |
|
||||
| Hellhound | hellhound | hellhound.bmp |
|
||||
| Hellspawn | hellspawn | hellspawn.bmp |
|
||||
| Highlander | highlander | highlander.bmp |
|
||||
| Hollander | **hollanderii** | **hollander ii.bmp** |
|
||||
| Hunchback | hunchback | hunchback.bmp |
|
||||
| Kodiak | kodiak | kodiak.bmp |
|
||||
| Loki | loki | loki.bmp |
|
||||
| Longbow | longbow | longbow.bmp |
|
||||
| Madcat | madcat | mad cat.bmp |
|
||||
| Madcat_MKII | **madcat2** | mad cat mkii.bmp |
|
||||
| Masakari | masakari | masakari.bmp |
|
||||
| Mauler | mauler | mauler.bmp |
|
||||
| Novacat | novacat | nova cat.bmp |
|
||||
| Osiris | osiris | osiris.bmp |
|
||||
| Owens | owens | owens.bmp |
|
||||
| Puma | puma | puma.bmp |
|
||||
| Raven | raven | raven.bmp |
|
||||
| Rifleman | rifleman | rifleman.bmp |
|
||||
| Ryoken | ryoken | ryoken.bmp |
|
||||
| Shadowcat | shadowcat | shadow cat.bmp |
|
||||
| Solitaire | solitaire | solitaire.bmp |
|
||||
| Sunder | sunder | sunder.bmp |
|
||||
| Templar | templar | templar.bmp |
|
||||
| Thanatos | thanatos | thanatos.bmp |
|
||||
| Thor | thor | thor.bmp |
|
||||
| Uller | uller | uller.bmp |
|
||||
| Urbanmech | urbanmech | urbanmech.bmp |
|
||||
| Uziel | uziel | uziel.bmp |
|
||||
| Victor | victor | victor.bmp |
|
||||
| Vulture | vulture | vulture.bmp |
|
||||
| Warhammer | warhammer | warhammer.bmp |
|
||||
| Wolfhound | wolfhound | wolfhound.bmp |
|
||||
| Zeus | zeus | zeus.bmp |
|
||||
|
||||
**Critical mismatches where directory name ? hud/MFD stem (files must use the stem, not the dir name):**
|
||||
|
||||
| Directory | Wrong name (dir-based) | Correct name (stem) |
|
||||
|---|---|---|
|
||||
| Battlemaster2c | battlemaster2c.bmp | **battlemasteriic.bmp** |
|
||||
| Behemoth2 | behemoth2.bmp | **behemothii.bmp** |
|
||||
| Blacknight | blacknight.bmp | **blackknight.bmp** |
|
||||
| Hollander | hollander.bmp | **hollanderii.bmp** |
|
||||
| Madcat_MKII | madcat_mkii.bmp | **madcat2.bmp** |
|
||||
|
||||
**Portrait mismatches for hsh/Mechs/ (table key ? DNL string):**
|
||||
|
||||
The `MechChassisTable.tbl` display key and `GetLocString()` DNL string differ for these mechs.
|
||||
mw4print uses the DNL string. The table key is NOT the correct portrait filename for these 5 mechs.
|
||||
|
||||
| Directory | Table key (wrong for mw4print) | DNL string (correct portrait stem) |
|
||||
|---|---|---|
|
||||
| Assassin2 | AssassinII ? assassinii | `DNL_ASSASSIN2 "Assassin II"` ? **assassin ii.bmp** |
|
||||
| Battlemaster2c | BattlemasterIIC ? battlemasteriic | `DNL_BATTLEMASTERIIC "Battlemaster IIc"` ? **battlemaster iic.bmp** |
|
||||
| Behemoth2 | BehemothII ? behemothii | `DNL_BEHEMOTHII "Behemoth II"` ? **behemoth ii.bmp** |
|
||||
| CauldronBorn | Cauldron-Born ? cauldron-born | `DNL_CAULDRONBORN "Cauldronborn"` ? **cauldronborn.bmp** |
|
||||
| Hollander | HollanderII ? hollanderii | `DNL_HOLLANDERII "Hollander II"` ? **hollander ii.bmp** |
|
||||
|
||||
---
|
||||
|
||||
### MechEditor Implementation Notes
|
||||
|
||||
The editor encodes all of the above knowledge in two Python dicts:
|
||||
|
||||
**`MECH_HSH_STEMS`** (in `mech_editor.py`)
|
||||
Maps lowercase dir name ? canonical stem for `hsh/hud/`, `hsh/MFD/`, `hsh/radar/hud/`.
|
||||
Source: `huddamage.cpp` `texturename[]` array.
|
||||
|
||||
**`MECH_PORTRAIT_OVERRIDES`** (in `mech_editor.py`)
|
||||
Maps lowercase dir name ? portrait stem for `hsh/Mechs/` where the DNL string differs from the chassis table key.
|
||||
Source: `DNL_*` entries in `Gameleap/code/mw4/Code/scriptstrings/StringResource.rc`.
|
||||
|
||||
For all other mechs, the portrait stem is derived dynamically from `MechChassisTable.tbl` (display key, lowercased).
|
||||
|
||||
The Assets tab in the editor shows all four image types. When an image is missing, it displays:
|
||||
```
|
||||
Wants: hsh/<subdir>/<expected_filename>.bmp
|
||||
```
|
||||
so the user knows exactly what to rename or create.
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
Chassis,InternalLocation,Model,Site,AmmoCount,GroupIndex,WeaponFacing
|
||||
Archer,LeftTorso,LRM15,site_ldmissile,24,2,2
|
||||
Archer,RightTorso,LRM15,site_rdmissile,24,2,2
|
||||
Ares,Special2,ClanLRM10,site_lmissileport,24,2,2
|
||||
Ares,Special2,ClanLRM10,site_missileport,24,2,2
|
||||
Ares,Special2,ClanLRM10,site_rmissileport,24,2,2
|
||||
AssassinII,Special1,LRM5,site_missileport,24,2,2
|
||||
Atlas,LeftTorso,LRM20,site_lmissileport,12,2,2
|
||||
Avatar,LeftTorso,LRM5,site_lmissileport,24,2,2
|
||||
Avatar,RightTorso,LRM5,site_rmissileport,24,2,2
|
||||
Avatar,LeftTorso,LRM10,site_lmissileport,24,2,2
|
||||
Avatar,RightTorso,LRM10,site_rmissileport,24,2,2
|
||||
Awesome,CenterTorso,LRM5,site_ctorsoport,24,2,2
|
||||
Battlemaster,RightTorso,MediumLaser,site_rdtorsoport,,1,1
|
||||
Battlemaster,LeftTorso,MediumLaser,site_ldtorsoport,,1,1
|
||||
BattlemasterIIC,RightTorso,ClanERMediumLaser,site_rdtorsoport,,1,1
|
||||
BattlemasterIIC,LeftTorso,ClanERMediumLaser,site_ldtorsoport,,1,1
|
||||
Black Lanner,Special2,ClanSRM6,site_rmissileport,15,2,2
|
||||
Black Lanner,Special1,ClanLRM10,site_lmissileport,24,2,2
|
||||
Bushwacker,Special1,LRM5,site_missileport,24,2,2
|
||||
Bushwacker,Special1,LRM5,site_missileport,24,2,2
|
||||
Catapult,LeftArm,LRM20,site_lmissileport,12,2,2
|
||||
Catapult,RightArm,LRM20,site_rmissileport,12,2,2
|
||||
Cauldron-Born,Special1,ClanLRM10,site_rmissileport,24,2,2
|
||||
Cauldron-Born,Special2,ClanLRM10,site_lmissileport,24,2,2
|
||||
Chimera,RightTorso,LRM5,site_missileport,24,2,2
|
||||
Chimera,RightTorso,LRM5,site_missileport,24,2,2
|
||||
Chimera,RightTorso,LRM5,site_missileport,24,2,2
|
||||
Chimera,RightTorso,LRM5,site_missileport,24,2,2
|
||||
Cyclops,LeftTorso,LRM10,site_lmissile,24,2,2
|
||||
Cougar,LeftTorso,ClanLRM10,site_lmissileport,12,2,2
|
||||
Cougar,RightTorso,ClanLRM10,site_rmissileport,12,2,2
|
||||
Deimos,Special1,ClanLRM15,site_lmissileport,16,2,2
|
||||
Deimos,Special2,ClanLRM15,site_rmissileport,16,2,2
|
||||
Dragon,CenterTorso,LRM10,site_missleport,24,2,2
|
||||
Flea,LeftTorso,SmallLaser,site_ltorsoport,,1,1
|
||||
Flea,RightTorso,SmallLaser,site_rtorsoport,,1,1
|
||||
Grizzly,LeftTorso,CLANLRM10,site_missleport,24,2,2
|
||||
Hellhound,LeftTorso,ClanLRM10,site_missileport,12,2,2
|
||||
Mad Cat,Special1,ClanLRM10,site_lmissileport,24,2,2
|
||||
Mad Cat,Special2,ClanLRM10,site_rmissileport,24,2,2
|
||||
Mad Cat MKII,Special2,ClanLRM15,site_lmissileport,16,2,2
|
||||
Mad Cat MKII,Special1,ClanLRM15,site_rmissileport,16,2,2
|
||||
Masakari,LeftTorso,ClanLRM10,site_lmissleport,24,2,2
|
||||
Masakari,LeftTorso,ClanLRM10,site_ltorsoport,24,2,2
|
||||
Mauler,LeftTorso,LRM5,site_lmissileport,24,2,2
|
||||
Mauler,LeftTorso,LRM5,site_lmissileport,24,2,2
|
||||
Mauler,LeftTorso,LRM5,site_lmissileport,24,2,2
|
||||
Mauler,RightTorso,LRM5,site_rmissileport,24,2,2
|
||||
Mauler,RightTorso,LRM5,site_rmissileport,24,2,2
|
||||
Mauler,RightTorso,LRM5,site_rmissileport,24,2,2
|
||||
Raven,RightTorso,LRM5,site_rtorsoport,24,2,2
|
||||
Sunder,LeftTorso,MediumLaser,site_ldtorsoport,,1,1
|
||||
Sunder,RightTorso,MediumLaser,site_rdtorsoport,,1,1
|
||||
Templar,LeftTorso,MediumPulseLaser,site_ldrtorsoport,,1,1
|
||||
Templar,RightTorso,MediumPulseLaser,site_rdrtorsoport,,1,1
|
||||
Thor,Special1,CLANLRM10,site_missileport,24,2,2
|
||||
Uziel,Special1,LRM10,site_missileport,24,2,2
|
||||
Vulture,LeftTorso,ClanLRM5,site_lmissileport,24,2,2
|
||||
Vulture,RightTorso,ClanLRM5,site_rmissileport,24,2,2
|
||||
Vulture,LeftTorso,ClanLRM10,site_lmissileport,24,2,2
|
||||
Vulture,RightTorso,ClanLRM10,site_rmissileport,24,2,2
|
||||
Wolfhound,CenterTorso,ClanERMediumLaser,site_reartorsoport,,1,1
|
||||
Zeus,RightTorso,MediumPulseLaser,site_reartorsoport,,1,1
|
||||
|
@@ -0,0 +1,45 @@
|
||||
Chassis,InternalLocation,Model,Site,AmmoCount,GroupIndex,WeaponFacing
|
||||
Ares,Special1,ClanERSmallLaser,site_lgunport,,1,
|
||||
Ares,Special1,ClanERSmallLaser,site_rgunport,,1,
|
||||
Ares,Special2,ClanLRM10,site_lmissileport,24,2,2
|
||||
Ares,Special2,ClanLRM10,site_missileport,24,2,2
|
||||
Ares,Special2,ClanLRM10,site_rmissileport,24,2,2
|
||||
AssassinII,Special1,LRM5,site_missileport,24,2,2
|
||||
Atlas,Special1,AC20,site_rtorsoport,10,1,
|
||||
Atlas,Special2,SRM6,site_llmissile,15,2,
|
||||
Avatar,Special1,MachineGun,site_ltorsoport,200,1,
|
||||
Avatar,Special1,MachineGun,site_rtorsoport,200,1,
|
||||
Battlemaster,Special2,PPC,site_rdgunport,,1,
|
||||
Battlemaster,Special1,SRM6,site_missile,15,2,
|
||||
BattlemasterIIC,Special1,ClanSSRM6,site_missile,15,2,
|
||||
Behemoth,Special1,LargeLaser,site_ctorsoport,,1,
|
||||
BehemothII,Special1,LargeLaser,site_ctorsoport,,1,
|
||||
Black Lanner,Special2,ClanSRM6,site_rmissileport,15,2,2
|
||||
Black Lanner,Special1,ClanLRM10,site_lmissileport,24,2,2
|
||||
Brigand,Special2,MediumLaser,site_ltorsoport,,1,
|
||||
Brigand,Special1,MediumLaser,site_rtorsoport,,1,
|
||||
Bushwacker,Special1,LRM5,site_missileport,24,2,2
|
||||
Bushwacker,Special1,LRM5,site_missileport,24,2,2
|
||||
Cauldron-Born,Special1,ClanLRM10,site_rmissileport,24,2,2
|
||||
Cauldron-Born,Special2,ClanLRM10,site_lmissileport,24,2,2
|
||||
Cyclops,Special1,MediumPulseLaser,site_gunport,,1,
|
||||
Deimos,Special1,ClanLRM15,site_lmissileport,16,2,2
|
||||
Deimos,Special2,ClanLRM15,site_rmissileport,16,2,2
|
||||
Hauptmann,Special1,ClanUltraAC20,site_rutorsoport,16,1,
|
||||
Hellspawn,Special1,SSRM2,site_rmissileport,50,2,
|
||||
HollanderII,Special2,SmallPulseLaser,site_cltorsoport,,1,
|
||||
HollanderII,Special2,SmallPulseLaser,site_crtorsoport,,1,
|
||||
HollanderII,Special1,GaussRifle,site_rtorsoport,16,1,
|
||||
Hunchback,Special1,AC10,site_rutorsoport,20,1,
|
||||
Loki,Special1,ClanSSRM6,site_missileport,15,2,
|
||||
Mad Cat,Special1,ClanLRM10,site_lmissileport,24,2,2
|
||||
Mad Cat,Special2,ClanLRM10,site_rmissileport,24,2,2
|
||||
Mad Cat MKII,Special2,ClanLRM15,site_lmissileport,16,2,2
|
||||
Mad Cat MKII,Special1,ClanLRM15,site_rmissileport,16,2,2
|
||||
Rifleman,Special1,MediumLaser,site_ltorsoport,,1,
|
||||
Rifleman,Special1,MediumLaser,site_rtorsoport,,1,
|
||||
Solitaire,Special1,ClanERLargeLaser,site_rtorsoport,,1,
|
||||
Thor,Special1,CLANLRM10,site_missileport,24,2,2
|
||||
Uziel,Special1,LRM10,site_missileport,24,2,2
|
||||
Vulture,Special1,ClanMachineGun,site_ltorsoport,200,1,
|
||||
Vulture,Special1,ClanMachineGun,site_rtorsoport,200,1,
|
||||
|
@@ -0,0 +1,144 @@
|
||||
[mission]
|
||||
MissionName=Coliseum - Attrition
|
||||
GameType=2
|
||||
TeamAllowed=0
|
||||
Visibility=1
|
||||
Weather=0
|
||||
TimeOfDay=0
|
||||
TimeLimit=15
|
||||
Radar=0
|
||||
HeatOn=0
|
||||
FriendlyFire=1
|
||||
SplashDamage=1
|
||||
UnlimitedAmmo=0
|
||||
WeaponJam=1
|
||||
AdvanceMode=1
|
||||
ArmorMode=1
|
||||
|
||||
[slot0]
|
||||
Type=1
|
||||
PilotName=Viper
|
||||
Mech=Atlas
|
||||
Team=0
|
||||
Skin=0
|
||||
Decal=3
|
||||
|
||||
[slot1]
|
||||
Type=1
|
||||
PilotName=Blackjack
|
||||
Mech=Mad Cat
|
||||
Team=0
|
||||
Skin=1
|
||||
Decal=4
|
||||
|
||||
[slot2]
|
||||
Type=1
|
||||
PilotName=Ghost
|
||||
Mech=Warhammer
|
||||
Team=0
|
||||
Skin=2
|
||||
Decal=2
|
||||
|
||||
[slot3]
|
||||
Type=1
|
||||
PilotName=Maverick
|
||||
Mech=Thor
|
||||
Team=0
|
||||
Skin=3
|
||||
Decal=5
|
||||
|
||||
[slot4]
|
||||
Type=1
|
||||
PilotName=Reaper
|
||||
Mech=Loki
|
||||
Team=0
|
||||
Skin=4
|
||||
Decal=6
|
||||
|
||||
[slot5]
|
||||
Type=1
|
||||
PilotName=Phoenix
|
||||
Mech=Daishi
|
||||
Team=0
|
||||
Skin=5
|
||||
Decal=9
|
||||
|
||||
[slot6]
|
||||
Type=1
|
||||
PilotName=Hammer
|
||||
Mech=Shadow Cat
|
||||
Team=0
|
||||
Skin=6
|
||||
Decal=10
|
||||
|
||||
[slot7]
|
||||
Type=1
|
||||
PilotName=Blade
|
||||
Mech=Battlemaster
|
||||
Team=0
|
||||
Skin=7
|
||||
Decal=11
|
||||
|
||||
[slot8]
|
||||
Type=1
|
||||
PilotName=Ironside
|
||||
Mech=Cauldron-Born
|
||||
Team=0
|
||||
Skin=8
|
||||
Decal=12
|
||||
|
||||
[slot9]
|
||||
Type=1
|
||||
PilotName=Tempest
|
||||
Mech=Vulture
|
||||
Team=0
|
||||
Skin=9
|
||||
Decal=3
|
||||
|
||||
[slot10]
|
||||
Type=1
|
||||
PilotName=Saber
|
||||
Mech=Black Hawk
|
||||
Team=0
|
||||
Skin=10
|
||||
Decal=16
|
||||
|
||||
[slot11]
|
||||
Type=1
|
||||
PilotName=Ajax
|
||||
Mech=Archer
|
||||
Team=0
|
||||
Skin=11
|
||||
Decal=49
|
||||
|
||||
[slot12]
|
||||
Type=1
|
||||
PilotName=Thunder
|
||||
Mech=Kodiak
|
||||
Team=0
|
||||
Skin=12
|
||||
Decal=2
|
||||
|
||||
[slot13]
|
||||
Type=1
|
||||
PilotName=Raven
|
||||
Mech=Uziel
|
||||
Team=0
|
||||
Skin=13
|
||||
Decal=50
|
||||
|
||||
[slot14]
|
||||
Type=1
|
||||
PilotName=Wraith
|
||||
Mech=Grizzly
|
||||
Team=0
|
||||
Skin=14
|
||||
Decal=48
|
||||
|
||||
[slot15]
|
||||
Type=1
|
||||
PilotName=Goliath
|
||||
Mech=Annihilator
|
||||
Team=0
|
||||
Skin=15
|
||||
Decal=5
|
||||
@@ -0,0 +1,145 @@
|
||||
[mission]
|
||||
MissionName=CentralPark - Team KotH
|
||||
GameType=6
|
||||
TeamAllowed=1
|
||||
TeamCount=4
|
||||
Visibility=1
|
||||
Weather=0
|
||||
TimeOfDay=0
|
||||
TimeLimit=15
|
||||
Radar=0
|
||||
HeatOn=0
|
||||
FriendlyFire=1
|
||||
SplashDamage=1
|
||||
UnlimitedAmmo=0
|
||||
WeaponJam=1
|
||||
AdvanceMode=1
|
||||
ArmorMode=1
|
||||
|
||||
[slot0]
|
||||
Type=1
|
||||
PilotName=Viper
|
||||
Mech=Atlas
|
||||
Team=0
|
||||
Skin=0
|
||||
Decal=3
|
||||
|
||||
[slot1]
|
||||
Type=1
|
||||
PilotName=Blackjack
|
||||
Mech=Mad Cat
|
||||
Team=0
|
||||
Skin=0
|
||||
Decal=3
|
||||
|
||||
[slot2]
|
||||
Type=1
|
||||
PilotName=Ghost
|
||||
Mech=Warhammer
|
||||
Team=0
|
||||
Skin=0
|
||||
Decal=3
|
||||
|
||||
[slot3]
|
||||
Type=1
|
||||
PilotName=Maverick
|
||||
Mech=Thor
|
||||
Team=0
|
||||
Skin=0
|
||||
Decal=3
|
||||
|
||||
[slot4]
|
||||
Type=1
|
||||
PilotName=Reaper
|
||||
Mech=Loki
|
||||
Team=1
|
||||
Skin=1
|
||||
Decal=4
|
||||
|
||||
[slot5]
|
||||
Type=1
|
||||
PilotName=Phoenix
|
||||
Mech=Daishi
|
||||
Team=1
|
||||
Skin=1
|
||||
Decal=4
|
||||
|
||||
[slot6]
|
||||
Type=1
|
||||
PilotName=Hammer
|
||||
Mech=Shadow Cat
|
||||
Team=1
|
||||
Skin=1
|
||||
Decal=4
|
||||
|
||||
[slot7]
|
||||
Type=1
|
||||
PilotName=Blade
|
||||
Mech=Battlemaster
|
||||
Team=1
|
||||
Skin=1
|
||||
Decal=4
|
||||
|
||||
[slot8]
|
||||
Type=1
|
||||
PilotName=Ironside
|
||||
Mech=Cauldron-Born
|
||||
Team=2
|
||||
Skin=2
|
||||
Decal=2
|
||||
|
||||
[slot9]
|
||||
Type=1
|
||||
PilotName=Tempest
|
||||
Mech=Vulture
|
||||
Team=2
|
||||
Skin=2
|
||||
Decal=2
|
||||
|
||||
[slot10]
|
||||
Type=1
|
||||
PilotName=Saber
|
||||
Mech=Black Hawk
|
||||
Team=2
|
||||
Skin=2
|
||||
Decal=2
|
||||
|
||||
[slot11]
|
||||
Type=1
|
||||
PilotName=Ajax
|
||||
Mech=Archer
|
||||
Team=2
|
||||
Skin=2
|
||||
Decal=2
|
||||
|
||||
[slot12]
|
||||
Type=1
|
||||
PilotName=Thunder
|
||||
Mech=Kodiak
|
||||
Team=3
|
||||
Skin=3
|
||||
Decal=5
|
||||
|
||||
[slot13]
|
||||
Type=1
|
||||
PilotName=Raven
|
||||
Mech=Uziel
|
||||
Team=3
|
||||
Skin=3
|
||||
Decal=5
|
||||
|
||||
[slot14]
|
||||
Type=1
|
||||
PilotName=Wraith
|
||||
Mech=Grizzly
|
||||
Team=3
|
||||
Skin=3
|
||||
Decal=5
|
||||
|
||||
[slot15]
|
||||
Type=1
|
||||
PilotName=Goliath
|
||||
Mech=Annihilator
|
||||
Team=3
|
||||
Skin=3
|
||||
Decal=5
|
||||
@@ -734,6 +734,179 @@ keeping old-RIO (type 0) protocol behavior byte-identical:
|
||||
call it via `-Command "& '...driver.ps1' game-start '-tbaud 115200'"` — `-File` binding
|
||||
rejects dash-leading positional args, and `Start-Process -ArgumentList` doesn't re-quote.
|
||||
|
||||
## 📋 Branch `mfdsplit`: mech loadouts, time list, build fixes (2026-07-18)
|
||||
|
||||
### Mech loadout changes
|
||||
- **Battlemaster IS** (`Content\Mechs\Battlemaster\battlemaster.subsystems`): replaced lone
|
||||
MediumPulseLaser default with full stock IS loadout — PPC (Special2), 6×ML (3 RT, 3 LT),
|
||||
2×MG (LA, 200 rds), SRM6 (Special1, 15 rds), all GroupIndex=1 except SRM6 (group 2).
|
||||
- **Battlemaster Clan 2C** (`battlemaster2c.subsystems`): ER PPC (RA), 6×ER ML (3 RT, 3 LT),
|
||||
2×Clan Gauss (LA, 16 rds each), Clan SSRM6 (Special1, 15 rds).
|
||||
- **Behemoth / Behemoth2** (`.subsystems`): moved Gauss rifles from weapon group 3 → group 1
|
||||
(3 occurrences each; gauss rifles now in group 1 alongside other main weapons).
|
||||
|
||||
### MP time-limit list fix (ConLobbyMission.script)
|
||||
- Expanded from 9 → 18 entries (1–15, 20, 25, 30 min); `max_displayed=10` so dropdown scrolls.
|
||||
- Fixed bare `else if` (missing braces) that caused a null-reference crash in the console lobby
|
||||
when the commit was merged from `main`. This was the root cause of the `aa500be7` regression.
|
||||
- Fixed `i==5` vs `i==6` max_displayed assignment for time vs radar dropdowns.
|
||||
|
||||
### Resource builder fix (build-resources.ps1) — VM / generic adapter support
|
||||
- Builder now always runs with `-window` (windowed mode + DDrawCompat). Fullscreen native DDraw
|
||||
fails on VMs with generic Microsoft display adapters (no hardware DDraw); windowed DDrawCompat
|
||||
works on all tested configs including VMs.
|
||||
- dgVoodoo2 D3D DLL interceptors (`D3D8.dll`, `D3D9.dll`, `D3DImm.dll`) in the working dir
|
||||
silently break the builder (it exits 0 without building anything). These files were left over
|
||||
from the abandoned dgVoodoo2 experiment (commit `87e25677`) — removed from repo (`git rm`).
|
||||
The build script also moves any such files aside defensively via the `$dgvMoved` block.
|
||||
- Removed all dead code for fullscreen fallback, bitdepth patching, ddraw move-aside logic.
|
||||
- `dgVoodoo.conf` / `dgVoodooCpl.exe` also removed from `Gameleap\mw4\` (no longer in use).
|
||||
- Expected behaviour on VM: a "Hardware Error: not compatible with MechWarrior 4" dialog appears
|
||||
at the end of the build — this is a GameOS hardware-capability warning, NOT a fatal error.
|
||||
Click OK; the .mw4 packages are built correctly regardless.
|
||||
|
||||
### Source tree Korean → English translation + UTF-8 cleanup (2026-07-18)
|
||||
- Translated all EUC-KR/CP949 Korean developer comments to English across **84 source files**
|
||||
(~876 lines). Zero Korean bytes remain outside intentional font-table headers (D3FFontEdit2/
|
||||
fontedit `all.h` etc.). Files are now clean UTF-8 (no BOM), safe for any modern editor.
|
||||
- Notable functional translations: `recscore.cpp` body-part return values and kill-announcer
|
||||
format strings (gameplay-visible on Korean Windows; now English on all systems); `nonmfc.h`
|
||||
assert dialog; GosView profiler `킪` → `us` (microseconds).
|
||||
- Latin-1 chars converted to proper UTF-8: © in 3dsmax4/Maxscrpt headers (82 files), ® in
|
||||
`gosHelp/Remote.cpp`, · bullet points in `ai command.hpp`, Û/ß in AnimationSuite headers.
|
||||
- Font table `*.h` files (`D3FFontEdit2/`, `fontedit/`) intentionally left as-is (raw byte
|
||||
values in C array data, not text).
|
||||
- `korean_diff.html` (side-by-side GitHub-style diff, ~873 KB) committed as documentation.
|
||||
|
||||
### Language DLL: English version from source
|
||||
- `Gameleap\mw4\Language.dll` and `MW4\Language.dll` replaced with the freshly compiled English
|
||||
build from `Language - Win32 English` config (`Language.dsp`). Fixes Korean button labels in
|
||||
the GameOS exception/crash dialog (`??? ??...` / `??` / `???` → More Details / Continue / Exit).
|
||||
The old binary was the original Korean build from the 2009 dev machine.
|
||||
|
||||
### mw4print v2.0 additions
|
||||
- **MySQL export** (`dbexport.h`/`dbexport.cpp`): late-bound runtime load of `libmysql.dll`
|
||||
(no compile-time MySQL SDK needed). Exports match data (match, player_result, pvp, optional
|
||||
event tables) to an external MySQL server after each print job. Schema in `db_schema.sql`.
|
||||
Config via `mw4print.ini [MySQLExport]`; UI via File → Database Settings (Ctrl+D).
|
||||
- **Configurable banner text**: File → Banner Setting... edits the bottom-of-sheet URL string
|
||||
(was hardcoded `WWW.MECHJOCK.COM`). Persisted to `options.ini [battle tech print] BannerText=`.
|
||||
- **libmysql.dll** (MySQL Connector/C 32-bit) added to `Gameleap\mw4\` so deploy copies it
|
||||
alongside `mw4print.exe`.
|
||||
- Version bumped to **2.0**, copyright year updated to **2026**.
|
||||
|
||||
## 📋 MFD mode 4: right device stagger fix (2026-07-18, eaa5fd3)
|
||||
Root cause: `CMFD_Device::BeginScene()` cleared BOTH MFD device back-buffers at `sh_step==0`.
|
||||
But in mode 4 the right MFD flip also fires at `sh_step==1` (= old `sh_step==0` after the
|
||||
stagger increment), so it presented a just-cleared buffer — only the grid, no channel data.
|
||||
|
||||
Fix: `BeginScene()` now only clears/grids the LEFT device at `sh_step==0`. New `BeginSceneRight()`
|
||||
(added to `render.cpp` / `render.hpp`, called from `WinMain.cpp`) clears/grids the RIGHT device at
|
||||
`sh_step==1` — one frame AFTER the right flip — so channels 3–4 render into a fresh buffer before
|
||||
the next flip. Mode 1 is unchanged.
|
||||
|
||||
Mode 4 cycle (with stagger):
|
||||
- `sh_step 0`: radar + left `BeginScene` (clear + grid); no flip
|
||||
- `sh_step 1`: flip right MFD (shows channels 3–4 from previous cycle) + right `BeginScene` (clear + grid)
|
||||
- `sh_step 2–4`: channels 0–2 → left device
|
||||
- `sh_step 5–6`: channels 3–4 → right device
|
||||
- `sh_step 0` (next): flip radar + left MFD (shows channels 0–2 from previous cycle)
|
||||
|
||||
Files: `CoreTech/Libraries/GameOS/WinMain.cpp`, `render.cpp`, `render.hpp`.
|
||||
|
||||
## 📋 Linux→Windows development workflow (2026-07-19, 55b9bfc5)
|
||||
`build-env/sync-to-windows.sh` — rsync script that pushes all source, content, toolchain, and
|
||||
assets to the Windows build machine at `/vwe/firestorm`. Excludes generated build outputs
|
||||
(`rel.bin/`, `dbg.bin/`, `*.mw4`, `*.dep`), `.git`/LFS objects, `_UNUSED/`, and the game deploy
|
||||
dir (`MW4/`). Run from Linux before triggering a Windows build.
|
||||
|
||||
## 📋 ddraw.dll removed from repo; build script moves it aside (2026-07-19, 0ceba9c7, 24825ff3)
|
||||
`Gameleap/mw4/ddraw.dll` (DDrawCompat) removed from git (was LFS-tracked); now lives as
|
||||
`ddraw.dll.old` in the same dir for reference. `deploy-editor.ps1` installs DDrawCompat as
|
||||
`ddraw.dll` at deploy time (the editor needs it for its windowed D3D7 viewport).
|
||||
`build-resources.ps1` moves `ddraw.dll` aside (`.buildaside`) before running `MW4pro.exe`
|
||||
because **DDrawCompat is fatal to MW4pro.exe in BOTH windowed and fullscreen modes**, then
|
||||
restores it in `finally`. The same block also defensively covers dgVoodoo2 interceptors
|
||||
(`D3D8/D3D9/D3DImm.dll`) in case they reappear.
|
||||
|
||||
## 📋 Branch `5.1.0b-in-progress`: multiplayer + RIO + source cleanup (2026-07-19)
|
||||
|
||||
### ConLobby V5.1.0b1 — Super6 mech rotation (c768f7c4)
|
||||
Changes from Buddy 'Highlight' Taylor (MCHL), merged manually:
|
||||
- Console version string bumped to **V5.1.0b1**.
|
||||
- `ROOKIEMECH` defines expanded from 4 → **6 mechs**: added Archer (ID=1) and Warhammer (ID=62).
|
||||
- 16-slot default assignments cycle through all 6 Super6 mechs.
|
||||
- Right-click randomizer expanded from `random(0,3)` → `random(0,5)`.
|
||||
|
||||
### CRIOMAIN.CPP — Korean translation + RIO poll timeout scaling (16fca6c4, a712002f)
|
||||
- Translated all EUC-KR/CP949 Korean developer comments (~35 lines) to English. File re-saved
|
||||
as clean UTF-8. CRLF line endings preserved (`* -text` in `.gitattributes`).
|
||||
⚠️ **Encoding hazard:** always read/write CRIOMAIN.CPP as binary (or with an explicit encoding
|
||||
codec). Python text-mode `readlines()` silently strips `\r`, causing a 3000+-line git diff when
|
||||
every line's `\r\n` becomes `\n`. If that happens, restore CRLF with `re.sub(b'(?<!\r)\n', b'\r\n', data)` in binary mode, then amend the commit.
|
||||
- Added **`g_dwRIOPollTimeout`** global (default 50 ms). Computed in `SetupConnection` before the
|
||||
receive loop using: `clamp(⌈480000/baud⌉, 5, 50)`. Preserves 50 ms at 9600 baud; floors at
|
||||
5 ms for 115200 baud. Implemented with explicit ternary — **`min`/`max` are undeclared in this
|
||||
translation unit under VC6** (not pulled in by CRIOMAIN's includes); use ternary or `__min`/`__max`.
|
||||
|
||||
### 16 pilots + 1 cameraship in multiplayer (f76dc05f)
|
||||
`MW4Shell.cpp`:
|
||||
- `CTCL_DefaultHostSetup` (non-coop): `Environment.NetworkMaxPlayers` set to
|
||||
`params->m_maxPlayers + (CTCL_GetTeslaCountAll() - CTCL_GetTeslaCount())`.
|
||||
The delta = camera-only seats (Tesla seats not assigned to pilots), reserving one extra
|
||||
DirectPlay slot per cameraship so the 17th connection isn't rejected.
|
||||
- `SetNetworkMissionParamater / PLAYER_LIMIT_PARAMETER`: same formula applied at runtime when
|
||||
host changes the player limit. `gos_NetServerCommands(gos_Commend_UpdateMaxPlayers)` still called;
|
||||
`break` must be present in this case (was accidentally dropped once — fall-through to
|
||||
`JOIN_IN_PROGRESS_PARAMETER` corrupts `m_joinInProgress`).
|
||||
- COOP branch unchanged (capped at 9+bots; no camera seat needed there).
|
||||
|
||||
`ConLobby.script`: launch guard `nTempPlayerCount > 16` raised to `> 17` so the cameraship
|
||||
connection doesn't trigger "Too many player/bots".
|
||||
|
||||
### hsh/ BMP canonical renames (5813aeb6, 2026-07-23)
|
||||
All `hsh/MFD/*.bmp` and `hsh/Mechs/*.bmp` filenames reconciled against the canonical stems
|
||||
expected by game code. The engine loads MFD images via `huddamage.cpp` `texturename[]` array
|
||||
(lowercase, no spaces) and Mechs portraits via `GetLocString` DNL strings (mixed-case with
|
||||
spaces). Any mismatch = silently missing image at runtime.
|
||||
Key renames:
|
||||
- `hsh/MFD/assassinii.bmp` → `assassin2.bmp` (matches `texturename[]` canonical)
|
||||
- `hsh/Mechs/battlemasteriic.bmp` → `battlemaster iic.bmp`
|
||||
- `hsh/Mechs/mad cat mk.ii.bmp` → `mad cat mkii.bmp`
|
||||
- `hsh/Mechs/behemoth ii.bmp` added (was absent)
|
||||
Most other files in both directories are LFS pointer updates only (content unchanged).
|
||||
|
||||
### RookieMission configurable defaults via options.ini (5813aeb6, 2026-07-23)
|
||||
CTCL (console) arcade mode has a "Rookie Mission" quick-launch that previously hardcoded all
|
||||
game params. Now all 13 params are overridable from an `[RookieMission]` section in
|
||||
`options.ini` (read by `CTCL_SetCDSP` at startup):
|
||||
- `MW4Shell.cpp`: added 14 `g_` globals (`g_szRookieMission`, `g_nRookieGameType`, and 12
|
||||
numeric params); registered as `gosScript_RegisterVariable` in `StartUp`/`ShutDown`;
|
||||
`CTCL_SetCDSP` reads the `[RookieMission]` page via `NotationFile` and populates them.
|
||||
Defaults: `"ScarabStronghold - Attrition"`, GameType=2 (Attrition), UnlimitedAmmo=1, all
|
||||
others zero. `g_nRookieTimeLimit=-1` means "use the server's current time setting".
|
||||
- `ConLobbyMission.script`: all hardcoded values in `MAIL_SET_ROOKIE_MISSION` handler replaced
|
||||
with `$$g_szRookieMission$$` / `$$g_nRookieXxx$$` references.
|
||||
- Requires rebuild: `MW4.exe` (Release + Profile).
|
||||
|
||||
### Mechlab turn rate label (5813aeb6, 2026-07-23)
|
||||
`StringResource.rc` `IDS_ML_CH_TURNRATE`: "Turn Rate (Degrees/Sec.):" →
|
||||
"Turn Rate (Top Speed Rad/Sec):" to match the actual `.data` field semantics
|
||||
(`TopSpeedTurnRate` is in rad/s at top speed, not deg/s).
|
||||
Requires rebuild: `ScriptStrings.dll`.
|
||||
|
||||
### BTFrstrm design documentation (840bc96c, 2026-07-23)
|
||||
Two Word documents added to `BTFrstrm/`:
|
||||
- `MechDependencyTree.docx` — dependency relationships between mech chassis/variants.
|
||||
- `Special_Zones.docx` — documentation of special zone types used in maps/missions.
|
||||
|
||||
### mech_loadouts.md: MechEditor data model (0344418a, 2026-07-23)
|
||||
`BTFrstrm/mech_loadouts.md` extended with a full reference section documenting the
|
||||
MechEditor web app (`/home/rich/Repositories/MechEditor/mech_editor.py`, localhost:8765):
|
||||
every `.data`/`.instance`/`.subsystems` field parsed, conversions performed (m/s ↔ kph,
|
||||
rad/s ↔ deg/s), and `hsh/` naming rules for MFD/Mechs/HUD/Radar images. Canonical
|
||||
reference for future mech data work.
|
||||
|
||||
## Next steps (proposed)
|
||||
- [x] ~~Windowed 3D viewport on Win11~~ — DONE via DDrawCompat (see STEP 8 viewport section).
|
||||
- [ ] (Optional) Curate remaining WIP content as features are exercised (editor loads dev `Content\`).
|
||||
|
||||
@@ -104,7 +104,7 @@ char *TimeToString( double secs )
|
||||
else
|
||||
if( secs*1000000.f >= 1.0f )
|
||||
{
|
||||
sprintf(TimeStr,"%.2f µS", secs*1000000.f);
|
||||
sprintf(TimeStr,"%.2f us", secs*1000000.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -24,9 +24,9 @@ const char *DivStrings[] =
|
||||
"1nS / div", // 10^-9
|
||||
"10nS / div", // 10^-8
|
||||
"100nS / div",
|
||||
"1µS / div",
|
||||
"10µS / div",
|
||||
"100µS / div",
|
||||
"1us / div",
|
||||
"10us / div",
|
||||
"100us / div",
|
||||
"1mS / div",
|
||||
"10mS / div",
|
||||
"100mS / div",
|
||||
|
||||
@@ -104,7 +104,7 @@ char *TimeToString( double secs )
|
||||
else
|
||||
if( secs*1000000.f >= 1.0f )
|
||||
{
|
||||
sprintf(TimeStr,"%.2f µS", secs*1000000.f);
|
||||
sprintf(TimeStr,"%.2f us", secs*1000000.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -24,9 +24,9 @@ const char *DivStrings[] =
|
||||
"1nS / div", // 10^-9
|
||||
"10nS / div", // 10^-8
|
||||
"100nS / div",
|
||||
"1µS / div",
|
||||
"10µS / div",
|
||||
"100µS / div",
|
||||
"1us / div",
|
||||
"10us / div",
|
||||
"100us / div",
|
||||
"1mS / div",
|
||||
"10mS / div",
|
||||
"100mS / div",
|
||||
|
||||
@@ -1032,19 +1032,19 @@ void __stdcall gos_SetViewport( DWORD LeftX, DWORD TopY, DWORD Width, DWORD Heig
|
||||
// You can only clear the backbuffer or Z buffer on the FIRST setup viewport (outside the Begin/End Scene
|
||||
//
|
||||
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
void __cdecl ClearTargetCameraBackBuffer()
|
||||
{
|
||||
D3DRECT rc={0,10,120,112};
|
||||
wClear(d3dDevice7,1,&rc,D3DCLEAR_TARGET,0xFF00FFFF,0,0);
|
||||
return ;
|
||||
}
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
void __stdcall gos_SetupViewport( bool FillZ, float ZBuffer, bool FillBG, DWORD BGColor, float top, float left, float bottom, float right, bool ClearStencil, DWORD StencilValue )
|
||||
{
|
||||
//상훈짱...
|
||||
//원래의 법칙에 어긋나는 행동이기 때문에 ASSERT를 무시한다.
|
||||
//sanghoon
|
||||
//This violates the normal rules, so we suppress the ASSERT.
|
||||
//gosASSERT( !InsideBeginScene || !(FillZ || FillBG) );
|
||||
//
|
||||
// Work out size of viewport
|
||||
|
||||
@@ -47,11 +47,11 @@ extern DWORD gDisableJoystick;
|
||||
bool DisablePolling=0;
|
||||
void CMRestoreEffects( int stick );
|
||||
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
int g_bUseOrgJoy = TRUE;
|
||||
void (__stdcall *g_pfnRIO_Joy)(DIJOYSTATE& js) = NULL; // Check out Test ..
|
||||
bool g_bNoWeaponRangeCheck = false;
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
//
|
||||
//
|
||||
// Initialize the DirectInput devices
|
||||
@@ -479,7 +479,7 @@ extern DWORD EnableDisplayInfo;
|
||||
|
||||
if( EnableDisplayInfo==0 ) {
|
||||
disp:
|
||||
sprintf(DisplayInfoText, "COIN: %d 코인이래요", g_nCoinCount);
|
||||
sprintf(DisplayInfoText, "COIN: %d coins", g_nCoinCount);
|
||||
EnableDisplayInfo = 1;
|
||||
} else if (EnableDisplayInfo==2) {
|
||||
if( timeGetTime() < EndDisplayInfoTime+50 ) {
|
||||
|
||||
@@ -100,11 +100,11 @@ IDirectDraw7* DDobject = NULL; // Primiary DirectDraw object (for persistant
|
||||
IDirectDraw7* CurrentDDobject = NULL; // DirectDraw object for rendering (can be the same as DDObject)
|
||||
IDirectDrawSurface7* ZBufferSurface = NULL; // ZBuffer surface
|
||||
IDirectDrawSurface7* RefZBufferSurface = NULL; // Referemce rasterizer ZBuffer surface
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
IDirectDrawSurface7* SH_TargetBufferSurface = NULL;
|
||||
IDirectDrawSurface7* SH_SwirlTexture= NULL;
|
||||
IDirectDrawSurface7* SH_GameEndTexture= NULL;
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
|
||||
DDSURFACEDESC2 BackBufferddsd;
|
||||
//
|
||||
@@ -167,7 +167,7 @@ float GammaSetting=0.0;
|
||||
bool UseGammaCorrection=0;
|
||||
float UserGamma=1.0f;
|
||||
|
||||
//����¯-begin
|
||||
//sanghoon begin
|
||||
bool use_shgui = false;
|
||||
bool hsh_initialized=false;
|
||||
bool hsh_mrdev_initialized=false;
|
||||
@@ -176,7 +176,7 @@ bool hsh_mrdev_initialized=false;
|
||||
#include "coord.cpp"
|
||||
//#include "hsh_dxras.cpp"
|
||||
#include "render.hpp"
|
||||
//����¯-end
|
||||
//sanghoon end
|
||||
|
||||
//
|
||||
// Value range 0-10,000, default 750 (See DirectX docs)
|
||||
@@ -1021,11 +1021,11 @@ void EnterFullScreenMode()
|
||||
//
|
||||
|
||||
#ifdef LAB_ONLY
|
||||
//����¯
|
||||
//sanghoon
|
||||
wSetCooperativeLevel( CurrentDDobject, hWindow, DDSCL_SETFOCUSWINDOW );
|
||||
wSetCooperativeLevel( CurrentDDobject, hWindow, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
|
||||
#else
|
||||
//����¯
|
||||
//sanghoon
|
||||
wSetCooperativeLevel( CurrentDDobject, hWindow, DDSCL_SETFOCUSWINDOW );
|
||||
wSetCooperativeLevel( CurrentDDobject, hWindow, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
|
||||
#endif
|
||||
@@ -1127,11 +1127,11 @@ void EnterFullScreenMode()
|
||||
}
|
||||
}
|
||||
|
||||
//����¯-begin
|
||||
//sanghoon begin
|
||||
if(use_shgui){
|
||||
HSH_EnterFullScreen2();
|
||||
}
|
||||
//����¯-end
|
||||
//sanghoon end
|
||||
|
||||
//
|
||||
// Changed modes, create all the surfaces
|
||||
@@ -1164,7 +1164,7 @@ void EnterFullScreenMode()
|
||||
// Debugging information
|
||||
//
|
||||
SPEW(( GROUP_DIRECTDRAW, "EnterFullScreenMode() Finished" ));
|
||||
//����
|
||||
//sanghoon
|
||||
}
|
||||
|
||||
|
||||
@@ -1289,7 +1289,7 @@ void DisplayBackBuffer()
|
||||
else
|
||||
{
|
||||
#if 0
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
extern bool sh_game_started;
|
||||
static FILE* fp=0;
|
||||
static recorded_count=0;
|
||||
@@ -1352,11 +1352,11 @@ extern bool sh_game_started;
|
||||
pp=(double*)malloc(800*600*2);
|
||||
}
|
||||
}
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
#endif
|
||||
wFlip( FrontBufferSurface,NULL,DDFLIP_DONOTWAIT );//|DDFLIP_INTERVAL2 );
|
||||
//���� ��ħ..
|
||||
//����
|
||||
//sanghoon marker..
|
||||
//sanghoon
|
||||
//wFlip( FrontBufferSurface,NULL,DDFLIP_WAIT );
|
||||
}
|
||||
}
|
||||
@@ -1403,11 +1403,11 @@ extern bool sh_game_started;
|
||||
//
|
||||
void DirectDrawRelease()
|
||||
{
|
||||
//����¯-begin
|
||||
//sanghoon begin
|
||||
if(use_shgui){
|
||||
HSH_DirectDrawRelease2();
|
||||
}
|
||||
//����¯-end
|
||||
//sanghoon end
|
||||
|
||||
SPEW(( GROUP_DIRECTDRAW, "DirectDrawRelease()" ));
|
||||
SafeFPU();
|
||||
@@ -1496,7 +1496,7 @@ void DirectDrawRelease()
|
||||
wRelease( ZBufferSurface );
|
||||
ZBufferSurface=0;
|
||||
}
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
//DirectDrawRelease
|
||||
if( SH_TargetBufferSurface)
|
||||
{
|
||||
@@ -1513,7 +1513,7 @@ void DirectDrawRelease()
|
||||
wRelease( SH_GameEndTexture );
|
||||
SH_GameEndTexture=0;
|
||||
}
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
if( GammaControlInterface )
|
||||
{
|
||||
wRelease( GammaControlInterface );
|
||||
@@ -1593,20 +1593,20 @@ void DirectDrawCreateDDObject()
|
||||
//
|
||||
// Create the NULL (primary) DirectDraw object
|
||||
//
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
/*
|
||||
wDirectDrawCreateEx( &DeviceArray[0].DeviceGUID, (void**)&DDobject, IID_IDirectDraw7, NULL );
|
||||
// wDirectDrawCreateEx( &DeviceArray[Environment.FullScreenDevice].DeviceGUID, (void**)&DDobject, IID_IDirectDraw7, NULL );
|
||||
wSetCooperativeLevel( DDobject, hWindow, DDSCL_NORMAL );
|
||||
CurrentDDobject=DDobject;
|
||||
*/
|
||||
//���� �ҽ�..
|
||||
//sanghoon ..
|
||||
//wDirectDrawCreateEx(&DeviceArray[0].DeviceGUID, (void**)&DDobject, IID_IDirectDraw7, NULL );
|
||||
wDirectDrawCreateEx(NULL, (void**)&DDobject, IID_IDirectDraw7, NULL );
|
||||
|
||||
wSetCooperativeLevel( DDobject, hWindow, DDSCL_NORMAL );
|
||||
CurrentDDobject=DDobject;
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
//
|
||||
//
|
||||
//
|
||||
@@ -1630,11 +1630,11 @@ bool SetupMode( bool FullScreen, DWORD Renderer )
|
||||
BackBufferSurface=0;
|
||||
ClipperObject=0;
|
||||
ZBufferSurface=0;
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
SH_TargetBufferSurface = 0;
|
||||
SH_SwirlTexture=0;
|
||||
SH_GameEndTexture=0;
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
Maind3dDevice7=0;
|
||||
d3dDevice7=0;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
@@ -1993,7 +1993,7 @@ bool SetupMode( bool FullScreen, DWORD Renderer )
|
||||
}
|
||||
wAddAttachedSurface( BackBufferSurface, ZBufferSurface );
|
||||
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
{
|
||||
DDSURFACEDESC2 rdesc;
|
||||
memset(&rdesc,0,sizeof(ddsd));
|
||||
@@ -2019,7 +2019,7 @@ bool SetupMode( bool FullScreen, DWORD Renderer )
|
||||
|
||||
if(SUCCEEDED(wCreateSurface( CurrentDDobject, &rdesc, &SH_SwirlTexture, NULL ))){
|
||||
;
|
||||
//ȭ�鿡 �ؽ��� ������ ����.
|
||||
//Draw texture content to screen. .
|
||||
}
|
||||
|
||||
rdesc.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE;
|
||||
@@ -2031,11 +2031,11 @@ bool SetupMode( bool FullScreen, DWORD Renderer )
|
||||
|
||||
if(SUCCEEDED(wCreateSurface( CurrentDDobject, &rdesc, &SH_GameEndTexture, NULL ))){
|
||||
;
|
||||
//ȭ�鿡 �ؽ��� ������ ����.
|
||||
//Draw texture content to screen. .
|
||||
}
|
||||
|
||||
}
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
//
|
||||
// Get the Z buffer pixel format (nVidia may always match front bit depth)
|
||||
//
|
||||
@@ -2258,7 +2258,7 @@ Failed:
|
||||
wRelease( ZBufferSurface );
|
||||
ZBufferSurface=0;
|
||||
}
|
||||
//����
|
||||
//sanghoon
|
||||
//SetupMode
|
||||
if( SH_TargetBufferSurface)
|
||||
{
|
||||
@@ -2275,7 +2275,7 @@ Failed:
|
||||
wRelease( SH_SwirlTexture );
|
||||
SH_SwirlTexture=0;
|
||||
}
|
||||
//����
|
||||
//sanghoon
|
||||
if( ClipperObject )
|
||||
{
|
||||
if( FrontBufferSurface )
|
||||
@@ -2578,7 +2578,7 @@ void DirectDrawCreateAllBuffers()
|
||||
wRelease( ZBufferSurface );
|
||||
ZBufferSurface=0;
|
||||
}
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
//DirectDrawCreateAllBuffers
|
||||
if( SH_TargetBufferSurface)
|
||||
{
|
||||
@@ -2595,7 +2595,7 @@ void DirectDrawCreateAllBuffers()
|
||||
wRelease( SH_SwirlTexture );
|
||||
SH_SwirlTexture=0;
|
||||
}
|
||||
//���� ��
|
||||
//sanghoon marker
|
||||
if( ClipperObject )
|
||||
{
|
||||
if( FrontBufferSurface )
|
||||
|
||||
@@ -161,7 +161,7 @@ HRESULT wEndScene( IDirect3DDevice7* d3dDevice7 )
|
||||
|
||||
//Original
|
||||
//if( FAILED(result) )
|
||||
//상훈
|
||||
//sanghoon
|
||||
if( FAILED(result) && result!=DDERR_SURFACELOST)
|
||||
PAUSE(( "FAILED (0x%x - %s) - EndScene()",result,ErrorNumberToMessage(result)));
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@ videoDevices BufferedDevices[8];
|
||||
int g_nDualHead = -1; // jcem
|
||||
int g_nDualHead2 = -1; // jcem
|
||||
int g_nNonDualHead = -1; // jcem
|
||||
int g_nMFD1 = -1; // mode 4: left 640x480 MFD monitor
|
||||
int g_nMFD2 = -1; // mode 4: right 640x480 MFD monitor
|
||||
// MSL 5.03 Mechview
|
||||
int g_nMechViewType; // jcem : 0 - no mechview, 1 - on radar screen, 2 - on main screen
|
||||
|
||||
@@ -380,6 +382,20 @@ void FindVideoCards()
|
||||
}
|
||||
}
|
||||
}
|
||||
// Mode 4 (split dual 640x480): find two extra D3D devices beyond
|
||||
// FullScreenDevice and g_nNonDualHead. These need no special resolution.
|
||||
{
|
||||
int found = 0;
|
||||
for (int t0 = 0; t0 < NumDevices && found < 2; t0++) {
|
||||
if (t0 == Environment.FullScreenDevice) continue;
|
||||
if (t0 == g_nNonDualHead) continue;
|
||||
if (DeviceArray[t0].D3DCaps.dwDevCaps & D3DDEVCAPS_HWRASTERIZATION) {
|
||||
if (found == 0) g_nMFD1 = t0;
|
||||
else g_nMFD2 = t0;
|
||||
found++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// jcem
|
||||
//
|
||||
// Check any known video cards have up to date drivers (Only on Windows9x)
|
||||
|
||||
@@ -834,11 +834,11 @@ __int64 ProfileRenderEnd( __int64 RenderTime )
|
||||
}
|
||||
|
||||
|
||||
//상훈짱 begin
|
||||
//sanghoon begin
|
||||
#include "render.hpp"
|
||||
HRESULT App_Render( LPDIRECT3DDEVICE7 pd3dDevice,LPDIRECTDRAWSURFACE7 pddsTexture);
|
||||
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
|
||||
|
||||
//
|
||||
@@ -915,8 +915,8 @@ void gos_UpdateDisplay( bool Everything )
|
||||
ProfileTime( TimeClearViewPort, gos_SetupViewport( 0, 0, 1, 0x303050 , 0.0, 0.0, 1.0, 1.0 ) );
|
||||
TimeInClearViewPort+=TimeClearViewPort;
|
||||
}
|
||||
//상훈짱 begin
|
||||
//backbuffer에 Background Image를 그린다...
|
||||
//sanghoon begin
|
||||
//Draw background image to backbuffer...
|
||||
|
||||
if(hsh_initialized){
|
||||
// 0 - no MFDs, 1 - orginal(5+1=dual & single), 2 - B&W(3 + 1=1 dual), 3 - color(3 + 1=2 dual)
|
||||
@@ -940,13 +940,25 @@ void gos_UpdateDisplay( bool Everything )
|
||||
radar_device.BeginScene();
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
// Step 0: clear + grid for radar and LEFT MFD.
|
||||
// Step 1: clear + grid for RIGHT MFD (staggered so the right
|
||||
// flip at new sh_step==1 shows channels 3-4 from the previous
|
||||
// cycle, not a freshly-cleared buffer).
|
||||
if(sh_step==0){
|
||||
radar_device.BeginScene();
|
||||
mfd_device.BeginScene(); // left device only
|
||||
} else if(sh_step==1) {
|
||||
mfd_device.BeginSceneRight(); // right device clear + grid
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else if(hsh_mrdev_initialized){
|
||||
mr_device.BeginScene();
|
||||
}
|
||||
|
||||
//HSH_RenderAux1SmallMech();
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
if (g_pfnCTCL_AfterBeginScene) {
|
||||
(*g_pfnCTCL_AfterBeginScene)();
|
||||
}
|
||||
@@ -1043,7 +1055,7 @@ void gos_UpdateDisplay( bool Everything )
|
||||
LOG_BLOCK("Gos::UpdateDebugger()");
|
||||
ProfileTime( TimeDebugger, UpdateDebugger() );
|
||||
}
|
||||
//상훈..
|
||||
//sanghoon
|
||||
#if 1
|
||||
extern LPDIRECT3DDEVICE7 d3dDevice7;
|
||||
static bool preload_GameEndScreem=true;;
|
||||
@@ -1077,8 +1089,8 @@ void gos_UpdateDisplay( bool Everything )
|
||||
//
|
||||
// Flip or Blit the current image onto the display
|
||||
//
|
||||
//상훈 앞
|
||||
//Flip을 한다.
|
||||
//sanghoon begin
|
||||
//Perform the Flip.
|
||||
if(hsh_initialized){
|
||||
// 0 - no MFDs, 1 - orginal(5+1=dual & single), 2 - B&W(3 + 1=1 dual), 3 - color(3 + 1=2 dual)
|
||||
switch(g_nTypeOfMFDs) {
|
||||
@@ -1106,13 +1118,32 @@ void gos_UpdateDisplay( bool Everything )
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
// 7-step cadence. Radar + left MFD flip on step 0 (same as mode 1).
|
||||
// Right MFD flip is staggered to step 1 so that three back-to-back
|
||||
// DGVoodoo2 Present() calls don't all land in the same frame and
|
||||
// cause rhythmic stutter on the main display.
|
||||
// Right device finishes rendering at step 6 (channel 4), so
|
||||
// flipping at step 1 is still correct timing.
|
||||
sh_step++;
|
||||
sh_step%=7;
|
||||
if(sh_step==0) {
|
||||
radar_device.EndScene();
|
||||
radar_device.pDDSFront->Flip(0,DDFLIP_DONOTWAIT|DDFLIP_NOVSYNC);
|
||||
mfd_device.EndScene();
|
||||
mfd_device.pDDSFront->Flip(0,DDFLIP_DONOTWAIT|DDFLIP_NOVSYNC);
|
||||
} else if(sh_step==1) {
|
||||
if (mfd_device_right.pDDSFront)
|
||||
mfd_device_right.pDDSFront->Flip(0,DDFLIP_DONOTWAIT|DDFLIP_NOVSYNC);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}else if(hsh_mrdev_initialized){
|
||||
mr_device.EndScene();
|
||||
mr_device.pDDSFront->Flip(0,DDFLIP_DONOTWAIT|DDFLIP_NOVSYNC);
|
||||
}
|
||||
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
{
|
||||
LOG_BLOCK("Gos::DisplayBackBuffer()");
|
||||
ProfileTime( TimeDisplay, DisplayBackBuffer() );
|
||||
|
||||
@@ -44,9 +44,9 @@ extern DWORD gNumLockMode;
|
||||
extern DWORD gCapLockMode;
|
||||
extern DWORD gScrollLockMode;
|
||||
|
||||
// úè - start
|
||||
// hyun begin
|
||||
void (__stdcall *g_pfnRIO_ButtonEvent)(BYTE* by) = NULL;
|
||||
// úè - end
|
||||
// hyun end
|
||||
//
|
||||
|
||||
//
|
||||
@@ -106,14 +106,14 @@ LRESULT CALLBACK GameOSWinProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
|
||||
switch( uMsg )
|
||||
{
|
||||
// úè
|
||||
// hyun
|
||||
case WM_USER + 100:
|
||||
{
|
||||
// úè - start
|
||||
// hyun begin
|
||||
if (g_pfnRIO_ButtonEvent) {
|
||||
(*g_pfnRIO_ButtonEvent)((BYTE*)&lParam);
|
||||
}
|
||||
// úè - end
|
||||
// hyun end
|
||||
}
|
||||
break;
|
||||
//
|
||||
|
||||
@@ -163,13 +163,13 @@ static bool IsValidAlphaPair( DIBSECTION& dib,DIBSECTION& diba)
|
||||
|
||||
if(dib.dsBmih.biHeight<0 || diba.dsBmih.biHeight<0)return false;
|
||||
|
||||
//픽셀 포맷을 일단 만족하는가?
|
||||
//Does it satisfy the pixel format requirement?
|
||||
if(!(bm.bmBitsPixel==24 && bma.bmBitsPixel==8))return false;
|
||||
|
||||
//비트맵의 크기가 X,Y모두 2의 지수승인가?
|
||||
//Are the bitmap dimensions (X,Y) both powers of 2?
|
||||
if(!(IsTextureDimension(w) && IsTextureDimension(h)))return false;
|
||||
|
||||
//RGB와 A비트맵의 크기가 같은가?
|
||||
//Are RGB and Alpha bitmaps the same size?
|
||||
if(bma.bmWidth!=w || bma.bmHeight!=h)return NULL;
|
||||
|
||||
return true;
|
||||
@@ -408,7 +408,7 @@ bool __cdecl DrawBitmapToSurface(LPDIRECTDRAWSURFACE7 pddsTexture,int x,int y,co
|
||||
|
||||
|
||||
|
||||
//8Bit Bitmap으로부터.. Alpha를 가진 텍스쳐를 만든다.
|
||||
//Create texture with Alpha from 8-bit Bitmap..
|
||||
static LPDIRECTDRAWSURFACE7 CreateATextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP hbm )
|
||||
{
|
||||
BITMAP bm={0,};
|
||||
@@ -442,7 +442,7 @@ static LPDIRECTDRAWSURFACE7 CreateATextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP h
|
||||
|
||||
LPDIRECTDRAWSURFACE7 CreateATextureFromFile(LPDIRECTDRAW7 pDD, CHAR* strName )
|
||||
{
|
||||
//ClipBoard.에 텍스트 내용을 복사한다...
|
||||
//Copy text content to Clipboard...
|
||||
/*
|
||||
OpenClipboard(hWindow);
|
||||
HGLOBAL h=GlobalAlloc(GMEM_MOVEABLE,512);
|
||||
@@ -531,7 +531,7 @@ bool CHSH_Device::InitFirst(int devicenum,DWORD resx,DWORD resy, CHSH_Device* pO
|
||||
pDD = pOtherHSHD->pDD;
|
||||
} else {
|
||||
HRESULT hr;
|
||||
//1. 해상도 변경.
|
||||
//1. Resolution change.
|
||||
wDirectDrawCreateEx( &DeviceArray[devicenum].DeviceGUID , (VOID**) &(pDD), IID_IDirectDraw7, NULL );
|
||||
pDD->SetCooperativeLevel(hWindow, dwFlags );
|
||||
hr=pDD->SetDisplayMode( resx, resy, 16, 60, 0 );
|
||||
@@ -846,10 +846,10 @@ void CHSH_Device::DrawThickFrameList(int framecount,RECT* prc,int t,DWORD dwColo
|
||||
}
|
||||
|
||||
|
||||
//texture 좌표.. u1,v1,u2,v2
|
||||
//texture 회전축 tx,ty
|
||||
//screen 회전축 x,y
|
||||
//회전각 e
|
||||
//Texture coordinates.. u1,v1,u2,v2
|
||||
//Texture rotation axis tx,ty
|
||||
//Screen rotation axis x,y
|
||||
//Rotation angle e
|
||||
|
||||
void CHSH_Device::DrawTextureRotate(float u1,float v1,float u2,float v2,float tx,float ty,float x,float y,float e,DWORD color)
|
||||
{
|
||||
@@ -858,9 +858,9 @@ void CHSH_Device::DrawTextureRotate(float u1,float v1,float u2,float v2,float tx
|
||||
float U2=u2-tx;
|
||||
float V2=v2-ty;
|
||||
|
||||
//(U1,V1),(U2,V1),(U1,V2),(U2,V2)네쌍을 회전변환 시킨다.
|
||||
//(U1,V1),(U2,V1),(U1,V2),(U2,V2) four pairs are rotation-transformed.
|
||||
//pt[0][0]....
|
||||
//거기에.. 각 축에..x,y를 더해준다.
|
||||
//Add x,y to each axis.
|
||||
float cose=cosf(e);
|
||||
float cos_u1=cose*U1;
|
||||
float cos_u2=cose*U2;
|
||||
@@ -883,11 +883,11 @@ void CHSH_Device::DrawTextureRotate(float u1,float v1,float u2,float v2,float tx
|
||||
pt[3][1] = sin_u2+cos_v2+y;
|
||||
|
||||
//HSH_Draw3DTexture2(0,pt,0xFF00FF00,u1, v1/256.0f, u2/256.0f, v2/256.0f);
|
||||
//거기에다가 모두 x,y를 다시 이동 시킨다.
|
||||
//Then translate all by x,y again.
|
||||
DrawTexture(pt,color,u1,v1,u2,v2);
|
||||
}
|
||||
|
||||
//임의로 스케일된다. x1,y1,x2,y2
|
||||
//Scaled arbitrarily. x1,y1,x2,y2
|
||||
void CHSH_Device::DrawTexture(float x1,float y1,float x2,float y2,DWORD dwColor, float u1,float v1,float u2,float v2)
|
||||
{
|
||||
|
||||
@@ -900,7 +900,7 @@ void CHSH_Device::DrawTexture(float x1,float y1,float x2,float y2,DWORD dwColor,
|
||||
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX ,v,4,0 );
|
||||
}
|
||||
|
||||
//임의로 스케일된다. x,y,width,height
|
||||
//Scaled arbitrarily. x,y,width,height
|
||||
void CHSH_Device::DrawTexture2(float x,float y,float w,float h,DWORD dwColor, float u1,float v1,float u2,float v2)
|
||||
{
|
||||
|
||||
@@ -914,7 +914,7 @@ void CHSH_Device::DrawTexture2(float x,float y,float w,float h,DWORD dwColor, fl
|
||||
}
|
||||
|
||||
|
||||
//스케일 되지 않는....
|
||||
//Not scaled....
|
||||
void CHSH_Device::DrawTexture(float x,float y,DWORD dwColor, float u1,float v1,float u2,float v2)
|
||||
{
|
||||
D3DTLVERTEX v[4];
|
||||
@@ -945,6 +945,8 @@ void CHSH_Device::DrawTexture(float pt[4][2],DWORD dwColor,float tx1,float ty1,f
|
||||
|
||||
extern int g_nDualHead;
|
||||
extern int g_nNonDualHead;
|
||||
extern int g_nMFD1; // mode 4: left 640x480 MFD monitor
|
||||
extern int g_nMFD2; // mode 4: right 640x480 MFD monitor
|
||||
// MSL 5.03 Mechview
|
||||
extern int g_nMechViewType; // jcem : 0 - no mechview, 1 - on radar screen, 2 - on main screen
|
||||
|
||||
@@ -976,11 +978,11 @@ bool CMR_Device::InitFirst()
|
||||
bool CMR_Device::InitSecond()
|
||||
{
|
||||
map_loaded=false;
|
||||
CHSH_Device::InitSecond(0,0); // no off screen - Target Texture를 그리지 않는다.
|
||||
CHSH_Device::InitSecond(0,0); // no off screen - do not create Target Texture.
|
||||
|
||||
char temppath[MAX_PATH],temppatha[MAX_PATH];
|
||||
|
||||
//1. 백그라운드이미지용 Surface
|
||||
//1. Surface for background image
|
||||
sprintf(temppath,"%s\\hsh\\%s",AssetsDirectory1,"mr_background.bmp");
|
||||
pDDSBackground=CreateSurfaceFromFile(pDD,temppath);
|
||||
|
||||
@@ -988,12 +990,12 @@ bool CMR_Device::InitSecond()
|
||||
MessageBeep(0);
|
||||
}
|
||||
|
||||
//2. 범용 텍스쳐
|
||||
//2. General-purpose texture
|
||||
sprintf(temppath,"%s\\hsh\\%s",AssetsDirectory1,"mr_texture.bmp");
|
||||
sprintf(temppatha,"%s\\hsh\\%s",AssetsDirectory1,"mr_texturea.bmp");
|
||||
pDDSTexture=CreateRGBATextureFromFile(pDD, temppath,temppatha,16);
|
||||
|
||||
//3. 맵용 텍스쳐..
|
||||
//3. Texture for map..
|
||||
pDDSMapTexture=CreatePixelFormatTexture(pDD,256,256,&DDPF_R5G6B5);
|
||||
|
||||
tw=256;
|
||||
@@ -1006,17 +1008,17 @@ bool CMR_Device::InitSecond()
|
||||
|
||||
bool CMR_Device::BeginScene()
|
||||
{
|
||||
//Render Target을 설정한다.
|
||||
//Set the Render Target.
|
||||
//SetRenderTargetTexture();
|
||||
|
||||
|
||||
//Texture에.. background image를 그린다. 일종의 Clear대신이다..
|
||||
//Draw background image to Texture. Used as a substitute for Clear..
|
||||
if(sh_game_started){
|
||||
//게임이 시작되었을때만 백그라운드를 그린다.
|
||||
//Draw background only when game has started.
|
||||
RECT rc={0,0,640,480};
|
||||
pDDSBack->BltFast(0,0,pDDSBackground,&rc,0);
|
||||
}else{
|
||||
//게임이 시작되지 않았으면.. blank를 보여준다.
|
||||
//If game has not started.. show blank.
|
||||
pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET ,0,1.0f,0);
|
||||
}
|
||||
|
||||
@@ -1066,6 +1068,23 @@ bool CMR_Device::LoadMRTargetTexture(const char *mechtexturename)
|
||||
|
||||
CMR_Device mr_device;
|
||||
|
||||
// Mode 4: the right-hand 640x480 MFD device. Shares VRAM with mfd_device
|
||||
// (same GPU), so mfd_device's pDDSTarget texture can be passed to this
|
||||
// device's pD3DDevice->SetTexture without a copy.
|
||||
CMFDRight_Device mfd_device_right;
|
||||
|
||||
bool CMFDRight_Device::InitFirst()
|
||||
{
|
||||
// Take over g_nMFD2 monitor at 640x480 fullscreen.
|
||||
return CHSH_Device::InitFirst(g_nMFD2, 640, 480);
|
||||
}
|
||||
|
||||
bool CMFDRight_Device::InitSecond()
|
||||
{
|
||||
// Create flip chain, D3D device and a render-target slot (1024x512).
|
||||
return CHSH_Device::InitSecond(1024, 512);
|
||||
}
|
||||
|
||||
/////////////////////////////////// CRadar_Device ///////////////////////////////////
|
||||
const char g_szRadarShutdown[] = "SHUT\nDOWN";
|
||||
const char g_szRadarStartup[] = "START\nUP";
|
||||
@@ -1152,18 +1171,18 @@ bool CRadar_Device::InitSecond()
|
||||
|
||||
bool CRadar_Device::BeginScene()
|
||||
{
|
||||
//Render Target을 설정한다.
|
||||
//Set the Render Target.
|
||||
SetRenderTargetTexture();
|
||||
|
||||
|
||||
//Texture에.. background image를 그린다. 일종의 Clear대신이다..
|
||||
//Draw background image to Texture. Used as a substitute for Clear..
|
||||
if(sh_game_started){
|
||||
//게임이 시작되었을때만 백그라운드를 그린다.
|
||||
//Draw background only when game has started.
|
||||
RECT rc={0,0,480,640};
|
||||
pDDSTarget->BltFast(0,0,pDDSBackground,&rc,0);
|
||||
if(IsMechShutdown())
|
||||
{
|
||||
//지도 영역을 지운다.
|
||||
//Clear map area.
|
||||
RECT rc={140,407,340,607};
|
||||
|
||||
DDBLTFX fx={0,};
|
||||
@@ -1173,15 +1192,15 @@ bool CRadar_Device::BeginScene()
|
||||
pDDSTarget->Blt(&rc,NULL,NULL,DDBLT_COLORFILL ,&fx);
|
||||
}
|
||||
}else{
|
||||
//게임이 시작되지 않았으면.. blank를 보여준다.
|
||||
//If game has not started.. show blank.
|
||||
pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET ,0,1.0f,0);
|
||||
}
|
||||
pD3DDevice->BeginScene();
|
||||
if(sh_game_started && IsMechShutdown()){
|
||||
//shut down button을 그린다.
|
||||
//Draw shutdown button.
|
||||
int state[12]={0,2,0,};
|
||||
state[3]=recent_state[3];//flush state는.. 최근 값을 가져다 쓴다.
|
||||
state[11]=recent_state[11];//flush state는.. 최근 값을 가져다 쓴다.
|
||||
state[3]=recent_state[3];//flush state: use the most recent value.
|
||||
state[11]=recent_state[11];//flush state: use the most recent value.
|
||||
if (!g_aaRadarText[0][0])
|
||||
strcpy(&g_aaRadarText[0][0], g_szRadarJumpjet);
|
||||
strcpy(&g_aaRadarText[1][0], g_szRadarStartup);
|
||||
@@ -1275,7 +1294,7 @@ POINTF radar_text_pos[12]={
|
||||
//state 1:ready
|
||||
//state 2:activated
|
||||
|
||||
//pilot mode에서는 다른 의미를 갖는다.
|
||||
//Has a different meaning in pilot mode.
|
||||
|
||||
bool CRadar_Device::DrawBackText(int state[12])
|
||||
{
|
||||
@@ -1349,7 +1368,7 @@ static DWORD channel_color[6]={
|
||||
|
||||
|
||||
CMFD_Device::CMFD_Device()
|
||||
: ch((DWORD)-1)
|
||||
: ch((DWORD)-1), m_pRightDevice(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1359,6 +1378,15 @@ CMFD_Device::~CMFD_Device()
|
||||
|
||||
bool CMFD_Device::InitFirst()
|
||||
{
|
||||
// Mode 4: use g_nMFD1 (640x480) for left panel; also start up the right
|
||||
// device here so both displays are ready before InitSecond runs.
|
||||
if (g_nTypeOfMFDs == 4) {
|
||||
m_pRightDevice = &mfd_device_right;
|
||||
CHSH_Device::InitFirst(g_nMFD1, 640, 480); // left device
|
||||
mfd_device_right.InitFirst(); // right device display mode
|
||||
return true;
|
||||
}
|
||||
m_pRightDevice = NULL;
|
||||
return CHSH_Device::InitFirst(g_nDualHead,1280,480);
|
||||
}
|
||||
|
||||
@@ -1366,12 +1394,12 @@ bool CMFD_Device::InitSecond()
|
||||
{
|
||||
CHSH_Device::InitSecond(1024,512); // 640 x 480
|
||||
if(g_f3dtarget){
|
||||
pDDSMechTexture=CreatePixelFormatTexture(pDD,128,128,&DDPF_R5G6B5);//3D메크 이미지 저장하기 위한 텍스쳐...
|
||||
pDDSMechTexture=CreatePixelFormatTexture(pDD,128,128,&DDPF_R5G6B5);//Texture for storing 3D mech image...
|
||||
}else{
|
||||
// MSL 5.02 Target MFD Image
|
||||
// pDDSMechTexture=CreatePixelFormatTexture(pDD,512,512,&DDPF_R5G6B5);//2D메크 이미지 저장하기 위한 텍스쳐...
|
||||
pDDSMechTexture=CreatePixelFormatTexture(pDD,1024,1024,&DDPF_R5G6B5);//2D메크 이미지 저장하기 위한 텍스쳐...
|
||||
//모든 메크의 이미지를 저장한다.
|
||||
// pDDSMechTexture=CreatePixelFormatTexture(pDD,512,512,&DDPF_R5G6B5);//texture for storing 2D mech image...
|
||||
pDDSMechTexture=CreatePixelFormatTexture(pDD,1024,1024,&DDPF_R5G6B5);//Texture for storing 2D mech image...
|
||||
//Store images for all mechs.
|
||||
for(int mech=0;mech<ARRAYSIZE(mechnames);mech++){
|
||||
// MSL 5.02 Target MFD Image
|
||||
// int x=(mech%4)*128;
|
||||
@@ -1387,8 +1415,8 @@ bool CMFD_Device::InitSecond()
|
||||
}
|
||||
//if(pDDSMechTexture==NULL)MessageBeep(0);
|
||||
//pDDSMechTexture=0;
|
||||
//pDDSDamageTexture=CreatePixelFormatTexture(pDD,512,512,&DDPF_R4G4B4A4);//데미지.. 이미지를..
|
||||
pDDSDamageTexture=0;//Reset할때.. 새로이 만든다... 지금은 굳이 만들 필요 없다.
|
||||
//pDDSDamageTexture=CreatePixelFormatTexture(pDD,512,512,&DDPF_R4G4B4A4);//damage image..
|
||||
pDDSDamageTexture=0;//On Reset: recreated... no need to create now.
|
||||
// MSL 5.03 Target Damage Display
|
||||
pDDSTargetTexture=0;
|
||||
|
||||
@@ -1409,6 +1437,11 @@ bool CMFD_Device::InitSecond()
|
||||
pD3DDevice->SetMaterial( &mtrl );
|
||||
pD3DDevice->SetRenderState( D3DRENDERSTATE_AMBIENT, 0xffffffff );
|
||||
|
||||
// Mode 4: create flip chain + D3D device for the right 640x480 monitor.
|
||||
if (g_nTypeOfMFDs == 4 && m_pRightDevice) {
|
||||
mfd_device_right.InitSecond();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1450,10 +1483,15 @@ bool CMFD_Device::BeginChannel(DWORD channel)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
// Same 7-step timing as mode 1: channels 0-4 map to sh_step 2-6.
|
||||
if (sh_step != (int)(channel + 2))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
ch=channel;
|
||||
|
||||
//Render Target을 설정한다.
|
||||
//Set the Render Target.
|
||||
SetRenderTargetTexture();
|
||||
pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET ,0,0,0);
|
||||
pD3DDevice->BeginScene();
|
||||
@@ -1475,8 +1513,42 @@ bool CMFD_Device::EndChannel()
|
||||
gCaptureScreen = 0;
|
||||
}
|
||||
|
||||
SetRenderTargetBackbuffer();
|
||||
pD3DDevice->BeginScene();
|
||||
// Mode 4: route this channel's blit to the correct physical monitor.
|
||||
// Handled here, before the modes 1-3 SetRenderTargetBackbuffer/BeginScene
|
||||
// block, so each path has exactly one matched Begin/EndScene pair.
|
||||
// Channels 0-2 go to the LEFT device (this, g_nMFD1).
|
||||
// Channels 3-4 go to the RIGHT device (m_pRightDevice, g_nMFD2).
|
||||
// pDDSTarget was created by this device's pDD; both devices are on the
|
||||
// same GPU so VRAM textures are mutually accessible.
|
||||
if (g_nTypeOfMFDs == 4 && m_pRightDevice) {
|
||||
CHSH_Device* target = (ch >= 3) ? m_pRightDevice : static_cast<CHSH_Device*>(this);
|
||||
target->SetRenderTargetBackbuffer();
|
||||
target->pD3DDevice->BeginScene();
|
||||
|
||||
target->pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,TRUE);
|
||||
target->pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_ONE);
|
||||
target->pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_ONE);
|
||||
|
||||
target->pD3DDevice->SetTexture(0, pDDSTarget);
|
||||
|
||||
DWORD color4 = channel_color[ch];
|
||||
float w4 = (float)target->size_back.cx; // 640
|
||||
float h4 = (float)target->size_back.cy; // 480
|
||||
float w2_4 = (float)size_target.cx; // 1024
|
||||
float h2_4 = (float)size_target.cy; // 512
|
||||
D3DTLVERTEX V4[4];
|
||||
V4[0]=D3DTLVERTEX(D3DVECTOR( -0.5f,h4-0.5f,0.9f),1.0f,color4,0, 0/w2_4,h4/h2_4);
|
||||
V4[1]=D3DTLVERTEX(D3DVECTOR( -0.5f, -0.5f,0.9f),1.0f,color4,0, 0/w2_4, 0/h2_4);
|
||||
V4[2]=D3DTLVERTEX(D3DVECTOR(w4-0.5f,h4-0.5f,0.9f),1.0f,color4,0,w4/w2_4,h4/h2_4);
|
||||
V4[3]=D3DTLVERTEX(D3DVECTOR(w4-0.5f, -0.5f,0.9f),1.0f,color4,0,w4/w2_4, 0/h2_4);
|
||||
target->pD3DDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_TLVERTEX,V4,4,NULL);
|
||||
|
||||
target->pD3DDevice->EndScene();
|
||||
ch = (DWORD)-1;
|
||||
} else {
|
||||
// Modes 1-3: blit to half of the single 1280-wide (or 640-wide) backbuffer.
|
||||
SetRenderTargetBackbuffer();
|
||||
pD3DDevice->BeginScene();
|
||||
|
||||
pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,TRUE);
|
||||
pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_ONE);
|
||||
@@ -1490,7 +1562,7 @@ bool CMFD_Device::EndChannel()
|
||||
//color = 0xFFFFFFFF;
|
||||
D3DTLVERTEX Vertices[4]; // Vertices for the cube
|
||||
|
||||
float w=(float)size_back.cx/2;//<==주의: 이점이 radar와 다른점이다.
|
||||
float w=(float)size_back.cx/2;//<==NOTE: this differs from radar.
|
||||
float x1=(ch/3)*w;
|
||||
float x2=x1+w;
|
||||
float h=(float)size_back.cy;
|
||||
@@ -1504,13 +1576,27 @@ bool CMFD_Device::EndChannel()
|
||||
|
||||
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX , Vertices, 4, NULL );
|
||||
|
||||
pD3DDevice->EndScene();
|
||||
ch = (DWORD)-1;
|
||||
pD3DDevice->EndScene();
|
||||
ch = (DWORD)-1;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Mode 4: same grid pattern as rcs640 but offset to x=0 for a standalone
|
||||
// 640x480 surface (left half of rcs1280).
|
||||
static RECT rcs640_solo[8]={
|
||||
{0,40,640,42},
|
||||
{ 160-1,0, 160+1,40},
|
||||
{ 320-1,0, 320+1,40},
|
||||
{ 480-1,0, 480+1,40},
|
||||
{0,480-42,640,480-40},
|
||||
{ 160-1,440, 160+1,480},
|
||||
{ 320-1,440, 320+1,480},
|
||||
{ 480-1,440, 480+1,480},
|
||||
};
|
||||
|
||||
bool CMFD_Device::BeginScene()
|
||||
{
|
||||
/*
|
||||
@@ -1533,10 +1619,21 @@ bool CMFD_Device::BeginScene()
|
||||
pD3DDevice->Clear(1,&s_rc2,D3DCLEAR_TARGET ,0,1.0f,0);
|
||||
//pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET ,0,1.0f,0);
|
||||
}break;
|
||||
case 4:
|
||||
// Clear and draw background grid on the LEFT device only.
|
||||
// The right device is cleared/gridded in BeginSceneRight(),
|
||||
// called from WinMain at old sh_step==1 (one frame after the
|
||||
// right MFD flip) so its back buffer has fresh content when flipped.
|
||||
SetRenderTargetBackbuffer();
|
||||
pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,0,1.0f,0);
|
||||
pD3DDevice->BeginScene();
|
||||
if(sh_game_started) DrawMFDBackGrid();
|
||||
pD3DDevice->EndScene();
|
||||
return true; // skip the common BeginScene/DrawGrid/EndScene below
|
||||
}
|
||||
pD3DDevice->BeginScene();
|
||||
if(sh_game_started) {
|
||||
//게임이 시작되었을때만.. 배경을 그린다.
|
||||
//Draw background only when game has started..
|
||||
DrawMFDBackGrid();
|
||||
}
|
||||
pD3DDevice->EndScene();
|
||||
@@ -1550,6 +1647,25 @@ bool CMFD_Device::EndScene()
|
||||
return true;
|
||||
}
|
||||
|
||||
// Mode 4: clear and draw the background grid on the right device.
|
||||
// Called from WinMain at old sh_step==1, one frame after the right MFD
|
||||
// flip, so channels 3-4 can render into a fresh back buffer before the
|
||||
// next flip at new sh_step==1 (= old sh_step==0).
|
||||
bool CMFD_Device::BeginSceneRight()
|
||||
{
|
||||
if (g_nTypeOfMFDs != 4 || !m_pRightDevice)
|
||||
return false;
|
||||
m_pRightDevice->SetRenderTargetBackbuffer();
|
||||
m_pRightDevice->pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET,0,1.0f,0);
|
||||
m_pRightDevice->pD3DDevice->BeginScene();
|
||||
if(sh_game_started) {
|
||||
m_pRightDevice->pD3DDevice->SetTexture(0,0);
|
||||
m_pRightDevice->DrawQuadList(8,rcs640_solo,0xFFFFFFFF);
|
||||
}
|
||||
m_pRightDevice->pD3DDevice->EndScene();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CMFD_Device::Release()
|
||||
{
|
||||
@@ -1559,6 +1675,11 @@ bool CMFD_Device::Release()
|
||||
SAFE_RELEASE(pDDSDamageTexture);
|
||||
// MSL 5.03 Target Damage Display
|
||||
SAFE_RELEASE(pDDSTargetTexture);
|
||||
// Mode 4: release the right device before releasing this (left) device.
|
||||
if (g_nTypeOfMFDs == 4 && m_pRightDevice) {
|
||||
m_pRightDevice->Release();
|
||||
m_pRightDevice = NULL;
|
||||
}
|
||||
CHSH_Device::Release();
|
||||
}
|
||||
return true;
|
||||
@@ -1654,7 +1775,7 @@ bool CMFD_Device::DrawMFDBackTextAux3(int state)
|
||||
POINTF &tc = mfd_text_coord[i];
|
||||
if(i!=4){
|
||||
pFont[2].DrawTextMultiLine(tc.x,tc.y,0XFFFFFFFF,mfd_text_weapon[i],TEXTALIGN_ORG);
|
||||
}else{//chain fire 표시
|
||||
}else{//display chain fire
|
||||
DrawQuad((int)tc.x-80,(int)tc.y-20,(int)tc.x+80,(int)tc.y+20,0xFFFFFFFF);
|
||||
pFont[2].DrawTextMultiLine(tc.x,tc.y,0XFF000000,mfd_text_weapon[i],TEXTALIGN_ORG);
|
||||
}
|
||||
@@ -1714,6 +1835,11 @@ bool CMFD_Device::DrawMFDBackGrid()
|
||||
case 2:
|
||||
DrawQuadList(8,rcs640,0xFFFFFFFF);
|
||||
break;
|
||||
case 4:
|
||||
// Left device uses the left-half grid (0..640).
|
||||
// Right device grid is drawn separately in BeginScene.
|
||||
DrawQuadList(8,rcs640_solo,0xFFFFFFFF);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -1763,20 +1889,20 @@ enum {TEAMORDER_NONE, TEAM_MODE, FREEFORALL_MODE, TEAM_MESSAGE1, TEAM_MESSAGE2};
|
||||
bool CMFD_Device::DrawMFDDefaultBackAux1(int state)
|
||||
{
|
||||
if(state==TEAM_MODE){
|
||||
//메크들의 상태를 보여준다.
|
||||
//Show mech status.
|
||||
DrawQuad(0,240-1,640,240+1,0xFFFFFFFF);
|
||||
DrawQuad(160-1,0,160+1,240,0xFFFFFFFF);
|
||||
DrawQuad(320-1,0,320+1,240,0xFFFFFFFF);
|
||||
DrawQuad(480-1,0,480+1,240,0xFFFFFFFF);
|
||||
}else if(state==FREEFORALL_MODE){
|
||||
DrawQuadList(8,aux1freequads,0xFFFFFFFF);
|
||||
}else if(state==TEAM_MESSAGE1){//이걸로서 더이상 그릴것이 없다.
|
||||
}else if(state==TEAM_MESSAGE1){//nothing more to draw.
|
||||
DrawMFDBackText(mfd_text_comm2);
|
||||
for(int i=0;i<7;i++){
|
||||
int y=80+i*40;
|
||||
pFont[0].DrawText(80,(float)y,0xFFFFFFFF,&aux1_messages[i][0],0);
|
||||
}
|
||||
}else if(state==TEAM_MESSAGE2){//이걸로서 더이상 그릴것이 없다.
|
||||
}else if(state==TEAM_MESSAGE2){//nothing more to draw.
|
||||
DrawMFDBackText(mfd_text_comm2);
|
||||
for(int i=0;i<7;i++){
|
||||
int y=80+i*40;
|
||||
@@ -1899,9 +2025,9 @@ void CHSHFont::Init(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ,const char*
|
||||
|
||||
DWORD x = 0;
|
||||
DWORD y = 0;
|
||||
char str[4] = {0,};//DWORD align시키기 위해서..(원래는 2를 쓰면된다.)
|
||||
char str[4] = {0,};//For DWORD alignment.. (originally 2 would suffice.)
|
||||
SIZE size;
|
||||
m_dwMaxWidth=0;//최소값으로 초기화한다.
|
||||
m_dwMaxWidth=0;//Initialize to minimum value.
|
||||
for( char c=32; c<127; c++ ){
|
||||
|
||||
str[0] = c;
|
||||
@@ -1911,11 +2037,11 @@ void CHSHFont::Init(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ,const char*
|
||||
x = 0;
|
||||
y += size.cy+1;
|
||||
}
|
||||
if(size.cx>(int)m_dwMaxWidth){//문자 하나중 가장 큰것..
|
||||
if(size.cx>(int)m_dwMaxWidth){//widest single character..
|
||||
m_dwMaxWidth=size.cx;
|
||||
}
|
||||
|
||||
//j가 i의 영역을 침범한다. 적절한 조치를 취할것...
|
||||
//j invades the region of i. Take appropriate action...
|
||||
ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL );
|
||||
|
||||
m_fTexCoords[c-32][0] = ((float)(x+0))/m_dwTexWidth;
|
||||
@@ -1947,7 +2073,7 @@ void CHSHFont::Init(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ,const char*
|
||||
DeleteDC( hDC );
|
||||
DeleteObject( hFont );
|
||||
|
||||
//////StateBlock관련..
|
||||
//////StateBlock related..
|
||||
for( UINT which=0; which<2; which++ ){
|
||||
m_pd3dDevice->BeginStateBlock();
|
||||
m_pd3dDevice->SetTexture( 0, m_pTexture );
|
||||
@@ -1988,9 +2114,9 @@ void CHSHFont::Init(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ,const char*
|
||||
|
||||
DWORD x = 0;
|
||||
DWORD y = 0;
|
||||
char str[4] = {0,};//DWORD align시키기 위해서..(원래는 2를 쓰면된다.)
|
||||
char str[4] = {0,};//For DWORD alignment.. (originally 2 would suffice.)
|
||||
SIZE size;
|
||||
m_dwMaxWidth=0;//최소값으로 초기화한다.
|
||||
m_dwMaxWidth=0;//Initialize to minimum value.
|
||||
for( char c=32; c<127; c++ ){
|
||||
|
||||
str[0] = c;
|
||||
@@ -2000,11 +2126,11 @@ void CHSHFont::Init(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ,const char*
|
||||
x = 0;
|
||||
y += size.cy+1;
|
||||
}
|
||||
if(size.cx>(int)m_dwMaxWidth){//문자 하나중 가장 큰것..
|
||||
if(size.cx>(int)m_dwMaxWidth){//widest single character..
|
||||
m_dwMaxWidth=size.cx;
|
||||
}
|
||||
|
||||
//j가 i의 영역을 침범한다. 적절한 조치를 취할것...
|
||||
//j invades the region of i. Take appropriate action...
|
||||
ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL );
|
||||
|
||||
m_fTexCoords[c-32][0] = ((float)(x+0))/m_dwTexWidth;
|
||||
@@ -2035,7 +2161,7 @@ void CHSHFont::Init(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ,const char*
|
||||
DeleteDC( hDC );
|
||||
DeleteObject( hFont );
|
||||
|
||||
//////StateBlock관련..
|
||||
//////StateBlock related..
|
||||
for( UINT which=0; which<2; which++ ){
|
||||
m_pd3dDevice->BeginStateBlock();
|
||||
m_pd3dDevice->SetTexture( 0, m_pTexture );
|
||||
@@ -2065,7 +2191,7 @@ void CHSHFont::Cleanup()
|
||||
}
|
||||
SAFE_RELEASE( m_pTexture );
|
||||
SAFE_RELEASE( m_pd3dDevice );
|
||||
}//m_pd3dDevice==NULL이면 아무것도 하지 않는다.
|
||||
}//If m_pd3dDevice==NULL, do nothing.
|
||||
|
||||
}
|
||||
HRESULT CHSHFont::GetTextExtent(const char* strText, SIZE* pSize )
|
||||
@@ -2114,12 +2240,12 @@ HRESULT CHSHFont::DrawText( float sx, float sy, DWORD dwColor,const char* strTex
|
||||
DWORD dwNumVtx = 0;
|
||||
D3DTLVERTEX * pVertices =m_pVB;
|
||||
char c;
|
||||
float osx=sx;//원래의 sx;
|
||||
float h = (m_fTexCoords[0][3]-m_fTexCoords[0][1]) * m_dwTexHeight ;//한글자의 높이는 모두 동일할 것이다.
|
||||
float osx=sx;//original sx;
|
||||
float h = (m_fTexCoords[0][3]-m_fTexCoords[0][1]) * m_dwTexHeight ;//Height of each character should all be the same.
|
||||
|
||||
while( (c = *strText++)!=0 ){
|
||||
|
||||
if( c == '\n')sy+=h,sx=osx;//여러줄을 표시할때...
|
||||
if( c == '\n')sy+=h,sx=osx;//when displaying multiple lines...
|
||||
|
||||
if( c < ' ' )continue;
|
||||
|
||||
@@ -2148,7 +2274,7 @@ HRESULT CHSHFont::DrawText( float sx, float sy, DWORD dwColor,const char* strTex
|
||||
sx += w;
|
||||
}
|
||||
|
||||
//나머지 것들을 그린다.
|
||||
//Draw the remaining items.
|
||||
if(dwNumVtx> 0 ){
|
||||
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX ,m_pVB,dwNumVtx,0 );
|
||||
}
|
||||
@@ -2216,7 +2342,7 @@ HRESULT CHSHFont::DrawTextMultiLine( float sx, float sy, DWORD dwColor,const cha
|
||||
break;
|
||||
}
|
||||
|
||||
char string[128];//최대값을 임의로 정한다.
|
||||
char string[128];//Max length set arbitrarily.
|
||||
strcpy(string,strText);
|
||||
char * seps="\n";
|
||||
char * token;
|
||||
@@ -2251,7 +2377,7 @@ HRESULT CHSHFont::DrawTextVerticalOrg( float sx, float sy, DWORD dwColor,const c
|
||||
float h = (float)((m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight);
|
||||
float w = (float)m_dwMaxWidth;
|
||||
|
||||
//가로 쓰기라고 가정했을때의 명칭이다.
|
||||
//Name assuming horizontal (left-to-right) text layout.
|
||||
int col_count=0;//maximum column count
|
||||
int row_count=1;
|
||||
|
||||
@@ -2269,7 +2395,7 @@ HRESULT CHSHFont::DrawTextVerticalOrg( float sx, float sy, DWORD dwColor,const c
|
||||
ccount++;
|
||||
if(ccount>col_count)col_count=ccount;//update the max value
|
||||
}
|
||||
//여기서는 새로 쓰기일때의 크기이다.
|
||||
//This is the size when writing from scratch.
|
||||
SIZE size;
|
||||
size.cx=(int)(row_count*w);
|
||||
size.cy=(int)(col_count*h);
|
||||
@@ -2282,7 +2408,7 @@ HRESULT CHSHFont::DrawTextVerticalOrg( float sx, float sy, DWORD dwColor,const c
|
||||
m_pd3dDevice->ApplyStateBlock( m_dwDrawTextStateBlock );
|
||||
m_pd3dDevice->SetTexture(0,m_pTexture);
|
||||
|
||||
char string[128];//최대값을 임의로 정한다.
|
||||
char string[128];//Max length set arbitrarily.
|
||||
strcpy(string,strText);
|
||||
char * seps="\n";
|
||||
char * token;
|
||||
@@ -2290,7 +2416,7 @@ HRESULT CHSHFont::DrawTextVerticalOrg( float sx, float sy, DWORD dwColor,const c
|
||||
DWORD dwNumVtx = 0;
|
||||
D3DTLVERTEX * pVertices =m_pVB;
|
||||
|
||||
float osy=sy-size.cy/2;//원래의 sy 가장 높은 좌표..;
|
||||
float osy=sy-size.cy/2;//original sy: topmost coordinate..;
|
||||
sx=sx-size.cx/2;
|
||||
|
||||
|
||||
@@ -2330,7 +2456,7 @@ HRESULT CHSHFont::DrawTextVerticalOrg( float sx, float sy, DWORD dwColor,const c
|
||||
token = strtok( NULL, seps );
|
||||
}
|
||||
|
||||
//나머지 것들을 그린다.
|
||||
//Draw the remaining items.
|
||||
if(dwNumVtx> 0 ){
|
||||
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX ,m_pVB,dwNumVtx,0 );
|
||||
}
|
||||
@@ -2380,20 +2506,20 @@ int __cdecl CopyTargetImage(int stage,LPDIRECTDRAWSURFACE7 tex,int step)
|
||||
if(stage==1){
|
||||
if(inited){
|
||||
//normal function
|
||||
//성능상의 이유로.. 맨처음에 두었음..
|
||||
//Placed at the top for performance reasons..
|
||||
RECT rc={0,0,128,128};
|
||||
LONG lPitch;
|
||||
LPDWORD agp_org,agp,pci_org,pci,mem;
|
||||
int x,y;
|
||||
int sx=0,sy=10,ex=120,ey=112;
|
||||
//int hy=ey-sy;//높이.
|
||||
//int hy=ey-sy;//height.
|
||||
// if(1<=sh_step&&sh_step<=3){
|
||||
//1. AGP->MEM
|
||||
//int h=(sh_step-1)*hy/3;//세그먼트 오프셋..
|
||||
//int h=(sh_step-1)*hy/3;//segment offset..
|
||||
mem=mem_org;
|
||||
agp_org=(DWORD*)GetSurfacePointer(SH_TargetBufferSurface,rc,lPitch,DDLOCK_READONLY );
|
||||
if(agp_org!=NULL){
|
||||
if(lPitch%4==0){// DWORD align됐을때만 실행한다.
|
||||
if(lPitch%4==0){// execute only when DWORD aligned.
|
||||
for(y=sy;y<ey;y++){
|
||||
agp=agp_org+lPitch/4*y;
|
||||
mem=mem_org+128*2/4*y;
|
||||
@@ -2426,7 +2552,7 @@ int __cdecl CopyTargetImage(int stage,LPDIRECTDRAWSURFACE7 tex,int step)
|
||||
mem=mem_org;
|
||||
pci_org=(DWORD*)GetSurfacePointer(texture,rc,lPitch,DDLOCK_WRITEONLY );
|
||||
if(pci_org){
|
||||
if(lPitch%4==0){// DWORD align됐을때만 실행한다.
|
||||
if(lPitch%4==0){// execute only when DWORD aligned.
|
||||
for(y=sy;y<ey;y++){
|
||||
pci=pci_org+lPitch/4*y;
|
||||
mem=mem_org+128*2/4*y;
|
||||
@@ -2467,16 +2593,16 @@ int __cdecl CopyTargetImage(int stage,LPDIRECTDRAWSURFACE7 tex,int step)
|
||||
// Full Screen
|
||||
//_____________________________________________________________________________________________________
|
||||
|
||||
//전에 SCREENS와 유사한 역할을 한다
|
||||
//command line paramemer에 의해 정해지고 이후에는 변하지 않는다.
|
||||
//Previously served a role similar to SCREENS
|
||||
//Set by command line parameter and does not change thereafter.
|
||||
bool use_multimonitor;
|
||||
|
||||
//보통 true이다.. 그러나 window모드로 들어가면.. false가된다.
|
||||
//true이면.. 각종 드로딩 루틴을 그리고 false를 일때는 일체 하지 않는다.
|
||||
//Normally true.. but becomes false when entering windowed mode..
|
||||
//If true.. runs all drawing routines; if false, does nothing.
|
||||
bool draw_mfd_huds;
|
||||
|
||||
//window모드가 되었을때 무조건 true가 되도록한다.(현재에는..)
|
||||
//멀티모디터 드로잉과는 관계없다.
|
||||
//Force to true when windowed mode is entered. (currently..)
|
||||
//Unrelated to multi-monitor drawing.
|
||||
bool draw_main_huds;
|
||||
CRadar_Device radar_device;
|
||||
CMFD_Device mfd_device;
|
||||
@@ -2489,6 +2615,9 @@ bool IsMultimonitorAvaliable()
|
||||
if ((*g_pfnCTCL_GetType)()==_ECTCL_CameraShip)
|
||||
return false;
|
||||
}
|
||||
// Mode 4 uses its own device slots ? g_nDualHead is not required.
|
||||
if (g_nTypeOfMFDs == 4)
|
||||
return (g_nMFD1 != -1 && g_nMFD2 != -1);
|
||||
if (g_nDualHead != -1) {
|
||||
// 0 - no MFDs, 1 - orginal(5+1=dual & single), 2 - B&W(3 + 1=1 dual), 3 - color(3 + 1=2 dual)
|
||||
switch(g_nTypeOfMFDs)
|
||||
@@ -2590,7 +2719,7 @@ void __cdecl DrawSwrling(LPDIRECT3DDEVICE7 pd3dDevice,LPDIRECTDRAWSURFACE7 pText
|
||||
const int segvert=(seg+1)*2;
|
||||
static D3DTLVERTEX Vertices[seg2][segvert]; // Vertices for the cube
|
||||
static bool vertices_initialized=false;
|
||||
//int rcount,scount;//회전 방향 setment수.., 직선 방향 segment수..
|
||||
//int rcount,scount;//num rotation-direction segments, num straight-direction segments..
|
||||
static float off_z=0;
|
||||
if(freload){
|
||||
char temppath[MAX_PATH];
|
||||
@@ -2616,7 +2745,7 @@ void __cdecl DrawSwrling(LPDIRECT3DDEVICE7 pd3dDevice,LPDIRECTDRAWSURFACE7 pText
|
||||
MakeTorus(Vertices[2],w/2,h/2, 0*f,100*f,seg,0xFF000000,0xFF666666,0.3f,0.5f,0,-500,0,-200);
|
||||
vertices_initialized=true;
|
||||
}else{
|
||||
//초기화 됐을경우는 텍스쳐 좌표를 계속해서 바꾼다.
|
||||
//If initialized, keep changing texture coordinates.
|
||||
static float offset=0;
|
||||
static float off=0;
|
||||
float bb=sinf(off)*2;
|
||||
@@ -2645,7 +2774,7 @@ void __cdecl DrawGameEndScreen(LPDIRECT3DDEVICE7 pd3dDevice,LPDIRECTDRAWSURFACE7
|
||||
{
|
||||
static D3DTLVERTEX Vertices[4]; // Vertices for the cube
|
||||
static bool vertices_initialized=false;
|
||||
//int rcount,scount;//회전 방향 setment수.., 직선 방향 segment수..
|
||||
//int rcount,scount;//num rotation-direction segments, num straight-direction segments..
|
||||
static float off_z=0;
|
||||
if(freload){
|
||||
extern bool g_bCOOP; // COin OPeration
|
||||
@@ -2676,7 +2805,7 @@ void __cdecl DrawGameEndScreen(LPDIRECT3DDEVICE7 pd3dDevice,LPDIRECTDRAWSURFACE7
|
||||
Vertices[3] = D3DTLVERTEX(D3DVECTOR( (float)w, (float)h, z_pos),1.0f,0xFFFFFFFF,0, 800.0f/1024.0f, 600.0f/1024.0f );
|
||||
vertices_initialized=true;
|
||||
}else{
|
||||
//초기화 됐을경우는 텍스쳐 좌표를 계속해서 바꾼다.
|
||||
//If initialized, keep changing texture coordinates.
|
||||
}
|
||||
pd3dDevice->SetTextureStageState(0,D3DTSS_COLOROP ,D3DTOP_MODULATE);
|
||||
pd3dDevice->SetTextureStageState(0,D3DTSS_COLORARG1 ,D3DTA_TEXTURE);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//D3DCOLOR_XXXX정위한다.(d3d8types.h에 정의되어 있으므로. 정의되어있지 않을것이다.
|
||||
//D3DCOLOR_XXXX macros are defined in d3d8types.h and will not be redefined here.
|
||||
#ifndef D3DCOLOR_ARGB
|
||||
|
||||
#define D3DCOLOR_ARGB(a,r,g,b) (D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))
|
||||
@@ -44,10 +44,10 @@ enum AUX1STATE
|
||||
#define AUX1_TEAM_MESSAGE 2
|
||||
#define AUX1_FREE_MESSAGE 3
|
||||
|
||||
//각 디바이스마다.., 각 폰트 종류(typeface,크기,굴기,기울기)가 달라질때 마다 하나씩 생성시켜 사용하면 된다.
|
||||
//Create one instance per device per font type (typeface, size, bold, italic).
|
||||
class CHSHFont
|
||||
{
|
||||
//일시적으로 사용되고.. 각 instance마다 사용되어질 필요가 없으므로 static으로 하였다.
|
||||
//Used temporarily; no need per instance, so declared static.
|
||||
static D3DTLVERTEX m_pVB[300];
|
||||
|
||||
LPDIRECT3DDEVICE7 m_pd3dDevice;
|
||||
@@ -59,7 +59,7 @@ class CHSHFont
|
||||
DWORD m_dwSavedStateBlock;
|
||||
DWORD m_dwDrawTextStateBlock;
|
||||
|
||||
DWORD m_dwMaxWidth;//문자 하나중 가장 큰것..
|
||||
DWORD m_dwMaxWidth;//Width of the widest single character..
|
||||
public:
|
||||
CHSHFont();
|
||||
~CHSHFont();
|
||||
@@ -80,10 +80,10 @@ public:
|
||||
CHSH_Device* m_pOtherHSHD;
|
||||
public:
|
||||
LPDIRECTDRAW7 pDD;
|
||||
LPDIRECTDRAWSURFACE7 pDDSFront; //Flip을 하기위해서 필요..
|
||||
LPDIRECTDRAWSURFACE7 pDDSBack; //Drawing하기 위해서 필요.
|
||||
LPDIRECTDRAWSURFACE7 pDDSTarget; //실제 그리는 텍스쳐 이다.
|
||||
LPDIRECTDRAWSURFACE7 pDDSTexture; //실제 그리는 텍스쳐 이다.
|
||||
LPDIRECTDRAWSURFACE7 pDDSFront; //Required for Flip..
|
||||
LPDIRECTDRAWSURFACE7 pDDSBack; //Required for Drawing.
|
||||
LPDIRECTDRAWSURFACE7 pDDSTarget; //The actual rendering texture.
|
||||
LPDIRECTDRAWSURFACE7 pDDSTexture; //The actual rendering texture.
|
||||
LPDIRECT3DDEVICE7 pD3DDevice;
|
||||
CHSHFont pFont[4];
|
||||
SIZE size_back;
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
bool InitFirst();
|
||||
bool InitSecond();
|
||||
LPDIRECTDRAWSURFACE7 pDDSBackground; //one attatched image sruface
|
||||
LPDIRECTDRAWSURFACE7 pDDSRadarDamageTexture;//메크 데미지 텍스쳐..
|
||||
LPDIRECTDRAWSURFACE7 pDDSRadarDamageTexture;//Mech damage texture..
|
||||
// MSL 5.03 Mechview
|
||||
LPDIRECTDRAWSURFACE7 pDDSMechViewBkgnd;
|
||||
LPDIRECTDRAWSURFACE7 pDDSMechViewBeagle;
|
||||
@@ -151,7 +151,7 @@ public:
|
||||
LPDIRECTDRAWSURFACE7 pDDSMechViewLightamp;
|
||||
LPDIRECTDRAWSURFACE7 m_pDDSMechView; //m x n - tiled 3D MechView images
|
||||
|
||||
virtual bool BeginScene(); //texture를 ratate시켜서 출력하기 위한 루틴이 포함된다.. background이미지를.. 미리 출력한다...
|
||||
virtual bool BeginScene(); //Rotates and outputs texture; pre-renders background image...
|
||||
virtual bool EndScene();
|
||||
virtual bool Release();
|
||||
bool LoadRadarDamageTexture(const char *mechtexturename);
|
||||
@@ -163,21 +163,23 @@ class CMFD_Device:public CHSH_Device
|
||||
{
|
||||
public:
|
||||
//CHSHFont SmallFont;
|
||||
LPDIRECTDRAWSURFACE7 pDDSMechTexture;//3D메크 이미지 저장하기 위한 텍스쳐...
|
||||
LPDIRECTDRAWSURFACE7 pDDSDamageTexture;//메크 데미지 텍스쳐..
|
||||
LPDIRECTDRAWSURFACE7 pDDSMechTexture;//Texture for storing 3D mech image...
|
||||
LPDIRECTDRAWSURFACE7 pDDSDamageTexture;//Mech damage texture..
|
||||
// MSL 5.03 Target Damage Display
|
||||
LPDIRECTDRAWSURFACE7 pDDSTargetTexture;//메크 데미지 텍스쳐..
|
||||
LPDIRECTDRAWSURFACE7 pDDSTargetTexture;//Target damage texture..
|
||||
|
||||
DWORD ch; //current channel....
|
||||
CHSH_Device* m_pRightDevice; // mode 4: pointer to right 640x480 device (NULL in modes 1-3)
|
||||
public:
|
||||
CMFD_Device();
|
||||
~CMFD_Device();
|
||||
bool InitFirst();
|
||||
bool InitSecond();
|
||||
bool BeginChannel(DWORD channel);// 0~4번의 채널을 정할 수 있게된다.
|
||||
bool BeginChannel(DWORD channel);// Select channel 0-4.
|
||||
bool EndChannel();
|
||||
virtual bool BeginScene(); //normal한 beginscene/endscene를 한다.
|
||||
virtual bool EndScene(); //flip을 한다.
|
||||
virtual bool BeginScene(); //Performs normal BeginScene/EndScene.
|
||||
bool BeginSceneRight(); // mode 4: clear+grid on right device at sh_step==1
|
||||
virtual bool EndScene(); //Performs the Flip.
|
||||
virtual bool Release();
|
||||
bool LoadDamageTexture(const char *mechtexturename);
|
||||
// MSL 5.03 Target Damage Display
|
||||
@@ -189,6 +191,19 @@ public:
|
||||
bool DrawMFDDefaultBackAux1(int state);
|
||||
};
|
||||
|
||||
// Mode 4 (split dual 640x480): right-side MFD device on its own 640x480 monitor.
|
||||
// Same GPU as the left device (mfd_device), so VRAM textures are shared.
|
||||
class CMFDRight_Device : public CHSH_Device
|
||||
{
|
||||
public:
|
||||
CMFDRight_Device() {}
|
||||
bool InitFirst();
|
||||
bool InitSecond();
|
||||
virtual bool BeginScene() { return true; }
|
||||
virtual bool EndScene() { return true; }
|
||||
virtual bool Release() { return CHSH_Device::Release(); }
|
||||
};
|
||||
|
||||
class CMR_Device:public CHSH_Device
|
||||
{
|
||||
public:
|
||||
@@ -199,10 +214,10 @@ public:
|
||||
bool InitFirst();
|
||||
bool InitSecond();
|
||||
LPDIRECTDRAWSURFACE7 pDDSBackground; //one attatched image sruface
|
||||
LPDIRECTDRAWSURFACE7 pDDSMapTexture; //스크롤되는 맵 이미지를 위한 텍스쳐..
|
||||
LPDIRECTDRAWSURFACE7 pDDSMRTargetTexture;//메크 데미지 텍스쳐..
|
||||
LPDIRECTDRAWSURFACE7 pDDSMapTexture; //Texture for scrollable map image..
|
||||
LPDIRECTDRAWSURFACE7 pDDSMRTargetTexture;//Mission Review target texture..
|
||||
bool LoadMRTargetTexture(const char *mechtexturename);
|
||||
virtual bool BeginScene(); //texture를 ratate시켜서 출력하기 위한 루틴이 포함된다.. background이미지를.. 미리 출력한다...
|
||||
virtual bool BeginScene(); //Rotates and outputs texture; pre-renders background image...
|
||||
virtual bool EndScene();
|
||||
virtual bool Release();
|
||||
};
|
||||
@@ -212,6 +227,7 @@ void HSH_DirectDrawRelease2();
|
||||
|
||||
extern CRadar_Device radar_device;
|
||||
extern CMFD_Device mfd_device;
|
||||
extern CMFDRight_Device mfd_device_right;
|
||||
extern CMR_Device mr_device;
|
||||
extern bool use_shgui;
|
||||
extern int sh_step;
|
||||
|
||||
@@ -71,7 +71,7 @@ INTERNET_STATUS_STATE_CHANGE
|
||||
INTERNET_STATE_DISCONNECTED_BY_USER
|
||||
Disconnected by user request.
|
||||
INTERNET_STATE_IDLE
|
||||
No network requests are being made by the Win32® Internet functions.
|
||||
No network requests are being made by the Win32® Internet functions.
|
||||
INTERNET_STATE_BUSY
|
||||
Network requests are being made by the Win32 Internet functions.
|
||||
INTERNET_STATUS_USER_INPUT_REQUIRED
|
||||
|
||||
@@ -1077,7 +1077,7 @@ int CStrArray::GetTotalLength() const
|
||||
int nTotalLength;
|
||||
int i, nSize = GetSize();
|
||||
|
||||
nTotalLength = nSize; // nSize개의 '\0'
|
||||
nTotalLength = nSize; // nSize null terminators '\0'
|
||||
for(i = 0; i < nSize; i++) {
|
||||
nTotalLength += strlen(GetAt(i));
|
||||
}
|
||||
|
||||
@@ -514,7 +514,7 @@ void CSOC_Server::OnSendFile()
|
||||
BYTE bCode;
|
||||
if (Disassemble("B", &bCode)) {
|
||||
ASSERT((bCode == 0) || (bCode == 3));
|
||||
// 받아가시오 from Game to console...
|
||||
// Receiving from Game to console...
|
||||
SYSTEMTIME* pSysTime;
|
||||
WORD wSysTimeSize;
|
||||
GUID* pGUID;
|
||||
@@ -530,7 +530,7 @@ void CSOC_Server::OnSendFile()
|
||||
pSF = g_pCTCLManager->m_SFM_Recv.Find(*pGUID, nType);
|
||||
if (pSF) {
|
||||
if (bCode == 3) {
|
||||
// 미션리뷰 서버가 mission review 받았다는 것을 받았느냐?
|
||||
// Did we receive confirmation the mission review server got the mission review?
|
||||
pSF->m_bProcessed = true;
|
||||
g_pCTCLManager->m_SFM_Recv.Cut(pSF);
|
||||
g_pCTCLManager->m_SFM_Done.AddTail(pSF);
|
||||
@@ -907,7 +907,7 @@ void CSOC_Client::OnSendFile()
|
||||
BYTE bCode;
|
||||
if (Disassemble("B", &bCode)) {
|
||||
ASSERT((bCode == 1) || (bCode == 2));
|
||||
// 받았오 from console to Game...
|
||||
// Received from console to Game...
|
||||
SYSTEMTIME* pSysTime;
|
||||
WORD wSysTimeSize;
|
||||
GUID* pGUID;
|
||||
@@ -1425,21 +1425,21 @@ void CCTCLManager::Run()
|
||||
#endif // !defined(CTCL_LAUNCHER)
|
||||
} else {
|
||||
/*
|
||||
클라이언트나 서버의 경우 실행되는 코드이다.
|
||||
Code executed for both client and server.
|
||||
|
||||
*있을수 있는 상태들
|
||||
서버/클라이언트가 결정되기전.. 명령 대기상태
|
||||
(종료/서버시작/클라이언트 시작등의 명령이 올수 있다.)
|
||||
*Possible states:
|
||||
Before server/client role is determined: waiting for commands
|
||||
(Commands such as exit/start-server/start-client may arrive.)
|
||||
|
||||
서버로 실행되어 서버 메크 설정에 대한 데이타를 기다리는 상태
|
||||
(CreateSession가 실행된 상태이다.)
|
||||
서버로 실행되어 Bot들에 대한 정보를 기다리는 상태
|
||||
(클라이언트의 참여는 클라이언트와 서버간에 자동으로 이루어진다.)
|
||||
서버로 실행되어 Launch를 기다리는 상태
|
||||
Running as server, waiting for server mech configuration data
|
||||
(State after CreateSession has been called.)
|
||||
Running as server, waiting for Bot information
|
||||
(Client joining happens automatically between client and server.)
|
||||
Running as server, waiting for Launch
|
||||
|
||||
==>클라이언트는 실행즉시 데이타들이 전달되므로 대기상태가 없다.
|
||||
==>Client has no waiting state as data is transferred immediately on startup.
|
||||
|
||||
==>각각의 상태를 정의하고 각 상태에 맞는 처리를 해주면 된다.
|
||||
==>Define each state and implement the appropriate handling for each.
|
||||
switch(state){
|
||||
}
|
||||
*/
|
||||
@@ -1521,8 +1521,8 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
//서버/클라이언트로서 실행준비하도록 명령을 전달한다.
|
||||
//또한 서버를 실행하는데 필요한 모든 파라미터도 함께 전달한다.
|
||||
//Send command to prepare for execution as server/client.
|
||||
//Also transmit all parameters required to run the server.
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
if (!pi.m_bBot) {
|
||||
@@ -1549,12 +1549,12 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
}
|
||||
if (i == g_nPlayerInfos) {
|
||||
// Bot들에 대한 정보를 모두 한데 묶어서 보낸다.
|
||||
// Bundle and send all Bot information together.
|
||||
CPacket pak(&SVR.GetGameSOC());
|
||||
|
||||
pak.Assemble("B", C_BOTS);
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
if (i != g_nServer) { // 원래 Bot만 지금은 서버를 제외한 전부...
|
||||
if (i != g_nServer) { // Originally bots only; now everyone except the server...
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
pak.Assemble("BnsDWwsnn", pi.m_bBot, pi.m_nLevelOrTesla, pi.m_szName, pi.m_nMechIndex, pi.m_fileID, pi.m_recordID, pi.m_szMech, pi.m_nTeamOrSkin, pi.m_nDecal);
|
||||
}
|
||||
@@ -1565,10 +1565,10 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
// 게임이 성공적으로 만들어지면 서버와 클라이언트들의 Mech에 대한 정보들을 Set한다...
|
||||
// Once the game is successfully created, set Mech info for server and all clients...
|
||||
if (SOCGame.m_nGameReturn == _EGR_OkCreateSession) {
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
if (i != g_nServer) { // 서버는 이미 SetMech에 진입한 상태...
|
||||
if (i != g_nServer) { // Server has already entered SetMech...
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
if (!pi.m_bBot) {
|
||||
CTeslaInfo& ti = m_aTIs.GetAt(pi.m_nLevelOrTesla);
|
||||
@@ -1581,8 +1581,8 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
//모든 클라이언드들이 서버에 참여하기를 기다린다.<==이 응답은 서버로 부터 얻을 수 있다.
|
||||
//참여가 모두 끝났으면, 서버로 하여금 게임을 Launch시키도록 한다.
|
||||
//Wait for all clients to join the server. <==This response comes from the server.
|
||||
//Once all clients have joined, instruct the server to Launch the game.
|
||||
if (SOCGame.m_nGameReturn == _EGR_OkLaunchReady) {
|
||||
g_nMech4Comm = 9;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
const char* m_pcsz;
|
||||
|
||||
int m_nLauncherConnection; // 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // m_bCameraShip값에 따라 게임 혹은 카메라 쉽과의 접속을 의미, 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // Connection to game or camera ship per m_bCameraShip, 0: no connection, +1: connected, -1: connecting
|
||||
int m_nApplType;
|
||||
int m_nApplState;
|
||||
int m_nGameState;
|
||||
|
||||
@@ -44,7 +44,7 @@ int GetDayEnd(int nYear, int nMonth)
|
||||
|
||||
long GetTotalSeconds(int nYear, int nMonth, int nDay)
|
||||
{
|
||||
// nYear, nMonth, nDay날의 0시 0분 0초를 0으로 한 초단위 수...
|
||||
// Seconds elapsed since 00:00:00 on the date nYear/nMonth/nDay...
|
||||
ASSERT(nYear >= 1970);
|
||||
ASSERT((1 <= nMonth) && (nMonth <= 12));
|
||||
ASSERT(1 <= nDay);
|
||||
@@ -57,13 +57,13 @@ long GetTotalSeconds(int nYear, int nMonth, int nDay)
|
||||
if (IsLeapYear(nStart)) {
|
||||
nDays++;
|
||||
}
|
||||
lTotal += nDays * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += nDays * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
}
|
||||
for(nStart = 1; nStart < nMonth; nStart++) {
|
||||
int nDayEnd = GetDayEnd(nYear, nStart);
|
||||
lTotal += nDayEnd * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += nDayEnd * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
}
|
||||
lTotal += (nDay - 1) * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += (nDay - 1) * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
|
||||
return lTotal;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class CTimeDate
|
||||
public:
|
||||
union {
|
||||
struct {
|
||||
// Bit Field는 앞쪽에 지정된 것이 LowBit이다.
|
||||
// Bit Fields declared first are at the low-bit end.
|
||||
DWORD m_xDay: 5; // 2^0, 2^5-1
|
||||
DWORD m_xMonth: 4; // 2^5, 2^4-1
|
||||
DWORD m_xYear: TIMEDATE_YEAR_BITS; // from 1900-2155 // 2^9, 2^8-1
|
||||
|
||||
@@ -1375,7 +1375,7 @@ void CSockAddr::SetTarget(const char* pcszAddr)
|
||||
{
|
||||
if (pcszAddr) {
|
||||
sin_addr.s_addr = inet_addr(pcszAddr);
|
||||
if (sin_addr.s_addr == INADDR_ANY) { // 0.0.0.0이기 때문에 HOST/Network Addr무관
|
||||
if (sin_addr.s_addr == INADDR_ANY) { // 0.0.0.0, HOST/Network Addr irrelevant
|
||||
hostent* pHN = gethostbyname(pcszAddr);
|
||||
if (pHN) {
|
||||
sin_addr.s_addr = *(u_long*)pHN->h_addr;
|
||||
@@ -3667,7 +3667,7 @@ CSOCListen* CSOCManager::DoListen(int nPort, PFN_CreateSOCClient pfnCSC, DWORD d
|
||||
pSOCListen = new CSOCListen(nPort);
|
||||
pSOCListen->SetCSCParam(pfnCSC, dwCSCParam1, dwCSCParam2);
|
||||
if (!DoListen(pSOCListen, nPort)) {
|
||||
// 같은 포트를 2번 Listen 하는 경우?...
|
||||
// Case of Listen on the same port twice?...
|
||||
pSOCListen = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ extern char SERVERID[];
|
||||
#endif // !MAX_PACKET
|
||||
#ifndef MAX_FTPBUF
|
||||
#define MAX_FTPBUF 1024
|
||||
// MAX_FTPBUF는 MAX_PACKET보다 반드시 작아야 한다?
|
||||
// MAX_FTPBUF must be smaller than MAX_PACKET?
|
||||
// 9+size==sizeof(bCmd) + sizeof(FTID) + sizeof(size) + size
|
||||
#endif // !MAX_FTPBUF
|
||||
|
||||
@@ -251,7 +251,7 @@ private:
|
||||
|
||||
#define ESTRF_USER_START 100
|
||||
|
||||
#define ESTRF_PASSWORDCHANGED 110 // 로그인하고 있는 동안에 패스워드가 바뀜
|
||||
#define ESTRF_PASSWORDCHANGED 110 // Password changed while logged in
|
||||
|
||||
void Randomize();
|
||||
|
||||
@@ -268,7 +268,7 @@ union UPacketValue
|
||||
|
||||
class CDAPacket : public SOCBase_Class
|
||||
{
|
||||
// Packet의 앞 부분을 처리하고 난 뒷 부분의 가변 파라미터...
|
||||
// Variable parameters in the tail portion after processing the packet header...
|
||||
public:
|
||||
BYTE m_bCmd;
|
||||
BYTE m_bReserved;
|
||||
@@ -361,8 +361,8 @@ public:
|
||||
#define C_ROOM_MAKE 232
|
||||
// s - name, s - password
|
||||
#define C_ROOM_JOIN 233
|
||||
// d - number(Room을 떠나는 것은 -1), s - password
|
||||
#define S_ROOM_JOIN 233 // C_ROOM_MAKE/C_ROOM_JOIN의 결과...
|
||||
// d - number (leaving a Room = -1), s - password
|
||||
#define S_ROOM_JOIN 233 // Result of C_ROOM_MAKE/C_ROOM_JOIN...
|
||||
// b - code(CSCODE_OK or error code), d - number
|
||||
#define C_ROOM_UPDS 234 // CSCODE_... + @
|
||||
|
||||
@@ -384,13 +384,13 @@ public:
|
||||
#define S_FTP 254 //... see ftp.txt
|
||||
#define X_KEEPALIVE 255 // no parameters, should be ignored...
|
||||
|
||||
#define TX_SYSTEM 0 // 시스템 메시지...
|
||||
#define TX_NORMAL 1 // 일반 채팅 텍스트
|
||||
#define TX_WARNING 2 // 경고
|
||||
#define TX_ERROR 3 // 오류
|
||||
#define TX_FATAL 4 // 치명적인 오류
|
||||
#define TX_INFO 5 // 사용자 정보 등의 Information Result...
|
||||
#define TX_SAY 6 // 귓속말
|
||||
#define TX_SYSTEM 0 // System message...
|
||||
#define TX_NORMAL 1 // Regular chat text
|
||||
#define TX_WARNING 2 // Warning
|
||||
#define TX_ERROR 3 // Error
|
||||
#define TX_FATAL 4 // Fatal error
|
||||
#define TX_INFO 5 // Information result (e.g. user info)...
|
||||
#define TX_SAY 6 // Whisper
|
||||
#define TX_LOCAL 7 // local echo....
|
||||
#define TX_UNKNOWN 0xffff // unknown...
|
||||
|
||||
@@ -493,7 +493,7 @@ CPacket
|
||||
protected:
|
||||
CSOC* m_pSOC;
|
||||
private:
|
||||
// 이 안의 블럭은 반드시 연속해야 한다...
|
||||
// The block within must be contiguous...
|
||||
WORD m_wLen;
|
||||
BYTE m_ba[MAX_PACKET];
|
||||
//
|
||||
@@ -587,7 +587,7 @@ end of variable PACKET_MAP definitions...
|
||||
class CFileTransfer : public TDBLNK(CFileTransfer*)
|
||||
{
|
||||
public:
|
||||
// 서버로 부터 받은 정보... - 혹은 클라이언트에게 전해줄 정보...
|
||||
// Information received from server... - or information to relay to client...
|
||||
BOOL m_bClientSite;
|
||||
DWORD m_dwFTID;
|
||||
DWORD m_dwGUARD;
|
||||
@@ -680,18 +680,18 @@ protected:
|
||||
// time out to Drop...
|
||||
DWORD m_dwKARcvTimeOut;
|
||||
#ifdef WIN32
|
||||
// 보통 Login과정에 쓰이는 윈도우 핸들
|
||||
// Window handle typically used during Login process
|
||||
HWND m_hWndOwner;
|
||||
#endif // WIN32
|
||||
// 보통 글로벌 변수로 쓰이는 소켓포인터에 대한 자동 NULL Assign을 위하여
|
||||
// For auto NULL assignment of socket pointer typically used as a global variable
|
||||
PSOC* m_ppSOC;
|
||||
// 소켓을 구분하기 위하여 사용자 프로그램에서 쓰이는 아이디
|
||||
// 주로 서버의 경우에는 클라이언트가 접속할 때마다 고유 아이디를 부여하여 사용
|
||||
// 하나의 Client가 다수의 서버에 접속할 때(주로 Star형) 각각의 접속을 구분할 때 사용
|
||||
// 클라이언트가 하나의 서버에만 접속하는 경우 클라이언트가 서버에 접속 중인지 혹은 접속했는지를 판단할 때
|
||||
// CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState()를 사용.
|
||||
// limits.h를 include해야함.
|
||||
// CSOC생성시의 기본값: CSOCServer == CSOC_SERVER_ID(=INT_MIN), CSOCClient == CSOC_CLIENT_ID(=0), CSOCListen == CSOC_LISTEN_ID(=-1)
|
||||
// ID used in user program to identify a socket
|
||||
// Mainly for servers: assigns a unique ID each time a client connects
|
||||
// Used to distinguish each connection when a client connects to multiple servers (Star topology)
|
||||
// When a client connects to only one server: used to check if client is connecting or already connected
|
||||
// Use CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState().
|
||||
// Must include limits.h.
|
||||
// Default values at CSOC creation: CSOCServer==CSOC_SERVER_ID(INT_MIN), CSOCClient==CSOC_CLIENT_ID(0), CSOCListen==CSOC_LISTEN_ID(-1)
|
||||
union {
|
||||
int m_nID;
|
||||
UINT m_uID;
|
||||
@@ -725,8 +725,8 @@ protected:
|
||||
DWORD m_xGracefulRemote: 1;
|
||||
DWORD m_xAbortyLocal: 1;
|
||||
DWORD m_xAbortyRemote: 1;
|
||||
DWORD m_xLoginStarted: 1; // 사용자가 직접 값을 Setting해야 한다.
|
||||
DWORD m_xLoginOK: 1; // 사용자가 직접 값을 Setting해야 한다.
|
||||
DWORD m_xLoginStarted: 1; // Must be set directly by the caller.
|
||||
DWORD m_xLoginOK: 1; // Must be set directly by the caller.
|
||||
} m_DW;
|
||||
DWORD m_dwVarFlags;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ inline BOOL AssertDialog(const char* pcszExpr, const char* pcszfile, int nLine)
|
||||
{
|
||||
char szBuf[MAX_PATH * 2];
|
||||
|
||||
sprintf(szBuf, "\"%s\" 파일의 %d줄에서 ASSERT!!!\n\n디버깅을 하시겠습니까?", pcszfile, nLine);
|
||||
sprintf(szBuf, "ASSERT!!! in \"%s\" at line %d\n\nDo you want to debug?", pcszfile, nLine);
|
||||
|
||||
#ifdef WIN32
|
||||
return ::MessageBox(NULL, szBuf, pcszExpr, MB_YESNO) == IDYES;
|
||||
|
||||
@@ -6,7 +6,7 @@ inline BOOL AssertDialog(const char* pcszExpr, const char* pcszfile, int nLine)
|
||||
{
|
||||
char szBuf[MAX_PATH * 2];
|
||||
|
||||
sprintf(szBuf, "\"%s\" 파일의 %d줄에서 ASSERT!!!\n\n디버깅을 하시겠습니까?", pcszfile, nLine);
|
||||
sprintf(szBuf, "ASSERT!!! in \"%s\" at line %d\n\nDo you want to debug?", pcszfile, nLine);
|
||||
|
||||
#ifdef WIN32
|
||||
return ::MessageBox(NULL, szBuf, pcszExpr, MB_YESNO) == IDYES;
|
||||
|
||||
@@ -76,18 +76,18 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//· code for changing sort order or priority levels
|
||||
//· new sort order
|
||||
//· new priority level
|
||||
//· priority set to remove
|
||||
//· priority set to add
|
||||
//· code for changing sort order or priority levels
|
||||
//· new sort order
|
||||
//· new priority level
|
||||
//· priority set to remove
|
||||
//· priority set to add
|
||||
} AdjustCommandData;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
//· command area from which to remove command
|
||||
//· command id of command to remove
|
||||
//· other info to pick what command to remove
|
||||
//· command area from which to remove command
|
||||
//· command id of command to remove
|
||||
//· other info to pick what command to remove
|
||||
} RemoveCommandData;
|
||||
|
||||
union CommandUnion
|
||||
|
||||
@@ -104,8 +104,8 @@ void CRIOMAIN::UpdateJoystickY (DIJOYSTATE &js)
|
||||
|
||||
lJ = JoystickY_Center - g_JoystickY;
|
||||
|
||||
// 고감도
|
||||
// Dead Zone 에서 벗어난 시점을 0으로 계산한다
|
||||
// High sensitivity
|
||||
// Calculate from the moment of exiting the Dead Zone as 0
|
||||
if (lJ > 0) {
|
||||
lJ -= DEADZONE_JOYSTICK;
|
||||
} else if (lJ < 0) {
|
||||
|
||||
@@ -43,7 +43,7 @@ LONG g_LeftPedalLast = 0;
|
||||
LONG g_RightPedalLast = 0;
|
||||
BOOL g_StartGame = FALSE;
|
||||
|
||||
static int g_nOpenComState = 0; // 鉉
|
||||
static int g_nOpenComState = 0; // hyun
|
||||
|
||||
DWORD g_dwLastAnalogUpdate = 0;
|
||||
|
||||
@@ -54,7 +54,7 @@ DWORD g_dwLastAnalogUpdate = 0;
|
||||
#define RESTART_CHAR 0xFE
|
||||
#define IDLE_CHAR 0xFF
|
||||
|
||||
//member 변수처럼 활용할것.
|
||||
//Use it like a member variable.
|
||||
static HANDLE g_hCom = INVALID_HANDLE_VALUE;
|
||||
static OVERLAPPED wos;
|
||||
static OVERLAPPED ros;
|
||||
@@ -108,6 +108,7 @@ int g_nRIOPacketCountB = (sizeof(g_baRIOLengthsB) / sizeof(g_baRIOLengthsB[0]));
|
||||
|
||||
int g_nRIOType = 0; // 0: old(original) type, 1: new type
|
||||
DWORD g_dwRIOBaud = 0; // [tbaud] 0: default by RIO type; else COM1 baud forced by -tbaud (high-speed replica of the original RIO board, protocol unchanged)
|
||||
DWORD g_dwRIOPollTimeout = 50; // [tbaud] WaitForMultipleObjects timeout (ms); computed from baud rate before the receive loop starts
|
||||
int g_nEjectButton = 61; // 61: original, 31: new type
|
||||
BYTE* g_pbRIOLengths = NULL;
|
||||
int g_nRIOPacketCount = 0;
|
||||
@@ -318,7 +319,7 @@ void RequestVersion();
|
||||
void RequestAnalogUpdate(BYTE bFreq = 3);
|
||||
|
||||
// start - for new RIO Board only...
|
||||
//received packet은 각각 다른 스레드에서 처리하므로.. ciritical section이 필요하다..
|
||||
//Received packets are handled in different threads.. a critical section is needed..
|
||||
BYTE received_buffer[128][16];
|
||||
int received_packet=0;//packets count in the received_buffer.
|
||||
DWORD received_serial=0;
|
||||
@@ -569,7 +570,7 @@ BOOL SetupConnection(HANDLE hCom)
|
||||
return TRUE;
|
||||
|
||||
/*
|
||||
원래 처리 루틴..
|
||||
Original processing routine..
|
||||
NPTTYINFO npTTYInfo=0 ;
|
||||
BYTE bset1 = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_DTRDSR) != 0) ;
|
||||
BYTE bset2 = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_RTSCTS) != 0) ;
|
||||
@@ -603,7 +604,7 @@ BOOL SetupConnection(HANDLE hCom)
|
||||
|
||||
|
||||
|
||||
//처리되지 않는 항목들.. GetCommState의 기본값으로 처리한다.
|
||||
//Unhandled items.. handled using GetCommState default values.
|
||||
DWORD fDsrSensitivity:1; // DSR sensitivity
|
||||
DWORD fTXContinueOnXoff:1; // XOFF continues Tx
|
||||
DWORD fErrorChar: 1; // enable error replacement
|
||||
@@ -647,7 +648,7 @@ HANDLE OpenConnection(int port)
|
||||
g_hLampEvent = CreateEvent(0,FALSE,0,0);
|
||||
g_hCommWatchThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)CommWatchProc, NULL, CREATE_SUSPENDED, &g_dwThreadID);
|
||||
if (g_hCommWatchThread) {
|
||||
//Thread까지 정상적으로 생성되었다.
|
||||
//Thread was created successfully.
|
||||
//////////////////////////////////////////////
|
||||
//All OK
|
||||
//Exit Point <======
|
||||
@@ -744,11 +745,11 @@ retry:
|
||||
for(int i=0;i<(int)dwLength;i++){
|
||||
int ch=(BYTE)lpszBlock[i];
|
||||
|
||||
//받은 문자만큼 루프를 돈다.
|
||||
//현재.. 받고 있는 packet이 없고.. 어떤 control문자라도 올 수 있는 상태이다.
|
||||
//Loop for the number of received characters.
|
||||
//Currently.. no packet is being received.. can receive any control character.
|
||||
|
||||
if(packetbyteremain!=0){
|
||||
//패킷에 해당하는 문자가 도착했다.. 나머지 문자들을 받는다.
|
||||
//Character corresponding to a packet has arrived.. receive the remaining characters.
|
||||
if (ch & 0x80) {
|
||||
packetbyteremain=0;
|
||||
chinpacket=0;
|
||||
@@ -758,7 +759,7 @@ retry:
|
||||
packetbytes[chinpacket] = ch;
|
||||
chinpacket++;
|
||||
if (packetbyteremain == 0) {
|
||||
//하나의 패킷이 완성되었다. 도착했다.. 즉시 반응한다.
|
||||
//A packet has been completed and arrived.. respond immediately.
|
||||
chinpacket--; // exclude check byte
|
||||
int packettype=packetbytes[0];
|
||||
BYTE bCheckByte = 0;
|
||||
@@ -837,21 +838,21 @@ retry:
|
||||
packettype++;
|
||||
packettype--;
|
||||
#endif // _DEBUG
|
||||
case rio_Ack2://◆◆◆◆◆◆◆◆◆◆
|
||||
case rio_Ack2:
|
||||
if (g_nRIOType != 0) {
|
||||
BYTE id=packetbytes[1];
|
||||
int popped_index=PopPacket(id);
|
||||
ack_timeout=GetTickCount()+30;
|
||||
if(popped_index==0){
|
||||
//맨처음것... 정상적인 경우이다.
|
||||
//This is the very first one... Normal case.
|
||||
}else if(popped_index>0){
|
||||
//맨처음것이 아닌것.
|
||||
//이전것들이 정상적으로 보내지지 않았으므로 다시 보낸다...
|
||||
ReSendPackets(popped_index);//잘못된 개수 만큼..
|
||||
//Not the very first one.
|
||||
//Previous ones were not sent successfully, resend...
|
||||
ReSendPackets(popped_index);//By the number of incorrect ones..
|
||||
}else{
|
||||
//실패 했다는것은.. 없는 id가 왔다는 것인데..
|
||||
//명백한 에러.. 그러나 특별히 대처할 방법은 없다.
|
||||
//그냥 무시한다.
|
||||
//Failure means an id that does not exist arrived..
|
||||
//An obvious error.. but there is no particular way to handle it.
|
||||
//Simply ignore it.
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -870,9 +871,9 @@ retry:
|
||||
// WriteTTYBlock(hWnd,"|",1);
|
||||
chinpacket=0;
|
||||
|
||||
//packetbytes버퍼를 지운다.
|
||||
//Clear the packetbytes buffer.
|
||||
} else {
|
||||
//아직 패킷 문자들이 다 도착하지 않았다.. 아무것도 하지 않는다.
|
||||
//Packet characters have not all arrived yet.. do nothing.
|
||||
;
|
||||
}
|
||||
}else{
|
||||
@@ -889,7 +890,7 @@ retry:
|
||||
}//for(int i=0;i<(int)dwLength;i++)
|
||||
|
||||
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
if (!fReadStat){
|
||||
if (GetLastError() == ERROR_IO_PENDING){
|
||||
while(!GetOverlappedResult( g_hCom,&ros, &dwLength, TRUE )){
|
||||
@@ -1000,12 +1001,24 @@ DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
|
||||
}
|
||||
|
||||
g_dwLastAnalogUpdate = GetTickCount() + 2800;
|
||||
// [tbaud] Scale the poll timeout proportionally to baud rate so faster links
|
||||
// poll more frequently. Formula: clamp(ceil(480000/baud), 5, 50)
|
||||
// preserves the existing 50ms at 9600 baud, floors at 5ms for high speeds.
|
||||
// effectiveBaud: use -tbaud override if set, else the RIO type's default.
|
||||
{
|
||||
DWORD effectiveBaud = (g_dwRIOBaud != 0) ? g_dwRIOBaud
|
||||
: ((g_nRIOType == 0) ? 9600UL : 115200UL);
|
||||
{
|
||||
DWORD t = (480000UL + effectiveBaud - 1) / effectiveBaud;
|
||||
g_dwRIOPollTimeout = (t < 5UL) ? 5UL : (t > 50UL ? 50UL : t);
|
||||
}
|
||||
}
|
||||
while(1) {
|
||||
DWORD dwEvtMask = 0;
|
||||
|
||||
WaitCommEvent( g_hCom, &dwEvtMask,&wcos );
|
||||
|
||||
DWORD ret=WaitForMultipleObjects(3,events,FALSE,50/*INFINITE*/);
|
||||
DWORD ret=WaitForMultipleObjects(3,events,FALSE,g_dwRIOPollTimeout);
|
||||
if(ret==WAIT_OBJECT_0){
|
||||
//An Comm Event has arrived.
|
||||
DWORD bytesread;
|
||||
@@ -1022,10 +1035,10 @@ DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
|
||||
}
|
||||
} else {*/
|
||||
if (g_nRIOType != 0) {
|
||||
///◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆위의 ReadCommBlock에서 ack를 받았을 경우 duetime을 update시킨다.
|
||||
///◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆CheckSentBuffer...
|
||||
///When ack is received from ReadCommBlock above, update duetime.
|
||||
///CheckSentBuffer...
|
||||
if(GetTickCount()>ack_timeout)
|
||||
ReSendPackets(sent_packet);//sent_buffer에 있는 모든것들을 다시 보내본다.
|
||||
ReSendPackets(sent_packet);//Resend everything in sent_buffer.
|
||||
}
|
||||
/*}*/
|
||||
}else if(ret==WAIT_OBJECT_0+1){
|
||||
@@ -1039,9 +1052,9 @@ DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
|
||||
//break;
|
||||
}else if (ret==WAIT_TIMEOUT) {
|
||||
if (g_nRIOType != 0) {
|
||||
///◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆CheckSentBuffer...
|
||||
///CheckSentBuffer...
|
||||
if(GetTickCount()>ack_timeout)
|
||||
ReSendPackets(sent_packet);//sent_buffer에 있는 모든것들을 다시 보내본다.
|
||||
ReSendPackets(sent_packet);//Resend everything in sent_buffer.
|
||||
}
|
||||
if (packetbyteremain == 0) {
|
||||
RequestAnalogUpdate();
|
||||
@@ -1236,8 +1249,8 @@ bool SaveReceivedPacket(const BYTE*ba,int length)
|
||||
|
||||
bool GetSerialFromReceivedBuffer(char * ba)
|
||||
{
|
||||
//ButtonPressed/Released만 저장해 놓는다..
|
||||
//모든 serial packet을 옮긴다.
|
||||
//Store only ButtonPressed/Released..
|
||||
//Transfer all serial packets.
|
||||
if(received_packet>0){
|
||||
if(received_buffer[0][2]==received_serial){
|
||||
CopyMemory(ba,received_buffer[0],16);
|
||||
@@ -1264,7 +1277,7 @@ bool QueuePacket(const BYTE *ba,int length)
|
||||
|
||||
int PopPacket(BYTE id)
|
||||
{
|
||||
//lamp는.. id가..
|
||||
//lamp.. check by id..
|
||||
//search the packet..
|
||||
for(int i=0;i<sent_packet;i++){
|
||||
if(sent_buffer[i][3]==id){
|
||||
@@ -1427,7 +1440,7 @@ void CBUTTON_GROUP::SetTable(BOOL bFlag/* = true*/)
|
||||
|
||||
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
||||
s_aCtrlLamp[b] = s_aSaveLamp[b];// = s_aButtonTable[b].lamp;
|
||||
// s_aButtonTable는 Old값이므로 초기치는 Off
|
||||
// s_aButtonTable is the old value, so the initial value is Off
|
||||
s_aButtonTable[b].lamp = LAMP_OFF;
|
||||
}
|
||||
|
||||
@@ -1439,7 +1452,7 @@ void CBUTTON_GROUP::SetTable(BOOL bFlag/* = true*/)
|
||||
}
|
||||
else
|
||||
{
|
||||
// 모든 테이블을 원래 상태로
|
||||
// Restore all tables to original state
|
||||
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
||||
s_aCtrlLamp[b] = s_aSaveLamp[b];
|
||||
}
|
||||
@@ -1534,7 +1547,7 @@ void CBUTTON_GROUP::ResetTable(BOOL bFlag/* = true*/)
|
||||
}
|
||||
else
|
||||
{
|
||||
// 모든 테이블을 Off
|
||||
// Turn off all tables
|
||||
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
||||
switch(b)
|
||||
{
|
||||
@@ -2212,13 +2225,13 @@ void CRIOMAIN::UpdatePadal (DIJOYSTATE &js)
|
||||
|
||||
Down Up
|
||||
======================
|
||||
← (+) (-) →
|
||||
<-- (+) (-) -->
|
||||
======================
|
||||
↗
|
||||
/^
|
||||
g_LeftPedalStart: INT_MAX (+)
|
||||
|
||||
lP = (LONG)g_LeftPedalStart - g_LeftPedal;
|
||||
lP 결과값은 무조건 음수
|
||||
lP result value is always negative
|
||||
*/
|
||||
|
||||
LONG lP = 0;
|
||||
@@ -2362,9 +2375,9 @@ void CRIOMAIN::UpdateThrottle (DIJOYSTATE &js)
|
||||
|
||||
Up Down
|
||||
======================
|
||||
← (-) (+) →
|
||||
<-- (-) (+) -->
|
||||
======================
|
||||
↗
|
||||
/^
|
||||
g_ThrottleStart: INT_MIN (-)
|
||||
*/
|
||||
|
||||
@@ -2447,11 +2460,11 @@ void CRIOMAIN::UpdateJoystick (DIJOYSTATE &js)
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
80 의 의미
|
||||
Meaning of 80
|
||||
|
||||
RIO (LEFT :120 ~ RIGHT :-80) 까지의 수를 돌려준다고 가정하고
|
||||
(LEFT의경우) RIGHT 의 최대값 80 이상인 값을 잘라버리고 나머지는
|
||||
버릴경우 LEFT 와 RIGHT가 동일한 속도로 움직일수 있다
|
||||
Assuming RIO returns values in range (LEFT:120 ~ RIGHT:-80)
|
||||
(In the LEFT case) clip values above the RIGHT maximum of 80, and the rest
|
||||
if discarded, LEFT and RIGHT can move at the same speed
|
||||
*/
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
LONG lJ;
|
||||
|
||||
@@ -19,16 +19,16 @@
|
||||
#include <MLR\MLRTexture.hpp>
|
||||
|
||||
#include "MWObject.hpp"
|
||||
//상훈짱 begin
|
||||
//sanghoon begin
|
||||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
|
||||
#include <GameOS\render.hpp>
|
||||
#define RADAR_SCALE 2.8f
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
|
||||
int m_gCool; // 鉉
|
||||
int m_gCool; // hyun: coolant
|
||||
|
||||
namespace MW4AI
|
||||
{
|
||||
@@ -121,22 +121,22 @@ GUIRadarManager::GUIRadarManager() :
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
|
||||
//상훈
|
||||
//sanghoon
|
||||
extern bool sh_game_started;
|
||||
|
||||
GUIRadarManager::~GUIRadarManager()
|
||||
{
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
sh_game_started=false;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
delete m_RangeText;
|
||||
|
||||
}
|
||||
|
||||
void DrawMapBoundary()
|
||||
{
|
||||
//DrawImplementation에서 추출해왔음..
|
||||
//미션이 시작한 후 한번만 그리게된다.(맵상의 작전 영역은 변하지 않으므로..)
|
||||
//Extracted from DrawImplementation..
|
||||
//Drawn only once after mission start (operation area on map does not change..)
|
||||
Scalar multx,multz;
|
||||
|
||||
multx = 200.0f/(MW4AI::MaxX - MW4AI::MinX);
|
||||
@@ -148,7 +148,7 @@ void DrawMapBoundary()
|
||||
int numpts = ptlist.GetLength ();
|
||||
|
||||
HDC hdcBackImage;
|
||||
radar_device.pDDSBackground->GetDC( &hdcBackImage);//백버퍼 준비용.. 이미지..
|
||||
radar_device.pDDSBackground->GetDC( &hdcBackImage);//Image for back buffer preparation..
|
||||
HPEN hpenold=(HPEN)SelectObject(hdcBackImage,CreatePen(PS_SOLID,1,RGB(255,0,0)));
|
||||
|
||||
for (int i=0;i<numpts;i++){
|
||||
@@ -184,7 +184,7 @@ void DrawMapBoundary()
|
||||
|
||||
void GUIRadarManager::Reset (void)
|
||||
{
|
||||
//상훈
|
||||
//sanghoon
|
||||
|
||||
MWApplication *m_App;
|
||||
m_App = MWApplication::GetInstance ();
|
||||
@@ -192,19 +192,19 @@ void GUIRadarManager::Reset (void)
|
||||
bool networking = MWApplication::GetInstance()->networkingFlag;
|
||||
if (!networking)
|
||||
m_RadarMode = 0;
|
||||
//상훈
|
||||
//sanghoon
|
||||
if(hsh_initialized)
|
||||
DrawMapBoundary();
|
||||
}
|
||||
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
/*
|
||||
char * radar_text[]={
|
||||
"JUMP\nJET","SHUT\nDOWN","OVER\nRIDE","FLUSH","CROUCH","",
|
||||
"RANGE","RADAR\nMODE","LIGHT\nAMP","SEARCH\nLIGHT","AUTO\nCENTER"
|
||||
};
|
||||
*/
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
//
|
||||
@@ -246,7 +246,7 @@ if(!hsh_initialized){
|
||||
Check_Pointer(vehicle);
|
||||
Check_Pointer(vehicle->GetSensor());
|
||||
/*
|
||||
//상훈 앞 맵
|
||||
//sanghoon begin: map
|
||||
Scalar multx,multz;
|
||||
|
||||
multx = 200.0f/(MW4AI::MaxX - MW4AI::MinX);
|
||||
@@ -655,7 +655,7 @@ if(!hsh_initialized){
|
||||
int i;
|
||||
|
||||
// Secondary Maps
|
||||
//맵과 맵 경계선을 그린다. (게임중에 변하지 않으므로 한번만 그린다.)
|
||||
//Draw map and boundary. (Drawn once since it does not change during game.)
|
||||
|
||||
if(!radar_device.MapDrawn){
|
||||
extern char AssetsDirectory1[MAX_PATH];
|
||||
@@ -724,8 +724,8 @@ if(!hsh_initialized){
|
||||
Check_Pointer(vehicle->GetSensor());
|
||||
|
||||
|
||||
///////////////////// MAP 시작 //////////////////////
|
||||
/////Torso Sweep그리기.. 시작
|
||||
///////////////////// MAP BEGIN //////////////////////
|
||||
/////Torso Sweep draw.. begin
|
||||
Scalar multx,multz;
|
||||
|
||||
multx = 200.0f/(MW4AI::MaxX - MW4AI::MinX);
|
||||
@@ -759,16 +759,16 @@ if(!hsh_initialized){
|
||||
radar_device.DrawQuad(-pos.x+240-1,-pos.y+508-1,-pos.x+240+2,-pos.y+508+2,0xFF0000C0);
|
||||
}
|
||||
|
||||
/////Torso Sweep그리기.. 끝
|
||||
/////Torso Sweep draw.. end
|
||||
|
||||
//맵상에 오브젝트들 그리기.
|
||||
//Draw objects on map.
|
||||
{
|
||||
radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
|
||||
MWObject *hsh_current_object;
|
||||
for(i=0;i<vehicle->GetSensor()->numberOfContacts;i++){
|
||||
hsh_current_object=vehicle->GetSensor()->GetSensorData()[i]->object.GetCurrent();
|
||||
if (hsh_current_object != NULL){
|
||||
bool draw_contact = true;//해당 오브젝트를 그릴것인지..에대한 플래그..
|
||||
bool draw_contact = true;//Flag: whether to draw this object..
|
||||
|
||||
// MSL 5.02 Bot on Map
|
||||
if (hsh_current_object->GetAI()==NULL && (MWApplication::GetInstance()->networkingFlag == false))draw_contact = false;
|
||||
@@ -833,10 +833,10 @@ if(!hsh_initialized){
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////// MAP 끝 //////////////////////
|
||||
///////////////////// MAP END //////////////////////
|
||||
|
||||
|
||||
///////////////////// RADAR 시작 //////////////////////
|
||||
///////////////////// RADAR BEGIN //////////////////////
|
||||
|
||||
radar_device.pD3DDevice->SetTexture(0,0);
|
||||
|
||||
@@ -855,7 +855,7 @@ if(!hsh_initialized){
|
||||
world_to_vehicle.Invert(vehicle_to_world);
|
||||
|
||||
|
||||
// 경계선 그리기..
|
||||
// Draw boundary line..
|
||||
|
||||
Mission *miss;
|
||||
miss = Mission::GetInstance ();
|
||||
@@ -900,7 +900,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
|
||||
|
||||
//Torso View그리기..
|
||||
//Draw Torso View..
|
||||
//HSH_RenderRadarTorsoView(-m_TorsoTwist);
|
||||
radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
|
||||
radar_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
|
||||
@@ -914,7 +914,7 @@ if(!hsh_initialized){
|
||||
radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER, D3DTFG_POINT );
|
||||
radar_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER, D3DTFG_POINT );
|
||||
|
||||
//Radar범위 그리기.
|
||||
//Draw Radar range.
|
||||
char text[10];
|
||||
if (radarRange != radarRangeOrg)
|
||||
sprintf (text,"NoLmt");
|
||||
@@ -923,11 +923,11 @@ if(!hsh_initialized){
|
||||
//HSH_DrawRadarNumber(345,386,text,1);
|
||||
radar_device.pFont[1].DrawText(80,350,0xFFFFFFFF,text,TEXTALIGN_ORG);
|
||||
|
||||
//ActiveMode그리기..
|
||||
//Draw ActiveMode..
|
||||
char* modechar=(vehicle->GetSensor ()->GetSensorMode () == Sensor::ActiveMode)?"Active":"Passive";
|
||||
radar_device.pFont[1].DrawText(395,350,0xFFFFFF,modechar,TEXTALIGN_ORG);
|
||||
|
||||
//빌딩 그리기
|
||||
//Draw buildings.
|
||||
MWObject *current_object;
|
||||
for(i=0;i<vehicle->GetSensor()->numberOfBuildingContacts;i++)
|
||||
{
|
||||
@@ -993,7 +993,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
}
|
||||
|
||||
//Object그리기.
|
||||
//Draw Objects.
|
||||
for(i=0;i<vehicle->GetSensor()->numberOfContacts;i++){
|
||||
current_object=vehicle->GetSensor()->GetSensorData()[i]->object.GetCurrent();
|
||||
if (current_object != NULL){
|
||||
@@ -1081,7 +1081,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
}
|
||||
|
||||
//Navigation Point그리기.
|
||||
//Draw Navigation Points.
|
||||
j=0;
|
||||
ChainIteratorOf<NavPoint *> iter (NavPoint::s_RevealedNavPoints);
|
||||
NavPoint *nav;
|
||||
@@ -1136,7 +1136,7 @@ if(!hsh_initialized){
|
||||
radar_device.DrawTexture(posx2,posy2,0xFFFFFFFF,(60+id*12),0,(60+id*12)+12,12);
|
||||
}
|
||||
|
||||
///////////////////// RADAR 끝 //////////////////////
|
||||
///////////////////// RADAR END //////////////////////
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1586,23 +1586,23 @@ if(!hsh_initialized){
|
||||
|
||||
|
||||
DWORD color = MakeColor (64,64,64,255);
|
||||
//막대 게이지의 백그라운드.. 기준..
|
||||
//Bar gauge background baseline..
|
||||
m_Textures[1]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
|
||||
color = MakeColor (255,255,255,255);
|
||||
loc.y += size.y - targetyval;
|
||||
size.y = (Scalar) targetyval;
|
||||
m_Textures[0]->TopLeft (m_Textures[0]->Left (),(Scalar) (m_BaseBottom - targetyval));
|
||||
m_Textures[0]->BlendMode (gos_BlendDecal);
|
||||
//삼색 막대 게이지 그리기..(clipping size를 조절함으로써.. 값을 조절하는 효과를 나타낸다.)
|
||||
//Draw tri-color bar gauge.. (value adjusted by modifying clip size..)
|
||||
|
||||
m_Textures[0]->Draw (loc,size,color,HUDTexture::NO_FLIP);
|
||||
color = MakeColor (0,125,0,250);
|
||||
size = Size ();
|
||||
loc = Location ();
|
||||
//막대 게이지의 프레임.
|
||||
//Bar gauge frame.
|
||||
DrawFrame ((int) (loc.x-2),(int) (loc.y-2),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
|
||||
//온도 텍스트의 프레임..
|
||||
//Temperature text frame..
|
||||
DrawFrame (261,542,303,560,color);
|
||||
m_HeatText->TopLeft (261,542);
|
||||
m_HeatText->BottomRight (303,560);
|
||||
@@ -1611,23 +1611,23 @@ if(!hsh_initialized){
|
||||
DWORD textw,texth;
|
||||
m_HeatText->DrawSize (textw,texth);
|
||||
|
||||
//온도를 정해진 색으로 출력한다.(게이지는 텍스쳐이므로 색을 지정할 필요가 없다.)
|
||||
//Display temperature in its designated color. (Gauge is a texture, no color spec needed.)
|
||||
m_HeatText->Draw (Point3D (282.0f - (textw/2.0f),551.0f - (texth/2.0f),0.9f));
|
||||
DrawLine (304,549,310,549,color);
|
||||
DrawLine (309,(int) heaty,309,549,color);
|
||||
DrawLine ((int) (loc.x-2),(int) (heaty),309,(int) (heaty),color);
|
||||
}else if(sh_step==1){
|
||||
//radar manager는 shutdown 시에 호출되지 않으므로.. 여기서 추가적으로 state를 업데이트 시켜준다.
|
||||
//radar manager is not called on shutdown.. state updated additionally here.
|
||||
MechWarrior4::VehicleInterface* p = MechWarrior4::VehicleInterface::GetInstance();
|
||||
p->GetGUIRadarStates(radar_device.recent_state);
|
||||
|
||||
int targetyval = (int) ((m_Heat * 23)/100.0f);
|
||||
Clamp (targetyval,0,22);
|
||||
//heat의 범위는??? 0~100???
|
||||
//What is the range of heat??? 0~100???
|
||||
|
||||
//target은 그리지 않고 현재 온도만 그린다.
|
||||
//Draw current temperature only, without the target.
|
||||
float sizey=256;
|
||||
//삼색 막대 게이지 그리기..(clipping size를 조절함으로써.. 값을 조절하는 효과를 나타낸다.)
|
||||
//Draw tri-color bar gauge.. (value adjusted by modifying clip size..)
|
||||
{
|
||||
radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
|
||||
//backbground image
|
||||
@@ -1642,7 +1642,7 @@ if(!hsh_initialized){
|
||||
radar_device.pD3DDevice->SetTexture(0,0);
|
||||
radar_device.DrawFrame(54-1,630-188-3,80+1,630+3,0xFFFFFFFF);
|
||||
}
|
||||
//텍스트
|
||||
//Text
|
||||
{
|
||||
char buf[16];
|
||||
// MSL 5.02 Heat Scale Header
|
||||
@@ -1664,7 +1664,7 @@ HUDJump::HUDJump ()
|
||||
m_TargetJump = -1.0f;
|
||||
Location (Point3D (467,539,0.9f));
|
||||
Size (Point3D (7,49,0.9f));
|
||||
//j라고 하는 작은 글자... <==실제로는 잘 보이지 않는다.
|
||||
//Small 'j' character... <==actually barely visible.
|
||||
AddTexture ("hud\\hud4",0,98,200,106,207);
|
||||
}
|
||||
|
||||
@@ -1703,14 +1703,14 @@ if(!hsh_initialized){
|
||||
size = Size ();
|
||||
loc = Location ();
|
||||
|
||||
DWORD color = MakeColor (255,255,255,250); // 원래 255,255,255,250이었음
|
||||
//j라고 하는 작은 글자...
|
||||
DWORD color = MakeColor (255,255,255,250); // was originally 255,255,255,250
|
||||
//Small 'j' character...
|
||||
m_Textures[0]->Draw (Point3D (loc.x+2,loc.y - m_Textures[0]->Size().y-2.0f,0.9f),m_Textures[0]->Size (),color);
|
||||
int targetyval = (int) (m_Jump * size.y);
|
||||
|
||||
color = MakeColor (0,125,0,250);
|
||||
|
||||
//녹색 게이지..
|
||||
//Green gauge..
|
||||
my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
if ((m_Jump != 0) && (m_Alpha != 0))
|
||||
{
|
||||
@@ -1718,11 +1718,11 @@ if(!hsh_initialized){
|
||||
my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
}
|
||||
|
||||
//게이지 맨위의 흰선..
|
||||
//White line at the top of gauge..
|
||||
color = MakeColor (255,255,255,200);
|
||||
DrawLine ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y-targetyval),color);
|
||||
|
||||
//테두리 그리기..
|
||||
//Draw border..
|
||||
color = MakeColor (0,125,0,250);
|
||||
DrawFrame ((int) loc.x,(int) (loc.y),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
}else if(sh_step==1){
|
||||
@@ -1736,7 +1736,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
}
|
||||
|
||||
//전반적으로 jumpjet과 거의 같다.
|
||||
//Overall almost identical to jumpjet.
|
||||
HUDCoolant::HUDCoolant ()
|
||||
{
|
||||
m_Alpha = 255;
|
||||
@@ -1745,7 +1745,7 @@ HUDCoolant::HUDCoolant ()
|
||||
m_Cool = 100;
|
||||
Location (Point3D (332,539,0.9f));
|
||||
Size (Point3D (7,49,0.9f));
|
||||
//C라고 하는 작은 글자..
|
||||
//Small 'C' character..
|
||||
AddTexture ("hud\\hud4",0,88,200,96,207);
|
||||
}
|
||||
|
||||
@@ -1782,7 +1782,7 @@ if(!hsh_initialized){
|
||||
loc = Location ();
|
||||
|
||||
DWORD color = MakeColor (0,125,0,250);
|
||||
//C라고 하는 작은 글자..
|
||||
//Small 'C' character..
|
||||
m_Textures[0]->Draw (Point3D (loc.x+2,loc.y - m_Textures[0]->Size().y-2.0f,0.9f),m_Textures[0]->Size (),color);
|
||||
|
||||
m_gCool = m_Cool;
|
||||
@@ -1790,19 +1790,19 @@ if(!hsh_initialized){
|
||||
Clamp (targetyval,0,(int) size.y);
|
||||
|
||||
color = MakeColor (0,100,255,250);
|
||||
//게이지 그리기..
|
||||
//Draw gauge..
|
||||
my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
if ((m_Cool != 0) && (m_Alpha != 0))
|
||||
{
|
||||
//flush했을때.. 흰색으로 깜박이는 효과 그리기...
|
||||
//When flushed.. draw white blinking effect...
|
||||
color = MakeColor (255,255,255,m_Alpha);
|
||||
my_DrawRect ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
}
|
||||
color = MakeColor (255,255,255,200);
|
||||
//게이지 위쪽의 흰선..
|
||||
//White line above gauge..
|
||||
DrawLine ((int) (loc.x),(int) (loc.y+size.y-targetyval),(int) (loc.x+size.x),(int) (loc.y+size.y-targetyval),color);
|
||||
|
||||
//게이지를 둘러싸는 프레임..
|
||||
//Frame surrounding gauge..
|
||||
color = MakeColor (0,125,0,250);
|
||||
DrawFrame ((int) loc.x,(int) (loc.y),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
}else if(sh_step==1){
|
||||
@@ -1817,7 +1817,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
|
||||
|
||||
//속도를 나타내는... HUD Component
|
||||
//HUD Component displaying speed...
|
||||
namespace NHUDSPEED
|
||||
{
|
||||
// const int for_speed_box[12] = {0,4,8,12,16,20,24,28,32,36,40,44};
|
||||
@@ -1928,25 +1928,25 @@ if(!hsh_initialized){
|
||||
speedy = loc.y + 56 - fred;
|
||||
|
||||
DWORD color = MakeColor (255,255,255,255);
|
||||
//게이지 백그라운드 눈금..
|
||||
//Gauge background tick marks..
|
||||
m_Textures[1]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
|
||||
loc.y += top;
|
||||
size.y = (Scalar) bottom - top;
|
||||
|
||||
//삼색 막대 게이지 그리기..(clipping size를 조절함으로써.. 값을 조절하는 효과를 나타낸다.)
|
||||
//Draw tri-color bar gauge.. (value adjusted by modifying clip size..)
|
||||
|
||||
m_Textures[0]->TopLeft (m_Textures[0]->Left (),(Scalar) (top));
|
||||
m_Textures[0]->BottomRight (m_Textures[0]->Right (),(Scalar) (bottom));
|
||||
m_Textures[0]->BlendMode (gos_BlendDecal);
|
||||
//colored 게이지..녹색으로 되어 있다.
|
||||
//Colored gauge.. currently green.
|
||||
m_Textures[0]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
|
||||
color = MakeColor (0,125,0,250);
|
||||
size = Size ();
|
||||
loc = Location ();
|
||||
//게이지를 둘러싸는.. 프레임 그리기..
|
||||
//Draw frame surrounding gauge..
|
||||
DrawFrame ((int) (loc.x-2),(int) (loc.y-2),(int) (loc.x+size.x),(int) (loc.y+size.y),color);
|
||||
|
||||
//속도 표시하는 프레임...
|
||||
//Speed display frame...
|
||||
DrawFrame (506,537,548,555,color);
|
||||
m_SpeedText->TopLeft (506,537);
|
||||
m_SpeedText->BottomRight (548,555);
|
||||
@@ -1958,15 +1958,15 @@ if(!hsh_initialized){
|
||||
|
||||
DWORD textw,texth;
|
||||
m_SpeedText->DrawSize (textw,texth);
|
||||
//속도 표시하는 텍스트.. 앞/뒤 방향에 따라서 색이 녹식/파란색.....으로 된다.
|
||||
//Speed text.. color is green/blue depending on forward/backward direction.....
|
||||
m_SpeedText->Draw (Point3D (527.0f - (textw/2.0f),546.0f - (texth/2.0f),0.9f));
|
||||
//속도프레임-게이지 프레임 연결하는 3 segment라인..
|
||||
//3-segment line connecting speed frame to gauge frame..
|
||||
DrawLine (498,549,506,549,color);
|
||||
DrawLine (498,(int) speedy,498,549,color);
|
||||
DrawLine ((int) (loc.x+size.x+2),(int) (speedy),498,(int) (speedy),color);
|
||||
}else if(sh_step==1){
|
||||
//적절하지는 않지만.. 미션 시간을 speed에서 같이 그린다.
|
||||
//미션 시간 그리기...hudtimer.cpp에 DrawImplementation에서 따온것임..
|
||||
//Not ideal, but draw mission time alongside speed display.
|
||||
//Draw mission timer... taken from DrawImplementation in hudtimer.cpp..
|
||||
{
|
||||
MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
|
||||
Verify (mwmiss);
|
||||
@@ -1983,7 +1983,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
|
||||
float offset;
|
||||
//126,62.. 188의 속도.. 2:1로 나누면..
|
||||
//126,62.. speed 188.. divided 2:1..
|
||||
|
||||
//backbground image
|
||||
radar_device.pD3DDevice->SetTexture(0,radar_device.pDDSTexture);
|
||||
@@ -2094,8 +2094,8 @@ HUDNav::HUDNav()
|
||||
navPointName = new HUDText ();
|
||||
navPointRange = new HUDNumberText ();
|
||||
playerAngle = new HUDNumberText ();
|
||||
navPointRange->SetSize (HUDText::MEDIUM_SIZE); // 원래 SMALL_SIZE였음
|
||||
playerAngle->SetSize (HUDText::MEDIUM_SIZE); // 원래 SMALL_SIZE였음
|
||||
navPointRange->SetSize (HUDText::MEDIUM_SIZE); // was originally SMALL_SIZE
|
||||
playerAngle->SetSize (HUDText::MEDIUM_SIZE); // was originally SMALL_SIZE
|
||||
|
||||
m_NavAlphaTime = 0;
|
||||
|
||||
@@ -2203,14 +2203,14 @@ if(!hsh_initialized){
|
||||
m_Textures[10]->TopLeft ((Scalar) (m_BaseLeft + offset),m_Textures[10]->Top ());
|
||||
size = m_Textures[10]->Size ();
|
||||
m_Textures[10]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
|
||||
//2번 aux의 줄자..의 대부분...(이걸로 표시되지 않을때.. 다음걸로 표시한다.)
|
||||
//Main portion of aux2 ruler... (if not displayable here, use next one.)
|
||||
#if 1
|
||||
loc.x += size.x;
|
||||
loc.x-=1;
|
||||
m_Textures[13]->BottomRight ((Scalar) m_BaseLeft+offset,m_Textures[13]->Bottom ());
|
||||
size = m_Textures[13]->Size ();
|
||||
m_Textures[13]->Draw (loc,size,color,HUDTexture::NO_FLIP,true);
|
||||
//2번 aux의 줄자의 짦은 부분....
|
||||
//Short tick marks of aux2 ruler....
|
||||
#endif
|
||||
|
||||
int heading = m_PlayerFacing;
|
||||
@@ -2223,7 +2223,7 @@ if(!hsh_initialized){
|
||||
bool draw = false;
|
||||
if (dir < 0)
|
||||
dir += 360;
|
||||
else if (dir > 360)//상훈 고침.. 원래는 --> "else if (dir > 360)" 였음..
|
||||
else if (dir > 360)//sanghoon fix: original was --> "else if (dir > 360)"..
|
||||
dir -= 360;
|
||||
switch (dir)
|
||||
{
|
||||
@@ -2265,11 +2265,11 @@ if(!hsh_initialized){
|
||||
navText[textid]->DrawSize (dx,dy);
|
||||
textloc.x -= dx/2;
|
||||
navText[textid]->Draw (textloc);
|
||||
//2번 aux방위각 표시.. 340 350 N 10 20...
|
||||
//Aux2 bearing display.. 340 350 N 10 20...
|
||||
}
|
||||
}
|
||||
|
||||
//2번 aux mech의 방향각도 표시...
|
||||
//Aux2 mech heading angle display...
|
||||
color = Color ();
|
||||
DrawFrame (400-13,10,400+13,22,color);
|
||||
DWORD dx,dy;
|
||||
@@ -2288,7 +2288,7 @@ if(!hsh_initialized){
|
||||
size = m_Textures[11]->Size ();
|
||||
color = Color ();
|
||||
m_Textures[11]->Draw (Point3D (400.0f,44.0f,0.9f),size,color);
|
||||
//2번 aux 중심표시.. 역삼각형..(매우작음)
|
||||
//Aux2 center indicator.. inverted triangle.. (very small)
|
||||
|
||||
if (m_NavPointRange != -1)
|
||||
{
|
||||
@@ -2299,9 +2299,9 @@ if(!hsh_initialized){
|
||||
textloc.y = 0;
|
||||
textloc.z = 0;
|
||||
// Draw navpoint bug or arrows
|
||||
//2번 aux navigation
|
||||
//navpoint bug:... 목표를 나타내는 동그라미를 발한다.(ruler안에 표시가능할때)
|
||||
//arrow ruler안에 표시가 불가능할때.. 방향만 좌/우 화살표로서 표시한다.
|
||||
//Aux2 navigation
|
||||
//navpoint: draw circle indicating objective (when displayable in ruler)
|
||||
//When unable to display in arrow ruler.. show direction with left/right arrow only.
|
||||
DWORD color = (m_NavAlpha << 24) + 0x00AF00;
|
||||
|
||||
size = Size ();
|
||||
@@ -2346,7 +2346,7 @@ if(!hsh_initialized){
|
||||
textloc.y += 5;
|
||||
textloc.z = 0.9f;
|
||||
}
|
||||
//지점 타켓의 이름을 그린다.
|
||||
//Draw the name of the point target.
|
||||
DWORD dx,dy;
|
||||
navPointName->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
|
||||
navPointName->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
|
||||
@@ -2357,7 +2357,7 @@ if(!hsh_initialized){
|
||||
navPointName->Draw (textloc);
|
||||
textloc.x += dx/2;
|
||||
|
||||
//지점 타켓의 거리를 그린다.
|
||||
//Draw distance to point target.
|
||||
textloc.y += 12.0f;
|
||||
navPointName->TopLeft (textloc.x-50.0f,textloc.y-2.0f);
|
||||
navPointName->BottomRight (textloc.x+50.0f,textloc.y+20.0f);
|
||||
@@ -2503,7 +2503,7 @@ if(!hsh_initialized){
|
||||
if(VehGetShutdownState()!=1)
|
||||
{
|
||||
mfd_device.DrawTexture(120,140,0xFFFFFFFF,testoffset+1,256,testoffset+402+1,256+18);
|
||||
//눈금위의 방위각 그리기
|
||||
//Draw bearing above tick marks
|
||||
int heading = m_PlayerFacing;
|
||||
int ii=0;
|
||||
for (int i=heading-20;i<=heading+20;i++,ii++){
|
||||
@@ -2521,7 +2521,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
|
||||
mfd_device.pD3DDevice->SetTexture(0,0);
|
||||
//현재 방위각 그리기
|
||||
//Draw current bearing
|
||||
{
|
||||
char text[8];
|
||||
wsprintf(text,"%d",(int)m_PlayerFacing);
|
||||
@@ -2530,19 +2530,19 @@ if(!hsh_initialized){
|
||||
}
|
||||
mfd_device.pD3DDevice->SetTexture(0,mfd_device.pDDSTexture);
|
||||
|
||||
//중심표시 역삼각형(매우작음) 그리기
|
||||
//Draw center-indicator inverted triangle (very small)
|
||||
mfd_device.DrawTexture(320-5,140,0xFFFFFFFF,59,30+256,70,39+256);
|
||||
|
||||
//목표 그리기.
|
||||
if (m_NavPointRange != -1){//목표 지점이 있을때.
|
||||
//Draw objective.
|
||||
if (m_NavPointRange != -1){//when a target waypoint exists.
|
||||
int hsh_textpos=0;
|
||||
//목표 표시 그리기.
|
||||
//Draw objective indicator.
|
||||
if ((m_NavPointFacing > -20) && (m_NavPointFacing < 20)){
|
||||
//방위각 내에 있을때.. 버그를 그린다.
|
||||
//When inside bearing range.. draw indicator.
|
||||
mfd_device.DrawTexture((int)(320-9-m_NavPointFacing*10),140+4,0xFFFFFFFF,87,28+256,106,47+256);
|
||||
hsh_textpos=(int)(320-m_NavPointFacing*10);
|
||||
}else{
|
||||
//방위각 밖에 있을때.. 화살표를 그린다.
|
||||
//When outside bearing range.. draw arrow.
|
||||
if (m_NavPointFacing <= -10){
|
||||
mfd_device.DrawTexture(520+4,140,0xFFFFFFFF,3,54+256,39,81+256);
|
||||
hsh_textpos=520;
|
||||
@@ -2552,12 +2552,12 @@ if(!hsh_initialized){
|
||||
}
|
||||
}
|
||||
|
||||
//목표 이름과 거리(텍스트) 그리기.
|
||||
//Draw objective name and distance (text).
|
||||
mfd_device.pFont[0].DrawText(hsh_textpos,140+26,0xFFFFFFFF,m_NavPointName,TEXTALIGN_CENTER);
|
||||
mfd_device.pFont[0].DrawText(hsh_textpos,140+46,0xFFFFFFFF,m_NavPointRangeText,TEXTALIGN_CENTER);
|
||||
}
|
||||
}
|
||||
//반드시.. scroe정보 그리는 루틴을 추가할것..
|
||||
//Must add routine to draw score info here..
|
||||
{
|
||||
char score[32]={0};
|
||||
char kills[32]={0};
|
||||
|
||||
@@ -51,9 +51,9 @@ namespace MechWarrior4
|
||||
Stuff::Scalar m_TorsoTwist;
|
||||
int m_RadarMode;
|
||||
stlport::vector<ShotEntry> m_ShotList;
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
int hsh_fdraw;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
bool OnShotList (ObjectID who);
|
||||
void ClipLine (Scalar& xpt1,Scalar& ypt1,Scalar& xpt2,Scalar& ypt2,Scalar cx,Scalar cy,Scalar rad);
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
void InitComFuncs (void);
|
||||
void KillComFuncs (void);
|
||||
|
||||
// úè - start
|
||||
// hyun begin
|
||||
typedef long LONG;
|
||||
typedef struct DIJOYSTATE {
|
||||
LONG lX;
|
||||
@@ -141,7 +141,7 @@ extern void (__stdcall *g_pfnRIO_ButtonEvent)(BYTE* by);
|
||||
extern void __stdcall RIO_Joy(DIJOYSTATE& js);
|
||||
extern void __stdcall RIO_ButEvent(BYTE* by);
|
||||
|
||||
// úè - end
|
||||
// hyun end
|
||||
|
||||
namespace MW4AI
|
||||
{
|
||||
@@ -200,13 +200,13 @@ Stuff::Scalar MechWarrior4::DECRYPT (Stuff::Scalar value)
|
||||
void
|
||||
MechWarrior4::InitializeClasses(Stuff::NotationFile *startup_ini)
|
||||
{
|
||||
// úè - start
|
||||
// hyun begin
|
||||
if (g_bUseOrgJoy)
|
||||
g_pfnRIO_Joy = NULL;
|
||||
else
|
||||
g_pfnRIO_Joy = RIO_Joy;
|
||||
g_pfnRIO_ButtonEvent = RIO_ButEvent;
|
||||
// úè - end
|
||||
// hyun end
|
||||
|
||||
Verify(!g_LibraryHeap);
|
||||
g_LibraryHeap = gos_CreateMemoryHeap("MechWarrior4(All)");
|
||||
@@ -753,8 +753,8 @@ void
|
||||
gos_DestroyMemoryHeap(g_LibraryHeap);
|
||||
g_LibraryHeap = NULL;
|
||||
|
||||
// úè - start
|
||||
// hyun begin
|
||||
g_pfnRIO_ButtonEvent = NULL;
|
||||
g_pfnRIO_Joy = NULL;
|
||||
// úè - end
|
||||
// hyun end
|
||||
}
|
||||
|
||||
@@ -132,6 +132,10 @@ extern SCRIPTCALLBACK(CTCL_GetMissionState);
|
||||
extern SCRIPTCALLBACK(CTCL_DoBreak);
|
||||
extern SCRIPTCALLBACK(CTCL_IsGameLoaded);
|
||||
extern SCRIPTCALLBACK(CTCL_DoReprint);
|
||||
extern SCRIPTCALLBACK(CTCL_LoadAutoFile);
|
||||
extern SCRIPTCALLBACK(CTCL_GetAutoSlotName);
|
||||
extern SCRIPTCALLBACK(CTCL_GetAutoSlotMech);
|
||||
extern SCRIPTCALLBACK(CTCL_GetAutoSlotInt);
|
||||
extern SCRIPTCALLBACK(CTCL_CheckPlayMovie);
|
||||
extern SCRIPTCALLBACK(CTCL_CheckCoinCounts);
|
||||
extern SCRIPTCALLBACK(CTCL_CheckUseJPD);
|
||||
@@ -158,6 +162,53 @@ int g_nWhyPaused = 0; // 0: not paused - invitation in menu-state, 1: briefing,
|
||||
extern SCRIPTCALLBACK(CTCL_WhyPaused);
|
||||
int g_nTimeList_Index = 3; // 3rd item in listbox...
|
||||
int g_nTimeList_Value = 7; // 7 minutes
|
||||
// [RookieMission] options.ini overrides ? defaults match the hardcoded script values
|
||||
char g_szRookieMission[256] = "ScarabStronghold - Attrition";
|
||||
char* g_pszRookieMission = g_szRookieMission; // pointer used for script registration
|
||||
int g_nRookieGameType = 2; // Attrition index in game-type list
|
||||
int g_nRookieVisibility = 0; // 0=clear
|
||||
int g_nRookieWeather = 0; // 0=off
|
||||
int g_nRookieTimeOfDay = 0; // 0=day
|
||||
int g_nRookieTimeLimit = -1; // -1=use g_nTimeList_Value
|
||||
int g_nRookieRadar = 0; // 0=novice
|
||||
int g_nRookieHeat = 0; // 0=off
|
||||
int g_nRookieFriendlyFire= 0;
|
||||
int g_nRookieSplash = 0;
|
||||
int g_nRookieUnlimitedAmmo = 1; // 1=on (be cautious)
|
||||
int g_nRookieWeaponJam = 0;
|
||||
int g_nRookieAdvanceMode = 0;
|
||||
int g_nRookieArmorMode = 0;
|
||||
// [automaticmode] options.ini ? Load File button
|
||||
struct SAutoFileSlot {
|
||||
char szName[64]; // pilot name
|
||||
char szMech[64]; // mech display name (matched against mech[] array)
|
||||
int nType; // 0=empty, 1=player, 2-9=bot difficulty level
|
||||
int nTeam;
|
||||
int nSkin;
|
||||
int nDecal;
|
||||
};
|
||||
static SAutoFileSlot g_aAutoSlots[16];
|
||||
static int g_nAutoSlotsCount = 0;
|
||||
static int g_bAutomaticMode = 0;
|
||||
static char g_szAutomaticFile[MAX_PATH] = "";
|
||||
// [automaticmode] game option globals ? separate from Rookie Mission defaults to preserve Default button behavior
|
||||
static char g_szAutoMission[256] = "";
|
||||
static char* g_pszAutoMission = g_szAutoMission;
|
||||
static int g_nAutoGameType = 2; // Attrition
|
||||
static int g_nAutoVisibility = 0;
|
||||
static int g_nAutoWeather = 0;
|
||||
static int g_nAutoTimeOfDay = 0;
|
||||
static int g_nAutoTimeLimit = -1; // -1 = server default
|
||||
static int g_nAutoRadar = 0;
|
||||
static int g_nAutoHeat = 0;
|
||||
static int g_nAutoFriendlyFire = 0;
|
||||
static int g_nAutoSplash = 0;
|
||||
static int g_nAutoUnlimitedAmmo = 1;
|
||||
static int g_nAutoWeaponJam = 0;
|
||||
static int g_nAutoAdvanceMode = 0;
|
||||
static int g_nAutoArmorMode = 0;
|
||||
static int g_nAutoTeamAllowed = 0; // 0=FFA 1=team game; set via TeamAllowed= in [mission]
|
||||
static int g_nAutoTeamCount = 2; // number of teams when TeamAllowed=1
|
||||
// MSL 5.06
|
||||
int g_nMechVariant = 0;
|
||||
int g_nMechLabOp = 0;
|
||||
@@ -727,6 +778,54 @@ void MW4Shell::StartUp()
|
||||
gosScript_RegisterCallback("CTCL_WhyPaused",&CTCL_WhyPaused,GOSVAR_INT,0,NULL);
|
||||
gosScript_RegisterVariable("g_nTimeList_Index", &g_nTimeList_Index, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nTimeList_Value", &g_nTimeList_Value, GOSVAR_INT, 0, NULL);
|
||||
// [RookieMission] ini-driven defaults
|
||||
gosScript_RegisterVariable("g_szRookieMission", &g_pszRookieMission, GOSVAR_STRING, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieGameType", &g_nRookieGameType, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieVisibility", &g_nRookieVisibility, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieWeather", &g_nRookieWeather, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieTimeOfDay", &g_nRookieTimeOfDay, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieTimeLimit", &g_nRookieTimeLimit, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieRadar", &g_nRookieRadar, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieHeat", &g_nRookieHeat, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieFriendlyFire",&g_nRookieFriendlyFire, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieSplash", &g_nRookieSplash, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieUnlimitedAmmo",&g_nRookieUnlimitedAmmo,GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieWeaponJam", &g_nRookieWeaponJam, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieAdvanceMode", &g_nRookieAdvanceMode, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nRookieArmorMode", &g_nRookieArmorMode, GOSVAR_INT, 0, NULL);
|
||||
// [automaticmode] callbacks + g_bAutomaticMode variable for script visibility
|
||||
gosScript_RegisterVariable("g_bAutomaticMode", &g_bAutomaticMode, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterCallback("CTCL_LoadAutoFile", &CTCL_LoadAutoFile, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterCallback("CTCL_GetAutoSlotName", &CTCL_GetAutoSlotName, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterCallback("CTCL_GetAutoSlotMech", &CTCL_GetAutoSlotMech, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterCallback("CTCL_GetAutoSlotInt", &CTCL_GetAutoSlotInt, GOSVAR_INT, 0, NULL);
|
||||
{
|
||||
NotationFile opts("options.ini", NotationFile::Standard, true);
|
||||
Page *pAuto = opts.FindPage("automaticmode");
|
||||
if (pAuto) {
|
||||
pAuto->GetEntry("automaticmode", &g_bAutomaticMode);
|
||||
const char *sz = NULL;
|
||||
if (pAuto->GetEntry("automaticfile", &sz) && sz)
|
||||
strncpy(g_szAutomaticFile, sz, sizeof(g_szAutomaticFile)-1);
|
||||
}
|
||||
}
|
||||
// [automaticmode] game option variables (separate from Rookie globals)
|
||||
gosScript_RegisterVariable("g_szAutoMission", &g_pszAutoMission, GOSVAR_STRING, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoGameType", &g_nAutoGameType, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoVisibility", &g_nAutoVisibility, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoWeather", &g_nAutoWeather, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoTimeOfDay", &g_nAutoTimeOfDay, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoTimeLimit", &g_nAutoTimeLimit, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoRadar", &g_nAutoRadar, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoHeat", &g_nAutoHeat, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoFriendlyFire", &g_nAutoFriendlyFire, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoSplash", &g_nAutoSplash, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoUnlimitedAmmo",&g_nAutoUnlimitedAmmo, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoWeaponJam", &g_nAutoWeaponJam, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoAdvanceMode", &g_nAutoAdvanceMode, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoArmorMode", &g_nAutoArmorMode, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoTeamAllowed", &g_nAutoTeamAllowed, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nAutoTeamCount", &g_nAutoTeamCount, GOSVAR_INT, 0, NULL);
|
||||
// MSL 5.06
|
||||
gosScript_RegisterVariable("g_nMechVariant", &g_nMechVariant, GOSVAR_INT, 0, NULL);
|
||||
gosScript_RegisterVariable("g_nMechLabOp", &g_nMechLabOp, GOSVAR_INT, 0, NULL);
|
||||
@@ -1108,6 +1207,44 @@ void MW4Shell::ShutDown()
|
||||
// jcem - start
|
||||
gosScript_UnregisterVariable("g_nTimeList_Value");
|
||||
gosScript_UnregisterVariable("g_nTimeList_Index");
|
||||
// [RookieMission] globals
|
||||
gosScript_UnregisterVariable("g_szRookieMission");
|
||||
gosScript_UnregisterVariable("g_nRookieGameType");
|
||||
gosScript_UnregisterVariable("g_nRookieVisibility");
|
||||
gosScript_UnregisterVariable("g_nRookieWeather");
|
||||
gosScript_UnregisterVariable("g_nRookieTimeOfDay");
|
||||
gosScript_UnregisterVariable("g_nRookieTimeLimit");
|
||||
gosScript_UnregisterVariable("g_nRookieRadar");
|
||||
gosScript_UnregisterVariable("g_nRookieHeat");
|
||||
gosScript_UnregisterVariable("g_nRookieFriendlyFire");
|
||||
gosScript_UnregisterVariable("g_nRookieSplash");
|
||||
gosScript_UnregisterVariable("g_nRookieUnlimitedAmmo");
|
||||
gosScript_UnregisterVariable("g_nRookieWeaponJam");
|
||||
gosScript_UnregisterVariable("g_nRookieAdvanceMode");
|
||||
gosScript_UnregisterVariable("g_nRookieArmorMode");
|
||||
// [automaticmode] callbacks + variable
|
||||
gosScript_UnregisterCallback("CTCL_GetAutoSlotInt");
|
||||
gosScript_UnregisterCallback("CTCL_GetAutoSlotMech");
|
||||
gosScript_UnregisterCallback("CTCL_GetAutoSlotName");
|
||||
gosScript_UnregisterCallback("CTCL_LoadAutoFile");
|
||||
gosScript_UnregisterVariable("g_bAutomaticMode");
|
||||
// [automaticmode] game option variables
|
||||
gosScript_UnregisterVariable("g_nAutoTeamCount");
|
||||
gosScript_UnregisterVariable("g_nAutoTeamAllowed");
|
||||
gosScript_UnregisterVariable("g_nAutoArmorMode");
|
||||
gosScript_UnregisterVariable("g_nAutoAdvanceMode");
|
||||
gosScript_UnregisterVariable("g_nAutoWeaponJam");
|
||||
gosScript_UnregisterVariable("g_nAutoUnlimitedAmmo");
|
||||
gosScript_UnregisterVariable("g_nAutoSplash");
|
||||
gosScript_UnregisterVariable("g_nAutoFriendlyFire");
|
||||
gosScript_UnregisterVariable("g_nAutoHeat");
|
||||
gosScript_UnregisterVariable("g_nAutoRadar");
|
||||
gosScript_UnregisterVariable("g_nAutoTimeLimit");
|
||||
gosScript_UnregisterVariable("g_nAutoTimeOfDay");
|
||||
gosScript_UnregisterVariable("g_nAutoWeather");
|
||||
gosScript_UnregisterVariable("g_nAutoVisibility");
|
||||
gosScript_UnregisterVariable("g_nAutoGameType");
|
||||
gosScript_UnregisterVariable("g_szAutoMission");
|
||||
// MSL 5.06
|
||||
gosScript_UnregisterVariable("g_nBlackMech");
|
||||
gosScript_UnregisterVariable("g_nMechVariant");
|
||||
@@ -1828,7 +1965,8 @@ int MW4Shell::SetNetworkMissionParamater(void * instance, int numParms, void **d
|
||||
case PLAYER_LIMIT_PARAMETER:
|
||||
params->m_playerLimit = INTPARM(1);
|
||||
Min_Clamp(params->m_playerLimit, Network::GetInstance()->GetPlayerCount());
|
||||
Environment.NetworkMaxPlayers = params->m_playerLimit;
|
||||
// Add camera slots on top of the pilot limit so cameraships can still connect
|
||||
Environment.NetworkMaxPlayers = params->m_playerLimit + (CTCL_GetTeslaCountAll() - CTCL_GetTeslaCount());
|
||||
gos_NetServerCommands(gos_Commend_UpdateMaxPlayers,0);
|
||||
break;
|
||||
|
||||
@@ -12731,6 +12869,143 @@ int __stdcall CTCL_SetCDSP(void* instance, int args, void* data[])
|
||||
{
|
||||
ASSERT(CTCL_IsConsole());
|
||||
CTCL_DefaultHostSetup(1);
|
||||
// Read [RookieMission] section from options.ini and populate script globals.
|
||||
// Missing keys leave globals at their initialised defaults (backward-compatible).
|
||||
{
|
||||
NotationFile options_ini("options.ini", NotationFile::Standard, true);
|
||||
Page *page = options_ini.FindPage("RookieMission");
|
||||
if (page)
|
||||
{
|
||||
const char *sz = NULL;
|
||||
if (page->GetEntry("MissionName", &sz) && sz)
|
||||
{
|
||||
strncpy(g_szRookieMission, sz, sizeof(g_szRookieMission) - 1);
|
||||
g_szRookieMission[sizeof(g_szRookieMission) - 1] = '\0';
|
||||
}
|
||||
page->GetEntry("GameType", &g_nRookieGameType);
|
||||
page->GetEntry("Visibility", &g_nRookieVisibility);
|
||||
page->GetEntry("Weather", &g_nRookieWeather);
|
||||
page->GetEntry("TimeOfDay", &g_nRookieTimeOfDay);
|
||||
page->GetEntry("TimeLimit", &g_nRookieTimeLimit);
|
||||
page->GetEntry("Radar", &g_nRookieRadar);
|
||||
page->GetEntry("HeatOn", &g_nRookieHeat);
|
||||
page->GetEntry("FriendlyFire", &g_nRookieFriendlyFire);
|
||||
page->GetEntry("SplashDamage", &g_nRookieSplash);
|
||||
page->GetEntry("UnlimitedAmmo", &g_nRookieUnlimitedAmmo);
|
||||
page->GetEntry("WeaponJam", &g_nRookieWeaponJam);
|
||||
page->GetEntry("AdvanceMode", &g_nRookieAdvanceMode);
|
||||
page->GetEntry("ArmorMode", &g_nRookieArmorMode);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// [automaticmode] Load File button ? reads automatic file into Rookie Mission globals + per-slot data.
|
||||
// Returns 1 if the file was found and loaded, 0 otherwise. File is NOT consumed (stays on disk).
|
||||
int __stdcall CTCL_LoadAutoFile(void* instance, int args, void* data[])
|
||||
{
|
||||
if (!g_bAutomaticMode || !g_szAutomaticFile[0])
|
||||
return 0;
|
||||
if (GetFileAttributes(g_szAutomaticFile) == 0xFFFFFFFF)
|
||||
return 0;
|
||||
|
||||
NotationFile autofile(g_szAutomaticFile, NotationFile::Standard, true);
|
||||
|
||||
// Game options ? stored in dedicated Auto globals, NOT Rookie Mission globals,
|
||||
// so the Default button continues to use the original [RookieMission] defaults.
|
||||
g_szAutoMission[0] = '\0';
|
||||
g_nAutoGameType = 2; g_nAutoVisibility = 0; g_nAutoWeather = 0;
|
||||
g_nAutoTimeOfDay = 0; g_nAutoTimeLimit = -1; g_nAutoRadar = 0;
|
||||
g_nAutoHeat = 0; g_nAutoFriendlyFire = 0; g_nAutoSplash = 0;
|
||||
g_nAutoUnlimitedAmmo = 1; g_nAutoWeaponJam = 0; g_nAutoAdvanceMode = 0;
|
||||
g_nAutoArmorMode = 0; g_nAutoTeamAllowed = 0; g_nAutoTeamCount = 2;
|
||||
|
||||
Page *pMission = autofile.FindPage("mission");
|
||||
if (pMission) {
|
||||
const char *sz = NULL;
|
||||
if (pMission->GetEntry("MissionName", &sz) && sz) {
|
||||
strncpy(g_szAutoMission, sz, sizeof(g_szAutoMission)-1);
|
||||
g_szAutoMission[sizeof(g_szAutoMission)-1] = '\0';
|
||||
}
|
||||
pMission->GetEntry("GameType", &g_nAutoGameType);
|
||||
pMission->GetEntry("Visibility", &g_nAutoVisibility);
|
||||
pMission->GetEntry("Weather", &g_nAutoWeather);
|
||||
pMission->GetEntry("TimeOfDay", &g_nAutoTimeOfDay);
|
||||
pMission->GetEntry("TimeLimit", &g_nAutoTimeLimit);
|
||||
pMission->GetEntry("Radar", &g_nAutoRadar);
|
||||
pMission->GetEntry("HeatOn", &g_nAutoHeat);
|
||||
pMission->GetEntry("FriendlyFire", &g_nAutoFriendlyFire);
|
||||
pMission->GetEntry("SplashDamage", &g_nAutoSplash);
|
||||
pMission->GetEntry("UnlimitedAmmo", &g_nAutoUnlimitedAmmo);
|
||||
pMission->GetEntry("WeaponJam", &g_nAutoWeaponJam);
|
||||
pMission->GetEntry("AdvanceMode", &g_nAutoAdvanceMode);
|
||||
pMission->GetEntry("ArmorMode", &g_nAutoArmorMode);
|
||||
pMission->GetEntry("TeamAllowed", &g_nAutoTeamAllowed);
|
||||
pMission->GetEntry("TeamCount", &g_nAutoTeamCount);
|
||||
}
|
||||
|
||||
// Per-slot data (up to 16 slots via [slot0]..[slot15] pages)
|
||||
g_nAutoSlotsCount = 0;
|
||||
memset(g_aAutoSlots, 0, sizeof(g_aAutoSlots));
|
||||
char szPageName[16];
|
||||
for (int i = 0; i < 16; i++) {
|
||||
sprintf(szPageName, "slot%d", i);
|
||||
Page *pSlot = autofile.FindPage(szPageName);
|
||||
if (!pSlot) break;
|
||||
g_nAutoSlotsCount = i + 1;
|
||||
const char *sz = NULL;
|
||||
if (pSlot->GetEntry("PilotName", &sz) && sz)
|
||||
strncpy(g_aAutoSlots[i].szName, sz, sizeof(g_aAutoSlots[i].szName)-1);
|
||||
sz = NULL;
|
||||
if (pSlot->GetEntry("Mech", &sz) && sz)
|
||||
strncpy(g_aAutoSlots[i].szMech, sz, sizeof(g_aAutoSlots[i].szMech)-1);
|
||||
pSlot->GetEntry("Type", &g_aAutoSlots[i].nType);
|
||||
pSlot->GetEntry("Team", &g_aAutoSlots[i].nTeam);
|
||||
pSlot->GetEntry("Skin", &g_aAutoSlots[i].nSkin);
|
||||
pSlot->GetEntry("Decal", &g_aAutoSlots[i].nDecal);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns pilot name string for slot k ? data[0]=string output buffer, data[1]=int k
|
||||
int __stdcall CTCL_GetAutoSlotName(void* instance, int args, void* data[])
|
||||
{
|
||||
int k = INTPARM(1);
|
||||
const char *sz = (k >= 0 && k < 16) ? g_aAutoSlots[k].szName : "";
|
||||
if (STRPARM(0)) gos_Free(STRPARM(0));
|
||||
STRPARM(0) = (char *)gos_Malloc(64);
|
||||
strncpy(STRPARM(0), sz, 63);
|
||||
STRPARM(0)[63] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns mech display name for slot k ? data[0]=string output buffer, data[1]=int k
|
||||
int __stdcall CTCL_GetAutoSlotMech(void* instance, int args, void* data[])
|
||||
{
|
||||
int k = INTPARM(1);
|
||||
const char *sz = (k >= 0 && k < 16) ? g_aAutoSlots[k].szMech : "";
|
||||
if (STRPARM(0)) gos_Free(STRPARM(0));
|
||||
STRPARM(0) = (char *)gos_Malloc(64);
|
||||
strncpy(STRPARM(0), sz, 63);
|
||||
STRPARM(0)[63] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Returns int field for slot k ? data[0]=int k, data[1]=int field (0=Type 1=Team 2=Skin 3=Decal)
|
||||
// field is passed as a script literal (0/1/2/3), so use VALUEPARM not INTPARM (literals are passed
|
||||
// as (void*)N directly, not as pointers; INTPARM would dereference NULL for field=0 and crash).
|
||||
int __stdcall CTCL_GetAutoSlotInt(void* instance, int args, void* data[])
|
||||
{
|
||||
int k = INTPARM(0);
|
||||
int field = VALUEPARM(1);
|
||||
if (k < 0 || k >= 16) return 0;
|
||||
switch (field) {
|
||||
case 0: return g_aAutoSlots[k].nType;
|
||||
case 1: return g_aAutoSlots[k].nTeam;
|
||||
case 2: return g_aAutoSlots[k].nSkin;
|
||||
case 3: return g_aAutoSlots[k].nDecal;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -12980,10 +13255,10 @@ void CTCL_API CTCL_SetMissionParams()
|
||||
//}
|
||||
NetMissionParameters::MWNetMissionParameters* lparams = app->GetLocalNetParams();
|
||||
|
||||
lparams->m_killLimit = 0; // no kill limit - 목표치
|
||||
lparams->m_killLimit = 0; // no kill limit - target value
|
||||
lparams->m_killLimitNumber = 0;
|
||||
lparams->m_respawnLimit = 0; // 생명제한을 둘 것인가?
|
||||
lparams->m_respawnLimitNumber = 0; // 생명수
|
||||
lparams->m_respawnLimit = 0; // apply a respawn limit?
|
||||
lparams->m_respawnLimitNumber = 0; // number of lives
|
||||
//params->m_isNight = params.m_isNight;
|
||||
lparams->m_onlyStockMech = FALSE;
|
||||
lparams->m_playMissionReview = 0; // params.m_playMissionReview;
|
||||
@@ -13250,7 +13525,7 @@ void CTCL_API CTCL_CheckServerReady()
|
||||
int i, nOK, nCount = Network::GetInstance()->GetPlayerCount();
|
||||
|
||||
BOOL bOK = FALSE;
|
||||
if (nCount == (g_nTeslas + 1)) { // 모든 클라이언트가 접속이 되어 있을 때...
|
||||
if (nCount == (g_nTeslas + 1)) { // when all clients are connected...
|
||||
for(nOK = 0, i = 0; i < Maximum_Players; ++i) {
|
||||
if (i != Connection::Server->GetID()) {
|
||||
const MechWarrior4::ServedConnectionData& scd = app->servedConnectionData[i];
|
||||
@@ -13307,17 +13582,16 @@ void CTCL_API CTCL_DefaultHostSetup(int nMode)
|
||||
params->m_allowdecaltransfer = 0;
|
||||
if (g_bCOOP) {
|
||||
Environment.NetworkMaxPlayers = 16;
|
||||
//if (CTCL_GetTeslaCount() < CTCL_GetTeslaCountAll()) {
|
||||
// any cameraship installed... so 1 more player can join
|
||||
//params->m_maxPlayers = 9;
|
||||
//params->m_maxBots = 8;
|
||||
//} else {
|
||||
// Reserve extra DirectPlay slots for camera seats (tracked separately from pilots in CTCL)
|
||||
// Original commented-out intent preserved and now implemented for non-COOP below
|
||||
params->m_maxPlayers = 9;
|
||||
params->m_maxBots = 8;
|
||||
//}
|
||||
} else {
|
||||
params->m_maxPlayers = 16;
|
||||
Environment.NetworkMaxPlayers = 16;
|
||||
// Reserve extra DirectPlay slots for cameraships: they share the session but are tracked
|
||||
// separately from pilot seats in CTCL (CTCL_GetTeslaCountAll - CTCL_GetTeslaCount = camera count).
|
||||
// Without this, cameraship connection is rejected by DirectPlay because slot 17 doesn't exist.
|
||||
Environment.NetworkMaxPlayers = params->m_maxPlayers + (CTCL_GetTeslaCountAll() - CTCL_GetTeslaCount());
|
||||
params->m_maxBots = 16;
|
||||
}
|
||||
params->m_allow3rdPerson = 1;
|
||||
@@ -14820,6 +15094,10 @@ void __stdcall CTCL_UpdateMechView()
|
||||
mfd_device.BeginScene();
|
||||
sh_step = 4;
|
||||
break;
|
||||
case 4:
|
||||
// Same 7-step cadence as mode 1.
|
||||
sh_step = 6;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -230,13 +230,13 @@ extern int g_nTeamOrderMode;
|
||||
extern bool g_bCOOP; // COin OPeration
|
||||
// jcem - end
|
||||
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
extern void __stdcall RIO_StartStop (BOOL bStart);
|
||||
void COOP_InputMode(bool bRestore);
|
||||
extern int g_bNoPlasma;
|
||||
extern void __stdcall PLASMA_Do(int nMode);
|
||||
extern void GeneralReset();
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
|
||||
extern bool __stdcall gos_NetDoneStartGame();
|
||||
extern bool __stdcall PrepareDefaultServerAdvertisers(void);
|
||||
@@ -1938,9 +1938,9 @@ public:
|
||||
void EndPos (DWORD& x,DWORD& y);
|
||||
bool Empty (void)
|
||||
{ return (m_Text[0] == 0); }
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
const char *hsh_get_m_Text(){return &m_Text[0];}
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
};
|
||||
|
||||
TextBox::TextBox (const char* pcszFontName, int nFontSize/* = -11*/, bool oldmode/* = false*/)
|
||||
@@ -3571,9 +3571,9 @@ void
|
||||
}
|
||||
Environment.DoGameLogic = &MWApplication::DoGameLogic;
|
||||
}
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
RIO_StartStop (TRUE);
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
|
||||
g_MRF.Started(); // jcem
|
||||
g_RSF.Started(); // jcem
|
||||
@@ -3696,9 +3696,9 @@ void
|
||||
g_RSF.Stopping(); // jcem
|
||||
|
||||
ClearTOC();
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
RIO_StartStop (FALSE);
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
if (CTCL_IsConsoleX()) {
|
||||
CTCL_SetGameState(_EGS_Closing);
|
||||
}
|
||||
@@ -3870,9 +3870,9 @@ sh_game_started = false;
|
||||
g_RSF.Stopping(); // jcem
|
||||
|
||||
ClearTOC();
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
RIO_StartStop (FALSE);
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
if (CTCL_IsConsoleX()) {
|
||||
CTCL_SetGameState(_EGS_Closing);
|
||||
}
|
||||
@@ -18435,7 +18435,7 @@ int __stdcall CTCL_StartCOOP(void* instance, int args, void* data[])
|
||||
// $$COOP: see void CSOC_Client::OnReadyStartGame()
|
||||
// C_ReadyStartGame
|
||||
|
||||
g_nTeslas = 0; // 싱글 게임
|
||||
g_nTeslas = 0; // single player game
|
||||
g_nBOTs = 7;
|
||||
g_nPlayerInfos = 1 + g_nBOTs + g_nTeslas;
|
||||
g_bIsServer = TRUE;
|
||||
@@ -18523,13 +18523,13 @@ int __stdcall CTCL_StartCOOP(void* instance, int args, void* data[])
|
||||
// MSL ADD MECH
|
||||
PI.m_nMechIndex = -1;
|
||||
//*
|
||||
// 각 메크에 대한 정보는 MechIndex를 참조함
|
||||
// See MechIndex for each mech's info
|
||||
PI.m_fileID = 0;
|
||||
PI.m_recordID = 0;
|
||||
strcpy(PI.m_szMech, s_paMechNames[11]); // Madcat
|
||||
strcpy(PI.m_szMech, "$Yellow");
|
||||
//*/
|
||||
PI.m_nTeamOrSkin = 1; // 빨강
|
||||
PI.m_nTeamOrSkin = 1; // red
|
||||
PI.m_nDecal = 1; // nDecal;
|
||||
PI.m_dwAddr = 0; // dwAddr;
|
||||
g_nPrintOut = FALSE;
|
||||
@@ -18576,7 +18576,7 @@ int __stdcall CTCL_StartCOOP(void* instance, int args, void* data[])
|
||||
strcpy(PI.m_szName, s_pNames[aLBN[2][i - 1]]);
|
||||
PI.m_nMechIndex = -1;
|
||||
//*
|
||||
//각 메크에 대한 정보는 MechIndex를 참조함
|
||||
//See MechIndex for each mech's info
|
||||
PI.m_fileID = 0;
|
||||
PI.m_recordID = 0;
|
||||
/*if (i == 1)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "MW4Headers.hpp"
|
||||
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
#include "MWVideoRenderer.hpp"
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
#include "MWGUIManager.hpp"
|
||||
#include "GUIWeaponManager.hpp"
|
||||
#include "GUIRadarManager.hpp"
|
||||
@@ -1554,7 +1554,7 @@ void MWGUIManager::RenderComponents (void)
|
||||
(*iter)->Draw ();
|
||||
}
|
||||
}else{
|
||||
//상훈... 셧다운 중일때..
|
||||
//sanghoon: while shutting down..
|
||||
for (iter = m_Components.begin ();iter != m_Components.end ();iter++)
|
||||
{
|
||||
//Main hudZoom,//hudReticle,hudObjective,hudTorsoBar,hudHelp,hudScore
|
||||
@@ -1597,11 +1597,11 @@ void MWGUIManager::RenderComponents (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
//상훈-앞
|
||||
//sanghoon begin
|
||||
extern CamerashipParams g_CamerashipParams;
|
||||
if (CTCL_IsConsoleX() || g_CamerashipParams.m_bAllowChatDisplay)
|
||||
hudChat->Draw (true);
|
||||
//상훈-뒤
|
||||
//sanghoon end
|
||||
hudScore->Draw (true);
|
||||
hudCamera->Draw(true);
|
||||
}
|
||||
@@ -1612,7 +1612,7 @@ void MWGUIManager::RenderComponents (void)
|
||||
gos_PopRenderStates ();
|
||||
|
||||
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
MWApplication* app = MWApplication::GetInstance();
|
||||
if (app->networkingFlag)
|
||||
{
|
||||
@@ -1648,7 +1648,7 @@ void MWGUIManager::RenderComponents (void)
|
||||
}
|
||||
}
|
||||
}
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
}
|
||||
|
||||
void MWGUIManager::ShowHelpArrow (bool value)
|
||||
|
||||
@@ -590,7 +590,7 @@ namespace MechWarrior4
|
||||
return (m_EndMissionTimer.Running());
|
||||
}
|
||||
|
||||
//상훈
|
||||
//sanghoon
|
||||
Stuff::Scalar GetMissionDuration ()
|
||||
{
|
||||
if (!m_EndMissionTimer.Running ())
|
||||
|
||||
@@ -3954,7 +3954,7 @@ void
|
||||
g_HUDPPCLevel = 10;
|
||||
}
|
||||
|
||||
//상훈
|
||||
//sanghoon
|
||||
//extern bool sh_isdeathmode;
|
||||
//Are we ejecting?
|
||||
if (m_NeedEject)
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL //
|
||||
//===========================================================================//
|
||||
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
#include "MW4.hpp"
|
||||
#include "Vehicle.hpp"
|
||||
#include "MechAnimationState.hpp"
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "SpringOf.hpp"
|
||||
#include "MechLabHeaders.h"
|
||||
#include <Stuff\Spline.hpp>
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
|
||||
|
||||
#include "MW4Headers.hpp"
|
||||
@@ -65,9 +65,9 @@
|
||||
#include "EyePointManager.hpp"
|
||||
#include "mw4shell.hpp"
|
||||
#include "NavPoint.hpp"
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
#include "MWVideoRenderer.hpp"
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
#include <Adept\CollisionGrid.hpp>
|
||||
#include <Adept\Controls.hpp>
|
||||
@@ -101,7 +101,7 @@ bool _stdcall WriteImageAfterGrab(BYTE* Image, const char* pcszFilePrefix);
|
||||
#include <mbstring.h>
|
||||
#define __mbsrchr(s,c) (char*)_mbsrchr((const unsigned char*)(s),(c))
|
||||
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
#include <windows.h>
|
||||
|
||||
#include "ctcls.h"
|
||||
@@ -208,7 +208,7 @@ float g_fNeedFlushLevel = 0.66;
|
||||
float g_fTimeMsgSender = 1.5f;
|
||||
float g_fTimeScoringAtEnd = 10.0f;
|
||||
Mech* FindNextMechToFollowByScore(Mech* pCur); // jcem
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
|
||||
CamerashipParams g_CamerashipParams;
|
||||
|
||||
@@ -2285,7 +2285,7 @@ void
|
||||
if (MWGUIManager::GetInstance () && IsObserving(true))
|
||||
{
|
||||
Check_Object(MWGUIManager::GetInstance());
|
||||
//상훈
|
||||
//sanghoon
|
||||
if (!CTCL_IsConsoleX() && !g_CamerashipParams.m_bAllowChatDisplay) {
|
||||
HUDChat *chat;
|
||||
chat = Cast_Object (HUDChat *,MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_CHAT));
|
||||
@@ -3781,11 +3781,11 @@ void VehicleInterface::ApplyControls(Time till)
|
||||
}
|
||||
else if (controlPacket.lookCommand == AnalogControlSave::LookBack)
|
||||
{
|
||||
//상훈
|
||||
//sanghoon
|
||||
ShowHUDIfOn(true);
|
||||
//MWGUIManager::GetInstance()->HideHudComponent (HUD_TARGETARROW);
|
||||
//ShowHUDIfOn(false);
|
||||
//상훈
|
||||
//sanghoon
|
||||
// MSL 5.04 Rear Firing Weapons
|
||||
// ShowStatic(cameraView == InMechCameraView);
|
||||
ShowStatic(true);
|
||||
@@ -4968,7 +4968,7 @@ void
|
||||
Scalar fT = gos_GetElapsedTime();
|
||||
if ((fT - g_fLastScoringTimeCechk) >= CAMERASHIP_SCORING_CHECK) {
|
||||
g_fLastScoringTimeCechk = fT;
|
||||
//상훈
|
||||
//sanghoon
|
||||
if (Application::GetInstance()->networkingFlag)
|
||||
{
|
||||
bool bNearEnd = false;
|
||||
@@ -5378,7 +5378,7 @@ again:
|
||||
if ((m_curView == STATE_DEATH_SEQUENCE_START) || (m_curView == STATE_DEATH_SEQUENCE_TRANS)) {
|
||||
bool bStateEnded = false;
|
||||
if (m_pMechDying != pMech) {
|
||||
// 죽는 도중에 타겟이 바뀐 경우
|
||||
// Case where target changes while dying
|
||||
ClearFixedPoint();
|
||||
m_fTimeStateEnd = fMT + g_CamerashipParams.m_fTimeStandard;
|
||||
m_pMechDying = m_pEnemy = NULL;
|
||||
@@ -5419,7 +5419,7 @@ again:
|
||||
}
|
||||
if ((m_pEnemy != m_pMechDying) && m_pEnemy->IsDestroyed()) {
|
||||
if (m_curView == STATE_DEATH_SEQUENCE_START) {
|
||||
// 죽음을 보여주는 도중에 상대방이 죽은 경우...
|
||||
// Case where opponent dies while death animation is playing...
|
||||
// move to trans...
|
||||
bStateEnded = true;
|
||||
}
|
||||
@@ -7495,7 +7495,7 @@ void
|
||||
// MSL 5.02 Zoom
|
||||
// m_reticuleCamera->SetPerspective(near_clip_zoom, far_clip_main + (100.0f * (horizontal_fov_main - horizontal_fov_zoom)), horizontal_fov_zoom, (height_to_width_zoom));
|
||||
m_reticuleCamera->SetPerspective(near_clip_zoom, far_clip_main + (100.0f * (horizontal_fov_main - horizontal_fov_zoom)), horizontal_fov_zoom, (height_to_width_zoom*1.75));
|
||||
//상훈
|
||||
//sanghoon
|
||||
// float height=(1-g_fZoomMarginLR*2)*800 * height_to_width_zoom/600;
|
||||
// float tb_margin=(1-height)/2;
|
||||
// m_reticuleCamera->SetViewport(1-g_fZoomMarginLR,1-tb_margin, g_fZoomMarginLR, tb_margin);
|
||||
@@ -8121,7 +8121,7 @@ void VehicleInterface::ChainFireGroup (Stuff::Time till,ChainIteratorOf<Weapon *
|
||||
}
|
||||
|
||||
//
|
||||
// 鉉 - start
|
||||
// hyun begin
|
||||
|
||||
groupWeaponIterator->ReadAndNext();
|
||||
|
||||
@@ -8135,7 +8135,7 @@ void VehicleInterface::ChainFireGroup (Stuff::Time till,ChainIteratorOf<Weapon *
|
||||
BOOL bWeaponGroup3 = (group3FireRequest > 0) && GetWeaponGroupID (*weapon, 3);
|
||||
|
||||
//
|
||||
// 鉉 - end
|
||||
// hyun end
|
||||
//
|
||||
|
||||
num_weapons ++;
|
||||
@@ -8369,7 +8369,7 @@ void
|
||||
}
|
||||
}
|
||||
*/
|
||||
// fireRequest > 0 (Enter Key : None Used) : 鉉
|
||||
// fireRequest > 0 (Enter Key : None Used) : hyun
|
||||
if(fireRequest > 0)
|
||||
{
|
||||
switch(weaponMode)
|
||||
@@ -8521,12 +8521,12 @@ void VehicleInterface::OverrideAutoCenterToTorsoMessageHandler(Adept::ReceiverDa
|
||||
Verify(message->messageID == OverrideAutoCenterToTorsoMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (28, LAMP_OFF); // 鉉
|
||||
g_pRIOMain->SetLampState (28, LAMP_OFF); // hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (28, LAMP_BRIGHT); // 鉉
|
||||
g_pRIOMain->SetLampState (28, LAMP_BRIGHT); // hyun
|
||||
|
||||
if (perminateTorsoMode == CenterLegsToTorso)
|
||||
{
|
||||
@@ -8539,7 +8539,7 @@ void VehicleInterface::OverrideAutoCenterToTorsoMessageHandler(Adept::ReceiverDa
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (28, LAMP_DEFAULT); // 鉉
|
||||
g_pRIOMain->SetLampState (28, LAMP_DEFAULT); // hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8658,11 +8658,11 @@ void
|
||||
}
|
||||
}
|
||||
|
||||
g_pRIOMain->SetLampState (17, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (17, LAMP_BRIGHT);// hyun
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (17, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (17, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8749,17 +8749,17 @@ void
|
||||
Verify(message->messageID == CrouchCommandMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (20, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (20, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (20, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (20, LAMP_BRIGHT);// hyun
|
||||
// if (executionState->GetState () == ExecutionStateEngine::AutoPilotState)
|
||||
executionState->RequestState(ExecutionStateEngine::AlwaysExecuteState);
|
||||
QueCommand(VehicleCommand::CrouchCommand);
|
||||
} else {
|
||||
g_pRIOMain->SetLampState (20, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (20, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -8786,10 +8786,10 @@ void
|
||||
|
||||
if (GetShutdownState()) {
|
||||
if (g_bJumpZoom)
|
||||
g_pRIOMain->SetLampState (16, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (16, LAMP_OFF);// hyun
|
||||
g_pRIOMain->SetLampState (50, LAMP_OFF);
|
||||
g_pRIOMain->SetLampState (33, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (34, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (33, LAMP_OFF);// hyun
|
||||
g_pRIOMain->SetLampState (34, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -8797,7 +8797,7 @@ void
|
||||
{
|
||||
if (GetJumpJetState() > 0) {
|
||||
if (g_bJumpZoom)
|
||||
g_pRIOMain->SetLampState (16, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (16, LAMP_BRIGHT);// hyun
|
||||
g_pRIOMain->SetLampState (33, LAMP_BRIGHT);
|
||||
g_pRIOMain->SetLampState (34, LAMP_BRIGHT);
|
||||
}
|
||||
@@ -8811,10 +8811,10 @@ void
|
||||
if (!GetShutdownState())
|
||||
if (GetJumpJetState() > 0) {
|
||||
if (g_bJumpZoom)
|
||||
g_pRIOMain->SetLampState (16, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (16, LAMP_DEFAULT);// hyun
|
||||
g_pRIOMain->SetLampState (50, LAMP_DEFAULT);
|
||||
g_pRIOMain->SetLampState (33, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (34, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (33, LAMP_DEFAULT);// hyun
|
||||
g_pRIOMain->SetLampState (34, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9284,12 +9284,12 @@ void
|
||||
}
|
||||
|
||||
if (!GetShutdownState())
|
||||
g_pRIOMain->SetLampState (7, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (7, LAMP_BRIGHT);// hyun
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!GetShutdownState())
|
||||
g_pRIOMain->SetLampState (7, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (7, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -9341,7 +9341,7 @@ void
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
//鉉SetWeaponMode(GroupFireMode);
|
||||
//hyun SetWeaponMode(GroupFireMode);
|
||||
// selectedWeaponGroup = 1;
|
||||
group1FireRequest ++;
|
||||
// fireRequest ++;
|
||||
@@ -9379,7 +9379,7 @@ void
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
//鉉SetWeaponMode(GroupFireMode);
|
||||
//hyun SetWeaponMode(GroupFireMode);
|
||||
// selectedWeaponGroup = 2;
|
||||
group2FireRequest ++;
|
||||
// fireRequest ++;
|
||||
@@ -9415,7 +9415,7 @@ void
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
//鉉SetWeaponMode(GroupFireMode);
|
||||
//hyun SetWeaponMode(GroupFireMode);
|
||||
// selectedWeaponGroup = 3;
|
||||
// fireRequest ++;
|
||||
group3FireRequest ++;
|
||||
@@ -9468,7 +9468,7 @@ void
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
//鉉SetWeaponMode(GroupFireMode);
|
||||
//hyun SetWeaponMode(GroupFireMode);
|
||||
// selectedWeaponGroup = 4;
|
||||
// fireRequest ++;
|
||||
// group4FireRequest ++;
|
||||
@@ -9508,7 +9508,7 @@ void
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
//鉉SetWeaponMode(GroupFireMode);
|
||||
//hyun SetWeaponMode(GroupFireMode);
|
||||
// selectedWeaponGroup = 5;
|
||||
// fireRequest ++;
|
||||
// group5FireRequest ++;
|
||||
@@ -9554,7 +9554,7 @@ void
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
//鉉SetWeaponMode(GroupFireMode);
|
||||
//hyun SetWeaponMode(GroupFireMode);
|
||||
//group6FireRequest ++;
|
||||
}
|
||||
else
|
||||
@@ -10344,19 +10344,19 @@ void
|
||||
Verify(message->messageID == ToggleSearchLightMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (27, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (27, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
if (g_SearchLight == TRUE)
|
||||
g_pRIOMain->SetLampState (27, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (27, LAMP_BRIGHT);// hyun
|
||||
QueCommand(VehicleCommand::ToggleSearchLightCommand);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (g_SearchLight == TRUE)
|
||||
g_pRIOMain->SetLampState (27, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (27, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10546,7 +10546,7 @@ void
|
||||
{
|
||||
//if (!GetShutdownState())
|
||||
//if (g_bCool == TRUE) {
|
||||
// g_pRIOMain->SetLampState (19, LAMP_BRIGHT);// 鉉
|
||||
// g_pRIOMain->SetLampState (19, LAMP_BRIGHT);// hyun
|
||||
//}
|
||||
|
||||
isCooling ++;
|
||||
@@ -10560,7 +10560,7 @@ void
|
||||
{
|
||||
//if (!GetShutdownState())
|
||||
//if (g_bCool == TRUE) {
|
||||
// g_pRIOMain->SetLampState (19, LAMP_DEFAULT);// 鉉
|
||||
// g_pRIOMain->SetLampState (19, LAMP_DEFAULT);// hyun
|
||||
//}
|
||||
|
||||
isCooling --;
|
||||
@@ -10734,7 +10734,7 @@ void
|
||||
|
||||
if (GetShutdownState())
|
||||
{
|
||||
g_pRIOMain->SetLampState (26, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (26, LAMP_OFF);// hyun
|
||||
g_pRIOMain->SetLampState (48, LAMP_OFF); // Light Amp Lamp MFD
|
||||
return;
|
||||
}
|
||||
@@ -10759,7 +10759,7 @@ void
|
||||
MWGUIManager::GetInstance()->ShowLightAmplification();
|
||||
Mission::GetInstance()->SetLightAmpMissionLights();
|
||||
ShowZoomIfOn (false);
|
||||
g_pRIOMain->SetLampState (26, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (26, LAMP_BRIGHT);// hyun
|
||||
if (!g_bJumpZoom)
|
||||
{
|
||||
if (g_pRIOMain->GetLampState (16) == LAMP_BRIGHT)
|
||||
@@ -10773,12 +10773,12 @@ void
|
||||
{
|
||||
if(vehicle->DoesHaveLightAmp())
|
||||
{
|
||||
g_pRIOMain->SetLampState (26, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (26, LAMP_DEFAULT);// hyun
|
||||
g_pRIOMain->SetLampState (48, LAMP_DEFAULT); // Light Amp Lamp MFD
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (26, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (26, LAMP_OFF);// hyun
|
||||
g_pRIOMain->SetLampState (48, LAMP_OFF); // Light Amp Lamp MFD
|
||||
}
|
||||
}
|
||||
@@ -10864,12 +10864,12 @@ void
|
||||
Verify(message->messageID == NextNavPointMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (38, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (38, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (38, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (38, LAMP_BRIGHT);// hyun
|
||||
m_selectedNavPoint.Remove();
|
||||
NavPoint *nav_point;
|
||||
if((nav_point = NavPoint::GetNextNavPoint()) != NULL)
|
||||
@@ -10890,7 +10890,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (38, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (38, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10915,12 +10915,12 @@ void
|
||||
Verify(message->messageID == PreviousNavPointMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (37, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (37, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (37, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (37, LAMP_BRIGHT);// hyun
|
||||
m_selectedNavPoint.Remove();
|
||||
NavPoint *nav_point;
|
||||
if((nav_point = NavPoint::GetPreviousNavPoint()) != NULL)
|
||||
@@ -10936,7 +10936,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (37, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (37, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10961,12 +10961,12 @@ void
|
||||
Verify(message->messageID == NextEnemyMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (10, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (10, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (10, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (10, LAMP_BRIGHT);// hyun
|
||||
Entity *next_enemy = NULL;
|
||||
Sensor *sensor = vehicle->GetSensor();
|
||||
if(sensor)
|
||||
@@ -10978,7 +10978,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (10, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (10, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11003,12 +11003,12 @@ void
|
||||
Verify(message->messageID == PreviousEnemyMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (9, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (9, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (9, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (9, LAMP_BRIGHT);// hyun
|
||||
Entity *next_enemy = NULL;
|
||||
Sensor *sensor = vehicle->GetSensor();
|
||||
if(sensor)
|
||||
@@ -11020,7 +11020,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (9, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (9, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11045,12 +11045,12 @@ void
|
||||
Verify(message->messageID == NearestEnemyMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (11, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (11, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (11, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (11, LAMP_BRIGHT);// hyun
|
||||
m_interfaceTarget.Remove();
|
||||
m_targetCamera->SetScene(NULL);
|
||||
Entity *entity = NULL;
|
||||
@@ -11065,7 +11065,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (11, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (11, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11232,12 +11232,12 @@ void
|
||||
|
||||
if (GetShutdownState())
|
||||
{
|
||||
g_pRIOMain->SetLampState (8, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (8, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (8, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (8, LAMP_BRIGHT);// hyun
|
||||
|
||||
Entity *target_entity;
|
||||
target_entity = targetQueryEntity.GetCurrent();
|
||||
@@ -11260,7 +11260,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (8, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (8, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11285,12 +11285,12 @@ void
|
||||
Verify(message->messageID == NextFriendlyMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (14, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (14, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (14, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (14, LAMP_BRIGHT);// hyun
|
||||
Entity *next_friendly = NULL;
|
||||
Sensor *sensor = vehicle->GetSensor();
|
||||
if(sensor)
|
||||
@@ -11303,7 +11303,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (14, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (14, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11328,12 +11328,12 @@ void
|
||||
Verify(message->messageID == PreviousFriendlyMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (13, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (13, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (13, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (13, LAMP_BRIGHT);// hyun
|
||||
Entity *next_friendly = NULL;
|
||||
Sensor *sensor = vehicle->GetSensor();
|
||||
if(sensor)
|
||||
@@ -11346,7 +11346,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (13, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (13, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11371,12 +11371,12 @@ void
|
||||
Verify(message->messageID == NearestFriendlyMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (15, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (15, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (15, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (15, LAMP_BRIGHT);// hyun
|
||||
Entity *entity = NULL;
|
||||
Sensor *sensor = vehicle->GetSensor();
|
||||
if(sensor)
|
||||
@@ -11388,7 +11388,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (15, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (15, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11478,7 +11478,7 @@ void VehicleInterface::OverrideShutdownMessageHandler(Adept::ReceiverDataMessage
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
//if (!GetShutdownState())
|
||||
// g_pRIOMain->SetLampState (18, LAMP_BRIGHT);// 鉉
|
||||
// g_pRIOMain->SetLampState (18, LAMP_BRIGHT);// hyun
|
||||
HeatManager *heat;
|
||||
if (vehicle->IsDerivedFrom (Mech::DefaultData))
|
||||
{
|
||||
@@ -11492,7 +11492,7 @@ void VehicleInterface::OverrideShutdownMessageHandler(Adept::ReceiverDataMessage
|
||||
}
|
||||
else {
|
||||
//if (!GetShutdownState())
|
||||
// g_pRIOMain->SetLampState (18, LAMP_DEFAULT);// 鉉
|
||||
// g_pRIOMain->SetLampState (18, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -11541,7 +11541,7 @@ void VehicleInterface::RightMFDMessageHandler (Adept::ReceiverDataMessageOf<int>
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (52, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (52, LAMP_BRIGHT);// hyun
|
||||
if(MWGUIManager::GetInstance())
|
||||
{
|
||||
Check_Object(MWGUIManager::GetInstance());
|
||||
@@ -11552,7 +11552,7 @@ void VehicleInterface::RightMFDMessageHandler (Adept::ReceiverDataMessageOf<int>
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (52, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (52, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11584,12 +11584,12 @@ void VehicleInterface::LeftMFDMessageHandler (Adept::ReceiverDataMessageOf<int>
|
||||
Verify(message->messageID == LeftMFDMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (12, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (12, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (12, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (12, LAMP_BRIGHT);// hyun
|
||||
if(MWGUIManager::GetInstance())
|
||||
{
|
||||
Check_Object(MWGUIManager::GetInstance());
|
||||
@@ -11610,7 +11610,7 @@ void VehicleInterface::LeftMFDMessageHandler (Adept::ReceiverDataMessageOf<int>
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (12, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (12, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -11632,12 +11632,12 @@ void VehicleInterface::ToggleRadarPassiveMessageHandler (Adept::ReceiverDataMess
|
||||
Verify(message->messageID == ToggleRadarPassiveMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (25, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (25, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (25, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (25, LAMP_BRIGHT);// hyun
|
||||
if(!vehicle->vehicleShutDown)
|
||||
{
|
||||
if(MWGUIManager::GetInstance())
|
||||
@@ -11676,7 +11676,7 @@ void VehicleInterface::ToggleRadarPassiveMessageHandler (Adept::ReceiverDataMess
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (25, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (25, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11702,12 +11702,12 @@ void
|
||||
Verify(message->messageID == ToggleRadarRangeMessageID);
|
||||
|
||||
if (GetShutdownState()) {
|
||||
g_pRIOMain->SetLampState (24, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (24, LAMP_OFF);// hyun
|
||||
return;
|
||||
}
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (24, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (24, LAMP_BRIGHT);// hyun
|
||||
if(!vehicle->vehicleShutDown)
|
||||
{
|
||||
if(MWGUIManager::GetInstance())
|
||||
@@ -11739,7 +11739,7 @@ void
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (24, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (24, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13533,13 +13533,13 @@ void VehicleInterface::ShowObjectivesMessageHandler(Adept::ReceiverDataMessageOf
|
||||
{
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (36, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (36, LAMP_BRIGHT);// hyun
|
||||
g_bObjMode = !g_bObjMode;
|
||||
// ObjectiveRenderer::Instance->ToggleObjective ();
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (36, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (36, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -13568,12 +13568,12 @@ void VehicleInterface::MuteMessageHandler(Adept::ReceiverDataMessageOf<int> *mes
|
||||
|
||||
if(message->dataContents > 0)
|
||||
{
|
||||
g_pRIOMain->SetLampState (55, LAMP_BRIGHT);// 鉉
|
||||
g_pRIOMain->SetLampState (55, LAMP_BRIGHT);// hyun
|
||||
g_bMuteMode = !g_bMuteMode;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_pRIOMain->SetLampState (55, LAMP_DEFAULT);// 鉉
|
||||
g_pRIOMain->SetLampState (55, LAMP_DEFAULT);// hyun
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13689,7 +13689,7 @@ void
|
||||
|
||||
if (GetShutdownState()) {
|
||||
if (!g_bJumpZoom)
|
||||
g_pRIOMain->SetLampState (16, LAMP_OFF);// 鉉
|
||||
g_pRIOMain->SetLampState (16, LAMP_OFF);// hyun
|
||||
g_pRIOMain->SetLampState (51, LAMP_OFF);
|
||||
return;
|
||||
}
|
||||
@@ -14489,7 +14489,7 @@ void VehicleInterface::ShowZoom (void)
|
||||
Check_Object(m_reticuleCamera);
|
||||
m_reticuleCamera->GetPerspective(near_clip, far_clip, horizontal_fov, height_to_width);
|
||||
//m_reticuleCamera->SetPerspective(near_clip, far_clip, s_zoomFOV[0], height_to_width);
|
||||
//상훈
|
||||
//sanghoon
|
||||
// jcem - begin
|
||||
float fZoom;
|
||||
gosASSERT(g_fZoomFOVA >= g_fZoomFOVB);
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
const char* m_pcsz;
|
||||
|
||||
int m_nLauncherConnection; // 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // m_bCameraShip값에 따라 게임 혹은 카메라 쉽과의 접속을 의미, 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // Connection to game or camera ship per m_bCameraShip, 0: no connection, +1: connected, -1: connecting
|
||||
int m_nApplType;
|
||||
int m_nApplState;
|
||||
int m_nGameState;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "MW4Headers.hpp"
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
#include "MWMission.hpp"
|
||||
#include "VehicleInterface.hpp"
|
||||
#include "Vehicle.hpp"
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "mech.hpp"
|
||||
#include "mechlabheaders.h"
|
||||
#include "bucket.hpp"
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
#include "hudcomp.hpp"
|
||||
#include "HUDChat.hpp"
|
||||
#include "hudcomm.hpp"
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "mwapplication.hpp"
|
||||
#include "..\missionlang\resource.h"
|
||||
|
||||
//상훈짱 begin
|
||||
//sanghoon begin
|
||||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
@@ -43,7 +43,7 @@
|
||||
extern Scalar g_fLastStartTime;
|
||||
extern Adept::ReplicatorID g_LastTarget;
|
||||
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
|
||||
extern "C" char* _stdcall CharPrevA(const char* lpszStart, const char* lpszCurrent);
|
||||
#define CharPrev CharPrevA
|
||||
@@ -164,7 +164,7 @@ void HUDChat::Reset (void)
|
||||
// KillData ();
|
||||
comm = Cast_Object (HUDComm *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));
|
||||
|
||||
//mr_device의 맵 데이타를 로드한다.
|
||||
//Load map data for mr_device.
|
||||
if(hsh_mrdev_initialized){
|
||||
extern char AssetsDirectory1[MAX_PATH];
|
||||
const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();
|
||||
@@ -228,12 +228,12 @@ static const float sm1_offset[][2]={
|
||||
{ 0*2, 0*2}, //special2
|
||||
};
|
||||
|
||||
//number: 0,1,2,3 lancemate의 순서..
|
||||
//part: 해당 lancemate mech의 part
|
||||
//color:해당 part의 color
|
||||
//number: 0,1,2,3 lancemate order..
|
||||
//part: mech part of the lancemate
|
||||
//color: color for this part
|
||||
void RenderAux1SmallMech(int num,int part,int color)
|
||||
{
|
||||
//각각의 offset에 따라서 그린다.
|
||||
//Draw according to each offset.
|
||||
if(sm1_texture[part][2]!=0){
|
||||
mfd_device.DrawTexture(
|
||||
sm1_offset[part][0]+190+num*160,
|
||||
@@ -598,15 +598,15 @@ void HUDChat::DrawImplementation(void)
|
||||
#endif
|
||||
|
||||
if(draw_mr){
|
||||
//미션 리뷰 내용을 그린다.
|
||||
//Draw mission review content.
|
||||
//_______________________________________________________________________________________________________
|
||||
//
|
||||
// Mech상태 및 메시지
|
||||
// Mech status and messages
|
||||
//_______________________________________________________________________________________________________
|
||||
if(!mr_device.map_loaded){
|
||||
comm = Cast_Object (HUDComm *, MWGUIManager::GetInstance ()->Component (MWGUIManager::HUD_COMM));
|
||||
|
||||
//mr_device의 맵 데이타를 로드한다.
|
||||
//Load map data for mr_device.
|
||||
extern char AssetsDirectory1[MAX_PATH];
|
||||
const Map__GameModel *model = Map::GetInstance ()->GetGameModel ();
|
||||
char temp[256];
|
||||
@@ -629,7 +629,7 @@ void HUDChat::DrawImplementation(void)
|
||||
int mech_count=0;
|
||||
PMechInfo pMechInfos = &g_aMechInfos[0];
|
||||
{
|
||||
//현재 다른 메크들의 이름 /Kill/Death를 그린다.
|
||||
//Draw the name/Kill/Death stats of other mechs.
|
||||
mech_count=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
|
||||
g_TeamOrderCount=mech_count;
|
||||
if (mech_count > 8) // jcem
|
||||
@@ -657,7 +657,7 @@ void HUDChat::DrawImplementation(void)
|
||||
|
||||
|
||||
mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);
|
||||
//메크의 Damage 상태를 그린다.
|
||||
//Draw mech Damage status.
|
||||
for (j=0;j<11;j++){
|
||||
if (j==7 || j==9 || j==10)
|
||||
continue;
|
||||
@@ -669,7 +669,7 @@ void HUDChat::DrawImplementation(void)
|
||||
}
|
||||
}
|
||||
|
||||
//메크의 Callsign/Score/Kills/Deaths를 그린다.
|
||||
//Draw mech Callsign/Score/Kills/Deaths.
|
||||
int nScore = 0, nKills = 0, nDeaths = 0;
|
||||
callsign=pMechInfos->m_pcszName;
|
||||
if (hud) {
|
||||
@@ -695,7 +695,7 @@ void HUDChat::DrawImplementation(void)
|
||||
pMechInfos++;
|
||||
}
|
||||
|
||||
//채팅장의 내용을 그린다.
|
||||
//Draw the contents of the chat window.
|
||||
stlport::list<ChatData>::iterator iter;
|
||||
int cy=300+30;//chat_y
|
||||
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
|
||||
@@ -733,8 +733,8 @@ void HUDChat::DrawImplementation(void)
|
||||
int i;
|
||||
|
||||
// Secondary Maps
|
||||
//맵과 맵 경계선을 그린다. (게임중에 변하지 않으므로 한번만 그린다.)
|
||||
//DrawMapBoundary();//다른 버전 구현할 것...
|
||||
//Draw map and boundary. (Drawn once since it does not change during game.)
|
||||
//DrawMapBoundary();//Implement alternate version...
|
||||
mr_device.pD3DDevice->SetRenderState(D3DRENDERSTATE_CLIPPING ,TRUE);
|
||||
mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSMapTexture);
|
||||
mr_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
|
||||
@@ -748,7 +748,7 @@ void HUDChat::DrawImplementation(void)
|
||||
//MechWarrior4::VehicleInterface* p = MechWarrior4::VehicleInterface::GetInstance();
|
||||
|
||||
|
||||
//미션 리뷰에서는 현재 메크가 중심에 표시되므로 맵이 스크롤 되어 표시된다.
|
||||
//In mission review, current mech is shown at center so the map scrolls.
|
||||
float MR_MSF=4.0f;//Mission Review - Map Scale Factor
|
||||
const float ViewSize=300.0f;//Mission Review - Map Size
|
||||
const float ViewLMargin=10;
|
||||
@@ -758,9 +758,9 @@ void HUDChat::DrawImplementation(void)
|
||||
|
||||
D3DVIEWPORT7 viewport={ViewLMargin,ViewTMargin,ViewSize,ViewSize,0.0f,1.0f};
|
||||
mr_device.pD3DDevice->SetViewport(&viewport);
|
||||
///////////////////// MAP 시작 //////////////////////
|
||||
///////////////////// MAP BEGIN //////////////////////
|
||||
|
||||
//Focus Mech를 설정하는 루틴을 넣어야한다.
|
||||
//Need to add routine to set Focus Mech.
|
||||
Scalar multx,multz;
|
||||
|
||||
|
||||
@@ -787,10 +787,10 @@ void HUDChat::DrawImplementation(void)
|
||||
|
||||
mr_device.pD3DDevice->SetTexture(0,mr_device.pDDSTexture);
|
||||
|
||||
//맵상에 메크들들 그리기.텍스트 먼저..
|
||||
//Draw mechs on map. Text first..
|
||||
for(i=0,pMechInfos = &g_aMechInfos[0];i<mech_count;i++,pMechInfos++){
|
||||
Mech* pMech = pMechInfos->m_pMech;
|
||||
//메크의 위치를 구할 것..
|
||||
//TODO: get mech position..
|
||||
|
||||
Stuff::Point3D pos;
|
||||
|
||||
@@ -827,10 +827,10 @@ void HUDChat::DrawImplementation(void)
|
||||
color,callsign,TEXTALIGN_HCENTER|TEXTALIGN_TOP);
|
||||
|
||||
}
|
||||
//아이콘 그리기.
|
||||
//Draw icon.
|
||||
for(i=0,pMechInfos = &g_aMechInfos[0];i<mech_count;i++,pMechInfos++){
|
||||
Mech* pMech = pMechInfos->m_pMech;
|
||||
//메크의 위치를 구할 것..
|
||||
//TODO: get mech position..
|
||||
|
||||
Stuff::Point3D pos;
|
||||
|
||||
@@ -886,7 +886,7 @@ void HUDChat::DrawImplementation(void)
|
||||
mr_device.pD3DDevice->SetViewport(&viewport2);
|
||||
|
||||
|
||||
///////////////////// MAP 끝 //////////////////////
|
||||
///////////////////// MAP END //////////////////////
|
||||
|
||||
//_______________________________________________________________________________________________________
|
||||
//
|
||||
@@ -894,7 +894,7 @@ void HUDChat::DrawImplementation(void)
|
||||
//_______________________________________________________________________________________________________
|
||||
|
||||
|
||||
//미션 시간 그리기...hudtimer.cpp에 DrawImplementation에서 따온것임..
|
||||
//Draw mission timer... taken from DrawImplementation in hudtimer.cpp..
|
||||
MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
|
||||
Verify (mwmiss);
|
||||
Stuff::Scalar cur_time=mwmiss->GetMissionTime();//-mwmiss->GetMissionTime();
|
||||
@@ -923,7 +923,7 @@ void HUDChat::DrawImplementation(void)
|
||||
if(g_nTeamOrderMode==TEAM_MODE){
|
||||
int i,j;
|
||||
int size=3;
|
||||
//메크들의 상태를 그린다.
|
||||
//Draw mech status.
|
||||
PMechInfo pMechInfos = &g_aMechInfos[1];
|
||||
size=MWApplication::GetInstance()->GetMechInfos(0, g_aMechInfos, g_TeamOrderOthers);
|
||||
size--;
|
||||
@@ -970,7 +970,7 @@ void HUDChat::DrawImplementation(void)
|
||||
pMechInfos++;
|
||||
}
|
||||
mfd_device.DrawMFDBackText(mfd_text_comm1);
|
||||
//채팅장의 내용을 그린다.
|
||||
//Draw the contents of the chat window.
|
||||
stlport::list<ChatData>::iterator iter;
|
||||
int cy=240;//chat_y
|
||||
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
|
||||
@@ -996,7 +996,7 @@ void HUDChat::DrawImplementation(void)
|
||||
}
|
||||
|
||||
}else if(g_nTeamOrderMode==FREEFORALL_MODE){
|
||||
//현재 다른 메크들의 이름 /Kill/Death를 그린다.
|
||||
//Draw the name/Kill/Death stats of other mechs.
|
||||
int size=0;
|
||||
PMechInfo pMechInfos = &g_aMechInfos[1];
|
||||
size=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers);
|
||||
@@ -1006,10 +1006,10 @@ void HUDChat::DrawImplementation(void)
|
||||
size = 7;
|
||||
|
||||
int i;
|
||||
//번호를 먼저 지운다.
|
||||
//Clear the numbers first.
|
||||
// MSL 5.03 Comm MFD
|
||||
for(i=0;i<7;i++)mfd_text_comm3[i][0]=0;
|
||||
//번호를 채워 넣는다.
|
||||
//Fill in the numbers.
|
||||
// MSL 5.03 Comm MFD
|
||||
for(i=0;i<size;i++)itoa(i+1,mfd_text_comm3[i],10);
|
||||
|
||||
@@ -1064,8 +1064,8 @@ void HUDChat::DrawImplementation(void)
|
||||
if(size.cx<160){
|
||||
mfd_device.pFont[1].DrawText((float)p2->x,(float)p2->y,0xFFFFFFFF,callsign,TEXTALIGN_ORG);
|
||||
}else{
|
||||
//최소크기 폰트도.. 넘어선다...
|
||||
//2line으로 만든다.
|
||||
//Even the minimum font size is exceeded...
|
||||
//Split into 2 lines.
|
||||
char callsign2[128];
|
||||
strcpy(callsign2,callsign);
|
||||
int len2=strlen(callsign)/2;
|
||||
@@ -1120,7 +1120,7 @@ void HUDChat::DrawImplementation(void)
|
||||
|
||||
pMechInfos++;
|
||||
}
|
||||
//채팅장의 내용을 그린다.
|
||||
//Draw the contents of the chat window.
|
||||
stlport::list<ChatData>::iterator iter;
|
||||
int cy=180;//chat_y
|
||||
for (iter = m_Messages.begin ();iter != m_Messages.end ();iter++){
|
||||
@@ -1145,7 +1145,7 @@ void HUDChat::DrawImplementation(void)
|
||||
iter = m_Messages.erase (iter);
|
||||
}
|
||||
/*
|
||||
//MWMission.cpp에서 가져온것인
|
||||
//Taken from MWMission.cpp
|
||||
MWMission *mwmiss = Cast_Object (MWMission *,Mission::GetInstance ());
|
||||
|
||||
int death=0,kill=0;//,score
|
||||
@@ -1167,7 +1167,7 @@ void HUDChat::DrawImplementation(void)
|
||||
}else if(g_nTeamOrderMode==TEAM_MESSAGE2){
|
||||
;//do nothing
|
||||
}
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
mfd_device.EndChannel();
|
||||
} else {
|
||||
}//hsh_initialized
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "MW4Headers.hpp"
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
#include "MWMission.hpp"
|
||||
#include "VehicleInterface.hpp"
|
||||
#include "Narc.hpp"
|
||||
@@ -13,7 +13,7 @@
|
||||
#include "mwguimanager.hpp"
|
||||
#include "MWPlayer.hpp"
|
||||
#include <Adept\Mission.hpp>
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
#include "hudcomp.hpp"
|
||||
#include "HUDComm.hpp"
|
||||
@@ -25,14 +25,14 @@
|
||||
#include "..\missionlang\resource.h"
|
||||
#include "mechlabheaders.h"
|
||||
|
||||
//상훈짱 begin
|
||||
//sanghoon begin
|
||||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
|
||||
#include <GameOS\render.hpp>
|
||||
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
|
||||
using namespace MechWarrior4;
|
||||
|
||||
|
||||
@@ -333,7 +333,7 @@ inline DWORD DarkerColor (DWORD color)
|
||||
{ m_Justification = value; }
|
||||
void Wrap (bool value)
|
||||
{ m_Wrap = value; }
|
||||
//상훈
|
||||
//sanghoon
|
||||
void SetAsAlt(){
|
||||
m_Font=altFontHandle;
|
||||
}
|
||||
@@ -381,9 +381,9 @@ inline DWORD DarkerColor (DWORD color)
|
||||
virtual void EndPos (DWORD& x,DWORD& y, bool bAdjust = true);
|
||||
bool Empty (void)
|
||||
{ return (m_Text[0] == 0); }
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
char *hsh_get_m_Text(){return m_Text;}
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
};
|
||||
|
||||
class HUDNumberText : public HUDText
|
||||
|
||||
@@ -95,7 +95,7 @@ void HUDTargetArrow::SetZoomWindow(Stuff::Scalar left,Stuff::Scalar top,Stuff::S
|
||||
|
||||
void HUDTargetArrow::DrawImplementation(void)
|
||||
{
|
||||
//상훈-깜박임 처리는 어디서 하는지 찾아 볼것.
|
||||
//sanghoon - need to find where blink handling is done.
|
||||
Point3D loc,size;
|
||||
DWORD color;
|
||||
int textx,texty,ty2;
|
||||
@@ -208,7 +208,7 @@ void HUDTargetArrow::DrawImplementation(void)
|
||||
{
|
||||
size = m_Textures[5]->Size ();
|
||||
m_Textures[5]->Draw (Point3D (m_TargetX,m_TargetY,0.9f),size,color);
|
||||
//꺽쇠 네개가 하나로 합쳐진 텍스쳐...
|
||||
//Texture of four angle brackets merged into one...
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -278,7 +278,7 @@ void HUDTorsoBar::DrawImplementation(void)
|
||||
Scalar currentxval,currentyval;
|
||||
Point3D size,loc,texsize;
|
||||
|
||||
//x축을 나타내는 그래프를 그리는 루틴...
|
||||
//Routine to draw the graph representing the x-axis...
|
||||
//_________________________________________________________________________
|
||||
size = TwistSize ();
|
||||
texsize = m_Textures[0]->Size ();
|
||||
@@ -289,7 +289,7 @@ void HUDTorsoBar::DrawImplementation(void)
|
||||
if (currentxval > 0)
|
||||
loc.x += 1.0f;
|
||||
DWORD color = DarkerColor (Color ());
|
||||
//가로 ruler를 그린다.(화살표는 들어있지 않음)
|
||||
//Draw horizontal ruler. (arrows not included)
|
||||
m_Textures[5]->Draw (loc,m_Textures[5]->Size (),color,HUDTexture::NO_FLIP,true);
|
||||
color = Color ();
|
||||
if (currentxval != 0)
|
||||
@@ -315,19 +315,19 @@ void HUDTorsoBar::DrawImplementation(void)
|
||||
ty= (DWORD) (loc.y+size.y+10);
|
||||
if ((currentxval > 5) || (currentxval < -5))
|
||||
{
|
||||
//과도한 twist시에 방향표시해줌..
|
||||
//Shows direction indicator when torso twist is excessive..
|
||||
m_TwistText->Draw (Point3D ((Scalar) tx,(Scalar) ty,0.9f));
|
||||
}
|
||||
//상체표시 사각형..
|
||||
//Upper body indicator rectangle..
|
||||
// Changed Torso Bar from Green to Yellow
|
||||
// MSL 5.00
|
||||
color = MakeColor (255,255,0,250);
|
||||
my_DrawRect (min,(int) loc.y,max,(int) (loc.y+size.y),color);
|
||||
|
||||
color = DarkerColor (Color ());
|
||||
//위쪽, 상체 방향표시 화살표..
|
||||
//Top arrow indicating upper body direction..
|
||||
m_Textures[2]->Draw (Point3D (loc.x-currentxval,loc.y-1,0.9f),texsize,color);
|
||||
//아래쪽. 중심표시 화살표..
|
||||
//Bottom arrow indicating center position..
|
||||
m_Textures[3]->Draw (Point3D (loc.x-1,loc.y+size.y+1,0.9f),texsize,color);
|
||||
// DrawLine ((int) (loc.x-currentxval),(int) (loc.y-1),(int) (loc.x-currentxval),(int) (loc.y+size.y),color);
|
||||
}
|
||||
@@ -339,7 +339,7 @@ void HUDTorsoBar::DrawImplementation(void)
|
||||
// DrawLine ((int) (loc.x),(int) (loc.y-1),(int) (loc.x),(int) (loc.y+size.y),color);
|
||||
}
|
||||
|
||||
//y축을 나타내는 그래프를 그리는 루틴...<==여기는 과도한 상하를 나타내는 텍스트가 없다.
|
||||
//Routine to draw graph for y-axis... <== no excessive up/down text here.
|
||||
//_________________________________________________________________________
|
||||
size = PitchSize ();
|
||||
currentyval = (m_TorsoPitch*size.y)/100.0f; // 33 is the width of the bar
|
||||
@@ -382,7 +382,7 @@ void HUDTorsoBar::DrawImplementation(void)
|
||||
m_Textures[1]->Draw (Point3D (loc.x+size.x,loc.y,0.9f),texsize,color);
|
||||
// DrawLine ((int) (loc.x-1),(int) (loc.y),(int) (loc.x+size.x+2),(int) (loc.y),color);
|
||||
}
|
||||
//끝.. DrawImplementation.
|
||||
//End.. DrawImplementation.
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "mwapplication.hpp"
|
||||
#include "..\missionlang\resource.h"
|
||||
|
||||
//상훈짱 begin
|
||||
//sanghoon begin
|
||||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
@@ -34,7 +34,7 @@ bool g_bNextTargetMode = false;
|
||||
bool g_bCrossTargetMode = false;
|
||||
// MSL 5.03 Secondary Damage Display
|
||||
int g_nAuxilMode = 0;
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
|
||||
using namespace MechWarrior4;
|
||||
namespace HUDDAMAGE
|
||||
@@ -330,9 +330,9 @@ HUDDamage::HUDDamage()
|
||||
Color (MakeColor (0,175,0,150));
|
||||
m_DamageFlashTime = 0;
|
||||
m_HitFlashTime = 0;
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
VehicleInterface::GetInstance()->hudDamageMode=false;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
m_ArmorMode = VehicleInterface::GetInstance()->hudDamageMode;
|
||||
for (i=0;i<MAX_HUD_DAMAGE_ZONE+1;i++)
|
||||
{
|
||||
@@ -410,7 +410,7 @@ void HUDDamage::Reset (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
//상훈
|
||||
//sanghoon
|
||||
mfd_device.LoadDamageTexture(texturename[m_MechID]);
|
||||
radar_device.LoadRadarDamageTexture(texturename[m_MechID]);
|
||||
}
|
||||
@@ -464,7 +464,7 @@ void HUDDamage::ArmorValue (Scalar values[MAX_HUD_DAMAGE_ZONE+1],bool firstpass)
|
||||
m_ArmorValues[i] = values[i];
|
||||
}
|
||||
}
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
|
||||
//nst DWORD SH_DamageColor[6]={0xFFFFFFFF,0xFFCCCCCC,0xFF999999,0xFF666666,0xFF333333,0xFF000000};
|
||||
const DWORD SH_DamageColor[6]={0xFFFFFFFF,0xFFDDDDDD,0xFFBBBBBB,0xFF999999,0xFF777777,0xFF333333};
|
||||
@@ -566,7 +566,7 @@ static RECT damage_back_frames[4]={
|
||||
{504,245,566,382},
|
||||
{573,245,634,382},
|
||||
};
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
void HUDDamage::DrawImplementation(void)
|
||||
{
|
||||
@@ -632,7 +632,7 @@ void HUDDamage::DrawImplementation(void)
|
||||
color = Color ();
|
||||
for (i=0;i<10;i++)
|
||||
{
|
||||
//글자를 그리는 곳인가??
|
||||
//Is this where text is drawn??
|
||||
m_Textures[20+i]->Draw (Point3D ((Scalar) bartable[i]+1.0f,(Scalar) y,0.9f),size,MakeColor (255,255,255,255),HUDTexture::NO_FLIP,true);
|
||||
if (!(m_HitFlashCount[trans_array[i]] & 0x01))
|
||||
{
|
||||
@@ -752,7 +752,7 @@ void HUDDamage::DrawImplementation(void)
|
||||
fred = 0;
|
||||
|
||||
for (i=0;i<11;i++)
|
||||
{//13이라는 숫자가 의미하는 것은 무엇일까?
|
||||
{//What does the number 13 mean here?
|
||||
#if 0
|
||||
if (i != fred)
|
||||
{
|
||||
@@ -872,7 +872,7 @@ void HUDDamage::DrawImplementation(void)
|
||||
mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
|
||||
mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
||||
|
||||
//원래것은..13,14,14,14,14,14,14,14,16,14의 간격을 두고 있다.
|
||||
//The original spacing is 13,14,14,14,14,14,14,14,16,14.
|
||||
const hsh_bartable[11] = {26+61*0,26+61*1,26+61*2,26+61*3,26+61*4,26+61*5,26+61*6,26+61*7,522,591,540};
|
||||
|
||||
DWORD color=0xFFFFFFFF;
|
||||
@@ -907,7 +907,7 @@ void HUDDamage::DrawImplementation(void)
|
||||
radar_device.pDDSTarget->Blt(&rc,NULL,NULL,DDBLT_COLORFILL ,&fx);
|
||||
|
||||
for (i=0;i<11;i++)
|
||||
{//13이라는 숫자가 의미하는 것은 무엇일까?
|
||||
{//What does the number 13 mean here?
|
||||
int dv=m_DamageValues[i];
|
||||
DWORD color=0xFF000000;
|
||||
if(0<=dv && dv<=5)
|
||||
@@ -948,7 +948,7 @@ void HUDDamage::DrawImplementation(void)
|
||||
{
|
||||
if (m_ArmorValues[trans_array[i]] != -1)
|
||||
{
|
||||
hsh_x=hsh_bartable[i];//7에서는 예외이다.
|
||||
hsh_x=hsh_bartable[i];//Exception at index 7.
|
||||
int tr=trans_array[i];
|
||||
|
||||
DWORD color=(m_HitFlashCount[tr] & 0x01)? 0xFFFFFFFF : SH_DamageColor[m_DamageValues[tr]];
|
||||
@@ -999,7 +999,7 @@ void HUDDamage::DrawImplementation(void)
|
||||
mfd_device.LoadDamageTexture(texturename[m_MechID]);
|
||||
|
||||
for (i=0;i<13;i++)
|
||||
{//13이라는 숫자가 의미하는 것은 무엇일까?
|
||||
{//What does the number 13 mean here?
|
||||
int dv=m_DamageValues[i];
|
||||
DWORD color=0xFF000000;
|
||||
if(0<=dv && dv<=5)color=SH_DamageColor[dv];
|
||||
@@ -1249,7 +1249,7 @@ HUDTargetDamage::HUDTargetDamage() :
|
||||
m_TargetName->Justification (HUDText::LEFT_ALIGN);
|
||||
m_TargetRangeText = new HUDNumberText ();
|
||||
m_TargetRangeText->Justification (HUDText::LEFT_ALIGN);
|
||||
//상훈
|
||||
//sanghoon
|
||||
// m_TargetRangeText->SetSize(HUDText::LARGE_SIZE);
|
||||
m_TargetRangeText->SetSize(HUDText::MEDIUM_SIZE);
|
||||
m_TargetAlignment = 0;
|
||||
@@ -1269,9 +1269,9 @@ HUDTargetDamage::HUDTargetDamage() :
|
||||
m_TargetMechID = 0;
|
||||
|
||||
m_Weapons.clear ();
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
VehicleInterface::GetInstance()->hudTargetDamageMode=false;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
m_ArmorMode = VehicleInterface::GetInstance()->hudTargetDamageMode;
|
||||
m_LastMechMode = false;
|
||||
}
|
||||
@@ -1315,7 +1315,7 @@ void HUDTargetDamage::Reset (void)
|
||||
}
|
||||
else
|
||||
{
|
||||
//상훈
|
||||
//sanghoon
|
||||
mfd_device.LoadTargetTexture(texturename[m_TargetMechID]);
|
||||
}
|
||||
|
||||
@@ -1764,7 +1764,7 @@ if(!hsh_initialized){
|
||||
|
||||
if (m_TargetTonnage == -1)
|
||||
{
|
||||
//타켓이 메크가 아닐때..
|
||||
//When target is not a mech..
|
||||
Verify (!m_ArmorMode); // only mechs show armor mode
|
||||
if (m_TargetVehicle.GetCurrent()->IsDerivedFrom (MWObject::DefaultData))
|
||||
{
|
||||
@@ -1805,7 +1805,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
else
|
||||
{
|
||||
//타켓이 메크일때..
|
||||
//When target is a mech..
|
||||
Verify (m_TargetVehicle.GetCurrent ()->IsDerivedFrom (Mech::DefaultData));
|
||||
Mech *mech = Cast_Object(Mech *, m_TargetVehicle.GetCurrent());
|
||||
Check_Object (mech);
|
||||
@@ -1826,7 +1826,7 @@ if(!hsh_initialized){
|
||||
|
||||
if (m_ArmorMode)
|
||||
{
|
||||
//타켓이 메크이고 아머 모드일때
|
||||
//When target is a mech and in armor mode
|
||||
int x,y;
|
||||
size = m_Textures[20]->Size ();
|
||||
|
||||
@@ -1897,7 +1897,7 @@ if(!hsh_initialized){
|
||||
}
|
||||
else
|
||||
{
|
||||
//상훈
|
||||
//sanghoon
|
||||
mfd_device.LoadTargetTexture(texturename[m_TargetMechID]);
|
||||
}
|
||||
|
||||
@@ -1910,7 +1910,7 @@ if(!hsh_initialized){
|
||||
fred = 0;
|
||||
|
||||
for (i=0;i<11;i++)
|
||||
{//13이라는 숫자가 의미하는 것은 무엇일까?
|
||||
{//What does the number 13 mean here?
|
||||
#if 0
|
||||
if (i != fred)
|
||||
{
|
||||
@@ -1983,7 +1983,7 @@ else
|
||||
|
||||
if (m_TargetVehicle.GetCurrent ())
|
||||
{
|
||||
//3D target 또는 2D Target을 그린다.
|
||||
//Draw 3D target or 2D target.
|
||||
if (!m_ArmorMode)
|
||||
{
|
||||
if(g_f3dtarget)
|
||||
@@ -2006,19 +2006,19 @@ else
|
||||
int mechindex=GetMechIndex(model->mechID);
|
||||
if(mechindex>=0)
|
||||
{
|
||||
//지원되는 mech만 그린다.
|
||||
//Draw only supported mechs.
|
||||
// MSL 5.02 Target MFD Image
|
||||
int x=(mechindex%8)*128;
|
||||
int y=(mechindex/8)*128;
|
||||
// int x=(mechindex%4)*128;
|
||||
// int y=(mechindex/4)*128;
|
||||
|
||||
//Target을 2D로 그린다.
|
||||
//Draw target in 2D.
|
||||
mfd_device.pD3DDevice->SetTexture(0,mfd_device.pDDSMechTexture);
|
||||
mfd_device.pD3DDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, FALSE);
|
||||
mfd_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MAGFILTER,D3DTFG_LINEAR);
|
||||
mfd_device.pD3DDevice->SetTextureStageState(0,D3DTSS_MINFILTER,D3DTFG_LINEAR);
|
||||
//메크의 종류별로 좌표를 계산하는.. 루틴을 작성하여 집어 넣을것...
|
||||
//Need to write routine to calculate coordinates per mech type...
|
||||
// MSL 5.02 Target MFD Image
|
||||
mfd_device.tw=1024,mfd_device.th=1024;
|
||||
// MSL 5.02 Target MFD Image Resize
|
||||
@@ -2060,7 +2060,7 @@ else
|
||||
radar_device.pDDSTarget->Blt(&rc,NULL,NULL,DDBLT_COLORFILL ,&fx);
|
||||
|
||||
for (int i=0;i<11;i++)
|
||||
{//13이라는 숫자가 의미하는 것은 무엇일까?
|
||||
{//What does the number 13 mean here?
|
||||
int dv=m_DamageValues[i];
|
||||
DWORD color=0xFF000000;
|
||||
if(0<=dv && dv<=5)
|
||||
@@ -2103,7 +2103,7 @@ else
|
||||
if (m_ShowData)
|
||||
{
|
||||
|
||||
//좌측 하단의 target의 무기의 상태를 표시하는 루틴..
|
||||
//Routine to display weapon status of target in lower-left..
|
||||
if (!m_ArmorMode)
|
||||
{
|
||||
stlport::vector<WeaponData>::iterator iter;
|
||||
@@ -2134,7 +2134,7 @@ else
|
||||
|
||||
if (m_TargetTonnage == -1)
|
||||
{
|
||||
//타켓이 메크가 아닐때..
|
||||
//When target is not a mech..
|
||||
Verify (!m_ArmorMode); // only mechs show armor mode
|
||||
if (m_TargetVehicle.GetCurrent()->IsDerivedFrom (MWObject::DefaultData))
|
||||
{
|
||||
@@ -2145,7 +2145,7 @@ else
|
||||
m_ArmorValues[0] = (veh->m_HitPoints / veh->m_MaxHitPoints);
|
||||
if (m_ArmorValues[0] != -1)
|
||||
{
|
||||
//데미지 막대 그래프를 그린다. 높이와 색상 동시에 표현된다.
|
||||
//Draw damage bar graph. Height and color are expressed simultaneously.
|
||||
int level;
|
||||
level = (int) ((m_ArmorValues[0]*(MAX_HUD_DAMAGE_LEVEL))+0.5f);
|
||||
level = MAX_HUD_DAMAGE_LEVEL - level;
|
||||
@@ -2160,7 +2160,7 @@ else
|
||||
}//When the target is not a mech.
|
||||
else
|
||||
{
|
||||
//타켓이 메크일때..
|
||||
//When target is a mech..
|
||||
Verify (m_TargetVehicle.GetCurrent ()->IsDerivedFrom (Mech::DefaultData));
|
||||
Mech *mech = Cast_Object(Mech *, m_TargetVehicle.GetCurrent());
|
||||
Check_Object (mech);
|
||||
@@ -2178,7 +2178,7 @@ else
|
||||
|
||||
if (m_ArmorMode)
|
||||
{
|
||||
//타켓이 메크이고 아머 모드일때
|
||||
//When target is a mech and in armor mode
|
||||
for (i=0;i<MAX_HUD_DAMAGE_ZONE;i++)
|
||||
{
|
||||
int tr=trans_array[i];
|
||||
@@ -2208,12 +2208,12 @@ else
|
||||
// MSL 5.03 Target Damage Display
|
||||
mfd_device.LoadTargetTexture(texturename[m_TargetMechID]);
|
||||
|
||||
//타켓이 메크이고 아머 모드가 아닐때..
|
||||
//When target is a mech and NOT in armor mode..
|
||||
if(mfd_device.pDDSTargetTexture==0)
|
||||
mfd_device.LoadTargetTexture(texturename[m_TargetMechID]);
|
||||
|
||||
for (i=0;i<11;i++)
|
||||
{//13이라는 숫자가 의미하는 것은 무엇일까?
|
||||
{//What does the number 13 mean here?
|
||||
int dv=m_DamageValues[i];
|
||||
DWORD color=0xFF000000;
|
||||
if(0<=dv && dv<=5)color=SH_DamageColor[dv];
|
||||
|
||||
@@ -77,11 +77,11 @@ namespace MechWarrior4
|
||||
int m_TargetMechID;
|
||||
bool m_ShowData;
|
||||
bool m_LastMechMode;
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
public:
|
||||
char hsh_targetname[64];
|
||||
char hsh_targetrange[64];
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
public:
|
||||
HUDTargetDamage();
|
||||
@@ -97,10 +97,10 @@ namespace MechWarrior4
|
||||
void TargetName (char *name)
|
||||
{
|
||||
m_TargetName->UpdateText (name);
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
strncpy(hsh_targetname,name,sizeof(hsh_targetname));
|
||||
hsh_targetname[sizeof(hsh_targetname)-1]=0;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
}
|
||||
void TargetRange (Stuff::Scalar value)
|
||||
{
|
||||
@@ -108,10 +108,10 @@ namespace MechWarrior4
|
||||
int temp = (int) value;
|
||||
sprintf (text,"%dm",temp);
|
||||
m_TargetRangeText->UpdateText (text);
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
strncpy(hsh_targetrange,text,sizeof(hsh_targetrange));
|
||||
hsh_targetrange[sizeof(hsh_targetrange)-1]=0;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
}
|
||||
void TargetTonnage (Stuff::Scalar value);
|
||||
void TargetAlignment (int value)
|
||||
|
||||
@@ -8,14 +8,14 @@
|
||||
#include "mwapplication.hpp"
|
||||
// MSL 5.02 Nav Points
|
||||
#include "navpoint.hpp"
|
||||
//상훈짱 begin
|
||||
//sanghoon begin
|
||||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
|
||||
#include <GameOS\render.hpp>
|
||||
extern char AssetsDirectory1[MAX_PATH];
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
|
||||
const Stuff::Time SHOT_TIME = 2.0;
|
||||
|
||||
@@ -37,7 +37,7 @@ HUDMap::HUDMap():
|
||||
AddTexture ("hud\\map",0,28,28,228,228);
|
||||
else{
|
||||
AddTexture (model->m_HudMap,0,0,0,255,255);
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
radar_device.MapDrawn=false;
|
||||
/*
|
||||
if(hsh_initialized){
|
||||
@@ -49,7 +49,7 @@ HUDMap::HUDMap():
|
||||
radar_device.MapDrawn=true;
|
||||
}
|
||||
*/
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
}
|
||||
|
||||
Location (Point3D (301,399,0.9f));
|
||||
@@ -154,7 +154,7 @@ void HUDMap::DrawImplementation(void)
|
||||
Point3D loc,size;
|
||||
int i;
|
||||
|
||||
//맵을 그린다.
|
||||
//Draw the map.
|
||||
Vehicle *vehicle = m_Vehicle.GetCurrent();
|
||||
|
||||
loc = Location ();
|
||||
@@ -163,7 +163,7 @@ void HUDMap::DrawImplementation(void)
|
||||
// loc.y -= (size.y/2.0f);
|
||||
m_Textures[0]->Draw (loc,size,MakeColor (255,255,255,255),HUDTexture::NO_FLIP,true);
|
||||
|
||||
//Torso Sweep(파이모양 시야각 표시도형)을 표시한다.
|
||||
//Display Torso Sweep (pie-shaped field-of-view indicator).
|
||||
if (NULL == vehicle)
|
||||
return;
|
||||
|
||||
@@ -214,7 +214,7 @@ void HUDMap::DrawImplementation(void)
|
||||
|
||||
|
||||
//Draw Radar Blips
|
||||
//레이다의 오브젝트들을 표시한다.
|
||||
//Display radar objects.
|
||||
|
||||
MWObject *current_object;
|
||||
for(i=0;i<vehicle->GetSensor()->numberOfContacts;i++)
|
||||
@@ -332,7 +332,7 @@ void HUDMap::DrawImplementation(void)
|
||||
color = MakeColor (255,255,255,250);
|
||||
m_Textures[id+20]->Draw (Point3D (object_display_pos.x,object_display_pos.y,0.9f),size,color,HUDTexture::NO_FLIP,true);
|
||||
}
|
||||
//작전 범위(Boundary) 표시 다각형(주황빨강)
|
||||
//Operation boundary display polygon (orange-red)
|
||||
size = Size ();
|
||||
loc = Location ();
|
||||
Mission *miss;
|
||||
|
||||
@@ -34,9 +34,9 @@ namespace MechWarrior4
|
||||
void DrawImplementation(void);
|
||||
void ConvertMapCoords (float& x,float& y);
|
||||
void ConvertMapCoords (Point3D& pt);
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
bool hsh_fdraw;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
public:
|
||||
HUDMap();
|
||||
|
||||
@@ -90,7 +90,7 @@ get_score:
|
||||
HUDScore::HUDScore()
|
||||
{
|
||||
m_AnimTime = 0;
|
||||
//상훈
|
||||
//sanghoon
|
||||
Location (Point3D (0,0,0.9f));
|
||||
// Location (Point3D (200,100,0.9f));
|
||||
Size (Point3D (310,300,0.9f));
|
||||
@@ -128,7 +128,7 @@ HUDScore::HUDScore()
|
||||
|
||||
m_PingHeader = new HUDText ();
|
||||
m_PingHeader ->SetAsAlt();
|
||||
//상훈
|
||||
//sanghoon
|
||||
/*
|
||||
m_PingHeader->Justification (HUDText::LEFT_ALIGN);
|
||||
m_PingHeader->UpdateText (app->GetLocString (IDS_PINGHEADER));
|
||||
@@ -444,7 +444,7 @@ void HUDScore::DrawImplementation(void)
|
||||
m_TimeLeftText->UpdateText (text);
|
||||
}
|
||||
|
||||
//상훈
|
||||
//sanghoon
|
||||
count+=1;
|
||||
loc = Location ();
|
||||
loc.y=600-count*LINE_HEIGHT;
|
||||
@@ -455,7 +455,7 @@ void HUDScore::DrawImplementation(void)
|
||||
|
||||
DWORD bcolor = BrighterColor (Color ());
|
||||
|
||||
//상훈..
|
||||
//sanghoon
|
||||
{
|
||||
Stuff::Point3D loc2(800-size.x,600-LINE_HEIGHT-1,0.9f);
|
||||
LDrawRect (loc2,0,0,size.x,LINE_HEIGHT,MakeColor (0,150,0,128));
|
||||
@@ -481,7 +481,7 @@ void HUDScore::DrawImplementation(void)
|
||||
m_PlayerTitle->Draw (Point3D (loc.x+10,yvalue,0.9f));
|
||||
|
||||
DWORD h;
|
||||
//상훈
|
||||
//sanghoon
|
||||
//m_PingHeader->DrawSize (pingwidth,h);
|
||||
//pingx = loc.x + size.x - pingwidth - 10;
|
||||
pingx = loc.x + size.x ;
|
||||
|
||||
@@ -367,10 +367,10 @@ void HUDReticle::DrawImplementation(void)
|
||||
m_Textures[36]->Draw (loc,size,m_LeftCenterColor);
|
||||
m_Textures[37]->Draw (loc,size,m_RightCenterColor);
|
||||
|
||||
for (i=0;i<3;i++)//상훈 원래 6이었음
|
||||
for (i=0;i<3;i++)//sanghoon: originally 6
|
||||
{
|
||||
size = m_Textures[20+i]->Size ();
|
||||
//CanHit는 Hudweapon에서 set한다...
|
||||
//CanHit is set in Hudweapon...
|
||||
if (m_Weapons->CanHit (i))
|
||||
color = MakeColor (0,255,0,255);
|
||||
else {
|
||||
|
||||
@@ -15,14 +15,14 @@ static float RECOVER_FROM_JAMMING_TIME = 5.0f;
|
||||
// MSL 5.03 Ammo Bay Fire
|
||||
static float TIME_AMMO_BAY_FIRE = 7.0f;
|
||||
|
||||
//상훈짱 begin
|
||||
//sanghoon begin
|
||||
#include <windows.h>
|
||||
#include <ddraw.h>
|
||||
#include <d3d.h>
|
||||
|
||||
#include <GameOS\render.hpp>
|
||||
extern bool g_bNoWeaponRangeCheck;
|
||||
//상훈짱 end
|
||||
//sanghoon end
|
||||
|
||||
static void MakeStringCaps(char* buffer)
|
||||
{
|
||||
@@ -555,7 +555,7 @@ if(mfd_device.BeginChannel(4))
|
||||
|
||||
|
||||
int rh=25;//row_height
|
||||
//16개의 row를 가질수 있는것으로 가정한다.(row포함)
|
||||
//Assumes up to 16 rows (including header row).
|
||||
// background boxes
|
||||
|
||||
mfd_device.DrawQuad(0+lm,0+tm,96+lm,(totalcount+1)*rh+10+tm,0xFF404040);
|
||||
@@ -609,13 +609,13 @@ if(mfd_device.BeginChannel(4))
|
||||
|
||||
DWORD hsh_color1=0,hsh_color2=0;
|
||||
|
||||
//무기 발사가능 상태: 각각의 색상에 대해 정확히 정의 할것.
|
||||
//Weapon fire-ready status: define exact color for each state.
|
||||
|
||||
//정상(타겟안에 있음)(발사가능) 0xFFFFFFFF
|
||||
//정상(타겟밖에 있음)(발사가능) 0xFFFFFFFF
|
||||
//로딩중(발사 불가) 0xFFA0A0A0
|
||||
//탄알이 떨어짐(발사불가) 0xFF808080
|
||||
//고장남(발사불가) 0xFF606060
|
||||
//Normal (target in range)(can fire) 0xFFFFFFFF
|
||||
//Normal (target out of range)(can fire) 0xFFFFFFFF
|
||||
//Reloading (cannot fire) 0xFFA0A0A0
|
||||
//Out of ammo (cannot fire) 0xFF808080
|
||||
//Destroyed (cannot fire) 0xFF606060
|
||||
DWORD nameheight=30;
|
||||
int top=5+(weapony+1)*rh;
|
||||
int bottom = top+rh;
|
||||
@@ -694,7 +694,7 @@ if(mfd_device.BeginChannel(4))
|
||||
char *weapon_string[3]={"1","2","3"};
|
||||
|
||||
|
||||
//해당 무기의 그룹의 상태를 표시한다.
|
||||
//Display the status of the weapon group.
|
||||
for(int i=0;i<3;i++){
|
||||
DWORD weapon_color=weapon_flag[i]?normal_color:nogroup_color;
|
||||
// MSL 5.00 Added Ammocount check, if = 0 then weapon name same as ammo nogroup_color
|
||||
@@ -707,7 +707,7 @@ if(mfd_device.BeginChannel(4))
|
||||
|
||||
Point3D numsize = m_Textures[20]->Size ();
|
||||
|
||||
//무기 이름을 표시한다.
|
||||
//Display weapon name.
|
||||
// MSL 5.00 Added Ammocount check, if = 0 then weapon name same as ammo out_color
|
||||
switch (weapon->m_status)
|
||||
{
|
||||
@@ -786,7 +786,7 @@ if(mfd_device.BeginChannel(4))
|
||||
}
|
||||
}
|
||||
|
||||
//현재 엔터키로 발사되는 선택된 무기에 대해서 프레임을 표시한다.
|
||||
//Display frame for the selected weapon currently fired with Enter.
|
||||
if (weapon->m_weapon == m_SingleFire.GetCurrent ()){
|
||||
mfd_device.DrawFrame(155+lm,top+1+tm,545+lm,bottom-1+tm,0xFFFFFFFF);
|
||||
}
|
||||
@@ -795,7 +795,7 @@ if(mfd_device.BeginChannel(4))
|
||||
if ((ammocount > -1) && (weapon->m_status != 2)){
|
||||
mfd_device.pFont[0].DrawText(615-5+lm,center+tm,ammocount_color,text,TEXTALIGN_VCENTER|TEXTALIGN_RIGHT);
|
||||
}else if (ammocount == -1){
|
||||
//무기수가 제한이 없는 무기의 종류에는 '-'를 표시한다.
|
||||
//Display '-' for weapon types with unlimited ammo.
|
||||
mfd_device.pFont[0].DrawText(615-5+lm,center+tm,ammocount_color,"-",TEXTALIGN_VCENTER|TEXTALIGN_RIGHT);
|
||||
}
|
||||
weapony ++;
|
||||
|
||||
@@ -1008,27 +1008,27 @@ const char* ArmorZoneStr(int nArmorZone)
|
||||
case Adept::DamageObject::NullArmorZone:
|
||||
return "()";
|
||||
case Adept::DamageObject::LeftLegArmorZone:
|
||||
return "왼발";
|
||||
return "Left Leg";
|
||||
case Adept::DamageObject::RightLegArmorZone:
|
||||
return "오른발";
|
||||
return "Right Leg";
|
||||
case Adept::DamageObject::LeftArmArmorZone:
|
||||
return "왼팔";
|
||||
return "Left Arm";
|
||||
case Adept::DamageObject::RightArmArmorZone:
|
||||
return "오른팔";
|
||||
return "Right Arm";
|
||||
case Adept::DamageObject::RightTorsoArmorZone:
|
||||
return "우측";
|
||||
return "Right Torso";
|
||||
case Adept::DamageObject::LeftTorsoArmorZone:
|
||||
return "좌측";
|
||||
return "Left Torso";
|
||||
case Adept::DamageObject::CenterTorsoArmorZone:
|
||||
return "전면";
|
||||
return "Front";
|
||||
case Adept::DamageObject::CenterRearTorsoArmorZone:
|
||||
return "후면";
|
||||
return "Rear";
|
||||
case Adept::DamageObject::HeadArmorZone:
|
||||
return "머리";
|
||||
return "Head";
|
||||
case Adept::DamageObject::SpecialArmorZone1:
|
||||
return "보조장치1";
|
||||
return "Aux Device 1";
|
||||
case Adept::DamageObject::SpecialArmorZone2:
|
||||
return "보조장치2";
|
||||
return "Aux Device 2";
|
||||
case Adept::DamageObject::DefaultArmorZone:
|
||||
return "Default";
|
||||
}
|
||||
@@ -1990,83 +1990,83 @@ public:
|
||||
static SMSGFMT s_aKill[20][2] = {
|
||||
{
|
||||
{ "%s's %s destroys %s's %s!", 0 }, // ok!
|
||||
{ "%s의 %s, %s의 %s을(를) 파괴하다!", 0 }, // ok!
|
||||
{ "%s's %s destroyed %s's %s!", 0 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s explodes in a fire-ball, thanks to %s.", 1 }, // ok!
|
||||
{ "%s의 %s, 각 기관부의 화염으로 폭발! %s의 절묘한 공격성공!", 1 }, // ok!
|
||||
{ "%s's %s explodes in flames! %s lands a perfect hit!", 1 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s delivers the last blow as %s's %s explodes in flames!", 2 }, // ok!
|
||||
{ "%s는 %s의 %s에!", 2 - 100}, // ok!
|
||||
{ "%s took a hit to %s's %s!", 2 - 100}, // ok!
|
||||
},
|
||||
{
|
||||
{ "Smoking wreckage is all that's left of %s's %s after %s delivers the fatal blow!", 1 },
|
||||
{ "%s의 무자비한 공격으로 %s의 %s 불타는 잔해만 남길 것이다.", 2 }, // ok!
|
||||
{ "%s's merciless assault leaves only burning wreckage of %s's %s.", 2 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Glorious victory goes to %s as the wreckage from %s's %s lies burning on the battlefield!", 2 },
|
||||
{ "전황은 급속도로 진전, %s의 생존가능성은 0%%!", 8 }, // ok!
|
||||
{ "The battle escalates rapidly - %s's survival probability is 0%%!", 8 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s is put out of it's misery by a devastating shot from %s.", 1 },
|
||||
{ "%s의 압도적인 화력 앞에 %s 처참히 무너지고 있다.", 4 }, // ok!
|
||||
{ "Under %s's overwhelming firepower, %s crumbles miserably.", 4 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s racks up another kill marker from reducing %s's %s to rubble!", 2 },
|
||||
{ "%s %s의 %s을(를) 때려 눕히고, 새로운 킬마크를 얻었다.", 2 }, // ok!
|
||||
{ "%s knocked out %s's %s and earned a new kill mark.", 2 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Fresh paint is applied to %s's %s to mark the destruction of %s's %s!", 0 }, // ok!
|
||||
{ "%s는 %s를 격추한 킬마크를 %s에 추가했다.", 0 - 100 },
|
||||
{ "%s added a kill mark on %s for shooting down %s.", 0 - 100 },
|
||||
},
|
||||
{
|
||||
{ "The burning wreckage of %s's %s is a reminder to all of the prowess of %s's battle skills!", 1 },
|
||||
{ "%s의 잔해는 %s이(가) 가져갈 승리의 기념품이 될것이다.", 7 }, // ok!
|
||||
{ "The wreckage of %s will be %s's trophy of victory.", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "The thunderous explosion of %s's %s is music to the ears of %s!", 1 },
|
||||
{ "%s의 귀에 들려오는 죽음의 전주곡. 지휘자는 %s.", 7 }, // ok!
|
||||
{ "A death prelude echoes in %s's ears. The conductor: %s.", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s is destroyed by %s's %s.", 3 },
|
||||
{ "%s'의 %s, %s의 %s에게 파괴되었다.", 3 }, // ok!
|
||||
{ "%s's %s was destroyed by %s's %s.", 3 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s brings the four horseman of the apocalypse down upon %s.", 4 },
|
||||
{ "%s(이)가 휘두르는 심판의 추가 %s에게 작렬했다.", 4 }, // ok!
|
||||
{ "The pendulum of judgment swung by %s strikes %s.", 4 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's life flashes as %s reduces the %s to a burning wreck.", 5 },
|
||||
{ "%s의 마지막 생명줄에, %s !", 7 - 100 }, // ok!
|
||||
{ "On %s's last lifeline, %s!", 7 - 100 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s is deafened by the resounding roar of the exploding %s, thanks to %s.", 1 },
|
||||
{ "%s 기체의 폭발소리와 함께, 저 하늘로 날아갔다. %s에게 영광을!", 7 }, // ok!
|
||||
{ "%s's mech explodes skyward. Glory to %s!", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "A kill marker is placed on %s's %s to mark the victory over %s.", 6 },
|
||||
{ "%s의 %s에 새로운 킬마크를 추가해야 할 듯, 희생자는 %s", 6 }, // ok!
|
||||
{ "A new kill mark should be added to %s's %s, victim: %s", 6 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s is delivered unto the inferno with regards from %s.", 7 },
|
||||
{ "%s, %s의 호위하에 지옥으로 향했다. %s에게 명복을!", 9 }, // ok!
|
||||
{ "%s headed to hell under %s's escort. Rest in peace, %s!", 9 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Another kill marker is given up by %s, as %s celebrates victory.", 7 },
|
||||
{ "%s, %s의 새로운 킬 마크가 되었다. 영원한 안식을…", 7 - 100 },
|
||||
{ "%s became %s's new kill mark. Rest in peace...", 7 - 100 },
|
||||
},
|
||||
{
|
||||
{ "Best wishes in the afterlife are presented to %s from %s.", 7 },
|
||||
{ "%s에게 남은 것은 오직 %s에 대한 복수뿐!", 7 }, // ok!
|
||||
{ "All that remains for %s is revenge against %s!", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Tragedy strikes %s as %s guns the %s down.", 5 },
|
||||
{ "%s 모든 화력을 동원해 %s의 %s을(를) 파괴했다.", 2 }, // ok!
|
||||
{ "%s brought all firepower to bear and destroyed %s's %s.", 2 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s earns the revenge of %s after the tragic destruction of the %s.", 2 },
|
||||
{ "%s의 비극적인 최후! %s 절망하는 %s을(를) 지켜볼 뿐이다.", 9 }, // ok!
|
||||
{ "A tragic end for %s! %s can only watch %s in despair.", 9 }, // ok!
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2077,11 +2077,11 @@ static SMSGFMT s_aKill[20][2] = {
|
||||
static SMSGFMT s_aSuicide[2][2] = {
|
||||
{
|
||||
{ "%s leaves the battlefield in disgrace after causing the destruction of the %s.", 0 },
|
||||
{ "%s 자폭! %s 불명예스럽게 전장을 떠났다!", 2 },
|
||||
{ "%s self-destructed! %s left the battlefield in disgrace!", 2 },
|
||||
},
|
||||
{
|
||||
{ "%s will not grace the halls of the honored mechwarriors after self-destructing the %s.", 0 },
|
||||
{ "%s 자폭! 비겁자여, 진실로 승리를 원하는가?", 3 },
|
||||
{ "%s self-destructed! Coward, do you truly desire victory?", 3 },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2106,43 +2106,43 @@ static SMSGFMT s_aSuicide[2][2] = {
|
||||
static SMSGFMT s_aShot[10][2] = {
|
||||
{
|
||||
{ "%s's %s fires the %s and damages the %s of %s's %s.", 0 },
|
||||
{ "%s %s의 %s에 %s으로 공격했다", 1 }, // ok!
|
||||
{ "%s attacked %s's %s with %s", 1 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s fires the %s's %s and decimates the %s of %s's %s.", 2 },
|
||||
{ "%s이(가) 탑승한 %s, %s로 %s이(가) 탑승한 %s의 %s에 피해를 입혔다.", 2 },
|
||||
{ "%s piloting %s damaged %s's %s on %s's %s.", 2 },
|
||||
},
|
||||
{
|
||||
{ "%s's %s takes a devastating hit in the %s from %s.", 3 },
|
||||
{ "%s의 %s, %s의 압도적인 공격에 %s에 피해를 입었다.", 4 }, // ok!
|
||||
{ "%s's %s took damage to the %s under %s's overwhelming attack.", 4 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s suffers a direct hit to it's %s from %s's %s.", 5 },
|
||||
{ "%s의 %s은(는) %s의 %s에 직접적인 피해를 받았다. 피해 %s!", 6 -100},
|
||||
{ "%s's %s took direct damage from %s's %s. Damage: %s!", 6 -100},
|
||||
},
|
||||
{
|
||||
{ "%s damages %s's %s.", 7 },
|
||||
{ "%s, %s의 %s에 피해를 입혔다..", 7 }, // ok!
|
||||
{ "%s dealt damage to %s's %s..", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Dense black smoke pours from %s's %s as a result of %s's targeted hit.", 8 },
|
||||
{ "%s의 절묘한 공격으로 %s의 %s에서 검은 연기가 퍼지고 있다.", 7 }, // ok!
|
||||
{ "Black smoke billows from %s's %s from %s's precise attack.", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Fire boils from the damaged %s of %s's %s after %s hits it with a %s.", 9 },
|
||||
{ "%s %s을(를) 발사하여, %s이(가) 탑승한 %s의 %s에 피해를 발생시켰다.", 10 }, // ok!
|
||||
{ "%s fired %s, dealing damage to the %s of %s's %s.", 10 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Smoke and fire are trailing from %s's %s, all results of the %s blast inflicted by %s.", 11 },
|
||||
{ "%s의 %s 공격에, 불과 연기가 %s의 기체를 뒤덮고 있다.", 15 }, // ok!
|
||||
{ "Fire and smoke engulf %s's mech from %s's %s attack.", 15 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s targets and fires the %s; %s cries in dismay as the %s's %s is damaged.", 10 },
|
||||
{ "%s %s을(를) 조준하여 %s이(가) 탑승한 %s의 %s에 맞춘 후 방아쇠를 당겼다.", 10 }, // ok!
|
||||
{ "%s aimed %s and pulled the trigger, hitting the %s of %s's %s.", 10 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s takes a severe wound to the %s as %s aims for the %s again.", 13 },
|
||||
{ "%s 다시 %s의 %s을(를) 조준하여 사격했다. %s, %s에 심각한 피해를 입은 듯.", 14 -100},
|
||||
{ "%s aimed again at %s's %s and fired. %s seems to have taken serious damage to %s.", 14 -100},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2150,19 +2150,19 @@ static SMSGFMT s_aShot[10][2] = {
|
||||
static SMSGFMT s_aCTF[1][2] = {
|
||||
{
|
||||
{ "%s captured flag.", 0 },
|
||||
{ "%s, 깃발 획득!.", 0 },
|
||||
{ "%s captured the flag!", 0 },
|
||||
},
|
||||
};
|
||||
static SMSGFMT s_aFBK[1][2] = {
|
||||
{
|
||||
{ "%s destroyed friendly building.", 0 },
|
||||
{ "%s, 깃발 획득!.", 0 },
|
||||
{ "%s captured the flag!", 0 },
|
||||
},
|
||||
};
|
||||
static SMSGFMT s_aEBK[1][2] = {
|
||||
{
|
||||
{ "%s destroyed enemy building.", 0 },
|
||||
{ "%s, 깃발 획득!.", 0 },
|
||||
{ "%s captured the flag!", 0 },
|
||||
},
|
||||
};
|
||||
const SMSGFMT* pcFMT;
|
||||
|
||||
@@ -1077,7 +1077,7 @@ int CStrArray::GetTotalLength() const
|
||||
int nTotalLength;
|
||||
int i, nSize = GetSize();
|
||||
|
||||
nTotalLength = nSize; // nSize개의 '\0'
|
||||
nTotalLength = nSize; // nSize null terminators '\0'
|
||||
for(i = 0; i < nSize; i++) {
|
||||
nTotalLength += strlen(GetAt(i));
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include<Windows.h>
|
||||
|
||||
//
|
||||
//Do not use ….\EulaTest\\1.0 as the key for your game; use your game name and version instead…
|
||||
//Do not use ....\EulaTest\\1.0 as the key for your game; use your game name and version instead...
|
||||
|
||||
// PLEASE NOTE: do not place backslashes on beginning or end of regkey.
|
||||
//
|
||||
@@ -11,7 +11,7 @@
|
||||
typedef DWORD (*EBUPROC) (LPCTSTR lpRegKeyLocation, LPCTSTR lpEULAFileName, LPCSTR lpWarrantyFileName, BOOL fCheckForFirstRun);
|
||||
|
||||
//
|
||||
//The game application’s .RC file should define strings for the EULA and WARRANTY pathnames…
|
||||
//The game application's .RC file should define strings for the EULA and WARRANTY pathnames...
|
||||
|
||||
//
|
||||
|
||||
@@ -28,13 +28,13 @@ bool FirstRunEula(const char *eula_filename,const char *warranty_filename)
|
||||
if (NULL == hMod)
|
||||
hMod = LoadLibrary("EBUEula.dll");
|
||||
|
||||
if (NULL == hMod) // can’t attach to DLL
|
||||
if (NULL == hMod) // can't attach to DLL
|
||||
{
|
||||
STOP(("Cannot Load EBUEula.dll"));
|
||||
}
|
||||
pfnEBUEula = (EBUPROC) GetProcAddress(hMod, "EBUEula");
|
||||
|
||||
if (NULL == pfnEBUEula) // can’t find entry point
|
||||
if (NULL == pfnEBUEula) // can't find entry point
|
||||
{
|
||||
FreeLibrary(hMod);
|
||||
STOP(("Cannot Find Entry Point to EBUEula.dll"));
|
||||
@@ -43,9 +43,9 @@ bool FirstRunEula(const char *eula_filename,const char *warranty_filename)
|
||||
|
||||
//
|
||||
//This call enables both EULA and warranty accepting/viewing/printing. If your
|
||||
//game doesn’t ship with a WARRANTY file, specifiy NULL instead of szWarranty…
|
||||
//game doesn't ship with a WARRANTY file, specifiy NULL instead of szWarranty...
|
||||
|
||||
//The code below, for instance, works with both OEM and retail builds…
|
||||
//The code below, for instance, works with both OEM and retail builds...
|
||||
|
||||
//
|
||||
const char *pszWarrantyParam = 0xFFFFFFFF != GetFileAttributes(warranty_filename) ? warranty_filename : NULL;
|
||||
|
||||
@@ -190,10 +190,10 @@ int bloatSizeTable[8] = {
|
||||
extern bool(__cdecl *NoCDMessageFunction)(void);
|
||||
|
||||
extern bool gNoDialogs;
|
||||
//상훈.. begin
|
||||
//sanghoon begin
|
||||
extern bool use_shgui;
|
||||
extern int SCREENS;
|
||||
//상훈.. end
|
||||
//sanghoon end
|
||||
|
||||
bool gRunEula=true;
|
||||
bool gNoCD=false;
|
||||
@@ -290,13 +290,13 @@ void _stdcall InitializeGameEngine()
|
||||
|
||||
|
||||
// bool needflip=Environment.fullScreen && IsFirstRun();
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
bool needflip=false;
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
if(needflip){
|
||||
//상훈 앞
|
||||
//sanghoon begin
|
||||
//MessageBeep(MB_ICONEXCLAMATION);
|
||||
//상훈 뒤
|
||||
//sanghoon end
|
||||
|
||||
EnterWindowMode();
|
||||
}
|
||||
@@ -336,7 +336,7 @@ void _stdcall InitializeGameEngine()
|
||||
{
|
||||
//Original
|
||||
//page->GetEntry("videodriverindex",&Environment.FullScreenDevice);
|
||||
//상훈
|
||||
//sanghoon
|
||||
Environment.FullScreenDevice=0;
|
||||
page->GetEntry("antialias",&Environment.AntiAlias);
|
||||
page->GetEntry("bitdepth",&Environment.bitDepth);
|
||||
@@ -355,7 +355,7 @@ void _stdcall InitializeGameEngine()
|
||||
//Original
|
||||
//page->GetEntry("HudDamageMode",&VehicleInterface::hudDamageMode);
|
||||
//page->GetEntry("HudTargetDamageMode",&VehicleInterface::hudTargetDamageMode);
|
||||
//상훈
|
||||
//sanghoon
|
||||
VehicleInterface::hudDamageMode=false;
|
||||
VehicleInterface::hudTargetDamageMode=false;
|
||||
}
|
||||
@@ -1088,9 +1088,9 @@ DWORD __stdcall gos_EnableSetting( gosSetting Setting, DWORD Value );
|
||||
Environment.soundDisable = (strstr(all_lower, "-nosound") != NULL);
|
||||
Environment.fullScreen = (strstr(all_lower, "-window") == NULL);
|
||||
|
||||
//상훈짱.. begin
|
||||
//sanghoon begin
|
||||
use_shgui=Environment.fullScreen?1:0;
|
||||
//상훈짱.. end
|
||||
//sanghoon end
|
||||
|
||||
gNoAutoConfig= (strstr(all_lower, "-noautoconfig") != NULL);
|
||||
|
||||
@@ -1440,7 +1440,7 @@ int WINAPI WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int n
|
||||
if (token && token[7])
|
||||
{
|
||||
int n = atoi(&token[7]);
|
||||
if ((0 <= n) && (n <= 3)) // 0 - no MFDs, 1 - orginal(5+1=dual & single), 2 - B&W(3 + 1=1 dual), 3 - color(3 + 1=2 dual)
|
||||
if ((0 <= n) && (n <= 4)) // 0 - no MFDs, 1 - orginal(5+1=dual & single), 2 - B&W(3 + 1=1 dual), 3 - color(3 + 1=2 dual), 4 - split dual 640x480
|
||||
g_nTypeOfMFDs = n;
|
||||
}
|
||||
token = strstr(all_lower, "-trio ");
|
||||
|
||||
@@ -517,7 +517,7 @@ void CSOC_Server::OnSendFile()
|
||||
BYTE bCode;
|
||||
if (Disassemble("B", &bCode)) {
|
||||
ASSERT((bCode == 0) || (bCode == 3));
|
||||
// 받아가시오 from Game to console...
|
||||
// Receiving from Game to console...
|
||||
SYSTEMTIME* pSysTime;
|
||||
WORD wSysTimeSize;
|
||||
GUID* pGUID;
|
||||
@@ -533,7 +533,7 @@ void CSOC_Server::OnSendFile()
|
||||
pSF = g_pCTCLManager->m_SFM_Recv.Find(*pGUID, nType);
|
||||
if (pSF) {
|
||||
if (bCode == 3) {
|
||||
// 미션리뷰 서버가 mission review 받았다는 것을 받았느냐?
|
||||
// Did we receive confirmation the mission review server got the mission review?
|
||||
pSF->m_bProcessed = true;
|
||||
g_pCTCLManager->m_SFM_Recv.Cut(pSF);
|
||||
g_pCTCLManager->m_SFM_Done.AddTail(pSF);
|
||||
@@ -910,7 +910,7 @@ void CSOC_Client::OnSendFile()
|
||||
BYTE bCode;
|
||||
if (Disassemble("B", &bCode)) {
|
||||
ASSERT((bCode == 1) || (bCode == 2));
|
||||
// 받았오 from console to Game...
|
||||
// Received from console to Game...
|
||||
SYSTEMTIME* pSysTime;
|
||||
WORD wSysTimeSize;
|
||||
GUID* pGUID;
|
||||
@@ -1437,21 +1437,21 @@ void CCTCLManager::Run()
|
||||
#endif // !defined(CTCL_LAUNCHER)
|
||||
} else {
|
||||
/*
|
||||
클라이언트나 서버의 경우 실행되는 코드이다.
|
||||
Code executed for both client and server.
|
||||
|
||||
*있을수 있는 상태들
|
||||
서버/클라이언트가 결정되기전.. 명령 대기상태
|
||||
(종료/서버시작/클라이언트 시작등의 명령이 올수 있다.)
|
||||
*Possible states:
|
||||
Before server/client role is determined: waiting for commands
|
||||
(Commands such as exit/start-server/start-client may arrive.)
|
||||
|
||||
서버로 실행되어 서버 메크 설정에 대한 데이타를 기다리는 상태
|
||||
(CreateSession가 실행된 상태이다.)
|
||||
서버로 실행되어 Bot들에 대한 정보를 기다리는 상태
|
||||
(클라이언트의 참여는 클라이언트와 서버간에 자동으로 이루어진다.)
|
||||
서버로 실행되어 Launch를 기다리는 상태
|
||||
Running as server, waiting for server mech configuration data
|
||||
(State after CreateSession has been called.)
|
||||
Running as server, waiting for Bot information
|
||||
(Client joining happens automatically between client and server.)
|
||||
Running as server, waiting for Launch
|
||||
|
||||
==>클라이언트는 실행즉시 데이타들이 전달되므로 대기상태가 없다.
|
||||
==>Client has no waiting state as data is transferred immediately on startup.
|
||||
|
||||
==>각각의 상태를 정의하고 각 상태에 맞는 처리를 해주면 된다.
|
||||
==>Define each state and implement the appropriate handling for each.
|
||||
switch(state){
|
||||
}
|
||||
*/
|
||||
@@ -1533,8 +1533,8 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
//서버/클라이언트로서 실행준비하도록 명령을 전달한다.
|
||||
//또한 서버를 실행하는데 필요한 모든 파라미터도 함께 전달한다.
|
||||
//Send command to prepare for execution as server/client.
|
||||
//Also transmit all parameters required to run the server.
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
if (!pi.m_bBot) {
|
||||
@@ -1561,12 +1561,12 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
}
|
||||
if (i == g_nPlayerInfos) {
|
||||
// Bot들에 대한 정보를 모두 한데 묶어서 보낸다.
|
||||
// Bundle and send all Bot information together.
|
||||
CPacket pak(&SVR.GetGameSOC());
|
||||
|
||||
pak.Assemble("B", C_BOTS);
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
if (i != g_nServer) { // 원래 Bot만 지금은 서버를 제외한 전부...
|
||||
if (i != g_nServer) { // Originally bots only; now everyone except the server...
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
pak.Assemble("BnsDWwsnn", pi.m_bBot, pi.m_nLevelOrTesla, pi.m_szName, pi.m_nMechIndex, pi.m_fileID, pi.m_recordID, pi.m_szMech, pi.m_nTeamOrSkin, pi.m_nDecal);
|
||||
}
|
||||
@@ -1577,10 +1577,10 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
// 게임이 성공적으로 만들어지면 서버와 클라이언트들의 Mech에 대한 정보들을 Set한다...
|
||||
// Once the game is successfully created, set Mech info for server and all clients...
|
||||
if (SOCGame.m_nGameReturn == _EGR_OkCreateSession) {
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
if (i != g_nServer) { // 서버는 이미 SetMech에 진입한 상태...
|
||||
if (i != g_nServer) { // Server has already entered SetMech...
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
if (!pi.m_bBot) {
|
||||
CTeslaInfo& ti = m_aTIs.GetAt(pi.m_nLevelOrTesla);
|
||||
@@ -1593,8 +1593,8 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
//모든 클라이언드들이 서버에 참여하기를 기다린다.<==이 응답은 서버로 부터 얻을 수 있다.
|
||||
//참여가 모두 끝났으면, 서버로 하여금 게임을 Launch시키도록 한다.
|
||||
//Wait for all clients to join the server. <==This response comes from the server.
|
||||
//Once all clients have joined, instruct the server to Launch the game.
|
||||
if (SOCGame.m_nGameReturn == _EGR_OkLaunchReady) {
|
||||
g_nMech4Comm = 9;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
const char* m_pcsz;
|
||||
|
||||
int m_nLauncherConnection; // 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // m_bCameraShip값에 따라 게임 혹은 카메라 쉽과의 접속을 의미, 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // Connection to game or camera ship per m_bCameraShip, 0: no connection, +1: connected, -1: connecting
|
||||
int m_nApplType;
|
||||
int m_nApplState;
|
||||
int m_nGameState;
|
||||
|
||||
@@ -44,7 +44,7 @@ int GetDayEnd(int nYear, int nMonth)
|
||||
|
||||
long GetTotalSeconds(int nYear, int nMonth, int nDay)
|
||||
{
|
||||
// nYear, nMonth, nDay날의 0시 0분 0초를 0으로 한 초단위 수...
|
||||
// Seconds elapsed since 00:00:00 on the date nYear/nMonth/nDay...
|
||||
ASSERT(nYear >= 1970);
|
||||
ASSERT((1 <= nMonth) && (nMonth <= 12));
|
||||
ASSERT(1 <= nDay);
|
||||
@@ -57,13 +57,13 @@ long GetTotalSeconds(int nYear, int nMonth, int nDay)
|
||||
if (IsLeapYear(nStart)) {
|
||||
nDays++;
|
||||
}
|
||||
lTotal += nDays * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += nDays * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
}
|
||||
for(nStart = 1; nStart < nMonth; nStart++) {
|
||||
int nDayEnd = GetDayEnd(nYear, nStart);
|
||||
lTotal += nDayEnd * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += nDayEnd * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
}
|
||||
lTotal += (nDay - 1) * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += (nDay - 1) * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
|
||||
return lTotal;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class CTimeDate
|
||||
public:
|
||||
union {
|
||||
struct {
|
||||
// Bit Field는 앞쪽에 지정된 것이 LowBit이다.
|
||||
// Bit Fields declared first are at the low-bit end.
|
||||
DWORD m_xDay: 5; // 2^0, 2^5-1
|
||||
DWORD m_xMonth: 4; // 2^5, 2^4-1
|
||||
DWORD m_xYear: TIMEDATE_YEAR_BITS; // from 1900-2155 // 2^9, 2^8-1
|
||||
|
||||
@@ -1375,7 +1375,7 @@ void CSockAddr::SetTarget(const char* pcszAddr)
|
||||
{
|
||||
if (pcszAddr) {
|
||||
sin_addr.s_addr = inet_addr(pcszAddr);
|
||||
if (sin_addr.s_addr == INADDR_ANY) { // 0.0.0.0이기 때문에 HOST/Network Addr무관
|
||||
if (sin_addr.s_addr == INADDR_ANY) { // 0.0.0.0, HOST/Network Addr irrelevant
|
||||
hostent* pHN = gethostbyname(pcszAddr);
|
||||
if (pHN) {
|
||||
sin_addr.s_addr = *(u_long*)pHN->h_addr;
|
||||
@@ -3667,7 +3667,7 @@ CSOCListen* CSOCManager::DoListen(int nPort, PFN_CreateSOCClient pfnCSC, DWORD d
|
||||
pSOCListen = new CSOCListen(nPort);
|
||||
pSOCListen->SetCSCParam(pfnCSC, dwCSCParam1, dwCSCParam2);
|
||||
if (!DoListen(pSOCListen, nPort)) {
|
||||
// 같은 포트를 2번 Listen 하는 경우?...
|
||||
// Case of Listen on the same port twice?...
|
||||
pSOCListen = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ extern char SERVERID[];
|
||||
#endif // !MAX_PACKET
|
||||
#ifndef MAX_FTPBUF
|
||||
#define MAX_FTPBUF 1024
|
||||
// MAX_FTPBUF는 MAX_PACKET보다 반드시 작아야 한다?
|
||||
// MAX_FTPBUF must be smaller than MAX_PACKET?
|
||||
// 9+size==sizeof(bCmd) + sizeof(FTID) + sizeof(size) + size
|
||||
#endif // !MAX_FTPBUF
|
||||
|
||||
@@ -251,7 +251,7 @@ private:
|
||||
|
||||
#define ESTRF_USER_START 100
|
||||
|
||||
#define ESTRF_PASSWORDCHANGED 110 // 로그인하고 있는 동안에 패스워드가 바뀜
|
||||
#define ESTRF_PASSWORDCHANGED 110 // Password changed while logged in
|
||||
|
||||
void Randomize();
|
||||
|
||||
@@ -268,7 +268,7 @@ union UPacketValue
|
||||
|
||||
class CDAPacket : public SOCBase_Class
|
||||
{
|
||||
// Packet의 앞 부분을 처리하고 난 뒷 부분의 가변 파라미터...
|
||||
// Variable parameters in the tail portion after processing the packet header...
|
||||
public:
|
||||
BYTE m_bCmd;
|
||||
BYTE m_bReserved;
|
||||
@@ -361,8 +361,8 @@ public:
|
||||
#define C_ROOM_MAKE 232
|
||||
// s - name, s - password
|
||||
#define C_ROOM_JOIN 233
|
||||
// d - number(Room을 떠나는 것은 -1), s - password
|
||||
#define S_ROOM_JOIN 233 // C_ROOM_MAKE/C_ROOM_JOIN의 결과...
|
||||
// d - number (leaving a Room = -1), s - password
|
||||
#define S_ROOM_JOIN 233 // Result of C_ROOM_MAKE/C_ROOM_JOIN...
|
||||
// b - code(CSCODE_OK or error code), d - number
|
||||
#define C_ROOM_UPDS 234 // CSCODE_... + @
|
||||
|
||||
@@ -384,13 +384,13 @@ public:
|
||||
#define S_FTP 254 //... see ftp.txt
|
||||
#define X_KEEPALIVE 255 // no parameters, should be ignored...
|
||||
|
||||
#define TX_SYSTEM 0 // 시스템 메시지...
|
||||
#define TX_NORMAL 1 // 일반 채팅 텍스트
|
||||
#define TX_WARNING 2 // 경고
|
||||
#define TX_ERROR 3 // 오류
|
||||
#define TX_FATAL 4 // 치명적인 오류
|
||||
#define TX_INFO 5 // 사용자 정보 등의 Information Result...
|
||||
#define TX_SAY 6 // 귓속말
|
||||
#define TX_SYSTEM 0 // System message...
|
||||
#define TX_NORMAL 1 // Regular chat text
|
||||
#define TX_WARNING 2 // Warning
|
||||
#define TX_ERROR 3 // Error
|
||||
#define TX_FATAL 4 // Fatal error
|
||||
#define TX_INFO 5 // Information result (e.g. user info)...
|
||||
#define TX_SAY 6 // Whisper
|
||||
#define TX_LOCAL 7 // local echo....
|
||||
#define TX_UNKNOWN 0xffff // unknown...
|
||||
|
||||
@@ -493,7 +493,7 @@ CPacket
|
||||
protected:
|
||||
CSOC* m_pSOC;
|
||||
private:
|
||||
// 이 안의 블럭은 반드시 연속해야 한다...
|
||||
// The block within must be contiguous...
|
||||
WORD m_wLen;
|
||||
BYTE m_ba[MAX_PACKET];
|
||||
//
|
||||
@@ -587,7 +587,7 @@ end of variable PACKET_MAP definitions...
|
||||
class CFileTransfer : public TDBLNK(CFileTransfer*)
|
||||
{
|
||||
public:
|
||||
// 서버로 부터 받은 정보... - 혹은 클라이언트에게 전해줄 정보...
|
||||
// Information received from server... - or information to relay to client...
|
||||
BOOL m_bClientSite;
|
||||
DWORD m_dwFTID;
|
||||
DWORD m_dwGUARD;
|
||||
@@ -680,18 +680,18 @@ protected:
|
||||
// time out to Drop...
|
||||
DWORD m_dwKARcvTimeOut;
|
||||
#ifdef WIN32
|
||||
// 보통 Login과정에 쓰이는 윈도우 핸들
|
||||
// Window handle typically used during Login process
|
||||
HWND m_hWndOwner;
|
||||
#endif // WIN32
|
||||
// 보통 글로벌 변수로 쓰이는 소켓포인터에 대한 자동 NULL Assign을 위하여
|
||||
// For auto NULL assignment of socket pointer typically used as a global variable
|
||||
PSOC* m_ppSOC;
|
||||
// 소켓을 구분하기 위하여 사용자 프로그램에서 쓰이는 아이디
|
||||
// 주로 서버의 경우에는 클라이언트가 접속할 때마다 고유 아이디를 부여하여 사용
|
||||
// 하나의 Client가 다수의 서버에 접속할 때(주로 Star형) 각각의 접속을 구분할 때 사용
|
||||
// 클라이언트가 하나의 서버에만 접속하는 경우 클라이언트가 서버에 접속 중인지 혹은 접속했는지를 판단할 때
|
||||
// CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState()를 사용.
|
||||
// limits.h를 include해야함.
|
||||
// CSOC생성시의 기본값: CSOCServer == CSOC_SERVER_ID(=INT_MIN), CSOCClient == CSOC_CLIENT_ID(=0), CSOCListen == CSOC_LISTEN_ID(=-1)
|
||||
// ID used in user program to identify a socket
|
||||
// Mainly for servers: assigns a unique ID each time a client connects
|
||||
// Used to distinguish each connection when a client connects to multiple servers (Star topology)
|
||||
// When a client connects to only one server: used to check if client is connecting or already connected
|
||||
// Use CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState().
|
||||
// Must include limits.h.
|
||||
// Default values at CSOC creation: CSOCServer==CSOC_SERVER_ID(INT_MIN), CSOCClient==CSOC_CLIENT_ID(0), CSOCListen==CSOC_LISTEN_ID(-1)
|
||||
union {
|
||||
int m_nID;
|
||||
UINT m_uID;
|
||||
@@ -725,8 +725,8 @@ protected:
|
||||
DWORD m_xGracefulRemote: 1;
|
||||
DWORD m_xAbortyLocal: 1;
|
||||
DWORD m_xAbortyRemote: 1;
|
||||
DWORD m_xLoginStarted: 1; // 사용자가 직접 값을 Setting해야 한다.
|
||||
DWORD m_xLoginOK: 1; // 사용자가 직접 값을 Setting해야 한다.
|
||||
DWORD m_xLoginStarted: 1; // Must be set directly by the caller.
|
||||
DWORD m_xLoginOK: 1; // Must be set directly by the caller.
|
||||
} m_DW;
|
||||
DWORD m_dwVarFlags;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ inline BOOL AssertDialog(const char* pcszExpr, const char* pcszfile, int nLine)
|
||||
{
|
||||
char szBuf[MAX_PATH * 2];
|
||||
|
||||
sprintf(szBuf, "\"%s\" 파일의 %d줄에서 ASSERT!!!\n\n디버깅을 하시겠습니까?", pcszfile, nLine);
|
||||
sprintf(szBuf, "ASSERT!!! in \"%s\" at line %d\n\nDo you want to debug?", pcszfile, nLine);
|
||||
|
||||
#ifdef WIN32
|
||||
return ::MessageBox(NULL, szBuf, pcszExpr, MB_YESNO) == IDYES;
|
||||
|
||||
@@ -1077,7 +1077,7 @@ int CStrArray::GetTotalLength() const
|
||||
int nTotalLength;
|
||||
int i, nSize = GetSize();
|
||||
|
||||
nTotalLength = nSize; // nSize개의 '\0'
|
||||
nTotalLength = nSize; // nSize null terminators '\0'
|
||||
for(i = 0; i < nSize; i++) {
|
||||
nTotalLength += strlen(GetAt(i));
|
||||
}
|
||||
|
||||
@@ -3092,13 +3092,13 @@ bool FirstRunEula(const char *eula_filename,const char *warranty_filename)
|
||||
if (NULL == hMod)
|
||||
hMod = LoadLibrary("EBUEula.dll");
|
||||
|
||||
if (NULL == hMod) // can’t attach to DLL
|
||||
if (NULL == hMod) // can't attach to DLL
|
||||
{
|
||||
STOP(("Cannot Load EBUEula.dll"));
|
||||
}
|
||||
pfnEBUEula = (EBUPROC) GetProcAddress(hMod, "EBUEula");
|
||||
|
||||
if (NULL == pfnEBUEula) // can’t find entry point
|
||||
if (NULL == pfnEBUEula) // can't find entry point
|
||||
{
|
||||
FreeLibrary(hMod);
|
||||
STOP(("Cannot Find Entry Point to EBUEula.dll"));
|
||||
@@ -3107,9 +3107,9 @@ bool FirstRunEula(const char *eula_filename,const char *warranty_filename)
|
||||
|
||||
//
|
||||
//This call enables both EULA and warranty accepting/viewing/printing. If your
|
||||
//game doesn’t ship with a WARRANTY file, specifiy NULL instead of szWarranty…
|
||||
//game doesn't ship with a WARRANTY file, specifiy NULL instead of szWarranty...
|
||||
|
||||
//The code below, for instance, works with both OEM and retail builds…
|
||||
//The code below, for instance, works with both OEM and retail builds...
|
||||
|
||||
//
|
||||
const char *pszWarrantyParam = 0xFFFFFFFF != GetFileAttributes(warranty_filename) ? warranty_filename : NULL;
|
||||
|
||||
@@ -517,7 +517,7 @@ void CSOC_Server::OnSendFile()
|
||||
BYTE bCode;
|
||||
if (Disassemble("B", &bCode)) {
|
||||
ASSERT((bCode == 0) || (bCode == 3));
|
||||
// 받아가시오 from Game to console...
|
||||
// Receiving from Game to console...
|
||||
SYSTEMTIME* pSysTime;
|
||||
WORD wSysTimeSize;
|
||||
GUID* pGUID;
|
||||
@@ -533,7 +533,7 @@ void CSOC_Server::OnSendFile()
|
||||
pSF = g_pCTCLManager->m_SFM_Recv.Find(*pGUID, nType);
|
||||
if (pSF) {
|
||||
if (bCode == 3) {
|
||||
// 미션리뷰 서버가 mission review 받았다는 것을 받았느냐?
|
||||
// Did we receive confirmation the mission review server got the mission review?
|
||||
pSF->m_bProcessed = true;
|
||||
g_pCTCLManager->m_SFM_Recv.Cut(pSF);
|
||||
g_pCTCLManager->m_SFM_Done.AddTail(pSF);
|
||||
@@ -910,7 +910,7 @@ void CSOC_Client::OnSendFile()
|
||||
BYTE bCode;
|
||||
if (Disassemble("B", &bCode)) {
|
||||
ASSERT((bCode == 1) || (bCode == 2));
|
||||
// 받았오 from console to Game...
|
||||
// Received from console to Game...
|
||||
SYSTEMTIME* pSysTime;
|
||||
WORD wSysTimeSize;
|
||||
GUID* pGUID;
|
||||
@@ -1438,21 +1438,21 @@ void CCTCLManager::Run()
|
||||
#endif // !defined(CTCL_LAUNCHER)
|
||||
} else {
|
||||
/*
|
||||
클라이언트나 서버의 경우 실행되는 코드이다.
|
||||
Code executed for both client and server.
|
||||
|
||||
*있을수 있는 상태들
|
||||
서버/클라이언트가 결정되기전.. 명령 대기상태
|
||||
(종료/서버시작/클라이언트 시작등의 명령이 올수 있다.)
|
||||
*Possible states:
|
||||
Before server/client role is determined: waiting for commands
|
||||
(Commands such as exit/start-server/start-client may arrive.)
|
||||
|
||||
서버로 실행되어 서버 메크 설정에 대한 데이타를 기다리는 상태
|
||||
(CreateSession가 실행된 상태이다.)
|
||||
서버로 실행되어 Bot들에 대한 정보를 기다리는 상태
|
||||
(클라이언트의 참여는 클라이언트와 서버간에 자동으로 이루어진다.)
|
||||
서버로 실행되어 Launch를 기다리는 상태
|
||||
Running as server, waiting for server mech configuration data
|
||||
(State after CreateSession has been called.)
|
||||
Running as server, waiting for Bot information
|
||||
(Client joining happens automatically between client and server.)
|
||||
Running as server, waiting for Launch
|
||||
|
||||
==>클라이언트는 실행즉시 데이타들이 전달되므로 대기상태가 없다.
|
||||
==>Client has no waiting state as data is transferred immediately on startup.
|
||||
|
||||
==>각각의 상태를 정의하고 각 상태에 맞는 처리를 해주면 된다.
|
||||
==>Define each state and implement the appropriate handling for each.
|
||||
switch(state){
|
||||
}
|
||||
*/
|
||||
@@ -1534,8 +1534,8 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
//서버/클라이언트로서 실행준비하도록 명령을 전달한다.
|
||||
//또한 서버를 실행하는데 필요한 모든 파라미터도 함께 전달한다.
|
||||
//Send command to prepare for execution as server/client.
|
||||
//Also transmit all parameters required to run the server.
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
if (!pi.m_bBot) {
|
||||
@@ -1562,12 +1562,12 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
}
|
||||
if (i == g_nPlayerInfos) {
|
||||
// Bot들에 대한 정보를 모두 한데 묶어서 보낸다.
|
||||
// Bundle and send all Bot information together.
|
||||
CPacket pak(&SVR.GetGameSOC());
|
||||
|
||||
pak.Assemble("B", C_BOTS);
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
if (i != g_nServer) { // 원래 Bot만 지금은 서버를 제외한 전부...
|
||||
if (i != g_nServer) { // Originally bots only; now everyone except the server...
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
pak.Assemble("BnsDWwsnn", pi.m_bBot, pi.m_nLevelOrTesla, pi.m_szName, pi.m_nMechIndex, pi.m_fileID, pi.m_recordID, pi.m_szMech, pi.m_nTeamOrSkin, pi.m_nDecal);
|
||||
}
|
||||
@@ -1578,10 +1578,10 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
// 게임이 성공적으로 만들어지면 서버와 클라이언트들의 Mech에 대한 정보들을 Set한다...
|
||||
// Once the game is successfully created, set Mech info for server and all clients...
|
||||
if (SOCGame.m_nGameReturn == _EGR_OkCreateSession) {
|
||||
for(i = 0; i < g_nPlayerInfos; i++) {
|
||||
if (i != g_nServer) { // 서버는 이미 SetMech에 진입한 상태...
|
||||
if (i != g_nServer) { // Server has already entered SetMech...
|
||||
SPlayerInfo& pi = g_aPlayerInfos[i];
|
||||
if (!pi.m_bBot) {
|
||||
CTeslaInfo& ti = m_aTIs.GetAt(pi.m_nLevelOrTesla);
|
||||
@@ -1594,8 +1594,8 @@ void CCTCLManager::DoMech4Comm()
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
//모든 클라이언드들이 서버에 참여하기를 기다린다.<==이 응답은 서버로 부터 얻을 수 있다.
|
||||
//참여가 모두 끝났으면, 서버로 하여금 게임을 Launch시키도록 한다.
|
||||
//Wait for all clients to join the server. <==This response comes from the server.
|
||||
//Once all clients have joined, instruct the server to Launch the game.
|
||||
if (SOCGame.m_nGameReturn == _EGR_OkLaunchReady) {
|
||||
g_nMech4Comm = 9;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
const char* m_pcsz;
|
||||
|
||||
int m_nLauncherConnection; // 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // m_bCameraShip값에 따라 게임 혹은 카메라 쉽과의 접속을 의미, 0: no connection, +1: connection, -1: connecting
|
||||
int m_nConnection2; // Connection to game or camera ship per m_bCameraShip, 0: no connection, +1: connected, -1: connecting
|
||||
int m_nApplType;
|
||||
int m_nApplState;
|
||||
int m_nGameState;
|
||||
|
||||
@@ -44,7 +44,7 @@ int GetDayEnd(int nYear, int nMonth)
|
||||
|
||||
long GetTotalSeconds(int nYear, int nMonth, int nDay)
|
||||
{
|
||||
// nYear, nMonth, nDay날의 0시 0분 0초를 0으로 한 초단위 수...
|
||||
// Seconds elapsed since 00:00:00 on the date nYear/nMonth/nDay...
|
||||
ASSERT(nYear >= 1970);
|
||||
ASSERT((1 <= nMonth) && (nMonth <= 12));
|
||||
ASSERT(1 <= nDay);
|
||||
@@ -57,13 +57,13 @@ long GetTotalSeconds(int nYear, int nMonth, int nDay)
|
||||
if (IsLeapYear(nStart)) {
|
||||
nDays++;
|
||||
}
|
||||
lTotal += nDays * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += nDays * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
}
|
||||
for(nStart = 1; nStart < nMonth; nStart++) {
|
||||
int nDayEnd = GetDayEnd(nYear, nStart);
|
||||
lTotal += nDayEnd * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += nDayEnd * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
}
|
||||
lTotal += (nDay - 1) * 24 * 60 * 60; // 24시간 60분 60초
|
||||
lTotal += (nDay - 1) * 24 * 60 * 60; // 24 hours * 60 min * 60 sec
|
||||
|
||||
return lTotal;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ class CTimeDate
|
||||
public:
|
||||
union {
|
||||
struct {
|
||||
// Bit Field는 앞쪽에 지정된 것이 LowBit이다.
|
||||
// Bit Fields declared first are at the low-bit end.
|
||||
DWORD m_xDay: 5; // 2^0, 2^5-1
|
||||
DWORD m_xMonth: 4; // 2^5, 2^4-1
|
||||
DWORD m_xYear: TIMEDATE_YEAR_BITS; // from 1900-2155 // 2^9, 2^8-1
|
||||
|
||||
@@ -1375,7 +1375,7 @@ void CSockAddr::SetTarget(const char* pcszAddr)
|
||||
{
|
||||
if (pcszAddr) {
|
||||
sin_addr.s_addr = inet_addr(pcszAddr);
|
||||
if (sin_addr.s_addr == INADDR_ANY) { // 0.0.0.0이기 때문에 HOST/Network Addr무관
|
||||
if (sin_addr.s_addr == INADDR_ANY) { // 0.0.0.0, HOST/Network Addr irrelevant
|
||||
hostent* pHN = gethostbyname(pcszAddr);
|
||||
if (pHN) {
|
||||
sin_addr.s_addr = *(u_long*)pHN->h_addr;
|
||||
@@ -3667,7 +3667,7 @@ CSOCListen* CSOCManager::DoListen(int nPort, PFN_CreateSOCClient pfnCSC, DWORD d
|
||||
pSOCListen = new CSOCListen(nPort);
|
||||
pSOCListen->SetCSCParam(pfnCSC, dwCSCParam1, dwCSCParam2);
|
||||
if (!DoListen(pSOCListen, nPort)) {
|
||||
// 같은 포트를 2번 Listen 하는 경우?...
|
||||
// Case of Listen on the same port twice?...
|
||||
pSOCListen = NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ extern char SERVERID[];
|
||||
#endif // !MAX_PACKET
|
||||
#ifndef MAX_FTPBUF
|
||||
#define MAX_FTPBUF 1024
|
||||
// MAX_FTPBUF는 MAX_PACKET보다 반드시 작아야 한다?
|
||||
// MAX_FTPBUF must be smaller than MAX_PACKET?
|
||||
// 9+size==sizeof(bCmd) + sizeof(FTID) + sizeof(size) + size
|
||||
#endif // !MAX_FTPBUF
|
||||
|
||||
@@ -251,7 +251,7 @@ private:
|
||||
|
||||
#define ESTRF_USER_START 100
|
||||
|
||||
#define ESTRF_PASSWORDCHANGED 110 // 로그인하고 있는 동안에 패스워드가 바뀜
|
||||
#define ESTRF_PASSWORDCHANGED 110 // Password changed while logged in
|
||||
|
||||
void Randomize();
|
||||
|
||||
@@ -268,7 +268,7 @@ union UPacketValue
|
||||
|
||||
class CDAPacket : public SOCBase_Class
|
||||
{
|
||||
// Packet의 앞 부분을 처리하고 난 뒷 부분의 가변 파라미터...
|
||||
// Variable parameters in the tail portion after processing the packet header...
|
||||
public:
|
||||
BYTE m_bCmd;
|
||||
BYTE m_bReserved;
|
||||
@@ -361,8 +361,8 @@ public:
|
||||
#define C_ROOM_MAKE 232
|
||||
// s - name, s - password
|
||||
#define C_ROOM_JOIN 233
|
||||
// d - number(Room을 떠나는 것은 -1), s - password
|
||||
#define S_ROOM_JOIN 233 // C_ROOM_MAKE/C_ROOM_JOIN의 결과...
|
||||
// d - number (leaving a Room = -1), s - password
|
||||
#define S_ROOM_JOIN 233 // Result of C_ROOM_MAKE/C_ROOM_JOIN...
|
||||
// b - code(CSCODE_OK or error code), d - number
|
||||
#define C_ROOM_UPDS 234 // CSCODE_... + @
|
||||
|
||||
@@ -384,13 +384,13 @@ public:
|
||||
#define S_FTP 254 //... see ftp.txt
|
||||
#define X_KEEPALIVE 255 // no parameters, should be ignored...
|
||||
|
||||
#define TX_SYSTEM 0 // 시스템 메시지...
|
||||
#define TX_NORMAL 1 // 일반 채팅 텍스트
|
||||
#define TX_WARNING 2 // 경고
|
||||
#define TX_ERROR 3 // 오류
|
||||
#define TX_FATAL 4 // 치명적인 오류
|
||||
#define TX_INFO 5 // 사용자 정보 등의 Information Result...
|
||||
#define TX_SAY 6 // 귓속말
|
||||
#define TX_SYSTEM 0 // System message...
|
||||
#define TX_NORMAL 1 // Regular chat text
|
||||
#define TX_WARNING 2 // Warning
|
||||
#define TX_ERROR 3 // Error
|
||||
#define TX_FATAL 4 // Fatal error
|
||||
#define TX_INFO 5 // Information result (e.g. user info)...
|
||||
#define TX_SAY 6 // Whisper
|
||||
#define TX_LOCAL 7 // local echo....
|
||||
#define TX_UNKNOWN 0xffff // unknown...
|
||||
|
||||
@@ -493,7 +493,7 @@ CPacket
|
||||
protected:
|
||||
CSOC* m_pSOC;
|
||||
private:
|
||||
// 이 안의 블럭은 반드시 연속해야 한다...
|
||||
// The block within must be contiguous...
|
||||
WORD m_wLen;
|
||||
BYTE m_ba[MAX_PACKET];
|
||||
//
|
||||
@@ -587,7 +587,7 @@ end of variable PACKET_MAP definitions...
|
||||
class CFileTransfer : public TDBLNK(CFileTransfer*)
|
||||
{
|
||||
public:
|
||||
// 서버로 부터 받은 정보... - 혹은 클라이언트에게 전해줄 정보...
|
||||
// Information received from server... - or information to relay to client...
|
||||
BOOL m_bClientSite;
|
||||
DWORD m_dwFTID;
|
||||
DWORD m_dwGUARD;
|
||||
@@ -680,18 +680,18 @@ protected:
|
||||
// time out to Drop...
|
||||
DWORD m_dwKARcvTimeOut;
|
||||
#ifdef WIN32
|
||||
// 보통 Login과정에 쓰이는 윈도우 핸들
|
||||
// Window handle typically used during Login process
|
||||
HWND m_hWndOwner;
|
||||
#endif // WIN32
|
||||
// 보통 글로벌 변수로 쓰이는 소켓포인터에 대한 자동 NULL Assign을 위하여
|
||||
// For auto NULL assignment of socket pointer typically used as a global variable
|
||||
PSOC* m_ppSOC;
|
||||
// 소켓을 구분하기 위하여 사용자 프로그램에서 쓰이는 아이디
|
||||
// 주로 서버의 경우에는 클라이언트가 접속할 때마다 고유 아이디를 부여하여 사용
|
||||
// 하나의 Client가 다수의 서버에 접속할 때(주로 Star형) 각각의 접속을 구분할 때 사용
|
||||
// 클라이언트가 하나의 서버에만 접속하는 경우 클라이언트가 서버에 접속 중인지 혹은 접속했는지를 판단할 때
|
||||
// CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState()를 사용.
|
||||
// limits.h를 include해야함.
|
||||
// CSOC생성시의 기본값: CSOCServer == CSOC_SERVER_ID(=INT_MIN), CSOCClient == CSOC_CLIENT_ID(=0), CSOCListen == CSOC_LISTEN_ID(=-1)
|
||||
// ID used in user program to identify a socket
|
||||
// Mainly for servers: assigns a unique ID each time a client connects
|
||||
// Used to distinguish each connection when a client connects to multiple servers (Star topology)
|
||||
// When a client connects to only one server: used to check if client is connecting or already connected
|
||||
// Use CSOCManager::FindSOC(CSOC_SERVER_ID==default)->GetConnectionState().
|
||||
// Must include limits.h.
|
||||
// Default values at CSOC creation: CSOCServer==CSOC_SERVER_ID(INT_MIN), CSOCClient==CSOC_CLIENT_ID(0), CSOCListen==CSOC_LISTEN_ID(-1)
|
||||
union {
|
||||
int m_nID;
|
||||
UINT m_uID;
|
||||
@@ -725,8 +725,8 @@ protected:
|
||||
DWORD m_xGracefulRemote: 1;
|
||||
DWORD m_xAbortyLocal: 1;
|
||||
DWORD m_xAbortyRemote: 1;
|
||||
DWORD m_xLoginStarted: 1; // 사용자가 직접 값을 Setting해야 한다.
|
||||
DWORD m_xLoginOK: 1; // 사용자가 직접 값을 Setting해야 한다.
|
||||
DWORD m_xLoginStarted: 1; // Must be set directly by the caller.
|
||||
DWORD m_xLoginOK: 1; // Must be set directly by the caller.
|
||||
} m_DW;
|
||||
DWORD m_dwVarFlags;
|
||||
};
|
||||
|
||||
@@ -6,7 +6,7 @@ inline BOOL AssertDialog(const char* pcszExpr, const char* pcszfile, int nLine)
|
||||
{
|
||||
char szBuf[MAX_PATH * 2];
|
||||
|
||||
sprintf(szBuf, "\"%s\" 파일의 %d줄에서 ASSERT!!!\n\n디버깅을 하시겠습니까?", pcszfile, nLine);
|
||||
sprintf(szBuf, "ASSERT!!! in \"%s\" at line %d\n\nDo you want to debug?", pcszfile, nLine);
|
||||
|
||||
#ifdef WIN32
|
||||
return ::MessageBox(NULL, szBuf, pcszExpr, MB_YESNO) == IDYES;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "mw4dummy.h"
|
||||
#include "recscore.h"
|
||||
#include "dbexport.h"
|
||||
typedef unsigned long UINT4;
|
||||
typedef unsigned char* POINTER;
|
||||
#include "logreport.h"
|
||||
@@ -23,6 +24,7 @@ static char THIS_FILE[] = __FILE__;
|
||||
|
||||
#include "mw4dummy.cpp"
|
||||
#include "recscore.cpp"
|
||||
#include "dbexport.cpp"
|
||||
#include "logreport.cpp"
|
||||
|
||||
#define IDT_TIMER 1000
|
||||
@@ -37,6 +39,12 @@ BEGIN_MESSAGE_MAP(CChildView,CWnd )
|
||||
ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
|
||||
ON_COMMAND(ID_FILE_LOGREPORT, OnFileLogReport)
|
||||
ON_COMMAND(ID_FILE_LOG2DATES, OnFileLog2Dates)
|
||||
ON_COMMAND(ID_FILE_DBSETTINGS, OnFileDbSettings)
|
||||
ON_COMMAND(ID_FILE_BANNERSETTING, OnFileBannerSetting)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDlgDBSettings, CDialog)
|
||||
ON_BN_CLICKED(IDC_DB_TEST, OnTestConnection)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDlgGet2Dates, CDialog)
|
||||
@@ -299,7 +307,9 @@ int CChildView::OnCreate(LPCREATESTRUCT lpCreateStruct)
|
||||
{
|
||||
if (CWnd ::OnCreate(lpCreateStruct) == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
DB_LoadConfig();
|
||||
|
||||
m_uTimer = SetTimer(IDT_TIMER, 1 * 1000, NULL);
|
||||
if (!m_uTimer)
|
||||
return -1;
|
||||
@@ -343,6 +353,121 @@ void CChildView::OnTimer(UINT nIDEvent)
|
||||
CWnd ::OnTimer(nIDEvent);
|
||||
}
|
||||
|
||||
void CChildView::OnFileBannerSetting()
|
||||
{
|
||||
CDlgBannerSetting dlg(this);
|
||||
dlg.DoModal();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDlgBannerSetting
|
||||
|
||||
CDlgBannerSetting::CDlgBannerSetting(CWnd* pParent)
|
||||
: CDialog(CDlgBannerSetting::IDD, pParent)
|
||||
{
|
||||
}
|
||||
|
||||
BEGIN_MESSAGE_MAP(CDlgBannerSetting, CDialog)
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
void CDlgBannerSetting::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
}
|
||||
|
||||
BOOL CDlgBannerSetting::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
SetDlgItemText(IDC_BANNER_TEXT, g_szPrintBanner);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CDlgBannerSetting::OnOK()
|
||||
{
|
||||
GetDlgItemText(IDC_BANNER_TEXT, g_szPrintBanner, sizeof(g_szPrintBanner));
|
||||
|
||||
// Persist to options.ini so it survives a restart.
|
||||
char szINI[MAX_PATH];
|
||||
sprintf(szINI, "%s\\options.ini", AssetsDirectory1);
|
||||
WritePrivateProfileString("battle tech print", "BannerText", g_szPrintBanner, szINI);
|
||||
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void CChildView::OnFileDbSettings()
|
||||
{
|
||||
CDlgDBSettings dlg(this);
|
||||
dlg.DoModal();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDlgDBSettings
|
||||
|
||||
CDlgDBSettings::CDlgDBSettings(CWnd* pParent)
|
||||
: CDialog(CDlgDBSettings::IDD, pParent)
|
||||
{
|
||||
}
|
||||
|
||||
void CDlgDBSettings::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
}
|
||||
|
||||
BOOL CDlgDBSettings::OnInitDialog()
|
||||
{
|
||||
CDialog::OnInitDialog();
|
||||
|
||||
CheckDlgButton(IDC_DB_ENABLED, g_dbConfig.bEnabled ? BST_CHECKED : BST_UNCHECKED);
|
||||
CheckDlgButton(IDC_DB_EXPORTEVENTS, g_dbConfig.bExportEvents ? BST_CHECKED : BST_UNCHECKED);
|
||||
|
||||
SetDlgItemText(IDC_DB_HOST, g_dbConfig.szHost);
|
||||
SetDlgItemInt (IDC_DB_PORT, g_dbConfig.nPort, FALSE);
|
||||
SetDlgItemText(IDC_DB_DATABASE, g_dbConfig.szDatabase);
|
||||
SetDlgItemText(IDC_DB_USERNAME, g_dbConfig.szUsername);
|
||||
SetDlgItemText(IDC_DB_PASSWORD, g_dbConfig.szPassword);
|
||||
|
||||
SetDlgItemText(IDC_DB_STATUS, "");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void CDlgDBSettings::OnOK()
|
||||
{
|
||||
g_dbConfig.bEnabled = IsDlgButtonChecked(IDC_DB_ENABLED) == BST_CHECKED;
|
||||
g_dbConfig.bExportEvents = IsDlgButtonChecked(IDC_DB_EXPORTEVENTS) == BST_CHECKED;
|
||||
|
||||
GetDlgItemText(IDC_DB_HOST, g_dbConfig.szHost, sizeof(g_dbConfig.szHost));
|
||||
g_dbConfig.nPort = (int)GetDlgItemInt(IDC_DB_PORT, NULL, FALSE);
|
||||
GetDlgItemText(IDC_DB_DATABASE, g_dbConfig.szDatabase, sizeof(g_dbConfig.szDatabase));
|
||||
GetDlgItemText(IDC_DB_USERNAME, g_dbConfig.szUsername, sizeof(g_dbConfig.szUsername));
|
||||
GetDlgItemText(IDC_DB_PASSWORD, g_dbConfig.szPassword, sizeof(g_dbConfig.szPassword));
|
||||
|
||||
DB_SaveConfig();
|
||||
CDialog::OnOK();
|
||||
}
|
||||
|
||||
void CDlgDBSettings::OnTestConnection()
|
||||
{
|
||||
// Read fields into a temporary config so we test what's in the UI,
|
||||
// not necessarily what was last saved.
|
||||
SDBConfig saved = g_dbConfig;
|
||||
|
||||
GetDlgItemText(IDC_DB_HOST, g_dbConfig.szHost, sizeof(g_dbConfig.szHost));
|
||||
g_dbConfig.nPort = (int)GetDlgItemInt(IDC_DB_PORT, NULL, FALSE);
|
||||
GetDlgItemText(IDC_DB_DATABASE, g_dbConfig.szDatabase, sizeof(g_dbConfig.szDatabase));
|
||||
GetDlgItemText(IDC_DB_USERNAME, g_dbConfig.szUsername, sizeof(g_dbConfig.szUsername));
|
||||
GetDlgItemText(IDC_DB_PASSWORD, g_dbConfig.szPassword, sizeof(g_dbConfig.szPassword));
|
||||
|
||||
SetDlgItemText(IDC_DB_STATUS, "Testing...");
|
||||
UpdateWindow();
|
||||
|
||||
char szError[512] = "";
|
||||
bool bOK = DB_TestConnection(szError, sizeof(szError));
|
||||
SetDlgItemText(IDC_DB_STATUS, bOK ? "OK - Connected successfully." : szError);
|
||||
|
||||
g_dbConfig = saved; // restore; OnOK() will save the final values
|
||||
}
|
||||
|
||||
void CChildView::OnFileOpen()
|
||||
{
|
||||
// TODO: Add your command handler code here
|
||||
|
||||
@@ -9,11 +9,41 @@
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
class CDlgBannerSetting : public CDialog
|
||||
{
|
||||
public:
|
||||
CDlgBannerSetting(CWnd* pParent = NULL);
|
||||
enum { IDD = IDD_BANNER_SETTING };
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX);
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CChildView window
|
||||
|
||||
class MW4PRINT_COPYDATASTRUCT;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CDlgDBSettings dialog
|
||||
|
||||
class CDlgDBSettings : public CDialog
|
||||
{
|
||||
public:
|
||||
CDlgDBSettings(CWnd* pParent = NULL);
|
||||
|
||||
enum { IDD = IDD_DB_SETTINGS };
|
||||
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX);
|
||||
virtual BOOL OnInitDialog();
|
||||
virtual void OnOK();
|
||||
afx_msg void OnTestConnection();
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
class CMyPrintInfo : public TDBLNK(CMyPrintInfo*)
|
||||
{
|
||||
public:
|
||||
@@ -131,6 +161,8 @@ protected:
|
||||
afx_msg void OnFileOpen();
|
||||
afx_msg void OnFileLogReport();
|
||||
afx_msg void OnFileLog2Dates();
|
||||
afx_msg void OnFileDbSettings();
|
||||
afx_msg void OnFileBannerSetting();
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
|
||||
@@ -1077,7 +1077,7 @@ int CStrArray::GetTotalLength() const
|
||||
int nTotalLength;
|
||||
int i, nSize = GetSize();
|
||||
|
||||
nTotalLength = nSize; // nSize개의 '\0'
|
||||
nTotalLength = nSize; // nSize null terminators '\0'
|
||||
for(i = 0; i < nSize; i++) {
|
||||
nTotalLength += strlen(GetAt(i));
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ void CSpcFileDialog::SetCustomFilter(const char* pcszName/* = NULL*/, const char
|
||||
m_ofn.lpstrCustomFilter = p;
|
||||
|
||||
if (!pcszName) {
|
||||
pcszName = "사용자 정의 파일";
|
||||
pcszName = "User-defined file";
|
||||
}
|
||||
strcpy(p, pcszName);
|
||||
p = &p[strlen(pcszName)];
|
||||
@@ -111,7 +111,7 @@ BOOL CSpcFileDialog::DoMessage(HWND hParent, UINT uMsg, WPARAM wParam, LPARAM lP
|
||||
switch(uMsg) {
|
||||
case WM_INITDIALOG:
|
||||
if (m_dwStyle) {
|
||||
//0x480 // 파일 이름 Edit
|
||||
//0x480 // File Name Edit
|
||||
HWND hReadOnly = ::GetDlgItem(hParent, 0x0410); // Read Only
|
||||
if (hReadOnly) {
|
||||
if (m_dwStyle == (DWORD)(-1)) {
|
||||
|
||||
@@ -21,8 +21,8 @@ public:
|
||||
CSpcFileDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt = NULL, LPCTSTR lpszFileName = NULL, DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, LPCTSTR lpszFilter = NULL, CWnd* pParentWnd = NULL);
|
||||
void SetTitle(const char* pcszTitle);
|
||||
void SetWorkingDir(const char* pcszWorkingDir);
|
||||
void SetFilterIndex(int nFilterIndex); // 1 기준한 값, 0은 사용자 필터
|
||||
int GetFilterIndex() const; // 1 기준한 값, 0은 사용자 필터
|
||||
void SetFilterIndex(int nFilterIndex); // 1-based index, 0 = user-defined filter
|
||||
int GetFilterIndex() const; // 1-based index, 0 = user-defined filter
|
||||
void SetCustomFilter(const char* pcszName = NULL, const char* pcszExt = NULL);
|
||||
void EnableHook(const char* pcszWindowText, DWORD dwStyle = (DWORD)(-1));
|
||||
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
-- mw4print MySQL database schema
|
||||
-- Tables are created automatically by mw4print on first export.
|
||||
-- This file documents the structure for reference.
|
||||
--
|
||||
-- Prerequisites: create the database first, then configure mw4print.ini:
|
||||
--
|
||||
-- [MySQLExport]
|
||||
-- Enabled=1
|
||||
-- Host=192.168.1.100
|
||||
-- Port=3306
|
||||
-- Database=firestorm_stats
|
||||
-- Username=mw4
|
||||
-- Password=yourpassword
|
||||
-- ExportEvents=0
|
||||
--
|
||||
-- Run this script manually if you want to pre-create the tables,
|
||||
-- or just let mw4print create them on first connect.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `match` (
|
||||
`match_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`match_time` DATETIME NOT NULL,
|
||||
`server_name` VARCHAR(256) NOT NULL DEFAULT '',
|
||||
`server_ip` VARCHAR(64) NOT NULL DEFAULT '',
|
||||
`map_name` VARCHAR(128) NOT NULL DEFAULT '',
|
||||
`scenario_name` VARCHAR(128) NOT NULL DEFAULT '',
|
||||
`game_type` INT NOT NULL DEFAULT 0,
|
||||
`game_type_name` VARCHAR(64) NOT NULL DEFAULT '',
|
||||
`is_team_game` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`player_count` INT NOT NULL DEFAULT 0,
|
||||
`team_count` INT NOT NULL DEFAULT 0,
|
||||
`team_scores` VARCHAR(64) NOT NULL DEFAULT '', -- comma-separated team totals: t0,t1,...,t7
|
||||
`game_length` INT NOT NULL DEFAULT 0,
|
||||
`kill_limit` INT NOT NULL DEFAULT 0, -- 0 = no limit
|
||||
`respawn_limit` INT NOT NULL DEFAULT 0, -- 0 = no limit
|
||||
`friendly_fire` INT NOT NULL DEFAULT 0, -- percentage
|
||||
`heat_on` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`armor_mode` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`unlimited_ammo` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`is_night` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`min_tonnage` INT NOT NULL DEFAULT 0,
|
||||
`max_tonnage` INT NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`match_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- game_type values (from GameTypes.h):
|
||||
-- 0 StockDestruction 1 StockTeamDestruction
|
||||
-- 2 StockAttrition 3 StockTeamAttrition
|
||||
-- 4 StockCaptureTheFlag 5 StockKingOfTheHill
|
||||
-- 6 StockTeamKingOfTheHill 7 StockTerritories
|
||||
-- 8 StockStealTheBacon 9 StockCaptureBase
|
||||
-- 10 StockDestroyObjective 11 StockEscort
|
||||
-- 12 StockMasterTrial 13 StockSiegeAssault
|
||||
-- 14 StockCampaign 15 CustomDestruction
|
||||
-- 16 CustomTeamDestruction 17 CustomAttrition
|
||||
-- 18 CustomTeamAttrition 19 CustomCaptureTheFlag
|
||||
-- 20 CustomKingOfTheHill 21 CustomTeamKingOfTheHill
|
||||
-- 22 CustomTerritories 23 CustomStealTheBacon
|
||||
-- 24 CustomCaptureBase 25 CustomDestroyObjective
|
||||
-- 26 CustomEscort 27 CustomMasterTrial
|
||||
-- 28 CustomSiegeAssault 29 CustomCampaign
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `player_result` (
|
||||
`result_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`match_id` INT UNSIGNED NOT NULL,
|
||||
`player_name` VARCHAR(64) NOT NULL DEFAULT '',
|
||||
`mech_name` VARCHAR(64) NOT NULL DEFAULT '',
|
||||
`team` INT NOT NULL DEFAULT 0, -- 0-7; meaningless in FFA (team_count=0)
|
||||
`score` INT NOT NULL DEFAULT 0,
|
||||
`kills` INT NOT NULL DEFAULT 0,
|
||||
`deaths` INT NOT NULL DEFAULT 0,
|
||||
`is_bot` TINYINT(1) NOT NULL DEFAULT 0,
|
||||
`pilot_decal` INT NOT NULL DEFAULT 0, -- decal index 0-63
|
||||
PRIMARY KEY (`result_id`),
|
||||
KEY `match_id` (`match_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `pvp` (
|
||||
`pvp_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`match_id` INT UNSIGNED NOT NULL,
|
||||
`attacker` VARCHAR(64) NOT NULL DEFAULT '', -- player_name of attacker
|
||||
`victim` VARCHAR(64) NOT NULL DEFAULT '', -- player_name of victim
|
||||
`kills` INT NOT NULL DEFAULT 0, -- times attacker killed victim
|
||||
`score` INT NOT NULL DEFAULT 0, -- score attacker earned from victim
|
||||
PRIMARY KEY (`pvp_id`),
|
||||
KEY `match_id` (`match_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
|
||||
-- Optional: populated only when ExportEvents=1 in mw4print.ini.
|
||||
-- Can generate thousands of rows per match; off by default.
|
||||
CREATE TABLE IF NOT EXISTS `event` (
|
||||
`event_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`match_id` INT UNSIGNED NOT NULL,
|
||||
`event_type` INT NOT NULL DEFAULT 0, -- CBucketManager::Bucket_Type (see below)
|
||||
`actor` VARCHAR(64) NOT NULL DEFAULT '',
|
||||
`target` VARCHAR(64) NOT NULL DEFAULT '',
|
||||
`weapon` INT NOT NULL DEFAULT 0,
|
||||
`body_zone` INT NOT NULL DEFAULT 0, -- DamageObject zone (see below)
|
||||
`param` INT NOT NULL DEFAULT 0, -- context-dependent value
|
||||
PRIMARY KEY (`event_id`),
|
||||
KEY `match_id` (`match_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
-- event_type values (CBucketManager::Bucket_Type):
|
||||
-- 0 KILL_LINK 1 DEATH_LINK
|
||||
-- 2 KILLS 3 FRIENDLY_KILLS
|
||||
-- 4 ENEMY_KILLS 5 KILLS_BY_TONNAGE
|
||||
-- 6 FRIENDLY_KILLS_BY_TONNAGE 7 ENEMY_KILLS_BY_TONNAGE
|
||||
-- 8 DEATHS 9 SUICIDES
|
||||
-- 10 DAMAGE_INFLICT 11 FRIENDLY_DAMAGE_INFLICT
|
||||
-- 12 ENEMY_DAMAGE_INFLICT 13 DAMAGE_RECEIVE
|
||||
-- 14 FRIENDLY_DAMAGE_RECEIVE 15 ENEMY_DAMAGE_RECEIVE
|
||||
-- 16 COMPONENT_KILLS 17 COMPONENT_DEATHS
|
||||
-- 18 FRIENDLY_COMPONENT_KILLS 19 FRIENDLY_COMPONENT_DEATHS
|
||||
-- 20 ENEMY_COMPONENT_KILLS 21 ENEMY_COMPONENT_DEATHS
|
||||
-- 22 DFA 23 SHOTS_HIT
|
||||
-- 24 SHOTS_FIRED 25 HEAD_SHOTS
|
||||
-- 26 ARM_SHOTS 27 LEG_SHOTS
|
||||
-- 28 TORSO_SHOTS 29 KILLS_PC
|
||||
-- 30 KILLS_AI 31 BLANK
|
||||
-- 32 SHUTDOWN_TIMER 33 OBJECTIVE
|
||||
-- 34 OBJECTIVE_CONTESTED 35 OBJECTIVE_UNCONTESTED
|
||||
-- 36 FLAGS_TAKEN 37 FLAGS_DROPPED
|
||||
-- 38 FLAGS_CAPTURED 39 FLAG_HOLD_TIME
|
||||
-- 40 TIME 41 ALIVE_PLAYERS
|
||||
-- 42 DEAD_PLAYERS 43 CUSTOM
|
||||
-- 44 ENEMY_TURRET_KILLS 45 FRIENDLY_TURRET_KILLS
|
||||
-- 46 ENEMY_BUILDING_KILLS 47 FRIENDLY_BUILDING_KILLS
|
||||
|
||||
-- body_zone values (DamageObject::DamageZone):
|
||||
-- 0 LeftLeg 1 RightLeg 2 LeftArm 3 RightArm
|
||||
-- 4 RightTorso 5 LeftTorso 6 CenterTorso 7 Head
|
||||
-- 8 SpecialZone1 9 SpecialZone2
|
||||
@@ -0,0 +1,486 @@
|
||||
// dbexport.cpp - MySQL export implementation for mw4print
|
||||
//
|
||||
// Included directly from ChildView.cpp (same pattern as recscore.cpp).
|
||||
//
|
||||
|
||||
#include "dbexport.h"
|
||||
|
||||
// ---- Config default values -----------------------------------------------
|
||||
|
||||
SDBConfig g_dbConfig = {
|
||||
false, // bEnabled
|
||||
"localhost", // szHost
|
||||
3306, // nPort
|
||||
"firestorm_stats", // szDatabase
|
||||
"mw4", // szUsername
|
||||
"", // szPassword
|
||||
false // bExportEvents
|
||||
};
|
||||
|
||||
// ---- MySQL late binding --------------------------------------------------
|
||||
//
|
||||
// We load libmysql.dll at runtime so the exe does not hard-link against it.
|
||||
// All function pointers are NULL until DB_LoadMySQL() succeeds.
|
||||
|
||||
static HMODULE g_hMySQL = NULL;
|
||||
|
||||
typedef void* MYSQLH; // opaque MYSQL* handle
|
||||
typedef unsigned long MYULONG;
|
||||
typedef unsigned __int64 MYULLONG;
|
||||
|
||||
// MYSQL_OPT_CONNECT_TIMEOUT = 0
|
||||
#define MY_OPT_CONNECT_TIMEOUT 0
|
||||
|
||||
typedef MYSQLH (__cdecl *PFN_mysql_init) (MYSQLH);
|
||||
typedef MYSQLH (__cdecl *PFN_mysql_real_connect) (MYSQLH, const char*, const char*, const char*, const char*, unsigned int, const char*, unsigned long);
|
||||
typedef void (__cdecl *PFN_mysql_options) (MYSQLH, int, const char*);
|
||||
typedef int (__cdecl *PFN_mysql_real_query) (MYSQLH, const char*, unsigned long);
|
||||
typedef MYULLONG (__cdecl *PFN_mysql_insert_id) (MYSQLH);
|
||||
typedef void (__cdecl *PFN_mysql_close) (MYSQLH);
|
||||
typedef const char* (__cdecl *PFN_mysql_error) (MYSQLH);
|
||||
typedef MYULONG (__cdecl *PFN_mysql_escape_string) (char*, const char*, MYULONG);
|
||||
|
||||
static PFN_mysql_init pfn_init = NULL;
|
||||
static PFN_mysql_real_connect pfn_real_connect = NULL;
|
||||
static PFN_mysql_options pfn_options = NULL;
|
||||
static PFN_mysql_real_query pfn_real_query = NULL;
|
||||
static PFN_mysql_insert_id pfn_insert_id = NULL;
|
||||
static PFN_mysql_close pfn_close = NULL;
|
||||
static PFN_mysql_error pfn_error = NULL;
|
||||
static PFN_mysql_escape_string pfn_escape_string = NULL;
|
||||
|
||||
static bool DB_LoadMySQL()
|
||||
{
|
||||
if (g_hMySQL)
|
||||
return true;
|
||||
|
||||
// Try app directory first, then system path.
|
||||
char szPath[MAX_PATH];
|
||||
sprintf(szPath, "%s\\libmysql.dll", AssetsDirectory1);
|
||||
g_hMySQL = LoadLibrary(szPath);
|
||||
if (!g_hMySQL)
|
||||
g_hMySQL = LoadLibrary("libmysql.dll");
|
||||
if (!g_hMySQL)
|
||||
return false;
|
||||
|
||||
#define GETPROC(name, pfn) pfn = (PFN_##name)GetProcAddress(g_hMySQL, #name); if (!pfn) { FreeLibrary(g_hMySQL); g_hMySQL=NULL; return false; }
|
||||
GETPROC(mysql_init, pfn_init)
|
||||
GETPROC(mysql_real_connect, pfn_real_connect)
|
||||
GETPROC(mysql_options, pfn_options)
|
||||
GETPROC(mysql_real_query, pfn_real_query)
|
||||
GETPROC(mysql_insert_id, pfn_insert_id)
|
||||
GETPROC(mysql_close, pfn_close)
|
||||
GETPROC(mysql_error, pfn_error)
|
||||
GETPROC(mysql_escape_string, pfn_escape_string)
|
||||
#undef GETPROC
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ---- Helpers -------------------------------------------------------------
|
||||
|
||||
// Open a connection using current config. Returns handle on success, NULL
|
||||
// on failure. Caller must call pfn_close on the returned handle.
|
||||
static MYSQLH DB_Connect(char* pszError, int nErrBufSize)
|
||||
{
|
||||
if (!DB_LoadMySQL()) {
|
||||
if (pszError)
|
||||
strncpy(pszError, "libmysql.dll not found. Install MySQL Connector/C and place libmysql.dll next to mw4print.exe.", nErrBufSize - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MYSQLH h = pfn_init(NULL);
|
||||
if (!h) {
|
||||
if (pszError)
|
||||
strncpy(pszError, "mysql_init failed (out of memory?)", nErrBufSize - 1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Short connect timeout so the app doesn't hang if server is unreachable.
|
||||
int nTimeout = 5;
|
||||
pfn_options(h, MY_OPT_CONNECT_TIMEOUT, (const char*)&nTimeout);
|
||||
|
||||
MYSQLH conn = pfn_real_connect(h,
|
||||
g_dbConfig.szHost,
|
||||
g_dbConfig.szUsername,
|
||||
g_dbConfig.szPassword,
|
||||
g_dbConfig.szDatabase,
|
||||
(unsigned int)g_dbConfig.nPort,
|
||||
NULL, 0);
|
||||
|
||||
if (!conn) {
|
||||
if (pszError) {
|
||||
strncpy(pszError, pfn_error(h), nErrBufSize - 1);
|
||||
pszError[nErrBufSize - 1] = '\0';
|
||||
}
|
||||
pfn_close(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
// Execute a query string; return true on success.
|
||||
static bool DB_Exec(MYSQLH h, const char* pszSQL)
|
||||
{
|
||||
return pfn_real_query(h, pszSQL, (unsigned long)strlen(pszSQL)) == 0;
|
||||
}
|
||||
|
||||
// Escape a string for use inside SQL single-quoted literals.
|
||||
// Writes into pszOut (must be at least 2*len+1 bytes).
|
||||
static void DB_Escape(char* pszOut, const char* pszIn)
|
||||
{
|
||||
if (pfn_escape_string)
|
||||
pfn_escape_string(pszOut, pszIn, (MYULONG)strlen(pszIn));
|
||||
else {
|
||||
// Fallback: manual escape of ' and backslash
|
||||
char* dst = pszOut;
|
||||
for (const char* src = pszIn; *src; ++src) {
|
||||
if (*src == '\'' || *src == '\\')
|
||||
*dst++ = '\\';
|
||||
*dst++ = *src;
|
||||
}
|
||||
*dst = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
// ---- CREATE TABLE statements (run on first connect) ----------------------
|
||||
|
||||
static const char* s_szCreateMatch =
|
||||
"CREATE TABLE IF NOT EXISTS `match` ("
|
||||
" `match_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,"
|
||||
" `match_time` DATETIME NOT NULL,"
|
||||
" `server_name` VARCHAR(256) NOT NULL DEFAULT '',"
|
||||
" `server_ip` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `map_name` VARCHAR(128) NOT NULL DEFAULT '',"
|
||||
" `scenario_name` VARCHAR(128) NOT NULL DEFAULT '',"
|
||||
" `game_type` INT NOT NULL DEFAULT 0,"
|
||||
" `game_type_name` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `is_team_game` TINYINT(1) NOT NULL DEFAULT 0,"
|
||||
" `player_count` INT NOT NULL DEFAULT 0,"
|
||||
" `team_count` INT NOT NULL DEFAULT 0,"
|
||||
" `team_scores` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `game_length` INT NOT NULL DEFAULT 0,"
|
||||
" `kill_limit` INT NOT NULL DEFAULT 0,"
|
||||
" `respawn_limit` INT NOT NULL DEFAULT 0,"
|
||||
" `friendly_fire` INT NOT NULL DEFAULT 0,"
|
||||
" `heat_on` TINYINT(1) NOT NULL DEFAULT 0,"
|
||||
" `armor_mode` TINYINT(1) NOT NULL DEFAULT 0,"
|
||||
" `unlimited_ammo` TINYINT(1) NOT NULL DEFAULT 0,"
|
||||
" `is_night` TINYINT(1) NOT NULL DEFAULT 0,"
|
||||
" `min_tonnage` INT NOT NULL DEFAULT 0,"
|
||||
" `max_tonnage` INT NOT NULL DEFAULT 0,"
|
||||
" PRIMARY KEY (`match_id`)"
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||
|
||||
static const char* s_szCreatePlayerResult =
|
||||
"CREATE TABLE IF NOT EXISTS `player_result` ("
|
||||
" `result_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,"
|
||||
" `match_id` INT UNSIGNED NOT NULL,"
|
||||
" `player_name` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `mech_name` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `team` INT NOT NULL DEFAULT 0,"
|
||||
" `score` INT NOT NULL DEFAULT 0,"
|
||||
" `kills` INT NOT NULL DEFAULT 0,"
|
||||
" `deaths` INT NOT NULL DEFAULT 0,"
|
||||
" `is_bot` TINYINT(1) NOT NULL DEFAULT 0,"
|
||||
" `pilot_decal` INT NOT NULL DEFAULT 0,"
|
||||
" PRIMARY KEY (`result_id`),"
|
||||
" KEY `match_id` (`match_id`)"
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||
|
||||
static const char* s_szCreatePVP =
|
||||
"CREATE TABLE IF NOT EXISTS `pvp` ("
|
||||
" `pvp_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,"
|
||||
" `match_id` INT UNSIGNED NOT NULL,"
|
||||
" `attacker` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `victim` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `kills` INT NOT NULL DEFAULT 0,"
|
||||
" `score` INT NOT NULL DEFAULT 0,"
|
||||
" PRIMARY KEY (`pvp_id`),"
|
||||
" KEY `match_id` (`match_id`)"
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||
|
||||
static const char* s_szCreateEvent =
|
||||
"CREATE TABLE IF NOT EXISTS `event` ("
|
||||
" `event_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,"
|
||||
" `match_id` INT UNSIGNED NOT NULL,"
|
||||
" `event_type` INT NOT NULL DEFAULT 0,"
|
||||
" `actor` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `target` VARCHAR(64) NOT NULL DEFAULT '',"
|
||||
" `weapon` INT NOT NULL DEFAULT 0,"
|
||||
" `body_zone` INT NOT NULL DEFAULT 0,"
|
||||
" `param` INT NOT NULL DEFAULT 0,"
|
||||
" PRIMARY KEY (`event_id`),"
|
||||
" KEY `match_id` (`match_id`)"
|
||||
") ENGINE=InnoDB DEFAULT CHARSET=utf8";
|
||||
|
||||
// Map CBucketManager::Bucket_Type int to a game_type name string.
|
||||
static const char* GameTypeName(int n)
|
||||
{
|
||||
switch (n) {
|
||||
case 0: return "StockDestruction";
|
||||
case 1: return "StockTeamDestruction";
|
||||
case 2: return "StockAttrition";
|
||||
case 3: return "StockTeamAttrition";
|
||||
case 4: return "StockCaptureTheFlag";
|
||||
case 5: return "StockKingOfTheHill";
|
||||
case 6: return "StockTeamKingOfTheHill";
|
||||
case 7: return "StockTerritories";
|
||||
case 8: return "StockStealTheBacon";
|
||||
case 9: return "StockCaptureBase";
|
||||
case 10: return "StockDestroyObjective";
|
||||
case 11: return "StockEscort";
|
||||
case 12: return "StockMasterTrial";
|
||||
case 13: return "StockSiegeAssault";
|
||||
case 14: return "StockCampaign";
|
||||
case 15: return "CustomDestruction";
|
||||
case 16: return "CustomTeamDestruction";
|
||||
case 17: return "CustomAttrition";
|
||||
case 18: return "CustomTeamAttrition";
|
||||
case 19: return "CustomCaptureTheFlag";
|
||||
case 20: return "CustomKingOfTheHill";
|
||||
case 21: return "CustomTeamKingOfTheHill";
|
||||
case 22: return "CustomTerritories";
|
||||
case 23: return "CustomStealTheBacon";
|
||||
case 24: return "CustomCaptureBase";
|
||||
case 25: return "CustomDestroyObjective";
|
||||
case 26: return "CustomEscort";
|
||||
case 27: return "CustomMasterTrial";
|
||||
case 28: return "CustomSiegeAssault";
|
||||
case 29: return "CustomCampaign";
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve a ReplicatorID to a player name by scanning aRSOs[].
|
||||
static const char* ResolvePlayerName(
|
||||
const ReplicatorID& id,
|
||||
PCRecScoreObject aRSOs[],
|
||||
int nPlayers)
|
||||
{
|
||||
for (int i = 0; i < nPlayers; i++) {
|
||||
if (aRSOs[i]->m_who == id)
|
||||
return aRSOs[i]->GetName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
// ---- Config I/O ----------------------------------------------------------
|
||||
|
||||
static void DB_GetINIPath(char* pszOut)
|
||||
{
|
||||
sprintf(pszOut, "%s\\mw4print.ini", AssetsDirectory1);
|
||||
}
|
||||
|
||||
void DB_LoadConfig()
|
||||
{
|
||||
char szINI[MAX_PATH];
|
||||
DB_GetINIPath(szINI);
|
||||
|
||||
const char* sec = "MySQLExport";
|
||||
g_dbConfig.bEnabled = !!GetPrivateProfileInt(sec, "Enabled", 0, szINI);
|
||||
GetPrivateProfileString(sec, "Host", "localhost", g_dbConfig.szHost, sizeof(g_dbConfig.szHost), szINI);
|
||||
g_dbConfig.nPort = GetPrivateProfileInt(sec, "Port", 3306, szINI);
|
||||
GetPrivateProfileString(sec, "Database", "firestorm_stats", g_dbConfig.szDatabase, sizeof(g_dbConfig.szDatabase), szINI);
|
||||
GetPrivateProfileString(sec, "Username", "mw4", g_dbConfig.szUsername, sizeof(g_dbConfig.szUsername), szINI);
|
||||
GetPrivateProfileString(sec, "Password", "", g_dbConfig.szPassword, sizeof(g_dbConfig.szPassword), szINI);
|
||||
g_dbConfig.bExportEvents = !!GetPrivateProfileInt(sec, "ExportEvents", 0, szINI);
|
||||
}
|
||||
|
||||
void DB_SaveConfig()
|
||||
{
|
||||
char szINI[MAX_PATH];
|
||||
DB_GetINIPath(szINI);
|
||||
|
||||
const char* sec = "MySQLExport";
|
||||
char szBuf[32];
|
||||
|
||||
WritePrivateProfileString(sec, "Enabled", g_dbConfig.bEnabled ? "1" : "0", szINI);
|
||||
WritePrivateProfileString(sec, "Host", g_dbConfig.szHost, szINI);
|
||||
_itoa(g_dbConfig.nPort, szBuf, 10);
|
||||
WritePrivateProfileString(sec, "Port", szBuf, szINI);
|
||||
WritePrivateProfileString(sec, "Database", g_dbConfig.szDatabase, szINI);
|
||||
WritePrivateProfileString(sec, "Username", g_dbConfig.szUsername, szINI);
|
||||
WritePrivateProfileString(sec, "Password", g_dbConfig.szPassword, szINI);
|
||||
WritePrivateProfileString(sec, "ExportEvents", g_dbConfig.bExportEvents ? "1" : "0", szINI);
|
||||
}
|
||||
|
||||
// ---- Test connection -----------------------------------------------------
|
||||
|
||||
bool DB_TestConnection(char* pszError, int nErrBufSize)
|
||||
{
|
||||
if (pszError && nErrBufSize > 0)
|
||||
pszError[0] = '\0';
|
||||
|
||||
MYSQLH h = DB_Connect(pszError, nErrBufSize);
|
||||
if (!h)
|
||||
return false;
|
||||
|
||||
bool bOK = DB_Exec(h, "SELECT 1");
|
||||
if (!bOK && pszError) {
|
||||
strncpy(pszError, pfn_error(h), nErrBufSize - 1);
|
||||
pszError[nErrBufSize - 1] = '\0';
|
||||
}
|
||||
pfn_close(h);
|
||||
return bOK;
|
||||
}
|
||||
|
||||
// ---- Main export ---------------------------------------------------------
|
||||
|
||||
bool DB_ExportMatch(
|
||||
const CRecScoreFull& rsf,
|
||||
PCRecScoreObject aRSOs[],
|
||||
int nPlayers,
|
||||
const int naTeams[8],
|
||||
int nTeamCount,
|
||||
const MWNetMissionParameters& params)
|
||||
{
|
||||
char szError[512];
|
||||
MYSQLH h = DB_Connect(szError, sizeof(szError));
|
||||
if (!h)
|
||||
return false;
|
||||
|
||||
char szSQL[4096];
|
||||
char szEsc[512];
|
||||
bool bOK = true;
|
||||
|
||||
// Ensure tables exist (silent if already present).
|
||||
DB_Exec(h, s_szCreateMatch);
|
||||
DB_Exec(h, s_szCreatePlayerResult);
|
||||
DB_Exec(h, s_szCreatePVP);
|
||||
if (g_dbConfig.bExportEvents)
|
||||
DB_Exec(h, s_szCreateEvent);
|
||||
|
||||
// ---- Insert match row ------------------------------------------------
|
||||
|
||||
// Build team_scores as comma-separated string e.g. "100,80,0,0,0,0,0,0"
|
||||
char szTeamScores[64];
|
||||
sprintf(szTeamScores, "%d,%d,%d,%d,%d,%d,%d,%d",
|
||||
rsf.m_naTeamScores[0], rsf.m_naTeamScores[1],
|
||||
rsf.m_naTeamScores[2], rsf.m_naTeamScores[3],
|
||||
rsf.m_naTeamScores[4], rsf.m_naTeamScores[5],
|
||||
rsf.m_naTeamScores[6], rsf.m_naTeamScores[7]);
|
||||
|
||||
char szServerNameE[512], szServerIPE[512], szMapE[256], szScenarioE[256], szGameTypeNameE[128];
|
||||
DB_Escape(szServerNameE, params.m_serverName);
|
||||
DB_Escape(szServerIPE, params.m_serverIP);
|
||||
DB_Escape(szMapE, params.m_mapName);
|
||||
DB_Escape(szScenarioE, params.m_scenarioName);
|
||||
DB_Escape(szGameTypeNameE, GameTypeName(params.m_ruleType));
|
||||
|
||||
sprintf(szSQL,
|
||||
"INSERT INTO `match` "
|
||||
"(match_time, server_name, server_ip, map_name, scenario_name, "
|
||||
" game_type, game_type_name, is_team_game, player_count, team_count, "
|
||||
" team_scores, game_length, kill_limit, respawn_limit, friendly_fire, "
|
||||
" heat_on, armor_mode, unlimited_ammo, is_night, min_tonnage, max_tonnage) "
|
||||
"VALUES ("
|
||||
"'%04d-%02d-%02d %02d:%02d:%02d'," // match_time
|
||||
"'%s','%s','%s','%s'," // server_name, server_ip, map_name, scenario_name
|
||||
"%d,'%s',%d,%d,%d," // game_type, game_type_name, is_team_game, player_count, team_count
|
||||
"'%s'," // team_scores
|
||||
"%d,%d,%d,%d," // game_length, kill_limit, respawn_limit, friendly_fire
|
||||
"%d,%d,%d,%d,%d,%d" // heat_on, armor_mode, unlimited_ammo, is_night, min_tonnage, max_tonnage
|
||||
")",
|
||||
rsf.m_SysTime.wYear, rsf.m_SysTime.wMonth, rsf.m_SysTime.wDay,
|
||||
rsf.m_SysTime.wHour, rsf.m_SysTime.wMinute, rsf.m_SysTime.wSecond,
|
||||
szServerNameE, szServerIPE, szMapE, szScenarioE,
|
||||
params.m_ruleType, szGameTypeNameE,
|
||||
rsf.m_bTeamGame ? 1 : 0, nPlayers, nTeamCount,
|
||||
szTeamScores,
|
||||
params.m_gameLength,
|
||||
params.m_killLimit ? params.m_killLimitNumber : 0,
|
||||
params.m_respawnLimit ? params.m_respawnLimitNumber : 0,
|
||||
params.m_friendlyFirePercentage,
|
||||
params.m_heatOn ? 1 : 0,
|
||||
params.m_armormodeOn ? 1 : 0,
|
||||
params.m_unlimitedAmmo ? 1 : 0,
|
||||
params.m_isNight ? 1 : 0,
|
||||
params.m_minimumTonnage,
|
||||
params.m_maximumTonnage);
|
||||
|
||||
bOK = DB_Exec(h, szSQL);
|
||||
if (!bOK) {
|
||||
pfn_close(h);
|
||||
return false;
|
||||
}
|
||||
|
||||
MYULLONG nMatchID = pfn_insert_id(h);
|
||||
|
||||
// ---- Insert player_result rows ---------------------------------------
|
||||
|
||||
for (int i = 0; i < nPlayers && bOK; i++) {
|
||||
const CRecScoreObject& rso = *aRSOs[i];
|
||||
char szNameE[128], szMechE[128];
|
||||
DB_Escape(szNameE, rso.GetName());
|
||||
DB_Escape(szMechE, rso.GetMech());
|
||||
|
||||
sprintf(szSQL,
|
||||
"INSERT INTO `player_result` "
|
||||
"(match_id, player_name, mech_name, team, score, kills, deaths, is_bot, pilot_decal) "
|
||||
"VALUES (%I64u,'%s','%s',%d,%d,%d,%d,%d,%d)",
|
||||
nMatchID,
|
||||
szNameE, szMechE,
|
||||
rso.m_nPilotTeam,
|
||||
rso.m_nScore,
|
||||
rso.m_nKills,
|
||||
rso.m_nDeaths,
|
||||
rso.m_bBOT ? 1 : 0,
|
||||
rso.m_nPilotDecal);
|
||||
|
||||
bOK = DB_Exec(h, szSQL);
|
||||
}
|
||||
|
||||
// ---- Insert pvp rows -------------------------------------------------
|
||||
|
||||
for (int p = 0; p < rsf.m_nPVPs && bOK; p++) {
|
||||
const CRecScoreFull::SPVP_Rec& pvp = rsf.m_pPVPs[p];
|
||||
const char* pszAttacker = ResolvePlayerName(pvp.m_Inf, aRSOs, nPlayers);
|
||||
const char* pszVictim = ResolvePlayerName(pvp.m_Rcv, aRSOs, nPlayers);
|
||||
|
||||
char szAttE[128], szVicE[128];
|
||||
DB_Escape(szAttE, pszAttacker);
|
||||
DB_Escape(szVicE, pszVictim);
|
||||
|
||||
sprintf(szSQL,
|
||||
"INSERT INTO `pvp` (match_id, attacker, victim, kills, score) "
|
||||
"VALUES (%I64u,'%s','%s',%d,%d)",
|
||||
nMatchID, szAttE, szVicE, pvp.m_nKills, pvp.m_nScore);
|
||||
|
||||
bOK = DB_Exec(h, szSQL);
|
||||
}
|
||||
|
||||
// ---- Insert event rows (optional) ------------------------------------
|
||||
|
||||
if (bOK && g_dbConfig.bExportEvents) {
|
||||
// Walk the CRecScorePack linked list.
|
||||
const CRecScorePack* pPack = rsf.m_pScorePackStart;
|
||||
while (pPack && bOK) {
|
||||
for (int e = 0; e < pPack->m_nCount && bOK; e++) {
|
||||
const SRecScore& rs = pPack->m_a[e];
|
||||
const char* pszActor = ResolvePlayerName(rs.m_who, aRSOs, nPlayers);
|
||||
const char* pszTarget = ResolvePlayerName(rs.m_whom, aRSOs, nPlayers);
|
||||
char szActE[128], szTgtE[128];
|
||||
DB_Escape(szActE, pszActor);
|
||||
DB_Escape(szTgtE, pszTarget);
|
||||
|
||||
sprintf(szSQL,
|
||||
"INSERT INTO `event` (match_id, event_type, actor, target, weapon, body_zone, param) "
|
||||
"VALUES (%I64u,%d,'%s','%s',%d,%d,%d)",
|
||||
nMatchID,
|
||||
rs.m_nType,
|
||||
szActE, szTgtE,
|
||||
rs.m_nBy,
|
||||
rs.m_Where.m_xWhere,
|
||||
rs.m_nParam);
|
||||
|
||||
bOK = DB_Exec(h, szSQL);
|
||||
}
|
||||
pPack = pPack->m_pNext;
|
||||
}
|
||||
}
|
||||
|
||||
pfn_close(h);
|
||||
return bOK;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// dbexport.h - MySQL export interface for mw4print
|
||||
//
|
||||
// Connects to an external MySQL server and writes match results after each
|
||||
// print job. MySQL is loaded at runtime via late binding (libmysql.dll) so
|
||||
// no MySQL SDK is required at compile time.
|
||||
//
|
||||
// Config is stored in mw4print.ini next to the exe:
|
||||
// [MySQLExport]
|
||||
// Enabled=0
|
||||
// Host=192.168.1.100
|
||||
// Port=3306
|
||||
// Database=firestorm_stats
|
||||
// Username=mw4
|
||||
// Password=
|
||||
// ExportEvents=0 (1 = also export per-event SRecScore rows)
|
||||
//
|
||||
|
||||
#ifndef __DBEXPORT_H__
|
||||
#define __DBEXPORT_H__
|
||||
|
||||
// ---- Config struct -------------------------------------------------------
|
||||
|
||||
struct SDBConfig
|
||||
{
|
||||
bool bEnabled;
|
||||
char szHost[256];
|
||||
int nPort;
|
||||
char szDatabase[64];
|
||||
char szUsername[64];
|
||||
char szPassword[64];
|
||||
bool bExportEvents; // export individual SRecScore events (can be many rows)
|
||||
};
|
||||
|
||||
extern SDBConfig g_dbConfig;
|
||||
|
||||
// ---- Public API ----------------------------------------------------------
|
||||
|
||||
// Load / save config from mw4print.ini in the app directory.
|
||||
void DB_LoadConfig();
|
||||
void DB_SaveConfig();
|
||||
|
||||
// Try to open a connection using current g_dbConfig, run a trivial query,
|
||||
// then disconnect. Returns true on success; on failure fills pszError
|
||||
// (up to nErrBufSize bytes) with the MySQL error string.
|
||||
bool DB_TestConnection(char* pszError, int nErrBufSize);
|
||||
|
||||
// Export one completed match to the database. Called from
|
||||
// CRecScoreFull::DoPrint() just before PrintDlg().
|
||||
// Returns true on success.
|
||||
bool DB_ExportMatch(
|
||||
const CRecScoreFull& rsf,
|
||||
PCRecScoreObject aRSOs[],
|
||||
int nPlayers,
|
||||
const int naTeams[8],
|
||||
int nTeamCount,
|
||||
const MWNetMissionParameters& params
|
||||
);
|
||||
|
||||
#endif // __DBEXPORT_H__
|
||||
@@ -93,6 +93,9 @@ BEGIN
|
||||
MENUITEM "&Log report...\t^L", ID_FILE_LOGREPORT
|
||||
MENUITEM "Log report(&Block)...\t^B", ID_FILE_LOG2DATES
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "&Database Settings...\t^D", ID_FILE_DBSETTINGS
|
||||
MENUITEM "Ban&ner Setting...", ID_FILE_BANNERSETTING
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "E&xit", ID_APP_EXIT
|
||||
END
|
||||
POPUP "&Help"
|
||||
@@ -110,6 +113,7 @@ END
|
||||
IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLE PURE
|
||||
BEGIN
|
||||
"B", ID_FILE_LOG2DATES, VIRTKEY, CONTROL, NOINVERT
|
||||
"D", ID_FILE_DBSETTINGS, VIRTKEY, CONTROL, NOINVERT
|
||||
"L", ID_FILE_LOGREPORT, VIRTKEY, CONTROL, NOINVERT
|
||||
"O", ID_FILE_OPEN, VIRTKEY, CONTROL, NOINVERT
|
||||
END
|
||||
@@ -126,12 +130,50 @@ CAPTION "About mw4print"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
|
||||
LTEXT "mw4print Version 1.0",IDC_STATIC,40,10,119,8,
|
||||
LTEXT "mw4print Version 2.0",IDC_STATIC,40,10,119,8,
|
||||
SS_NOPREFIX
|
||||
LTEXT "Copyright (C) 2002",IDC_STATIC,40,25,119,8
|
||||
LTEXT "Copyright (C) 2026",IDC_STATIC,40,25,119,8
|
||||
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
|
||||
END
|
||||
|
||||
IDD_BANNER_SETTING DIALOG DISCARDABLE 0, 0, 300, 65
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Banner Setting"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Banner text:",IDC_STATIC,7,9,50,8
|
||||
EDITTEXT IDC_BANNER_TEXT,60,7,233,14,ES_AUTOHSCROLL
|
||||
DEFPUSHBUTTON "OK",IDOK,189,43,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,244,43,50,14
|
||||
LTEXT "(Printed at the bottom of every score sheet. Leave blank to hide.)",
|
||||
IDC_STATIC,7,28,286,16
|
||||
END
|
||||
|
||||
IDD_DB_SETTINGS DIALOG DISCARDABLE 0, 0, 300, 175
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Database Export Settings"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
CONTROL "Enable MySQL export",IDC_DB_ENABLED,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,7,200,12
|
||||
LTEXT "Host:",IDC_STATIC,7,26,30,8
|
||||
EDITTEXT IDC_DB_HOST,55,24,170,14,ES_AUTOHSCROLL
|
||||
LTEXT "Port:",IDC_STATIC,7,46,30,8
|
||||
EDITTEXT IDC_DB_PORT,55,44,50,14,ES_AUTOHSCROLL | ES_NUMBER
|
||||
LTEXT "Database:",IDC_STATIC,7,66,40,8
|
||||
EDITTEXT IDC_DB_DATABASE,55,64,170,14,ES_AUTOHSCROLL
|
||||
LTEXT "Username:",IDC_STATIC,7,86,40,8
|
||||
EDITTEXT IDC_DB_USERNAME,55,84,170,14,ES_AUTOHSCROLL
|
||||
LTEXT "Password:",IDC_STATIC,7,106,40,8
|
||||
EDITTEXT IDC_DB_PASSWORD,55,104,170,14,ES_AUTOHSCROLL | ES_PASSWORD
|
||||
CONTROL "Export individual events (many rows)",IDC_DB_EXPORTEVENTS,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,123,200,12
|
||||
PUSHBUTTON "Test Connection",IDC_DB_TEST,226,104,68,14
|
||||
LTEXT "",IDC_DB_STATUS,7,141,286,18,SS_NOPREFIX
|
||||
DEFPUSHBUTTON "OK",IDOK,189,155,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,244,155,50,14
|
||||
END
|
||||
|
||||
IDD_GET_2DATES DIALOG DISCARDABLE 0, 0, 187, 75
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Date selection"
|
||||
@@ -157,8 +199,8 @@ END
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,1
|
||||
PRODUCTVERSION 1,0,0,1
|
||||
FILEVERSION 2,0,0,0
|
||||
PRODUCTVERSION 2,0,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
@@ -175,13 +217,13 @@ BEGIN
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "mw4print MFC Application\0"
|
||||
VALUE "FileVersion", "1, 0, 0, 1\0"
|
||||
VALUE "FileVersion", "2, 0, 0, 0\0"
|
||||
VALUE "InternalName", "mw4print\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2002\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2026\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "mw4print.EXE\0"
|
||||
VALUE "ProductName", "mw4print Application\0"
|
||||
VALUE "ProductVersion", "1, 0, 0, 1\0"
|
||||
VALUE "ProductVersion", "2, 0, 0, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
||||
@@ -268,6 +268,10 @@ static RECT s_rcTextMargin; // check!!! - margin 2 panes on bottom relative to t
|
||||
// so g_aFonts[FNTI_INFO_TEXT/FNTI_INFO_TEXT_BOLD].m_nTextHeight should less then s_nTextHeight
|
||||
static int s_nTextHeight; // check!!! - text line height
|
||||
|
||||
// Configurable banner text printed at the bottom of each sheet.
|
||||
// Set via [battle tech print] BannerText= in options.ini next to the exe.
|
||||
char g_szPrintBanner[256] = "Join the worlds greatest Battletech community at WWW.MECHJOCK.COM today!";
|
||||
|
||||
void _stdcall GetFileName4GUID(char szBuf[256], const char* pcszDrv, const char* pcszPath, const char* pcszExt, const GUID& guid = *(const GUID*)NULL);
|
||||
|
||||
void WriteMString(MemoryStream& mf, const MString& ms)
|
||||
@@ -1008,27 +1012,27 @@ const char* ArmorZoneStr(int nArmorZone)
|
||||
case Adept::DamageObject::NullArmorZone:
|
||||
return "()";
|
||||
case Adept::DamageObject::LeftLegArmorZone:
|
||||
return "왼발";
|
||||
return "Left Leg";
|
||||
case Adept::DamageObject::RightLegArmorZone:
|
||||
return "오른발";
|
||||
return "Right Leg";
|
||||
case Adept::DamageObject::LeftArmArmorZone:
|
||||
return "왼팔";
|
||||
return "Left Arm";
|
||||
case Adept::DamageObject::RightArmArmorZone:
|
||||
return "오른팔";
|
||||
return "Right Arm";
|
||||
case Adept::DamageObject::RightTorsoArmorZone:
|
||||
return "우측";
|
||||
return "Right Torso";
|
||||
case Adept::DamageObject::LeftTorsoArmorZone:
|
||||
return "좌측";
|
||||
return "Left Torso";
|
||||
case Adept::DamageObject::CenterTorsoArmorZone:
|
||||
return "전면";
|
||||
return "Front";
|
||||
case Adept::DamageObject::CenterRearTorsoArmorZone:
|
||||
return "후면";
|
||||
return "Rear";
|
||||
case Adept::DamageObject::HeadArmorZone:
|
||||
return "머리";
|
||||
return "Head";
|
||||
case Adept::DamageObject::SpecialArmorZone1:
|
||||
return "보조장치1";
|
||||
return "Aux Device 1";
|
||||
case Adept::DamageObject::SpecialArmorZone2:
|
||||
return "보조장치2";
|
||||
return "Aux Device 2";
|
||||
case Adept::DamageObject::DefaultArmorZone:
|
||||
return "Default";
|
||||
}
|
||||
@@ -1996,83 +2000,83 @@ public:
|
||||
static SMSGFMT s_aKill[20][2] = {
|
||||
{
|
||||
{ "%s's %s destroys %s's %s!", 0 }, // ok!
|
||||
{ "%s의 %s, %s의 %s을(를) 파괴하다!", 0 }, // ok!
|
||||
{ "%s's %s destroyed %s's %s!", 0 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s explodes in a fire-ball, thanks to %s.", 1 }, // ok!
|
||||
{ "%s의 %s, 각 기관부의 화염으로 폭발! %s의 절묘한 공격성공!", 1 }, // ok!
|
||||
{ "%s's %s explodes in flames! %s lands a perfect hit!", 1 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s delivers the last blow as %s's %s explodes in flames!", 2 }, // ok!
|
||||
{ "%s는 %s의 %s에!", 2 - 100}, // ok!
|
||||
{ "%s took a hit to %s's %s!", 2 - 100}, // ok!
|
||||
},
|
||||
{
|
||||
{ "Smoking wreckage is all that's left of %s's %s after %s delivers the fatal blow!", 1 },
|
||||
{ "%s의 무자비한 공격으로 %s의 %s 불타는 잔해만 남길 것이다.", 2 }, // ok!
|
||||
{ "%s's merciless assault leaves only burning wreckage of %s's %s.", 2 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Glorious victory goes to %s as the wreckage from %s's %s lies burning on the battlefield!", 2 },
|
||||
{ "전황은 급속도로 진전, %s의 생존가능성은 0%%!", 8 }, // ok!
|
||||
{ "The battle escalates rapidly - %s's survival probability is 0%%!", 8 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s is put out of it's misery by a devastating shot from %s.", 1 },
|
||||
{ "%s의 압도적인 화력 앞에 %s 처참히 무너지고 있다.", 4 }, // ok!
|
||||
{ "Under %s's overwhelming firepower, %s crumbles miserably.", 4 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s racks up another kill marker from reducing %s's %s to rubble!", 2 },
|
||||
{ "%s %s의 %s을(를) 때려 눕히고, 새로운 킬마크를 얻었다.", 2 }, // ok!
|
||||
{ "%s knocked out %s's %s and earned a new kill mark.", 2 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Fresh paint is applied to %s's %s to mark the destruction of %s's %s!", 0 }, // ok!
|
||||
{ "%s는 %s를 격추한 킬마크를 %s에 추가했다.", 0 - 100 },
|
||||
{ "%s added a kill mark on %s for shooting down %s.", 0 - 100 },
|
||||
},
|
||||
{
|
||||
{ "The burning wreckage of %s's %s is a reminder to all of the prowess of %s's battle skills!", 1 },
|
||||
{ "%s의 잔해는 %s이(가) 가져갈 승리의 기념품이 될것이다.", 7 }, // ok!
|
||||
{ "The wreckage of %s will be %s's trophy of victory.", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "The thunderous explosion of %s's %s is music to the ears of %s!", 1 },
|
||||
{ "%s의 귀에 들려오는 죽음의 전주곡. 지휘자는 %s.", 7 }, // ok!
|
||||
{ "A death prelude echoes in %s's ears. The conductor: %s.", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s is destroyed by %s's %s.", 3 },
|
||||
{ "%s'의 %s, %s의 %s에게 파괴되었다.", 3 }, // ok!
|
||||
{ "%s's %s was destroyed by %s's %s.", 3 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s brings the four horsemen of the apocalypse down upon %s.", 4 },
|
||||
{ "%s(이)가 휘두르는 심판의 추가 %s에게 작렬했다.", 4 }, // ok!
|
||||
{ "The pendulum of judgment swung by %s strikes %s.", 4 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's life flashes as %s reduces the %s to a burning wreck.", 5 },
|
||||
{ "%s의 마지막 생명줄에, %s !", 7 - 100 }, // ok!
|
||||
{ "On %s's last lifeline, %s!", 7 - 100 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s is deafened by the resounding roar of the exploding %s, thanks to %s.", 1 },
|
||||
{ "%s 기체의 폭발소리와 함께, 저 하늘로 날아갔다. %s에게 영광을!", 7 }, // ok!
|
||||
{ "%s's mech explodes skyward. Glory to %s!", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "A kill marker is placed on %s's %s to mark the victory over %s.", 6 },
|
||||
{ "%s의 %s에 새로운 킬마크를 추가해야 할 듯, 희생자는 %s", 6 }, // ok!
|
||||
{ "A new kill mark should be added to %s's %s, victim: %s", 6 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s is delivered unto the inferno with regards from %s.", 7 },
|
||||
{ "%s, %s의 호위하에 지옥으로 향했다. %s에게 명복을!", 9 }, // ok!
|
||||
{ "%s headed to hell under %s's escort. Rest in peace, %s!", 9 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Another kill marker is given up by %s, as %s celebrates victory.", 7 },
|
||||
{ "%s, %s의 새로운 킬 마크가 되었다. 영원한 안식을…", 7 - 100 },
|
||||
{ "%s became %s's new kill mark. Rest in peace...", 7 - 100 },
|
||||
},
|
||||
{
|
||||
{ "Best wishes in the afterlife are presented to %s from %s.", 7 },
|
||||
{ "%s에게 남은 것은 오직 %s에 대한 복수뿐!", 7 }, // ok!
|
||||
{ "All that remains for %s is revenge against %s!", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Tragedy strikes %s as %s guns the %s down.", 5 },
|
||||
{ "%s 모든 화력을 동원해 %s의 %s을(를) 파괴했다.", 2 }, // ok!
|
||||
{ "%s brought all firepower to bear and destroyed %s's %s.", 2 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s earns the revenge of %s after the tragic destruction of the %s.", 2 },
|
||||
{ "%s의 비극적인 최후! %s 절망하는 %s을(를) 지켜볼 뿐이다.", 9 }, // ok!
|
||||
{ "A tragic end for %s! %s can only watch %s in despair.", 9 }, // ok!
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2083,11 +2087,11 @@ static SMSGFMT s_aKill[20][2] = {
|
||||
static SMSGFMT s_aSuicide[2][2] = {
|
||||
{
|
||||
{ "%s leaves the battlefield in disgrace after causing the destruction of the %s.", 0 },
|
||||
{ "%s 자폭! %s 불명예스럽게 전장을 떠났다!", 2 },
|
||||
{ "%s self-destructed! %s left the battlefield in disgrace!", 2 },
|
||||
},
|
||||
{
|
||||
{ "%s will not grace the halls of the honored mechwarriors after self-destructing the %s.", 0 },
|
||||
{ "%s 자폭! 비겁자여, 진실로 승리를 원하는가?", 3 },
|
||||
{ "%s self-destructed! Coward, do you truly desire victory?", 3 },
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2112,43 +2116,43 @@ static SMSGFMT s_aSuicide[2][2] = {
|
||||
static SMSGFMT s_aShot[10][2] = {
|
||||
{
|
||||
{ "%s's %s fires the %s and damages the %s of %s's %s.", 0 },
|
||||
{ "%s %s의 %s에 %s으로 공격했다", 1 }, // ok!
|
||||
{ "%s attacked %s's %s with %s", 1 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s fires the %s's %s and decimates the %s of %s's %s.", 2 },
|
||||
{ "%s이(가) 탑승한 %s, %s로 %s이(가) 탑승한 %s의 %s에 피해를 입혔다.", 2 },
|
||||
{ "%s piloting %s damaged %s's %s on %s's %s.", 2 },
|
||||
},
|
||||
{
|
||||
{ "%s's %s takes a devastating hit in the %s from %s.", 3 },
|
||||
{ "%s의 %s, %s의 압도적인 공격에 %s에 피해를 입었다.", 4 }, // ok!
|
||||
{ "%s's %s took damage to the %s under %s's overwhelming attack.", 4 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s's %s suffers a direct hit to it's %s from %s's %s.", 5 },
|
||||
{ "%s의 %s은(는) %s의 %s에 직접적인 피해를 받았다. 피해 %s!", 6 -100},
|
||||
{ "%s's %s took direct damage from %s's %s. Damage: %s!", 6 -100},
|
||||
},
|
||||
{
|
||||
{ "%s damages %s's %s.", 7 },
|
||||
{ "%s, %s의 %s에 피해를 입혔다..", 7 }, // ok!
|
||||
{ "%s dealt damage to %s's %s..", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Dense black smoke pours from %s's %s as a result of %s's targeted hit.", 8 },
|
||||
{ "%s의 절묘한 공격으로 %s의 %s에서 검은 연기가 퍼지고 있다.", 7 }, // ok!
|
||||
{ "Black smoke billows from %s's %s from %s's precise attack.", 7 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Fire boils from the damaged %s of %s's %s after %s hits it with a %s.", 9 },
|
||||
{ "%s %s을(를) 발사하여, %s이(가) 탑승한 %s의 %s에 피해를 발생시켰다.", 10 }, // ok!
|
||||
{ "%s fired %s, dealing damage to the %s of %s's %s.", 10 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "Smoke and fire are trailing from %s's %s, all results of the %s blast inflicted by %s.", 11 },
|
||||
{ "%s의 %s 공격에, 불과 연기가 %s의 기체를 뒤덮고 있다.", 15 }, // ok!
|
||||
{ "Fire and smoke engulf %s's mech from %s's %s attack.", 15 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s targets and fires the %s; %s cries in dismay as the %s's %s is damaged.", 10 },
|
||||
{ "%s %s을(를) 조준하여 %s이(가) 탑승한 %s의 %s에 맞춘 후 방아쇠를 당겼다.", 10 }, // ok!
|
||||
{ "%s aimed %s and pulled the trigger, hitting the %s of %s's %s.", 10 }, // ok!
|
||||
},
|
||||
{
|
||||
{ "%s takes a severe wound to the %s as %s aims for the %s again.", 13 },
|
||||
{ "%s 다시 %s의 %s을(를) 조준하여 사격했다. %s, %s에 심각한 피해를 입은 듯.", 14 -100},
|
||||
{ "%s aimed again at %s's %s and fired. %s seems to have taken serious damage to %s.", 14 -100},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -2156,19 +2160,19 @@ static SMSGFMT s_aShot[10][2] = {
|
||||
static SMSGFMT s_aCTF[1][2] = {
|
||||
{
|
||||
{ "%s captured flag.", 0 },
|
||||
{ "%s, 깃발 획득!.", 0 },
|
||||
{ "%s captured the flag!", 0 },
|
||||
},
|
||||
};
|
||||
static SMSGFMT s_aFBK[1][2] = {
|
||||
{
|
||||
{ "%s destroyed friendly building.", 0 },
|
||||
{ "%s, 깃발 획득!.", 0 },
|
||||
{ "%s captured the flag!", 0 },
|
||||
},
|
||||
};
|
||||
static SMSGFMT s_aEBK[1][2] = {
|
||||
{
|
||||
{ "%s destroyed enemy building.", 0 },
|
||||
{ "%s, 깃발 획득!.", 0 },
|
||||
{ "%s captured the flag!", 0 },
|
||||
},
|
||||
};
|
||||
const SMSGFMT* pcFMT;
|
||||
@@ -2602,6 +2606,15 @@ int CRecScoreFull::DoPrint() const
|
||||
MemoryStream stream(m_pMissionParam, m_nMissionParamSize, 0);
|
||||
params.LoadParameters(&stream);
|
||||
|
||||
#ifdef MW4PRINT
|
||||
// ---- Database export (before printing) ----
|
||||
// Export match data to the external MySQL database if configured.
|
||||
if (g_dbConfig.bEnabled) {
|
||||
DB_ExportMatch(*this, aRSOs, nPlayers, naTeams, nTeamCount, params);
|
||||
}
|
||||
// -------------------------------------------
|
||||
#endif // MW4PRINT
|
||||
|
||||
static int s_nIndex = -1; // for job name - not important!!
|
||||
if (++s_nIndex >= 10)
|
||||
s_nIndex = 0;
|
||||
@@ -2925,8 +2938,7 @@ void CRecScoreFull::DoPrint(HDC hDC, const RECT& rcDraw, const POINT& DPI, int n
|
||||
|
||||
Rectangle(hDC, rcMH.left, rcURL.top, rcMH.right, rcURL.bottom);
|
||||
|
||||
static const char s_szURL[] = "Join the worlds greatest Battletech community at WWW.MECHJOCK.COM today!";
|
||||
DrawText(hDC, s_szURL, strlen(s_szURL), &rcURL, DT_CENTER | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER);
|
||||
DrawText(hDC, g_szPrintBanner, strlen(g_szPrintBanner), &rcURL, DT_CENTER | DT_NOPREFIX | DT_SINGLELINE | DT_VCENTER);
|
||||
|
||||
SelectObject(hDC, hFontOld);
|
||||
// end URL Text
|
||||
@@ -3498,6 +3510,11 @@ void CRecScoreFull::LoadPrintParams() const
|
||||
LoadPrintParam(strOI, "TextMarginR", s_rcTextMargin.right, U_point(300), 0, U_cm(100));
|
||||
LoadPrintParam(strOI, "TextMarginB", s_rcTextMargin.bottom, U_point(300), 0, U_cm(100));
|
||||
LoadPrintParam(strOI, "TextHeight", s_nTextHeight, U_point(1100), U_point(600), U_point(1500));
|
||||
|
||||
// Configurable banner/URL text printed at the bottom of each sheet.
|
||||
GetPrivateProfileString("battle tech print", "BannerText",
|
||||
"Join the worlds greatest Battletech community at WWW.MECHJOCK.COM today!",
|
||||
g_szPrintBanner, sizeof(g_szPrintBanner), strOI);
|
||||
LoadPrintParam(strOI, "ImageTitleHeight", g_aFonts[FNTI_IMAGE_TITLE].m_nTextHeight, U_point(1500), U_point(900), U_point(2000));
|
||||
LoadPrintParam(strOI, "TableTextHeight", g_aFonts[FNTI_TABLE_TEXT].m_nTextHeight, U_point(900), U_point(600), U_point(1200));
|
||||
LoadPrintParam(strOI, "MHTextHeight", g_aFonts[FNTI_MISSION_HIGHLIGHTS].m_nTextHeight, U_point(1200), U_point(800), U_point(1600));
|
||||
|
||||
@@ -10,15 +10,31 @@
|
||||
#define IDC_DNT_END 1001
|
||||
#define ID_FILE_LOGREPORT 32771
|
||||
#define ID_FILE_LOG2DATES 32772
|
||||
#define ID_FILE_DBSETTINGS 32773
|
||||
#define ID_FILE_BANNERSETTING 32774
|
||||
|
||||
#define IDD_DB_SETTINGS 131
|
||||
#define IDD_BANNER_SETTING 132
|
||||
|
||||
#define IDC_DB_ENABLED 1002
|
||||
#define IDC_DB_HOST 1003
|
||||
#define IDC_DB_PORT 1004
|
||||
#define IDC_DB_DATABASE 1005
|
||||
#define IDC_DB_USERNAME 1006
|
||||
#define IDC_DB_PASSWORD 1007
|
||||
#define IDC_DB_TEST 1008
|
||||
#define IDC_DB_STATUS 1009
|
||||
#define IDC_DB_EXPORTEVENTS 1010
|
||||
#define IDC_BANNER_TEXT 1011
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_3D_CONTROLS 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 131
|
||||
#define _APS_NEXT_COMMAND_VALUE 32772
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_RESOURCE_VALUE 133
|
||||
#define _APS_NEXT_COMMAND_VALUE 32775
|
||||
#define _APS_NEXT_CONTROL_VALUE 1012
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -806,7 +806,7 @@ STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_ML_CH_ACCELERATION "Acceleration (Meters/Sec.):"
|
||||
IDS_ML_CH_DECELERATION "Deceleration (Meters/Sec.):"
|
||||
IDS_ML_CH_TURNRATE "Turn Rate (Degrees/Sec.):"
|
||||
IDS_ML_CH_TURNRATE "Turn Rate (Top Speed Rad/Sec):"
|
||||
IDS_ML_CH_TWISTRANGE "Torso Twist Range (Degrees):"
|
||||
IDS_ML_CH_TWISTSPEED "Torso Twist Speed (Degrees/Sec.):"
|
||||
IDS_ML_CH_NEWMECH "NEW 'MECH"
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
// forward declaration
|
||||
class FPInterface;
|
||||
|
||||
//ッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッ
|
||||
//----------------------------------------------------------------------
|
||||
// A data channel is a homogeneous collection of objects of a user defined
|
||||
// type (data objects). Data channels are uniquely identified by a Class_ID.
|
||||
//
|
||||
@@ -52,7 +52,7 @@ class IDataChannel : public InterfaceServer
|
||||
#define DATACHANNEL_INTERFACE Interface_ID(0x38a718a8, 0x14685b4b)
|
||||
#define GetDataChannelInterface(obj) ((IDataChannel*)obj->GetInterface(DATACHANNEL_INTERFACE))
|
||||
|
||||
//ッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッ
|
||||
//----------------------------------------------------------------------
|
||||
// Face-data channel interface
|
||||
//
|
||||
// This is an abstraction of a collection of data objects that is
|
||||
@@ -149,7 +149,7 @@ class IFaceDataChannel : public IDataChannel
|
||||
#define FACEDATACHANNEL_INTERFACE Interface_ID(0x181358d5, 0x3cab1bc9)
|
||||
#define GetFaceDataChannelInterface(obj) ((IFaceDataChannel*)obj->GetInterface(FACEDATACHANNEL_INTERFACE))
|
||||
|
||||
//ッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッ
|
||||
//----------------------------------------------------------------------
|
||||
// Interface class that allows to execute a callback method (Proc) for all
|
||||
// face-data channels of an object.
|
||||
//
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
// GUID that identifies this ifc (interface)
|
||||
#define FACEDATAMGR_INTERFACE Interface_ID(0x1b454148, 0x6a066927)
|
||||
|
||||
//ッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッ
|
||||
//----------------------------------------------------------------------
|
||||
// Interface for managing face-data channels.
|
||||
// Objects that want to have face-data channels should implement this ifc
|
||||
//
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#include <map>
|
||||
#include "export.h"
|
||||
|
||||
//ッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッ
|
||||
//----------------------------------------------------------------------
|
||||
// Face-data management implementation
|
||||
//________________________________________________________________________
|
||||
class IFaceDataMgrImpl : public IFaceDataMgr
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
// GUID that identifies this ifc (interface)
|
||||
#define PIPELINECLIENT_INTERFACE Interface_ID(0x62383d51, 0x2d0f7d6a)
|
||||
|
||||
//ッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッッ
|
||||
//----------------------------------------------------------------------
|
||||
// This interface should be implemented by objects that flow up the
|
||||
// geometry pipeline and have data members that belong to the pipeline
|
||||
// channels (geometry, topology, texmap, etc)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* BitMaps.h - MAX bitmap access classes
|
||||
*
|
||||
* Copyright © John Wainwright 1996
|
||||
* Copyright © John Wainwright 1996
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* HashTable.h - HashTable class for MAXScript
|
||||
*
|
||||
* Copyright © John Wainwright 1996
|
||||
* Copyright © John Wainwright 1996
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* IVisualMSMgr - core interface to the VisualMS manager
|
||||
* IVisualMSForm - interface to an existing form
|
||||
*
|
||||
* Copyright © Autodesk, Inc, 2000. John Wainwright.
|
||||
* Copyright © Autodesk, Inc, 2000. John Wainwright.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MAXKeys.h - MAX controller keyframe access classes
|
||||
*
|
||||
* Copyright © John Wainwright 1996
|
||||
* Copyright © John Wainwright 1996
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MAXMaterials.h - MAX material & map wrapper classes
|
||||
*
|
||||
* Copyright © John Wainwright 1996
|
||||
* Copyright © John Wainwright 1996
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user