Arthur Brandao 6 éve
szülő
commit
095dc48144
6 módosított fájl, 569 hozzáadás és 13 törlés
  1. 4 0
      Serveur/constante.h
  2. 45 4
      Serveur/delay.c
  3. 8 3
      Serveur/delay.h
  4. 489 3
      Serveur/game.c
  5. 8 0
      Serveur/game.h
  6. 15 3
      Serveur/handler.c

+ 4 - 0
Serveur/constante.h

@@ -36,6 +36,10 @@
 #define MAXPLAYER 4 //Nombre max de joueur par parti
 #define MAPDIR "map/" //Chemin vers le dossier des maps
 #define TIMEMAJOR 10 //Temps du major en seconde
+#define TIMEBOMB 4 //Nombre de seconde avant explosion de la bombe
+#define SPAWNRATE 30 //% de chance de spawn d'un objet
+#define DAMAGEBOMB 0.4 //% de degat des bombes
+#define DAMAGEMINE 0.6 //% de degat des mines
 
 /* --- Reseaux --- */
 #define PORT_UDP 18624

+ 45 - 4
Serveur/delay.c

@@ -42,23 +42,28 @@ void* delay_thread(void* data) {
     if (game[d->game].active) {
         pthread_mutex_lock(&playerMutex[(d->game * MAXPLAYER) + d->player]);
         if (game[d->game].player[d->player]->ini) {
-            if (d->callback(&game[d->game], d->player) != SUCCESS) {
+            if (d->callback(&game[d->game], d->player, d->data) != SUCCESS) {
                 adderror("Erreur callback Delay");
             }
         }
         pthread_mutex_unlock(&playerMutex[(d->game * MAXPLAYER) + d->player]);
     }
     pthread_mutex_unlock(&gameMutex[d->game]);
+    //Free data
+    if(d->data != NULL){
+        free(data);
+    }
     return NULL;
 }
 
 /* --- Fonctions publiques --- */
-void delay(int second, int game, int player, int(*callback)(Game*, int)) {
+void delay(int second, int game, int player, int(*callback)(Game*, int, void*)) {
     pthread_t thread;
-    delay_t* d = malloc(sizeof (timer_t));
+    delay_t* d = malloc(sizeof (delay_t));
     d->second = second;
     d->game = game;
     d->player = player;
+    d->data = NULL;
     d->callback = callback;
     //Creation thread
     if (pthread_create(&thread, NULL, delay_thread, d) != 0) {
@@ -66,7 +71,21 @@ void delay(int second, int game, int player, int(*callback)(Game*, int)) {
     }
 }
 
-int callback_major_end(Game* g, int playerIndex) {
+void delay_data(int second, int game, int player, void* data, int(*callback)(Game*, int, void*)) {
+    pthread_t thread;
+    delay_t* d = malloc(sizeof (delay_t));
+    d->second = second;
+    d->game = game;
+    d->player = player;
+    d->data = data;
+    d->callback = callback;
+    //Creation thread
+    if (pthread_create(&thread, NULL, delay_thread, d) != 0) {
+        adderror("Impossible de créer le thread Delay");
+    }
+}
+
+int callback_major_end(Game* g, int playerIndex, void* data) {
     JsonEncoder notif;
     //Retire le bonus major
     g->player[playerIndex]->major = 0;
@@ -78,4 +97,26 @@ int callback_major_end(Game* g, int playerIndex) {
         return FAIL;
     }
     return SUCCESS;
+}
+
+int callback_bomb_explode(Game* g, int playerIndex, void* data){
+    JsonEncoder notif;
+    int* pos = (int*) data;
+    ini_encoder(&notif);
+    //Retire mutex car mis dans la fonction
+    pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
+    pthread_mutex_unlock(&gameMutex[g->index]);
+    //Gestion des explosions
+    if(bomb_explode(g, playerIndex, pos[0], pos[1], &notif)){
+        //Notification joueurs
+        if(!notify_player(g, "POST", "attack/explose", &notif, -1)){
+            clean_json_encoder(&notif);
+            return FAIL;
+        }
+    }
+    //Remise des mutex
+    pthread_mutex_lock(&gameMutex[g->index]);
+    pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
+    clean_json_encoder(&notif);
+    return SUCCESS;
 }

+ 8 - 3
Serveur/delay.h

@@ -17,7 +17,8 @@ typedef struct{
     int second; //Seconde à attendre
     int game; //Index de la game dans le tableau
     int player; //Index du joueur dans le tableau de game
-    int(*callback)(Game*, int);
+    void* data; //Autres données pour le callback
+    int(*callback)(Game*, int, void*);
 }delay_t;
 
 /* --- Fonctions --- */
@@ -28,9 +29,13 @@ typedef struct{
  * @param int Index du joueur dans la game
  * @param int(*)(Game*, int) Le callback
  */
-void delay(int, int, int, int(*)(Game*, int));
+void delay(int, int, int, int(*)(Game*, int, void*));
 
-int callback_major_end(Game*, int);
+void delay_data(int, int, int, void*, int(*)(Game*, int, void*));
+
+int callback_major_end(Game*, int, void*);
+
+int callback_bomb_explode(Game*, int, void*);
 
 #endif /* DELAY_H */
 

+ 489 - 3
Serveur/game.c

@@ -175,7 +175,7 @@ int create_game(char* name, char* map) {
         game[index].player[i] = malloc(sizeof (Player));
         game[index].player[i]->ini = false;
     }
-    game[index].object = malloc(sizeof(Object));
+    game[index].object = malloc(sizeof (Object));
     object_ini(game[index].object);
     //object_add(game[index].object, OBJ_MAJOR, 1, 1);
     pthread_mutex_unlock(&gameMutex[index]);
@@ -299,6 +299,491 @@ boolean player_collision(Game* g, int x, int y) {
     return false;
 }
 
+boolean player_collision_index(Game* g, int x, int y, int* index) {
+    for (int i = 0; i < MAXPLAYER; i++) {
+        if (g->player[i]->ini) {
+            if (g->player[i]->x == x && g->player[i]->y == y) {
+                *index = i;
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+boolean bomb_explode(Game* g, int playerIndex, int x, int y, JsonEncoder* json) {
+    printf("Explode\n");
+    JsonEncoder object, notif;
+    JsonArray bomb, bonus, chain;
+    int res, index, cBomb = 0, cBonus = 0, cChain = 0;
+    //Inie json
+    ini_encoder(&object);
+    ini_encoder(&notif);
+    ini_array_encoder(&bomb);
+    ini_array_encoder(&bonus);
+    ini_array_encoder(&chain);
+    //Mutex
+    pthread_mutex_lock(&gameMutex[g->index]);
+    pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
+    //Determine le type de la bombe
+    switch (g->map[x][y]) {
+        case '1':
+            add_string(json, "type", "classic");
+            break;
+        case '2':
+            add_string(json, "type", "mine");
+            break;
+        case '3':
+            add_string(json, "type", "remote");
+            break;
+        default:
+            pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
+            pthread_mutex_unlock(&gameMutex[g->index]);
+            return false;
+    }
+    //Determine la position de la bombe
+    char pos[20];
+    memset(pos, 0, 20);
+    snprintf(pos, 20, "%d,%d", x, y);
+    add_string(json, "pos", pos);
+    //Si le joueur à un bonus
+    if (g->player[playerIndex]->firePower > 0) {
+        add_boolean(json, "bonus", true);
+    } else {
+        add_boolean(json, "bonus", false);
+    }
+    //Calcul l'explosion non mine
+    if (g->map[x][y] != '2') {
+        g->map[x][y] = '_';
+        //Vers le haut
+        for (int i = 0; i < 2 + g->player[playerIndex]->firePower; i++) {
+            //Si on est dans la map
+            if (y - 1 - i >= 0) {
+                //Si un mur destructible
+                if (g->map[x][y - 1 - i] == '*') {
+                    g->map[x][y - 1 - i] = '_';
+                    res = spawn_object(g, x, y - 1 - i, &object);
+                    if (res == 1) { //Bombe
+                        cBomb++;
+                        add_array_object(&bomb, &object);
+                        clean_json_encoder(&object);
+                    } else if (res == 2) { //Bonus Malus
+                        cBonus++;
+                        add_array_object(&bonus, &object);
+                        clean_json_encoder(&object);
+                    }
+                }
+                //Si un joueur
+                if (player_collision_index(g, x, y - 1 - i, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x][y - 1 - i] == '1' || g->map[x][y - 1 - i] == '2' || g->map[x][y - 1 - i] == '3') {
+                    cChain++;
+                    bomb_chain(g, playerIndex, x, y - 1 - i, &chain);
+                }
+            }
+        }
+        //Vers le bas
+        for (int i = 0; i < 2 + g->player[playerIndex]->firePower; i++) {
+            //Si on est dans la map
+            if (y + 1 + i <= g->height) {
+                //Si un mur destructible
+                if (g->map[x][y + 1 + i] == '*') {
+                    g->map[x][y + 1 + i] = '_';
+                    res = spawn_object(g, x, y + 1 + i, &object);
+                    if (res == 1) { //Bombe
+                        cBomb++;
+                        add_array_object(&bomb, &object);
+                        clean_json_encoder(&object);
+                    } else if (res == 2) { //Bonus Malus
+                        cBonus++;
+                        add_array_object(&bonus, &object);
+                        clean_json_encoder(&object);
+                    }
+                }
+                //Si un joueur
+                if (player_collision_index(g, x, y + 1 + i, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x][y + 1 + i] == '1' || g->map[x][y + 1 + i] == '2' || g->map[x][y + 1 + i] == '3') {
+                    cChain++;
+                    bomb_chain(g, playerIndex, x, y + 1 + i, &chain);
+                }
+            }
+        }
+        //Vers la gauche
+        for (int i = 0; i < 2 + g->player[playerIndex]->firePower; i++) {
+            //Si on est dans la map
+            if (x - 1 - i >= 0) {
+                //Si un mur destructible
+                if (g->map[x - 1 - i][y] == '*') {
+                    g->map[x - 1 - i][y] = '_';
+                    res = spawn_object(g, x - 1 - i, y, &object);
+                    if (res == 1) { //Bombe
+                        cBomb++;
+                        add_array_object(&bomb, &object);
+                        clean_json_encoder(&object);
+                    } else if (res == 2) { //Bonus Malus
+                        cBonus++;
+                        add_array_object(&bonus, &object);
+                        clean_json_encoder(&object);
+                    }
+                }
+                //Si un joueur
+                if (player_collision_index(g, x - 1 - i, y, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x - 1 - i][y] == '1' || g->map[x - 1 - i][y] == '2' || g->map[x - 1 - i][y] == '3') {
+                    cChain++;
+                    bomb_chain(g, playerIndex, x - 1 - i, y, &chain);
+                }
+            }
+        }
+        //Vers la droite
+        for (int i = 0; i < 2 + g->player[playerIndex]->firePower; i++) {
+            //Si on est dans la map
+            if (x + 1 + i >= 0) {
+                //Si un mur destructible
+                if (g->map[x + 1 + i][y] == '*') {
+                    g->map[x + 1 + i][y] = '_';
+                    res = spawn_object(g, x + 1 + i, y, &object);
+                    if (res == 1) { //Bombe
+                        cBomb++;
+                        add_array_object(&bomb, &object);
+                        clean_json_encoder(&object);
+                    } else if (res == 2) { //Bonus Malus
+                        cBonus++;
+                        add_array_object(&bonus, &object);
+                        clean_json_encoder(&object);
+                    }
+                }
+                //Si un joueur
+                if (player_collision_index(g, x + 1 + i, y, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x + 1 + i][y] == '1' || g->map[x + 1 + i][y] == '2' || g->map[x + 1 + i][y] == '3') {
+                    cChain++;
+                    bomb_chain(g, playerIndex, x + 1 + i, y, &chain);
+                }
+            }
+        }
+    }        
+    //Si c'est une mine
+    else {
+        g->map[x][y] = '_';
+        //Recup le joueur
+        if (player_collision_index(g, x, y, &index)) {
+            if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+            if (g->player[index]->major == 0) {
+                //Baisse la vie
+                g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * DAMAGEMINE);
+                //Notification du joueur
+                describe_player(g->player[index], &notif);
+                if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                    adderror("Impossible de notifer le client");
+                }
+                clean_json_encoder(&notif);
+            }
+            if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+        }
+    }
+    //Affichage de la map
+    
+    //Ajout des json
+    add_array(json, "bomb", &bomb);
+    add_array(json, "bonusMalus", &bonus);
+    add_array(json, "chain", &chain);
+    //Nettoyage
+    pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
+    pthread_mutex_unlock(&gameMutex[g->index]);
+    return true;
+}
+
+void bomb_chain(Game* g, int playerIndex, int x, int y, JsonArray* chain) {
+    JsonEncoder json, notif;
+    int index;
+    //Inie json
+    ini_encoder(&json);
+    ini_encoder(&notif);
+    //Determine le type de la bombe
+    switch (g->map[x][y]) {
+        case '1':
+            add_string(&json, "type", "classic");
+            break;
+        case '2':
+            add_string(&json, "type", "mine");
+            break;
+        case '3':
+            add_string(&json, "type", "remote");
+            break;
+        default:
+            return;
+    }
+    //Determine la position de la bombe
+    char pos[20];
+    memset(pos, 0, 20);
+    snprintf(pos, 20, "%d,%d", x, y);
+    add_string(&json, "pos", pos);
+    //Calcul l'explosion non mine
+    if (g->map[x][y] != '2') {
+        g->map[x][y] = '_';
+        //Vers le haut
+        for (int i = 0; i < 2; i++) {
+            //Si on est dans la map
+            if (y - 1 - i >= 0) {
+                //Si un mur destructible
+                if (g->map[x][y - 1 - i] == '*') {
+                    g->map[x][y - 1 - i] = '_';
+                }
+                //Si un joueur
+                if (player_collision_index(g, x, y - 1 - i, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x][y - 1 - i] == '1' || g->map[x][y - 1 - i] == '2' || g->map[x][y - 1 - i] == '3') {
+                    bomb_chain(g, playerIndex, x, y - 1 - i, chain);
+                }
+            }
+        }
+        //Vers le bas
+        for (int i = 0; i < 2 + g->player[playerIndex]->firePower; i++) {
+            //Si on est dans la map
+            if (y + 1 + i <= g->height) {
+                //Si un mur destructible
+                if (g->map[x][y + 1 + i] == '*') {
+                    g->map[x][y + 1 + i] = '_';
+                }
+                //Si un joueur
+                if (player_collision_index(g, x, y + 1 + i, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x][y + 1 + i] == '1' || g->map[x][y + 1 + i] == '2' || g->map[x][y + 1 + i] == '3') {
+                    bomb_chain(g, playerIndex, x, y + 1 + i, chain);
+                }
+            }
+        }
+        //Vers la gauche
+        for (int i = 0; i < 2 + g->player[playerIndex]->firePower; i++) {
+            //Si on est dans la map
+            if (x - 1 - i >= 0) {
+                //Si un mur destructible
+                if (g->map[x - 1 - i][y] == '*') {
+                    g->map[x - 1 - i][y] = '_';
+                }
+                //Si un joueur
+                if (player_collision_index(g, x - 1 - i, y, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x - 1 - i][y] == '1' || g->map[x - 1 - i][y] == '2' || g->map[x - 1 - i][y] == '3') {
+                    bomb_chain(g, playerIndex, x - 1 - i, y, chain);
+                }
+            }
+        }
+        //Vers la droite
+        for (int i = 0; i < 2 + g->player[playerIndex]->firePower; i++) {
+            //Si on est dans la map
+            if (x + 1 + i >= 0) {
+                //Si un mur destructible
+                if (g->map[x + 1 + i][y] == '*') {
+                    g->map[x + 1 + i][y] = '_';
+                }
+                //Si un joueur
+                if (player_collision_index(g, x + 1 + i, y, &index)) {
+                    if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                    if (g->player[index]->major == 0) {
+                        //Baisse la vie
+                        g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * (DAMAGEBOMB - (0.1 * i)));
+                        //Notification du joueur
+                        describe_player(g->player[index], &notif);
+                        if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                            adderror("Impossible de notifer le client");
+                        }
+                        clean_json_encoder(&notif);
+                    }
+                    if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+                }
+                //Si une bombe
+                if (g->map[x + 1 + i][y] == '1' || g->map[x + 1 + i][y] == '2' || g->map[x + 1 + i][y] == '3') {
+                    bomb_chain(g, playerIndex, x + 1 + i, y, chain);
+                }
+            }
+        }
+    }        
+    //Si c'est une mine
+    else {
+        g->map[x][y] = '_';
+        //Recup le joueur
+        if (player_collision_index(g, x, y, &index)) {
+            if (index != playerIndex) pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + index]);
+            if (g->player[index]->major == 0) {
+                //Baisse la vie
+                g->player[index]->life = g->player[index]->life - (g->player[index]->maxLife * DAMAGEMINE);
+                //Notification du joueur
+                describe_player(g->player[index], &notif);
+                if (!notify_client(g->player[index]->cli, "POST", "attack/affect", &notif)) {
+                    adderror("Impossible de notifer le client");
+                }
+                clean_json_encoder(&notif);
+            }
+            if (index != playerIndex) pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + index]);
+        }
+    }
+    //Ajoute json dans le tableau
+    add_array_object(chain, &json);
+    //Nettoyage
+    clean_json_encoder(&json);
+}
+
+int spawn_object(Game* g, int x, int y, JsonEncoder* json) {
+    int random, res = 0;
+    //Generation random si spawn ou non
+    srand(time(NULL));
+    random = rand() % 100 + 1;
+    if (random > SPAWNRATE) {
+        return 0; //Pas de spawn
+    }
+    //Choisit l'objet
+    random = rand() % 11;
+    switch (random) {
+        case OBJ_BCLASSIC:
+            res = 1;
+            add_string(json, "type", "classic");
+            break;
+        case OBJ_BMINE:
+            res = 1;
+            add_string(json, "type", "mine");
+            break;
+        case OBJ_BREMOTE:
+            res = 1;
+            add_string(json, "type", "remote");
+            break;
+        case OBJ_BOMBUP:
+            res = 2;
+            add_string(json, "type", "bomb_up");
+            break;
+        case OBJ_BOMBDOWN:
+            res = 2;
+            add_string(json, "type", "bomb_down");
+            break;
+        case OBJ_FIREPOWER:
+            res = 2;
+            add_string(json, "type", "fire_power");
+            break;
+        case OBJ_SCOOTER:
+            res = 2;
+            add_string(json, "type", "scooter");
+            break;
+        case OBJ_BROKENLEG:
+            res = 2;
+            add_string(json, "type", "broken_legs");
+            break;
+        case OBJ_LIFEUP:
+            res = 2;
+            add_string(json, "type", "life_up");
+            break;
+        case OBJ_LIFEMAX:
+            res = 2;
+            add_string(json, "type", "life_max");
+            break;
+        case OBJ_MAJOR:
+            res = 2;
+            add_string(json, "type", "major");
+            break;
+    }
+    //Ajoute l'objet dans la partie
+    object_add(g->object, random, x, y);
+    //Ajoute postion au json
+    char pos[20];
+    memset(pos, 0, 20);
+    snprintf(pos, 20, "%d,%d", x, y);
+    add_string(json, "pos", pos);
+    //Retourne type d'ajout
+    return res;
+}
+
 void remove_player(Game* g, int playerIndex) {
     pthread_mutex_lock(&gameMutex[g->index]);
     pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + playerIndex]);
