Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
1a1c8f4
Added Team Loadouts to PlayerData
Oct 14, 2025
e1d1f69
Fixed the commented parts of the code
Oct 15, 2025
c6e3bb9
Add loadout handling and PlayerData integration between ModelControll…
Oct 17, 2025
4abb284
Loadout: wire ModelController via SerializeField, pass PlayerData int…
Oct 31, 2025
a4f28c6
Merge branch 'main' into UI/DefenceGallery/Feature/TeamLoadOuts
Oct 31, 2025
dcb636e
Added loadout save prompt, “slot 0” popup, and cleaned code a bit
Nov 4, 2025
9b0795f
Merge branch 'main' into UI/DefenceGallery/Feature/TeamLoadOuts
Nov 4, 2025
a5adb2d
Added SelectedCharacters slots to LoadoutPopup, adjusted its UI, and …
Nov 10, 2025
63d0864
Add loadout save confirmation, selectable row backgrounds, and UI imp…
Nov 14, 2025
f365e71
Merge branch 'main' into UI/DefenceGallery/Feature/TeamLoadOuts
Nov 17, 2025
01e43e0
SelectedCharacter slot details get properly enabled again.
BillTheBeast Nov 18, 2025
9d71ece
Added inline/popup loadout mode switch and button variants
Nov 20, 2025
30f4621
Merge branch 'main' into UI/DefenceGallery/Feature/TeamLoadOuts
Nov 20, 2025
496e474
Merge branch 'main' into UI/DefenceGallery/Feature/TeamLoadOuts
BillTheBeast Dec 1, 2025
7645b3e
Added Loadout 2 dynamic loadout system with runtime slot creation and…
Dec 2, 2025
26b9a85
Added popup loadout sync, hid inline add-button when max slots added,…
Dec 4, 2025
c080ded
Unified loadout lists, refined inline/popup behavior, and updated pop…
Dec 10, 2025
9b1a1d6
Added loadout-aware character editing and automatic loadout saving in…
Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 127 additions & 9 deletions Assets/Altzone/Scripts/Model/Poco/Player/PlayerData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,17 @@ public class PlayerData

public int points = 0;

public TeamLoadOut[] LoadOuts = new TeamLoadOut[8]
{
new TeamLoadOut(), new TeamLoadOut(), new TeamLoadOut(), new TeamLoadOut(),
new TeamLoadOut(), new TeamLoadOut(), new TeamLoadOut(), new TeamLoadOut()
};

public int SelectedLoadOut = 0;

public PlayStyles playStyles;

public string emotionSelectorDate = null;
public string emotionSelectorDate = null;

public string daysBetweenInput = "0";

Expand Down Expand Up @@ -115,7 +123,7 @@ public List<Emotion> playerDataEmotionList
get
{
List<Emotion> list = new();
foreach(string emotion in _playerDataEmotionList)
foreach (string emotion in _playerDataEmotionList)
{
list.Add((Emotion)Enum.Parse(typeof(Emotion), emotion));
}
Expand Down Expand Up @@ -149,11 +157,14 @@ public PlayerData(string id, string clanId, int currentCustomCharacterId, string
Id = id;
ClanId = clanId ?? string.Empty;
SelectedCharacterId = currentCustomCharacterId;
if(characters != null)BuildCharacterLists(characters);
if (characters != null) BuildCharacterLists(characters);
BuildSelectedCharacterList(currentBattleCharacterIds);
Name = name;
BackpackCapacity = backpackCapacity;
UniqueIdentifier = uniqueIdentifier;


EnsureLoadoutsInitialized();
}

public PlayerData(ServerPlayer player, bool limited = false)
Expand All @@ -176,7 +187,10 @@ public PlayerData(ServerPlayer player, bool limited = false)
stats = player.gameStatistics;
Task = player.DailyTask != null ? new(player.DailyTask) : null;
AvatarData = player.avatar != null ? new(player.name, player.avatar) : null;
if (!limited) Task = player.DailyTask != null ? new(player.DailyTask): null;
if (!limited) Task = player.DailyTask != null ? new(player.DailyTask) : null;


EnsureLoadoutsInitialized();
}


Expand All @@ -199,9 +213,12 @@ public void UpdatePlayerData(ServerPlayer player)
points = player.points;
stats = player.gameStatistics;
Task = player.DailyTask != null ? new(player.DailyTask) : null;
AvatarData = player.avatar !=null ? new(player.name ,player.avatar): null;
AvatarData = player.avatar != null ? new(player.name, player.avatar) : null;
if (_playerDataEmotionList == null || _playerDataEmotionList.Count == 0) playerDataEmotionList = new List<Emotion> { Emotion.Blank, Emotion.Love, Emotion.Playful, Emotion.Joy, Emotion.Sorrow, Emotion.Anger, Emotion.Blank };
if (daysBetweenInput == null) daysBetweenInput = "0";


EnsureLoadoutsInitialized();
}

