Compare commits

...

9 Commits

Author SHA1 Message Date
Günther Brammer 6ad42ed24d Restore icons in the player join menu 2016-01-30 16:04:38 +01:00
Günther Brammer 7f75d09740 Increase height of dialog/menu title bars to the standard icon height 2016-01-30 16:04:37 +01:00
Günther Brammer 90860d3422 Use bigger icons for player menu where available 2016-01-30 16:04:37 +01:00
Günther Brammer d60f767f5c Increase all symbol sizes in player menu from 35 to 40 2016-01-30 16:04:22 +01:00
Günther Brammer dd49c5a2fe Increase the symbol size in the player menu items with labels 2016-01-30 16:04:06 +01:00
Günther Brammer 435e5a8eeb Simplify menu construction functions 2016-01-30 16:04:06 +01:00
Günther Brammer 66d78fddab Remove unused support for secondary menu command 2016-01-30 16:04:06 +01:00
Günther Brammer bddbc23354 Remove C4ObjectMenu
It's been superseded by other methods.
2016-01-30 16:04:05 +01:00
Günther Brammer 9741c1e853 Clonk: Don't play idle animations if Menu is open
At least, in theory. I only removed the plain GetMenu() call because the
engine GetMenu is going away.
2016-01-30 16:03:59 +01:00
41 changed files with 146 additions and 2323 deletions

View File

@ -713,8 +713,6 @@ set(OC_CLONK_SOURCES
src/object/C4ObjectInfoList.h src/object/C4ObjectInfoList.h
src/object/C4ObjectList.cpp src/object/C4ObjectList.cpp
src/object/C4ObjectList.h src/object/C4ObjectList.h
src/object/C4ObjectMenu.cpp
src/object/C4ObjectMenu.h
src/object/C4ObjectPtr.cpp src/object/C4ObjectPtr.cpp
src/object/C4ObjectPtr.h src/object/C4ObjectPtr.h
src/object/C4ObjectScript.cpp src/object/C4ObjectScript.cpp

View File

@ -158,11 +158,6 @@
<col></col> <col></col>
<col>When an object is loaded from a savegame or network synchronization is performed. Objects with a transfer zone should reset the zone in this call. Also see <emlink href="script/fn/SetTransferZone.html">SetTransferZone</emlink>().</col> <col>When an object is loaded from a savegame or network synchronization is performed. Objects with a transfer zone should reset the zone in this call. Also see <emlink href="script/fn/SetTransferZone.html">SetTransferZone</emlink>().</col>
</row> </row>
<row id="MenuQueryCancel">
<literal_col>MenuQueryCancel</literal_col>
<col>int selection, object menu_object</col>
<col>When the player wants to close a user defined object menu. Return value <code>true</code> will keep the menu open.</col>
</row>
<row id="IsFulfilled"> <row id="IsFulfilled">
<literal_col>IsFulfilled</literal_col> <literal_col>IsFulfilled</literal_col>
<col></col> <col></col>
@ -213,11 +208,6 @@
<col>object for_collection_of_object</col> <col>object for_collection_of_object</col>
<col>Called to determine the least needed inventory object when a clonk tries to collect a new object and his inventory is full. The function should return the object to be dropped to gain space, or <code>nil</code> if none.</col> <col>Called to determine the least needed inventory object when a clonk tries to collect a new object and his inventory is full. The function should return the object to be dropped to gain space, or <code>nil</code> if none.</col>
</row> </row>
<row id="OnMenuSelection">
<literal_col>OnMenuSelection</literal_col>
<col>int index, object menu_object</col>
<col>When an object menu entry is selected.</col>
</row>
<row id="CalcValue"> <row id="CalcValue">
<literal_col>CalcValue</literal_col> <literal_col>CalcValue</literal_col>
<col>object in_base, int for_player</col> <col>object in_base, int for_player</col>

View File

@ -120,18 +120,6 @@
<literal_col>MenuLeft / MenuUp / MenuRight / MenuDown</literal_col> <literal_col>MenuLeft / MenuUp / MenuRight / MenuDown</literal_col>
<col>Navigation in the player menu (asynchronous command).</col> <col>Navigation in the player menu (asynchronous command).</col>
</row> </row>
<row>
<literal_col>ObjectMenuOK / ObjectMenuSelect / ObjectMenuOKAll</literal_col>
<col>Confirmation of the selected item in a menu (synchronous command).</col>
</row>
<row>
<literal_col>ObjectMenuCancel</literal_col>
<col>Close a menu (synchronous command).</col>
</row>
<row>
<literal_col>ObjectMenuLeft / ObjectMenuUp / ObjectMenuRight / ObjectMenuDown</literal_col>
<col>Navigation in a menu (synchronous command).</col>
</row>
</table> </table>
</col> </col>
</row> </row>

View File

@ -1,105 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>AddMenuItem</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax>
<rtype>int</rtype>
<params>
<param>
<type>string</type>
<name>caption</name>
<desc>Text of the new menu entry</desc>
</param>
<param>
<type>string</type>
<name>command</name>
<desc>Command to be executed when the menu item is selected. This can be either a function name or a statement. If a function name is given then the function will be called in the object which was given as command_object to <funclink>CreateMenu</funclink>.</desc>
</param>
<param>
<type>id</type>
<name>symbol</name>
<desc>The ID is used as a picture for the menu item. The name of the definition can be used in caption using %s. Also the ID is passed as the first parameter to the call to command in case it is a function name.</desc>
</param>
<param>
<type>int</type>
<name>count</name>
<desc>Numeric value to be displayed next to the menu entry (such as counts and amounts).</desc>
</param>
<param>
<type>any</type>
<name>parameter</name>
<desc>Second parameter to the function specified in command (see remark).</desc>
</param>
<param>
<type>string</type>
<name>info_caption</name>
<desc>Description text of the new menu entry.</desc>
</param>
<param>
<type>int</type>
<name>extra</name>
<desc>Extra parameter for special behaviour of the menu entry.<br/> Lower 7 bits (0-127): menu symbol.<br/> 0: normal<br/> 1: rank symbol. With symbol specified, the Rank.png component of that definition will be used. count indicates the rank<br/> 2: picture facet, shifted to the right by XPar1 times the facet width. This is used to include multiple menu symbols in a single definition.<br/> 3: XPar1 specifies an object to be drawn with the rank symbol. If the object has no info section (and thus no rank), there will be an empty entry in context menus.<br/> 4: XPar1 specifies an object to be drawn.<br/> 7: XPar1 is a prop list that contains parameters for the menu symbol drawing. See picture parameter of <funclink>CustomMessage</funclink> for possible members. Bit 8 (128): XPar2 is used as object value and overrides the normal object value. Also see extra in <funclink>CreateMenu</funclink></desc>
<optional />
</param>
<param>
<type>any</type>
<name>XPar1</name>
<desc>First additional parameter for extra.</desc>
<optional />
</param>
<param>
<type>any</type>
<name>XPar2</name>
<desc>Second additional parameter for extra.</desc>
<optional />
</param>
</params>
</syntax>
<desc>Adds a menu entry.</desc>
<remark>Custom menu symbols should best have square aspect ratio.</remark>
<remark>If a function name is specified for command, the following parameters are passed: <code>symbol, parameter, bRight[, value]</code> with bRight indicating whether the menu entry was selected with [Special2] or the right mouse button. value is passed only if bit 8 is set in extra and specifies the displayed (overridden) object value of the menu entry.</remark>
<examples>
<example>
<code>
func ControlUse()
{
// Create local menu with local commandos
CreateMenu(GetID());
// Create menu items
AddMenuItem(&quot;Say hello&quot;, &quot;SayHello&quot;);
AddMenuItem(&quot;Do magic&quot;, &quot;DoMagic&quot;);
AddMenuItem(&quot;Create an object: %s&quot;, &quot;CreateItem&quot;, Rock);
AddMenuItem(&quot;Create another object: %s&quot;, &quot;CreateItem&quot;, Firestone);
}
func SayHello()
{
Message(&quot;Hello&quot;,this);
}
func DoMagic()
{
Sound(&quot;Magic*&quot;);
}
func CreateItem(id item)
{
CreateContents(item);
}</code>
<text>Menu for a special item.</text>
</example>
</examples>
<related>
<funclink>CreateMenu</funclink>
<funclink>SelectMenuItem</funclink>
<funclink>CloseMenu</funclink>
</related>
</func>
<author>jwk</author><date>2002-04</date>
</funcs>

View File

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>ClearMenuItems</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax><rtype>int</rtype></syntax>
<desc>Removes all entries from a menu.</desc>
<examples>
<example>
<code>var clonk=<funclink>GetCursor</funclink>();
clonk-&gt;<funclink>CreateMenu</funclink>(Clonk, clonk, nil, &quot;&quot;, 0, 2);
clonk-&gt;<funclink>AddMenuItem</funclink>(&quot;&quot;, &quot;&quot;, Gold, nil,nil,&quot;Old Text&quot;);
[...]
clonk-&gt;ClearMenuItems();
clonk-&gt;<funclink>AddMenuItem</funclink>(nil, &quot;&quot;, Gold, nil,0,0,&quot;New Text&quot;);</code>
<text>Opens a text window containing the entry "Old Text" for the selected clonk. Then changes the entry to "New Text".</text>
</example>
</examples>
<related>
<funclink>CreateMenu</funclink>
<funclink>AddMenuItem</funclink>
<funclink>CloseMenu</funclink>
</related>
</func>
<author>Sven2</author><date>2003-06</date>
</funcs>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>CloseMenu</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax><rtype>bool</rtype></syntax>
<desc>Closes the menu of the calling object.</desc>
<examples>
<example>
<code><funclink>Contained</funclink>()-&gt;CloseMenu();</code>
<text>Closes the container's menu.</text>
</example>
</examples>
<related><funclink>CreateMenu</funclink></related>
</func>
<author>Sven2</author><date>2001-11</date>
</funcs>

View File

@ -1,148 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>CreateMenu</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax>
<rtype>bool</rtype>
<params>
<param>
<type>id</type>
<name>symbol</name>
<desc>The picture of this object definition is used as symbol.</desc>
</param>
<param>
<type>object</type>
<name>command_object</name>
<desc>Object to receive the menu command (see <funclink>AddMenuItem</funclink>). Can be <code>nil</code> in local calls.</desc>
</param>
<param>
<type>int</type>
<name>extra</name>
<desc>
Additional information to be displayed about the currently selected entry. C4MN_ values are now also defined as constants:
<table>
<rowh>
<col>Constant</col>
<col>Value</col>
<col>Effect</col>
</rowh>
<row>
<col>C4MN_Extra_None</col>
<col>0</col>
<col>Nothing</col>
</row>
<row>
<col>C4MN_Extra_Components</col>
<col>1</col>
<col>Components</col>
</row>
<row>
<col>C4MN_Extra_Value</col>
<col>2</col>
<col>Value</col>
</row>
<row>
<col>C4MN_Extra_MagicValue</col>
<col>3</col>
<col>Value as magic value. extra_data is also displayed for comparison, e.g. "50/100".</col>
</row>
<row>
<col>C4MN_Extra_Info</col>
<col>4</col>
<col>Display object description immediately.</col>
</row>
<row>
<col>C4MN_Extra_ComponentsMagic</col>
<col>5</col>
<col>Display components and magic value.</col>
<col></col>
</row>
</table>
</desc>
</param>
<param>
<type>string</type>
<name>caption</name>
<desc>Text to be displayed if the menu is empty.</desc>
</param>
<param>
<type>int</type>
<name>extra_data</name>
<desc>Comparison value for extra 3.</desc>
</param>
<param>
<type>int</type>
<name>style</name>
<desc>
Appearance of the menu. The following constants are defined:
<table>
<rowh>
<col>Constant</col>
<col>Value</col>
<col>Appearance</col>
</rowh>
<row>
<col>C4MN_Style_Normal</col>
<col>0</col>
<col>Normal</col>
</row>
<row>
<col>C4MN_Style_Context</col>
<col>1</col>
<col>Context menu</col>
</row>
<row>
<col>C4MN_Style_Info</col>
<col>2</col>
<col>Info menu</col>
</row>
<row>
<col>C4MN_Style_Dialog</col>
<col>3</col>
<col>Dialog</col>
</row>
<row>
<col>C4MN_Style_EqualItemHeight</col>
<col>128</col>
<col>Can be combined with C4MN_Style_Dialog: all entries with an icon are drawn with the same height.</col>
</row>
</table>
</desc>
</param>
<param>
<type>bool</type>
<name>permanent</name>
<desc>The menu stays open after an entry has been selected.</desc>
</param>
<param>
<type>id</type>
<name>menu_id</name>
<desc>If specified, this id is used as menu id. The current menu id is returned by <funclink>GetMenu</funclink></desc>
<optional />
</param>
</params>
</syntax>
<desc>Creates a user defined menu for the specified object. Menu entries are to be added using <funclink>AddMenuItem</funclink>.</desc>
<examples>
<example>
<text>see <funclink>AddMenuItem</funclink></text>
</example>
</examples>
<related>
<funclink>AddMenuItem</funclink>
<funclink>SelectMenuItem</funclink>
<funclink>GetMenu</funclink>
<funclink>CloseMenu</funclink>
</related>
</func>
<author>springer</author><date>2002-04</date>
<author>Sven2</author><date>2007-03</date>
</funcs>

View File

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>GetMenu</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax><rtype>id?</rtype></syntax>
<desc>Returns the id of the menu if the object has an open menu. This is usually the id of the menu symbol (symbol) unless <funclink>CreateMenu</funclink> was used to explicitly use a differing menu id in idMenuID.</desc>
<remark>A return value of <code>nil</code> means that no valid symbol could be determined. This may happen e.g. if no object pointer was passed during a global call to the function. Engine defined menus such as Buy, Sell, etc. never return valid ids.</remark>
<related>
<funclink>CreateMenu</funclink>
<funclink>CloseMenu</funclink>
</related>
</func>
<author>wipfmetz</author><date>2002-08</date>
</funcs>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>GetMenuSelection</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax><rtype>int?</rtype></syntax>
<desc>Determines the currently selected menu entry of the currently open menu of an object, or <code>nil</code> if no menu is open.</desc>
<examples>
<example>
<code><funclink>Log</funclink>(&quot;Current selection: entry %d...&quot;, <funclink>GetCursor</funclink>(0)-&gt;GetMenuSelection();</code>
<text>Writes to the log which menu entry the player has currently selected.</text>
</example>
</examples>
<related><funclink>CreateMenu</funclink></related>
</func>
<author>Sven2</author><date>2001-11</date>
</funcs>

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>SelectMenuItem</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax>
<rtype>bool</rtype>
<params>
<param>
<type>int</type>
<name>number</name>
<desc>Number of the menu item which is to be selected. The first entry is number 0.</desc>
</param>
</params>
</syntax>
<desc>Sets menu selection in an object menu.</desc>
<related>
<funclink>GetMenuSelection</funclink>
<funclink>GetMenu</funclink>
<funclink>CreateMenu</funclink>
<funclink>AddMenuItem</funclink>
</related>
</func>
<author>PeterW</author><date>2002-10</date>
</funcs>

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>SetMenuSize</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax>
<rtype>bool</rtype>
<params>
<param>
<type>int</type>
<name>coloumns</name>
<desc>0-50: number of entries to be displayed per line</desc>
</param>
<param>
<type>int</type>
<name>rows</name>
<desc>0-50: number of entries to be displayed per column</desc>
</param>
</params>
</syntax>
<desc>Changes the display size of an object menu so the specified number of menu entries will be displayed per line or column.</desc>
<related>
<funclink>GetMenuSelection</funclink>
<funclink>GetMenu</funclink>
<funclink>CreateMenu</funclink>
<funclink>AddMenuItem</funclink>
</related>
</func>
<author>Sven2</author><date>2003-06</date>
</funcs>

View File

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE funcs
SYSTEM '../../../clonk.dtd'>
<?xml-stylesheet type="text/xsl" href="../../../clonk.xsl"?>
<funcs>
<func>
<title>ShowInfo</title>
<category>Objects</category>
<subcat>Menu</subcat>
<version>5.1 OC</version>
<syntax>
<rtype>bool</rtype>
</syntax>
<desc>Displays the description text of an object in a popup window (a menu window).</desc>
<remark>The information window's background will be the definition image of the obect.</remark>
<examples>
<example>
<code>func ControlSpecial()
{
if(!<funclink>Contents</funclink>()) return;
<funclink>Contents</funclink>()-&gt;ShowInfo();
}</code>
<text>A feature for a special clonk: pressing a (to be defined) 'special' key will display the description of the first inventory item in a popup window.</text>
</example>
</examples>
<related>
<funclink>SetCommand</funclink>
<funclink>GetDesc</funclink>
<funclink>CreateMenu</funclink>
<funclink>AddMenuItem</funclink>
<funclink>CloseMenu</funclink>
</related>
</func>
<author>Sven2</author><date>2002-08</date>
</funcs>

View File

@ -496,7 +496,7 @@ func FxIntWalkTimer(pTarget, effect)
effect.animation_id = PlayAnimation(anim, CLONK_ANIM_SLOT_Movement, GetWalkAnimationPosition(anim, 0), Anim_Linear(0, 0, 1000, 5, ANIM_Remove)); effect.animation_id = PlayAnimation(anim, CLONK_ANIM_SLOT_Movement, GetWalkAnimationPosition(anim, 0), Anim_Linear(0, 0, 1000, 5, ANIM_Remove));
} }
// The clonk has to stand, not making a pause animation yet and not doing other actions with the hands (e.g. loading the bow) // The clonk has to stand, not making a pause animation yet and not doing other actions with the hands (e.g. loading the bow)
else if(anim == Clonk_WalkStand && !GetHandAction() && GetMenu() == nil) else if(anim == Clonk_WalkStand && !GetHandAction() && !pTarget->~GetMenu())
{ {
if (effect.footstop_time) effect.footstep_time = 0; if (effect.footstop_time) effect.footstep_time = 0;
if(!effect.idle_animation_time) if(!effect.idle_animation_time)

View File

@ -1088,14 +1088,6 @@ If you want to remove the menu, the suggested method is clonk->TryCancelMenu() t
*/ */
func GetMenu() func GetMenu()
{ {
// No new-style menu set? Return the classic menu ID. This is deprecated and should be removed in some future.
// This function must return a proplist, but clashes with the engine-defined "GetMenu".
// This workaround here at least allows developers to reach the Clonk's menu ID.
if (this.control.menu == nil)
{
var menu_id = inherited(...);
if (menu_id) return {ID = menu_id};
}
return this.control.menu; return this.control.menu;
} }

View File

@ -79,8 +79,6 @@ IDS_COMM_PUSHTO=Schieben
IDS_COMM_PUT=Ablegen IDS_COMM_PUT=Ablegen
IDS_COMM_RETRY=Erneuter Versuch IDS_COMM_RETRY=Erneuter Versuch
IDS_COMM_SELL=Verkaufen IDS_COMM_SELL=Verkaufen
IDS_COMM_TAKE2=Herausnehmen
IDS_COMM_TAKE=Nehmen
IDS_COMM_THROW=Werfen IDS_COMM_THROW=Werfen
IDS_COMM_TRANSFER=Bewegung IDS_COMM_TRANSFER=Bewegung
IDS_COMM_UNGRAB=Loslassen IDS_COMM_UNGRAB=Loslassen

View File

@ -79,8 +79,6 @@ IDS_COMM_PUSHTO=Push
IDS_COMM_PUT=Put IDS_COMM_PUT=Put
IDS_COMM_RETRY=Retry IDS_COMM_RETRY=Retry
IDS_COMM_SELL=Sell IDS_COMM_SELL=Sell
IDS_COMM_TAKE2=Take out
IDS_COMM_TAKE=Take
IDS_COMM_THROW=Throw IDS_COMM_THROW=Throw
IDS_COMM_TRANSFER=Movement IDS_COMM_TRANSFER=Movement
IDS_COMM_UNGRAB=Let go IDS_COMM_UNGRAB=Let go

View File

@ -56,7 +56,7 @@ const int C4S_MaxPlayer = 4;
const int C4D_MaxVertex = 30; const int C4D_MaxVertex = 30;
const int const int
C4SymbolSize = 35, C4SymbolSize = 40,
C4SymbolBorder = 5, C4SymbolBorder = 5,
C4UpperBoardHeight = 50, C4UpperBoardHeight = 50,
C4PictureSize = 64, C4PictureSize = 64,
@ -194,27 +194,17 @@ const BYTE
COM_CursorLeft = 30, COM_CursorLeft = 30,
COM_CursorRight = 31; COM_CursorRight = 31;
const BYTE const BYTE
// COM_Help = 35, (obsolete, was: help-mode button)
COM_PlayerMenu = 36, COM_PlayerMenu = 36,
COM_Chat = 37; COM_Chat = 37;
const BYTE const BYTE
COM_MenuEnter = 38, COM_MenuEnter = 38,
COM_MenuEnterAll = 39,
COM_MenuClose = 40, COM_MenuClose = 40,
COM_MenuShowText = 42,
COM_MenuLeft = 52, COM_MenuLeft = 52,
COM_MenuRight = 53, COM_MenuRight = 53,
COM_MenuUp = 54, COM_MenuUp = 54,
COM_MenuDown = 55, COM_MenuDown = 55;
COM_MenuSelect = 60,
COM_MenuFirst = COM_MenuEnter,
COM_MenuLast = COM_MenuSelect,
COM_MenuNavigation1 = COM_MenuShowText,
COM_MenuNavigation2 = COM_MenuSelect;
//=================================== SendCommand ======================================== //=================================== SendCommand ========================================
const int32_t const int32_t

View File

@ -30,7 +30,6 @@
#include "C4GraphicsSystem.h" #include "C4GraphicsSystem.h"
#include "C4Viewport.h" #include "C4Viewport.h"
#include "C4Object.h" #include "C4Object.h"
#include "C4ObjectMenu.h"
#include <algorithm> #include <algorithm>
@ -69,15 +68,6 @@ void C4PlayerControlDef::CompileFunc(StdCompiler *pComp)
{ "MenuUp", CDA_MenuUp }, { "MenuUp", CDA_MenuUp },
{ "MenuRight", CDA_MenuRight }, { "MenuRight", CDA_MenuRight },
{ "MenuDown", CDA_MenuDown }, { "MenuDown", CDA_MenuDown },
{ "ObjectMenuTextComplete", CDA_ObjectMenuTextComplete },
{ "ObjectMenuOK", CDA_ObjectMenuOK },
{ "ObjectMenuOKAll", CDA_ObjectMenuOKAll },
{ "ObjectMenuSelect",CDA_ObjectMenuSelect },
{ "ObjectMenuCancel",CDA_ObjectMenuCancel },
{ "ObjectMenuLeft", CDA_ObjectMenuLeft },
{ "ObjectMenuUp", CDA_ObjectMenuUp },
{ "ObjectMenuRight", CDA_ObjectMenuRight },
{ "ObjectMenuDown", CDA_ObjectMenuDown },
{ "ZoomIn", CDA_ZoomIn }, { "ZoomIn", CDA_ZoomIn },
{ "ZoomOut", CDA_ZoomOut }, { "ZoomOut", CDA_ZoomOut },
{ NULL, CDA_None } { NULL, CDA_None }
@ -1214,14 +1204,10 @@ bool C4PlayerControl::ExecuteControlAction(int32_t iControl, C4PlayerControlDef:
// get affected player // get affected player
C4Player *pPlr = NULL; C4Player *pPlr = NULL;
C4Viewport *pVP; C4Viewport *pVP;
C4Object *pCursor = NULL;
C4Menu *pCursorMenu = NULL;
if (iPlr > -1) if (iPlr > -1)
{ {
pPlr = ::Players.Get(iPlr); pPlr = ::Players.Get(iPlr);
if (!pPlr) return false; if (!pPlr) return false;
pCursor = pPlr->Cursor;
if (pCursor && pCursor->Menu && pCursor->Menu->IsActive()) pCursorMenu = pCursor->Menu;
} }
// exec action (on player) // exec action (on player)
switch (eAction) switch (eAction)
@ -1238,16 +1224,6 @@ bool C4PlayerControl::ExecuteControlAction(int32_t iControl, C4PlayerControlDef:
case C4PlayerControlDef::CDA_MenuUp: if (!pPlr || !pPlr->Menu.IsActive() || fUp) return false; pPlr->Menu.Control(COM_MenuUp ,0); return true; // navigate case C4PlayerControlDef::CDA_MenuUp: if (!pPlr || !pPlr->Menu.IsActive() || fUp) return false; pPlr->Menu.Control(COM_MenuUp ,0); return true; // navigate
case C4PlayerControlDef::CDA_MenuRight: if (!pPlr || !pPlr->Menu.IsActive() || fUp) return false; pPlr->Menu.Control(COM_MenuRight,0); return true; // navigate case C4PlayerControlDef::CDA_MenuRight: if (!pPlr || !pPlr->Menu.IsActive() || fUp) return false; pPlr->Menu.Control(COM_MenuRight,0); return true; // navigate
case C4PlayerControlDef::CDA_MenuDown: if (!pPlr || !pPlr->Menu.IsActive() || fUp) return false; pPlr->Menu.Control(COM_MenuDown,0); return true; // navigate case C4PlayerControlDef::CDA_MenuDown: if (!pPlr || !pPlr->Menu.IsActive() || fUp) return false; pPlr->Menu.Control(COM_MenuDown,0); return true; // navigate
case C4PlayerControlDef::CDA_ObjectMenuTextComplete: if (!pCursorMenu || fUp || !pCursorMenu->IsTextProgressing()) return false; pCursorMenu->Control(COM_MenuShowText,0); return true; // fast-foward text display
case C4PlayerControlDef::CDA_ObjectMenuOK: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuEnter,0); return true; // ok on item
case C4PlayerControlDef::CDA_ObjectMenuOKAll: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuEnterAll,0); return true; // alt ok on item
case C4PlayerControlDef::CDA_ObjectMenuSelect: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuSelect,rKeyExtraData.iStrength); return true; // select an item directly
case C4PlayerControlDef::CDA_ObjectMenuCancel: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuClose,0); return true; // close menu
case C4PlayerControlDef::CDA_ObjectMenuLeft: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuLeft ,0); return true; // navigate
case C4PlayerControlDef::CDA_ObjectMenuUp: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuUp ,0); return true; // navigate
case C4PlayerControlDef::CDA_ObjectMenuRight: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuRight,0); return true; // navigate
case C4PlayerControlDef::CDA_ObjectMenuDown: if (!pCursorMenu || fUp) return false; pCursorMenu->Control(COM_MenuDown ,0); return true; // navigate
case C4PlayerControlDef::CDA_ZoomIn: if (!pPlr || fUp || !(pVP = ::Viewports.GetViewport(iPlr))) return false; pVP->ChangeZoom(C4GFX_ZoomStep); return true; // viewport zoom case C4PlayerControlDef::CDA_ZoomIn: if (!pPlr || fUp || !(pVP = ::Viewports.GetViewport(iPlr))) return false; pVP->ChangeZoom(C4GFX_ZoomStep); return true; // viewport zoom
case C4PlayerControlDef::CDA_ZoomOut: if (!pPlr || fUp || !(pVP = ::Viewports.GetViewport(iPlr))) return false; pVP->ChangeZoom(1.0f/C4GFX_ZoomStep); return true; // viewport zoom case C4PlayerControlDef::CDA_ZoomOut: if (!pPlr || fUp || !(pVP = ::Viewports.GetViewport(iPlr))) return false; pVP->ChangeZoom(1.0f/C4GFX_ZoomStep); return true; // viewport zoom

