Skip to content

Commit

Permalink
Implement more of InGameUI (#1065)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonwil authored Feb 1, 2024
1 parent eff5c4e commit 2243feb
Show file tree
Hide file tree
Showing 13 changed files with 1,576 additions and 105 deletions.
1,265 changes: 1,226 additions & 39 deletions src/game/client/ingameui.cpp

Large diffs are not rendered by default.

81 changes: 45 additions & 36 deletions src/game/client/ingameui.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "color.h"
#include "coord.h"
#include "drawable.h"
#include "gamewindow.h"
#include "mouse.h"
#include "object.h"
#include "radiusdecal.h"
Expand Down Expand Up @@ -131,6 +132,8 @@ class SuperweaponInfo : public MemoryPoolObject

class FloatingTextData : public MemoryPoolObject
{
IMPLEMENT_POOL(FloatingTextData);

public:
FloatingTextData();
~FloatingTextData();
Expand Down Expand Up @@ -271,56 +274,56 @@ class InGameUI : public SubsystemInterface, public SnapShot
virtual void Xfer_Snapshot(Xfer *xfer) override;
virtual void Load_Post_Process() override;
virtual void Popup_Message(
Utf8String const &message, int width_percent, int height_percent, int width, bool pause, bool pause_music);
virtual void Popup_Message(Utf8String const &message,
const Utf8String &message, int width_percent, int height_percent, int width, bool pause, bool pause_music);
virtual void Popup_Message(const Utf8String &message,
int width_percent,
int height_percent,
int width,
int color,
bool pause,
bool pause_music);
virtual void Message_Color(RGBColor const *color, Utf16String message, ...);
virtual void Message_Color(const RGBColor *color, Utf16String message, ...);
virtual void Message(Utf16String message, ...);
virtual void Message(Utf8String message, ...);
virtual void Toggle_Messages() { m_messagesOn = !m_messagesOn; }
virtual bool Is_Messages_On() { return m_messagesOn; }
virtual void Military_Subtitle(Utf8String const &subtitle, int duration);
virtual void Military_Subtitle(const Utf8String &subtitle, int duration);
virtual void Remove_Military_Subtitle();
virtual void Display_Cant_Build_Message(LegalBuildCode code);
virtual void Begin_Area_Select_Hint(GameMessage const *msg);
virtual void End_Area_Select_Hint(GameMessage const *msg);
virtual void Create_Move_Hint(GameMessage const *msg);
virtual void Create_Attack_Hint(GameMessage const *msg);
virtual void Create_Force_Attack_Hint(GameMessage const *msg);
virtual void Create_Mouseover_Hint(GameMessage const *msg);
virtual void Create_Command_Hint(GameMessage const *msg);
virtual void Create_Garrison_Hint(GameMessage const *msg);
virtual void Begin_Area_Select_Hint(const GameMessage *msg);
virtual void End_Area_Select_Hint(const GameMessage *msg);
virtual void Create_Move_Hint(const GameMessage *msg);
virtual void Create_Attack_Hint(const GameMessage *msg);
virtual void Create_Force_Attack_Hint(const GameMessage *msg);
virtual void Create_Mouseover_Hint(const GameMessage *msg);
virtual void Create_Command_Hint(const GameMessage *msg);
virtual void Create_Garrison_Hint(const GameMessage *msg);
virtual void Add_Superweapon(
int player_index, Utf8String const &power_name, ObjectID id, SpecialPowerTemplate const *power_template);
int player_index, const Utf8String &power_name, ObjectID id, const SpecialPowerTemplate *power_template);
virtual bool Remove_Superweapon(
int player_index, Utf8String const &power_name, ObjectID id, SpecialPowerTemplate const *power_template);
virtual void Object_Changed_Team(Object const *obj, int old_player_index, int new_player_index);
int player_index, const Utf8String &power_name, ObjectID id, const SpecialPowerTemplate *power_template);
virtual void Object_Changed_Team(const Object *obj, int old_player_index, int new_player_index);
virtual void Set_Superweapon_Display_Enabled_By_Script(bool enable);
virtual bool Get_Superweapon_Display_Enabled_By_Script();
virtual void Hide_Object_Superweapon_Display_By_Script(Object const *obj);
virtual void Show_Object_Superweapon_Display_By_Script(Object const *obj);
virtual void Hide_Object_Superweapon_Display_By_Script(const Object *obj);
virtual void Show_Object_Superweapon_Display_By_Script(const Object *obj);
virtual void Set_Scrolling(bool is_scrolling);
virtual bool Is_Scrolling();
virtual void Set_Selecting(bool is_selecting);
virtual bool Is_Selecting();
virtual void Set_Scroll_Amount(Coord2D amt);
virtual Coord2D Get_Scroll_Amount();
virtual void Set_GUI_Command(CommandButton const *command);
virtual CommandButton const *Get_GUI_Command();
virtual void Place_Build_Available(ThingTemplate const *build, Drawable *build_drawable);
virtual ThingTemplate const *Get_Pending_Place_Type();
virtual ObjectID const Get_Pending_Place_Source_Object_ID();
virtual void Set_GUI_Command(const CommandButton *command);
virtual const CommandButton *Get_GUI_Command();
virtual void Place_Build_Available(const ThingTemplate *build, Drawable *build_drawable);
virtual const ThingTemplate *Get_Pending_Place_Type();
virtual ObjectID Get_Pending_Place_Source_Object_ID();
#ifndef GAME_DEBUG_STRUCTS
virtual bool Get_Prevent_Left_Click_Deselection_In_Alternate_Mouse_Mode_For_One_Click();
virtual void Set_Prevent_Left_Click_Deselection_In_Alternate_Mouse_Mode_For_One_Click(bool prevent);
#endif
virtual void Set_Placement_Start(ICoord2D const *start);
virtual void Set_Placement_End(ICoord2D const *end);
virtual void Set_Placement_Start(const ICoord2D *start);
virtual void Set_Placement_End(const ICoord2D *end);
virtual bool Is_Placement_Anchored();
virtual void Get_Placement_Points(ICoord2D *start, ICoord2D *end);
virtual float Get_Placement_Angle();
Expand All @@ -338,23 +341,23 @@ class InGameUI : public SubsystemInterface, public SnapShot
virtual bool Is_Any_Selected_KindOf(KindOfType kindof);
virtual bool Is_All_Selected_KindOf(KindOfType kindof);
virtual void Set_Radius_Cursor(
RadiusCursorType cursor, SpecialPowerTemplate const *power_template, WeaponSlotType weapon_slot);
RadiusCursorType cursor, const SpecialPowerTemplate *power_template, WeaponSlotType weapon_slot);
virtual void Set_Radius_Cursor_None() { Set_Radius_Cursor(RADIUS_CURSOR_NONE, nullptr, WEAPONSLOT_PRIMARY); }
virtual void Set_Input_Enabled(bool enable);
virtual bool Get_Input_Enabled() { return m_inputEnabled; }
virtual void Disregard_Drawable(Drawable *draw);
virtual void Pre_Draw();
virtual void Post_Draw();
virtual void Play_Movie(Utf8String const &movie_name);
virtual void Play_Movie(const Utf8String &movie_name);
virtual void Stop_Movie();
virtual VideoBuffer *Video_Buffer();
virtual void Play_Cameo_Movie(Utf8String const &movie_name);
virtual void Play_Cameo_Movie(const Utf8String &movie_name);
virtual void Stop_Cameo_Movie();
virtual VideoBuffer *Cameo_Video_Buffer();
virtual DrawableID Get_Moused_Over_Drawable_ID();
virtual void Set_Quit_Menu_Visible(bool visible) { m_isQuitMenuVisible = visible; }
virtual bool Is_Quit_Menu_Visible() { return m_isQuitMenuVisible; }
virtual FieldParse const *Get_Field_Parse() { return s_fieldParseTable; }
virtual const FieldParse *Get_Field_Parse() { return s_fieldParseTable; }
virtual int Select_Units_Matching_Current_Selection();
virtual int Select_Matching_Across_Screen();
virtual int Select_Matching_Across_Map();
Expand All @@ -366,15 +369,15 @@ class InGameUI : public SubsystemInterface, public SnapShot
BitFlags<KINDOF_COUNT> must_be_set, BitFlags<KINDOF_COUNT> must_be_clear);
virtual int Select_All_Units_By_Type_Across_Region(
IRegion2D *region, BitFlags<KINDOF_COUNT> must_be_set, BitFlags<KINDOF_COUNT> must_be_clear);
virtual void Build_Region(ICoord2D const *anchor, ICoord2D const *dest, IRegion2D *region);
virtual void Build_Region(const ICoord2D *anchor, const ICoord2D *dest, IRegion2D *region);
virtual bool Get_Displayed_Max_Warning() { return m_displayedMaxWarning; }
virtual void Set_Displayed_Max_Warning(bool selected) { m_displayedMaxWarning = selected; }
virtual void Add_Floating_Text(Utf16String const &text, Coord3D const *pos, int color);
virtual void Add_Floating_Text(const Utf16String &text, const Coord3D *pos, int color);
virtual void Add_Idle_Worker(Object *obj);
virtual void Remove_Idle_Worker(Object *obj, int slot);
virtual void Select_Next_Idle_Worker();
virtual void Recreate_Control_Bar();
virtual void Disable_Tooltips_Until(unsigned int until);
virtual void Disable_Tooltips_Until(unsigned int frame);
virtual void Clear_Tooltips_Disabled();
virtual bool Are_Tooltips_Disabled();
virtual int Get_Idle_Worker_Count();
Expand All @@ -384,15 +387,15 @@ class InGameUI : public SubsystemInterface, public SnapShot
virtual void Update_Idle_Worker();
virtual void Reset_Idle_Worker();
#ifdef GAME_DEBUG_STRUCTS
virtual void Debug_Add_Floating_Text(Utf8String const &text, Coord3D const *pos, int color);
virtual void Debug_Add_Floating_Text(const Utf8String &text, const Coord3D *pos, int color);
#endif
virtual View *Create_View() = 0;

