Der Skript Profiler sagt:
03180ms UPLB::BuyMenu
03127ms Direct exec
03113ms UPLB::BuyWare
wobei die besagten 2 Funktionen so aussehen:
private func BuyMenu(selection)
{
// kein caller?
if (!caller) return(0);
// Menü mit allen kaufbaren Objekten
CreateMenu(GetID(building), caller, 0,2, "Es gibt nichts zu kaufen", 0,0,1);
// alle Homebasematerials durchgehen
var i, ID;
while (ID = GetHomebaseMaterial(GetOwner(),0,i,C4D_All()))
{
AddMenuItem("Kauf: %s", "BuyWare", ID, caller, GetHomebaseMaterial(GetOwner(),ID), i);
++i;
}
// Menüeintrag setzen, falls einer angegeben ist
SelectMenuItem(selection, caller);
}
private func BuyWare(ID, selection)
{
// genug finanzielle Rücklagen?
if (GetWealth(GetOwner()) < GetValue(0,ID))
{
PlayerMessage(GetOwner(), "Nicht genug Geld!", building);
Sound("Error");
return(BuyMenu(selection));
}
// Ware auch noch da?
if (!GetHomebaseMaterial(GetOwner(),ID))
{
Sound("Error");
return(BuyMenu(selection));
}
// Ware erzeugen
var ware = CreateContents(ID, building);
DoHomebaseMaterial(GetOwner(), ID, -1);
// frische Clonks müssen noch zur Crew hinzugefügt werden
if (GetOCF(ware) & OCF_CrewMember())
MakeCrewMember(ware, GetOwner());
// erst noch bezahlen
DoWealth(GetOwner(), -GetValue(0,ID));
Sound("Cash");
// und fertig
return(BuyMenu(selection));
}
Die Verzögerungen treten erst auf, wenn ein Objekt gekauft wird. Das erstmalige Aufrufen des Kaufmenüs ist nicht langsam.
Wobei es auch von der Anzahl der kaufbaren Objekte abzuhängen scheint. Wenn die Auswahl klein ist, hakt es nur wenig. Aber mit der Flagge klappt auch bei großer auswahl alles einwandfrei, weshalb ich es gern über die Flagge lösen würde... aktuell habe ich deswegen sogar das Kaufmenü vom Uplink insofern deaktiviert, dass man dort nur eine Flagge kaufen kann. Wenn man mehr kaufen will, muss man dann die Flagge verwenden.
Hast du in C4ObjectMenu.cpp oder sonst wo, irgendeinen Befehl gesehen den ich nutzen kann? Ich hoffe halt, dass da z.b sowas wie hier im uplink steht, also eine Funktion mit einem Namen, die das ganze Kaufverhalten regelt und die ich dann einfach aus dem uplink heraus aufrufe und dadurch das Flaggenkaufmenü geöffnet wird.
Was der Profiler danach sagt - falls das nicht das komplette Log ist - wäre interessant.
Ich hätte angenommen, die Auflistung verursacht den Lag, und sehe in BuyWare keinen klassischen "Frameschlucker". Das ist komisch.
hab nur den Teil kopiert, weil danach glaub ich nur noch andere Objekte gelistet sind... Ich starte den Skriptprofiler, kaufe 10-20 dinge und stoppe ihn wieder. Gibts noch eine andere Vorgehensweise? Die komplette Liste sieht zb so aus:
-> StartScriptProfiler()
= true
Profiler statistics:
.................................
08160ms Direct exec
08152ms UPLB::BuyWare
08126ms UPLB::BuyMenu
00579ms TS9Z::FogofWar
00564ms _Z2A::CheckPollution
00285ms global IsNight
00230ms _Z2A::Waste
00213ms global ForestChange
00138ms global IsDay
00107ms _Z2A::FilterAir
00107ms R_EG::Regen
00092ms global PathFree
00042ms global PathFree
00040ms CLNK::FxInventarCheckTimer
00034ms global FadeGraphics
00032ms global Find_ID
00028ms global SetGraphics
00023ms global FxShowWeaponTimer
00017ms GRA1::IsBulletGrasTarget
00015ms UPLB::Heal
00013ms TIME::Timing
00013ms global Find_Action
00012ms TIME::RestoreColors
00010ms STRS::Dusk
00010ms global FxgraphFadeStart
00010ms HZCK::UpdateCharge
00010ms 1HUD::Timer
00010ms TIME::TimingTwo
00007ms global Find_Func
00006ms global RandomX
00006ms EGLN::Twinkle
00006ms TIME::UpdateGraphics
00005ms TIME::RestoreMatColors
00004ms global VerticesStuck
00004ms _ETG::Check
00003ms GOAL::CheckTime
00003ms WRBO::Check
00003ms BEAR::Activity
00003ms TIME::Dawn
00003ms SSUN::CheckLight
00003ms TRE3::IsTree
00003ms TRE3::IsDeadTree
00003ms GOAL::EnoughGoals
00003ms BEAR::DoJump
00002ms OWL1::Owl
00002ms TIME::RestoreSkyColors
00002ms TRE4::IsDeadTree
00002ms CHMU::Entrance
00002ms CHMU::Pack
00002ms _CHF::IsWaste
00002ms TRE2::IsDeadTree
00002ms _GVC::GmVal
00002ms BMAN::Check
00001ms global Find_Exclude
00001ms global Find_OCF
00001ms global Find_Category
00001ms global GetGraphics
00001ms FARP::JoinPack
00001ms FARP::CalcValue
00001ms LGFL::Init
00001ms BEAR::Walking
00001ms FARP::Entrance
00001ms CHMU::JoinPack
00001ms TRE2::IsTree
00001ms ATO2::IsWaste
00001ms GRA1::Seed
00001ms D12M::Check
00001ms global FxgraphFadeTimer
00001ms _CHF::PackCount
................................
-> StopScriptProfiler()
= true
Mh, vielleicht irre ich mich auch, aber:
> CreateMenu(GetID(building), caller, 0,2, "Es gibt nichts zu kaufen", 0,0,1);
Das Menü ist durch die
1
ein permanentes Menü, oder? (D.h. es geht nicht zu, wenn du einen Eintrag auswählst)
> return(BuyMenu(selection));
.. und trotzdem erzeugst du das Menü neu, sobald ein Eintrag ausgewählt wurde? Versuch mal einfach testweise das Menü nicht-permanent zu machen. Also einfach die
1
oben zu einer
0
machen.
gute Idee, hat aber leider nichts verändert =/
habe aber grad festgestellt, dass der Lag auch auftritt, wenn ich nichts kaufe, sondern das Menü über die "graben" Taste schließe.
Das Auflisten der Objekte sorgt definitiv für den Lag - leider gibt es da keine wirkliche Möglichkeit, um die Funktion zu optimieren und gleichzeitig aktuellste Informationen zu gewährleisten.
Als eine Art Ansatz für einen Workaround der mir einfällt, wäre das ganze mit Hilfe der Commands zu regeln: SetCommand(pClonk, "Buy", pBase) sorgt dafür, dass das Engineseitige Kaufmenü geöffnet wird. Leider versucht der Clonk, beim Versuch etwas zu kaufen, zur Basis hinzugehen. Wenn man an der Stelle den Command abfangen könnte und die Informationen herausholen könnte, könnte man das so relativ einfach umsetzen. Mit ControlCommand war es mir jedoch nicht möglich, diese Buy-Commands abzufangen, weshalb mir im Moment nicht weiter einfallen könnte, wie man das lösen möchte.
Die andere Alternative wäre, die Anzahl der Objekte die aufgelistet werden zu limitieren und bspw. auf ein Seitensystem zurückzugreifen. (Wobei das bei sehr vielen Objekten ziemlich unangenehm sein kann.)
Danke für die Mühe eine Lösung zu finden :)
Hmm.. da es schon wirklich viele Objekte sind, ist das Kaufmenü allgemein sehr überfüllt, weshalb eine Untergliederung in Kategorien garnicht mal schlecht wäre...
Es gibt im Uplink noch ein anderes Kaufsystem, welches Trades zwischen den Spielern abwickelt. Dort existiert bereits so ein Kategoriesystem, welches ich schon mit den meisten meiner Objekte aufgefüllt habe. Man muss leider jede einzelne Objekt ID in ein Array eintragen, aber für die meisten Dinge habe ich das bereits erledigt.
D.h sollten wir keine Lösung finden, werde ich wohl das Kategoriesystem übernehmen :)