View File

@ -42,8 +42,6 @@ public:
CDA_Script, // default: Script callback CDA_Script, // default: Script callback
CDA_Menu, // open player menu (async) CDA_Menu, // open player menu (async)
CDA_MenuOK, CDA_MenuCancel, CDA_MenuLeft, CDA_MenuUp, CDA_MenuRight, CDA_MenuDown, // player menu controls (async) CDA_MenuOK, CDA_MenuCancel, CDA_MenuLeft, CDA_MenuUp, CDA_MenuRight, CDA_MenuDown, // player menu controls (async)
CDA_ObjectMenuTextComplete, // object menu fast-foward through text animation (async)
CDA_ObjectMenuOK, CDA_ObjectMenuOKAll, CDA_ObjectMenuSelect, CDA_ObjectMenuCancel, CDA_ObjectMenuLeft, CDA_ObjectMenuUp, CDA_ObjectMenuRight, CDA_ObjectMenuDown, // object menu controls (sync)
CDA_ZoomIn, CDA_ZoomOut // player viewport control (async) CDA_ZoomIn, CDA_ZoomOut // player viewport control (async)
}; };
@ -86,9 +84,8 @@ public:
bool operator ==(const C4PlayerControlDef &cmp) const; bool operator ==(const C4PlayerControlDef &cmp) const;
bool Execute(bool fUp, const C4KeyEventData &rKeyExtraData); // key was triggered - execute and return if handled bool Execute(bool fUp, const C4KeyEventData &rKeyExtraData); // key was triggered - execute and return if handled
bool IsSyncObjectMenuControl() const { return eAction>=CDA_ObjectMenuOK && eAction<=CDA_ObjectMenuDown; } bool IsAsync() const { return eAction != CDA_None && eAction != CDA_Script; } // true if to be executed directly when triggered
bool IsAsync() const { return eAction != CDA_None && eAction != CDA_Script && !IsSyncObjectMenuControl(); } // true if to be executed directly when triggered bool IsSync() const { return eAction == CDA_Script; } // true if to be executed via control queue
bool IsSync() const { return eAction == CDA_Script || IsSyncObjectMenuControl(); } // true if to be executed via control queue
bool IsValid() const { return eAction != CDA_None; } bool IsValid() const { return eAction != CDA_None; }
}; };

View File

@ -969,8 +969,6 @@ const char * GetRecordChunkTypeName(C4RecordChunkType eType)
case RCT_MatScan: return "MatScan"; // landscape scan execute case RCT_MatScan: return "MatScan"; // landscape scan execute
case RCT_MatScanDo: return "MatScanDo"; // landscape scan mat change case RCT_MatScanDo: return "MatScanDo"; // landscape scan mat change
case RCT_Area: return "Area"; // object area change case RCT_Area: return "Area"; // object area change
case RCT_MenuAdd: return "MenuAdd"; // add menu item
case RCT_MenuAddC: return "MenuAddC"; // add menu item: Following commands
case RCT_OCF: return "OCF"; // OCF setting of updating case RCT_OCF: return "OCF"; // OCF setting of updating
case RCT_DirectExec: return "DirectExec"; // a DirectExec-script case RCT_DirectExec: return "DirectExec"; // a DirectExec-script
case RCT_Definition: return "Definition"; // Definition callback case RCT_Definition: return "Definition"; // Definition callback

View File

@ -78,8 +78,6 @@ enum C4RecordChunkType // record file chunk type
RCT_MatScan = 0x9E, // landscape scan execute RCT_MatScan = 0x9E, // landscape scan execute
RCT_MatScanDo= 0x9F, // landscape scan mat change RCT_MatScanDo= 0x9F, // landscape scan mat change
RCT_Area = 0xA0, // object area change RCT_Area = 0xA0, // object area change
RCT_MenuAdd = 0xA1, // add menu item
RCT_MenuAddC = 0xA2, // add menu item: Following commands
RCT_OCF = 0xA3, // OCF setting of updating RCT_OCF = 0xA3, // OCF setting of updating
RCT_DirectExec = 0xA4, // a DirectExec-script RCT_DirectExec = 0xA4, // a DirectExec-script
RCT_Definition = 0xA5, // Definition callback RCT_Definition = 0xA5, // Definition callback

View File

@ -46,7 +46,6 @@
#include <C4Player.h> #include <C4Player.h>
#include <C4GameOverDlg.h> #include <C4GameOverDlg.h>
#include <C4GameParameters.h> #include <C4GameParameters.h>
#include <C4ObjectMenu.h>
#include <C4GameLobby.h> #include <C4GameLobby.h>
#include <C4ChatDlg.h> #include <C4ChatDlg.h>
#include <C4PlayerControl.h> #include <C4PlayerControl.h>

View File