void Add_World_Animation(
Anim2DTemplate *anim, const Coord3D *pos, WorldAnimationOptions options, float time, float z_rise);
void Set_Mouse_Cursor(MouseCursor cursor);
SuperweaponInfo *Find_SW_Info(
int player_index, Utf8String const &power_name, ObjectID id, SpecialPowerTemplate const *power_template);
int player_index, const Utf8String &power_name, ObjectID id, const SpecialPowerTemplate *power_template);
void Add_Named_Timer(const Utf8String &timer_name, const Utf16String &text, bool countdown);
void Remove_Named_Timer(const Utf8String &timer_name);
void Show_Named_Timer_Display(bool show);
Expand All @@ -416,8 +419,12 @@ class InGameUI : public SubsystemInterface, public SnapShot
ActionType action, const Object *object_to_interact_with, SelectionRules rule, bool force_to_attack) const;
bool Can_Selected_Objects_Do_Action(
ActionType action, const Object *object_to_interact_with, SelectionRules rule, bool additional_checking) const;
bool Can_Selected_Objects_Do_Special_Power(
CommandButton *command, const Object *object_to_interact_with, Coord3D *position, SelectionRules rule) const;
bool Can_Selected_Objects_Do_Special_Power(CommandButton *command,
const Object *object_to_interact_with,
Coord3D *position,
SelectionRules rule,
unsigned int options,
Object *custom_object) const;
bool Can_Selected_Objects_Override_Special_Power_Destination(
const Coord3D *pos, SelectionRules rule, SpecialPowerType type) const;
bool Can_Selected_Objects_Effectively_Use_Weapon(
Expand Down Expand Up @@ -562,7 +569,7 @@ class InGameUI : public SubsystemInterface, public SnapShot
bool m_isSelecting;
MouseMode m_mouseMode;
MouseCursor m_mouseCursor; // not 100% identified yet
DrawableID m_mousedOverObjectID;
DrawableID m_mousedOverDrawableID;
Coord2D m_scrollAmt;
bool m_isQuitMenuVisible;
bool m_messagesOn;
Expand Down Expand Up @@ -618,6 +625,8 @@ void Hide_Replay_Controls();
void Show_Replay_Controls();
void Toggle_Replay_Controls();

WindowMsgHandledType Idle_Worker_System(GameWindow *window, unsigned int message, unsigned int data_1, unsigned int data_2);

#ifdef GAME_DLL
extern InGameUI *&g_theInGameUI;
extern GameWindow *&g_replayWindow;
Expand Down
2 changes: 1 addition & 1 deletion src/game/common/rts/actionmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ CanAttackResult ActionManager::Get_Can_Attack_Object(
return Call_Method<CanAttackResult, ActionManager, const Object *, const Object *, CommandSourceType, AbleToAttackType>(
PICK_ADDRESS(0x00496850, 0x008E0B72), this, obj, object_to_attack, source, attack);
#else
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
#endif
}

Expand Down
4 changes: 3 additions & 1 deletion src/game/common/rts/actionmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ class Player;

enum CanEnterType
{
CAN_ENTER_UNK,
CAN_ENTER_0,
CAN_ENTER_1,
CAN_ENTER_2,
};

class ActionManager : public SubsystemInterface
Expand Down
2 changes: 1 addition & 1 deletion src/game/common/rts/player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2894,7 +2894,7 @@ void Player::Garrison_All_Units(CommandSourceType source)
}
}

