unit UParty;
interface
uses ModiSDK, UIni;
type
TRoundInfo = record
Plugin: Word;
PluginNr: Integer;
Medley: boolean;
MedleySurprise: boolean;
Winner: Byte;
end;
TeamOrderEntry = record
Teamnum: Byte;
Score: Byte;
end;
TeamOrderArray = Array[0..5] of Byte;
TPartyPlugin = record
ID: byte;
TimesPlayed: byte;
Medley: boolean;
MedleySurprise: boolean;
Selected: boolean;
Name: string;
Desc: string;
end;
TParty_Session = class
private
function GetRandomPlayer(Team: Byte): Byte;
function GetRandomPlugin(var medley: boolean; var surprise: boolean; var nr: integer): byte;
function IsWinner(Player, Winner: Byte): boolean;
procedure GenScores;
public
Plugins: array of TPartyPlugin;
Teams: TTeamInfo;
Rounds: array of TRoundInfo;
CurRound: Byte;
constructor Create;
procedure StartNewParty(NumRounds: Byte);
procedure StartRound;
procedure EndRound;
function GetTeamOrder: TeamOrderArray;
function GetWinnerString(Round: Byte): String;
end;
var
PartySession: TParty_Session;
Placings: Array [0..5] of Byte;
implementation
uses UDLLManager, UGraphic, UMain, ULanguage, ULog;
//----------
//Constructor - Prepares the Class
//----------
constructor TParty_Session.Create;
begin
// - Nothing in here atm
end;
//----------
// Returns a number of a random plugin (New Version)
//----------
function TParty_Session.GetRandomPlugin(var medley: boolean; var surprise: boolean; var nr: integer): byte;
Type
TOrder = record
ID: integer;
medley: boolean;
surprise: boolean;
Nr: integer;
end;
var
I, J, K: Integer;
plugin_order: array of TOrder;
temp: TOrder;
min, len: integer;
begin
//search for min played
min := high(min);
for I := 0 to Length(Plugins) - 1 do
begin
if Plugins[I].TimesPlayed < min then
min := Plugins[I].TimesPlayed;
end;
//fill plugin list
SetLength(plugin_order, 0);
for I := 0 to Length(Plugins) - 1 do
begin
if (Plugins[I].TimesPlayed = min) then
begin
len := Length(plugin_order);
SetLength(plugin_order, len+1);
plugin_order[len].ID := Plugins[I].ID;
plugin_order[len].medley := Plugins[I].Medley;
plugin_order[len].surprise := Plugins[I].MedleySurprise;
plugin_order[len].Nr := I;
end;
end;
K := random(Length(plugin_order));
Inc(Plugins[plugin_order[K].Nr].TimesPlayed);
medley := plugin_order[K].medley;
surprise := plugin_order[K].surprise;
nr := plugin_order[K].Nr;
Result := plugin_order[K].ID;
end;
//----------
//StartNewParty - Clears the Class and Prepares for new Party
//----------
procedure TParty_Session.StartNewParty(NumRounds: Byte);
var
TeamMode: Boolean;
Len: Integer;
I, J: Integer;
NumMedleys: Integer;
begin
//Set cur Round to Round 1
CurRound := 255;
//Set Rounds
NumMedleys := 0;
If (Length(Plugins) >= 1) then
begin
SetLength (Rounds, NumRounds);
For I := 0 to NumRounds-1 do
begin
PartySession.Rounds[I].Plugin := GetRandomPlugin(PartySession.Rounds[I].Medley,
PartySession.Rounds[I].MedleySurprise,
PartySession.Rounds[I].PluginNr);
PartySession.Rounds[I].Winner := 255;
if PartySession.Rounds[I].Medley then
inc(NumMedleys);
end;
end
else SetLength (Rounds, 0);
PlayersPlay := Teams.NumTeams;
//Get Teammode and Set Joker, also set TimesPlayed
TeamMode := True;
For I := 0 to Teams.NumTeams-1 do
begin
if Teams.Teaminfo[I].NumPlayers < 2 then
begin
TeamMode := False;
end;
//Set Player Attributes
For J := 0 to Teams.TeamInfo[I].NumPlayers-1 do
begin
Teams.TeamInfo[I].Playerinfo[J].TimesPlayed := 0;
end;
Teams.Teaminfo[I].Joker := Round(NumRounds*0.7)+NumMedleys;
Teams.Teaminfo[I].Score := 0;
end;
//Reset Played-array
SetLength(ScreenSong.MedleyPlayed, 0);
SetLength(ScreenSong.PartyPlayed, 0);
end;
//----------
//GetRandomPlayer - Gives back a Random Player to Play next Round
//----------
function TParty_Session.GetRandomPlayer(Team: Byte): Byte;
var
I, R: Integer;
lowestTP: Byte;
NumPwithLTP: Byte;
begin
LowestTP := high(Byte);
NumPwithLTP := 0;
Result := 0;
//Search for Players that have not often played yet
For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
begin
if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then
begin
lowestTP := Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed;
NumPwithLTP := 1;
end
else if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP) then
begin
Inc(NumPwithLTP);
end;
end;
//Create Random No
R := Random(NumPwithLTP);
//Search for Random Player
For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do
begin
if Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP then
begin
//Player Found
if (R = 0) then
begin
Result := I;
Break;
end;
Dec(R);
end;
end;
end;
//----------
//StartNextRound - Prepares ScreenSingModi for Next Round And Load Plugin
//----------
procedure TParty_Session.StartRound;
var
I: Integer;
begin
if ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then
begin
//Increase Current Round
Inc (CurRound);
Rounds[CurRound].Winner := 255;
DllMan.LoadPlugin(Rounds[CurRound].Plugin);
//Select Players
for I := 0 to Teams.NumTeams-1 do
Teams.Teaminfo[I].CurPlayer := GetRandomPlayer(I);
//Set ScreenSingModie Variables
ScreenSingModi.TeamInfo := Teams;
//Set
end;
end;
//----------
//IsWinner - Returns True if the Players Bit is set in the Winner Byte
//----------
function TParty_Session.IsWinner(Player, Winner: Byte): boolean;
var
Bit: Byte;
begin
Case Player of
0: Bit := 1;
1: Bit := 2;
2: Bit := 4;
3: Bit := 8;
4: Bit := 16;
5: Bit := 32;
end;
Result := ((Winner AND Bit) = Bit);
end;
//----------
//GenScores - Inc Scores for Cur. Round
//----------
procedure TParty_Session.GenScores;
var
I: Byte;
begin
for I := 0 to Teams.NumTeams-1 do
begin
if isWinner(I, Rounds[CurRound].Winner) then
Inc(Teams.Teaminfo[I].Score);
end;
end;
//----------
//GetWinnerString - Get String with WinnerTeam Name, when there is more than one Winner than Connect with and or ,
//----------
function TParty_Session.GetWinnerString(Round: Byte): String;
var
Winners: Array of String;
I: Integer;
begin
Result := Language.Translate('PARTY_NOBODY');
if (Round > High(Rounds)) then
exit;
if (Rounds[Round].Winner = 0) then
begin
exit;
end;
if (Rounds[Round].Winner = 255) then
begin
Result := Language.Translate('PARTY_NOTPLAYEDYET');
exit;
end;
SetLength(Winners, 0);
for I := 0 to Teams.NumTeams-1 do
begin
if isWinner(I, Rounds[Round].Winner) then
begin
SetLength(Winners, Length(Winners) + 1);
Winners[high(Winners)] := Teams.TeamInfo[I].Name;
end;
end;
Result := Language.Implode(Winners);
end;
//----------
//EndRound - Get Winner from ScreenSingModi and Save Data to RoundArray
//----------
procedure TParty_Session.EndRound;
var
I, J, MaxScore: Integer;
begin
//Copy Winner
if Rounds[CurRound].Medley then
begin
Rounds[CurRound].Winner := 0;
MaxScore := 0;
for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers-1 do
begin
ScreenSingModi.PlayerInfo.Playerinfo[I].Percentage :=
ScreenSingModi.PlayerInfo.Playerinfo[I].Score div 9999;
if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score > MaxScore) then
begin
MaxScore := ScreenSingModi.PlayerInfo.Playerinfo[I].Score;
Case I of
0: Rounds[CurRound].Winner := 1;
1: Rounds[CurRound].Winner := 2;
2: Rounds[CurRound].Winner := 4;
3: Rounds[CurRound].Winner := 8;
4: Rounds[CurRound].Winner := 16;
5: Rounds[CurRound].Winner := 32;
end;
end
else if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score = MaxScore) AND
(ScreenSingModi.PlayerInfo.Playerinfo[I].Score <> 0) then
begin
Case I of
0: Rounds[CurRound].Winner := Rounds[CurRound].Winner OR 1;
1: Rounds[CurRound].Winner := Rounds[CurRound].Winner OR 2;
2: Rounds[CurRound].Winner := Rounds[CurRound].Winner OR 4;
3: Rounds[CurRound].Winner := Rounds[CurRound].Winner OR 8;
4: Rounds[CurRound].Winner := Rounds[CurRound].Winner OR 16;
5: Rounds[CurRound].Winner := Rounds[CurRound].Winner OR 32;
end;
end;
end;
//When nobody has Points -> Everybody loose
if (MaxScore = 0) then
Rounds[CurRound].Winner := 0;
end else
Rounds[CurRound].Winner := ScreenSingModi.Winner;
//Set Scores
if (Ini.NewPartyPoints = 1) and (Rounds[CurRound].Winner <> 0) then
begin
MaxScore := 0;
for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers-1 do
if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score > MaxScore) then
MaxScore := ScreenSingModi.PlayerInfo.Playerinfo[I].Score;
if (MaxScore > 0) then
begin
//New Points
//Get Placings
for I := 0 to Teams.NumTeams-1 do
begin
Placings[I] := 0;
for J := 0 to Teams.NumTeams-1 do
If (ScreenSingModi.PlayerInfo.Playerinfo[J].Score > ScreenSingModi.PlayerInfo.Playerinfo[I].Score) then
Inc(Placings[I]);
end;
for I := 0 to Teams.NumTeams-1 do
Teams.Teaminfo[I].Score := Teams.Teaminfo[I].Score + ((Placings[I] - (Teams.NumTeams-1)) * -1);
end
end
else
//Old Points
GenScores;
//Increase TimesPlayed 4 all Players
For I := 0 to Teams.NumTeams-1 do
Inc(Teams.Teaminfo[I].Playerinfo[Teams.Teaminfo[I].CurPlayer].TimesPlayed);
end;
//----------
//GetTeamOrder - Gives back the Placing of eacb Team [First Position of Array is Teamnum of first placed Team, ...]
//----------
function TParty_Session.GetTeamOrder: TeamOrderArray;
var
I, J: Integer;
ATeams: array [0..5] of TeamOrderEntry;
TempTeam: TeamOrderEntry;
begin
//Fill Team Array
For I := 0 to Teams.NumTeams-1 do
begin
ATeams[I].Teamnum := I;
ATeams[I].Score := Teams.Teaminfo[I].Score;
end;
//Sort Teams
for J := 0 to Teams.NumTeams-1 do
for I := 1 to Teams.NumTeams-1 do
if ATeams[I].Score > ATeams[I-1].Score then
begin
TempTeam := ATeams[I-1];
ATeams[I-1] := ATeams[I];
ATeams[I] := TempTeam;
end;
//Copy to Result
For I := 0 to Teams.NumTeams-1 do
Result[I] := ATeams[I].TeamNum;
end;
end.