@ -26,7 +26,6 @@
#include <C4FullScreen.h> #include <C4FullScreen.h>
#include <C4Stat.h> #include <C4Stat.h>
#include <C4Player.h> #include <C4Player.h>
#include <C4ObjectMenu.h>
#include <C4MouseControl.h> #include <C4MouseControl.h>
#include <C4PXS.h> #include <C4PXS.h>
#include <C4GameMessage.h> #include <C4GameMessage.h>
@ -151,22 +150,6 @@ void C4Viewport::DrawMenu(C4TargetFacet &cgo0)
return; return;
} }
// Player cursor object menu
if (pPlr && pPlr->Cursor && pPlr->Cursor->Menu)
{
if (ResetMenuPositions) pPlr->Cursor->Menu->ResetLocation();
// if mouse is dragging, make it transparent to easy construction site drag+drop
bool fDragging=false;
if (::MouseControl.IsDragging() && ::MouseControl.IsViewport(this))
{
fDragging = true;
pDraw->ActivateBlitModulation(0x4fffffff);
}
// draw menu
pPlr->Cursor->Menu->Draw(cgo);
// reset modulation for dragging
if (fDragging) pDraw->DeactivateBlitModulation();
}
// Player menu // Player menu
if (pPlr && pPlr->Menu.IsActive()) if (pPlr && pPlr->Menu.IsActive())
{ {
@ -798,8 +781,6 @@ bool C4Viewport::IsViewportMenu(class C4Menu *pMenu)
C4Player *pPlr = ::Players.Get(Player); C4Player *pPlr = ::Players.Get(Player);
// Player eliminated: No menu // Player eliminated: No menu
if (pPlr && pPlr->Eliminated) return false; if (pPlr && pPlr->Eliminated) return false;
// Player cursor object menu
if (pPlr && pPlr->Cursor && pPlr->Cursor->Menu == pMenu) return true;
// Player menu // Player menu
if (pPlr && pPlr->Menu.IsActive() && &(pPlr->Menu) == pMenu) return true; if (pPlr && pPlr->Menu.IsActive() && &(pPlr->Menu) == pMenu) return true;
// Fullscreen menu (if active, only one viewport can exist) // Fullscreen menu (if active, only one viewport can exist)

View File

@ -96,7 +96,6 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix);
#define PSF_CalcValue "~CalcValue" // C4Object *pInBase, int iForPlayer #define PSF_CalcValue "~CalcValue" // C4Object *pInBase, int iForPlayer
#define PSF_CalcDefValue "~CalcDefValue" // C4Object *pInBase, int iForPlayer #define PSF_CalcDefValue "~CalcDefValue" // C4Object *pInBase, int iForPlayer
#define PSF_InputCallback "InputCallback" // const char *szText #define PSF_InputCallback "InputCallback" // const char *szText
#define PSF_MenuQueryCancel "~MenuQueryCancel" // int iSelection
#define PSF_IsFulfilled "~IsFulfilled" // int for_plr #define PSF_IsFulfilled "~IsFulfilled" // int for_plr
#define PSF_AttachTargetLost "~AttachTargetLost" #define PSF_AttachTargetLost "~AttachTargetLost"
#define PSF_CrewSelection "~CrewSelection" // bool fDeselect #define PSF_CrewSelection "~CrewSelection" // bool fDeselect
@ -149,7 +148,6 @@ bool C4ValueToMatrix(const C4ValueArray& array, StdMeshMatrix* matrix);
// On* Callbacks // On* Callbacks
#define PSF_OnGameOver "~OnGameOver" #define PSF_OnGameOver "~OnGameOver"
#define PSF_MenuSelection "~OnMenuSelection" // int iItemIndex, C4Object *pMenuObject
#define PSF_OnActionJump "~OnActionJump" // int iXDir100, iYDir100 #define PSF_OnActionJump "~OnActionJump" // int iXDir100, iYDir100
#define PSF_OnOwnerChanged "~OnOwnerChanged" // iNewOwner, iOldOwner #define PSF_OnOwnerChanged "~OnOwnerChanged" // iNewOwner, iOldOwner
#define PSF_EnergyChange "~OnEnergyChange" // int iChange, int iCause, int iCausedByPlayer #define PSF_EnergyChange "~OnEnergyChange" // int iChange, int iCause, int iCausedByPlayer

View File

@ -139,12 +139,12 @@ namespace C4GUI
// draw symbol // draw symbol
if (fctIcon.Surface) if (fctIcon.Surface)
{ {
C4Facet cgoSymbol(cgo.Surface, cgo.TargetX + rcBounds.x + 1, cgo.TargetY + rcBounds.y + 1, rcBounds.Hgt-2, rcBounds.Hgt-2); C4Facet cgoSymbol(cgo.Surface, cgo.TargetX + rcBounds.x, cgo.TargetY + rcBounds.y, rcBounds.Hgt, rcBounds.Hgt);
fctIcon.Draw(cgoSymbol); fctIcon.Draw(cgoSymbol);
} }
// calculations for automatic scrolling // calculations for automatic scrolling
int32_t iXOff = 0; int32_t iXOff = 0, iYOff;
if (iAlign == ALeft) iXOff += 5; if (iAlign == ALeft) iXOff += C4GUI_IconLabelSpacing;
if (iAutoScrollDelay) if (iAutoScrollDelay)
{ {
C4TimeMilliseconds tNow = C4TimeMilliseconds::Now(); C4TimeMilliseconds tNow = C4TimeMilliseconds::Now();
@ -168,14 +168,17 @@ namespace C4GUI
// print out text; clipped // print out text; clipped
pDraw->StorePrimaryClipper(); pDraw->StorePrimaryClipper();
pDraw->SetPrimaryClipper(rcBounds.x + GetLeftIndent() + cgo.TargetX, rcBounds.y + cgo.TargetY, rcBounds.x+rcBounds.Wdt - GetRightIndent() + cgo.TargetX, rcBounds.y+rcBounds.Hgt + cgo.TargetY); pDraw->SetPrimaryClipper(rcBounds.x + GetLeftIndent() + cgo.TargetX, rcBounds.y + cgo.TargetY, rcBounds.x+rcBounds.Wdt - GetRightIndent() + cgo.TargetX, rcBounds.y+rcBounds.Hgt + cgo.TargetY);
pDraw->TextOut(sText.getData(), *pFont, 1.0f, cgo.Surface, x0 + cgo.TargetX + iXOff, rcBounds.y + cgo.TargetY + (rcBounds.Hgt-pFont->GetLineHeight())/2-1, dwFgClr, iAlign); iYOff = (rcBounds.Hgt-pFont->GetLineHeight())/2-1;
// even border all around the text
if (!fctIcon.Surface) iXOff += iYOff;
pDraw->TextOut(sText.getData(), *pFont, 1.0f, cgo.Surface, x0 + cgo.TargetX + iXOff, rcBounds.y + cgo.TargetY + iYOff, dwFgClr, iAlign);
pDraw->RestorePrimaryClipper(); pDraw->RestorePrimaryClipper();
} }
int32_t WoodenLabel::GetDefaultHeight(CStdFont *pUseFont) int32_t WoodenLabel::GetDefaultHeight(CStdFont *pUseFont)
{ {
if (!pUseFont) pUseFont = &(::GraphicsResource.TextFont); if (!pUseFont) pUseFont = &(::GraphicsResource.TextFont);
return std::max<int32_t>(pUseFont->GetLineHeight(), C4GUI_MinWoodBarHgt); return std::max<int32_t>(pUseFont->GetLineHeight(), C4SymbolSize);
} }
void WoodenLabel::SetIcon(const C4Facet &rfctIcon) void WoodenLabel::SetIcon(const C4Facet &rfctIcon)

View File

@ -47,16 +47,9 @@ void C4MainMenu::Default()
Player=NO_OWNER; Player=NO_OWNER;
} }
bool C4MainMenu::Init(C4FacetSurface &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) bool C4MainMenu::InitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iId, int32_t iStyle)
{ {
if (!DoInit(fctSymbol, szEmpty, iExtra, iExtraData, iId, iStyle)) return false; if (!DoInitRefSym(fctSymbol, szEmpty, iId, iStyle)) return false;
Player=iPlayer;
return true;
}
bool C4MainMenu::InitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle)
{
if (!DoInitRefSym(fctSymbol, szEmpty, iExtra, iExtraData, iId, iStyle)) return false;
Player=iPlayer; Player=iPlayer;
return true; return true;
} }
@ -71,7 +64,7 @@ bool C4MainMenu::ActivateNewPlayer(int32_t iPlayer)
// Menu symbol/init // Menu symbol/init
if (GfxR->fctPlayerClr.Surface) if (GfxR->fctPlayerClr.Surface)
GfxR->fctPlayerClr.Surface->SetClr(0xff); GfxR->fctPlayerClr.Surface->SetClr(0xff);
InitRefSym(GfxR->fctPlayerClr, LoadResStr("IDS_MENU_NOPLRFILES"), iPlayer); InitRefSym(GfxR->fctPlayerClr, LoadResStr("IDS_MENU_CPNEWPLAYER"), iPlayer, 0, C4MN_Style_Context);
for (DirectoryIterator iter(Config.General.UserDataPath); *iter; ++iter) for (DirectoryIterator iter(Config.General.UserDataPath); *iter; ++iter)
if (WildcardMatch("*.ocp", *iter)) if (WildcardMatch("*.ocp", *iter))
{ {
@ -85,13 +78,22 @@ bool C4MainMenu::ActivateNewPlayer(int32_t iPlayer)
// Load player info // Load player info
C4PlayerInfoCore C4P; C4PlayerInfoCore C4P;
if (!C4P.Load(hGroup)) { hGroup.Close(); continue; } if (!C4P.Load(hGroup)) { hGroup.Close(); continue; }
// Load custom portrait
C4FacetSurface fctSymbol;
if (!fctSymbol.Load(hGroup, C4CFN_BigIcon, C4FCT_Full, C4FCT_Full, false, true))
fctSymbol.Load(hGroup, C4CFN_BigIcon, C4FCT_Full, C4FCT_Full, false, true);
// Close group // Close group
hGroup.Close(); hGroup.Close();
// Add player item // Add player item
sprintf(szCommand, "JoinPlayer:%s", szFilename); sprintf(szCommand, "JoinPlayer:%s", szFilename);
StdStrBuf sItemText; StdStrBuf sItemText;
sItemText.Format(LoadResStr("IDS_MENU_NEWPLAYER"), C4P.PrefName); sItemText.Format(LoadResStr("IDS_MENU_NEWPLAYER"), C4P.PrefName);
C4FacetSurface fctSymbol; // No custom portrait: use default player image
if (!fctSymbol.Surface)
{
fctSymbol.Create(C4SymbolSize, C4SymbolSize);
GfxR->fctPlayerClr.DrawClr(fctSymbol, true, C4P.PrefColorDw);
}
// Add menu item // Add menu item
Add(sItemText.getData(), fctSymbol, szCommand); Add(sItemText.getData(), fctSymbol, szCommand);
// Reset symbol facet (menu holds on to the surface) // Reset symbol facet (menu holds on to the surface)
@ -151,7 +153,7 @@ bool C4MainMenu::DoRefillInternal(bool &rfRefilled)
sprintf(szInfoCaption,LoadResStr("IDS_MENU_ATTACKINFO"),pPlr->GetName(),szFriendly,szNot); sprintf(szInfoCaption,LoadResStr("IDS_MENU_ATTACKINFO"),pPlr->GetName(),szFriendly,szNot);
if (iIndex==pPlayer->Number) SCopy(LoadResStr("IDS_MENU_ATTACKSELF"),szInfoCaption); if (iIndex==pPlayer->Number) SCopy(LoadResStr("IDS_MENU_ATTACKSELF"),szInfoCaption);
// Add item // Add item
Add(sMsg.getData(),fctSymbol,szCommand,C4MN_Item_NoCount,NULL,szInfoCaption); Add(sMsg.getData(),fctSymbol,szCommand,szInfoCaption);
fctSymbol.Default(); fctSymbol.Default();
} }
break; break;
@ -209,7 +211,7 @@ bool C4MainMenu::DoRefillInternal(bool &rfRefilled)
sTeamName.Ref(LoadResStr("IDS_PRC_NEWTEAM")); sTeamName.Ref(LoadResStr("IDS_PRC_NEWTEAM"));
const char *szOperation = (Identification == C4MN_TeamSwitch) ? "TeamSwitch" : "TeamSel"; const char *szOperation = (Identification == C4MN_TeamSwitch) ? "TeamSwitch" : "TeamSel";
Add(sTeamName.getData(), fctSymbol,FormatString("%s:%d", szOperation, pTeam ? pTeam->GetID() : TEAMID_New).getData(), Add(sTeamName.getData(), fctSymbol,FormatString("%s:%d", szOperation, pTeam ? pTeam->GetID() : TEAMID_New).getData(),
C4MN_Item_NoCount,NULL,FormatString(LoadResStr("IDS_MSG_JOINTEAM"), sTeamName.getData()).getData(), C4ID(pTeam ? pTeam->GetID() : 0)); FormatString(LoadResStr("IDS_MSG_JOINTEAM"), sTeamName.getData()).getData());
fctSymbol.Default(); fctSymbol.Default();
} }
break; break;
@ -224,7 +226,7 @@ bool C4MainMenu::DoRefillInternal(bool &rfRefilled)
if (!pVP) return false; if (!pVP) return false;
int32_t iInitialSelection = 0; int32_t iInitialSelection = 0;
// Add free view // Add free view
AddRefSym(LoadResStr("IDS_MSG_FREEVIEW"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Star), "Observe:Free", C4MN_Item_NoCount, NULL, LoadResStr("IDS_MSG_FREELYSCROLLAROUNDTHEMAP")); AddRefSym(LoadResStr("IDS_MSG_FREEVIEW"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Star), "Observe:Free", LoadResStr("IDS_MSG_FREELYSCROLLAROUNDTHEMAP"));
// Add players // Add players
C4Player *pPlr; int32_t iIndex; C4Player *pPlr; int32_t iIndex;
for (iIndex=0; (pPlr = ::Players.GetByIndex(iIndex)); iIndex++) for (iIndex=0; (pPlr = ::Players.GetByIndex(iIndex)); iIndex++)
@ -246,7 +248,7 @@ bool C4MainMenu::DoRefillInternal(bool &rfRefilled)
StdStrBuf sInfo; StdStrBuf sInfo;
sInfo.Format(LoadResStr("IDS_TEXT_FOLLOWVIEWOFPLAYER"), pPlr->GetName()); sInfo.Format(LoadResStr("IDS_TEXT_FOLLOWVIEWOFPLAYER"), pPlr->GetName());
// Add item // Add item
Add(sMsg.getData(),fctSymbol,sCommand.getData(),C4MN_Item_NoCount,NULL,sInfo.getData()); Add(sMsg.getData(),fctSymbol,sCommand.getData(),sInfo.getData());
fctSymbol.Default(); fctSymbol.Default();
// check if this is the currently selected player // check if this is the currently selected player
if (pVP->GetPlayer() == pPlr->Number) iInitialSelection = GetItemCount()-1; if (pVP->GetPlayer() == pPlr->Number) iInitialSelection = GetItemCount()-1;
@ -288,12 +290,12 @@ void C4MainMenu::OnUserSelectItem(int32_t Player, int32_t iIndex)
SetSelection(iIndex, true, true); SetSelection(iIndex, true, true);
} }
void C4MainMenu::OnUserEnter(int32_t Player, int32_t iIndex, bool fRight) void C4MainMenu::OnUserEnter(int32_t Player, int32_t iIndex)
{ {
// direct menu control // direct menu control
// but ensure selection is Okay before // but ensure selection is Okay before
SetSelection(iIndex, true, false); SetSelection(iIndex, true, false);
Enter(fRight); Enter();
} }
void C4MainMenu::OnUserClose() void C4MainMenu::OnUserClose()
@ -339,7 +341,7 @@ bool C4MainMenu::ActivateGoals(int32_t iPlayer, bool fDoActivate)
::GraphicsResource.fctCaptain.Draw(fctGF); ::GraphicsResource.fctCaptain.Draw(fctGF);
} }
StdStrBuf Command; Command.Format("Player:Goal:%s", idGoal.ToString()); StdStrBuf Command; Command.Format("Player:Goal:%s", idGoal.ToString());
Add(pDef->GetName(),fctSymbol,Command.getData(),C4MN_Item_NoCount,NULL,""); Add(pDef->GetName(),fctSymbol,Command.getData(),"");
} }
// Go back to options menu on close // Go back to options menu on close
SetCloseCommand("ActivateMenu:Main"); SetCloseCommand("ActivateMenu:Main");
@ -363,7 +365,7 @@ bool C4MainMenu::ActivateRules(int32_t iPlayer)
{ {
fctSymbol.Create(C4SymbolSize,C4SymbolSize); pDef->Draw(fctSymbol); fctSymbol.Create(C4SymbolSize,C4SymbolSize); pDef->Draw(fctSymbol);
sprintf(Command, "Player:Rule:%s", idGoal.ToString()); sprintf(Command, "Player:Rule:%s", idGoal.ToString());
Add(pDef->GetName(),fctSymbol,Command,C4MN_Item_NoCount,NULL,""); Add(pDef->GetName(),fctSymbol,Command,"");
} }
// Go back to options menu on close // Go back to options menu on close
SetCloseCommand("ActivateMenu:Main"); SetCloseCommand("ActivateMenu:Main");
@ -458,7 +460,7 @@ bool C4MainMenu::ActivateSavegame(int32_t iPlayer)
// Item caption // Item caption
strCaption = LoadResStr("IDS_MENU_CPSAVEGAME"); strCaption = LoadResStr("IDS_MENU_CPSAVEGAME");
// add menu item // add menu item
AddRefSym(strCaption.getData(), GfxR->fctMenu.GetPhase(i - 1, fFree ? 2 : 1), strCommand.getData(), C4MN_Item_NoCount, NULL, LoadResStr("IDS_MENU_CPSAVEGAMEINFO")); AddRefSym(strCaption.getData(), GfxR->fctMenu.GetPhase(i - 1, fFree ? 2 : 1), strCommand.getData(), LoadResStr("IDS_MENU_CPSAVEGAMEINFO"));
} }
// Go back to options menu on close // Go back to options menu on close
@ -470,7 +472,7 @@ bool C4MainMenu::ActivateSavegame(int32_t iPlayer)
bool C4MainMenu::ActivateHost(int32_t iPlayer) bool C4MainMenu::ActivateHost(int32_t iPlayer)
{ {
// Menu symbol/init // Menu symbol/init
InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), LoadResStr("IDS_MENU_DISCONNECTCLIENT"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), LoadResStr("IDS_MENU_DISCONNECTCLIENT"), iPlayer, 0, C4MN_Style_Context);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
SetPermanent(true); SetPermanent(true);
// Clients // Clients
@ -490,27 +492,20 @@ bool C4MainMenu::ActivateHost(int32_t iPlayer)
bool C4MainMenu::ActivateClient(int32_t iPlayer) bool C4MainMenu::ActivateClient(int32_t iPlayer)
{ {
// Menu symbol/init InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), LoadResStr("IDS_MENU_DISCONNECTFROMSERVER"), iPlayer, 0, C4MN_Style_Context);
C4FacetSurface fctSymbol;
InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), LoadResStr("IDS_MENU_DISCONNECTFROMSERVER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
fctSymbol.Create(C4SymbolSize, C4SymbolSize); GfxR->fctOKCancel.Draw(fctSymbol,true,3,0); AddRefSym(LoadResStr("IDS_BTN_YES"), GfxR->fctOKCancel.GetPhase(3,0), "Part");
Add(LoadResStr("IDS_BTN_YES"), fctSymbol, "Part"); AddRefSym(LoadResStr("IDS_BTN_NO"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Close), "");
fctSymbol.Create(C4SymbolSize, C4SymbolSize); GfxR->fctOKCancel.Draw(fctSymbol,true,1,0);
Add(LoadResStr("IDS_BTN_NO"), fctSymbol, "");
SetCloseCommand("ActivateMenu:Main"); SetCloseCommand("ActivateMenu:Main");
return true; return true;
} }
bool C4MainMenu::ActivateSurrender(int32_t iPlayer) bool C4MainMenu::ActivateSurrender(int32_t iPlayer)
{ {
C4FacetSurface fctSymbol; InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Surrender), LoadResStr("IDS_MENU_SURRENDER"), iPlayer, 0, C4MN_Style_Context);
InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Surrender), LoadResStr("IDS_MENU_SURRENDER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
fctSymbol.Create(C4SymbolSize, C4SymbolSize); GfxR->fctOKCancel.Draw(fctSymbol,true,3,0); AddRefSym(LoadResStr("IDS_BTN_YES"), GfxR->fctOKCancel.GetPhase(3), "Surrender");
Add(LoadResStr("IDS_BTN_YES"), fctSymbol, "Surrender"); AddRefSym(LoadResStr("IDS_BTN_NO"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Close), "");
fctSymbol.Create(C4SymbolSize, C4SymbolSize); GfxR->fctOKCancel.Draw(fctSymbol,true,1,0);
Add(LoadResStr("IDS_BTN_NO"), fctSymbol, "");
SetCloseCommand("ActivateMenu:Main"); SetCloseCommand("ActivateMenu:Main");
return true; return true;
} }
@ -518,15 +513,12 @@ bool C4MainMenu::ActivateSurrender(int32_t iPlayer)
bool C4MainMenu::ActivateOptions(int32_t iPlayer, int32_t selection) bool C4MainMenu::ActivateOptions(int32_t iPlayer, int32_t selection)
{ {
// Menu symbol/init // Menu symbol/init
InitRefSym(GfxR->fctOptions.GetPhase(0), LoadResStr("IDS_MNU_OPTIONS"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); InitRefSym(GfxR->fctOptions.GetPhase(0), LoadResStr("IDS_MNU_OPTIONS"), iPlayer, 0, C4MN_Style_Context);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
SetPermanent(true); SetPermanent(true);
// Sound AddRefSym(LoadResStr("IDS_DLG_SOUND"), GfxR->fctOptions.GetPhase(17 + Config.Sound.RXSound),"Options:Sound");
AddRefSym(LoadResStr("IDS_DLG_SOUND"), GfxR->fctOptions.GetPhase(17 + Config.Sound.RXSound),"Options:Sound",C4MN_Item_NoCount); AddRefSym(LoadResStr("IDS_MNU_MUSIC"), GfxR->fctOptions.GetPhase(1 + Config.Sound.RXMusic),"Options:Music");
// Music AddRefSym(LoadResStr("IDS_MENU_DISPLAY"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_View), "ActivateMenu:Display");
AddRefSym(LoadResStr("IDS_MNU_MUSIC"), GfxR->fctOptions.GetPhase(1 + Config.Sound.RXMusic),"Options:Music",C4MN_Item_NoCount);
// Music
AddRefSym(LoadResStr("IDS_MENU_DISPLAY"), GfxR->fctMenu.GetPhase(8), "ActivateMenu:Display");
// Restore selection // Restore selection
SetSelection(selection, false, true); SetSelection(selection, false, true);
// Go back to main menu on close // Go back to main menu on close
@ -538,24 +530,24 @@ bool C4MainMenu::ActivateOptions(int32_t iPlayer, int32_t selection)
bool C4MainMenu::ActivateDisplay(int32_t iPlayer, int32_t selection) bool C4MainMenu::ActivateDisplay(int32_t iPlayer, int32_t selection)
{ {
// Menu symbol/init // Menu symbol/init
InitRefSym(GfxR->fctMenu.GetPhase(8), LoadResStr("IDS_MENU_DISPLAY"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context); InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_View), LoadResStr("IDS_MENU_DISPLAY"), iPlayer, 0, C4MN_Style_Context);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
SetPermanent(true); SetPermanent(true);
// Crew player names // Crew player names
AddRefSym(LoadResStr("IDS_MNU_PLAYERNAMES"), GfxR->fctOptions.GetPhase(7 + Config.Graphics.ShowCrewNames), "Display:PlayerNames", C4MN_Item_NoCount, NULL, LoadResStr("IDS_MENU_PLAYERNAMES_DESC")); AddRefSym(LoadResStr("IDS_MNU_PLAYERNAMES"), GfxR->fctOptions.GetPhase(7 + Config.Graphics.ShowCrewNames), "Display:PlayerNames", LoadResStr("IDS_MENU_PLAYERNAMES_DESC"));
// Crew clonk names // Crew clonk names
AddRefSym(LoadResStr("IDS_MNU_CLONKNAMES"), GfxR->fctOptions.GetPhase(9 + Config.Graphics.ShowCrewCNames), "Display:ClonkNames", C4MN_Item_NoCount, NULL, LoadResStr("IDS_MENU_CLONKNAMES_DESC")); AddRefSym(LoadResStr("IDS_MNU_CLONKNAMES"), GfxR->fctOptions.GetPhase(9 + Config.Graphics.ShowCrewCNames), "Display:ClonkNames", LoadResStr("IDS_MENU_CLONKNAMES_DESC"));
// Upper Board // Upper Board
if (!Application.isEditor) if (!Application.isEditor)
{ {
AddRefSym(LoadResStr("IDS_MNU_UPPERBOARD"),GfxR->fctOptions.GetPhase(3 + Config.Graphics.UpperBoard),"Display:UpperBoard",C4MN_Item_NoCount); AddRefSym(LoadResStr("IDS_MNU_UPPERBOARD"),GfxR->fctOptions.GetPhase(3 + Config.Graphics.UpperBoard),"Display:UpperBoard");
} }
// FPS // FPS
if (!Application.isEditor) if (!Application.isEditor)
AddRefSym(LoadResStr("IDS_MNU_FPS"), GfxR->fctOptions.GetPhase(5 + Config.General.FPS), "Display:FPS", C4MN_Item_NoCount); AddRefSym(LoadResStr("IDS_MNU_FPS"), GfxR->fctOptions.GetPhase(5 + Config.General.FPS), "Display:FPS");
// Clock // Clock
if (!Application.isEditor) if (!Application.isEditor)
AddRefSym(LoadResStr("IDS_MNU_CLOCK"), GfxR->fctOptions.GetPhase(15 + Config.Graphics.ShowClock), "Display:Clock", C4MN_Item_NoCount); AddRefSym(LoadResStr("IDS_MNU_CLOCK"), GfxR->fctOptions.GetPhase(15 + Config.Graphics.ShowClock), "Display:Clock");
// Restore selection // Restore selection
SetSelection(selection, false, true); SetSelection(selection, false, true);
// Go back to options menu on close // Go back to options menu on close
@ -569,10 +561,7 @@ bool C4MainMenu::ActivateMain(int32_t iPlayer)
// Determine player // Determine player
C4Player *pPlr = ::Players.Get(iPlayer); C4Player *pPlr = ::Players.Get(iPlayer);
// Menu symbol/init // Menu symbol/init
C4FacetSurface fctSymbol; InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Player), LoadResStr(pPlr ? "IDS_MENU_CPMAIN" : "IDS_MENU_OBSERVER"), iPlayer, 0, C4MN_Style_Context);
fctSymbol.Create(C4SymbolSize, C4SymbolSize);
GfxR->fctOKCancel.Draw(fctSymbol, true, 1, 1);
Init(fctSymbol, LoadResStr(pPlr ? "IDS_MENU_CPMAIN" : "IDS_MENU_OBSERVER"), iPlayer, C4MN_Extra_None, 0, 0, C4MN_Style_Context);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
// Goals+Rules (player menu only) // Goals+Rules (player menu only)
// Goal menu can't be shown because of script callbacks // Goal menu can't be shown because of script callbacks
@ -581,55 +570,55 @@ bool C4MainMenu::ActivateMain(int32_t iPlayer)
if (pPlr) if (pPlr)
{ {
// Goals // Goals
AddRefSym(LoadResStr("IDS_MENU_CPGOALS"),GfxR->fctMenu.GetPhase(4),"ActivateMenu:Goals",C4MN_Item_NoCount,NULL,LoadResStr("IDS_MENU_CPGOALSINFO")); AddRefSym(LoadResStr("IDS_MENU_CPGOALS"),GfxR->fctMenu.GetPhase(4),"ActivateMenu:Goals",LoadResStr("IDS_MENU_CPGOALSINFO"));
// Rules // Rules
AddRefSym(LoadResStr("IDS_MENU_CPRULES"),GfxR->fctMenu.GetPhase(5),"ActivateMenu:Rules",C4MN_Item_NoCount,NULL,LoadResStr("IDS_MENU_CPRULESINFO")); AddRefSym(LoadResStr("IDS_MENU_CPRULES"),GfxR->fctMenu.GetPhase(5),"ActivateMenu:Rules",LoadResStr("IDS_MENU_CPRULESINFO"));
} }
// Observer menu in free viewport // Observer menu in free viewport
if (!pPlr) if (!pPlr)
{ {
AddRefSym(LoadResStr("IDS_TEXT_VIEW"),C4GUI::Icon::GetIconFacet(C4GUI::Ico_View),"ActivateMenu:Observer",C4MN_Item_NoCount,NULL,LoadResStr("IDS_TEXT_DETERMINEPLAYERVIEWTOFOLL")); AddRefSym(LoadResStr("IDS_TEXT_VIEW"),C4GUI::Icon::GetIconFacet(C4GUI::Ico_View),"ActivateMenu:Observer",LoadResStr("IDS_TEXT_DETERMINEPLAYERVIEWTOFOLL"));
} }
// Hostility (player menu only) // Hostility (player menu only)
if (pPlr && (::Players.GetCount() > 1)) if (pPlr && (::Players.GetCount() > 1))
{ {
GfxR->fctFlagClr.Surface->SetClr(0xff0000); GfxR->fctFlagClr.Surface->SetClr(0xff0000);
AddRefSym(LoadResStr("IDS_MENU_CPATTACK"),GfxR->fctMenu.GetPhase(7),"ActivateMenu:Hostility",C4MN_Item_NoCount,NULL,LoadResStr("IDS_MENU_CPATTACKINFO")); AddRefSym(LoadResStr("IDS_MENU_CPATTACK"),C4GUI::Icon::GetIconFacet(C4GUI::Ico_MeleeLeague),"ActivateMenu:Hostility",LoadResStr("IDS_MENU_CPATTACKINFO"));
} }
// Team change // Team change
if (pPlr && Game.Teams.IsTeamSwitchAllowed()) if (pPlr && Game.Teams.IsTeamSwitchAllowed())
{ {
C4Facet fctTeams; fctTeams = C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team); C4Facet fctTeams; fctTeams = C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team);
AddRefSym(LoadResStr("IDS_MSG_SELTEAM"),fctTeams,"ActivateMenu:TeamSel",C4MN_Item_NoCount,NULL,LoadResStr("IDS_MSG_ALLOWSYOUTOJOINADIFFERENT")); AddRefSym(LoadResStr("IDS_MSG_SELTEAM"),fctTeams,"ActivateMenu:TeamSel",LoadResStr("IDS_MSG_ALLOWSYOUTOJOINADIFFERENT"));
} }
// Player join // Player join
if ((::Players.GetCount() < Game.Parameters.MaxPlayers) && !Game.Parameters.isLeague()) if ((::Players.GetCount() < Game.Parameters.MaxPlayers) && !Game.Parameters.isLeague())
{ {
AddRefSym(LoadResStr("IDS_MENU_CPNEWPLAYER"),GfxR->fctPlayerClr.GetPhase(),"ActivateMenu:NewPlayer",C4MN_Item_NoCount,NULL,LoadResStr("IDS_MENU_CPNEWPLAYERINFO")); AddRefSym(LoadResStr("IDS_MENU_CPNEWPLAYER"),GfxR->fctPlayerClr.GetPhase(),"ActivateMenu:NewPlayer",LoadResStr("IDS_MENU_CPNEWPLAYERINFO"));
} }
// Save game (player menu only - should we allow saving games with no players in it?) // Save game (player menu only - should we allow saving games with no players in it?)
if (pPlr && (!::Network.isEnabled() || ::Network.isHost())) if (pPlr && (!::Network.isEnabled() || ::Network.isHost()))
{ {
AddRefSym(LoadResStr("IDS_MENU_CPSAVEGAME"),GfxR->fctMenu.GetPhase(0),"ActivateMenu:Save:Game",C4MN_Item_NoCount,NULL,LoadResStr("IDS_MENU_CPSAVEGAMEINFO")); AddRefSym(LoadResStr("IDS_MENU_CPSAVEGAME"),GfxR->fctMenu.GetPhase(0),"ActivateMenu:Save:Game",LoadResStr("IDS_MENU_CPSAVEGAMEINFO"));
} }
// Options // Options
AddRefSym(LoadResStr("IDS_MNU_OPTIONS"), GfxR->fctOptions.GetPhase(0), "ActivateMenu:Options",C4MN_Item_NoCount, NULL, LoadResStr("IDS_MNU_OPTIONSINFO")); AddRefSym(LoadResStr("IDS_MNU_OPTIONS"), GfxR->fctOptions.GetPhase(0), "ActivateMenu:Options", LoadResStr("IDS_MNU_OPTIONSINFO"));
// Disconnect // Disconnect
if (::Network.isEnabled()) if (::Network.isEnabled())
{ {
// Host // Host
if (::Network.isHost() && Game.Clients.getClient(NULL)) if (::Network.isHost() && Game.Clients.getClient(NULL))
AddRefSym(LoadResStr("IDS_MENU_DISCONNECT"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), "ActivateMenu:Host", C4MN_Item_NoCount, NULL, LoadResStr("IDS_TEXT_KICKCERTAINCLIENTSFROMTHE")); AddRefSym(LoadResStr("IDS_MENU_DISCONNECT"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), "ActivateMenu:Host", LoadResStr("IDS_TEXT_KICKCERTAINCLIENTSFROMTHE"));
// Client // Client
if (!::Network.isHost()) if (!::Network.isHost())
AddRefSym(LoadResStr("IDS_MENU_DISCONNECT"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), "ActivateMenu:Client", C4MN_Item_NoCount, NULL, LoadResStr("IDS_TEXT_DISCONNECTTHEGAMEFROMTHES")); AddRefSym(LoadResStr("IDS_MENU_DISCONNECT"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Disconnect), "ActivateMenu:Client", LoadResStr("IDS_TEXT_DISCONNECTTHEGAMEFROMTHES"));
} }
// Surrender (player menu only) // Surrender (player menu only)
if (pPlr) if (pPlr)
AddRefSym(LoadResStr("IDS_MENU_CPSURRENDER"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Surrender), "ActivateMenu:Surrender", C4MN_Item_NoCount, NULL, LoadResStr("IDS_MENU_CPSURRENDERINFO")); AddRefSym(LoadResStr("IDS_MENU_CPSURRENDER"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Surrender), "ActivateMenu:Surrender", LoadResStr("IDS_MENU_CPSURRENDERINFO"));
// Abort // Abort
if (!Application.isEditor) if (!Application.isEditor)
AddRefSym(LoadResStr("IDS_MENU_ABORT"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Exit), "Abort", C4MN_Item_NoCount, NULL, LoadResStr("IDS_MENU_ABORT_DESC")); AddRefSym(LoadResStr("IDS_MENU_ABORT"), C4GUI::Icon::GetIconFacet(C4GUI::Ico_Exit), "Abort", LoadResStr("IDS_MENU_ABORT_DESC"));
// No empty menus // No empty menus
if (GetItemCount()==0) Close(false); if (GetItemCount()==0) Close(false);
// Done // Done
@ -639,10 +628,7 @@ bool C4MainMenu::ActivateMain(int32_t iPlayer)
bool C4MainMenu::ActivateHostility(int32_t iPlayer) bool C4MainMenu::ActivateHostility(int32_t iPlayer)
{ {
// Init menu // Init menu
C4FacetSurface fctSymbol; InitRefSym(GfxR->fctMenu.GetPhase(7), LoadResStr("IDS_MENU_CPATTACK"), iPlayer, C4MN_Hostility);
fctSymbol.Create(C4SymbolSize, C4SymbolSize);
GfxR->fctMenu.GetPhase(7).Draw(fctSymbol);
Init(fctSymbol, LoadResStr("IDS_MENU_CPATTACK"), iPlayer, C4MN_Extra_None, 0, C4MN_Hostility);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
SetPermanent(true); SetPermanent(true);
Refill(); Refill();
@ -875,7 +861,7 @@ bool C4MainMenu::ActivateObserver()
// Safety: Viewport lost? // Safety: Viewport lost?
if (!::Viewports.GetViewport(NO_OWNER)) return false; if (!::Viewports.GetViewport(NO_OWNER)) return false;
// Menu symbol/init // Menu symbol/init
InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_View), LoadResStr("IDS_TEXT_VIEW"), NO_OWNER, C4MN_Extra_None, 0, C4MN_Observer, C4MN_Style_Context); InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_View), LoadResStr("IDS_TEXT_VIEW"), NO_OWNER, C4MN_Observer, C4MN_Style_Context);
SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom); SetAlignment(C4MN_Align_Left | C4MN_Align_Bottom);
// Players added in Refill // Players added in Refill
Refill(); Refill();

View File

@ -41,8 +41,7 @@ protected:
int32_t Player; int32_t Player;
public: public:
bool Init(C4FacetSurface &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal); bool InitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal);
bool InitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iPlayer, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal);
bool ActivateMain(int32_t iPlayer); bool ActivateMain(int32_t iPlayer);
bool ActivateNewPlayer(int32_t iPlayer); bool ActivateNewPlayer(int32_t iPlayer);
@ -64,7 +63,7 @@ protected:
virtual void OnSelectionChanged(int32_t iNewSelection); virtual void OnSelectionChanged(int32_t iNewSelection);
virtual void OnUserSelectItem(int32_t Player, int32_t iIndex); virtual void OnUserSelectItem(int32_t Player, int32_t iIndex);
virtual void OnUserEnter(int32_t Player, int32_t iIndex, bool fRight); virtual void OnUserEnter(int32_t Player, int32_t iIndex);
virtual void OnUserClose(); virtual void OnUserClose();
virtual int32_t GetControllingPlayer() { return Player; } virtual int32_t GetControllingPlayer() { return Player; }

View File

