Errechnete Werte aus versch. Feldern

cola1

Mitglied
Hey,

es geht darum bei der Erstellung eines Spielcharakters (inkl. Rasse und Klasse) bestimmte Attribute (Stärke, Leben etc.) in die Datenbank zu schreiben und ich nicht weiß wo man dabei anfängt :-(

In einer Tabelle stehen GRUNDWerte für die Rasse, welche sich im Verlauf des Spieles nicht mehr verändern. Irgendwomit muss man ja starten und es ist schicker, wenn die Werte etwas variieren.
Beispiel `Rasse`:
Mensch, 25 Stärke, 23 Intelligenz


In einer weiteren Tabellen stehen levelbasierte Werte für eine Klasse, welche pro Level erneut den gesamten Charakterwerten gutgeschrieben werden sollen.
Beispiel `Klasse`:
Krieger, 4 Stärke, 0 Intelligenz


Beispiel des gewünschten Endergebnisses:
User erstellt einen menschlichen Krieger, Standardlevel 1.
Programm rechnet nun Grundwerte aus `Rasse` + Werte aus `Klasse` * Charakterlevel 1


In Zahlen:
25 Stärke + 4 Stärke * 1 = 29 Stärke
23 Intelligenz + 0 Intelligenz * 1 = 23 Intelligenz


Charakter steigt eine Stufe:
25 Stärke + 4 Stärke * 2 = 33 Stärke
Intelligenz natürlich auch, obwohl sich nichts ändert... ich denke dieser Teil der "Optimierung" hinsichtlicher unnötiger Rechnerei WEIL multipliziert mal 0 übersteigt meine derzeitigen Fähigkeiten :D


Wo fange ich an?
Meine grobe Idee wäre folgende:

PHP:
// Grundwert für die Rasse
// Wie die Rasse ($var1) aus dem Formular zum Erstellen eines Spielcharakters übergeben?
// Wie die ganzen (5) AttributIDs ($var2) erhalten? 
$sql    =   "
            SELECT 
                attributAmount
            FROM
                race_attributes
            WHERE
                raceID = $var1
            AND
                attributID = $var2
            ";
$result = $db->query($sql);

// Levelwert für die Klasse
$sql    =   "
            SELECT 
                attributAmount
            FROM
                class_attributes
            WHERE
                classID = $var1
            AND
                attributID = $var2
            ";
$result = $db->query($sql);

/*

hier rechnen...
Für die Erstellung des Characters reicht 
Grundwert `race` + Levelwert `class`
aber dafür müssen die richtigen Werte 
gefunden werden... :-(

*/

// Erklärung: attributID
// 4 = Stärke
// 5 = Intelligenz
// usw...

$sql    =   "
            INSERT INTO character_attributes
                (characterID, attributID, attributAmount)
            VALUES
                (1, 4, $x),
                (1, 5, $x),
                (1, 6, $x),
                (1, 7, $x),
                (1, 8, $x); 
            "; // muss das Semikolon hinter die letzte VALUE?

$stmt   = $db->prepare($sql);
$stmt->bind_param('iiii'); // geht das?
$stmt->execute()
$stmt->close();

Frage: Wie ist es möglich die insgesamt 5 Attribute während der Erstellung der Spielfigur zu errechnen und wieder in die Datenbank (andere Tabelle) zu schreiben?
 
Zuletzt bearbeitet:
Wie ist es möglich die insgesamt 5 Attribute während der Erstellung der Spielfigur zu errechnen und wieder in die Datenbank (andere Tabelle) zu schreiben?

Frage steht jetzt am ende von #1 :)
 
Jepp. Ersetz dein $x im INSERT durch die Berechnung

Etwa so kannst du alle Attribute auf einmal berechnen und einfügen
SQL:
INSERT INTO 
	character_attributes
	(characterID, attributID, attributAmount)
SELECT
	{$characterid} 	AS characterID,
	race.attributID AS attributID,
	race.attributAmount + class.attributAmount AS attributID
FROM
	race_attributes AS race
	INNER JOIN class_attributes AS class
		race.attributID = class.attributID
WHERE
	race.raceID = {$raceid}
	AND class.classID = {$classid};
 
Zuletzt bearbeitet von einem Moderator:
Bin ich mit diesem Script auf dem richtigen Weg?

Funktionieren tut es nicht, obwohl die $success-Meldung ausgeben wird.

Habe mit print_r($sql) folgende Meldung erhalten (ohne print_r keine Meldung):
SQL:
 INSERT INTO 
characters (userID, raceID, classID, characterName, creationDate) 
VALUES 
(18, 3, 1, 2, NOW()) 
INSERT INTO 
character_attributes (characterID, attributID, attributAmount) 
SELECT 1 AS characterID, race.attributID AS attributID, race.attributAmount + class.attributAmount AS attributID 
FROM
race_attributes AS race 
INNER JOIN 
class_attributes AS class race.attributID = class.attributID 
WHERE 
race.raceID = 3 AND class.classID = 2;

Mein Senf:
Der erste INSERT-Befehl sieht gut aus sieht gut aus, kommt leider nicht an und der CharacterName als INT?! Die Tabelle steht auf Auto Increment, daher keine characterID angegeben - richtig?

Danach folgt der zweite INSERT-Befehl und fängt schon falsch an, glaube ich. Muss nicht erst ein weiterer, zweiter Character erstellt werden bevor wir "SELECTEN"? Leider legt der erste Befehl noch keinen Character an.

Habe den Befehlt natürlich von Yaslaw übernommen.

Hier die gesamte Logik:
PHP:
<?php
if(!isset($_POST['submit'])) return;

if(!isset($_POST['race']) || !isset($_POST['gender']) || !isset($_POST['class']) ||
	!isset($_POST['characterName'])) {
    $error = $lang_registration_errorForm;
    return;
}

if(strlen($_POST['characterName']) > $lang_game_usernameMaxLenght) {
    $error = $lang_registration_errorUsername;
    return;
}

$_POST['characterName'] = trim($_POST['characterName']);

//$userID kommt aus einer anderen Datei, wird bestimmt noch öfter benötigt...
$raceID = $_POST['race'];
$genderID = $_POST['gender'];
$classID = $_POST['class'];
$characterName = $_POST['characterName'];

$sql  = "
        INSERT INTO characters
            (userID, raceID, classID, characterName, creationDate)
        VALUES
            ($userID, $raceID, $genderID, $classID, NOW())
        ";

$sql .= "
        INSERT INTO 
            character_attributes
            (characterID, attributID, attributAmount)
        SELECT
            $characterID AS characterID,
            race.attributID AS attributID,
            race.attributAmount + class.attributAmount AS attributID
        FROM
            race_attributes AS race
        INNER JOIN
            class_attributes AS class
            race.attributID = class.attributID
        WHERE
            race.raceID = $raceID
            AND class.classID = $classID;
        ";

if ($db->multi_query($sql)) {
    do {
        if ($result = $db->store_result()) {
            while ($row = $result->fetch_row()) {
                printf("%s\n", $row[0]);
            }
            $result->free();
        }
        if ($db->more_results()) {
            printf("-----------------\n");
        }
    } while ($db->next_result());
}
print_r($sql);
$db->close();

$success = $lang_registration_success;
?>

Also.. ehm. Warum wird denn kein neuer Eintrag in Characters erstellt? Ohne einen Character kann der Rest garnicht funktionieren :p
 
Zuletzt bearbeitet von einem Moderator:
Augen auf mein Freund und Werde/Felder abzählen und vergleiche
PHP:
//Du hast das folgende. Das stimmen die Felder doch niemals mit den Werten überein
$sql  = "
        INSERT INTO characters
            (userID, raceID, classID, characterName, creationDate)
        VALUES
            ($userID, $raceID, $genderID, $classID, NOW())
        ";

MySQL hat ; als Trennzeichen von Befehlen. Du solltest also deine 2 INSERTS mit ; trennen oder grad einzeln abfeuern.
 
Falls jemand noch einen hilfreichen Wink hat wäre ich sehr dankbar, brauche allerdings erstmal eine Pause.

Erhalte mittlerweise diese Meldungen:

SQL:
 INSERT INTO
characters (userID, raceID, genderID, classID, characterName, creationDate)
VALUES (?, ?, ?, ?, ?, NOW())

INSERT INTO
character_attributes (characterID, attributID, attributAmount)
SELECT
1 AS characterID, race.attributID AS attributID, race.attributAmount + class.attributAmount AS attributAmount
FROM
race_attributes AS race
INNER JOIN
class_attributes AS class race.attributID = class.attributID
WHERE race.raceID = 12 AND class.classID = 9

Etwas stimmte mit dem Query nicht: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'race.attributID = class.attributID WHERE race.raceID' at line 12

Mit diesem (anfängerisch zusammengeflickten) Code:
PHP:
<?php
if(!isset($_POST['submit'])) return;

if(!isset($_POST['race']) || !isset($_POST['gender']) || !isset($_POST['class']) ||
	!isset($_POST['characterName'])) {
    $error = $lang_registration_errorForm;
    return;
}

if(strlen($_POST['characterName']) > $lang_game_usernameMaxLenght) {
    $error = $lang_registration_errorUsername;
    return;
}

$_POST['characterName'] = trim($_POST['characterName']);

$raceID = $_POST['race'];
$genderID = $_POST['gender'];
$classID = $_POST['class'];
$characterName = $_POST['characterName'];

$sql  = "
        INSERT INTO characters
            (userID, raceID, genderID, classID, characterName, creationDate)
        VALUES
            (?, ?, ?, ?, ?, NOW())
        ";
$stmt = $db->prepare($sql);
$stmt->bind_param('iiiis', $userID, $_POST['raceID'], $_POST['genderID'], $_POST['classID'], $_POST['characterName']);
$stmt->execute();
print_r($sql);
$stmt->close();

$sql    =   "
            INSERT INTO 
                character_attributes
                (characterID, attributID, attributAmount)
            SELECT
                $characterID AS characterID,
                race.attributID AS attributID,
                race.attributAmount + class.attributAmount AS attributAmount
            FROM
                race_attributes AS race
            INNER JOIN
                class_attributes AS class
                race.attributID = class.attributID
            WHERE
                race.raceID = $raceID
            AND
                class.classID = $classID
            ";
$result = $db->query($sql);
print_r($sql);
if (!$result) {
    die ('\n Etwas stimmte mit dem Query nicht: '.$db->error);
}

$success = $lang_registration_success;
?>
 
Hier fehlt ein ON:
SQL:
class_attributes AS class race.attributID = class.attributID
Teste es mal so:
SQL:
INSERT INTO
    character_attributes(
        characterID,
        attributID,
        attributAmount
    )
SELECT
    {$characterid} AS characterID,
    race.attributID AS attributID,
    ( race.attributAmount + class.attributAmount ) AS attributAmount
FROM
    race_attributes AS race
INNER JOIN
    class_attributes AS class
ON
    race.attributID = class.attributID
WHERE
    race.raceID = {$raceid}
AND
    class.classID = {$classid};
 
Zuletzt bearbeitet:
Danke schonmal. Muss der Befehl eine characterID selecten?

Habe grade einen kleinen Zwischenschritt zum Prüfen des ersten Statements eingebaut (rinnkopiert :D) und das zweite große Statement auskommentiert. Es wird nicht einmal ein neuer Character gespeichert und die Fehlermeldung ist die eigens definierte, nämlich die $lang_registration_errorStmt.

Aktuellster Code mit allen Vorschlägen (nur bis nach dem ersten Statement):
PHP:
if(!isset($_POST['submit'])) return;

if(!isset($_POST['race']) || !isset($_POST['gender']) || !isset($_POST['class']) ||
	!isset($_POST['characterName'])) {
    $error = $lang_registration_errorForm;
    return;
}

if(strlen($_POST['characterName']) > $lang_game_usernameMaxLenght) {
    $error = $lang_registration_errorUsername;
    return;
}

$_POST['characterName'] = trim($_POST['characterName']);

$raceID = $_POST['race'];
$genderID = $_POST['gender'];
$classID = $_POST['class'];
$characterName = $_POST['characterName'];

$sql  = '
        INSERT INTO characters
            (userID, raceID, genderID, classID, characterName, creationDate)
        VALUES
            (?, ?, ?, ?, ?, NOW())
        ';
        
$stmt = $db->prepare($sql);
print_r($sql);
$stmt->bind_param('iiiis', $userID, $_POST['raceID'], $_POST['genderID'], $_POST['classID'], $_POST['characterName']);
if(!$stmt->execute()) {
    if(strpos($db->error, 'Duplicate') !== false) {
        $error = $lang_registration_errorDuplicate;
    } else {
    $error = $lang_registration_errorStmt;
    }
    return;
}
$stmt->close();

Habe mich jetzt schon Stunden damit befasst... und kann es nicht fassen :/
Danke an alle bis hier. Morgen wird es!
 
Zurück