@@ -314,12 +799,12 @@ void stop_game(Game* g) {
     g->active = false;
     //Suppr les joueurs
     for (int i = 0; i < MAXPLAYER; i++) {
-        pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + i]);
+        //pthread_mutex_lock(&playerMutex[(g->index * MAXPLAYER) + i]);
         if (g->player[i]->ini) {
             delete_player(g->player[i]);
         }
         free(g->player[i]);
-        pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + i]);
+        //pthread_mutex_unlock(&playerMutex[(g->index * MAXPLAYER) + i]);
     }
     //Libere la memoire
     object_clean(g->object);
@@ -338,6 +823,7 @@ void stop_game(Game* g) {
 void clean_games() {
     for (int i = 0; i < MAXGAME; i++) {
         if (game[i].active) {
+            pthread_mutex_unlock(&gameMutex[i]);
             stop_game(&game[i]);
         }
     }

+ 8 - 0
Serveur/game.h

@@ -76,6 +76,14 @@ boolean notify_player(Game*, char*, char*, JsonEncoder*, int);
 
 boolean player_collision(Game*, int, int);
 
+boolean player_collision_index(Game*, int, int, int*);
+
+boolean bomb_explode(Game*, int, int, int, JsonEncoder*);
+
+void bomb_chain(Game*, int, int, int, JsonArray*);
+
+int spawn_object(Game*, int, int, JsonEncoder*);
+
 void remove_player(Game*, int);
 
 void stop_game(Game*);

+ 15 - 3
Serveur/handler.c

@@ -625,25 +625,37 @@ int handler_attack_bomb(int cliId, JsonParser* json) {
     //Verif si la bombe peut être posé et pose
     length = strlen(class);
     if (strncmp(class, "classic", length) == 0) {
-        ok = p->classicBomb > 0 && p->nbBomb > p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
+        ok = p->classicBomb > 0 && p->nbBomb < p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
         if (ok) {
             p->nbBomb++;
             p->classicBomb--;
             game[index].map[x][y] = '1';
+            //Lance timer
+            printf("Ici\n");
+            int* tab = malloc(sizeof(int) * 2);
+            tab[0] = x;
+            tab[1] = y;
+            //Ajoute bombe
+            object_add(p->bomb, OBJ_BCLASSIC, x, y);
+            //Timer
+            printf("Delay\n");
+            delay_data(TIMEBOMB, index, playerIndex, (void*) tab, callback_bomb_explode);
         }
     } else if (strncmp(class, "mine", length) == 0) {
-        ok = p->mine > 0 && p->nbBomb > p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
+        ok = p->mine > 0 && p->nbBomb < p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
         if (ok) {
             p->nbBomb++;
             p->mine--;
             game[index].map[x][y] = '2';
+            //Ajoute la bombe dans la liste du joueur
         }
     } else if (strncmp(class, "remote", length) == 0) {
-        ok = p->remoteBomb > 0 && p->nbBomb > p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
+        ok = p->remoteBomb > 0 && p->nbBomb < p->maxBomb && game[index].map[x][y] == '_' && !player_collision(&game[index], x, y);
         if (ok) {
             p->nbBomb++;
             p->remoteBomb--;
             game[index].map[x][y] = '3';
+            //Ajoute la bombe dans la liste du joueur
         }
     } else {
         pthread_mutex_unlock(&playerMutex[(index * MAXPLAYER) + playerIndex]);