if (g_theActionManager->Can_Enter_Object(obj, o, source, CAN_ENTER_UNK)) {
if (g_theActionManager->Can_Enter_Object(obj, o, source, CAN_ENTER_0)) {
update->AI_Enter(o, source);
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/game/logic/ai/aigroup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1846,7 +1846,7 @@ void AIGroup::Group_Attack_Object_Private(bool force, Object *victim, int max_sh
CanAttackResult attack = member_obj->Get_Able_To_Attack_Specific_Object(
static_cast<AbleToAttackType>(force), victim, cmd_source, WEAPONSLOT_UNK);

if (attack == ATTACK_RESULT_3 || attack == ATTACK_RESULT_2) {
if (attack == ATTACK_RESULT_CAN_ATTACK || attack == ATTACK_RESULT_OUT_OF_RANGE) {
AIUpdateInterface *update = member_obj->Get_AI_Update_Interface();

if (update != nullptr) {
Expand Down Expand Up @@ -1919,7 +1919,7 @@ void AIGroup::Group_Attack_Position(const Coord3D *pos, int max_shots_to_fire, C
CanAttackResult attack = contain_obj->Get_Able_To_Use_Weapon_Against_Target(
ATTACK_TYPE_0, nullptr, &attack_pos, cmd_source, WEAPONSLOT_UNK);

if (attack == ATTACK_RESULT_3 || attack == ATTACK_RESULT_2) {
if (attack == ATTACK_RESULT_CAN_ATTACK || attack == ATTACK_RESULT_OUT_OF_RANGE) {
AIUpdateInterface *contain_update = contain_obj->Get_AI_Update_Interface();

if (contain_update != nullptr) {
Expand Down
2 changes: 1 addition & 1 deletion src/game/logic/ai/turretai.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ StateReturnType TurretAIAimTurretState::Update()
target_obj,
owner_update->Get_Last_Command_Source(),
WEAPONSLOT_UNK);
is_able_to_attack = attack == ATTACK_RESULT_3 || attack == ATTACK_RESULT_2;
is_able_to_attack = attack == ATTACK_RESULT_CAN_ATTACK || attack == ATTACK_RESULT_OUT_OF_RANGE;
}

not_in_range = !turret->Friend_Is_Any_Weapon_In_Range_Of(target_obj);
Expand Down
37 changes: 19 additions & 18 deletions src/game/logic/object/weaponset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,22 +429,22 @@ CanAttackResult WeaponSet::Get_Able_To_Attack_Specific_Object(AbleToAttackType t
if (source_obj == nullptr || victim_obj == nullptr || source_obj->Is_Effectively_Dead()
|| victim_obj->Is_Effectively_Dead() || source_obj->Is_Destroyed() || victim_obj->Is_Destroyed()
|| victim_obj == source_obj) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}

bool same_player =
source_obj->Get_Controlling_Player() == victim_obj->Get_Controlling_Player() && Is_Attack_Type_1(type);

if (victim_obj->Get_Status(OBJECT_STATUS_MASKED)) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}

if (victim_obj->Is_KindOf(KINDOF_UNATTACKABLE)) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}

if (victim_obj->Get_Status(OBJECT_STATUS_NO_ATTACK_FROM_AI) && source == COMMANDSOURCE_AI) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}

bool check_stealth = true;
Expand All @@ -464,7 +464,7 @@ CanAttackResult WeaponSet::Get_Able_To_Attack_Specific_Object(AbleToAttackType t
}

if (!victim_obj->Is_KindOf(KINDOF_DISGUISER)) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}

{
Expand All @@ -478,7 +478,7 @@ CanAttackResult WeaponSet::Get_Able_To_Attack_Specific_Object(AbleToAttackType t
if (player != nullptr) {
if (player2 != nullptr) {
if (player->Get_Relationship(player2->Get_Default_Team()) != ENEMIES) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}
}
}
Expand All @@ -491,14 +491,14 @@ CanAttackResult WeaponSet::Get_Able_To_Attack_Specific_Object(AbleToAttackType t

if (relationship != ENEMIES && !Is_Attack_Type_1(type) && (!victim_obj->Is_KindOf(KINDOF_MINE) || relationship == ALLIES)
&& source == COMMANDSOURCE_PLAYER && (!victim_obj->Get_Script_Status(STATUS_TARGETABLE) || relationship == ALLIES)) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}

const Object *containedby = victim_obj->Get_Contained_By();

if (containedby != nullptr) {
if (containedby->Get_Contain()->Is_Enclosing_Container_For(victim_obj)) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}
}

Expand All @@ -513,7 +513,7 @@ CanAttackResult WeaponSet::Get_Able_To_Attack_Specific_Object(AbleToAttackType t
if (source_obj->Get_Team()->Get_Relationship(controlling_player->Get_Default_Team()) != ENEMIES) {
if (source == COMMANDSOURCE_PLAYER
&& (!victim_obj->Get_Script_Status(STATUS_TARGETABLE) || relationship == ALLIES)) {
return ATTACK_RESULT_0;
return ATTACK_RESULT_CANNOT_ATTACK;
}
}
}
Expand Down Expand Up @@ -620,22 +620,22 @@ CanAttackResult WeaponSet::Get_Able_To_Use_Weapon_Against_Target(AbleToAttackTyp
if ((source_obj->Is_KindOf(KINDOF_IMMOBILE) || source_obj->Is_KindOf(KINDOF_SPAWNS_ARE_THE_WEAPONS)
|| containedby != nullptr)
&& has_weapon && !weapon_in_range && type != ATTACK_TYPE_4) {
return ATTACK_RESULT_1;
return ATTACK_RESULT_UNREACHABLE;
}

CanAttackResult result = is_in_range ? ATTACK_RESULT_3 : ATTACK_RESULT_2;
CanAttackResult result = is_in_range ? ATTACK_RESULT_CAN_ATTACK : ATTACK_RESULT_OUT_OF_RANGE;

if (Has_Any_Damage_Weapon()) {
if ((mask & m_totalAntiMask) == 0) {
return ATTACK_RESULT_1;
return ATTACK_RESULT_UNREACHABLE;
}

if (victim_obj == nullptr) {
return result;
}

if (!Is_Any_Within_Target_Pitch(source_obj, victim_obj)) {
return ATTACK_RESULT_1;
return ATTACK_RESULT_UNREACHABLE;
}

WeaponSlotType start_slot;
Expand Down Expand Up @@ -677,7 +677,7 @@ CanAttackResult WeaponSet::Get_Able_To_Use_Weapon_Against_Target(AbleToAttackTyp
CanAttackResult can =
obj->Get_Able_To_Use_Weapon_Against_Target(type, victim_obj, location, source, WEAPONSLOT_UNK);

if (can == ATTACK_RESULT_2 || can == ATTACK_RESULT_3) {
if (can == ATTACK_RESULT_OUT_OF_RANGE || can == ATTACK_RESULT_CAN_ATTACK) {
return can;
}
}
Expand All @@ -689,13 +689,14 @@ CanAttackResult WeaponSet::Get_Able_To_Use_Weapon_Against_Target(AbleToAttackTyp
SpawnBehaviorInterface *behavior = source_obj->Get_Spawn_Behavior_Interface();

if (behavior == nullptr
|| behavior->Get_Can_Any_Slaves_Use_Weapon_Against_Target(type, victim_obj, location, source) != ATTACK_RESULT_3) {
return ATTACK_RESULT_1;
|| behavior->Get_Can_Any_Slaves_Use_Weapon_Against_Target(type, victim_obj, location, source)
!= ATTACK_RESULT_CAN_ATTACK) {
return ATTACK_RESULT_UNREACHABLE;
}

if (source_obj->Is_KindOf(KINDOF_IMMOBILE) && source_obj->Is_KindOf(KINDOF_SPAWNS_ARE_THE_WEAPONS)
&& result == ATTACK_RESULT_2) {
return ATTACK_RESULT_3;
&& result == ATTACK_RESULT_OUT_OF_RANGE) {
return ATTACK_RESULT_CAN_ATTACK;
}

return result;
Expand Down
8 changes: 4 additions & 4 deletions src/game/logic/object/weaponset.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,10 @@ enum WeaponLockType

enum CanAttackResult
{
ATTACK_RESULT_0 = 0,
ATTACK_RESULT_1,
ATTACK_RESULT_2,
ATTACK_RESULT_3,
ATTACK_RESULT_CANNOT_ATTACK = 0,
ATTACK_RESULT_UNREACHABLE,
ATTACK_RESULT_OUT_OF_RANGE,
ATTACK_RESULT_CAN_ATTACK,
};

enum AbleToAttackType
Expand Down
Loading

0 comments on commit 2243feb

Please sign in to comment.