Skip to content

Commit

Permalink
Merge branch 'develop' into VulthooTweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
Basilisk3 authored Dec 21, 2024
2 parents 70c0b18 + 508885d commit e77abc0
Show file tree
Hide file tree
Showing 15 changed files with 304 additions and 29 deletions.
1 change: 1 addition & 0 deletions changelog/snippets/balance.6464.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- (#6464) Make engineers assisting a shield start repairing the shield in 0.1 seconds instead of 0.7 to 1.1 seconds.
3 changes: 0 additions & 3 deletions changelog/snippets/balance.6568.md

This file was deleted.

1 change: 0 additions & 1 deletion changelog/snippets/fix.6546.md

This file was deleted.

1 change: 1 addition & 0 deletions changelog/snippets/other.6577.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- (#6577) Annotate `AddBlinkyBox`. This UI-side global engine function makes a unit's selection box blink for some time.
35 changes: 35 additions & 0 deletions docs/_posts/2024-12-10-3816.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
layout: post
title: Game version 3816
permalink: changelog/3816
---

# Game version 3816 (10th of December, 2024)

This hotfix primarily fixes the bug that rating and divisions were not displayed in matchmaker games.

With kind regards,

BlackYps

## Balance

- (#6568) Vulthoo have been underperforming after their rework. Their biggest weak point was the excessive amount of build time required which made it impractical to make them in the earlier stages of tech 2 especially.
- Vulthoo:
- BuildTime: 3300 --> 2700

## Bug fixes

- (#6546) Fix an exploit that allows being notified of enemy Billy nuke launches.

- (#6569) Fix the matchmaker lobby not passing ratings, divisions and clan tags to the session, making them not visible in the scoreboard.


## Contributors

With thanks to the following people who contributed through coding and testing:

- Jip
- Nomander
- ETFreeman
- Clyf
4 changes: 2 additions & 2 deletions engine/User.lua
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@
--- | 'NUMPAD_DECIMAL'
--- | 'NUMPAD_DIVIDE'

--- No clue what this does
---@param entityId number
--- Repeatedly the selection box of the unit to the hovered-over state to create a blinking effect
---@param entityId EntityId
---@param onTime number
---@param offTime number
---@param totalTime number
Expand Down
2 changes: 2 additions & 0 deletions engine/User/CLobby.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ local CLobby = {}
---@field Timeouts any # Read by the engine to determine the behavior of time outs.
---@field CivilianAlliance any # Read by the engine to determine the alliance towards civilians.
---@field GameSpeed any # Read by the engine to determine the behavior of game speed (adjustments).
---@field Ratings table<string, number>
---@field Divisions table<string, string>

---@class UILobbyLaunchGameModsConfiguration
---@field name string # Read by the engine, TODO
Expand Down
41 changes: 37 additions & 4 deletions lua/shield.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ local MathSqrt = math.sqrt
local MathMin = math.min

local TableAssimilate = table.assimilate
local TableGetn = table.getn
local TableEmpty = table.empty

-- cache globals
local Warp = Warp
Expand All @@ -59,6 +61,9 @@ local ArmyGetHandicap = ArmyGetHandicap
local CoroutineYield = coroutine.yield
local CreateEmitterAtBone = CreateEmitterAtBone
local _c_CreateShield = _c_CreateShield
local IssueClearCommands = IssueClearCommands
local IssueRepair = IssueRepair
local IssueGuard = IssueGuard

-- cache cfunctions
local EntityGetHealth = _G.moho.entity_methods.GetHealth
Expand Down Expand Up @@ -87,6 +92,8 @@ local EntitySetParentOffset = _G.moho.entity_methods.SetParentOffset
local UnitSetScriptBit = _G.moho.unit_methods.SetScriptBit
local UnitIsUnitState = _G.moho.unit_methods.IsUnitState
local UnitRevertCollisionShape = _G.moho.unit_methods.RevertCollisionShape
local UnitGetGuards = _G.moho.unit_methods.GetGuards
local UnitGetCommandQueue = _G.moho.unit_methods.GetCommandQueue

local IEffectOffsetEmitter = _G.moho.IEffect.OffsetEmitter

Expand Down Expand Up @@ -356,7 +363,7 @@ Shield = ClassShield(moho.shield_methods, Entity) {

--- Retrieves allied shields that overlap with this shield, caches the results per tick
-- @param self A shield that we're computing the overlapping shields for
-- @param tick Optional parameter, represents the game tick. Used to determine if we need to refresh the cash
-- @param tick Optional parameter, represents the game tick. Used to determine if we need to refresh the cache
GetOverlappingShields = function(self, tick)

-- allow the game tick to be send to us, saves cycles
Expand Down Expand Up @@ -509,6 +516,12 @@ Shield = ClassShield(moho.shield_methods, Entity) {
self:ApplyDamage(instigator, amount, vector, damageType, true)
end,

---@param self Shield
---@param instigator Unit
---@param amount number
---@param vector Vector
---@param dmgType DamageType
---@param doOverspill boolean
ApplyDamage = function(self, instigator, amount, vector, dmgType, doOverspill)

-- cache information used throughout the function
Expand Down Expand Up @@ -565,12 +578,32 @@ Shield = ClassShield(moho.shield_methods, Entity) {

-- do damage logic for shield

if self.Owner ~= instigator then
local owner = self.Owner
if owner ~= instigator then
local absorbed = self:OnGetDamageAbsorption(instigator, amount, dmgType)

-- take some damage
EntityAdjustHealth(self, instigator, -absorbed)

-- force guards to start repairing in 1 tick instead of waiting for them to react 7-11 ticks
if tick > owner.tickIssuedShieldRepair then
owner.tickIssuedShieldRepair = tick
local guards = UnitGetGuards(owner)
if not TableEmpty(guards) then
-- filter out guards with something queued after the shield assist order, as to not delete clear their queue
for i, guard in guards do
if TableGetn(UnitGetCommandQueue(guard)) >= 2 then
guards[i] = nil
end
end

-- For the filtered guards, clear their assist order, order repair, then re-add the assist order after
IssueClearCommands(guards)
IssueRepair(guards, owner)
IssueGuard(guards, owner)
end
end

-- check to spawn impact effect
local r = Random(1, self.Size)
if dmgType ~= "ShieldSpill"
Expand Down Expand Up @@ -684,8 +717,8 @@ Shield = ClassShield(moho.shield_methods, Entity) {
end,

--- Called when a shield collides with a projectile to check if the collision is valid
-- @param self The shield we're checking the collision for
-- @param other The projectile we're checking the collision with
---@param self Shield The shield we're checking the collision for
---@param other Projectile The projectile we're checking the collision with
OnCollisionCheck = function(self, other)

-- special logic when it is a projectile to simulate air crashes
Expand Down
1 change: 1 addition & 0 deletions lua/sim/Unit.lua
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ local cUnitGetBuildRate = cUnit.GetBuildRate
---@field ReclaimTimeMultiplier? number
---@field CaptureTimeMultiplier? number
---@field PlatoonHandle? Platoon
---@field tickIssuedShieldRepair number? # Used by shields to keep track of when this unit's guards were ordered to start shield repair instantly
Unit = ClassUnit(moho.unit_methods, IntelComponent, VeterancyComponent, DebugUnitComponent) {

IsUnit = true,
Expand Down
87 changes: 75 additions & 12 deletions lua/ui/lobby/autolobby/AutolobbyController.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ local DebugComponent = import("/lua/shared/components/DebugComponent.lua").Debug
local AutolobbyServerCommunicationsComponent = import("/lua/ui/lobby/autolobby/components/AutolobbyServerCommunicationsComponent.lua")
.AutolobbyServerCommunicationsComponent

local AutolobbyArgumentsComponent = import("/lua/ui/lobby/autolobby/components/AutolobbyArguments.lua").AutolobbyArgumentsComponent

local AutolobbyMessages = import("/lua/ui/lobby/autolobby/AutolobbyMessages.lua").AutolobbyMessages

local AutolobbyEngineStrings = {
Expand Down Expand Up @@ -62,6 +64,7 @@ local AutolobbyEngineStrings = {
---@field DIV string # Related to rating/divisions
---@field SUBDIV string # Related to rating/divisions
---@field PL number # Related to rating/divisions
---@field PlayerClan string

---@alias UIAutolobbyConnections boolean[][]
---@alias UIAutolobbyStatus UIPeerLaunchStatus[]
Expand All @@ -86,7 +89,7 @@ local AutolobbyEngineStrings = {
---@field DesiredPeerId UILobbyPeerId

--- Responsible for the behavior of the automated lobby.
---@class UIAutolobbyCommunications : moho.lobby_methods, DebugComponent, UIAutolobbyServerCommunicationsComponent
---@class UIAutolobbyCommunications : moho.lobby_methods, DebugComponent, UIAutolobbyServerCommunicationsComponent, UIAutolobbyArgumentsComponent
---@field Trash TrashBag
---@field LocalPeerId UILobbyPeerId # a number that is stringified
---@field LocalPlayerName string # nickname
Expand All @@ -100,15 +103,15 @@ local AutolobbyEngineStrings = {
---@field LobbyParameters? UIAutolobbyParameters # Used for rejoining functionality
---@field HostParameters? UIAutolobbyHostParameters # Used for rejoining functionality
---@field JoinParameters? UIAutolobbyJoinParameters # Used for rejoining functionality
AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsComponent, DebugComponent) {
AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsComponent, AutolobbyArgumentsComponent, DebugComponent) {

---@param self UIAutolobbyCommunications
__init = function(self)
self.Trash = TrashBag()

self.LocalPeerId = "-2"
self.LocalPlayerName = "Charlie"
self.PlayerCount = tonumber(GetCommandLineArg("/players", 1)[1]) or 2
self.PlayerCount = self:GetCommandLineArgumentNumber("/players", 2)
self.HostID = "-2"

self.GameMods = {}
Expand Down Expand Up @@ -147,20 +150,21 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC
end

-- retrieve team and start spot
info.Team = tonumber(GetCommandLineArg("/team", 1)[1])
info.StartSpot = tonumber(GetCommandLineArg("/startspot", 1)[1]) or -1 -- TODO
info.Team = self:GetCommandLineArgumentNumber("/team", -1)
info.StartSpot = self:GetCommandLineArgumentNumber("/startspot", -1)

-- determine army color based on start location
info.PlayerColor = GameColors.MapToWarmCold(info.StartSpot)
info.ArmyColor = GameColors.MapToWarmCold(info.StartSpot)

-- retrieve rating
info.DEV = tonumber(GetCommandLineArg("/deviation", 1)[1]) or 500
info.MEAN = tonumber(GetCommandLineArg("/mean", 1)[1]) or 1500
info.NG = tonumber(GetCommandLineArg("/numgames", 1)[1]) or 0
info.DIV = (GetCommandLineArg("/division", 1)[1]) or ""
info.SUBDIV = (GetCommandLineArg("/subdivision", 1)[1]) or ""
info.DEV = self:GetCommandLineArgumentNumber("/deviation", 500)
info.MEAN = self:GetCommandLineArgumentNumber("/mean", 1500)
info.NG = self:GetCommandLineArgumentNumber("/numgames", 0)
info.DIV = self:GetCommandLineArgumentString("/division", "")
info.SUBDIV = self:GetCommandLineArgumentString("/subdivision", "")
info.PL = math.floor(info.MEAN - 3 * info.DEV)
info.PlayerClan = self:GetCommandLineArgumentString("/clan", "")

return info
end,
Expand Down Expand Up @@ -193,7 +197,7 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC
}

-- process game options from the command line
for name, value in Utils.GetCommandLineArgTable("/gameoptions") do
for name, value in self:GetCommandLineArgumentArray("/gameoptions") do
if name and value then
options[name] = value
else
Expand Down Expand Up @@ -294,6 +298,59 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC
return 'Ready'
end,

---@param self UIAutolobbyCommunications
---@param playerOptions UIAutolobbyPlayer[]
---@return table<string, number>
CreateRatingsTable = function(self, playerOptions)
---@type table<string, number>
local allRatings = {}

for slot, options in pairs(playerOptions) do
if options.Human and options.PL then
allRatings[options.PlayerName] = options.PL
end
end

return allRatings
end,

---@param self UIAutolobbyCommunications
---@param playerOptions UIAutolobbyPlayer[]
---@return table<string, string>
CreateDivisionsTable = function(self, playerOptions)
---@type table<string, string>
local allDivisions = {}

for slot, options in pairs(playerOptions) do
if options.Human and options.PL then
if options.DIV ~= "unlisted" then
local division = options.DIV
if options.SUBDIV and options.SUBDIV ~= "" then
division = division .. ' ' .. options.SUBDIV
end
allDivisions[options.PlayerName] = division
end
end
end

return allDivisions
end,

---@param self UIAutolobbyCommunications
---@param playerOptions UIAutolobbyPlayer[]
---@return table<string, string>
CreateClanTagsTable = function(self, playerOptions)
local allClanTags = {}

for slot, options in pairs(playerOptions) do
if options.PlayerClan then
allClanTags[options.PlayerName] = options.PlayerClan
end
end

return allClanTags
end,

--- Verifies whether we can launch the game.
---@param self UIAutolobbyCommunications
---@param peerStatus UIAutolobbyStatus
Expand Down Expand Up @@ -488,6 +545,12 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC
self:SendPlayerOptionToServer(ownerId, 'Faction', playerOptions.Faction)
end

-- tuck them into the game options. By all means a hack, but
-- this way they are available in both the sim and the UI
self.GameOptions.Ratings = self:CreateRatingsTable(self.PlayerOptions)
self.GameOptions.Divisions = self:CreateDivisionsTable(self.PlayerOptions)
self.GameOptions.ClanTags = self:CreateClanTagsTable(self.PlayerOptions)

-- create game configuration
local gameConfiguration = {
GameMods = self.GameMods,
Expand All @@ -496,7 +559,7 @@ AutolobbyCommunications = Class(MohoLobbyMethods, AutolobbyServerCommunicationsC
Observers = {},
}

-- send it to all players and tell them to launch
-- send it to all players and tell them to launch with the configuration
self:BroadcastData({ Type = "Launch", GameConfig = gameConfiguration })
self:LaunchGame(gameConfiguration)
end
Expand Down
Loading

0 comments on commit e77abc0

Please sign in to comment.