From 7a01b05b3861a667eb32ce2e0fc88ff3bacb99ae Mon Sep 17 00:00:00 2001 From: mogguh Date: Tue, 2 Sep 2008 17:25:26 +0000 Subject: Moved: The folder classes has been renamed to base Updated: ultrastardx.dpr has been changed accordingly git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1339 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 630 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 630 insertions(+) create mode 100644 src/base/UParty.pas (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas new file mode 100644 index 00000000..01a182b1 --- /dev/null +++ b/src/base/UParty.pas @@ -0,0 +1,630 @@ +unit UParty; + +interface + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +{$I switches.inc} + +uses UPartyDefs, UCoreModule, UPluginDefs; + +type + ARounds = Array [0..252] of Integer; //0..252 needed for + PARounds = ^ARounds; + + TRoundInfo = record + Modi: Cardinal; + Winner: Byte; + end; + + TeamOrderEntry = record + Teamnum: Byte; + Score: Byte; + end; + + TeamOrderArray = Array[0..5] of Byte; + + TUS_ModiInfoEx = record + Info: TUS_ModiInfo; + Owner: Integer; + TimesPlayed: Byte; //Helper for setting Round Plugins + end; + + TPartySession = class (TCoreModule) + private + bPartyMode: Boolean; //Is this Party or Singleplayer + CurRound: Byte; + + Modis: Array of TUS_ModiInfoEx; + Teams: TTeamInfo; + + function IsWinner(Player, Winner: Byte): boolean; + procedure GenScores; + function GetRandomPlugin(TeamMode: Boolean): Cardinal; + function GetRandomPlayer(Team: Byte): Byte; + public + //Teams: TTeamInfo; + Rounds: array of TRoundInfo; + + //TCoreModule methods to inherit + Constructor Create; override; + Procedure Info(const pInfo: PModuleInfo); override; + Function Load: Boolean; override; + Function Init: Boolean; override; + Procedure DeInit; override; + Destructor Destroy; override; + + //Register Modi Service + Function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new Modi. wParam: Pointer to TUS_ModiInfo + + //Start new Party + Function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new Party Mode. Returns Non Zero on Success + Function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns Pointer to Cur. Modis TUS_ModiInfo (to Use with Singscreen) + Function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops Party Mode. Returns 1 If Partymode was enabled before. + Function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases CurRound by 1; Returns num of Round or -1 if last Round is already played + + Function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading + Function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and does the RoundEnding + + Function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success + Function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success + + Function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ... + Function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam + end; + +const + StandardModi = 0; //Modi ID that will be played in non party Mode + +implementation + +uses UCore, UGraphic, UMain, ULanguage, ULog, SysUtils; + +{********************* + TPluginLoader + Implentation +*********************} + +//------------- +// Function that gives some Infos about the Module to the Core +//------------- +Procedure TPartySession.Info(const pInfo: PModuleInfo); +begin + pInfo^.Name := 'TPartySession'; + pInfo^.Version := MakeVersion(1,0,0,chr(0)); + pInfo^.Description := 'Manages Party Modi and Party Game'; +end; + +//------------- +// Just the Constructor +//------------- +Constructor TPartySession.Create; +begin + inherited; + //UnSet PartyMode + bPartyMode := False; +end; + +//------------- +//Is Called on Loading. +//In this Method only Events and Services should be created +//to offer them to other Modules or Plugins during the Init process +//If False is Returned this will cause a Forced Exit +//------------- +Function TPartySession.Load: Boolean; +begin + //Add Register Party Modi Service + Result := True; + Core.Services.AddService('Party/RegisterModi', nil, Self.RegisterModi); + Core.Services.AddService('Party/StartParty', nil, Self.StartParty); + Core.Services.AddService('Party/GetCurModi', nil, Self.GetCurModi); +end; + +//------------- +//Is Called on Init Process +//In this Method you can Hook some Events and Create + Init +//your Classes, Variables etc. +//If False is Returned this will cause a Forced Exit +//------------- +Function TPartySession.Init: Boolean; +begin + //Just set Prvate Var to true. + Result := true; +end; + +//------------- +//Is Called if this Module has been Inited and there is a Exit. +//Deinit is in backwards Initing Order +//------------- +Procedure TPartySession.DeInit; +begin + //Force DeInit + +end; + +//------------- +//Is Called if this Module will be unloaded and has been created +//Should be used to Free Memory +//------------- +Destructor TPartySession.Destroy; +begin + //Just save some Memory if it wasn't done now.. + SetLength(Modis, 0); + inherited; +end; + +//------------- +// Registers a new Modi. wParam: Pointer to TUS_ModiInfo +// Service for Plugins +//------------- +Function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; +var + Len: Integer; + Info: PUS_ModiInfo; +begin + Info := PModiInfo; + //Copy Info if cbSize is correct + If (Info.cbSize = SizeOf(TUS_ModiInfo)) then + begin + Len := Length(Modis); + SetLength(Modis, Len + 1); + + Modis[Len].Info := Info^; + end + else + Core.ReportError(Integer(PChar('Plugins try to Register Modi with wrong Pointer, or wrong TUS_ModiInfo Record.')), PChar('TPartySession')); + + // FIXME: return a valid result + Result := 0; +end; + +//---------- +// Returns a Number of a Random Plugin +//---------- +Function TPartySession.GetRandomPlugin(TeamMode: Boolean): Cardinal; +var + LowestTP: Byte; + NumPwithLTP: Word; + I: Integer; + R: Word; +begin + Result := StandardModi; //If there are no matching Modis, Play StandardModi + LowestTP := high(Byte); + NumPwithLTP := 0; + + //Search for Plugins not often played yet + For I := 0 to high(Modis) do + begin + if (Modis[I].TimesPlayed < lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then + begin + lowestTP := Modis[I].TimesPlayed; + NumPwithLTP := 1; + end + else if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then + begin + Inc(NumPwithLTP); + end; + end; + + //Create Random No + R := Random(NumPwithLTP); + + //Search for Random Plugin + For I := 0 to high(Modis) do + begin + if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then + begin + //Plugin Found + if (R = 0) then + begin + Result := I; + Inc(Modis[I].TimesPlayed); + Break; + end; + + Dec(R); + end; + end; +end; + +//---------- +// Starts new Party Mode. Returns Non Zero on Success +//---------- +Function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; +var + I: Integer; + aiRounds: PARounds; + TeamMode: Boolean; +begin + Result := 0; + If (Teams.NumTeams >= 1) AND (NumRounds < High(Byte)-1) then + begin + bPartyMode := false; + aiRounds := PAofIRounds; + + Try + //Is this Teammode(More then one Player per Team) ? + TeamMode := True; + For I := 0 to Teams.NumTeams-1 do + TeamMode := TeamMode AND (Teams.Teaminfo[I].NumPlayers > 1); + + //Set Rounds + SetLength(Rounds, NumRounds); + + For I := 0 to High(Rounds) do + begin //Set Plugins + If (aiRounds[I] = -1) then + Rounds[I].Modi := GetRandomPlugin(TeamMode) + Else If (aiRounds[I] >= 0) AND (aiRounds[I] <= High(Modis)) AND (TeamMode OR ((Modis[aiRounds[I]].Info.LoadingSettings AND MLS_TeamOnly) = 0)) then + Rounds[I].Modi := aiRounds[I] + Else + Rounds[I].Modi := StandardModi; + + Rounds[I].Winner := High(Byte); //Set Winner to Not Played + end; + + CurRound := High(Byte); //Set CurRound to not defined + + //Return teh true and Set PartyMode + bPartyMode := True; + Result := 1; + + Except + Core.ReportError(Integer(PChar('Can''t start PartyMode.')), PChar('TPartySession')); + end; + end; +end; + +//---------- +// Returns Pointer to Cur. ModiInfoEx (to Use with Singscreen) +//---------- +Function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer; +begin + If (bPartyMode) AND (CurRound <= High(Rounds)) then + begin //If PartyMode is enabled: + //Return the Plugin of the Cur Round + Result := Integer(@Modis[Rounds[CurRound].Modi]); + end + else + begin //Return StandardModi + Result := Integer(@Modis[StandardModi]); + end; +end; + +//---------- +// Stops Party Mode. Returns 1 If Partymode was enabled before. And -1 if Change was not possible +//---------- +Function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer; +begin + Result := -1; + If (bPartyMode) then + begin + // to-do : Whitü: Check here if SingScreen is not Shown atm. + bPartyMode := False; + Result := 1; + end + else + Result := 0; +end; + +//---------- +//GetRandomPlayer - Gives back a Random Player to Play next Round +//---------- +function TPartySession.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; + +//---------- +// NextRound - Increases CurRound by 1; Returns num of Round or -1 if last Round is already played +//---------- +Function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer; +var I: Integer; +begin + If ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then + begin //everythings OK! -> Start the Round, maaaaan + Inc(CurRound); + + //Set Players to play this Round + for I := 0 to Teams.NumTeams-1 do + Teams.Teaminfo[I].CurPlayer := GetRandomPlayer(I); + + // FIXME: return a valid result + Result := 0; + end + else + Result := -1; +end; + +//---------- +//IsWinner - Returns True if the Players Bit is set in the Winner Byte +//---------- +function TPartySession.IsWinner(Player, Winner: Byte): boolean; +var + Bit: Byte; +begin + Bit := 1 shl Player; + + Result := ((Winner AND Bit) = Bit); +end; + +//---------- +//GenScores - Inc Scores for Cur. Round +//---------- +procedure TPartySession.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; + +//---------- +// CallModiInit - Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading +//---------- +Function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer; +begin + If (not bPartyMode) then + begin //Set Rounds if not in PartyMode + SetLength(Rounds, 1); + Rounds[0].Modi := StandardModi; + Rounds[0].Winner := High(Byte); + CurRound := 0; + end; + + Try + //Core. + Except + on E : Exception do + begin + Core.ReportError(Integer(PChar('Error starting Modi: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession')); + If (Rounds[CurRound].Modi = StandardModi) then + begin + Core.ReportError(Integer(PChar('Can''t start StandardModi, will exit now!')), PChar('TPartySession')); + Halt; + end + Else //Select StandardModi + begin + Rounds[CurRound].Modi := StandardModi + end; + end; + End; + + // FIXME: return a valid result + Result := 0; +end; + +//---------- +// CallModiDeInit - Calls DeInitProc and does the RoundEnding +//---------- +Function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; +var + I: Integer; + MaxScore: Word; +begin + If (bPartyMode) then + begin + //Get Winner Byte! + if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get Winners from Plugin + Rounds[CurRound].Winner := Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID) + else + begin //Create winners by Score :/ + Rounds[CurRound].Winner := 0; + MaxScore := 0; + for I := 0 to Teams.NumTeams-1 do + begin + // to-do : recode Percentage stuff + //PlayerInfo.Playerinfo[I].Percentage := PlayerInfo.Playerinfo[I].Score div 9999; + if (Player[I].ScoreTotalInt > MaxScore) then + begin + MaxScore := Player[I].ScoreTotalInt; + Rounds[CurRound].Winner := 1 shl I; + end + else if (Player[I].ScoreTotalInt = MaxScore) AND (Player[I].ScoreTotalInt <> 0) then + begin + Rounds[CurRound].Winner := Rounds[CurRound].Winner or (1 shl I); + end; + end; + + + //When nobody has Points -> Everybody loose + if (MaxScore = 0) then + Rounds[CurRound].Winner := 0; + + end; + + //Generate teh Scores + GenScores; + + //Inc Players TimesPlayed + If ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings AND MLS_IncTP) = MLS_IncTP) then + begin + For I := 0 to Teams.NumTeams-1 do + Inc(Teams.TeamInfo[I].Playerinfo[Teams.TeamInfo[I].CurPlayer].TimesPlayed); + end; + end + else if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then + Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID); + + // FIXME: return a valid result + Result := 0; +end; + +//---------- +// GetTeamInfo - Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success +//---------- +Function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; +var Info: ^TTeamInfo; +begin + Result := -1; + Info := pTeamInfo; + If (Info <> nil) then + begin + Try + // to - do : Check Delphi memory management in this case + //Not sure if i had to copy PChars to a new address or if delphi manages this o0 + Info^ := Teams; + Result := 0; + Except + Result := -2; + End; + end; +end; + +//---------- +// SetTeamInfo - Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success +//---------- +Function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; +var + TeamInfobackup: TTeamInfo; + Info: ^TTeamInfo; +begin + Result := -1; + Info := pTeamInfo; + If (Info <> nil) then + begin + Try + TeamInfoBackup := Teams; + // to - do : Check Delphi memory management in this case + //Not sure if i had to copy PChars to a new address or if delphi manages this o0 + Teams := Info^; + Result := 0; + Except + Teams := TeamInfoBackup; + Result := -2; + End; + end; +end; + +//---------- +// GetTeamOrder - Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ... +//---------- +Function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; +var + I, J: Integer; + ATeams: array [0..5] of TeamOrderEntry; + TempTeam: TeamOrderEntry; +begin + // to-do : PartyMode: Write this in another way, so that teams with the same scire get the same Placing + //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 + Result := 0; + For I := 0 to Teams.NumTeams-1 do + Result := Result or (ATeams[I].TeamNum Shl I*3); +end; + +//---------- +// GetWinnerString - wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam +//---------- +Function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer; +var + Winners: Array of String; + I: Integer; + ResultStr: String; + S: ^String; +begin + ResultStr := Language.Translate('PARTY_NOBODY'); + + if (wParam <= High(Rounds)) then + begin + if (Rounds[wParam].Winner <> 0) then + begin + if (Rounds[wParam].Winner = 255) then + begin + ResultStr := Language.Translate('PARTY_NOTPLAYEDYET'); + end + else + begin + SetLength(Winners, 0); + for I := 0 to Teams.NumTeams-1 do + begin + if isWinner(I, Rounds[wParam].Winner) then + begin + SetLength(Winners, Length(Winners) + 1); + Winners[high(Winners)] := Teams.TeamInfo[I].Name; + end; + end; + ResultStr := Language.Implode(Winners); + end; + end; + end; + + //Now Return what we have got + If (lParam = nil) then + begin //ReturnString Length + Result := Length(ResultStr); + end + Else + begin //Return String + Try + S := lParam; + S^ := ResultStr; + Result := 0; + Except + Result := -1; + + End; + end; +end; + +end. -- cgit v1.2.3 From dbf39d5bfc56c24a67d481187c619dc84828221f Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Tue, 23 Sep 2008 21:17:22 +0000 Subject: gpl header added and property svn:header set to "HeadURL Id" git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1403 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 01a182b1..27c2fd44 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -1,3 +1,28 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + unit UParty; interface -- cgit v1.2.3 From 015b6c092b0779ee9b53ed1ee78044737f8dc592 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Tue, 23 Sep 2008 21:43:52 +0000 Subject: indentation unified, no code change. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1406 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 27c2fd44..cf19e46e 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -33,7 +33,10 @@ interface {$I switches.inc} -uses UPartyDefs, UCoreModule, UPluginDefs; +uses + UPartyDefs, + UCoreModule, + UPluginDefs; type ARounds = Array [0..252] of Integer; //0..252 needed for -- cgit v1.2.3 From 0ed59f77bc20668ca5d0aae02d4ea076c18d853f Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Sat, 15 Nov 2008 23:34:48 +0000 Subject: formatting and language. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1522 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 411 ++++++++++++++++++++++++++-------------------------- 1 file changed, 209 insertions(+), 202 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index cf19e46e..f86377f5 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -39,76 +39,82 @@ uses UPluginDefs; type - ARounds = Array [0..252] of Integer; //0..252 needed for + ARounds = array [0..252] of integer; //0..252 needed for PARounds = ^ARounds; TRoundInfo = record - Modi: Cardinal; - Winner: Byte; + Modi: cardinal; + Winner: byte; end; TeamOrderEntry = record - Teamnum: Byte; - Score: Byte; + Teamnum: byte; + Score: byte; end; - TeamOrderArray = Array[0..5] of Byte; + TeamOrderArray = array[0..5] of byte; TUS_ModiInfoEx = record - Info: TUS_ModiInfo; - Owner: Integer; - TimesPlayed: Byte; //Helper for setting Round Plugins + Info: TUS_ModiInfo; + Owner: integer; + TimesPlayed: byte; //Helper for setting round plugins end; TPartySession = class (TCoreModule) private - bPartyMode: Boolean; //Is this Party or Singleplayer - CurRound: Byte; + bPartyMode: boolean; //Is this party or single player + CurRound: byte; - Modis: Array of TUS_ModiInfoEx; + Modis: array of TUS_ModiInfoEx; Teams: TTeamInfo; - function IsWinner(Player, Winner: Byte): boolean; + function IsWinner(Player, Winner: byte): boolean; procedure GenScores; - function GetRandomPlugin(TeamMode: Boolean): Cardinal; - function GetRandomPlayer(Team: Byte): Byte; + function GetRandomPlugin(TeamMode: boolean): cardinal; + function GetRandomPlayer(Team: byte): byte; public //Teams: TTeamInfo; Rounds: array of TRoundInfo; //TCoreModule methods to inherit - Constructor Create; override; - Procedure Info(const pInfo: PModuleInfo); override; - Function Load: Boolean; override; - Function Init: Boolean; override; - Procedure DeInit; override; - Destructor Destroy; override; + constructor Create; override; + procedure Info(const pInfo: PModuleInfo); override; + function Load: boolean; override; + function Init: boolean; override; + procedure DeInit; override; + destructor Destroy; override; - //Register Modi Service - Function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new Modi. wParam: Pointer to TUS_ModiInfo + //Register modus service + function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new modus. wParam: Pointer to TUS_ModiInfo //Start new Party - Function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new Party Mode. Returns Non Zero on Success - Function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns Pointer to Cur. Modis TUS_ModiInfo (to Use with Singscreen) - Function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops Party Mode. Returns 1 If Partymode was enabled before. - Function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases CurRound by 1; Returns num of Round or -1 if last Round is already played + function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new party mode. Returns non zero on success + function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns pointer to cur. Modis TUS_ModiInfo (to Use with Singscreen) + function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops party mode. Returns 1 if party mode was enabled before. + function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases curround by 1; Returns num of round or -1 if last round is already played - Function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading - Function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and does the RoundEnding + function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls curmodis init proc. If an error occurs, returns nonzero. In this case a new plugin was selected. Please renew loading + function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and ends the round - Function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success - Function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success + function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo record to pointer at lParam. Returns zero on success + function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo record from pointer at lParam. Returns zero on success - Function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ... - Function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam + function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns team order. Structure: Bits 1..3: Team at place1; Bits 4..6: Team at place2 ... + function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is roundnum. If (Pointer = nil) then return length of the string. Otherwise write the string to address at lParam end; const - StandardModi = 0; //Modi ID that will be played in non party Mode + StandardModi = 0; //Modus ID that will be played in non-party mode implementation -uses UCore, UGraphic, UMain, ULanguage, ULog, SysUtils; +uses + UCore, + UGraphic, + UMain, + ULanguage, + ULog, + SysUtils; {********************* TPluginLoader @@ -116,19 +122,19 @@ uses UCore, UGraphic, UMain, ULanguage, ULog, SysUtils; *********************} //------------- -// Function that gives some Infos about the Module to the Core +// function that gives some infos about the module to the core //------------- -Procedure TPartySession.Info(const pInfo: PModuleInfo); +procedure TPartySession.Info(const pInfo: PModuleInfo); begin pInfo^.Name := 'TPartySession'; pInfo^.Version := MakeVersion(1,0,0,chr(0)); - pInfo^.Description := 'Manages Party Modi and Party Game'; + pInfo^.Description := 'Manages party modi and party game'; end; //------------- -// Just the Constructor +// Just the constructor //------------- -Constructor TPartySession.Create; +constructor TPartySession.Create; begin inherited; //UnSet PartyMode @@ -136,14 +142,14 @@ begin end; //------------- -//Is Called on Loading. -//In this Method only Events and Services should be created -//to offer them to other Modules or Plugins during the Init process -//If False is Returned this will cause a Forced Exit +//Is called on loading. +//In this method only events and services should be created +//to offer them to other modules or plugins during the init process +//If false is returned this will cause a forced exit //------------- -Function TPartySession.Load: Boolean; +function TPartySession.Load: boolean; begin - //Add Register Party Modi Service + //Add register party modus service Result := True; Core.Services.AddService('Party/RegisterModi', nil, Self.RegisterModi); Core.Services.AddService('Party/StartParty', nil, Self.StartParty); @@ -151,50 +157,49 @@ begin end; //------------- -//Is Called on Init Process -//In this Method you can Hook some Events and Create + Init -//your Classes, Variables etc. -//If False is Returned this will cause a Forced Exit +//Is called on init process +//In this method you can hook some events and create + init +//your classes, variables etc. +//If false is returned this will cause a forced exit //------------- -Function TPartySession.Init: Boolean; +function TPartySession.Init: boolean; begin - //Just set Prvate Var to true. + //Just set private var to true. Result := true; end; //------------- -//Is Called if this Module has been Inited and there is a Exit. -//Deinit is in backwards Initing Order +//Is called if this module has been inited and there is an exit. +//Deinit is in reverse initing order //------------- -Procedure TPartySession.DeInit; +procedure TPartySession.DeInit; begin //Force DeInit - end; //------------- -//Is Called if this Module will be unloaded and has been created -//Should be used to Free Memory +//Is called if this module will be unloaded and has been created +//Should be used to free memory //------------- -Destructor TPartySession.Destroy; +destructor TPartySession.Destroy; begin - //Just save some Memory if it wasn't done now.. + //Just save some memory if it wasn't done now.. SetLength(Modis, 0); inherited; end; //------------- -// Registers a new Modi. wParam: Pointer to TUS_ModiInfo -// Service for Plugins +// Registers a new modus. wParam: Pointer to TUS_ModiInfo +// Service for plugins //------------- -Function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; +function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; var - Len: Integer; + Len: integer; Info: PUS_ModiInfo; begin Info := PModiInfo; //Copy Info if cbSize is correct - If (Info.cbSize = SizeOf(TUS_ModiInfo)) then + if (Info.cbSize = SizeOf(TUS_ModiInfo)) then begin Len := Length(Modis); SetLength(Modis, Len + 1); @@ -202,35 +207,35 @@ begin Modis[Len].Info := Info^; end else - Core.ReportError(Integer(PChar('Plugins try to Register Modi with wrong Pointer, or wrong TUS_ModiInfo Record.')), PChar('TPartySession')); + Core.ReportError(integer(PChar('Plugins try to register modus with wrong pointer, or wrong TUS_ModiInfo record.')), PChar('TPartySession')); // FIXME: return a valid result Result := 0; end; //---------- -// Returns a Number of a Random Plugin +// Returns a number of a random plugin //---------- -Function TPartySession.GetRandomPlugin(TeamMode: Boolean): Cardinal; +function TPartySession.GetRandomPlugin(TeamMode: boolean): cardinal; var - LowestTP: Byte; - NumPwithLTP: Word; - I: Integer; - R: Word; + LowestTP: byte; + NumPwithLTP: word; + I: integer; + R: word; begin - Result := StandardModi; //If there are no matching Modis, Play StandardModi - LowestTP := high(Byte); + Result := StandardModi; //If there are no matching modi, play standard modus + LowestTP := high(byte); NumPwithLTP := 0; //Search for Plugins not often played yet - For I := 0 to high(Modis) do + for I := 0 to high(Modis) do begin - if (Modis[I].TimesPlayed < lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then + if (Modis[I].TimesPlayed < lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then begin lowestTP := Modis[I].TimesPlayed; NumPwithLTP := 1; end - else if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then + else if (Modis[I].TimesPlayed = lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then begin Inc(NumPwithLTP); end; @@ -240,9 +245,9 @@ begin R := Random(NumPwithLTP); //Search for Random Plugin - For I := 0 to high(Modis) do + for I := 0 to high(Modis) do begin - if (Modis[I].TimesPlayed = lowestTP) And (((Modis[I].Info.LoadingSettings AND MLS_TeamOnly) <> 0) = TeamMode) then + if (Modis[I].TimesPlayed = lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then begin //Plugin Found if (R = 0) then @@ -258,76 +263,76 @@ begin end; //---------- -// Starts new Party Mode. Returns Non Zero on Success +// Starts new party mode. Returns non zero on success //---------- -Function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; +function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; var - I: Integer; + I: integer; aiRounds: PARounds; - TeamMode: Boolean; + TeamMode: boolean; begin Result := 0; - If (Teams.NumTeams >= 1) AND (NumRounds < High(Byte)-1) then + if (Teams.NumTeams >= 1) and (NumRounds < High(byte)-1) then begin bPartyMode := false; aiRounds := PAofIRounds; - Try + try //Is this Teammode(More then one Player per Team) ? TeamMode := True; - For I := 0 to Teams.NumTeams-1 do - TeamMode := TeamMode AND (Teams.Teaminfo[I].NumPlayers > 1); + for I := 0 to Teams.NumTeams-1 do + TeamMode := TeamMode and (Teams.Teaminfo[I].NumPlayers > 1); //Set Rounds SetLength(Rounds, NumRounds); - For I := 0 to High(Rounds) do + for I := 0 to High(Rounds) do begin //Set Plugins - If (aiRounds[I] = -1) then + if (aiRounds[I] = -1) then Rounds[I].Modi := GetRandomPlugin(TeamMode) - Else If (aiRounds[I] >= 0) AND (aiRounds[I] <= High(Modis)) AND (TeamMode OR ((Modis[aiRounds[I]].Info.LoadingSettings AND MLS_TeamOnly) = 0)) then + else if (aiRounds[I] >= 0) and (aiRounds[I] <= High(Modis)) and (TeamMode or ((Modis[aiRounds[I]].Info.LoadingSettings and MLS_TeamOnly) = 0)) then Rounds[I].Modi := aiRounds[I] - Else + else Rounds[I].Modi := StandardModi; - Rounds[I].Winner := High(Byte); //Set Winner to Not Played + Rounds[I].Winner := High(byte); //Set Winner to Not Played end; - CurRound := High(Byte); //Set CurRound to not defined + CurRound := High(byte); //Set CurRound to not defined //Return teh true and Set PartyMode bPartyMode := True; Result := 1; - Except - Core.ReportError(Integer(PChar('Can''t start PartyMode.')), PChar('TPartySession')); + except + Core.ReportError(integer(PChar('Can''t start PartyMode.')), PChar('TPartySession')); end; end; end; //---------- -// Returns Pointer to Cur. ModiInfoEx (to Use with Singscreen) +// Returns Pointer to Cur. ModiInfoEx (to use with sing screen) //---------- -Function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer; begin - If (bPartyMode) AND (CurRound <= High(Rounds)) then + if (bPartyMode) and (CurRound <= High(Rounds)) then begin //If PartyMode is enabled: //Return the Plugin of the Cur Round - Result := Integer(@Modis[Rounds[CurRound].Modi]); + Result := integer(@Modis[Rounds[CurRound].Modi]); end else begin //Return StandardModi - Result := Integer(@Modis[StandardModi]); + Result := integer(@Modis[StandardModi]); end; end; //---------- // Stops Party Mode. Returns 1 If Partymode was enabled before. And -1 if Change was not possible //---------- -Function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer; begin Result := -1; - If (bPartyMode) then + if (bPartyMode) then begin // to-do : Whitü: Check here if SingScreen is not Shown atm. bPartyMode := False; @@ -338,59 +343,60 @@ begin end; //---------- -//GetRandomPlayer - Gives back a Random Player to Play next Round +//GetRandomPlayer - gives back a random player to play next round //---------- -function TPartySession.GetRandomPlayer(Team: Byte): Byte; +function TPartySession.GetRandomPlayer(Team: byte): byte; var - I, R: Integer; - lowestTP: Byte; - NumPwithLTP: Byte; + I, R: integer; + lowestTP: byte; + NumPwithLTP: byte; begin - LowestTP := high(Byte); - NumPwithLTP := 0; - Result := 0; + 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 + //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 - 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; + 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); + //Create random no + R := Random(NumPwithLTP); - //Search for Random Player - For I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do + //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 - if Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP then + //Player found + if (R = 0) then begin - //Player Found - if (R = 0) then - begin - Result := I; - Break; - end; - - Dec(R); + Result := I; + Break; end; + + Dec(R); end; + end; end; //---------- -// NextRound - Increases CurRound by 1; Returns num of Round or -1 if last Round is already played +// NextRound - Increases CurRound by 1; Returns num of round or -1 if last round is already played //---------- -Function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer; -var I: Integer; +function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer; +var + I: integer; begin - If ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then + if ((CurRound < high(Rounds)) or (CurRound = high(CurRound))) then begin //everythings OK! -> Start the Round, maaaaan Inc(CurRound); @@ -406,23 +412,23 @@ begin end; //---------- -//IsWinner - Returns True if the Players Bit is set in the Winner Byte +//IsWinner - returns true if the players bit is set in the winner byte //---------- -function TPartySession.IsWinner(Player, Winner: Byte): boolean; +function TPartySession.IsWinner(Player, Winner: byte): boolean; var - Bit: Byte; + Bit: byte; begin Bit := 1 shl Player; - Result := ((Winner AND Bit) = Bit); + Result := ((Winner and Bit) = Bit); end; //---------- -//GenScores - Inc Scores for Cur. Round +//GenScores - inc scores for cur. round //---------- procedure TPartySession.GenScores; var - I: Byte; + I: byte; begin for I := 0 to Teams.NumTeams-1 do begin @@ -432,86 +438,86 @@ begin end; //---------- -// CallModiInit - Calls CurModis Init Proc. If an Error occurs, Returns Nonzero. In this Case a New Plugin was Selected. Please renew Loading +// CallModiInit - calls CurModis Init Proc. If an error occurs, returns nonzero. In this case a new plugin was selected. Please renew loading //---------- -Function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer; begin - If (not bPartyMode) then - begin //Set Rounds if not in PartyMode + if (not bPartyMode) then + begin //Set rounds if not in party mode SetLength(Rounds, 1); Rounds[0].Modi := StandardModi; - Rounds[0].Winner := High(Byte); + Rounds[0].Winner := High(byte); CurRound := 0; end; - Try + try //Core. - Except + except on E : Exception do begin - Core.ReportError(Integer(PChar('Error starting Modi: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession')); - If (Rounds[CurRound].Modi = StandardModi) then + Core.ReportError(integer(PChar('Error starting modus: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession')); + if (Rounds[CurRound].Modi = StandardModi) then begin - Core.ReportError(Integer(PChar('Can''t start StandardModi, will exit now!')), PChar('TPartySession')); + Core.ReportError(integer(PChar('Can''t start standard modus, will exit now!')), PChar('TPartySession')); Halt; end - Else //Select StandardModi + else //Select StandardModi begin Rounds[CurRound].Modi := StandardModi end; end; - End; + end; // FIXME: return a valid result Result := 0; end; //---------- -// CallModiDeInit - Calls DeInitProc and does the RoundEnding +// CallModiDeInit - calls DeInitProc and ends the round //---------- -Function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; var - I: Integer; - MaxScore: Word; + I: integer; + MaxScore: word; begin - If (bPartyMode) then + if (bPartyMode) then begin //Get Winner Byte! - if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get Winners from Plugin + if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get winners from plugin Rounds[CurRound].Winner := Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID) else - begin //Create winners by Score :/ + begin //Create winners by score :/ Rounds[CurRound].Winner := 0; MaxScore := 0; for I := 0 to Teams.NumTeams-1 do begin - // to-do : recode Percentage stuff + // to-do : recode percentage stuff //PlayerInfo.Playerinfo[I].Percentage := PlayerInfo.Playerinfo[I].Score div 9999; if (Player[I].ScoreTotalInt > MaxScore) then begin MaxScore := Player[I].ScoreTotalInt; Rounds[CurRound].Winner := 1 shl I; end - else if (Player[I].ScoreTotalInt = MaxScore) AND (Player[I].ScoreTotalInt <> 0) then + else if (Player[I].ScoreTotalInt = MaxScore) and (Player[I].ScoreTotalInt <> 0) then begin Rounds[CurRound].Winner := Rounds[CurRound].Winner or (1 shl I); end; end; - //When nobody has Points -> Everybody loose + //When nobody has points -> everybody looses if (MaxScore = 0) then Rounds[CurRound].Winner := 0; end; - //Generate teh Scores + //Generate the scores GenScores; - //Inc Players TimesPlayed - If ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings AND MLS_IncTP) = MLS_IncTP) then + //Inc players TimesPlayed + if ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings and MLS_IncTP) = MLS_IncTP) then begin - For I := 0 to Teams.NumTeams-1 do + for I := 0 to Teams.NumTeams-1 do Inc(Teams.TeamInfo[I].Playerinfo[Teams.TeamInfo[I].CurPlayer].TimesPlayed); end; end @@ -523,69 +529,70 @@ begin end; //---------- -// GetTeamInfo - Writes TTeamInfo Record to Pointer at lParam. Returns Zero on Success +// GetTeamInfo - writes TTeamInfo record to pointer at lParam. Returns zero on success //---------- -Function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; -var Info: ^TTeamInfo; +function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; +var + Info: ^TTeamInfo; begin Result := -1; Info := pTeamInfo; - If (Info <> nil) then + if (Info <> nil) then begin - Try + try // to - do : Check Delphi memory management in this case //Not sure if i had to copy PChars to a new address or if delphi manages this o0 Info^ := Teams; Result := 0; - Except + except Result := -2; - End; + end; end; end; //---------- -// SetTeamInfo - Read TTeamInfo Record from Pointer at lParam. Returns Zero on Success +// SetTeamInfo - read TTeamInfo record from pointer at lParam. Returns zero on success //---------- -Function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; +function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; var TeamInfobackup: TTeamInfo; Info: ^TTeamInfo; begin Result := -1; Info := pTeamInfo; - If (Info <> nil) then + if (Info <> nil) then begin - Try + try TeamInfoBackup := Teams; // to - do : Check Delphi memory management in this case //Not sure if i had to copy PChars to a new address or if delphi manages this o0 Teams := Info^; Result := 0; - Except + except Teams := TeamInfoBackup; Result := -2; - End; + end; end; end; //---------- -// GetTeamOrder - Returns Team Order. Structure: Bits 1..3: Team at Place1; Bits 4..6: Team at Place2 ... +// GetTeamOrder - returns team order. Structure: Bits 1..3: Team at place1; Bits 4..6: Team at place2 ... //---------- -Function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; var - I, J: Integer; + I, J: integer; ATeams: array [0..5] of TeamOrderEntry; TempTeam: TeamOrderEntry; begin - // to-do : PartyMode: Write this in another way, so that teams with the same scire get the same Placing - //Fill Team Array - For I := 0 to Teams.NumTeams-1 do + // to-do : PartyMode: Write this in another way, so that teams with the same score get the same place + //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 + //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 @@ -597,17 +604,17 @@ begin //Copy to Result Result := 0; - For I := 0 to Teams.NumTeams-1 do + for I := 0 to Teams.NumTeams-1 do Result := Result or (ATeams[I].TeamNum Shl I*3); end; //---------- -// GetWinnerString - wParam is Roundnum. If (Pointer = nil) then Return Length of the String. Otherwise Write the String to Address at lParam +// GetWinnerString - wParam is Roundnum. If (pointer = nil) then return length of the string. Otherwise write the string to address at lParam //---------- -Function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer; var - Winners: Array of String; - I: Integer; + Winners: array of String; + I: integer; ResultStr: String; S: ^String; begin @@ -637,21 +644,21 @@ begin end; end; - //Now Return what we have got - If (lParam = nil) then - begin //ReturnString Length + //Now return what we have got + if (lParam = nil) then + begin //Return string length Result := Length(ResultStr); end - Else + else begin //Return String - Try + try S := lParam; S^ := ResultStr; Result := 0; - Except + except Result := -1; - End; + end; end; end; -- cgit v1.2.3 From 17cfff8c4f38f58b33038622a2fed261c9fa6088 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Wed, 26 Nov 2008 22:46:11 +0000 Subject: formatting and modi change to modus git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1528 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 54 ++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index f86377f5..18d15745 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -104,7 +104,7 @@ type end; const - StandardModi = 0; //Modus ID that will be played in non-party mode + StandardModus = 0; //Modus ID that will be played in non-party mode implementation @@ -138,7 +138,7 @@ constructor TPartySession.Create; begin inherited; //UnSet PartyMode - bPartyMode := False; + bPartyMode := false; end; //------------- @@ -150,7 +150,7 @@ end; function TPartySession.Load: boolean; begin //Add register party modus service - Result := True; + Result := true; Core.Services.AddService('Party/RegisterModi', nil, Self.RegisterModi); Core.Services.AddService('Party/StartParty', nil, Self.StartParty); Core.Services.AddService('Party/GetCurModi', nil, Self.GetCurModi); @@ -223,7 +223,7 @@ var I: integer; R: word; begin - Result := StandardModi; //If there are no matching modi, play standard modus + Result := StandardModus; //If there are no matching modi, play standard modus LowestTP := high(byte); NumPwithLTP := 0; @@ -241,15 +241,15 @@ begin end; end; - //Create Random No + //Create random no R := Random(NumPwithLTP); - //Search for Random Plugin + //Search for random plugin for I := 0 to high(Modis) do begin if (Modis[I].TimesPlayed = lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then begin - //Plugin Found + //Plugin found if (R = 0) then begin Result := I; @@ -278,8 +278,8 @@ begin aiRounds := PAofIRounds; try - //Is this Teammode(More then one Player per Team) ? - TeamMode := True; + //Is this team mode (More than one player per team) ? + TeamMode := true; for I := 0 to Teams.NumTeams-1 do TeamMode := TeamMode and (Teams.Teaminfo[I].NumPlayers > 1); @@ -287,31 +287,31 @@ begin SetLength(Rounds, NumRounds); for I := 0 to High(Rounds) do - begin //Set Plugins + begin //Set plugins if (aiRounds[I] = -1) then Rounds[I].Modi := GetRandomPlugin(TeamMode) else if (aiRounds[I] >= 0) and (aiRounds[I] <= High(Modis)) and (TeamMode or ((Modis[aiRounds[I]].Info.LoadingSettings and MLS_TeamOnly) = 0)) then Rounds[I].Modi := aiRounds[I] else - Rounds[I].Modi := StandardModi; + Rounds[I].Modi := StandardModus; - Rounds[I].Winner := High(byte); //Set Winner to Not Played + Rounds[I].Winner := High(byte); //Set winner to not played end; CurRound := High(byte); //Set CurRound to not defined - //Return teh true and Set PartyMode - bPartyMode := True; + //Return true and set party mode + bPartyMode := true; Result := 1; except - Core.ReportError(integer(PChar('Can''t start PartyMode.')), PChar('TPartySession')); + Core.ReportError(integer(PChar('Can''t start party mode.')), PChar('TPartySession')); end; end; end; //---------- -// Returns Pointer to Cur. ModiInfoEx (to use with sing screen) +// Returns pointer to Cur. ModiInfoEx (to use with sing screen) //---------- function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer; begin @@ -321,21 +321,21 @@ begin Result := integer(@Modis[Rounds[CurRound].Modi]); end else - begin //Return StandardModi - Result := integer(@Modis[StandardModi]); + begin //Return standard modus + Result := integer(@Modis[StandardModus]); end; end; //---------- -// Stops Party Mode. Returns 1 If Partymode was enabled before. And -1 if Change was not possible +// Stops party mode. Returns 1 if party mode was enabled before and -1 if change was not possible //---------- function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer; begin Result := -1; if (bPartyMode) then begin - // to-do : Whitü: Check here if SingScreen is not Shown atm. - bPartyMode := False; + // to-do : Whitü: Check here if sing screen is not shown atm. + bPartyMode := false; Result := 1; end else @@ -355,7 +355,7 @@ begin NumPwithLTP := 0; Result := 0; - //Search for Players that have not often played yet + //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 @@ -445,7 +445,7 @@ begin if (not bPartyMode) then begin //Set rounds if not in party mode SetLength(Rounds, 1); - Rounds[0].Modi := StandardModi; + Rounds[0].Modi := StandardModus; Rounds[0].Winner := High(byte); CurRound := 0; end; @@ -456,14 +456,14 @@ begin on E : Exception do begin Core.ReportError(integer(PChar('Error starting modus: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession')); - if (Rounds[CurRound].Modi = StandardModi) then + if (Rounds[CurRound].Modi = StandardModus) then begin Core.ReportError(integer(PChar('Can''t start standard modus, will exit now!')), PChar('TPartySession')); Halt; end - else //Select StandardModi + else //Select standard modus begin - Rounds[CurRound].Modi := StandardModi + Rounds[CurRound].Modi := StandardModus end; end; end; @@ -650,7 +650,7 @@ begin Result := Length(ResultStr); end else - begin //Return String + begin //Return string try S := lParam; S^ := ResultStr; -- cgit v1.2.3 From f469075a0335399c753ae5d2d362047dedf116b1 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Sat, 7 Mar 2009 21:14:14 +0000 Subject: final cleanup of Umain. Creation of UNote git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1627 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 18d15745..23012dfe 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -111,9 +111,9 @@ implementation uses UCore, UGraphic, - UMain, ULanguage, ULog, + UNote, SysUtils; {********************* -- cgit v1.2.3 From 31b5e9286f721b7cc81f620a28d8de5d0087c63c Mon Sep 17 00:00:00 2001 From: tobigun Date: Sat, 21 Mar 2009 19:11:54 +0000 Subject: New plugin mode reverted (will be moved to a branch afterwards). Party mode might work again (untested). This might break linux compatibility. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1641 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 562 +++++++++++++--------------------------------------- 1 file changed, 140 insertions(+), 422 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 23012dfe..9d70e2be 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -34,208 +34,85 @@ interface {$I switches.inc} uses - UPartyDefs, - UCoreModule, - UPluginDefs; + ModiSDK; type - ARounds = array [0..252] of integer; //0..252 needed for - PARounds = ^ARounds; - TRoundInfo = record - Modi: cardinal; + Plugin: word; Winner: byte; end; TeamOrderEntry = record - Teamnum: byte; + TeamNum: byte; Score: byte; end; TeamOrderArray = array[0..5] of byte; - TUS_ModiInfoEx = record - Info: TUS_ModiInfo; - Owner: integer; - TimesPlayed: byte; //Helper for setting round plugins + TPartyPlugin = record + ID: byte; + TimesPlayed: byte; end; - TPartySession = class (TCoreModule) + TPartySession = class private - bPartyMode: boolean; //Is this party or single player - CurRound: byte; - - Modis: array of TUS_ModiInfoEx; - Teams: TTeamInfo; - - function IsWinner(Player, Winner: byte): boolean; + function GetRandomPlayer(Team: Byte): Byte; + function GetRandomPlugin(Plugins: array of TPartyPlugin): byte; + function IsWinner(Player, Winner: Byte): boolean; procedure GenScores; - function GetRandomPlugin(TeamMode: boolean): cardinal; - function GetRandomPlayer(Team: byte): byte; public - //Teams: TTeamInfo; + Teams: TTeamInfo; Rounds: array of TRoundInfo; + CurRound: Byte; - //TCoreModule methods to inherit - constructor Create; override; - procedure Info(const pInfo: PModuleInfo); override; - function Load: boolean; override; - function Init: boolean; override; - procedure DeInit; override; - destructor Destroy; override; + constructor Create; - //Register modus service - function RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; //Registers a new modus. wParam: Pointer to TUS_ModiInfo - - //Start new Party - function StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; //Starts new party mode. Returns non zero on success - function GetCurModi(wParam: TwParam; lParam: TlParam): integer; //Returns pointer to cur. Modis TUS_ModiInfo (to Use with Singscreen) - function StopParty(wParam: TwParam; lParam: TlParam): integer; //Stops party mode. Returns 1 if party mode was enabled before. - function NextRound(wParam: TwParam; lParam: TlParam): integer; //Increases curround by 1; Returns num of round or -1 if last round is already played - - function CallModiInit(wParam: TwParam; lParam: TlParam): integer; //Calls curmodis init proc. If an error occurs, returns nonzero. In this case a new plugin was selected. Please renew loading - function CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; //Calls DeInitProc and ends the round - - function GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Writes TTeamInfo record to pointer at lParam. Returns zero on success - function SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; //Read TTeamInfo record from pointer at lParam. Returns zero on success - - function GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; //Returns team order. Structure: Bits 1..3: Team at place1; Bits 4..6: Team at place2 ... - function GetWinnerString(wParam: TwParam; lParam: TlParam): integer; //wParam is roundnum. If (Pointer = nil) then return length of the string. Otherwise write the string to address at lParam + procedure StartNewParty(NumRounds: Byte); + procedure StartRound; + procedure EndRound; + function GetTeamOrder: TeamOrderArray; + function GetWinnerString(Round: Byte): String; end; -const - StandardModus = 0; //Modus ID that will be played in non-party mode +var + PartySession: TPartySession; implementation uses - UCore, + UDLLManager, UGraphic, - ULanguage, - ULog, UNote, - SysUtils; - -{********************* - TPluginLoader - Implentation -*********************} - -//------------- -// function that gives some infos about the module to the core -//------------- -procedure TPartySession.Info(const pInfo: PModuleInfo); -begin - pInfo^.Name := 'TPartySession'; - pInfo^.Version := MakeVersion(1,0,0,chr(0)); - pInfo^.Description := 'Manages party modi and party game'; -end; + ULanguage, + ULog; -//------------- -// Just the constructor -//------------- constructor TPartySession.Create; begin inherited; - //UnSet PartyMode - bPartyMode := false; -end; - -//------------- -//Is called on loading. -//In this method only events and services should be created -//to offer them to other modules or plugins during the init process -//If false is returned this will cause a forced exit -//------------- -function TPartySession.Load: boolean; -begin - //Add register party modus service - Result := true; - Core.Services.AddService('Party/RegisterModi', nil, Self.RegisterModi); - Core.Services.AddService('Party/StartParty', nil, Self.StartParty); - Core.Services.AddService('Party/GetCurModi', nil, Self.GetCurModi); -end; - -//------------- -//Is called on init process -//In this method you can hook some events and create + init -//your classes, variables etc. -//If false is returned this will cause a forced exit -//------------- -function TPartySession.Init: boolean; -begin - //Just set private var to true. - Result := true; -end; - -//------------- -//Is called if this module has been inited and there is an exit. -//Deinit is in reverse initing order -//------------- -procedure TPartySession.DeInit; -begin - //Force DeInit -end; - -//------------- -//Is called if this module will be unloaded and has been created -//Should be used to free memory -//------------- -destructor TPartySession.Destroy; -begin - //Just save some memory if it wasn't done now.. - SetLength(Modis, 0); - inherited; -end; - -//------------- -// Registers a new modus. wParam: Pointer to TUS_ModiInfo -// Service for plugins -//------------- -function TPartySession.RegisterModi(nothin: TwParam; pModiInfo: TlParam): integer; -var - Len: integer; - Info: PUS_ModiInfo; -begin - Info := PModiInfo; - //Copy Info if cbSize is correct - if (Info.cbSize = SizeOf(TUS_ModiInfo)) then - begin - Len := Length(Modis); - SetLength(Modis, Len + 1); - - Modis[Len].Info := Info^; - end - else - Core.ReportError(integer(PChar('Plugins try to register modus with wrong pointer, or wrong TUS_ModiInfo record.')), PChar('TPartySession')); - - // FIXME: return a valid result - Result := 0; end; //---------- // Returns a number of a random plugin //---------- -function TPartySession.GetRandomPlugin(TeamMode: boolean): cardinal; +function TPartySession.GetRandomPlugin(Plugins: array of TPartyPlugin): byte; var LowestTP: byte; NumPwithLTP: word; I: integer; R: word; begin - Result := StandardModus; //If there are no matching modi, play standard modus LowestTP := high(byte); NumPwithLTP := 0; //Search for Plugins not often played yet - for I := 0 to high(Modis) do + for I := 0 to high(Plugins) do begin - if (Modis[I].TimesPlayed < lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then + if (Plugins[I].TimesPlayed < lowestTP) then begin - lowestTP := Modis[I].TimesPlayed; + lowestTP := Plugins[I].TimesPlayed; NumPwithLTP := 1; end - else if (Modis[I].TimesPlayed = lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then + else if (Plugins[I].TimesPlayed = lowestTP) then begin Inc(NumPwithLTP); end; @@ -245,110 +122,89 @@ begin R := Random(NumPwithLTP); //Search for random plugin - for I := 0 to high(Modis) do + for I := 0 to high(Plugins) do begin - if (Modis[I].TimesPlayed = lowestTP) and (((Modis[I].Info.LoadingSettings and MLS_TeamOnly) <> 0) = TeamMode) then + if Plugins[I].TimesPlayed = LowestTP then begin //Plugin found if (R = 0) then begin - Result := I; - Inc(Modis[I].TimesPlayed); + Result := Plugins[I].ID; + Inc(Plugins[I].TimesPlayed); Break; end; - Dec(R); end; end; end; //---------- -// Starts new party mode. Returns non zero on success +//StartNewParty - Reset and prepares for new party //---------- -function TPartySession.StartParty(NumRounds: TwParam; PAofIRounds: TlParam): integer; +procedure TPartySession.StartNewParty(NumRounds: Byte); var - I: integer; - aiRounds: PARounds; + Plugins: array of TPartyPlugin; TeamMode: boolean; + Len: integer; + I, J: integer; begin - Result := 0; - if (Teams.NumTeams >= 1) and (NumRounds < High(byte)-1) then - begin - bPartyMode := false; - aiRounds := PAofIRounds; - - try - //Is this team mode (More than one player per team) ? - TeamMode := true; - for I := 0 to Teams.NumTeams-1 do - TeamMode := TeamMode and (Teams.Teaminfo[I].NumPlayers > 1); - - //Set Rounds - SetLength(Rounds, NumRounds); - - for I := 0 to High(Rounds) do - begin //Set plugins - if (aiRounds[I] = -1) then - Rounds[I].Modi := GetRandomPlugin(TeamMode) - else if (aiRounds[I] >= 0) and (aiRounds[I] <= High(Modis)) and (TeamMode or ((Modis[aiRounds[I]].Info.LoadingSettings and MLS_TeamOnly) = 0)) then - Rounds[I].Modi := aiRounds[I] - else - Rounds[I].Modi := StandardModus; - - Rounds[I].Winner := High(byte); //Set winner to not played - end; - - CurRound := High(byte); //Set CurRound to not defined + //Set current round to 1 + CurRound := 255; - //Return true and set party mode - bPartyMode := true; - Result := 1; + PlayersPlay := Teams.NumTeams; - except - Core.ReportError(integer(PChar('Can''t start party mode.')), PChar('TPartySession')); + //Get team-mode 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); + Teams.Teaminfo[I].Score := 0; end; -end; -//---------- -// Returns pointer to Cur. ModiInfoEx (to use with sing screen) -//---------- -function TPartySession.GetCurModi(wParam: TwParam; lParam: TlParam): integer; -begin - if (bPartyMode) and (CurRound <= High(Rounds)) then - begin //If PartyMode is enabled: - //Return the Plugin of the Cur Round - Result := integer(@Modis[Rounds[CurRound].Modi]); - end - else - begin //Return standard modus - Result := integer(@Modis[StandardModus]); + //Fill plugin array + SetLength(Plugins, 0); + for I := 0 to high(DLLMan.Plugins) do + begin + if TeamMode or (not DLLMan.Plugins[I].TeamModeOnly) then + begin + //Add only those plugins playable with current PlayerConfiguration + Len := Length(Plugins); + SetLength(Plugins, Len + 1); + Plugins[Len].ID := I; + Plugins[Len].TimesPlayed := 0; + end; end; -end; -//---------- -// Stops party mode. Returns 1 if party mode was enabled before and -1 if change was not possible -//---------- -function TPartySession.StopParty(wParam: TwParam; lParam: TlParam): integer; -begin - Result := -1; - if (bPartyMode) then + //Set rounds + if (Length(Plugins) >= 1) then begin - // to-do : Whitü: Check here if sing screen is not shown atm. - bPartyMode := false; - Result := 1; + SetLength (Rounds, NumRounds); + for I := 0 to NumRounds-1 do + begin + PartySession.Rounds[I].Plugin := GetRandomPlugin(Plugins); + PartySession.Rounds[I].Winner := 255; + end; end else - Result := 0; + SetLength (Rounds, 0); end; -//---------- -//GetRandomPlayer - gives back a random player to play next round -//---------- +{** + * Returns a random player to play next round + *} function TPartySession.GetRandomPlayer(Team: byte): byte; var I, R: integer; - lowestTP: byte; + LowestTP: byte; NumPwithLTP: byte; begin LowestTP := high(byte); @@ -369,7 +225,7 @@ begin end; end; - //Create random no + //Create random number R := Random(NumPwithLTP); //Search for random player @@ -389,202 +245,83 @@ begin end; end; -//---------- -// NextRound - Increases CurRound by 1; Returns num of round or -1 if last round is already played -//---------- -function TPartySession.NextRound(wParam: TwParam; lParam: TlParam): integer; +{** + * Prepares ScreenSingModi for next round and loads plugin + *} +procedure TPartySession.StartRound; var I: integer; begin - if ((CurRound < high(Rounds)) or (CurRound = high(CurRound))) then - begin //everythings OK! -> Start the Round, maaaaan + if ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then + begin + //Increase Current Round Inc(CurRound); - //Set Players to play this Round + 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); - - // FIXME: return a valid result - Result := 0; - end - else - Result := -1; -end; - -//---------- -//IsWinner - returns true if the players bit is set in the winner byte -//---------- -function TPartySession.IsWinner(Player, Winner: byte): boolean; -var - Bit: byte; -begin - Bit := 1 shl Player; - Result := ((Winner and Bit) = Bit); -end; - -//---------- -//GenScores - inc scores for cur. round -//---------- -procedure TPartySession.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; - -//---------- -// CallModiInit - calls CurModis Init Proc. If an error occurs, returns nonzero. In this case a new plugin was selected. Please renew loading -//---------- -function TPartySession.CallModiInit(wParam: TwParam; lParam: TlParam): integer; -begin - if (not bPartyMode) then - begin //Set rounds if not in party mode - SetLength(Rounds, 1); - Rounds[0].Modi := StandardModus; - Rounds[0].Winner := High(byte); - CurRound := 0; + //Set ScreenSingModie Variables + ScreenSingModi.TeamInfo := Teams; end; - - try - //Core. - except - on E : Exception do - begin - Core.ReportError(integer(PChar('Error starting modus: ' + Modis[Rounds[CurRound].Modi].Info.Name + ' ErrorStr: ' + E.Message)), PChar('TPartySession')); - if (Rounds[CurRound].Modi = StandardModus) then - begin - Core.ReportError(integer(PChar('Can''t start standard modus, will exit now!')), PChar('TPartySession')); - Halt; - end - else //Select standard modus - begin - Rounds[CurRound].Modi := StandardModus - end; - end; - end; - - // FIXME: return a valid result - Result := 0; end; //---------- -// CallModiDeInit - calls DeInitProc and ends the round +//EndRound - Get Winner from ScreenSingModi and Save Data to RoundArray //---------- -function TPartySession.CallModiDeInit(wParam: TwParam; lParam: TlParam): integer; +procedure TPartySession.EndRound; var - I: integer; - MaxScore: word; + I: Integer; begin - if (bPartyMode) then - begin - //Get Winner Byte! - if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then //get winners from plugin - Rounds[CurRound].Winner := Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID) - else - begin //Create winners by score :/ - Rounds[CurRound].Winner := 0; - MaxScore := 0; - for I := 0 to Teams.NumTeams-1 do - begin - // to-do : recode percentage stuff - //PlayerInfo.Playerinfo[I].Percentage := PlayerInfo.Playerinfo[I].Score div 9999; - if (Player[I].ScoreTotalInt > MaxScore) then - begin - MaxScore := Player[I].ScoreTotalInt; - Rounds[CurRound].Winner := 1 shl I; - end - else if (Player[I].ScoreTotalInt = MaxScore) and (Player[I].ScoreTotalInt <> 0) then - begin - Rounds[CurRound].Winner := Rounds[CurRound].Winner or (1 shl I); - end; - end; - + //Copy Winner + Rounds[CurRound].Winner := ScreenSingModi.Winner; + //Set Scores + GenScores; - //When nobody has points -> everybody looses - if (MaxScore = 0) then - Rounds[CurRound].Winner := 0; + //Increase TimesPlayed 4 all Players + For I := 0 to Teams.NumTeams-1 do + Inc(Teams.Teaminfo[I].Playerinfo[Teams.Teaminfo[I].CurPlayer].TimesPlayed); - end; - - //Generate the scores - GenScores; - - //Inc players TimesPlayed - if ((Modis[Rounds[CurRound-1].Modi].Info.LoadingSettings and MLS_IncTP) = MLS_IncTP) then - begin - for I := 0 to Teams.NumTeams-1 do - Inc(Teams.TeamInfo[I].Playerinfo[Teams.TeamInfo[I].CurPlayer].TimesPlayed); - end; - end - else if (@Modis[Rounds[CurRound].Modi].Info.ModiDeInit <> nil) then - Modis[Rounds[CurRound].Modi].Info.ModiDeInit(Modis[Rounds[CurRound].Modi].Info.ID); - - // FIXME: return a valid result - Result := 0; end; //---------- -// GetTeamInfo - writes TTeamInfo record to pointer at lParam. Returns zero on success +//IsWinner - returns true if the player's bit is set in the winner byte //---------- -function TPartySession.GetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; +function TPartySession.IsWinner(Player, Winner: byte): boolean; var - Info: ^TTeamInfo; + Mask: byte; begin - Result := -1; - Info := pTeamInfo; - if (Info <> nil) then - begin - try - // to - do : Check Delphi memory management in this case - //Not sure if i had to copy PChars to a new address or if delphi manages this o0 - Info^ := Teams; - Result := 0; - except - Result := -2; - end; - end; + Mask := 1 shl Player; + Result := (Winner and Mask) <> 0; end; //---------- -// SetTeamInfo - read TTeamInfo record from pointer at lParam. Returns zero on success +//GenScores - increase scores for current round //---------- -function TPartySession.SetTeamInfo(wParam: TwParam; pTeamInfo: TlParam): integer; +procedure TPartySession.GenScores; var - TeamInfobackup: TTeamInfo; - Info: ^TTeamInfo; + I: byte; begin - Result := -1; - Info := pTeamInfo; - if (Info <> nil) then + for I := 0 to Teams.NumTeams-1 do begin - try - TeamInfoBackup := Teams; - // to - do : Check Delphi memory management in this case - //Not sure if i had to copy PChars to a new address or if delphi manages this o0 - Teams := Info^; - Result := 0; - except - Teams := TeamInfoBackup; - Result := -2; - end; + if isWinner(I, Rounds[CurRound].Winner) then + Inc(Teams.Teaminfo[I].Score); end; end; //---------- -// GetTeamOrder - returns team order. Structure: Bits 1..3: Team at place1; Bits 4..6: Team at place2 ... +//GetTeamOrder - returns the placement of each Team [First Position of Array is Teamnum of first placed Team, ...] //---------- -function TPartySession.GetTeamOrder(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.GetTeamOrder: TeamOrderArray; var I, J: integer; ATeams: array [0..5] of TeamOrderEntry; TempTeam: TeamOrderEntry; begin - // to-do : PartyMode: Write this in another way, so that teams with the same score get the same place + // TODO: PartyMode: Write this in another way, so that teams with the same score get the same place //Fill Team array for I := 0 to Teams.NumTeams-1 do begin @@ -603,63 +340,44 @@ begin end; //Copy to Result - Result := 0; for I := 0 to Teams.NumTeams-1 do - Result := Result or (ATeams[I].TeamNum Shl I*3); + Result[I] := ATeams[I].TeamNum; end; //---------- -// GetWinnerString - wParam is Roundnum. If (pointer = nil) then return length of the string. Otherwise write the string to address at lParam +//GetWinnerString - Get String with WinnerTeam Name, when there is more than one Winner than Connect with and or , //---------- -function TPartySession.GetWinnerString(wParam: TwParam; lParam: TlParam): integer; +function TPartySession.GetWinnerString(Round: byte): string; var - Winners: array of String; + Winners: array of string; I: integer; - ResultStr: String; - S: ^String; begin - ResultStr := Language.Translate('PARTY_NOBODY'); + Result := Language.Translate('PARTY_NOBODY'); + + if (Round > High(Rounds)) then + exit; - if (wParam <= High(Rounds)) then + if (Rounds[Round].Winner = 0) then begin - if (Rounds[wParam].Winner <> 0) then - begin - if (Rounds[wParam].Winner = 255) then - begin - ResultStr := Language.Translate('PARTY_NOTPLAYEDYET'); - end - else - begin - SetLength(Winners, 0); - for I := 0 to Teams.NumTeams-1 do - begin - if isWinner(I, Rounds[wParam].Winner) then - begin - SetLength(Winners, Length(Winners) + 1); - Winners[high(Winners)] := Teams.TeamInfo[I].Name; - end; - end; - ResultStr := Language.Implode(Winners); - end; - end; + exit; end; - //Now return what we have got - if (lParam = nil) then - begin //Return string length - Result := Length(ResultStr); - end - else - begin //Return string - try - S := lParam; - S^ := ResultStr; - Result := 0; - except - Result := -1; + 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; end. -- cgit v1.2.3 From b551fcdcdd11c178e224caf5c2c3c33c7a2cf4ad Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Sun, 26 Apr 2009 16:07:50 +0000 Subject: Cosmetics git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1700 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 74 ++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 9d70e2be..e29b977c 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -44,34 +44,34 @@ type TeamOrderEntry = record TeamNum: byte; - Score: byte; + Score: byte; end; TeamOrderArray = array[0..5] of byte; TPartyPlugin = record - ID: byte; + ID: byte; TimesPlayed: byte; end; TPartySession = class private - function GetRandomPlayer(Team: Byte): Byte; + function GetRandomPlayer(Team: byte): byte; function GetRandomPlugin(Plugins: array of TPartyPlugin): byte; - function IsWinner(Player, Winner: Byte): boolean; + function IsWinner(Player, Winner: byte): boolean; procedure GenScores; public - Teams: TTeamInfo; - Rounds: array of TRoundInfo; - CurRound: Byte; + Teams: TTeamInfo; + Rounds: array of TRoundInfo; + CurRound: byte; constructor Create; - procedure StartNewParty(NumRounds: Byte); + procedure StartNewParty(NumRounds: byte); procedure StartRound; procedure EndRound; function GetTeamOrder: TeamOrderArray; - function GetWinnerString(Round: Byte): String; + function GetWinnerString(Round: byte): string; end; var @@ -96,10 +96,10 @@ end; //---------- function TPartySession.GetRandomPlugin(Plugins: array of TPartyPlugin): byte; var - LowestTP: byte; + LowestTP: byte; NumPwithLTP: word; - I: integer; - R: word; + I: integer; + R: word; begin LowestTP := high(byte); NumPwithLTP := 0; @@ -141,12 +141,12 @@ end; //---------- //StartNewParty - Reset and prepares for new party //---------- -procedure TPartySession.StartNewParty(NumRounds: Byte); +procedure TPartySession.StartNewParty(NumRounds: byte); var - Plugins: array of TPartyPlugin; + Plugins: array of TPartyPlugin; TeamMode: boolean; - Len: integer; - I, J: integer; + Len: integer; + I, J: integer; begin //Set current round to 1 CurRound := 255; @@ -155,7 +155,7 @@ begin //Get team-mode and set joker, also set TimesPlayed TeamMode := true; - for I := 0 to Teams.NumTeams-1 do + for I := 0 to Teams.NumTeams - 1 do begin if Teams.Teaminfo[I].NumPlayers < 2 then begin @@ -166,7 +166,7 @@ begin begin Teams.TeamInfo[I].Playerinfo[J].TimesPlayed := 0; end; - Teams.Teaminfo[I].Joker := Round(NumRounds*0.7); + Teams.Teaminfo[I].Joker := Round(NumRounds * 0.7); Teams.Teaminfo[I].Score := 0; end; @@ -174,7 +174,7 @@ begin SetLength(Plugins, 0); for I := 0 to high(DLLMan.Plugins) do begin - if TeamMode or (not DLLMan.Plugins[I].TeamModeOnly) then + if TeamMode or (not DLLMan.Plugins[I].TeamModeOnly) then begin //Add only those plugins playable with current PlayerConfiguration Len := Length(Plugins); @@ -188,7 +188,7 @@ begin if (Length(Plugins) >= 1) then begin SetLength (Rounds, NumRounds); - for I := 0 to NumRounds-1 do + for I := 0 to NumRounds - 1 do begin PartySession.Rounds[I].Plugin := GetRandomPlugin(Plugins); PartySession.Rounds[I].Winner := 255; @@ -203,16 +203,16 @@ end; *} function TPartySession.GetRandomPlayer(Team: byte): byte; var - I, R: integer; - LowestTP: byte; + I, R: integer; + LowestTP: byte; NumPwithLTP: byte; begin - LowestTP := high(byte); + LowestTP := high(byte); NumPwithLTP := 0; - Result := 0; + Result := 0; //Search for players that have not often played yet - for I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do + for I := 0 to Teams.Teaminfo[Team].NumPlayers - 1 do begin if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then begin @@ -229,7 +229,7 @@ begin R := Random(NumPwithLTP); //Search for random player - for I := 0 to Teams.Teaminfo[Team].NumPlayers-1 do + for I := 0 to Teams.Teaminfo[Team].NumPlayers - 1 do begin if Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP then begin @@ -252,7 +252,7 @@ procedure TPartySession.StartRound; var I: integer; begin - if ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then + if ((CurRound < high(Rounds)) or (CurRound = high(CurRound))) then begin //Increase Current Round Inc(CurRound); @@ -261,7 +261,7 @@ begin DllMan.LoadPlugin(Rounds[CurRound].Plugin); //Select Players - for I := 0 to Teams.NumTeams-1 do + for I := 0 to Teams.NumTeams - 1 do Teams.Teaminfo[I].CurPlayer := GetRandomPlayer(I); //Set ScreenSingModie Variables @@ -305,7 +305,7 @@ procedure TPartySession.GenScores; var I: byte; begin - for I := 0 to Teams.NumTeams-1 do + for I := 0 to Teams.NumTeams - 1 do begin if isWinner(I, Rounds[CurRound].Winner) then Inc(Teams.Teaminfo[I].Score); @@ -317,21 +317,21 @@ end; //---------- function TPartySession.GetTeamOrder: TeamOrderArray; var - I, J: integer; - ATeams: array [0..5] of TeamOrderEntry; + I, J: integer; + ATeams: array [0..5] of TeamOrderEntry; TempTeam: TeamOrderEntry; begin // TODO: PartyMode: Write this in another way, so that teams with the same score get the same place //Fill Team array - for I := 0 to Teams.NumTeams-1 do + 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 + 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]; @@ -345,12 +345,12 @@ begin end; //---------- -//GetWinnerString - Get String with WinnerTeam Name, when there is more than one Winner than Connect with and or , +//GetWinnerString - Get string with WinnerTeam Name, when there is more than one Winner than Connect with and or , //---------- function TPartySession.GetWinnerString(Round: byte): string; var Winners: array of string; - I: integer; + I: integer; begin Result := Language.Translate('PARTY_NOBODY'); @@ -369,7 +369,7 @@ begin end; SetLength(Winners, 0); - for I := 0 to Teams.NumTeams-1 do + for I := 0 to Teams.NumTeams - 1 do begin if isWinner(I, Rounds[Round].Winner) then begin -- cgit v1.2.3 From 384aa7c5adbaec638277e9caf0840dad77540b58 Mon Sep 17 00:00:00 2001 From: k-m_schindler Date: Sun, 19 Jul 2009 17:06:29 +0000 Subject: Do not use range overflow for CurRound. Could probably be done nicer. git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1853 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index e29b977c..615418f1 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -254,8 +254,13 @@ var begin if ((CurRound < high(Rounds)) or (CurRound = high(CurRound))) then begin - //Increase Current Round - Inc(CurRound); + // Increase Current Round but not beyond its limit + // CurRound is set to 255 to begin with! + // Ugly solution if you ask me. + if CurRound < high(CurRound) then + Inc(CurRound) + else + CurRound := 0; Rounds[CurRound].Winner := 255; DllMan.LoadPlugin(Rounds[CurRound].Plugin); -- cgit v1.2.3 From 917901e8e33438c425aef50a0a7417f32d77b760 Mon Sep 17 00:00:00 2001 From: s_alexander Date: Mon, 9 Nov 2009 00:27:55 +0000 Subject: merged unicode branch (r1931) into trunk git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1939 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 615418f1..52eb5a05 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -71,7 +71,7 @@ type procedure StartRound; procedure EndRound; function GetTeamOrder: TeamOrderArray; - function GetWinnerString(Round: byte): string; + function GetWinnerString(Round: byte): UTF8String; end; var @@ -352,9 +352,9 @@ end; //---------- //GetWinnerString - Get string with WinnerTeam Name, when there is more than one Winner than Connect with and or , //---------- -function TPartySession.GetWinnerString(Round: byte): string; +function TPartySession.GetWinnerString(Round: byte): UTF8String; var - Winners: array of string; + Winners: array of UTF8String; I: integer; begin Result := Language.Translate('PARTY_NOBODY'); -- cgit v1.2.3 From 4711217f127aa0c10fa52755fd567c570277a1a1 Mon Sep 17 00:00:00 2001 From: s_alexander Date: Tue, 12 Jan 2010 17:42:41 +0000 Subject: merged lua into trunk git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2071 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 1021 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 802 insertions(+), 219 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 52eb5a05..94580241 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -34,355 +34,938 @@ interface {$I switches.inc} uses - ModiSDK; + ULua; type - TRoundInfo = record - Plugin: word; - Winner: byte; + { array holds ids of modes or Party_Round_Random + its length defines the number of rounds + it is used as argument for TPartyGame.StartParty } + ARounds = array of integer; + + { element of APartyTeamRanking returned by TPartyGame.GetTeamRanking + and parameter for TPartyGame.SetWinner } + TParty_TeamRanking = record + Team: Integer; //< id of team + Rank: Integer; //< 1 to Length(Teams) e.g. 1 is for placed first end; + AParty_TeamRanking = array of TParty_TeamRanking; //< returned by TPartyGame.GetTeamRanking - TeamOrderEntry = record - TeamNum: byte; - Score: byte; + TParty_RoundList = record + Index: integer; + Name: UTF8String; end; + AParty_ModeList = array of TParty_RoundList; + + { record used by TPartyGame to store round specific data } + TParty_Round = record + Mode: Integer; + AlreadyPlayed: Boolean; //< true if round was already played + Ranking: AParty_TeamRanking; + RankingSet: Boolean; //< true if Self.Ranking is already set + end; + + TParty_ModeInfo = record + Name: String; // name of this mode + Parent: Integer; // Id of owning plugin + + CanNonParty: Boolean; //< is playable when not in party mode + CanParty: Boolean; //< is playable in party mode + + // one bit in the following settings stands for + // a player or team count + // PlayerCount = 2 or 4 indicates that the mode is playable with 2 and 3 players per team + // TeamCount = 1 or 2 or 4 or 8 or 16 or 32 indicates that the mode is playable with 1 to 6 teams + PlayerCount: Integer; //< playable with one, two, three etc. players per team + TeamCount: Integer; //< playable with one, two, three etc. different teams + + + Functions: record // lua functions that will be called at specific events + BeforeSongSelect: String; // default actions are executed if functions = nil + AfterSongSelect: String; + + BeforeSing: String; + OnSing: String; + AfterSing: String; + end; + end; + + { used by TPartyGame to store player specific data } + TParty_PlayerInfo = record + Name: String; //< Playername + TimesPlayed: Integer; //< How often this Player has Sung + end; + + { used by TPartyGame to store team specific data } + TParty_TeamInfo = record + Name: String; //< name of the Team + Score: Word; //< current score + JokersLeft: Integer; //< jokers this team has left - TeamOrderArray = array[0..5] of byte; + NextPlayer: Integer; //Id of the player that plays the next (the current) song - TPartyPlugin = record - ID: byte; - TimesPlayed: byte; + Players: array of TParty_PlayerInfo; end; - TPartySession = class + TPartyGame = class private - function GetRandomPlayer(Team: byte): byte; - function GetRandomPlugin(Plugins: array of TPartyPlugin): byte; - function IsWinner(Player, Winner: byte): boolean; + bPartyGame: boolean; //< are we playing party or standard mode + CurRound: Integer; //< indicates which of the elements of Rounds is played next (at the moment) + + bPartyStarted: Boolean; + + TimesPlayed: array of Integer; //< times every mode was played in current party game (for random mode calculation) + procedure GenScores; + function GetRandomMode: integer; + function GetRandomPlayer(Team: integer): integer; + + { returns true if a mode is playable with current playerconfig } + function ModePlayable(I: integer): boolean; + + function CallLua(Parent: Integer; Func: String):Boolean; + + procedure SetRankingByScore; public - Teams: TTeamInfo; - Rounds: array of TRoundInfo; - CurRound: byte; + //Teams: TTeamInfo; + Rounds: array of TParty_Round; //< holds info which modes are played in this party game (if started) + Teams: array of TParty_TeamInfo; //< holds info of teams playing in current round (private for easy manipulation of lua functions) + + Modes: array of TParty_ModeInfo; //< holds info of registred party modes + + property CurrentRound: Integer read CurRound; constructor Create; - procedure StartNewParty(NumRounds: byte); - procedure StartRound; - procedure EndRound; - function GetTeamOrder: TeamOrderArray; - function GetWinnerString(Round: byte): UTF8String; + { set the attributes of Info to default values } + procedure DefaultModeInfo(var Info: TParty_ModeInfo); + + { registers a new mode, returns true on success + (mode name does not already exist) } + function RegisterMode(Info: TParty_ModeInfo): Boolean; + + { returns true if modes are available for + players and teams that are currently set + up. if there are no teams set up it returns + if there are any party modes available } + function ModesAvailable: Boolean; + + { returns an array with the name of all available modes (that + are playable with current player configuration } + function GetAvailableModes: AParty_ModeList; + + { clears all party specific data previously stored } + procedure Clear; + + { adds a team to the team array, returning its id + can only be called when game is not already started } + function AddTeam(Name: String): Integer; + + { adds a player to the player array, returning its id + can only be called when game is not already started } + function AddPlayer(Team: Integer; Name: String): Integer; + + { starts a new PartyGame, returns true on success + before a call of this function teams and players + has to be added by AddTeam and AddPlayer } + + function StartGame(Rounds: ARounds): Boolean; + + { sets the winner(s) of current round + returns true on success } + function SetRanking(Ranking: AParty_TeamRanking): Boolean; + + { increases round counter by 1 and clears all round specific information; + returns the number of the current round or -1 if last round has already + been played } + function NextRound: integer; + + { indicates that current round has already been played } + procedure RoundPlayed; + + { true if in a Party Game (not in standard mode) } + property PartyGame: Boolean read BPartyGame; + + + { returns true if last round was already played } + function GameFinished: Boolean; + + { call plugins defined function and/or default procedure + only default procedure is called when no function is defined by plugin + if plugins function returns true then default is called after plugins + function was executed} + procedure CallBeforeSongSelect; + procedure CallAfterSongSelect; + procedure CallBeforeSing; + procedure CallOnSing; + procedure CallAfterSing; + + { returns an array[1..6] of TParty_TeamRanking. + the index stands for the placing, + team is the team number (in the team array) + rank is correct rank if some teams have the + same score. + } + function GetTeamRanking: AParty_TeamRanking; + + { returns a string like "Team 1 (and Team 2) win" } + function GetWinnerString(Round: integer): UTF8String; + + destructor Destroy; end; +const + { minimal amount of teams for party mode } + Party_Teams_Min = 2; + + { maximal amount of teams for party mode } + Party_Teams_Max = 3; + + { minimal amount of players for party mode } + Party_Players_Min = 1; + + { maximal amount of players for party mode } + Party_Players_Max = 4; + + { amount of jokers each team gets at the beginning of the game } + Party_Count_Jokers = 5; + + { to indicate that element (mode) should set randomly in ARounds array } + Party_Round_Random = -1; + + { values for TParty_TeamRanking.Rank } + PR_First = 1; + PR_Second = 2; + PR_Third = 3; + + StandardModus = 0; //Modus Id that will be played in non-party mode + var - PartySession: TPartySession; + Party: TPartyGame; implementation uses - UDLLManager, UGraphic, - UNote, ULanguage, - ULog; + ULog, + ULuaCore, + UDisplay, + USong, + UNote, + SysUtils; -constructor TPartySession.Create; +//------------- +// Just the constructor +//------------- +constructor TPartyGame.Create; begin inherited; + + Clear; end; -//---------- -// Returns a number of a random plugin -//---------- -function TPartySession.GetRandomPlugin(Plugins: array of TPartyPlugin): byte; +destructor TPartyGame.Destroy; +begin + inherited; +end; + +{ clears all party specific data previously stored } +procedure TPartyGame.Clear; + var + I: Integer; +begin + bPartyGame := false; // no party game + CurRound := low(integer); + + bPartyStarted := false; //game not startet + + SetLength(Teams, 0); //remove team info + SetLength(Rounds, 0); //remove round info + + // clear times played + for I := 0 to High(TimesPlayed) do + TimesPlayed[I] := 0; +end; + +{ private: some intelligent randomnes for plugins } +function TPartyGame.GetRandomMode: integer; +var + LowestTP: integer; + NumPwithLTP: integer; + I: integer; + R: integer; +begin + Result := 0; //If there are no matching modes, play first modus + LowestTP := high(Integer); + NumPwithLTP := 0; + + // search for the plugins less played yet + for I := 0 to high(Modes) do + begin + if (ModePlayable(I)) then + begin + if (TimesPlayed[I] < lowestTP) then + begin + lowestTP := TimesPlayed[I]; + NumPwithLTP := 1; + end + else if (TimesPlayed[I] = lowestTP) then + begin + Inc(NumPwithLTP); + end; + end; + end; + + // create random number + R := Random(NumPwithLTP); + + // select the random mode from the modes with less timesplayed + for I := 0 to high(Modes) do + begin + if (TimesPlayed[I] = lowestTP) and (ModePlayable(I)) then + begin + //Plugin found + if (R = 0) then + begin + Result := I; + Inc(TimesPlayed[I]); + Break; + end; + + Dec(R); + end; + end; +end; + +{ private: GetRandomPlayer - returns a random player + that does not play to often ;) } +function TPartyGame.GetRandomPlayer(Team: integer): integer; var - LowestTP: byte; - NumPwithLTP: word; - I: integer; - R: word; + I, R: integer; + lowestTP: Integer; + NumPwithLTP: Integer; begin - LowestTP := high(byte); + LowestTP := high(Integer); NumPwithLTP := 0; + Result := 0; - //Search for Plugins not often played yet - for I := 0 to high(Plugins) do + // search for players that have less played yet + for I := 0 to High(Teams[Team].Players) do begin - if (Plugins[I].TimesPlayed < lowestTP) then + if (Teams[Team].Players[I].TimesPlayed < lowestTP) then begin - lowestTP := Plugins[I].TimesPlayed; + lowestTP := Teams[Team].Players[I].TimesPlayed; NumPwithLTP := 1; end - else if (Plugins[I].TimesPlayed = lowestTP) then + else if (Teams[Team].Players[I].TimesPlayed = lowestTP) then begin Inc(NumPwithLTP); end; end; - //Create random no + // create random number R := Random(NumPwithLTP); - //Search for random plugin - for I := 0 to high(Plugins) do + // search for selected random player + for I := 0 to High(Teams[Team].Players) do begin - if Plugins[I].TimesPlayed = LowestTP then + if Teams[Team].Players[I].TimesPlayed = lowestTP then begin - //Plugin found if (R = 0) then - begin - Result := Plugins[I].ID; - Inc(Plugins[I].TimesPlayed); + begin // found selected player + Result := I; Break; end; + Dec(R); end; end; end; //---------- -//StartNewParty - Reset and prepares for new party +//GenScores - inc scores for cur. round //---------- -procedure TPartySession.StartNewParty(NumRounds: byte); +procedure TPartyGame.GenScores; var - Plugins: array of TPartyPlugin; - TeamMode: boolean; - Len: integer; - I, J: integer; + I: Integer; +begin + if (Length(Teams) = 2) then + begin // score generation for 2 teams, winner gets 1 point + for I := 0 to High(Rounds[CurRound].Ranking) do + if (Rounds[CurRound].Ranking[I].Rank = PR_First) then + Inc(Teams[Rounds[CurRound].Ranking[I].Team].Score); + end + else if (Length(Teams) = 3) then + begin // score generation for 3 teams, + // winner gets 3 points 2nd gets 1 point + for I := 0 to High(Rounds[CurRound].Ranking) do + if (Rounds[CurRound].Ranking[I].Rank = PR_First) then + Inc(Teams[Rounds[CurRound].Ranking[I].Team].Score, 3) + else if (Rounds[CurRound].Ranking[I].Rank = PR_Second) then + Inc(Teams[Rounds[CurRound].Ranking[I].Team].Score); + end +end; + +{ set the attributes of Info to default values } +procedure TPartyGame.DefaultModeInfo(var Info: TParty_ModeInfo); begin - //Set current round to 1 - CurRound := 255; + Info.Name := 'undefined'; + Info.Parent := -1; //< not loaded by plugin (e.g. Duell) + Info.CanNonParty := false; + Info.CanParty := false; + Info.PlayerCount := High(Integer); //< no restrictions either on player count + Info.TeamCount := High(Integer); //< nor on team count + Info.Functions.BeforeSongSelect := ''; //< use default functions + Info.Functions.AfterSongSelect := ''; + Info.Functions.BeforeSing := ''; + Info.Functions.OnSing := ''; + Info.Functions.AfterSing := ''; +end; - PlayersPlay := Teams.NumTeams; +{ registers a new mode, returns true on success + (mode name does not already exist) } +function TPartyGame.RegisterMode(Info: TParty_ModeInfo): Boolean; + var + Len: integer; + LowerName: String; + I: integer; +begin + Result := false; - //Get team-mode and set joker, also set TimesPlayed - TeamMode := true; - for I := 0 to Teams.NumTeams - 1 do + if (Info.Name <> 'undefined') then begin - if Teams.Teaminfo[I].NumPlayers < 2 then + // search for a plugin w/ same name + LowerName := lowercase(Info.Name); // case sensitive search + for I := 0 to high(Modes) do + if (LowerName = lowercase(Modes[I].Name)) then + exit; //< no success (name already exist) + + // add new mode to array and append and clear a new TimesPlayed element + Len := Length(Modes); + SetLength(Modes, Len + 1); + SetLength(TimesPlayed, Len + 1); + + Modes[Len] := Info; + TimesPlayed[Len] := 0; + + Result := True; + end; +end; + +{ returns true if a mode is playable with current playerconfig } +function TPartyGame.ModePlayable(I: integer): boolean; + var + J: integer; +begin + if (Length(Teams) = 0) then + Result := true + else + begin + if (Modes[I].TeamCount and (1 shl (Length(Teams) - 1)) <> 0) then begin - TeamMode := false; + Result := true; + + for J := 0 to High(Teams) do + Result := Result and (Modes[I].PlayerCount and (1 shl (Length(Teams[J].Players) - 1)) <> 0); + end + else + Result := false; + end; +end; + +{ returns true if modes are available for + players and teams that are currently set + up. if there are no teams set up it returns + if there are any party modes available } +function TPartyGame.ModesAvailable: Boolean; + var + I: integer; + CountTeams: integer; +begin + CountTeams := Length(Teams); + if CountTeams = 0 then + begin + Result := (Length(Modes) > 0); + end + else + begin + Result := false; + for I := 0 to High(Modes) do + begin + Result := ModePlayable(I); + + if Result then + Exit; end; - //Set player attributes - for J := 0 to Teams.TeamInfo[I].NumPlayers-1 do + end; +end; + +{ returns an array with the name of all available modes (that + are playable with current player configuration } +function TPartyGame.GetAvailableModes: AParty_ModeList; + var + I: integer; + Len: integer; +begin + Len := 0; + SetLength(Result, Len + 1); + Result[Len].Index := Party_Round_Random; + Result[Len].Name := Language.Translate('MODE_RANDOM_NAME'); + + for I := 0 to High(Modes) do + if (ModePlayable(I)) then begin - Teams.TeamInfo[I].Playerinfo[J].TimesPlayed := 0; + Inc(Len); + SetLength(Result, Len + 1); + Result[Len].Index := I; + Result[Len].Name := Language.Translate('MODE_' + Uppercase(Modes[I].Name) + '_NAME'); end; - Teams.Teaminfo[I].Joker := Round(NumRounds * 0.7); - Teams.Teaminfo[I].Score := 0; +end; + +{ adds a team to the team array, returning its id + can only be called when game is not already started } +function TPartyGame.AddTeam(Name: String): Integer; +begin + Result := -1; + if (not bPartyStarted) and (Length(Name) > 0) and (Length(Teams) < Party_Teams_Max) then + begin + Result := Length(Teams); + SetLength(Teams, Result + 1); + + Teams[Result].Name := Name; + Teams[Result].Score := 0; + Teams[Result].JokersLeft := Party_Count_Jokers; + Teams[Result].NextPlayer := -1; end; +end; + +{ adds a player to the player array, returning its id + can only be called when game is not already started } +function TPartyGame.AddPlayer(Team: Integer; Name: String): Integer; +begin + Result := -1; - //Fill plugin array - SetLength(Plugins, 0); - for I := 0 to high(DLLMan.Plugins) do + if (not bPartyStarted) and (Team >= 0) and (Team <= High(Teams)) and (Length(Teams[Team].Players) < Party_Players_Max) and (Length(Name) > 0) then begin - if TeamMode or (not DLLMan.Plugins[I].TeamModeOnly) then - begin - //Add only those plugins playable with current PlayerConfiguration - Len := Length(Plugins); - SetLength(Plugins, Len + 1); - Plugins[Len].ID := I; - Plugins[Len].TimesPlayed := 0; - end; + // append element to players array + Result := Length(Teams[Team].Players); + SetLength(Teams[Team].Players, Result + 1); + + // fill w/ data + Teams[Team].Players[Result].Name := Name; + Teams[Team].Players[Result].TimesPlayed := 0; end; +end; + +{ starts a new PartyGame, returns true on success + before a call of this function teams and players + has to be added by AddTeam and AddPlayer } +function TPartyGame.StartGame(Rounds: ARounds): Boolean; + var + I: integer; +begin + Result := false; - //Set rounds - if (Length(Plugins) >= 1) then + if (not bPartyStarted) and (Length(Rounds) > 0) and (Length(Teams) >= Party_Teams_Min) then begin - SetLength (Rounds, NumRounds); - for I := 0 to NumRounds - 1 do + // check teams for minimal player count + for I := 0 to High(Teams) do + if (Length(Teams[I].Players) < Party_Players_Min) then + exit; + + // create rounds array + SetLength(Self.Rounds, Length(Rounds)); + + for I := 0 to High(Rounds) do begin - PartySession.Rounds[I].Plugin := GetRandomPlugin(Plugins); - PartySession.Rounds[I].Winner := 255; + // copy round or select a random round + if (Rounds[I] <> Party_Round_Random) and (Rounds[I] >= 0) and (Rounds[I] <= High(Modes)) then + Self.Rounds[I].Mode := Rounds[I] + else + Self.Rounds[I].Mode := GetRandomMode; + + Self.Rounds[I].AlreadyPlayed := false; + Self.Rounds[I].RankingSet := false; + + SetLength(Self.Rounds[I].Ranking, 0); end; + + // get the party started!11 + bPartyStarted := true; + bPartyGame := true; + CurRound := low(integer); //< set not to -1 to indicate that party game is not finished + + // first round + NextRound; + + Result := True; + end; +end; + +{ sets the winner(s) of current round + returns true on success } +function TPartyGame.SetRanking(Ranking: AParty_TeamRanking): Boolean; + var + I, J: Integer; + TeamExists: Integer; + Len: Integer; + Temp: TParty_TeamRanking; +begin + if (bPartyStarted) and (CurRound >= 0) and (CurRound <= High(Rounds)) then + begin + Rounds[CurRound].Ranking := Ranking; + Result := true; + + // look for teams that don't exist + TeamExists := 0; + for I := 0 to High(Rounds[CurRound].Ranking) do + TeamExists := TeamExists or (1 shl (Rounds[CurRound].Ranking[I].Team-1)); + + // create teams that don't exist + Len := Length(Rounds[CurRound].Ranking); + for I := 0 to High(Teams) do + if (TeamExists and (1 shl I) = 0) then + begin + Inc(Len); + SetLength(Rounds[CurRound].Ranking, Len); + Rounds[CurRound].Ranking[Len-1].Team := I + 1; + Rounds[CurRound].Ranking[Len-1].Rank := Length(Teams); + end; + + // we may remove rankings from invalid teams here to + // but at the moment this is not necessary, because the + // functions this function is called from don't create + // invalid rankings + + // bubble sort rankings by team + J := High(Rounds[CurRound].Ranking); + repeat + for I := 0 to J - 1 do + if (Rounds[CurRound].Ranking[I].Team > Rounds[CurRound].Ranking[I+1].Team) then + begin + Temp := Rounds[CurRound].Ranking[I]; + Rounds[CurRound].Ranking[I] := Rounds[CurRound].Ranking[I+1]; + Rounds[CurRound].Ranking[I+1] := Temp; + end; + Dec(J); + until J <= 0; + + //set rounds RankingSet to true + Rounds[CurRound].RankingSet := true; end else - SetLength (Rounds, 0); + Result := false; end; -{** - * Returns a random player to play next round - *} -function TPartySession.GetRandomPlayer(Team: byte): byte; -var - I, R: integer; - LowestTP: byte; - NumPwithLTP: byte; +{ sets ranking of current round by score saved in players array } +procedure TPartyGame.SetRankingByScore; + var + I, J: Integer; + Rank: Integer; + Ranking: AParty_TeamRanking; + Scores: array of Integer; + TmpRanking: TParty_TeamRanking; + TmpScore: Integer; 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 + if (Length(Player) = Length(Teams)) then begin - if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then + SetLength(Ranking, Length(Teams)); + SetLength(Scores, Length(Teams)); + + // fill ranking array + for I := 0 to High(Ranking) do begin - lowestTP := Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed; - NumPwithLTP := 1; - end - else if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP) then + Ranking[I].Team := I; + Ranking[I].Rank := 0; + Scores[I] := Player[I].ScoreTotalInt; + end; + + // bubble sort by score + J := High(Ranking); + repeat + for I := 0 to J - 1 do + if (Scores[I] < Scores[I+1]) then + begin + TmpRanking := Ranking[I]; + Ranking[I] := Ranking[I+1]; + Ranking[I+1] := TmpRanking; + + TmpScore := Scores[I]; + Scores[I] := Scores[I+1]; + Scores[I+1] := TmpScore; + end; + Dec(J); + until J <= 0; + + // set rank field + Rank := 1; //first rank has id 1 + for I := 0 to High(Ranking) do begin - Inc(NumPwithLTP); + Ranking[I].Rank := Rank; + + if (I < High(Ranking)) and (Scores[I] <> Scores[I+1]) then + Inc(Rank); // next rank if next team has different score end; + end + else + SetLength(Ranking, 0); + + SetRanking(Ranking); +end; + +{ increases round counter by 1 and clears all round specific information; + returns the number of the current round or -1 if last round has already + been played } +function TPartyGame.NextRound: integer; + var I: Integer; +begin + // some lines concerning the previous round + if (CurRound >= 0) then + begin + Rounds[CurRound].AlreadyPlayed := true; + + GenScores; end; - //Create random number - R := Random(NumPwithLTP); + // increase round counter + Inc(CurRound); + if (CurRound < -1) then // we start first round + CurRound := 0; - //Search for random player - for I := 0 to Teams.Teaminfo[Team].NumPlayers - 1 do + if (CurRound > High(Rounds)) then + CurRound := -1; //< last round played + + Result := CurRound; + + // some lines concerning the next round + if (CurRound >= 0) then 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; + // select player + for I := 0 to High(Teams) do + Teams[I].NextPlayer := GetRandomPlayer(I); end; end; -{** - * Prepares ScreenSingModi for next round and loads plugin - *} -procedure TPartySession.StartRound; -var - I: integer; +{ indicates that current round has already been played } +procedure TPartyGame.RoundPlayed; begin - if ((CurRound < high(Rounds)) or (CurRound = high(CurRound))) then + if (bPartyStarted) and (CurRound >= 0) and (CurRound <= High(Rounds)) then begin - // Increase Current Round but not beyond its limit - // CurRound is set to 255 to begin with! - // Ugly solution if you ask me. - if CurRound < high(CurRound) then - Inc(CurRound) - else - CurRound := 0; + // set rounds ranking by score if it was not set by plugin + if (not Rounds[CurRound].RankingSet) then + SetRankingByScore; + + Rounds[CurRound].AlreadyPlayed := True; + end; +end; + +{ returns true if last round was already played } +function TPartyGame.GameFinished: Boolean; +begin + Result := (bPartyStarted and (CurRound = -1)); +end; - Rounds[CurRound].Winner := 255; - DllMan.LoadPlugin(Rounds[CurRound].Plugin); +{ private: calls the specified function Func from lua plugin Parent + if both exist. + return true if default function should be called + (function or plugin does not exist, or function returns + true) } +function TPartyGame.CallLua(Parent: Integer; Func: String):Boolean; + var + P: TLuaPlugin; +begin + // call default function by default + Result := true; - //Select Players - for I := 0 to Teams.NumTeams - 1 do - Teams.Teaminfo[I].CurPlayer := GetRandomPlayer(I); + // check for core plugin and empty function name + if (Parent >= 0) and (Length(Func) > 0) then + begin + // get plugin that registred the mode + P := LuaCore.GetPluginById(Parent); - //Set ScreenSingModie Variables - ScreenSingModi.TeamInfo := Teams; + if (P <> nil) then + begin + if (P.CallFunctionByName(Func, 0, 1)) then + // check result + Result := (lua_toboolean(P.LuaState, 1)); + end; end; end; -//---------- -//EndRound - Get Winner from ScreenSingModi and Save Data to RoundArray -//---------- -procedure TPartySession.EndRound; -var - I: Integer; +{ call plugins defined function and/or default procedure + only default procedure is called when no function is defined by plugin + if plugins function returns true then default is called after plugins + function was executed} +procedure TPartyGame.CallBeforeSongSelect; begin - //Copy Winner - Rounds[CurRound].Winner := ScreenSingModi.Winner; - //Set Scores - GenScores; + if (CurRound >= 0) then + begin + // we set screen song to party mode + // plugin should not have to do this if it + // don't want default procedure to be executed + ScreenSong.Mode := smPartyMode; + + with Modes[Rounds[CurRound].Mode] do + if (CallLua(Parent, Functions.BeforeSongSelect)) then + begin // execute default function: + // display song select screen + Display.FadeTo(@ScreenSong); + end; + end; +end; - //Increase TimesPlayed 4 all Players - For I := 0 to Teams.NumTeams-1 do - Inc(Teams.Teaminfo[I].Playerinfo[Teams.Teaminfo[I].CurPlayer].TimesPlayed); +procedure TPartyGame.CallAfterSongSelect; +begin + if (CurRound >= 0) then + begin + with Modes[Rounds[CurRound].Mode] do + if (CallLua(Parent, Functions.AfterSongSelect)) then + begin // execute default function: + // display sing screen + ScreenSong.StartSong; + end; + end; end; -//---------- -//IsWinner - returns true if the player's bit is set in the winner byte -//---------- -function TPartySession.IsWinner(Player, Winner: byte): boolean; -var - Mask: byte; +procedure TPartyGame.CallBeforeSing; begin - Mask := 1 shl Player; - Result := (Winner and Mask) <> 0; + if (CurRound >= 0) then + begin + with Modes[Rounds[CurRound].Mode] do + if (CallLua(Parent, Functions.BeforeSing)) then + begin // execute default function: + + //nothing atm + { to-do : compartmentalize TSingScreen.OnShow into + functions for init of a specific part of + sing screen. + these functions should be called here before + sing screen is shown, or it should be called + by plugin if it wants to define a custom + singscreen start up. } + + //set correct playersplay + if (bPartyGame) then + PlayersPlay := Length(Teams); + end; + end; end; -//---------- -//GenScores - increase scores for current round -//---------- -procedure TPartySession.GenScores; -var - I: byte; +procedure TPartyGame.CallOnSing; begin - for I := 0 to Teams.NumTeams - 1 do + if (CurRound >= 0) then begin - if isWinner(I, Rounds[CurRound].Winner) then - Inc(Teams.Teaminfo[I].Score); + with Modes[Rounds[CurRound].Mode] do + if (CallLua(Parent, Functions.OnSing)) then + begin // execute default function: + + //nothing atm + end; end; end; -//---------- -//GetTeamOrder - returns the placement of each Team [First Position of Array is Teamnum of first placed Team, ...] -//---------- -function TPartySession.GetTeamOrder: TeamOrderArray; -var - I, J: integer; - ATeams: array [0..5] of TeamOrderEntry; - TempTeam: TeamOrderEntry; +procedure TPartyGame.CallAfterSing; begin - // TODO: PartyMode: Write this in another way, so that teams with the same score get the same place - //Fill Team array - for I := 0 to Teams.NumTeams - 1 do + if (CurRound >= 0) then + begin + with Modes[Rounds[CurRound].Mode] do + if (CallLua(Parent, Functions.AfterSing)) then + begin // execute default function: + + if (bPartyGame) then + // display party score screen + Display.FadeTo(@ScreenPartyScore) + else //display standard score screen + Display.FadeTo(@ScreenScore); + end; + end; +end; + +{ returns an array[1..6] of integer. the index stands for the placing, + value is the team number (in the team array) } +function TPartyGame.GetTeamRanking: AParty_TeamRanking; + var + I, J: Integer; + Temp: TParty_TeamRanking; + Rank: Integer; +begin + SetLength(Result, Length(Teams)); + + // fill ranking array + for I := 0 to High(Result) do begin - ATeams[I].Teamnum := I; - ATeams[I].Score := Teams.Teaminfo[I].Score; + Result[I].Team := I; + Result[I].Rank := 0; 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 + // bubble sort by score + J := High(Result); + repeat + for I := 0 to J - 1 do + if (Teams[Result[I].Team].Score < Teams[Result[I+1].Team].Score) then begin - TempTeam := ATeams[I-1]; - ATeams[I-1] := ATeams[I]; - ATeams[I] := TempTeam; + Temp := Result[I]; + Result[I] := Result[I+1]; + Result[I+1] := Temp; end; + Dec(J); + until J <= 0; - //Copy to Result - for I := 0 to Teams.NumTeams-1 do - Result[I] := ATeams[I].TeamNum; + // set rank field + Rank := 1; //first rank has id 1 + for I := 0 to High(Result) do + begin + Result[I].Rank := Rank; + + if (I < High(Result)) and (Teams[Result[I].Team].Score <> Teams[Result[I+1].Team].Score) then + Inc(Rank); // next rank if next team has different score + end; end; -//---------- -//GetWinnerString - Get string with WinnerTeam Name, when there is more than one Winner than Connect with and or , -//---------- -function TPartySession.GetWinnerString(Round: byte): UTF8String; +{ returns a string like "Team 1 (and Team 2) win" + if Round is in range from 0 to high(Rounds) then + result is name of winners of specified round. + if Round is -1 the result is name of winners of + the whole party game} +function TPartyGame.GetWinnerString(Round: integer): UTF8String; var Winners: array of UTF8String; - I: integer; + I: integer; + Ranking: AParty_TeamRanking; begin - Result := Language.Translate('PARTY_NOBODY'); + Result := ''; + Ranking := nil; - if (Round > High(Rounds)) then - exit; - - if (Rounds[Round].Winner = 0) then + if (Round >= 0) and (Round <= High(Rounds)) then begin - exit; - end; + if (not Rounds[Round].AlreadyPlayed) then + Result := Language.Translate('PARTY_NOTPLAYEDYET') + else + Ranking := Rounds[Round].Ranking; + end + else if (Round = -1) then + Ranking := GetTeamRanking; - 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 + if (Ranking <> nil) then begin - if isWinner(I, Rounds[Round].Winner) then + SetLength(Winners, 0); + for I := 0 to High(Ranking) do begin - SetLength(Winners, Length(Winners) + 1); - Winners[high(Winners)] := Teams.TeamInfo[I].Name; + if (Ranking[I].Rank = PR_First) and (Ranking[I].Team >= 0) and (Ranking[I].Team <= High(Teams)) then + begin + SetLength(Winners, Length(Winners) + 1); + Winners[high(Winners)] := UTF8String(Teams[Ranking[I].Team].Name); + end; end; + + if (Length(Winners) > 0) then + Result := Language.Implode(Winners); end; - Result := Language.Implode(Winners); + + if (Length(Result) = 0) then + Result := Language.Translate('PARTY_NOBODY'); end; end. -- cgit v1.2.3 From c8af7cb20362428d566d41d8bbe3091b40e7346a Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Mon, 25 Jan 2010 19:15:54 +0000 Subject: fix execution of default behaviour for party hooks (caused e.g. song never ending bug) git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2093 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 133 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 87 insertions(+), 46 deletions(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 94580241..2f89afd6 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -797,8 +797,12 @@ end; if plugins function returns true then default is called after plugins function was executed} procedure TPartyGame.CallBeforeSongSelect; + var + ExecuteDefault: boolean; begin - if (CurRound >= 0) then + if not bPartyStarted then + ExecuteDefault := true + else if (CurRound >= 0) then begin // we set screen song to party mode // plugin should not have to do this if it @@ -806,79 +810,116 @@ begin ScreenSong.Mode := smPartyMode; with Modes[Rounds[CurRound].Mode] do - if (CallLua(Parent, Functions.BeforeSongSelect)) then - begin // execute default function: - // display song select screen - Display.FadeTo(@ScreenSong); - end; + ExecuteDefault := (CallLua(Parent, Functions.BeforeSongSelect)); + end + else + ExecuteDefault := true; + + // execute default function: + if ExecuteDefault then + begin + // display song select screen + Display.FadeTo(@ScreenSong); end; end; -procedure TPartyGame.CallAfterSongSelect; +procedure TPartyGame.CallAfterSongSelect; + var + ExecuteDefault: boolean; begin - if (CurRound >= 0) then + if not bPartyStarted then + ExecuteDefault := true + else if (CurRound >= 0) then begin with Modes[Rounds[CurRound].Mode] do - if (CallLua(Parent, Functions.AfterSongSelect)) then - begin // execute default function: + ExecuteDefault := (CallLua(Parent, Functions.AfterSongSelect)); + end + else + ExecuteDefault := true; - // display sing screen - ScreenSong.StartSong; - end; + // execute default function: + if ExecuteDefault then + begin + // display sing screen + ScreenSong.StartSong; end; end; -procedure TPartyGame.CallBeforeSing; +procedure TPartyGame.CallBeforeSing; + var + ExecuteDefault: boolean; begin - if (CurRound >= 0) then + if not bPartyStarted then + ExecuteDefault := true + else if (CurRound >= 0) then begin with Modes[Rounds[CurRound].Mode] do - if (CallLua(Parent, Functions.BeforeSing)) then - begin // execute default function: - - //nothing atm - { to-do : compartmentalize TSingScreen.OnShow into - functions for init of a specific part of - sing screen. - these functions should be called here before - sing screen is shown, or it should be called - by plugin if it wants to define a custom - singscreen start up. } - - //set correct playersplay - if (bPartyGame) then - PlayersPlay := Length(Teams); - end; + ExecuteDefault := (CallLua(Parent, Functions.BeforeSing)); + end + else + ExecuteDefault := true; + + // execute default function: + if ExecuteDefault then + begin + //nothing atm + { to-do : compartmentalize TSingScreen.OnShow into + functions for init of a specific part of + sing screen. + these functions should be called here before + sing screen is shown, or it should be called + by plugin if it wants to define a custom + singscreen start up. } + + //set correct playersplay + if (bPartyGame) then + PlayersPlay := Length(Teams); end; end; procedure TPartyGame.CallOnSing; + var + ExecuteDefault: boolean; begin - if (CurRound >= 0) then + if not bPartyStarted then + ExecuteDefault := true + else if (CurRound >= 0) then begin with Modes[Rounds[CurRound].Mode] do - if (CallLua(Parent, Functions.OnSing)) then - begin // execute default function: + ExecuteDefault := (CallLua(Parent, Functions.OnSing));; + end + else + ExecuteDefault := true; - //nothing atm - end; + // execute default function: + if ExecuteDefault then + begin + //nothing atm end; end; procedure TPartyGame.CallAfterSing; + var + ExecuteDefault: boolean; begin - if (CurRound >= 0) then + if not bPartyStarted then + ExecuteDefault := true + else if (CurRound >= 0) then begin with Modes[Rounds[CurRound].Mode] do - if (CallLua(Parent, Functions.AfterSing)) then - begin // execute default function: - - if (bPartyGame) then - // display party score screen - Display.FadeTo(@ScreenPartyScore) - else //display standard score screen - Display.FadeTo(@ScreenScore); - end; + ExecuteDefault := (CallLua(Parent, Functions.AfterSing)); + end + else + ExecuteDefault := true; + + // execute default function: + if ExecuteDefault then + begin + if (bPartyGame) then + // display party score screen + Display.FadeTo(@ScreenPartyScore) + else //display standard score screen + Display.FadeTo(@ScreenScore); end; end; -- cgit v1.2.3 From 1e38a5b1aeaef43c4807113251705a5cc1099ae7 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Sun, 18 Jul 2010 10:33:05 +0000 Subject: fix party player selection git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@2581 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UParty.pas | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'src/base/UParty.pas') diff --git a/src/base/UParty.pas b/src/base/UParty.pas index 2f89afd6..bc485dca 100644 --- a/src/base/UParty.pas +++ b/src/base/UParty.pas @@ -174,6 +174,9 @@ type returns true on success } function SetRanking(Ranking: AParty_TeamRanking): Boolean; + { increases players TimesPlayed value } + procedure IncTimesPlayed; + { increases round counter by 1 and clears all round specific information; returns the number of the current round or -1 if last round has already been played } @@ -210,7 +213,7 @@ type { returns a string like "Team 1 (and Team 2) win" } function GetWinnerString(Round: integer): UTF8String; - destructor Destroy; + destructor Destroy; override; end; const @@ -713,6 +716,15 @@ begin SetRanking(Ranking); end; +{ increases players TimesPlayed value } +procedure TPartyGame.IncTimesPlayed; + var I: Integer; +begin + for I := 0 to High(Teams) do + with Teams[I] do + Inc(Players[NextPlayer].TimesPlayed); +end; + { increases round counter by 1 and clears all round specific information; returns the number of the current round or -1 if last round has already been played } @@ -722,6 +734,8 @@ begin // some lines concerning the previous round if (CurRound >= 0) then begin + IncTimesPlayed; + Rounds[CurRound].AlreadyPlayed := true; GenScores; -- cgit v1.2.3