@ -30,41 +30,23 @@
#include <C4PlayerList.h> #include <C4PlayerList.h>
#include <C4GameControl.h> #include <C4GameControl.h>
const int32_t C4MN_DefInfoWdt = 270, // default width of info windows
C4MN_DlgWdt = 270, // default width of dialog windows
C4MN_DlgLines = 5, // default number of text lines visible in a dialog window
C4MN_DlgLineMargin = 5, // px distance between text items
C4MN_DlgOptionLineMargin = 3, // px distance between dialog option items
C4MN_DlgPortraitWdt = 64, // size of portrait
C4MN_DlgPortraitIndent = 5; // space between portrait and text
const int32_t C4MN_InfoCaption_Delay = 90; const int32_t C4MN_InfoCaption_Delay = 90;
// ----------------------------------------------------------- // -----------------------------------------------------------
// C4MenuItem // C4MenuItem
C4MenuItem::C4MenuItem(C4Menu *pMenu, int32_t iIndex, const char *szCaption, C4MenuItem::C4MenuItem(C4Menu *pMenu, int32_t iIndex, const char *szCaption, const char *szCommand, const char *szInfoCaption, int32_t iStyle)
const char *szCommand, int32_t iCount, C4Object *pObject, const char *szInfoCaption, : C4GUI::Element(), pSymbolGraphics(NULL), dwSymbolClr(0u), fSelected(false),
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, int32_t iStyle, bool fIsSelectable) iStyle(iStyle), pMenu(pMenu), iIndex(iIndex)
: C4GUI::Element(), Count(iCount), id(idID), Object(pObject), pSymbolObj(NULL), pSymbolGraphics(NULL), dwSymbolClr(0u),
fOwnValue(fOwnValue), iValue(iValue), fSelected(false), iStyle(iStyle), pMenu(pMenu),
iIndex(iIndex), IsSelectable(fIsSelectable), TextDisplayProgress(-1)
{ {
*Caption=*Command=*Command2=*InfoCaption=0; *Caption=*Command=*InfoCaption=0;
Symbol.Default(); Symbol.Default();
SCopy(szCaption,Caption,C4MaxTitle); SCopy(szCaption,Caption,C4MaxTitle);
SCopy(szCommand,Command,_MAX_FNAME+30); SCopy(szCommand,Command,_MAX_FNAME+30);
SCopy(szCommand2,Command2,_MAX_FNAME+30);
SCopy(szInfoCaption,InfoCaption,C4MaxTitle); SCopy(szInfoCaption,InfoCaption,C4MaxTitle);
// some info caption corrections // some info caption corrections
SReplaceChar(InfoCaption, 10, ' '); SReplaceChar(InfoCaption, 13, '|'); SReplaceChar(InfoCaption, 10, ' '); SReplaceChar(InfoCaption, 13, '|');
SetToolTip(InfoCaption); SetToolTip(InfoCaption);
// components initialization
if (idID)
{
C4Def *pDef = C4Id2Def(idID);
if (pDef) pDef->GetComponents(&Components, NULL);
}
} }
C4MenuItem::~C4MenuItem() C4MenuItem::~C4MenuItem()
@ -72,53 +54,11 @@ C4MenuItem::~C4MenuItem()
Symbol.Clear(); Symbol.Clear();
} }
void C4MenuItem::DoTextProgress(int32_t &riByVal)
{
// any progress to be done?
if (TextDisplayProgress<0) return;
// if this is an option or empty text, show it immediately
if (IsSelectable || !*Caption) { TextDisplayProgress=-1; return; }
// normal text: move forward in unbroken message, ignoring markup
StdStrBuf sText(Caption);
C4Markup MarkupChecker(false);
const char *szPos = sText.getPtr(std::min<int>(TextDisplayProgress, sText.getLength()));
while (riByVal && *szPos)
{
MarkupChecker.SkipTags(&szPos);
if (!*szPos) break;
--riByVal;
// Advance one UTF-8 character
uint32_t c = GetNextCharacter(&szPos);
// Treat embedded images {{XXX}} as one entity
if(c == '{' && *szPos == '{')
{
int32_t end = SCharPos('}', szPos);
if(end > 0 && szPos[end+1] == '}')
szPos += end + 2;
}
}
if (!*szPos)
TextDisplayProgress=-1;
else
TextDisplayProgress = szPos - Caption;
}
bool C4MenuItem::IsDragElement()
{
// any constructibles can be dragged
C4Def *pDef = C4Id2Def(id);
return pDef && pDef->Constructable;
}
int32_t C4MenuItem::GetSymbolWidth(int32_t iForHeight) int32_t C4MenuItem::GetSymbolWidth(int32_t iForHeight)
{ {
// Context or dialog menus // Context menus
if (iStyle==C4MN_Style_Context || (iStyle==C4MN_Style_Dialog && Symbol.Surface)) if (iStyle==C4MN_Style_Context)
return std::max(Symbol.Wdt * iForHeight / std::max(Symbol.Hgt, 1.0f), static_cast<float>(iForHeight)); return std::max(Symbol.Wdt * iForHeight / std::max(Symbol.Hgt, 1.0f), static_cast<float>(iForHeight));
// Info menus
if (iStyle==C4MN_Style_Info && Symbol.Surface && Symbol.Wdt)
return Symbol.Wdt;
// no symbol // no symbol
return 0; return 0;
} }
@ -128,9 +68,8 @@ void C4MenuItem::DrawElement(C4TargetFacet &cgo)
// get target pos // get target pos
C4Facet cgoOut(cgo.Surface, cgo.TargetX + rcBounds.x, cgo.TargetY + rcBounds.y, rcBounds.Wdt, rcBounds.Hgt); C4Facet cgoOut(cgo.Surface, cgo.TargetX + rcBounds.x, cgo.TargetY + rcBounds.y, rcBounds.Wdt, rcBounds.Hgt);
// Select mark // Select mark
if (iStyle!=C4MN_Style_Info) if (fSelected)
if (fSelected && TextDisplayProgress) pDraw->DrawBoxDw(cgo.Surface, cgoOut.X, cgoOut.Y, cgoOut.X + cgoOut.Wdt - 1, cgoOut.Y + cgoOut.Hgt - 1, C4RGB(0xca, 0, 0));
pDraw->DrawBoxDw(cgo.Surface, cgoOut.X, cgoOut.Y, cgoOut.X + cgoOut.Wdt - 1, cgoOut.Y + cgoOut.Hgt - 1, C4RGB(0xca, 0, 0));
// Symbol/text areas // Symbol/text areas
C4Facet cgoItemSymbol,cgoItemText; C4Facet cgoItemSymbol,cgoItemText;
cgoItemSymbol=cgoItemText=cgoOut; cgoItemSymbol=cgoItemText=cgoOut;
@ -146,80 +85,29 @@ void C4MenuItem::DrawElement(C4TargetFacet &cgo)
C4Facet cgoSymbolOut(cgoItemSymbol.Surface, cgoItemSymbol.X, cgoItemSymbol.Y, cgoItemSymbol.Wdt, cgoItemSymbol.Wdt); C4Facet cgoSymbolOut(cgoItemSymbol.Surface, cgoItemSymbol.X, cgoItemSymbol.Y, cgoItemSymbol.Wdt, cgoItemSymbol.Wdt);
// Draw item symbol: // Draw item symbol:
// Draw if there is no text progression at all (TextDisplayProgress==-1, or if it's progressed far enough already (TextDisplayProgress>0) if (pSymbolGraphics)
if(pSymbolObj && TextDisplayProgress)
{
pSymbolObj->DrawPicture(cgoSymbolOut, false, NULL);
}
else if (pSymbolGraphics && TextDisplayProgress)
{ {
pSymbolGraphics->Draw(cgoSymbolOut, dwSymbolClr ? dwSymbolClr : 0xffffffff, NULL, 0, 0, NULL); pSymbolGraphics->Draw(cgoSymbolOut, dwSymbolClr ? dwSymbolClr : 0xffffffff, NULL, 0, 0, NULL);
} }
else if (Symbol.Surface && TextDisplayProgress) else if (Symbol.Surface)
Symbol.DrawClr(cgoItemSymbol, true, dwSymbolClr); Symbol.DrawClr(cgoItemSymbol, true, dwSymbolClr);
// Draw item text // Draw item text
pDraw->StorePrimaryClipper(); pDraw->SubPrimaryClipper(cgoItemText.X, cgoItemText.Y, cgoItemText.X+cgoItemText.Wdt-1, cgoItemText.Y+cgoItemText.Hgt-1); pDraw->StorePrimaryClipper(); pDraw->SubPrimaryClipper(cgoItemText.X, cgoItemText.Y, cgoItemText.X+cgoItemText.Wdt-1, cgoItemText.Y+cgoItemText.Hgt-1);
switch (iStyle) if (iStyle == C4MN_Style_Context)
{ pDraw->TextOut(Caption, ::GraphicsResource.FontRegular, 1.0f, cgoItemText.Surface,
case C4MN_Style_Context: cgoItemText.X + C4GUI_IconLabelSpacing,
pDraw->TextOut(Caption,::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface,cgoItemText.X,cgoItemText.Y,C4Draw::DEFAULT_MESSAGE_COLOR,ALeft); cgoItemText.Y + round((cgoItemText.Hgt - ::GraphicsResource.FontRegular.GetLineHeight())/2)-1,
break; C4GUI_ContextFontClr);
case C4MN_Style_Info:
{
StdStrBuf sText;
::GraphicsResource.FontRegular.BreakMessage(InfoCaption, cgoItemText.Wdt, &sText, true);
pDraw->TextOut(sText.getData(), ::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface,cgoItemText.X,cgoItemText.Y);
break;
}
case C4MN_Style_Dialog:
{
// cut buffer at text display pos
char cXChg='\0'; int iStopPos = 0;
if (TextDisplayProgress>-1)
{
iStopPos = std::min<int>(TextDisplayProgress, strlen(Caption));
cXChg = Caption[iStopPos];
Caption[iStopPos] = '\0';
}
// display broken text
StdStrBuf sText;
::GraphicsResource.FontRegular.BreakMessage(Caption, cgoItemText.Wdt, &sText, true);
pDraw->TextOut(sText.getData(),::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface,cgoItemText.X,cgoItemText.Y);
// restore complete text
if (cXChg) Caption[iStopPos] = cXChg;
break;
}
}
pDraw->RestorePrimaryClipper(); pDraw->RestorePrimaryClipper();
// Draw count
if (Count!=C4MN_Item_NoCount)
{
char szCount[10+1];
sprintf(szCount,"%ix",Count);
pDraw->TextOut(szCount, ::GraphicsResource.FontRegular, 1.0, cgoItemText.Surface, cgoItemText.X+cgoItemText.Wdt-1, cgoItemText.Y+cgoItemText.Hgt-1-::GraphicsResource.FontRegular.GetLineHeight(), C4Draw::DEFAULT_MESSAGE_COLOR, ARight);
}
} }
void C4MenuItem::MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam) void C4MenuItem::MouseInput(C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam)
{ {
// clicky clicky! // clicky clicky!
if (iButton == C4MC_Button_LeftDown) if (iButton == C4MC_Button_LeftUp || iButton == C4MC_Button_RightUp)
{ {
// button down: Init drag only; Enter selection only by button up pMenu->UserEnter(::MouseControl.GetPlayer(), this);
if (IsDragElement())
StartDragging(rMouse, iX, iY, dwKeyParam);
}
else if (iButton == C4MC_Button_LeftUp)
{
// left-click performed
pMenu->UserEnter(::MouseControl.GetPlayer(), this, false);
return;
}
else if (iButton == C4MC_Button_RightUp)
{
// right-up: Alternative enter command
pMenu->UserEnter(::MouseControl.GetPlayer(), this, true);
return; return;
} }
// inherited; this is just setting some vars // inherited; this is just setting some vars
@ -257,17 +145,11 @@ void C4Menu::Default()
Symbol.Default(); Symbol.Default();
Caption[0]=0; Caption[0]=0;
Permanent=false; Permanent=false;
Extra=C4MN_Extra_None;
ExtraData=0;
TimeOnSelection=0; TimeOnSelection=0;
Identification=0; Identification=0;
LocationSet=false; LocationSet=false;
Columns=Lines=0; Columns=Lines=0;
Alignment= C4MN_Align_Right | C4MN_Align_Bottom; Alignment= C4MN_Align_Right | C4MN_Align_Bottom;
VisibleCount=0;
fHasPortrait = false;
fTextProgressing = false;
fEqualIconItemHeight = false;
CloseCommand.Clear(); CloseCommand.Clear();
fActive = false; fActive = false;
} }
@ -301,122 +183,62 @@ bool C4Menu::TryClose(bool fOK, bool fControl)
return true; return true;
} }
bool C4Menu::DoInit(C4FacetSurface &fctSymbol, const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) bool C4Menu::DoInitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iId, int32_t iStyle)
{
Clear(); Default();
Symbol.GrabFrom(fctSymbol);
return InitMenu(szEmpty, iExtra, iExtraData, iId, iStyle);
}
bool C4Menu::DoInitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle)
{ {
Clear(); Default(); Clear(); Default();
Symbol.Set(fctSymbol); Symbol.Set(fctSymbol);
return InitMenu(szEmpty, iExtra, iExtraData, iId, iStyle); return InitMenu(szEmpty, iId, iStyle);
} }
bool C4Menu::InitMenu(const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle) bool C4Menu::InitMenu(const char *szEmpty, int32_t iId, int32_t iStyle)
{ {
SCopy(szEmpty,Caption,C4MaxTitle); SCopy(szEmpty,Caption,C4MaxTitle);
Extra=iExtra; ExtraData=iExtraData;
Identification=iId; Identification=iId;
if (*Caption || iStyle == C4MN_Style_Dialog) SetTitle(Caption, HasMouse()); else SetTitle(" ", HasMouse()); if (*Caption) SetTitle(Caption, HasMouse()); else SetTitle(" ", HasMouse());
if (pTitle) pTitle->SetIcon(Symbol); if (pTitle) pTitle->SetIcon(Symbol);
Style=iStyle & C4MN_Style_BaseMask; Style=iStyle;
// Menus are synchronous to allow COM_MenuUp/Down to be converted to movements at the clients // Menus are synchronous to allow COM_MenuUp/Down to be converted to movements at the clients
if (Style == C4MN_Style_Normal) if (Style == C4MN_Style_Normal)
Columns = 5; Columns = 5;
else else
// in reality, Dialog menus may have two coloumns (first for the portrait)
// however, they are not uniformly spaced and stuff; so they are better just ignored and handled by the drawing routine
Columns=1; Columns=1;
if (iStyle & C4MN_Style_EqualItemHeight) SetEqualItemHeight(true);
if (Style == C4MN_Style_Dialog) Alignment = C4MN_Align_Top;
::pGUI->ShowDialog(this, false); ::pGUI->ShowDialog(this, false);
fTextProgressing = false;
fActive = true; fActive = true;
return true; return true;
} }
bool C4Menu::AddRefSym(const char *szCaption, const C4Facet &fctSymbol, const char *szCommand, bool C4Menu::AddRefSym(const char *szCaption, const C4Facet &fctSymbol, const char *szCommand, const char *szInfoCaption)
int32_t iCount, C4Object *pObject, const char *szInfoCaption,
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable)
{ {
if (!IsActive()) return false; if (!IsActive()) return false;
// Create new menu item // Create new menu item
C4MenuItem *pNew = new C4MenuItem(this, ItemCount, szCaption,szCommand,iCount,pObject,szInfoCaption,idID,szCommand2,fOwnValue,iValue,Style,fIsSelectable); C4MenuItem *pNew = new C4MenuItem(this, ItemCount, szCaption,szCommand,szInfoCaption,Style);
// Ref Symbol // Ref Symbol
pNew->RefSymbol(fctSymbol); pNew->RefSymbol(fctSymbol);
// Add // Add
return AddItem(pNew, szCaption, szCommand, iCount, pObject, szInfoCaption, idID, szCommand2, fOwnValue, iValue, fIsSelectable); return AddItem(pNew, szCaption, szCommand, szInfoCaption);
} }
bool C4Menu::Add(const char *szCaption, C4FacetSurface &fctSymbol, const char *szCommand, bool C4Menu::Add(const char *szCaption, C4FacetSurface &fctSymbol, const char *szCommand, const char *szInfoCaption)
int32_t iCount, C4Object *pObject, const char *szInfoCaption,
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable)
{ {
if (!IsActive()) return false; if (!IsActive()) return false;
// Create new menu item // Create new menu item
C4MenuItem *pNew = new C4MenuItem(this, ItemCount, szCaption,szCommand,iCount,pObject,szInfoCaption,idID,szCommand2,fOwnValue,iValue,Style,fIsSelectable); C4MenuItem *pNew = new C4MenuItem(this, ItemCount, szCaption,szCommand,szInfoCaption,Style);
// Set Symbol // Set Symbol
pNew->GrabSymbol(fctSymbol); pNew->GrabSymbol(fctSymbol);
// Add // Add
return AddItem(pNew, szCaption, szCommand, iCount, pObject, szInfoCaption, idID, szCommand2, fOwnValue, iValue, fIsSelectable); return AddItem(pNew, szCaption, szCommand, szInfoCaption);
} }
bool C4Menu::Add(const char *szCaption, C4Object* pGfxObj, const char *szCommand, bool C4Menu::AddItem(C4MenuItem *pNew, const char *szCaption, const char *szCommand, const char *szInfoCaption)
int32_t iCount, C4Object *pObject, const char *szInfoCaption,
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable)
{ {
if (!IsActive()) return false;
// Create new menu item
C4MenuItem *pNew = new C4MenuItem(this, ItemCount, szCaption,szCommand,iCount,pObject,szInfoCaption,idID,szCommand2,fOwnValue,iValue,Style,fIsSelectable);
// Set Symbol
pNew->SetGraphics(pGfxObj);
// Add
return AddItem(pNew, szCaption, szCommand, iCount, pObject, szInfoCaption, idID, szCommand2, fOwnValue, iValue, fIsSelectable);
}
bool C4Menu::Add(const char *szCaption, C4DefGraphics* pGfx, const char *szCommand,
int32_t iCount, C4Object *pObject, const char *szInfoCaption,
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable)
{
if (!IsActive()) return false;
// Create new menu item
C4MenuItem *pNew = new C4MenuItem(this, ItemCount, szCaption,szCommand,iCount,pObject,szInfoCaption,idID,szCommand2,fOwnValue,iValue,Style,fIsSelectable);
// Set Symbol
pNew->SetGraphics(pGfx);
// Add
return AddItem(pNew, szCaption, szCommand, iCount, pObject, szInfoCaption, idID, szCommand2, fOwnValue, iValue, fIsSelectable);
}
bool C4Menu::AddItem(C4MenuItem *pNew, const char *szCaption, const char *szCommand,
int32_t iCount, C4Object *pObject, const char *szInfoCaption,
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable)
{
#ifdef DEBUGREC_MENU
if (Config.General.DebugRec)
if (pObject)
{
C4RCMenuAdd rc = { pObject ? pObject->Number : -1, iCount, idID, fOwnValue, iValue, fIsSelectable };
AddDbgRec(RCT_MenuAdd, &rc, sizeof(C4RCMenuAdd));
if (szCommand) AddDbgRec(RCT_MenuAddC, szCommand, strlen(szCommand)+1);
if (szCommand2) AddDbgRec(RCT_MenuAddC, szCommand2, strlen(szCommand2)+1);
}
#endif
// Add it to the list // Add it to the list
pClientWindow->AddElement(pNew); pClientWindow->AddElement(pNew);
// first menuitem is portrait, if it does not have text but a facet
if (!ItemCount && (!szCaption || !*szCaption))
fHasPortrait = true;
// Item count // Item count
ItemCount++; ItemCount++;
// set new item size // set new item size
if (!pClientWindow->IsFrozen()) UpdateElementPositions(); if (!pClientWindow->IsFrozen()) UpdateElementPositions();
// Init selection if not frozen // Init selection if not frozen
if (Selection==-1 && fIsSelectable && !pClientWindow->IsFrozen()) SetSelection(ItemCount-1, false, false); if (Selection==-1 && !pClientWindow->IsFrozen()) SetSelection(ItemCount-1, false, false);
// initial progress
if (fTextProgressing) pNew->TextDisplayProgress = 0;
// adjust scrolling, etc. // adjust scrolling, etc.
UpdateScrollBar(); UpdateScrollBar();
// Success // Success
@ -430,7 +252,6 @@ bool C4Menu::Control(BYTE byCom, int32_t iData)
switch (byCom) switch (byCom)
{ {
case COM_MenuEnter: Enter(); break; case COM_MenuEnter: Enter(); break;
case COM_MenuEnterAll: Enter(true); break;
case COM_MenuClose: TryClose(false, true); break; case COM_MenuClose: TryClose(false, true); break;
// organize with nicer subfunction... // organize with nicer subfunction...
@ -464,13 +285,6 @@ bool C4Menu::Control(BYTE byCom, int32_t iData)
iData-=Columns; iData-=Columns;
MoveSelection(iData, true, true); MoveSelection(iData, true, true);
break; break;
case COM_MenuSelect:
if (ItemCount)
SetSelection(iData & (~C4MN_AdjustPosition), !!(iData & C4MN_AdjustPosition), true);
break;
case COM_MenuShowText:
SetTextProgress(-1, false);
break;
} }
return true; return true;
@ -488,23 +302,17 @@ bool C4Menu::IsActive()
return fActive; return fActive;
} }
bool C4Menu::Enter(bool fRight) bool C4Menu::Enter()
{ {
// Not active // Not active
if (!IsActive()) return false; if (!IsActive()) return false;
if (Style==C4MN_Style_Info) return false;
// Get selected item // Get selected item
C4MenuItem *pItem = GetSelectedItem(); C4MenuItem *pItem = GetSelectedItem();
if (!pItem) if (!pItem)
{
// okay for dialogs: Just close them
if (Style == C4MN_Style_Dialog) TryClose(false, true);
return true; return true;
}
// Copy command to buffer (menu might be cleared) // Copy command to buffer (menu might be cleared)
char szCommand[_MAX_FNAME+30+1]; char szCommand[_MAX_FNAME+30+1];
SCopy(pItem->Command,szCommand); SCopy(pItem->Command,szCommand);
if (fRight && pItem->Command2[0]) SCopy(pItem->Command2,szCommand);
// Close if not permanent // Close if not permanent
if (!Permanent) { Close(true); fActive = false; } if (!Permanent) { Close(true); fActive = false; }
@ -536,12 +344,8 @@ bool C4Menu::MoveSelection(int32_t iBy, bool fAdjustPosition, bool fDoCalls)
iNewSel += iBy; iNewSel += iBy;
// selection is out of menu range // selection is out of menu range
if (!Inside<int32_t>(iNewSel, 0, ItemCount-1)) return false; if (!Inside<int32_t>(iNewSel, 0, ItemCount-1)) return false;
// determine newly selected item
C4MenuItem *pNewSel = GetItem(iNewSel);
// nothing selectable
if (!pNewSel || !pNewSel->IsSelectable) continue;
// got something: go select it // got something: go select it
break; if (GetItem(iNewSel)) break;
} }
// select it // select it
return !!SetSelection(iNewSel, fAdjustPosition, fDoCalls); return !!SetSelection(iNewSel, fAdjustPosition, fDoCalls);
@ -553,7 +357,7 @@ bool C4Menu::SetSelection(int32_t iSelection, bool fAdjustPosition, bool fDoCall
if (!IsActive()) return false; if (!IsActive()) return false;
// Outside Limits / Selectable // Outside Limits / Selectable
C4MenuItem *pNewSel = GetItem(iSelection); C4MenuItem *pNewSel = GetItem(iSelection);
if ((iSelection==-1 && !ItemCount) || (pNewSel && pNewSel->IsSelectable)) if ((iSelection==-1 && !ItemCount) || pNewSel)
{ {
// Selection change // Selection change
if (iSelection!=Selection) if (iSelection!=Selection)
@ -629,102 +433,36 @@ void C4Menu::SetSize(int32_t iToWdt, int32_t iToHgt)
void C4Menu::InitLocation(C4Facet &cgoArea) void C4Menu::InitLocation(C4Facet &cgoArea)
{ {
ItemWidth=ItemHeight=C4SymbolSize;
// Item size by style if (Style == C4MN_Style_Context)
switch (Style)
{ {
case C4MN_Style_Normal: ItemHeight = std::max<int32_t>(ItemHeight, ::GraphicsResource.FontRegular.GetLineHeight());
ItemWidth=ItemHeight=C4SymbolSize;
break;
case C4MN_Style_Context:
{
ItemHeight = std::max<int32_t>(C4MN_SymbolSize, ::GraphicsResource.FontRegular.GetLineHeight());
int32_t iWdt, iHgt; int32_t iWdt, iHgt;
::GraphicsResource.FontRegular.GetTextExtent(Caption, ItemWidth, iHgt, true); ::GraphicsResource.FontRegular.GetTextExtent(Caption, iWdt, iHgt, true);
// FIXME: Blah. This stuff should be calculated correctly by pTitle. // FIXME: Blah. This stuff should be calculated correctly by pTitle.
ItemWidth += ItemHeight + 16; ItemWidth += iWdt + 20 + C4GUI_IconLabelSpacing;
C4MenuItem *pItem; C4MenuItem *pItem;
for (int i = 0; (pItem = GetItem(i)); ++i) for (int i = 0; (pItem = GetItem(i)); ++i)
{ {
::GraphicsResource.FontRegular.GetTextExtent(pItem->Caption, iWdt, iHgt, true); ::GraphicsResource.FontRegular.GetTextExtent(pItem->Caption, iWdt, iHgt, true);
ItemWidth = std::max(ItemWidth, iWdt + pItem->GetSymbolWidth(ItemHeight)); ItemWidth = std::max(ItemWidth, iWdt + pItem->GetSymbolWidth(ItemHeight) + C4GUI_IconLabelSpacing);
} }
ItemWidth += 3; // Add some extra space so text doesn't touch right border frame... ItemWidth += 3; // Add some extra space so text doesn't touch right border frame...
break;
}
case C4MN_Style_Info:
{
// calculate size from a default size determined by a window width of C4MN_DefInfoWdt
int32_t iWdt,iHgt,iLargestTextWdt;
::GraphicsResource.FontRegular.GetTextExtent(Caption,iWdt,iHgt, true);
iLargestTextWdt = iWdt + 2 * C4MN_SymbolSize + C4MN_FrameWidth;
ItemWidth=std::min<int>(cgoArea.Wdt - 2*C4MN_FrameWidth, std::max(iLargestTextWdt, C4MN_DefInfoWdt));
ItemHeight=0;
StdStrBuf sText;
C4MenuItem *pItem;
for (int32_t i=0; (pItem=GetItem(i)); ++i)
{
::GraphicsResource.FontRegular.BreakMessage(pItem->InfoCaption, ItemWidth, &sText, true);
::GraphicsResource.FontRegular.GetTextExtent(sText.getData(),iWdt,iHgt, true);
assert(iWdt <= ItemWidth);
ItemWidth=std::max(ItemWidth,iWdt); ItemHeight=std::max(ItemHeight,iHgt);
iLargestTextWdt = std::max(iLargestTextWdt, iWdt);
}
// although width calculation is done from C4MN_DefInfoWdt, this may be too large for some very tiny info windows
// so make sure no space is wasted
ItemWidth = std::min(ItemWidth, iLargestTextWdt);
// Add some extra space so text doesn't touch right border frame...
ItemWidth += 3;
// Now add some space to show the picture on the left
ItemWidth += C4PictureSize;
// And set a minimum item height (again, for the picture)
ItemHeight = std::max<int>(ItemHeight, C4PictureSize);
break;
} }
case C4MN_Style_Dialog: Lines = ItemCount/Columns+std::min<int32_t>(ItemCount%Columns,1);
{
// dialog window: Item width is whole dialog, portrait subtracted if any
// Item height varies
int32_t iWdt,iHgt;
::GraphicsResource.FontRegular.GetTextExtent(Caption,iWdt,iHgt, true);
ItemWidth=std::min<int>(cgoArea.Wdt - 2*C4MN_FrameWidth, std::max<int>(iWdt + 2 * C4MN_SymbolSize + C4MN_FrameWidth, C4MN_DlgWdt));
ItemHeight=iHgt; // Items may be multiline and higher
if (HasPortrait())
{
// subtract portrait only if this would not make the dialog too small
if (ItemWidth > C4MN_DlgPortraitWdt*2 && cgoArea.Hgt > cgoArea.Wdt)
ItemWidth = std::max<int>(ItemWidth - C4MN_DlgPortraitWdt - C4MN_DlgPortraitIndent, 40);
}
}
}
int DisplayedItemCount = ItemCount - HasPortrait();
if (Style == C4MN_Style_Dialog)
Lines = C4MN_DlgLines;
else
Lines = DisplayedItemCount/Columns+std::min<int32_t>(DisplayedItemCount%Columns,1);
// adjust by max. height // adjust by max. height
Lines=std::max<int32_t>(std::min<int32_t>((cgoArea.Hgt-100)/std::max<int32_t>(ItemHeight,1),Lines),1); Lines=std::max<int32_t>(std::min<int32_t>((cgoArea.Hgt-100)/std::max<int32_t>(ItemHeight,1),Lines),1);
InitSize(); InitSize();
int32_t X,Y; int32_t X,Y;
if (Alignment & C4MN_Align_Free) X = (cgoArea.Wdt - rcBounds.Wdt)/2;
{ Y = (cgoArea.Hgt - rcBounds.Hgt)/2;
X = rcBounds.x;
Y = rcBounds.y;
}
else
{
X = (cgoArea.Wdt - rcBounds.Wdt)/2;
Y = (cgoArea.Hgt - rcBounds.Hgt)/2;
}
// Alignment // Alignment
if (Alignment & C4MN_Align_Left) X=C4SymbolSize; if (Alignment & C4MN_Align_Left) X=C4SymbolSize;
if (Alignment & C4MN_Align_Right) X=cgoArea.Wdt-2*C4SymbolSize-rcBounds.Wdt; if (Alignment & C4MN_Align_Right) X=cgoArea.Wdt-2*C4SymbolSize-rcBounds.Wdt;
if (Alignment & C4MN_Align_Top) Y=C4SymbolSize; if (Alignment & C4MN_Align_Top) Y=C4SymbolSize;
if (Alignment & C4MN_Align_Bottom) Y=cgoArea.Hgt-C4SymbolSize-rcBounds.Hgt; if (Alignment & C4MN_Align_Bottom) Y=cgoArea.Hgt-C4SymbolSize-rcBounds.Hgt;
if (Alignment & C4MN_Align_Free) { X=Clamp<int32_t>(X,0,cgoArea.Wdt-rcBounds.Wdt); Y=Clamp<int32_t>(Y,0,cgoArea.Hgt-rcBounds.Hgt); }
// Centered (due to small viewport size) // Centered (due to small viewport size)
if (rcBounds.Wdt>cgoArea.Wdt-2*C4SymbolSize) X=(cgoArea.Wdt-rcBounds.Wdt)/2; if (rcBounds.Wdt>cgoArea.Wdt-2*C4SymbolSize) X=(cgoArea.Wdt-rcBounds.Wdt)/2;
if (rcBounds.Hgt>cgoArea.Hgt-2*C4SymbolSize) Y=(cgoArea.Hgt-rcBounds.Hgt)/2; if (rcBounds.Hgt>cgoArea.Hgt-2*C4SymbolSize) Y=(cgoArea.Hgt-rcBounds.Hgt)/2;
@ -749,17 +487,8 @@ void C4Menu::InitSize()
int Width, Height; int Width, Height;
Width=Columns*ItemWidth; Width=Columns*ItemWidth;
Height=Lines*ItemHeight; Height=Lines*ItemHeight;
VisibleCount = Columns*Lines;
bool fBarNeeded; bool fBarNeeded;
if (HasPortrait()) Width += C4MN_DlgPortraitWdt + C4MN_DlgPortraitIndent; fBarNeeded = pLast && pLast->GetBounds().y + pLast->GetBounds().Hgt > pClientWindow->GetBounds().Hgt;
// dialogs have auto-enlarge vertically
if (pLast && Style == C4MN_Style_Dialog)
{
Height = std::max<int>(Height, pLast->GetBounds().y + pLast->GetBounds().Hgt + C4MN_DlgLineMargin);
fBarNeeded = false;
}
else
fBarNeeded = pLast && pLast->GetBounds().y + pLast->GetBounds().Hgt > pClientWindow->GetBounds().Hgt;
// add dlg margins // add dlg margins
Width += GetMarginLeft() + GetMarginRight() + pClientWindow->GetMarginLeft() + pClientWindow->GetMarginRight(); Width += GetMarginLeft() + GetMarginRight() + pClientWindow->GetMarginLeft() + pClientWindow->GetMarginRight();
Height += GetMarginTop() + GetMarginBottom() + pClientWindow->GetMarginTop() + pClientWindow->GetMarginBottom(); Height += GetMarginTop() + GetMarginBottom() + pClientWindow->GetMarginTop() + pClientWindow->GetMarginBottom();
@ -794,67 +523,16 @@ void C4Menu::Draw(C4TargetFacet &cgo)
ParentClass::Draw(cgo); ParentClass::Draw(cgo);
// draw tooltip if selection time has been long enough // draw tooltip if selection time has been long enough
if (!fTextProgressing) ++TimeOnSelection; ++TimeOnSelection;
if (TimeOnSelection >= C4MN_InfoCaption_Delay) if (TimeOnSelection >= C4MN_InfoCaption_Delay && !::Control.isReplay() && !::pGUI->Mouse.IsActiveInput())
if (Style != C4MN_Style_Info) // No tooltips in info menus - doesn't make any sense...
if (!::Control.isReplay())
if (!::pGUI->Mouse.IsActiveInput())
{
C4MenuItem *pSel = GetSelectedItem();
if (pSel && *pSel->InfoCaption)
{
int32_t iX=0, iY=0;
pSel->ClientPos2ScreenPos(iX, iY);
C4GUI::Screen::DrawToolTip(pSel->InfoCaption, cgo, iX, iY);
}
}
}
void C4Menu::DrawElement(C4TargetFacet &cgo)
{
// inherited (background)
typedef C4GUI::Dialog ParentClass;
ParentClass::DrawElement(cgo);
// Get selected item id
C4ID idSelected; C4MenuItem *pItem;
if ((pItem = GetSelectedItem())) idSelected = pItem->id; else idSelected = C4ID::None;
C4Def *pDef = C4Id2Def(idSelected);
// Get item value
int32_t iValue = 0;
if (pDef)
{ {
if (pItem && pItem->fOwnValue) C4MenuItem *pSel = GetSelectedItem();
iValue = pItem->iValue; if (pSel && *pSel->InfoCaption)
else {
iValue = pDef->GetValue(NULL, NO_OWNER); int32_t iX=0, iY=0;
} pSel->ClientPos2ScreenPos(iX, iY);
C4GUI::Screen::DrawToolTip(pSel->InfoCaption, cgo, iX, iY);
// Store and clear global clipper }
// int32_t iX1,iY1,iX2,iY2;
// pDraw->GetPrimaryClipper(iX1,iY1,iX2,iY2);
// pDraw->SubPrimaryClipper(rcBounds.x, rcBounds.y, rcBounds.x+rcBounds.Wdt-1, rcBounds.y+rcBounds.Hgt-1);
C4Facet cgoExtra(cgo.Surface, cgo.TargetX+rcBounds.x+1, cgo.TargetY+rcBounds.y+rcBounds.Hgt-C4MN_SymbolSize-1, rcBounds.Wdt-2, C4MN_SymbolSize);
// Draw bar divider
if (Extra)
{
DrawFrame(cgoExtra.Surface, cgoExtra.X-1, cgoExtra.Y-1, cgoExtra.Wdt+1, cgoExtra.Hgt+1);
}
// Draw specified extra
switch (Extra)
{
case C4MN_Extra_Components:
if (pItem) pItem->Components.Draw(cgoExtra,-1,::Definitions,C4D_All,true,C4FCT_Right | C4FCT_Triple | C4FCT_Half);
break;
case C4MN_Extra_Value:
{
if (pDef) ::GraphicsResource.fctWealth.DrawValue(cgoExtra,iValue,0,0,C4FCT_Right);
}
break;
} }
} }
@ -916,9 +594,6 @@ void C4Menu::Execute()
if (!Game.iTick35 || NeedRefill) if (!Game.iTick35 || NeedRefill)
if (!RefillInternal()) if (!RefillInternal())
Close(false); Close(false);
// text progress
if (fTextProgressing)
SetTextProgress(+1, true);
} }
bool C4Menu::Refill() bool C4Menu::Refill()
@ -936,19 +611,17 @@ void C4Menu::AdjustSelection()
// selection valid? // selection valid?
C4MenuItem *pSelection = GetItem(Selection); C4MenuItem *pSelection = GetItem(Selection);
int iSel = Selection; int iSel = Selection;
if (!pSelection || !pSelection->IsSelectable) if (!pSelection)
{ {
// set to new first valid selection: Downwards first // set to new first valid selection: Downwards first
iSel = Selection; iSel = Selection;
while (--iSel>=0) while (--iSel>=0)
if ((pSelection = GetItem(iSel))) if ((pSelection = GetItem(iSel)))
if (pSelection->IsSelectable) break;
break;
// no success: upwards then // no success: upwards then
if (iSel<0) if (iSel<0)
for (iSel=Selection+1; (pSelection = GetItem(iSel)); ++iSel) for (iSel=Selection+1; (pSelection = GetItem(iSel)); ++iSel)
if (pSelection->IsSelectable) break;
break;
} }
// set it then // set it then
if (!pSelection) if (!pSelection)
@ -957,38 +630,6 @@ void C4Menu::AdjustSelection()
SetSelection(iSel, iSel != Selection, true); SetSelection(iSel, iSel != Selection, true);
} }
bool C4Menu::ConvertCom(int32_t &rCom, int32_t &rData, bool fAsyncConversion)
{
// This function converts normal Coms to menu Coms before they are send to the queue
// Menu not active
if (!IsActive()) return false;
// Convert plain com control to menu com
switch (rCom)
{
// Convert recognized menu coms
case COM_Throw: rCom = COM_MenuEnter; break;
case COM_Dig: rCom = COM_MenuClose; break;
case COM_Special2: rCom = COM_MenuEnterAll; break;
case COM_Up: rCom = COM_MenuUp; break;
case COM_Left: rCom = COM_MenuLeft; break;
case COM_Down: rCom = COM_MenuDown; break;
case COM_Right: rCom = COM_MenuRight; break;
// Not a menu com: do nothing
default: return true;
}
// If text is still progressing, any menu com will complete it first
// Note: conversion to COM_MenuShowText is not synchronized because text lengths may vary
// between clients. The above switch is used to determine whether the com was a menu com
if (fTextProgressing && fAsyncConversion)
rCom = COM_MenuShowText;
// Done
return true;
}
bool C4Menu::SetLocation(int32_t iX, int32_t iY) bool C4Menu::SetLocation(int32_t iX, int32_t iY)
{ {
// just set position... // just set position...
@ -996,41 +637,6 @@ bool C4Menu::SetLocation(int32_t iX, int32_t iY)
return true; return true;
} }
bool C4Menu::SetTextProgress(int32_t iToProgress, bool fAdd)
{
// menu active at all?
if (!IsActive()) return false;
// set: enable or disable progress?
if (!fAdd)
fTextProgressing = (iToProgress >= 0);
else
{
// add: Does not enable progressing
if (!fTextProgressing) return false;
}
// update menu items
C4MenuItem *pItem;
bool fAnyItemUnfinished = false;
for (int32_t i=HasPortrait(); (pItem = GetItem(i)); ++i)
{
// disabled progress: set all progresses to shown
if (!fTextProgressing)
{
pItem->TextDisplayProgress = -1;
continue;
}
// do progress on item, if any is left
// this call automatically reduces iToProgress as it's used up
if (!fAdd) pItem->TextDisplayProgress = 0;
if (iToProgress) pItem->DoTextProgress(iToProgress);
if (pItem->TextDisplayProgress > -1) fAnyItemUnfinished = true;
}
// if that progress showed everything already, mark as not progressing
fTextProgressing = fAnyItemUnfinished;
// done, success
return true;
}
C4Viewport *C4Menu::GetViewport() C4Viewport *C4Menu::GetViewport()
{ {
// ask all viewports // ask all viewports
@ -1049,22 +655,7 @@ void C4Menu::UpdateElementPositions()
// reposition client scrolling window // reposition client scrolling window
pClientWindow->SetBounds(GetContainedClientRect()); pClientWindow->SetBounds(GetContainedClientRect());
// re-stack all list items // re-stack all list items
int xOff, yOff = 0; C4MenuItem *pCurr = static_cast<C4MenuItem *>(pClientWindow->GetFirst());
C4MenuItem *pCurr = static_cast<C4MenuItem *>(pClientWindow->GetFirst()), *pPrev = NULL;
if (HasPortrait() && pCurr)
{
// recheck portrait
xOff = C4MN_DlgPortraitWdt + C4MN_DlgPortraitIndent;
C4Facet &fctPortrait = pCurr->Symbol;
C4Rect rcPortraitBounds(0,0, C4MN_DlgPortraitWdt + C4MN_DlgPortraitIndent, fctPortrait.Hgt * C4MN_DlgPortraitWdt / std::max<int>(fctPortrait.Wdt, 1));
if (pCurr->GetBounds() != rcPortraitBounds)
{
pCurr->GetBounds() = rcPortraitBounds;
pCurr->UpdateOwnPos();
}
pCurr = static_cast<C4MenuItem *>(pCurr->GetNext());
}
else xOff = 0;
// recheck list items // recheck list items
int32_t iMaxDlgOptionHeight = -1; int32_t iMaxDlgOptionHeight = -1;
int32_t iIndex = 0; C4Rect rcNewBounds(0,0,ItemWidth,ItemHeight); int32_t iIndex = 0; C4Rect rcNewBounds(0,0,ItemWidth,ItemHeight);
@ -1072,67 +663,14 @@ void C4Menu::UpdateElementPositions()
while ((pCurr = pNext)) while ((pCurr = pNext))
{ {
pNext = static_cast<C4MenuItem *>(pCurr->GetNext()); pNext = static_cast<C4MenuItem *>(pCurr->GetNext());
if (Style == C4MN_Style_Dialog) rcNewBounds.x = (iIndex % std::max<int32_t>(Columns, 1)) * ItemWidth;
{ rcNewBounds.y = (iIndex / std::max<int32_t>(Columns, 1)) * ItemHeight;
// y-margin always, except between options
if (!pPrev || (!pPrev->IsSelectable || !pCurr->IsSelectable)) yOff += C4MN_DlgLineMargin; else yOff += C4MN_DlgOptionLineMargin;
// determine item height.
StdStrBuf sText;
int32_t iAssumedItemHeight = ::GraphicsResource.FontRegular.GetLineHeight();
int32_t iWdt, iAvailWdt = ItemWidth, iSymWdt;
for (;;)
{
iSymWdt = std::min<int32_t>(pCurr->GetSymbolWidth(iAssumedItemHeight), iAvailWdt/2);
iAvailWdt = ItemWidth - iSymWdt;
::GraphicsResource.FontRegular.BreakMessage(pCurr->Caption, iAvailWdt, &sText, true);
::GraphicsResource.FontRegular.GetTextExtent(sText.getData(),iWdt,rcNewBounds.Hgt, true);
if (!iSymWdt || rcNewBounds.Hgt <= iAssumedItemHeight) break;
// If there is a symbol, the symbol grows as more lines become available
// Thus, less space is available for the text, and it might become larger
iAssumedItemHeight = rcNewBounds.Hgt;
}
if (fEqualIconItemHeight && iSymWdt)
{
// force equal height for all symbol items
if (iMaxDlgOptionHeight < 0)
{
// first selectable item inits field
iMaxDlgOptionHeight = rcNewBounds.Hgt;
}
else if (rcNewBounds.Hgt <= iMaxDlgOptionHeight)
{
// following item height smaller or equal: Force equal
rcNewBounds.Hgt = iMaxDlgOptionHeight;
}
else
{
// following item larger height: Need to re-stack from beginning
iMaxDlgOptionHeight = rcNewBounds.Hgt;
pNext = pFirstStack;
pPrev = NULL;
yOff = 0;
iIndex = 0;
continue;
}
}
assert(iWdt <= iAvailWdt);
rcNewBounds.x = 0;
rcNewBounds.y = yOff;
yOff += rcNewBounds.Hgt;
}
else
{
rcNewBounds.x = (iIndex % std::max<int32_t>(Columns, 1)) * ItemWidth;
rcNewBounds.y = (iIndex / std::max<int32_t>(Columns, 1)) * ItemHeight;
}
rcNewBounds.x += xOff;
if (pCurr->GetBounds() != rcNewBounds) if (pCurr->GetBounds() != rcNewBounds)
{ {
pCurr->GetBounds() = rcNewBounds; pCurr->GetBounds() = rcNewBounds;
pCurr->UpdateOwnPos(); pCurr->UpdateOwnPos();
} }
++iIndex; ++iIndex;
pPrev = pCurr;
} }
// update scrolling // update scrolling
pClientWindow->SetClientHeight(rcNewBounds.y + rcNewBounds.Hgt); pClientWindow->SetClientHeight(rcNewBounds.y + rcNewBounds.Hgt);
@ -1143,7 +681,7 @@ void C4Menu::UpdateElementPositions()
szCapt = pSel->Caption; szCapt = pSel->Caption;
else else
szCapt = Caption; szCapt = Caption;
SetTitle((*szCapt || Style == C4MN_Style_Dialog) ? szCapt : " ", HasMouse()); SetTitle((*szCapt) ? szCapt : " ", HasMouse());
} }
void C4Menu::UpdateOwnPos() void C4Menu::UpdateOwnPos()
@ -1158,20 +696,18 @@ void C4Menu::UserSelectItem(int32_t Player, C4MenuItem *pItem)
{ {
// not if user con't control anything // not if user con't control anything
if (IsReadOnly()) return; if (IsReadOnly()) return;
// the item must be selectable if (!pItem) return;
if (!pItem || !pItem->IsSelectable) return;
// queue or direct selection // queue or direct selection
OnUserSelectItem(Player, pItem->iIndex); OnUserSelectItem(Player, pItem->iIndex);
} }
void C4Menu::UserEnter(int32_t Player, C4MenuItem *pItem, bool fRight) void C4Menu::UserEnter(int32_t Player, C4MenuItem *pItem)
{ {
// not if user con't control anything // not if user con't control anything
if (IsReadOnly()) return; if (IsReadOnly()) return;
// the item must be selectable if (!pItem) return;
if (!pItem || !pItem->IsSelectable) return;
// queue or direct enter // queue or direct enter
OnUserEnter(Player, pItem->iIndex, fRight); OnUserEnter(Player, pItem->iIndex);
} }
void C4Menu::UserClose(bool fOK) void C4Menu::UserClose(bool fOK)
@ -1196,13 +732,6 @@ bool C4Menu::HasMouse()
return false; return false;
} }
void C4Menu::ClearPointers(C4Object *pObj)
{
C4MenuItem *pItem;
for (int32_t i=0; (pItem = GetItem(i)); ++i)
pItem->ClearPointers(pObj);
}
#ifdef _DEBUG #ifdef _DEBUG
void C4Menu::AssertSurfaceNotUsed(C4Surface *sfc) void C4Menu::AssertSurfaceNotUsed(C4Surface *sfc)
{ {

View File

@ -27,24 +27,12 @@
enum enum
{ {
C4MN_SymbolSize = 16,
C4MN_FrameWidth = 2 C4MN_FrameWidth = 2
}; };
enum enum
{ {
C4MN_Style_Normal = 0, C4MN_Style_Normal = 0,
C4MN_Style_Context = 1, C4MN_Style_Context = 1,
C4MN_Style_Info = 2,
C4MN_Style_Dialog = 3,
C4MN_Style_BaseMask = 127,
C4MN_Style_EqualItemHeight = 128
};
enum
{
C4MN_Extra_None = 0,
C4MN_Extra_Components = 1,
C4MN_Extra_Value = 2,
C4MN_Extra_Info = 4,
}; };
enum enum
{ {
@ -52,15 +40,6 @@ enum
C4MN_Align_Right = 2, C4MN_Align_Right = 2,
C4MN_Align_Top = 4, C4MN_Align_Top = 4,
C4MN_Align_Bottom = 8, C4MN_Align_Bottom = 8,
C4MN_Align_Free = 16
};
enum
{
C4MN_Item_NoCount = 12345678
};
enum
{
C4MN_AdjustPosition = 1<<31
}; };
class C4MenuItem : public C4GUI::Element class C4MenuItem : public C4GUI::Element
@ -71,51 +50,31 @@ public:
protected: protected:
char Caption[C4MaxTitle+1]; char Caption[C4MaxTitle+1];
char Command[_MAX_FNAME+30+1]; char Command[_MAX_FNAME+30+1];
char Command2[_MAX_FNAME+30+1];
char InfoCaption[2*C4MaxTitle+1]; char InfoCaption[2*C4MaxTitle+1];
int32_t Count;
C4ID id;
C4Object *Object;
C4FacetSurface Symbol; C4FacetSurface Symbol;
C4Object* pSymbolObj; // drawn instead of symbol, if non-null
C4DefGraphics* pSymbolGraphics; // drawn instead of symbol, if non-null C4DefGraphics* pSymbolGraphics; // drawn instead of symbol, if non-null
uint32_t dwSymbolClr; uint32_t dwSymbolClr;
bool fOwnValue; // if set, a specific value is to be shown
int32_t iValue; // specific value to be shown
bool fSelected; // item is selected; set by menu bool fSelected; // item is selected; set by menu
int32_t iStyle; int32_t iStyle;
class C4Menu *pMenu; class C4Menu *pMenu;
int32_t iIndex; int32_t iIndex;
bool IsSelectable;
int32_t TextDisplayProgress; // dialog menus only: Amount of text which is to be displayed already (-1 for everything)
C4IDList Components; // components to be displayed in info line if item is selected
private: private:
bool IsDragElement();
int32_t GetSymbolWidth(int32_t iForHeight); int32_t GetSymbolWidth(int32_t iForHeight);
protected: protected:
virtual void DrawElement(C4TargetFacet &cgo); // draw menu item virtual void DrawElement(C4TargetFacet &cgo); // draw menu item
// ctor // ctor
C4MenuItem(C4Menu *pMenu, int32_t iIndex, const char *szCaption, const char *szCommand, C4MenuItem(C4Menu *pMenu, int32_t iIndex, const char *szCaption, const char *szCommand, const char *szInfoCaption, int32_t iStyle);
int32_t iCount, C4Object *pObject, const char *szInfoCaption,
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, int32_t iStyle, bool fIsSelectable);
void GrabSymbol(C4FacetSurface &fctSymbol) { Symbol.GrabFrom(fctSymbol); if (Symbol.Surface) dwSymbolClr=Symbol.Surface->GetClr(); } void GrabSymbol(C4FacetSurface &fctSymbol) { Symbol.GrabFrom(fctSymbol); if (Symbol.Surface) dwSymbolClr=Symbol.Surface->GetClr(); }
void SetGraphics(C4Object* pObj) { pSymbolObj = pObj; }
void SetGraphics(C4DefGraphics* pGfx) { pSymbolGraphics = pGfx; } void SetGraphics(C4DefGraphics* pGfx) { pSymbolGraphics = pGfx; }
void RefSymbol(const C4Facet &fctSymbol) { Symbol.Set(fctSymbol); if (Symbol.Surface) dwSymbolClr=Symbol.Surface->GetClr(); } void RefSymbol(const C4Facet &fctSymbol) { Symbol.Set(fctSymbol); if (Symbol.Surface) dwSymbolClr=Symbol.Surface->GetClr(); }
void SetSelected(bool fToVal) { fSelected = fToVal; } void SetSelected(bool fToVal) { fSelected = fToVal; }
void DoTextProgress(int32_t &riByVal); // progress number of shown characters by given amount
public: public:
C4ID GetC4ID() const { return id; }
int32_t GetValue() const { return iValue; }
C4Object *GetObject() const { return Object; }
const char *GetCommand() const { return Command; } const char *GetCommand() const { return Command; }
void ClearPointers(C4Object* pObj) { if(pObj == Object) Object = NULL; if(pObj == pSymbolObj) pSymbolObj = NULL; }
// GUI calls // GUI calls
virtual void MouseInput(class C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam); // input: mouse movement or buttons virtual void MouseInput(class C4GUI::CMouse &rMouse, int32_t iButton, int32_t iX, int32_t iY, DWORD dwKeyParam); // input: mouse movement or buttons
virtual void MouseEnter(class C4GUI::CMouse &rMouse); // called when mouse cursor enters element region: Select this item (deselects any other) virtual void MouseEnter(class C4GUI::CMouse &rMouse); // called when mouse cursor enters element region: Select this item (deselects any other)
@ -139,23 +98,16 @@ protected:
int32_t Selection,TimeOnSelection; int32_t Selection,TimeOnSelection;
int32_t ItemCount; int32_t ItemCount;
int32_t ItemWidth,ItemHeight; int32_t ItemWidth,ItemHeight;
int32_t Extra,ExtraData;
int32_t Identification; int32_t Identification;
int32_t Columns; // sync int32_t Columns; // sync
int32_t Lines; // async int32_t Lines; // async
int32_t Alignment; int32_t Alignment;
int32_t VisibleCount;
StdStrBuf CloseCommand; // script command that will be executed on menu close StdStrBuf CloseCommand; // script command that will be executed on menu close
char Caption[C4MaxTitle+1]; char Caption[C4MaxTitle+1];
C4FacetSurface Symbol; C4FacetSurface Symbol;
C4GUI::ScrollWindow *pClientWindow; // window containing the menu items C4GUI::ScrollWindow *pClientWindow; // window containing the menu items
bool fHasPortrait; // if set, first menu item is used at a portrait at topleft of menu
bool fTextProgressing; // if true, text is being shown progressively (dialog menus)
bool fEqualIconItemHeight; // for dialog menus only: If set, all options with an icon are forced to have the same height
bool fActive; // set if menu is shown - independant of GUI to keep synchronized when there's no GUI bool fActive; // set if menu is shown - independant of GUI to keep synchronized when there's no GUI
public: public:
bool ConvertCom(int32_t &rCom, int32_t &rData, bool fAsyncConversion);
void ClearPointers(C4Object *pObj);
bool Refill(); bool Refill();
void Execute(); void Execute();
void SetPermanent(bool fPermanent); void SetPermanent(bool fPermanent);
@ -165,7 +117,6 @@ public:
int32_t GetPosition(); int32_t GetPosition();
int32_t GetSelection(); int32_t GetSelection();
bool IsContextMenu() { return Style == C4MN_Style_Context; } bool IsContextMenu() { return Style == C4MN_Style_Context; }
int GetSymbolSize() { return (Style == C4MN_Style_Dialog) ? 64 : C4SymbolSize; }
int32_t GetItemHeight() { return ItemHeight; } int32_t GetItemHeight() { return ItemHeight; }
C4MenuItem* GetSelectedItem(); C4MenuItem* GetSelectedItem();
C4MenuItem* GetItem(int32_t iIndex); C4MenuItem* GetItem(int32_t iIndex);
@ -174,47 +125,27 @@ public:
bool SetSelection(int32_t iSelection, bool fAdjustPosition, bool fDoCalls); bool SetSelection(int32_t iSelection, bool fAdjustPosition, bool fDoCalls);
bool SetPosition(int32_t iPosition); bool SetPosition(int32_t iPosition);
void SetSize(int32_t iToWdt, int32_t iToHgt); void SetSize(int32_t iToWdt, int32_t iToHgt);
bool Enter(bool fRight=false); bool Enter();
bool IsActive(); bool IsActive();
bool Control(BYTE byCom, int32_t iData); bool Control(BYTE byCom, int32_t iData);
bool KeyControl(BYTE byCom); // direct keyboard callback bool KeyControl(BYTE byCom); // direct keyboard callback
bool AddRefSym(const char *szCaption, const C4Facet &fctSymbol, const char *szCommand, bool AddRefSym(const char *szCaption, const C4Facet &fctSymbol, const char *szCommand, const char *szInfoCaption=NULL);
int32_t iCount=C4MN_Item_NoCount, C4Object *pObject=NULL, bool Add(const char *szCaption, C4FacetSurface &fctSymbol, const char *szCommand, const char *szInfoCaption=NULL);
const char *szInfoCaption=NULL,
C4ID idID=C4ID::None, const char *szCommand2=NULL, bool fOwnValue=false, int32_t iValue=0, bool fIsSelectable=true);
bool Add(const char *szCaption, C4FacetSurface &fctSymbol, const char *szCommand,
int32_t iCount=C4MN_Item_NoCount, C4Object *pObject=NULL,
const char *szInfoCaption=NULL,
C4ID idID=C4ID::None, const char *szCommand2=NULL, bool fOwnValue=false, int32_t iValue=0, bool fIsSelectable=true);
bool Add(const char *szCaption, C4Object* pGfxObj, const char *szCommand,
int32_t iCount=C4MN_Item_NoCount, C4Object *pObject=NULL,
const char *szInfoCaption=NULL,
C4ID idID=C4ID::None, const char *szCommand2=NULL, bool fOwnValue=false, int32_t iValue=0, bool fIsSelectable=true);
bool Add(const char *szCaption, C4DefGraphics* pGfx, const char *szCommand,
int32_t iCount=C4MN_Item_NoCount, C4Object *pObject=NULL,
const char *szInfoCaption=NULL,
C4ID idID=C4ID::None, const char *szCommand2=NULL, bool fOwnValue=false, int32_t iValue=0, bool fIsSelectable=true);
void ClearItems(); void ClearItems();
void ResetLocation() { LocationSet = false; } void ResetLocation() { LocationSet = false; }
bool SetLocation(int32_t iX, int32_t iY); // set location relative to user viewport bool SetLocation(int32_t iX, int32_t iY); // set location relative to user viewport
bool SetTextProgress(int32_t iToProgress, bool fAdd); // enable/disable progressive text display and set starting pos
void SetEqualItemHeight(bool fToVal) { fEqualIconItemHeight = fToVal; } // enable/disable equal item heights
bool TryClose(bool fOK, bool fControl); bool TryClose(bool fOK, bool fControl);
void SetCloseCommand(const char *strCommand); void SetCloseCommand(const char *strCommand);
bool IsTextProgressing() const { return fTextProgressing; }
#ifdef _DEBUG #ifdef _DEBUG
void AssertSurfaceNotUsed(C4Surface *sfc); void AssertSurfaceNotUsed(C4Surface *sfc);
#endif #endif
private: private:
bool AddItem(C4MenuItem *pNew, const char *szCaption, const char *szCommand, bool AddItem(C4MenuItem *pNew, const char *szCaption, const char *szCommand, const char *szInfoCaption);
int32_t iCount, C4Object *pObject, const char *szInfoCaption, bool InitMenu(const char *szEmpty, int32_t iId, int32_t iStyle);
C4ID idID, const char *szCommand2, bool fOwnValue, int32_t iValue, bool fIsSelectable);
bool InitMenu(const char *szEmpty, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle);
protected: protected:
bool DoInitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal); bool DoInitRefSym(const C4Facet &fctSymbol, const char *szEmpty, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal);
bool DoInit(C4FacetSurface &fctSymbol, const char *szEmpty, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal);
void DrawBuffer(C4Facet &cgo); void DrawBuffer(C4Facet &cgo);
void AdjustSelection(); void AdjustSelection();
void AdjustPosition(); void AdjustPosition();
@ -227,7 +158,7 @@ protected:
void InitSize(); void InitSize();
void UpdateScrollBar(); // call InitSize if a scroll bar is needed but not present or vice vera void UpdateScrollBar(); // call InitSize if a scroll bar is needed but not present or vice vera
void UserSelectItem(int32_t Player, C4MenuItem *pItem); // select item (direct) or do control (object menus) void UserSelectItem(int32_t Player, C4MenuItem *pItem); // select item (direct) or do control (object menus)
void UserEnter(int32_t Player, C4MenuItem *pItem, bool fRight); // enter on an item void UserEnter(int32_t Player, C4MenuItem *pItem); // enter on an item
bool HasMouse(); // returns whether the controlling player has mouse control bool HasMouse(); // returns whether the controlling player has mouse control
virtual bool DoRefillInternal(bool &rfRefilled) { return true; }; virtual bool DoRefillInternal(bool &rfRefilled) { return true; };
@ -235,15 +166,13 @@ protected:
virtual void OnSelectionChanged(int32_t iNewSelection) {} // do object callbacks if selection changed in user menus virtual void OnSelectionChanged(int32_t iNewSelection) {} // do object callbacks if selection changed in user menus
virtual bool IsCloseDenied() { return false; } // do MenuQueryCancel-callbacks for user menus virtual bool IsCloseDenied() { return false; } // do MenuQueryCancel-callbacks for user menus
virtual void OnUserSelectItem(int32_t Player, int32_t iIndex) {} virtual void OnUserSelectItem(int32_t Player, int32_t iIndex) {}
virtual void OnUserEnter(int32_t Player, int32_t iIndex, bool fRight) {} virtual void OnUserEnter(int32_t Player, int32_t iIndex) {}
virtual void OnUserClose() {}; virtual void OnUserClose() {};
virtual bool IsReadOnly() { return false; } // determine whether the menu is just viewed by an observer, and should not issue any calls virtual bool IsReadOnly() { return false; } // determine whether the menu is just viewed by an observer, and should not issue any calls
virtual int32_t GetControllingPlayer() { return NO_OWNER; } virtual int32_t GetControllingPlayer() { return NO_OWNER; }
virtual const char *GetID() { return 0; } // no ID needed, because it's a viewport dlg virtual const char *GetID() { return 0; } // no ID needed, because it's a viewport dlg
bool HasPortrait() { return fHasPortrait; } // dialog menus only: Whether a portrait is shown in the topleft
protected: protected:
// C4GUI // C4GUI
virtual C4Viewport *GetViewport(); // return associated viewport virtual C4Viewport *GetViewport(); // return associated viewport
@ -253,12 +182,11 @@ protected:
void UpdateElementPositions(); // reposition list items so they are stacked vertically void UpdateElementPositions(); // reposition list items so they are stacked vertically
virtual int32_t GetZOrdering() { return -1; } virtual int32_t GetZOrdering() { return -1; }
virtual void Draw(C4TargetFacet &cgo); virtual void Draw(C4TargetFacet &cgo);
virtual void DrawElement(C4TargetFacet &cgo); // draw menu
virtual bool IsOwnPtrElement() { return true; } virtual bool IsOwnPtrElement() { return true; }
virtual void UserClose(bool fOK); virtual void UserClose(bool fOK);
// bottom area needed for extra info // bottom area needed for extra info
virtual int32_t GetMarginBottom() { return ((Extra) ? C4MN_SymbolSize : 0) + C4MN_FrameWidth + BaseClass::GetMarginBottom(); } virtual int32_t GetMarginBottom() { return C4MN_FrameWidth + BaseClass::GetMarginBottom(); }
virtual int32_t GetMarginLeft() { return C4MN_FrameWidth + BaseClass::GetMarginLeft(); } virtual int32_t GetMarginLeft() { return C4MN_FrameWidth + BaseClass::GetMarginLeft(); }
virtual int32_t GetMarginRight() { return C4MN_FrameWidth + BaseClass::GetMarginRight(); } virtual int32_t GetMarginRight() { return C4MN_FrameWidth + BaseClass::GetMarginRight(); }

View File

@ -26,7 +26,6 @@
#include <C4ObjectInfo.h> #include <C4ObjectInfo.h>
#include <C4Random.h> #include <C4Random.h>
#include <C4GameMessage.h> #include <C4GameMessage.h>
#include <C4ObjectMenu.h>
#include <C4Player.h> #include <C4Player.h>
#include <C4SoundSystem.h> #include <C4SoundSystem.h>
#include <C4Landscape.h> #include <C4Landscape.h>
@ -72,8 +71,6 @@ const char *CommandName(int32_t iCommand)
case C4CMD_Retry: return "Retry"; case C4CMD_Retry: return "Retry";
case C4CMD_Home: return "Home"; case C4CMD_Home: return "Home";
case C4CMD_Call: return "Call"; case C4CMD_Call: return "Call";
case C4CMD_Take: return "Take";
case C4CMD_Take2: return "Take2";
default: return "None"; default: return "None";
} }
} }
@ -106,8 +103,6 @@ const char* CommandNameID(int32_t iCommand)
case C4CMD_Retry: return "IDS_COMM_RETRY"; case C4CMD_Retry: return "IDS_COMM_RETRY";
case C4CMD_Home: return "IDS_CON_HOME"; case C4CMD_Home: return "IDS_CON_HOME";
case C4CMD_Call: return "IDS_COMM_CALL"; case C4CMD_Call: return "IDS_COMM_CALL";
case C4CMD_Take: return "IDS_COMM_TAKE";
case C4CMD_Take2: return "IDS_COMM_TAKE2";
default: return "IDS_COMM_NONE"; default: return "IDS_COMM_NONE";
} }
} }
@ -824,18 +819,6 @@ void C4Command::Throw()
Finish(true); Finish(true);
} }
void C4Command::Take()
{
ObjectComTake(cObj);
Finish(true);
}
void C4Command::Take2()
{
ObjectComTake2(cObj);
Finish(true);
}
void C4Command::Drop() void C4Command::Drop()
{ {
@ -948,14 +931,6 @@ bool C4Command::GetTryEnter()
void C4Command::Get() void C4Command::Get()
{ {
// Data set and target specified: open get menu & done (old style)
if (((Data.getInt()==1) || (Data.getInt()==2)) && Target)
{
cObj->ActivateMenu((Data.getInt()==1) ? C4MN_Get : C4MN_Contents,0,0,0,Target);
Finish(true); return;
}
// Get target specified by container and type // Get target specified by container and type
if (!Target && Target2 && Data) if (!Target && Target2 && Data)
if (!(Target = Target2->Contents.Find(Data.getDef()))) if (!(Target = Target2->Contents.Find(Data.getDef())))
@ -1098,15 +1073,6 @@ void C4Command::Get()
void C4Command::Activate() void C4Command::Activate()
{ {
// Container specified, but no Target & no type: open activate menu for container
if (Target2 && !Target && !Data)
{
cObj->ActivateMenu(C4MN_Activate,0,0,0,Target2);
Finish(true);
return;
}
// Target object specified & outside: success // Target object specified & outside: success
if (Target) if (Target)
if (!Target->Contained) if (!Target->Contained)
@ -1349,8 +1315,6 @@ void C4Command::Execute()
case C4CMD_Retry: Retry(); break; case C4CMD_Retry: Retry(); break;
case C4CMD_Home: Home(); break; case C4CMD_Home: Home(); break;
case C4CMD_Call: Call(); break; case C4CMD_Call: Call(); break;
case C4CMD_Take: Take(); break; // carlo
case C4CMD_Take2: Take2(); break; // carlo
default: Finish(); break; default: Finish(); break;
} }
@ -1954,8 +1918,6 @@ int32_t C4Command::GetExpGain()
case C4CMD_Dig: case C4CMD_Dig:
case C4CMD_Buy: case C4CMD_Buy:
case C4CMD_Sell: case C4CMD_Sell:
case C4CMD_Take:
case C4CMD_Take2:
return 1; return 1;
// not that simple // not that simple

View File

@ -49,12 +49,10 @@ enum C4CMD
C4CMD_Retry, C4CMD_Retry,
C4CMD_Home, C4CMD_Home,
C4CMD_Call, C4CMD_Call,
C4CMD_Take,
C4CMD_Take2,
}; };
const int32_t C4CMD_First = C4CMD_Follow, const int32_t C4CMD_First = C4CMD_Follow,
C4CMD_Last = C4CMD_Take2; // carlo C4CMD_Last = C4CMD_Call;
const int32_t C4CMD_Mode_SilentSub = 0, // subcommand; failure will cause base to fail (no message in case of failure) const int32_t C4CMD_Mode_SilentSub = 0, // subcommand; failure will cause base to fail (no message in case of failure)
C4CMD_Mode_Base = 1, // regular base command C4CMD_Mode_Base = 1, // regular base command
@ -118,8 +116,6 @@ protected:
void Throw(); void Throw();
void Jump(); void Jump();
void Wait(); void Wait();
void Take();
void Take2();
bool GetTryEnter(); // at object pos during get-command: Try entering it bool GetTryEnter(); // at object pos during get-command: Try entering it
void Get(); void Get();
void Put(); void Put();

View File

@ -26,7 +26,6 @@
#include <C4Application.h> #include <C4Application.h>
#include <C4Game.h> #include <C4Game.h>
#include <C4Menu.h> #include <C4Menu.h>
#include <C4ObjectMenu.h>
#include <C4Player.h> #include <C4Player.h>
#include <C4Log.h> #include <C4Log.h>
#include <C4Material.h> #include <C4Material.h>
@ -490,12 +489,6 @@ void C4DefGraphicsPtrBackupEntry::AssignUpdate()
// looped through w/o removal? // looped through w/o removal?
if (!pGfxOverlay) break; if (!pGfxOverlay) break;
} }
// update menu frame decorations - may do multiple updates to the same deco if multiple menus share it...
C4GUI::FrameDecoration *pDeco;
if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration()))
if (pDeco->idSourceDef == pDef->id)
if (!pDeco->UpdateGfx())
pObj->Menu->SetFrameDeco(NULL);
} }
} }
// done; reset field to indicate finished update // done; reset field to indicate finished update
@ -545,11 +538,6 @@ void C4DefGraphicsPtrBackupEntry::AssignRemoval()
// looped through w/o removal? // looped through w/o removal?
if (!pGfxOverlay) break; if (!pGfxOverlay) break;
} }
// remove menu frame decorations
C4GUI::FrameDecoration *pDeco;
if (pDef && pObj->Menu && (pDeco = pObj->Menu->GetFrameDecoration()))
if (pDeco->idSourceDef == pDef->id)
pObj->Menu->SetFrameDeco(NULL);
} }
// done; reset field to indicate finished update // done; reset field to indicate finished update
pGraphicsPtr = NULL; pGraphicsPtr = NULL;