public void UpdateCustomCharacter(CustomCharacter character)
Expand Down Expand Up @@ -267,16 +284,16 @@ private bool SetBaseCharacter(ReadOnlyCollection<BaseCharacter> baseCharacters,

private void BuildSelectedCharacterList(string[] server_ids)
{
for(int i=0; i < 3; i++)
for (int i = 0; i < 3; i++)
{
string serverid = null;
if(server_ids.Length > i) serverid = server_ids[i];
if (server_ids.Length > i) serverid = server_ids[i];

if (_characterList == null) _characterList = new();
CustomCharacter character = _characterList.FirstOrDefault(c => c.ServerID == serverid);
if (i < SelectedCharacterIds.Length)
{
if (SelectedCharacterIds[i] != null) SelectedCharacterIds[i].SetData(serverid, character == null ? CharacterID.None :character.Id);
if (SelectedCharacterIds[i] != null) SelectedCharacterIds[i].SetData(serverid, character == null ? CharacterID.None : character.Id);
else SelectedCharacterIds[i] = new(serverid, character == null ? CharacterID.None : character.Id);
}
else SelectedCharacterIds.Append(new(serverid, character == null ? CharacterID.None : character.Id));
Expand All @@ -287,7 +304,108 @@ public override string ToString()
{
return
$"{nameof(Id)}: {Id}, {nameof(ClanId)}: {ClanId}, {nameof(SelectedCharacterId)}: {SelectedCharacterId}," +
$"{nameof(SelectedCharacterIds)}: {string.Join<CustomCharacterListObject>(",", SelectedCharacterIds)}, { nameof(Name)}: {Name}, {nameof(BackpackCapacity)}: {BackpackCapacity}, {nameof(UniqueIdentifier)}: {UniqueIdentifier}";
$"{nameof(SelectedCharacterIds)}: {string.Join<CustomCharacterListObject>(",", SelectedCharacterIds)}, {nameof(Name)}: {Name}, {nameof(BackpackCapacity)}: {BackpackCapacity}, {nameof(UniqueIdentifier)}: {UniqueIdentifier}";
}

/// <summary>
/// Loads the chosen loadout into SelectedCharacterIds (makes it the active team).
/// </summary>
public void ApplyLoadout(int index)
{
if (index < 0 || index > LoadOuts.Length)

{
Debug.LogError($"Invalid index {index}. Allowed range is 0 - {LoadOuts.Length}");
return;
}
if (index == 0)
{

SelectedLoadOut = 0;
return;
}

TeamLoadOut selectedSlot = LoadOuts[index - 1];
if (selectedSlot == null || selectedSlot.Slots == null) return;

// Copies values from the saved slot to the active team (without sharing references)
for (int i = 0; i < 3; i++)
{
CustomCharacterListObject savedMember = selectedSlot.Slots[i];
if (savedMember == null) savedMember = new CustomCharacterListObject();

if (SelectedCharacterIds[i] == null)
SelectedCharacterIds[i] = new CustomCharacterListObject();

SelectedCharacterIds[i].SetData(savedMember.ServerID, savedMember.CharacterID);
}

SelectedLoadOut = index;
}

/// <summary>
/// Saves the current active team (SelectedCharacterIds) into the chosen slot (1-3).
/// Creates new instances so references are not shared with SelectedCharacterIds
/// </summary>
public void SaveCurrentTeamToLoadout(int index)
{

if (index <= 0 || index > LoadOuts.Length)
{
Debug.LogError($"Invalid index {index}. Allowed range is 1 - {LoadOuts.Length}");
return;
}

if (LoadOuts[index - 1] == null)
LoadOuts[index - 1] = new TeamLoadOut();

if (LoadOuts[index - 1].Slots == null)
LoadOuts[index - 1].Slots = new CustomCharacterListObject[3];

for (int i = 0; i < 3; i++)
{
CustomCharacterListObject activeMember = SelectedCharacterIds[i];
if (activeMember == null) activeMember = new CustomCharacterListObject();


CustomCharacterListObject savedCopy = new CustomCharacterListObject();
savedCopy.SetData(activeMember.ServerID, activeMember.CharacterID);

LoadOuts[index - 1].Slots[i] = savedCopy;

}
}

/// <summary>
/// This is called whenever the user changes the team in the UI.
/// If a saved slot (1-3) is selected, changes are saved immediately to that slot.
/// </summary>
public void OnCurrentTeamChanged_AutoSave()
{

if (SelectedLoadOut > 0 && SelectedLoadOut <= LoadOuts.Length)
{
SaveCurrentTeamToLoadout(SelectedLoadOut);
}
Storefront.Get().SavePlayerData(this, null);


}

public void EnsureLoadoutsInitialized()
{
if (LoadOuts == null || LoadOuts.Length != 8)
{
LoadOuts = new TeamLoadOut[8];
}

for (int i = 0; i < LoadOuts.Length; i++)
{
if (LoadOuts[i] == null)
LoadOuts[i] = new TeamLoadOut();
}
}


}
}
31 changes: 31 additions & 0 deletions Assets/Altzone/Scripts/Model/Poco/Player/TeamLoadOut.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using Altzone.Scripts.Model.Poco.Game;
using UnityEngine;

namespace Altzone.Scripts.Model.Poco.Player
{
[Serializable]
public class TeamLoadOut
{
public CustomCharacterListObject[] Slots = new CustomCharacterListObject[3]
{
new CustomCharacterListObject(Id: CharacterID.None),
new CustomCharacterListObject(Id: CharacterID.None),
new CustomCharacterListObject(Id: CharacterID.None)
};

public bool IsEmpty
{
get
{
if (Slots == null) return true;
foreach (var slot in Slots)
{
if (slot != null && slot.CharacterID != CharacterID.None)
return false;
}
return true;
}
}
}
}
11 changes: 11 additions & 0 deletions Assets/Altzone/Scripts/Model/Poco/Player/TeamLoadOut.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading