Das Metin2 Acce-System ist eine Costume-Accessoire-Mechanik, die ältere Server nie hatten, die auf modernen Private-Servern aber fast Standard geworden ist. Die Idee ist simpel: Du „socketst" ein normales Item in ein Rücken-Accessoire-Costume (die Acce), und die Acce absorbiert einen Prozentsatz der Boni dieses Items und wendet sie auf den Charakter an. In diesem Leitfaden zeige ich, wie ich die Mechanik von Grund auf hinzufüge – sowohl server- als auch clientseitig.
Was macht das Acce-System genau?
Das klassische Costume-System ändert nur das Aussehen; Acce geht einen Schritt weiter. Der Spieler trägt ein Accessoire, das das Aussehen verändert, und legt dann eine starke Rüstung, eine Waffe oder ein anderes Item hinein. Die Acce verbraucht das Item optisch nicht – sie „absorbiert" einen festen Prozentsatz seiner Bonus-Stats (zum Beispiel Schaden gegen Monster, HP, Kritische Chance) und gewährt sie dem Spieler als zusätzliche Stats. So behält der Spieler das gewünschte Aussehen und gewinnt eine versteckte Machtquelle. Es ist ein tolles System, das deinem Server sowohl Sammeln als auch Machtprogression hinzufügt.
Item-Proto: das Acce-Costume definieren
Alles beginnt im Item-Proto. Acce-Items sind vom Typ ITEM_COSTUME wie ein normales Costume, aber ihr Subtyp muss COSTUME_ACCE sein. Im Item-Editor oder in der Tabelle item_proto:
- Type:
COSTUME - SubType:
ACCE - WearFlags: ein Flag für den Ausrüstungsslot, den das Accessoire nutzt (üblicherweise ein separater
WEAR_COSTUME_ACCE-Slot).
Dieser Subtyp teilt dem Server mit: „Dieses Item ist eine Acce und kann ein anderes Item enthalten." Für die Optik brauchst du außerdem ein .gr2-Modell und ein Icon, aber die Mechanik beruht vollständig auf dem Subtyp und den Sockets.
Sockets: das absorbierte Item speichern
In Metin2 hat jedes Item einige Socket-Slots (normalerweise für Metin-Steine / Diamanten). Für die Acce verwenden wir diese Sockets neu, um Informationen über das eingelegte Item zu speichern. Der sauberste Ansatz ist, mit Konstanten festzulegen, welcher Socket was enthält:
// item.h — was speichern die Sockets der Acce?
enum EAcceSocket
{
ACCE_ABSORBED_VNUM_SLOT = 0, // vnum des absorbierten Items
ACCE_ABSORB_PCT_SLOT = 1, // Absorptionsprozent (z. B. 50 = 50%)
};
Wenn der Spieler im Acce-Fenster ein Item absorbiert, schreibt der Server dessen vnum in socket0 und den berechneten Absorptionsprozentsatz in socket1. Da Sockets zusammen mit dem Item in der Datenbank gespeichert werden, überlebt diese Information sogar einen Server-Neustart – genau das macht das Acce-System persistent.
Die absorbierten Boni auf den Spieler anwenden
Die eigentliche Arbeit besteht darin, die Boni des absorbierten Items zu berechnen und dem Charakter hinzuzufügen, solange die Acce getragen wird. Wir lesen die absorbierte vnum aus dem Socket der Acce, holen das Proto dieses Items und multiplizieren seine apply-Boni mit dem Prozentsatz:
// char_item.cpp — Boni anwenden beim Tragen / Ablegen der Acce
void CHARACTER::__ApplyAcceAbsorb(LPITEM pAcce, bool bAdd)
{
if (!pAcce || pAcce->GetSubType() != COSTUME_ACCE)
return;
DWORD dwVnum = pAcce->GetSocket(ACCE_ABSORBED_VNUM_SLOT);
int iPct = pAcce->GetSocket(ACCE_ABSORB_PCT_SLOT);
if (dwVnum == 0 || iPct <= 0)
return;
TItemTable * pProto = ITEM_MANAGER::instance().GetTable(dwVnum);
if (!pProto)
return;
for (int i = 0; i < ITEM_APPLY_MAX_NUM; ++i)
{
BYTE bType = pProto->aApplies[i].bType;
long lValue = pProto->aApplies[i].lValue;
if (bType == APPLY_NONE || lValue == 0)
continue;
long lAbsorbed = (lValue * iPct) / 100;
ApplyPoint(bType, bAdd ? lAbsorbed : -lAbsorbed);
}
}
Diese Funktion rufst du dort auf, wo der Charakter seine Stats neu berechnet – also in ComputePoints(), während die getragenen Items verarbeitet werden:
// char.cpp — in ComputePoints() bei der Verarbeitung der Ausruestung
LPITEM pAcce = GetWear(WEAR_COSTUME_ACCE);
if (pAcce)
__ApplyAcceAbsorb(pAcce, true);
Da ComputePoints() die Stats von Grund auf neu aufbaut, fügen wir hier immer mit true hinzu; wenn der Spieler die Acce ablegt, löscht die nächste Neuberechnung den Bonus automatisch. Der Parameter bAdd ist nützlich, um den Bonus live zu entfernen, ohne eine vollständige Neuberechnung.
Das Acce-Fenster: Paketfluss und Client
Damit der Spieler ein Item in die Acce ziehen kann, brauchst du ein UI-Fenster. Es wird clientseitig mit uiacce.py (einer Python-Root-Datei) gezeichnet und kommuniziert über eigene Pakete mit dem Server. Der typische Ablauf ist:
- Der Spieler klickt mit rechts auf die Acce → der Client sendet
HEADER_CG_ACCE_REFINE_OPEN, der Server öffnet das Fenster. - Der Spieler legt das Acce-Item und das zu absorbierende Item in die Slots.
- Beim Klick auf „Kombinieren" sendet der Client
HEADER_CG_ACCE_REFINE; der Server berechnet den Absorptionsprozentsatz, schreibt die Sockets und meldet das Ergebnis mitHEADER_GC_ACCE_REFINE_RESULTzurück.
Du musst diese Paket-Header mit derselben Nummer auf Client- und Serverseite in packet.h definieren – eine Abweichung verursacht einen sofortigen Client-„Crash". Vergiss auch nicht, die nötigen Zeilen für die Fenstertexte in locale_game.txt hinzuzufügen.
Absorptionsraten und häufige Fehler
Wie du den Absorptionsprozentsatz festlegst, ist ganz deine Balance-Entscheidung. Zwei gängige Methoden gibt es: eine feste Rate (zum Beispiel immer 50 %) oder eine variable Rate aus einer Tabelle, basierend auf Level/Grade des Items. Eine variable Rate liefert ausgewogenere Ergebnisse, weil du automatisch begrenzen kannst, wie viel sehr starke Items absorbieren. Hier die häufigsten Fehler:
- Sockets nicht gespeichert: Stelle nach der Absorption sicher, dass du das Item nach dem
SetSocket()-Aufruf in die Datenbank persistierst; sonst verschwindet der Bonus beim Neustart. - Doppelter Bonus: Rufst du
__ApplyAcceAbsorbsowohl inComputePointsals auch beim Anlegen auf, wird der Bonus verdoppelt. Verwalte es von einer einzigen Stelle aus. - Falscher Ausrüstungsslot: Ohne separaten
WEAR-Slot für die Acce kollidiert sie mit dem normalen Costume. - Paketnummern-Konflikt: Unterscheiden sich Client- und Server-Header, öffnet sich das Fenster nicht oder es stürzt ab.
Häufige Fragen
Verschwindet das in die Acce gelegte Item?
In der klassischen Mechanik ja – das absorbierte Item wird verbraucht und nur sein Bonus bleibt. Manche Server machen das Item entfernbar; dann musst du auch die Attribute des Items in den Sockets speichern und sie bei einer „Entfernen"-Aktion zurückgeben.
Wird der Acce-Bonus vom Levellimit des getragenen Items beeinflusst?
Nein. Es gelten die eigenen LimitType-Felder der Acce (etwa ein Levellimit); die Levelanforderung des absorbierten Items wird nicht direkt angewendet. Du balancierst über die Limits der Acce selbst.
Kann dieses System später zu einer bestehenden Source hinzugefügt werden?
Ja. Das Acce-System ist vollständig modular: ein neuer Subtyp, ein paar Funktionen, Paket-Header und ein Client-Fenster. Es lässt sich hinzufügen, ohne bestehende Quest-, Item- oder Costume-Systeme anzutasten.
Willst du ein vollständiges Acce-System auf deinem Server? Vom Proto bis zum Client-Fenster, von der Absorptionsbalance bis zur Datenbankpersistenz baue ich die gesamte Kette – kontaktiere mich.