View File

@ -35,7 +35,6 @@
#include <C4Random.h> #include <C4Random.h>
#include <C4Log.h> #include <C4Log.h>
#include <C4Player.h> #include <C4Player.h>
#include <C4ObjectMenu.h>
#include <C4RankSystem.h> #include <C4RankSystem.h>
#include <C4GameMessage.h> #include <C4GameMessage.h>
#include <C4GraphicsResource.h> #include <C4GraphicsResource.h>
@ -209,7 +208,6 @@ void C4Object::Default()
Command=NULL; Command=NULL;
Contained=NULL; Contained=NULL;
TopFace.Default(); TopFace.Default();
Menu=NULL;
MaterialContents=NULL; MaterialContents=NULL;
Marker=0; Marker=0;
ColorMod=0xffffffff; ColorMod=0xffffffff;
@ -1064,8 +1062,6 @@ void C4Object::Execute()
// Animation. If the mesh is attached, then don't execute animation here but let the parent object do it to make sure it is only executed once a frame. // Animation. If the mesh is attached, then don't execute animation here but let the parent object do it to make sure it is only executed once a frame.
if (pMeshInstance && !pMeshInstance->GetAttachParent()) if (pMeshInstance && !pMeshInstance->GetAttachParent())
pMeshInstance->ExecuteAnimation(1.0f/37.0f /* play smoothly at 37 FPS */); pMeshInstance->ExecuteAnimation(1.0f/37.0f /* play smoothly at 37 FPS */);
// Menu
if (Menu) Menu->Execute();
} }
bool C4Object::At(int32_t ctx, int32_t cty) const bool C4Object::At(int32_t ctx, int32_t cty) const
@ -1366,7 +1362,6 @@ bool C4Object::Exit(int32_t iX, int32_t iY, int32_t iR, C4Real iXDir, C4Real iYD
// Misc updates // Misc updates
Mobile=1; Mobile=1;
InLiquid=0; InLiquid=0;
CloseMenu(true);
UpdateFace(true); UpdateFace(true);
SetOCF(); SetOCF();
// Engine calls // Engine calls
@ -1406,12 +1401,6 @@ bool C4Object::Enter(C4Object *pTarget, bool fCalls, bool fCopyMotion, bool *pfR
if (Contained) if (!Exit(GetX(),GetY())) return false; if (Contained) if (!Exit(GetX(),GetY())) return false;
if (Contained || !Status || !pTarget->Status) return false; if (Contained || !Status || !pTarget->Status) return false;
// Failsafe updates // Failsafe updates
if (Menu)
{
CloseMenu(true);
// CloseMenu might do bad stuff
if (Contained || !Status || !pTarget->Status) return false;
}
SetOCF(); SetOCF();
// Set container // Set container
Contained=pTarget; Contained=pTarget;
@ -1568,132 +1557,6 @@ bool C4Object::CreateContentsByList(C4IDList &idlist)
return true; return true;
} }
static void DrawMenuSymbol(int32_t iMenu, C4Facet &cgo, int32_t iOwner)
{
C4Facet ccgo;
DWORD dwColor=0;
if (ValidPlr(iOwner)) dwColor=::Players.Get(iOwner)->ColorDw;
switch (iMenu)
{
case C4MN_Buy:
::GraphicsResource.fctFlagClr.DrawClr(ccgo = cgo.GetFraction(75, 75), true, dwColor);
::GraphicsResource.fctWealth.Draw(ccgo = cgo.GetFraction(100, 50, C4FCT_Left, C4FCT_Bottom));
::GraphicsResource.fctArrow.Draw(ccgo = cgo.GetFraction(70, 70, C4FCT_Right, C4FCT_Center), false, 0);
break;
case C4MN_Sell:
::GraphicsResource.fctFlagClr.DrawClr(ccgo = cgo.GetFraction(75, 75), true, dwColor);
::GraphicsResource.fctWealth.Draw(ccgo = cgo.GetFraction(100, 50, C4FCT_Left, C4FCT_Bottom));
::GraphicsResource.fctArrow.Draw(ccgo = cgo.GetFraction(70, 70, C4FCT_Right, C4FCT_Center), false, 1);
break;
}
}
bool C4Object::ActivateMenu(int32_t iMenu, int32_t iMenuSelect,
int32_t iMenuData, int32_t iMenuPosition,
C4Object *pTarget)
{
// Variables
C4FacetSurface fctSymbol;
C4IDList ListItems;
// Close any other menu
if (Menu && Menu->IsActive()) if (!Menu->TryClose(true, false)) return false;
// Create menu
if (!Menu) Menu = new C4ObjectMenu; else Menu->ClearItems();
// Open menu
switch (iMenu)
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Activate:
// No target specified: use own container as target
if (!pTarget) if (!(pTarget=Contained)) break;
// Opening contents menu blocked by RejectContents
if (!!pTarget->Call(PSF_RejectContents)) return false;
// Create symbol
fctSymbol.Create(C4SymbolSize,C4SymbolSize);
pTarget->Def->Draw(fctSymbol,false,pTarget->Color,pTarget);
// Init
Menu->Init(fctSymbol,FormatString(LoadResStr("IDS_OBJ_EMPTY"),pTarget->GetName()).getData(),this,C4MN_Extra_None,0,iMenu);
Menu->SetPermanent(true);
Menu->SetRefillObject(pTarget);
// Success
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Buy:
// No target specified: container is base
if (!pTarget) if (!(pTarget=Contained)) break;
// Create symbol
fctSymbol.Create(C4SymbolSize,C4SymbolSize);
DrawMenuSymbol(C4MN_Buy, fctSymbol, pTarget->Owner);
// Init menu
Menu->Init(fctSymbol,LoadResStr("IDS_PLR_NOBUY"),this,C4MN_Extra_Value,0,iMenu);
Menu->SetPermanent(true);
Menu->SetRefillObject(pTarget);
// Success
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Sell:
// No target specified: container is base
if (!pTarget) if (!(pTarget=Contained)) break;
// Create symbol & init
fctSymbol.Create(C4SymbolSize,C4SymbolSize);
DrawMenuSymbol(C4MN_Sell, fctSymbol, pTarget->Owner);
Menu->Init(fctSymbol,FormatString(LoadResStr("IDS_OBJ_EMPTY"),pTarget->GetName()).getData(),this,C4MN_Extra_Value,0,iMenu);
Menu->SetPermanent(true);
Menu->SetRefillObject(pTarget);
// Success
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Get:
case C4MN_Contents:
// No target specified
if (!pTarget) break;
// Opening contents menu blocked by RejectContents
if (!!pTarget->Call(PSF_RejectContents)) return false;
// Create symbol & init
fctSymbol.Create(C4SymbolSize,C4SymbolSize);
pTarget->Def->Draw(fctSymbol,false,pTarget->Color,pTarget);
Menu->Init(fctSymbol,FormatString(LoadResStr("IDS_OBJ_EMPTY"),pTarget->GetName()).getData(),this,C4MN_Extra_None,0,iMenu);
Menu->SetPermanent(true);
Menu->SetRefillObject(pTarget);
// Success
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Info:
// Target by parameter
if (!pTarget) break;
// Create symbol & init menu
fctSymbol.Create(C4SymbolSize, C4SymbolSize); GfxR->fctOKCancel.Draw(fctSymbol,true,0,1);
Menu->Init(fctSymbol, pTarget->GetName(), this, C4MN_Extra_None, 0, iMenu, C4MN_Style_Info);
Menu->SetPermanent(true);
Menu->SetAlignment(C4MN_Align_Free);
C4Viewport *pViewport = ::Viewports.GetViewport(Controller); // Hackhackhack!!!
if (pViewport) Menu->SetLocation((pTarget->GetX() + pTarget->Shape.GetX() + pTarget->Shape.Wdt + 10 - pViewport->GetViewX()) * pViewport->GetZoom(),
(pTarget->GetY() + pTarget->Shape.GetY() - pViewport->GetViewY()) * pViewport->GetZoom());
// Add info item
fctSymbol.Create(C4PictureSize, C4PictureSize); pTarget->Def->Draw(fctSymbol, false, pTarget->Color, pTarget);
Menu->Add(pTarget->GetName(), fctSymbol, "", C4MN_Item_NoCount, NULL, pTarget->GetInfoString().getData());
fctSymbol.Default();
// Success
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
// Invalid menu identification
CloseMenu(true);
return false;
}
bool C4Object::CloseMenu(bool fForce)
{
if (Menu)
{
if (Menu->IsActive()) if (!Menu->TryClose(fForce, false)) return false;
if (!Menu->IsCloseQuerying()) { delete Menu; Menu=NULL; } // protect menu deletion from recursive menu operation calls
}
return true;
}
BYTE C4Object::GetArea(int32_t &aX, int32_t &aY, int32_t &aWdt, int32_t &aHgt) const BYTE C4Object::GetArea(int32_t &aX, int32_t &aY, int32_t &aWdt, int32_t &aHgt) const
{ {
if (!Status || !Def) return 0; if (!Status || !Def) return 0;
@ -1870,8 +1733,6 @@ void C4Object::ClearPointers(C4Object *pObj)
C4Command *cCom; C4Command *cCom;
for (cCom=Command; cCom; cCom=cCom->Next) for (cCom=Command; cCom; cCom=cCom->Next)
cCom->ClearPointers(pObj); cCom->ClearPointers(pObj);
// Menu
if (Menu) Menu->ClearPointers(pObj);
// Layer // Layer
if (Layer==pObj) Layer=NULL; if (Layer==pObj) Layer=NULL;
// gfx overlays // gfx overlays
@ -2549,7 +2410,6 @@ void C4Object::Clear()
if (pEffects) { delete pEffects; pEffects=NULL; } if (pEffects) { delete pEffects; pEffects=NULL; }
if (pSolidMaskData) { delete pSolidMaskData; pSolidMaskData=NULL; } if (pSolidMaskData) { delete pSolidMaskData; pSolidMaskData=NULL; }
if (Menu) delete Menu; Menu=NULL;
if (MaterialContents) delete MaterialContents; MaterialContents=NULL; if (MaterialContents) delete MaterialContents; MaterialContents=NULL;
// clear commands! // clear commands!
C4Command *pCom, *pNext; C4Command *pCom, *pNext;
@ -2657,8 +2517,6 @@ void C4Object::SyncClearance()
t_contact = 0; t_contact = 0;
// Update OCF // Update OCF
SetOCF(); SetOCF();
// Menu
CloseMenu(true);
// Material contents // Material contents
if (MaterialContents) delete MaterialContents; MaterialContents=NULL; if (MaterialContents) delete MaterialContents; MaterialContents=NULL;
// reset speed of staticback-objects // reset speed of staticback-objects
@ -2759,9 +2617,6 @@ void C4Object::SetCommand(int32_t iCommand, C4Object *pTarget, C4Value iTx, int3
{ {
// Clear stack // Clear stack
ClearCommands(); ClearCommands();
// Close menu
if (fControl)
if (!CloseMenu(false)) return;
// Script overload // Script overload
if (fControl) if (fControl)
if (!!Call(PSF_ControlCommand,&C4AulParSet(C4VString(CommandName(iCommand)), if (!!Call(PSF_ControlCommand,&C4AulParSet(C4VString(CommandName(iCommand)),
@ -4410,13 +4265,6 @@ void C4Object::DirectComContents(C4Object *pTarget, bool fDoCalls)
if (!(Contents.ShiftContents(pTarget))) return; if (!(Contents.ShiftContents(pTarget))) return;
// Selection sound // Selection sound
if (fDoCalls) if (!Contents.GetObject()->Call("~Selection", &C4AulParSet(C4VObj(this)))) StartSoundEffect("Clonk::Action::Grab",false,100,this); if (fDoCalls) if (!Contents.GetObject()->Call("~Selection", &C4AulParSet(C4VObj(this)))) StartSoundEffect("Clonk::Action::Grab",false,100,this);
// update menu with the new item in "put" entry
if (Menu && Menu->IsActive() && Menu->IsContextMenu())
{
Menu->Refill();
}
// Done
return;
} }
void C4Object::GetParallaxity(int32_t *parX, int32_t *parY) const void C4Object::GetParallaxity(int32_t *parX, int32_t *parY) const

View File

@ -153,10 +153,6 @@ public:
uint32_t Marker; // state var used by Objects::CrossCheck and C4FindObject - NoSave uint32_t Marker; // state var used by Objects::CrossCheck and C4FindObject - NoSave
C4ObjectPtr Layer; C4ObjectPtr Layer;
C4DrawTransform *pDrawTransform; // assigned drawing transformation C4DrawTransform *pDrawTransform; // assigned drawing transformation
// Menu
class C4ObjectMenu *Menu; // SyncClearance-NoSave //
C4Facet TopFace; // NoSave // C4Facet TopFace; // NoSave //
C4Def *Def; C4Def *Def;
C4ObjectPtr Contained; C4ObjectPtr Contained;
@ -268,8 +264,6 @@ public:
bool At(int32_t ctx, int32_t cty) const; bool At(int32_t ctx, int32_t cty) const;
bool At(int32_t ctx, int32_t cty, DWORD &ocf) const; bool At(int32_t ctx, int32_t cty, DWORD &ocf) const;
void GetOCFForPos(int32_t ctx, int32_t cty, DWORD &ocf) const; void GetOCFForPos(int32_t ctx, int32_t cty, DWORD &ocf) const;
bool CloseMenu(bool fForce);
bool ActivateMenu(int32_t iMenu, int32_t iMenuSelect=0, int32_t iMenuData=0, int32_t iMenuPosition=0, C4Object *pTarget=NULL);
int32_t ContactCheck(int32_t atx, int32_t aty, uint32_t *border_hack_contacts=0, bool collide_halfvehic=false); int32_t ContactCheck(int32_t atx, int32_t aty, uint32_t *border_hack_contacts=0, bool collide_halfvehic=false);
bool Contact(int32_t cnat); bool Contact(int32_t cnat);
void StopAndContact(C4Real & ctco, C4Real limit, C4Real & speed, int32_t cnat); void StopAndContact(C4Real & ctco, C4Real limit, C4Real & speed, int32_t cnat);

View File

@ -26,7 +26,6 @@
#include <C4Command.h> #include <C4Command.h>
#include <C4Random.h> #include <C4Random.h>
#include <C4GameMessage.h> #include <C4GameMessage.h>
#include <C4ObjectMenu.h>
#include <C4Player.h> #include <C4Player.h>
#include <C4GraphicsResource.h> #include <C4GraphicsResource.h>
#include <C4Material.h> #include <C4Material.h>
@ -225,7 +224,6 @@ bool ObjectComUnGrab(C4Object *cObj)
C4Object *pTarget = cObj->Action.Target; C4Object *pTarget = cObj->Action.Target;
if (ObjectActionStand(cObj)) if (ObjectActionStand(cObj))
{ {
if (!cObj->CloseMenu(false)) return false;
cObj->Call(PSF_Grab, &C4AulParSet(C4VObj(pTarget), C4VBool(false))); cObj->Call(PSF_Grab, &C4AulParSet(C4VObj(pTarget), C4VBool(false)));
// clear action target // clear action target
cObj->Action.Target = NULL; cObj->Action.Target = NULL;
@ -405,31 +403,10 @@ bool ObjectComPutTake(C4Object *cObj, C4Object *pTarget, C4Object *pThing) // by
// Has thing, put to target // Has thing, put to target
if (pThing) if (pThing)
return ObjectComPut(cObj,pTarget,pThing); return ObjectComPut(cObj,pTarget,pThing);
// If target is own container, activate activation menu
if (pTarget==cObj->Contained)
return ObjectComTake(cObj); // carlo
// Assuming target is grabbed, check for grab get
if (pTarget->Def->GrabPutGet & C4D_Grab_Get)
{
// Activate get menu
return cObj->ActivateMenu(C4MN_Get,0,0,0,pTarget);
}
// Failure // Failure
return false; return false;
} }
// carlo
bool ObjectComTake(C4Object *cObj) // by C4CMD_Take
{
return cObj->ActivateMenu(C4MN_Activate);
}
// carlo
bool ObjectComTake2(C4Object *cObj) // by C4CMD_Take2
{
return cObj->ActivateMenu(C4MN_Get,0,0,0,cObj->Contained);
}
bool ObjectComPunch(C4Object *cObj, C4Object *pTarget, int32_t punch) bool ObjectComPunch(C4Object *cObj, C4Object *pTarget, int32_t punch)
{ {
if (!cObj || !pTarget) return false; if (!cObj || !pTarget) return false;

View File

@ -717,13 +717,6 @@ void C4ObjectList::DrawSelectMark(C4TargetFacet &cgo) const
cLnk->Obj->DrawSelectMark(cgo); cLnk->Obj->DrawSelectMark(cgo);
} }
void C4ObjectList::CloseMenus()
{
C4Object *cobj; C4ObjectLink *clnk;
for (clnk=First; clnk && (cobj=clnk->Obj); clnk=clnk->Next)
cobj->CloseMenu(true);
}
void C4ObjectList::Copy(const C4ObjectList &rList) void C4ObjectList::Copy(const C4ObjectList &rList)
{ {
Clear(); Default(); Clear(); Default();
@ -998,4 +991,4 @@ C4ObjectList::iterator C4ObjectList::ReverseView::begin() const
C4ObjectList::iterator C4ObjectList::ReverseView::end() const C4ObjectList::iterator C4ObjectList::ReverseView::end() const
{ {
return iterator(list, nullptr, true); return iterator(list, nullptr, true);
} }

View File

@ -109,7 +109,6 @@ public:
void DrawIfCategory(C4TargetFacet &cgo, int iPlayer, uint32_t dwCat, bool fInvert); // draw all objects that match dwCat (or don't match if fInvert) void DrawIfCategory(C4TargetFacet &cgo, int iPlayer, uint32_t dwCat, bool fInvert); // draw all objects that match dwCat (or don't match if fInvert)
void Draw(C4TargetFacet &cgo, int iPlayer, int MinPlane, int MaxPlane); // draw all objects void Draw(C4TargetFacet &cgo, int iPlayer, int MinPlane, int MaxPlane); // draw all objects
void DrawSelectMark(C4TargetFacet &cgo) const; void DrawSelectMark(C4TargetFacet &cgo) const;
void CloseMenus();
void UpdateGraphics(bool fGraphicsChanged); void UpdateGraphics(bool fGraphicsChanged);
void UpdateFaces(bool bUpdateShape); void UpdateFaces(bool bUpdateShape);
void ClearInfo(C4ObjectInfo *pInfo); void ClearInfo(C4ObjectInfo *pInfo);

View File

@ -1,316 +0,0 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2008-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
// Menus attached to objects; script created or internal
#include "C4Include.h"
#include "C4ObjectMenu.h"
#include "C4Control.h"
#include "C4Object.h"
#include "C4ObjectCom.h"
#include "C4Player.h"
#include "C4Viewport.h"
#include "C4MouseControl.h"
#include "C4GraphicsResource.h"
#include "C4Game.h"
#include "C4PlayerList.h"
#include "C4GameObjects.h"
// -----------------------------------------------------------
// C4ObjectMenu
C4ObjectMenu::C4ObjectMenu() : C4Menu()
{
Default();
}
void C4ObjectMenu::Default()
{
C4Menu::Default();
eCallbackType = CB_None;
Object = ParentObject = RefillObject = NULL;
RefillObjectContentsCount=0;
UserMenu = false;
CloseQuerying = false;
}
bool C4ObjectMenu::IsCloseDenied()
{
// abort if menu is permanented by script; stop endless recursive calls if user opens a new menu by CloseQuerying-flag
if (UserMenu && !CloseQuerying)
{
CloseQuerying = true;
bool fResult = false;
C4AulParSet pars(C4VInt(Selection), C4VObj(ParentObject));
if (eCallbackType == CB_Object)
{
if (Object) fResult = !!Object->Call(PSF_MenuQueryCancel, &pars);
}
else if (eCallbackType == CB_Scenario)
fResult = !!::GameScript.Call(PSF_MenuQueryCancel, &pars);
CloseQuerying = false;
if (fResult) return true;
}
// close OK
return false;
}
void C4ObjectMenu::LocalInit(C4Object *pObject, bool fUserMenu)
{
Object=pObject;
UserMenu=fUserMenu;
ParentObject=GetParentObject();
if (pObject) eCallbackType = CB_Object; else eCallbackType = CB_Scenario;
}
bool C4ObjectMenu::Init(C4FacetSurface &fctSymbol, const char *szEmpty, C4Object *pObject, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle, bool fUserMenu)
{
if (!DoInit(fctSymbol, szEmpty, iExtra, iExtraData, iId, iStyle)) return false;
LocalInit(pObject, fUserMenu);
return true;
}
bool C4ObjectMenu::InitRefSym(const C4TargetFacet &fctSymbol, const char *szEmpty, C4Object *pObject, int32_t iExtra, int32_t iExtraData, int32_t iId, int32_t iStyle, bool fUserMenu)
{
if (!DoInitRefSym(fctSymbol, szEmpty, iExtra, iExtraData, iId, iStyle)) return false;
LocalInit(pObject, fUserMenu);
return true;
}
void C4ObjectMenu::OnSelectionChanged(int32_t iNewSelection)
{
// do selection callback
if (UserMenu)
{
C4AulParSet pars(C4VInt(iNewSelection), C4VObj(ParentObject));
if (eCallbackType == CB_Object && Object)
Object->Call(PSF_MenuSelection, &pars);
else if (eCallbackType == CB_Scenario)
::GameScript.Call(PSF_MenuSelection, &pars);
}
}
void C4ObjectMenu::ClearPointers(C4Object *pObj)
{
if (Object==pObj) { Object=NULL; }
if (ParentObject==pObj) ParentObject=NULL; // Reason for menu close anyway.
if (RefillObject==pObj) RefillObject=NULL;
C4Menu::ClearPointers(pObj);
}
C4Object* C4ObjectMenu::GetParentObject()
{
for (C4Object *cObj : Objects)
if (cObj->Menu == this)
return cObj;
return NULL;
}
void C4ObjectMenu::SetRefillObject(C4Object *pObj)
{
RefillObject=pObj;
NeedRefill=true;
Refill();
}
bool C4ObjectMenu::DoRefillInternal(bool &rfRefilled)
{
// Variables
C4FacetSurface fctSymbol;
C4Object *pObj;
char szCaption[256+1],szCommand[256+1],szCommand2[256+1];
int32_t iCount;
C4Def *pDef;
C4IDList ListItems;
C4Object *pTarget;
C4Facet fctTarget;
// Refill
switch (Identification)
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Activate:
// Clear items
ClearItems();
// Refill target
if (!(pTarget=RefillObject)) return false;
{
// Add target contents items
C4ObjectListIterator iter(pTarget->Contents);
while ((pObj = iter.GetNext(&iCount)))
{
pDef = pObj->Def;
if (pDef->NoGet) continue;
// Prefer fully constructed objects
if (~pObj->OCF & OCF_FullCon)
{
// easy way: only if first concat check matches
// this doesn't catch all possibilities, but that will rarely matter
C4Object *pObj2=pTarget->Contents.Find(pDef, ANY_OWNER, OCF_FullCon);
if (pObj2) if (pObj2->CanConcatPictureWith(pObj)) pObj = pObj2;
}
// Caption
sprintf(szCaption,LoadResStr("IDS_MENU_ACTIVATE"),(const char *) pObj->GetName());
// Picture
fctSymbol.Set(fctSymbol.Surface, 0,0,C4SymbolSize,C4SymbolSize);
pObj->Picture2Facet(fctSymbol);
// Commands
sprintf(szCommand,"SetCommand(\"Activate\",Object(%d))&&ExecuteCommand()",pObj->Number);
sprintf(szCommand2,"SetCommand(\"Activate\",nil,%d,0,Object(%d),%s)&&ExecuteCommand()",pTarget->Contents.ObjectCount(pDef->id),pTarget->Number,pDef->id.ToString());
// Add menu item
Add(szCaption,fctSymbol,szCommand,iCount,pObj,"",pDef->id,szCommand2,true,pObj->GetValue(pTarget, NO_OWNER));
// facet taken over (arrg!)
fctSymbol.Default();
}
}
break;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
case C4MN_Get:
case C4MN_Contents:
// Clear items
ClearItems();
// Refill target
if (!(pTarget = RefillObject)) return false;
{
// Add target contents items
C4ObjectListIterator iter(pTarget->Contents);
while ((pObj = iter.GetNext(&iCount)))
{
pDef = pObj->Def;
if (pDef->NoGet) continue;
// Prefer fully constructed objects
if (~pObj->OCF & OCF_FullCon)
{
// easy way: only if first concat check matches
// this doesn't catch all possibilities, but that will rarely matter
C4Object *pObj2 = pTarget->Contents.Find(pDef, ANY_OWNER, OCF_FullCon);
if (pObj2) if (pObj2->CanConcatPictureWith(pObj)) pObj = pObj2;
}
// Determine whether to get or activate
bool fGet = true;
if (!(pObj->OCF & OCF_Carryable)) fGet = false; // not a carryable item
if (Identification == C4MN_Contents)
{
if (Object && !!Object->Call(PSF_RejectCollection, &C4AulParSet(C4VPropList(pObj->Def), C4VObj(pObj)))) fGet = false; // collection rejected
}
if (!(pTarget->OCF & OCF_Entrance)) fGet = true; // target object has no entrance: cannot activate - force get
// Caption
sprintf(szCaption, LoadResStr(fGet ? "IDS_MENU_GET" : "IDS_MENU_ACTIVATE"), (const char *)pObj->GetName());
// Picture
fctSymbol.Set(fctSymbol.Surface, 0, 0, C4SymbolSize, C4SymbolSize);
pObj->Picture2Facet(fctSymbol);
// Primary command: get/activate single object
sprintf(szCommand, "SetCommand(\"%s\", Object(%d)) && ExecuteCommand()", fGet ? "Get" : "Activate", pObj->Number);
// Secondary command: get/activate all objects of the chosen type
szCommand2[0] = 0; int32_t iAllCount;
if ((iAllCount = pTarget->Contents.ObjectCount(pDef->id)) > 1)
sprintf(szCommand2, "SetCommand(\"%s\", nil, %d,0, Object(%d), %s) && ExecuteCommand()", fGet ? "Get" : "Activate", iAllCount, pTarget->Number, pDef->id.ToString());
// Add menu item (with object)
Add(szCaption, fctSymbol, szCommand, iCount, pObj, "", pDef->id, szCommand2);
fctSymbol.Default();
}
}
break;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
default:
// Not an internal menu
return true;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
}
// Successfull internal refill
rfRefilled = true;
return true;
}
void C4ObjectMenu::Execute()
{
if (!IsActive()) return;
// Immediate refill check by RefillObject contents count check
if (RefillObject)
if (RefillObject->Contents.ObjectCount()!=RefillObjectContentsCount)
{ NeedRefill=true; RefillObjectContentsCount=RefillObject->Contents.ObjectCount(); }
// inherited
C4Menu::Execute();
}
void C4ObjectMenu::OnUserSelectItem(int32_t Player, int32_t iIndex)
{
// queue.... 2do
Game.Input.Add(CID_PlrControl, new C4ControlPlayerControl(Player,Game.PlayerControlDefs.InternalCons.CON_ObjectMenuSelect,iIndex | C4MN_AdjustPosition));
}
void C4ObjectMenu::OnUserEnter(int32_t Player, int32_t iIndex, bool fRight)
{
// object menu: Through queue 2do
Game.Input.Add(CID_PlrControl, new C4ControlPlayerControl(Player,fRight ? Game.PlayerControlDefs.InternalCons.CON_ObjectMenuOKAll : Game.PlayerControlDefs.InternalCons.CON_ObjectMenuOK,iIndex));
}
void C4ObjectMenu::OnUserClose()
{
// Queue 2do
Game.Input.Add(CID_PlrControl, new C4ControlPlayerControl(::MouseControl.GetPlayer(),Game.PlayerControlDefs.InternalCons.CON_ObjectMenuCancel,0));
}
bool C4ObjectMenu::IsReadOnly()
{
// get viewport
C4Viewport *pVP = GetViewport();
if (!pVP) return false;
// is it an observer viewport?
if (pVP->fIsNoOwnerViewport)
// is this a synced menu?
if (eCallbackType == CB_Object || eCallbackType == CB_Scenario)
// then don't control it!
return true;
// if the player is eliminated, do not control either!
if (!pVP->fIsNoOwnerViewport)
{
C4Player *pPlr = ::Players.Get(::MouseControl.GetPlayer());
if (pPlr && pPlr->Eliminated) return true;
}
return false;
}
int32_t C4ObjectMenu::GetControllingPlayer()
{
// menu controlled by object controller
return Object ? Object->Controller : NO_OWNER;
}
bool C4ObjectMenu::MenuCommand(const char *szCommand, bool fIsCloseCommand)
{
switch (eCallbackType)
{
case CB_Object:
// Object menu
if (Object) Object->MenuCommand(szCommand);
break;
case CB_Scenario:
// Object menu with scenario script callback
::GameScript.DirectExec(NULL, szCommand, "MenuCommand");
break;
case CB_None:
// TODO
break;
}
return true;
}

View File

@ -1,89 +0,0 @@
/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 1998-2000, Matthes Bender
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
* Copyright (c) 2009-2013, The OpenClonk Team and contributors
*
* Distributed under the terms of the ISC license; see accompanying file
* "COPYING" for details.
*
* "Clonk" is a registered trademark of Matthes Bender, used with permission.
* See accompanying file "TRADEMARK" for details.
*
* To redistribute this file separately, substitute the full license texts
* for the above references.
*/
// Menus attached to objects; script created or internal
// These menus are shown to players if the target object is the current cursor
#ifndef INC_C4ObjectMenu
#define INC_C4ObjectMenu
#include "C4Menu.h"
enum
{
C4MN_None = 0,
/*C4MN_Construction = 1, obsolete, now reserved */
/*C4MN_Bridge = 2, obsolete, now reserved */
C4MN_Take = 3,
C4MN_Buy = 4,
C4MN_Sell = 5,
C4MN_Activate = 6,
/*C4MN_Hostility = 7, now defined in C4MainMenu*/
/*C4MN_Surrender = 8, obsolete, now reserved*/
/*C4MN_Put = 9, obsolete, now reserved*/
/*C4MN_Magic = 10, obsolete, now reserved*/
/*C4MN_Main = 12, now defined in C4MainMenu*/
C4MN_Get = 13,
/*C4MN_Context = 14, obsolete, now reserved*/
C4MN_Info = 15,
/*C4MN_TeamSelection= 16, now defined in C4MainMenu */
/*C4MN_TeamSwitch = 17, now defined in C4MainMenu */
C4MN_Contents = 18
};
class C4ObjectMenu : public C4Menu
{
public:
C4ObjectMenu();
virtual void Default();
enum CallbackType { CB_None=0, CB_Object, CB_Scenario };
protected:
C4Object *Object;
C4Object *ParentObject;
C4Object *RefillObject;
int32_t RefillObjectContentsCount;
CallbackType eCallbackType;
bool UserMenu; // set for script created menus; user menus do CloseQuery and MenuSelection callbacks
bool CloseQuerying; // recursion check for close query callback
void LocalInit(C4Object *pObject, bool fUserMenu);
public:
void SetRefillObject(C4Object *pObj);
void ClearPointers(C4Object *pObj);
bool Init(C4FacetSurface &fctSymbol, const char *szEmpty, C4Object *pObject, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal, bool fUserMenu=false);
bool InitRefSym(const C4TargetFacet &fctSymbol, const char *szEmpty, C4Object *pObject, int32_t iExtra=C4MN_Extra_None, int32_t iExtraData=0, int32_t iId=0, int32_t iStyle=C4MN_Style_Normal, bool fUserMenu=false);
void Execute();
virtual C4Object* GetParentObject();
bool IsCloseQuerying() const { return !!CloseQuerying; }
protected:
virtual bool MenuCommand(const char *szCommand, bool fIsCloseCommand);
virtual bool DoRefillInternal(bool &rfRefilled);
virtual void OnSelectionChanged(int32_t iNewSelection); // do object callbacks if selection changed in user menus
virtual bool IsCloseDenied(); // do MenuQueryCancel-callbacks for user menus
virtual bool IsReadOnly(); // determine whether the menu is just viewed by an observer, and should not issue any calls
virtual void OnUserSelectItem(int32_t Player, int32_t iIndex);
virtual void OnUserEnter(int32_t Player, int32_t iIndex, bool fRight);
virtual void OnUserClose();
virtual int32_t GetControllingPlayer();
};
#endif

View File

@ -28,7 +28,6 @@
#include <C4MeshAnimation.h> #include <C4MeshAnimation.h>
#include <C4ObjectCom.h> #include <C4ObjectCom.h>
#include <C4ObjectInfo.h> #include <C4ObjectInfo.h>
#include <C4ObjectMenu.h>
#include <C4Player.h> #include <C4Player.h>
#include <C4PlayerList.h> #include <C4PlayerList.h>
#include <C4Random.h> #include <C4Random.h>
@ -786,358 +785,6 @@ static C4PropList* FnGetID(C4Object *Obj)
return Obj->GetPrototype(); return Obj->GetPrototype();
} }
static Nillable<C4ID> FnGetMenu(C4Object *Obj)
{
if (Obj->Menu && Obj->Menu->IsActive())
return C4ID(Obj->Menu->GetIdentification());
return C4Void();
}
static bool FnCreateMenu(C4Object *Obj, C4Def *pDef, C4Object *pCommandObj,
long iExtra, C4String *szCaption, long iExtraData,
long iStyle, bool fPermanent, C4ID idMenuID)
{
if (pCommandObj)
// object menu: Validate object
if (!pCommandObj->Status) return false;
// else scenario script callback: No command object OK
// Create symbol
C4FacetSurface fctSymbol;
fctSymbol.Create(C4SymbolSize,C4SymbolSize);
if (pDef) pDef->Draw(fctSymbol);
// Clear any old menu, init new menu
if (!Obj->CloseMenu(false)) return false;
if (!Obj->Menu) Obj->Menu = new C4ObjectMenu; else Obj->Menu->ClearItems();
Obj->Menu->Init(fctSymbol,FnStringPar(szCaption),pCommandObj,iExtra,iExtraData,(idMenuID ? idMenuID : pDef ? pDef->id : C4ID::None).GetHandle(),iStyle,true);
// Set permanent
Obj->Menu->SetPermanent(fPermanent);
return true;
}
const int C4MN_Add_ImgRank = 1,
C4MN_Add_ImgIndexed = 2,
C4MN_Add_ImgObjRank = 3,
C4MN_Add_ImgObject = 4,
C4MN_Add_ImgTextSpec = 5,
C4MN_Add_ImgColor = 6,
C4MN_Add_ImgPropListSpec = 7,
C4MN_Add_MaxImage = 127, // mask for param which decides what to draw as the menu symbol
C4MN_Add_PassValue = 128,
C4MN_Add_ForceCount = 256,
C4MN_Add_ForceNoDesc = 512;
#ifndef _MSC_VER
#define _snprintf snprintf
#endif
static bool FnAddMenuItem(C4Object *Obj, C4String * szCaption, C4String * szCommand, C4Def * pDef, int iCount, const C4Value & Parameter, C4String * szInfoCaption, int iExtra, const C4Value & XPar, const C4Value & XPar2)
{
if (!Obj->Menu) return false;
char caption[256+1];
char parameter[256+1];
char dummy[256+1];
char command[512+1];
char command2[512+1];
char infocaption[C4MaxTitle+1];
// get needed symbol size
int iSymbolSize = Obj->Menu->GetSymbolSize();
// Compose caption with def name
if (szCaption)
{
const char * s = FnStringPar(szCaption);
const char * sep = strstr(s, "%s");
if (sep && pDef)
{
strncpy(caption, s, std::min<intptr_t>(sep - s,256));
caption[std::min<intptr_t>(sep - s,256)] = 0;
strncat(caption, pDef->GetName(), 256);
strncat(caption, sep + 2, 256);
}
else
{
strncpy(caption, s, 256);
caption[256] = 0;
}
}
else
caption[0] = 0;
// create string to include type-information in command
switch (Parameter.GetType())
{
case C4V_Int:
sprintf(parameter, "%d", Parameter.getInt());
break;
case C4V_Bool:
SCopy(Parameter.getBool() ? "true" : "false", parameter);
break;
case C4V_PropList:
if (Parameter.getPropList()->GetObject())
sprintf(parameter, "Object(%d)", Parameter.getPropList()->GetObject()->Number);
else if (Parameter.getPropList()->GetDef())
sprintf(parameter, "C4Id(\"%s\")", Parameter.getPropList()->GetDef()->id.ToString());
else
throw C4AulExecError("proplist as parameter to AddMenuItem");
break;
case C4V_String:
// note this breaks if there is '"' in the string.
parameter[0] = '"';
SCopy(Parameter.getStr()->GetCStr(), parameter + 1, sizeof(command)-3);
SAppendChar('"', command);
break;
case C4V_Nil:
SCopy("nil", parameter);
break;
case C4V_Array:
// Arrays were never allowed, so tell the scripter
throw C4AulExecError("array as parameter to AddMenuItem");
default:
return false;
}
// own value
bool fOwnValue = false; long iValue=0;
if (iExtra & C4MN_Add_PassValue)
{
fOwnValue = true;
iValue = XPar2.getInt();
}
// New Style: native script command
size_t i = 0;
for (; i < SLen(FnStringPar(szCommand)); i++)
if (!IsIdentifier(FnStringPar(szCommand)[i]))
break;
if (i < SLen(FnStringPar(szCommand)))
{
// Search for "%d" an replace it by "%s" for insertion of formatted parameter
SCopy(FnStringPar(szCommand), dummy, 256);
char* pFound = const_cast<char*>(SSearch(dummy, "%d"));
if (pFound != 0)
*(pFound - 1) = 's';
// Compose left-click command
sprintf(command, dummy, parameter, 0);
// Compose right-click command
sprintf(command2, dummy, parameter, 1);
}
// Old style: function name with id and parameter
else
{
const char *szScriptCom = FnStringPar(szCommand);
if (szScriptCom && *szScriptCom)
{
if (iExtra & C4MN_Add_PassValue)
{
// with value
sprintf(command,"%s(%s,%s,0,%ld)",szScriptCom,pDef ? pDef->id.ToString() : "nil",parameter,iValue);
sprintf(command2,"%s(%s,%s,1,%ld)",szScriptCom,pDef ? pDef->id.ToString() : "nil",parameter,iValue);
}
else
{
// without value
sprintf(command,"%s(%s,%s)",szScriptCom,pDef ? pDef->id.ToString() : "nil",parameter);
sprintf(command2,"%s(%s,%s,1)",szScriptCom,pDef ? pDef->id.ToString() : "nil",parameter);
}
}
else
{
// no command
*command = *command2 = '\0';
}
}
// Info caption
SCopy(FnStringPar(szInfoCaption),infocaption,C4MaxTitle);
// Create symbol
C4FacetSurface fctSymbol;
C4DefGraphics* pGfx = NULL;
C4Object* pGfxObj = NULL;
switch (iExtra & C4MN_Add_MaxImage)
{
case C4MN_Add_ImgRank:
{
// symbol by rank
C4Facet *pfctRankSym = &::GraphicsResource.fctRank;
int32_t iRankSymNum = ::GraphicsResource.iNumRanks;
if (pDef && pDef->pRankSymbols)
{
pfctRankSym = pDef->pRankSymbols;
iRankSymNum = pDef->iNumRankSymbols;
}
C4RankSystem::DrawRankSymbol(&fctSymbol, iCount, pfctRankSym, iRankSymNum, true);
iCount=0;
break;
}
case C4MN_Add_ImgIndexed:
// draw indexed facet
fctSymbol.Create(iSymbolSize,iSymbolSize);
if (pDef)
pDef->Draw(fctSymbol, false, 0, NULL, XPar.getInt());
break;
case C4MN_Add_ImgObjRank:
{
// draw current gfx of XPar_C4V including rank
if (!XPar.CheckConversion(C4V_Object)) return false;
C4Object *pGfxObj = XPar.getObj();
if (pGfxObj && pGfxObj->Status)
{
// create graphics
// get rank gfx
C4Facet *pRankRes=&::GraphicsResource.fctRank;
long iRankCnt=::GraphicsResource.iNumRanks;
C4Def *pDef=pGfxObj->Def;
if (pDef->pRankSymbols)
{
pRankRes=pDef->pRankSymbols;
iRankCnt=pDef->iNumRankSymbols;
}
// context menu
C4Facet fctRank;
if (Obj->Menu->IsContextMenu())
{
// context menu entry: left object gfx
long C4MN_SymbolSize = Obj->Menu->GetItemHeight();
fctSymbol.Create(C4MN_SymbolSize * 2,C4MN_SymbolSize);
fctSymbol.Wdt = C4MN_SymbolSize;
pGfxObj->Def->Draw(fctSymbol, false, pGfxObj->Color, pGfxObj);
// right of it the rank
fctRank = fctSymbol;
fctRank.X = C4MN_SymbolSize;
fctSymbol.Wdt *= 2;
}
else
{
// regular menu: draw object picture
fctSymbol.Create(iSymbolSize,iSymbolSize);
pGfxObj->Def->Draw(fctSymbol, false, pGfxObj->Color, pGfxObj);
// rank at top-right corner
fctRank = fctSymbol;
fctRank.X = fctRank.Wdt - pRankRes->Wdt;
fctRank.Wdt = pRankRes->Wdt;
fctRank.Hgt = pRankRes->Hgt;
}
// draw rank
if (pGfxObj->Info)
{
C4Facet fctBackup = (const C4Facet &) fctSymbol;
fctSymbol.Set(fctRank);
C4RankSystem::DrawRankSymbol(&fctSymbol, pGfxObj->Info->Rank, pRankRes, iRankCnt, true);
fctSymbol.Set(fctBackup);
}
}
}
break;
case C4MN_Add_ImgObject:
{
// draw object picture
if (!XPar.CheckConversion(C4V_Object))
throw C4AulExecError(FormatString("call to \"%s\" parameter %d: got \"%s\", but expected \"%s\"!",
"AddMenuItem", 8, XPar.GetTypeName(), GetC4VName(C4V_Object)
).getData());
pGfxObj = XPar.getObj();
}
break;
case C4MN_Add_ImgTextSpec:
{
C4Def* pDef = C4Id2Def(C4ID(std::string(caption)));
if(pDef)
{
pGfx = &pDef->Graphics;
}
else
{
fctSymbol.Create(iSymbolSize,iSymbolSize);
uint32_t dwClr = XPar.getInt();
if (!szCaption || !Game.DrawTextSpecImage(fctSymbol, caption, NULL, dwClr ? dwClr : 0xff))
return false;
}
*caption = '\0';
}
break;
case C4MN_Add_ImgPropListSpec:
{
C4PropList *gfx_proplist = XPar.getPropList();
fctSymbol.Create(iSymbolSize,iSymbolSize);
if (!Game.DrawPropListSpecImage(fctSymbol, gfx_proplist))
return false;
}
break;
case C4MN_Add_ImgColor:
// draw colored def facet
fctSymbol.Create(iSymbolSize,iSymbolSize);
if (pDef)
pDef->Draw(fctSymbol, false, XPar.getInt());
break;
default:
// default: by def, if it is not specifically NONE
if (pDef)
{
fctSymbol.Create(iSymbolSize,iSymbolSize);
pDef->Draw(fctSymbol);
}
else
{
// otherwise: Clear symbol!
}
break;
}
// Convert default zero count to no count
if (iCount==0 && !(iExtra & C4MN_Add_ForceCount)) iCount=C4MN_Item_NoCount;
// menuitems without commands are never selectable
bool fIsSelectable = !!*command;
// Add menu item
if(pGfxObj)
Obj->Menu->Add(caption,pGfxObj,command,iCount,NULL,infocaption,pDef ? pDef->id : C4ID::None,command2,fOwnValue,iValue,fIsSelectable);
else if(pGfx)
Obj->Menu->Add(caption,pGfx,command,iCount,NULL,infocaption,pDef ? pDef->id : C4ID::None,command2,fOwnValue,iValue,fIsSelectable);
else
Obj->Menu->Add(caption,fctSymbol,command,iCount,NULL,infocaption,pDef ? pDef->id : C4ID::None,command2,fOwnValue,iValue,fIsSelectable);
return true;
}
static bool FnSelectMenuItem(C4Object *Obj, long iItem)
{
if (!Obj->Menu) return false;
return !!Obj->Menu->SetSelection(iItem, false, true);
}
static bool FnSetMenuDecoration(C4Object *Obj, C4ID idNewDeco)
{
if (!Obj->Menu) return false;
C4GUI::FrameDecoration *pNewDeco = new C4GUI::FrameDecoration();
if (!pNewDeco->SetByDef(idNewDeco))
{
delete pNewDeco;
return false;
}
Obj->Menu->SetFrameDeco(pNewDeco);
return true;
}
static bool FnSetMenuTextProgress(C4Object *Obj, long iNewProgress)
{
if (!Obj->Menu) return false;
return Obj->Menu->SetTextProgress(iNewProgress, false);
}
// Check / Status // Check / Status
static C4Object *FnContained(C4Object *Obj) static C4Object *FnContained(C4Object *Obj)
@ -1299,12 +946,6 @@ static long FnObjectNumber(C4Object *Obj)
// See FnObject // See FnObject
} }
static long FnShowInfo(C4Object *Obj, C4Object *pObj)
{
if (!pObj) pObj=Obj; if (!pObj) return false;
return Obj->ActivateMenu(C4MN_Info,0,0,0,pObj);
}
static C4Void FnSetMass(C4Object *Obj, long iValue) static C4Void FnSetMass(C4Object *Obj, long iValue)
{ {
Obj->OwnMass=iValue-Obj->Def->Mass; Obj->OwnMass=iValue-Obj->Def->Mass;
@ -1421,17 +1062,6 @@ static Nillable<long> FnGetClrModulation(C4Object *Obj, long iOverlayID)
return Obj->ColorMod; return Obj->ColorMod;
} }
static bool FnCloseMenu(C4Object *Obj)
{
return !!Obj->CloseMenu(true);
}
static Nillable<long> FnGetMenuSelection(C4Object *Obj)
{
if (!Obj->Menu || !Obj->Menu->IsActive()) return C4Void();
return Obj->Menu->GetSelection();
}
static bool FnCanConcatPictureWith(C4Object *Obj, C4Object *pObj) static bool FnCanConcatPictureWith(C4Object *Obj, C4Object *pObj)
{ {
// safety // safety
@ -1536,15 +1166,6 @@ static long FnGetDefBottom(C4PropList * _this)
return 0; return 0;
} }
static bool FnSetMenuSize(C4Object *Obj, long iCols, long iRows)
{
// get menu
C4Menu *pMnu=Obj->Menu;
if (!pMnu || !pMnu->IsActive()) return false;
pMnu->SetSize(Clamp<long>(iCols, 0, 50), Clamp<long>(iRows, 0, 50));
return true;
}
static bool FnGetCrewEnabled(C4Object *Obj) static bool FnGetCrewEnabled(C4Object *Obj)
{ {
// return status // return status
@ -1593,16 +1214,6 @@ static C4Void FnDoCrewExp(C4Object *Obj, long iChange)
return C4Void(); return C4Void();
} }
static bool FnClearMenuItems(C4Object *Obj)
{
// check menu
if (!Obj->Menu) return false;
// clear the items
Obj->Menu->ClearItems();
// success
return true;
}
static C4Object *FnGetObjectLayer(C4Object *Obj) static C4Object *FnGetObjectLayer(C4Object *Obj)
{ {
// get layer object // get layer object
@ -2476,28 +2087,6 @@ C4ScriptConstDef C4ScriptObjectConstMap[]=
{ "VIS_LayerToggle" ,C4V_Int, VIS_LayerToggle}, { "VIS_LayerToggle" ,C4V_Int, VIS_LayerToggle},
{ "VIS_OverlayOnly" ,C4V_Int, VIS_OverlayOnly}, { "VIS_OverlayOnly" ,C4V_Int, VIS_OverlayOnly},
{ "C4MN_Style_Normal" ,C4V_Int, C4MN_Style_Normal},
{ "C4MN_Style_Context" ,C4V_Int, C4MN_Style_Context},
{ "C4MN_Style_Info" ,C4V_Int, C4MN_Style_Info},
{ "C4MN_Style_Dialog" ,C4V_Int, C4MN_Style_Dialog},
{ "C4MN_Style_EqualItemHeight",C4V_Int, C4MN_Style_EqualItemHeight},
{ "C4MN_Extra_None" ,C4V_Int, C4MN_Extra_None},
{ "C4MN_Extra_Components" ,C4V_Int, C4MN_Extra_Components},
{ "C4MN_Extra_Value" ,C4V_Int, C4MN_Extra_Value},
{ "C4MN_Extra_Info" ,C4V_Int, C4MN_Extra_Info},
{ "C4MN_Add_ImgRank" ,C4V_Int, C4MN_Add_ImgRank},
{ "C4MN_Add_ImgIndexed" ,C4V_Int, C4MN_Add_ImgIndexed},
{ "C4MN_Add_ImgObjRank" ,C4V_Int, C4MN_Add_ImgObjRank},
{ "C4MN_Add_ImgObject" ,C4V_Int, C4MN_Add_ImgObject},
{ "C4MN_Add_ImgTextSpec" ,C4V_Int, C4MN_Add_ImgTextSpec},
{ "C4MN_Add_ImgPropListSpec",C4V_Int, C4MN_Add_ImgPropListSpec},
{ "C4MN_Add_ImgColor" ,C4V_Int, C4MN_Add_ImgColor},
{ "C4MN_Add_PassValue" ,C4V_Int, C4MN_Add_PassValue},
{ "C4MN_Add_ForceCount" ,C4V_Int, C4MN_Add_ForceCount},
{ "C4MN_Add_ForceNoDesc" ,C4V_Int, C4MN_Add_ForceNoDesc},
{ "GFXOV_MODE_None" ,C4V_Int, C4GraphicsOverlay::MODE_None }, // gfx overlay modes { "GFXOV_MODE_None" ,C4V_Int, C4GraphicsOverlay::MODE_None }, // gfx overlay modes
{ "GFXOV_MODE_Base" ,C4V_Int, C4GraphicsOverlay::MODE_Base }, // { "GFXOV_MODE_Base" ,C4V_Int, C4GraphicsOverlay::MODE_Base }, //
{ "GFXOV_MODE_Action" ,C4V_Int, C4GraphicsOverlay::MODE_Action }, // { "GFXOV_MODE_Action" ,C4V_Int, C4GraphicsOverlay::MODE_Action }, //
@ -2612,7 +2201,6 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
AddFunc(pEngine, "GetOwner", FnGetOwner); AddFunc(pEngine, "GetOwner", FnGetOwner);
AddFunc(pEngine, "GetMass", FnGetMass); AddFunc(pEngine, "GetMass", FnGetMass);
AddFunc(pEngine, "GetBreath", FnGetBreath); AddFunc(pEngine, "GetBreath", FnGetBreath);
AddFunc(pEngine, "GetMenu", FnGetMenu);
AddFunc(pEngine, "GetVertexNum", FnGetVertexNum); AddFunc(pEngine, "GetVertexNum", FnGetVertexNum);
AddFunc(pEngine, "GetVertex", FnGetVertex); AddFunc(pEngine, "GetVertex", FnGetVertex);
AddFunc(pEngine, "SetVertex", FnSetVertex); AddFunc(pEngine, "SetVertex", FnSetVertex);
@ -2670,11 +2258,6 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
AddFunc(pEngine, "SetComponent", FnSetComponent); AddFunc(pEngine, "SetComponent", FnSetComponent);
AddFunc(pEngine, "SetCrewStatus", FnSetCrewStatus, false); AddFunc(pEngine, "SetCrewStatus", FnSetCrewStatus, false);
AddFunc(pEngine, "SetPosition", FnSetPosition); AddFunc(pEngine, "SetPosition", FnSetPosition);
AddFunc(pEngine, "CreateMenu", FnCreateMenu);
AddFunc(pEngine, "AddMenuItem", FnAddMenuItem);
AddFunc(pEngine, "SelectMenuItem", FnSelectMenuItem);
AddFunc(pEngine, "SetMenuDecoration", FnSetMenuDecoration);
AddFunc(pEngine, "SetMenuTextProgress", FnSetMenuTextProgress);
AddFunc(pEngine, "ObjectDistance", FnObjectDistance); AddFunc(pEngine, "ObjectDistance", FnObjectDistance);
AddFunc(pEngine, "GetValue", FnGetValue); AddFunc(pEngine, "GetValue", FnGetValue);
AddFunc(pEngine, "GetRank", FnGetRank); AddFunc(pEngine, "GetRank", FnGetRank);
@ -2690,18 +2273,13 @@ void InitObjectFunctionMap(C4AulScriptEngine *pEngine)
AddFunc(pEngine, "CanConcatPictureWith", FnCanConcatPictureWith); AddFunc(pEngine, "CanConcatPictureWith", FnCanConcatPictureWith);
AddFunc(pEngine, "SetGraphics", FnSetGraphics); AddFunc(pEngine, "SetGraphics", FnSetGraphics);
AddFunc(pEngine, "ObjectNumber", FnObjectNumber); AddFunc(pEngine, "ObjectNumber", FnObjectNumber);
AddFunc(pEngine, "ShowInfo", FnShowInfo);
AddFunc(pEngine, "CheckVisibility", FnCheckVisibility); AddFunc(pEngine, "CheckVisibility", FnCheckVisibility);
AddFunc(pEngine, "SetClrModulation", FnSetClrModulation); AddFunc(pEngine, "SetClrModulation", FnSetClrModulation);
AddFunc(pEngine, "GetClrModulation", FnGetClrModulation); AddFunc(pEngine, "GetClrModulation", FnGetClrModulation);
AddFunc(pEngine, "CloseMenu", FnCloseMenu);
AddFunc(pEngine, "GetMenuSelection", FnGetMenuSelection);
AddFunc(pEngine, "GetDefBottom", FnGetDefBottom); AddFunc(pEngine, "GetDefBottom", FnGetDefBottom);
AddFunc(pEngine, "SetMenuSize", FnSetMenuSize);
AddFunc(pEngine, "GetCrewEnabled", FnGetCrewEnabled); AddFunc(pEngine, "GetCrewEnabled", FnGetCrewEnabled);
AddFunc(pEngine, "SetCrewEnabled", FnSetCrewEnabled); AddFunc(pEngine, "SetCrewEnabled", FnSetCrewEnabled);
AddFunc(pEngine, "DoCrewExp", FnDoCrewExp); AddFunc(pEngine, "DoCrewExp", FnDoCrewExp);
AddFunc(pEngine, "ClearMenuItems", FnClearMenuItems);
AddFunc(pEngine, "GetObjectLayer", FnGetObjectLayer); AddFunc(pEngine, "GetObjectLayer", FnGetObjectLayer);
AddFunc(pEngine, "SetObjectLayer", FnSetObjectLayer); AddFunc(pEngine, "SetObjectLayer", FnSetObjectLayer);
AddFunc(pEngine, "SetShape", FnSetShape); AddFunc(pEngine, "SetShape", FnSetShape);

View File

@ -33,7 +33,6 @@
#include <C4Log.h> #include <C4Log.h>
#include <C4FullScreen.h> #include <C4FullScreen.h>
#include <C4GameOverDlg.h> #include <C4GameOverDlg.h>
#include <C4ObjectMenu.h>
#include <C4MouseControl.h> #include <C4MouseControl.h>
#include <C4GameMessage.h> #include <C4GameMessage.h>
#include <C4GraphicsResource.h> #include <C4GraphicsResource.h>
@ -112,8 +111,6 @@ void C4Player::ClearPointers(C4Object *pObj, bool fDeath)
if (ViewCursor==pObj) ViewCursor = NULL; if (ViewCursor==pObj) ViewCursor = NULL;
// View // View
if (ViewTarget==pObj) ViewTarget=NULL; if (ViewTarget==pObj) ViewTarget=NULL;
// Menu
Menu.ClearPointers(pObj);
// messageboard-queries // messageboard-queries
RemoveMessageBoardQuery(pObj); RemoveMessageBoardQuery(pObj);
} }
@ -1217,7 +1214,7 @@ bool C4Player::ActivateMenuTeamSelection(bool fFromMain)
{ {
// Menu symbol/init // Menu symbol/init
bool fSwitch = !(Status==PS_TeamSelection); bool fSwitch = !(Status==PS_TeamSelection);
Menu.InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team),LoadResStr("IDS_MSG_SELTEAM"),Number, C4MN_Extra_None, 0, fSwitch ? C4MN_TeamSwitch : C4MN_TeamSelection); Menu.InitRefSym(C4GUI::Icon::GetIconFacet(C4GUI::Ico_Team),LoadResStr("IDS_MSG_SELTEAM"),Number, fSwitch ? C4MN_TeamSwitch : C4MN_TeamSelection);
Menu.SetAlignment(fSwitch ? C4MN_Align_Left | C4MN_Align_Bottom : 0); Menu.SetAlignment(fSwitch ? C4MN_Align_Left | C4MN_Align_Bottom : 0);
Menu.Refill(); Menu.Refill();
// Go back to options menu on close // Go back to options menu on close