From 18278cdef8bd73412468cdf630b1cca6367f9b24 Mon Sep 17 00:00:00 2001 From: Lutz Date: Mon, 21 Aug 2017 13:01:14 -0500 Subject: [PATCH 1/4] + Copied the Amulet of Life Saving's code from entity.cpp being hit by boulder --- src/actboulder.cpp | 91 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 6 deletions(-) diff --git a/src/actboulder.cpp b/src/actboulder.cpp index ce047abfb..72c588cb2 100644 --- a/src/actboulder.cpp +++ b/src/actboulder.cpp @@ -76,12 +76,91 @@ int boulderCheckAgainstEntity(Entity* my, Entity* entity) spawnGib(entity); entity->modHP(-80); entity->setObituary(language[1505]); - if ( entity->behavior == &actPlayer ) - if ( stats->HP <= 0 ) - { - steamAchievementClient(entity->skill[2], "BARONY_ACH_THROW_ME_THE_WHIP"); - } - if ( stats->HP > 0 ) + + bool bHasLifeSaving = false; + if ( entity->behavior == &actPlayer ) + { + if ( stats->HP <= 0 ) + { + steamAchievementClient(entity->skill[2], "BARONY_ACH_THROW_ME_THE_WHIP"); + if ( stats->amulet->type == AMULET_LIFESAVING ) + { + // The Player had an Amulet of Life Saving! Revive them, if it isn't cursed + Sint32 player = -1; + for ( Sint32 iPlayer = 0; iPlayer < numplayers; ++iPlayer ) + { + if ( entity == players[iPlayer]->entity ) + { + player = iPlayer; //Set the player. + } + } + + if ( stats->amulet->beatitude >= 0 ) + { + messagePlayer(player, language[654]); // "You are brought back to life." + messagePlayer(player, language[655]); // "However, your amulet crumbles to dust." + steamAchievementClient(player, "BARONY_ACH_BORN_AGAIN"); + stats->HUNGER = 800; + + if ( stats->MAXHP < 10 ) + { + stats->MAXHP = 10; + if ( player > 0 && multiplayer == SERVER ) + { + strcpy((char*)net_packet->data, "ATTR"); + net_packet->data[4] = clientnum; + net_packet->data[5] = (Sint8)stats->STR; + net_packet->data[6] = (Sint8)stats->DEX; + net_packet->data[7] = (Sint8)stats->CON; + net_packet->data[8] = (Sint8)stats->INT; + net_packet->data[9] = (Sint8)stats->PER; + net_packet->data[10] = (Sint8)stats->CHR; + net_packet->data[11] = (Sint8)stats->EXP; + net_packet->data[12] = (Sint8)stats->LVL; + SDLNet_Write16((Sint16)stats->HP, &net_packet->data[13]); + SDLNet_Write16((Sint16)stats->MAXHP, &net_packet->data[15]); + SDLNet_Write16((Sint16)stats->MP, &net_packet->data[17]); + SDLNet_Write16((Sint16)stats->MAXMP, &net_packet->data[19]); + net_packet->address.host = net_clients[player - 1].host; + net_packet->address.port = net_clients[player - 1].port; + net_packet->len = 21; + sendPacketSafe(net_sock, -1, net_packet, player - 1); + } + } + + entity->setHP(std::max(stats->MAXHP, 10)); + for ( int iEffect = 0; iEffect < NUMEFFECTS; iEffect++ ) + { + stats->EFFECTS[iEffect] = false; + stats->EFFECTS_TIMERS[iEffect] = 0; + } + entity->flags[BURNING] = false; + serverUpdateEntityFlag(entity, BURNING); + serverUpdateEffects(player); + } + else + { + messagePlayer(player, language[656]); // "Whoops, sorry. Guess it was a dud." + messagePlayer(player, language[657]); // "See you in the next life." + } + stats->amulet->status = BROKEN; + playSoundEntity(entity, 76, 64); + if ( player > 0 && multiplayer == SERVER ) + { + strcpy((char*)net_packet->data, "ARMR"); + net_packet->data[4] = 7; + net_packet->data[5] = stats->amulet->status; + net_packet->address.host = net_clients[player - 1].host; + net_packet->address.port = net_clients[player - 1].port; + net_packet->len = 6; + sendPacketSafe(net_sock, -1, net_packet, player - 1); + } + stats->amulet = nullptr; + } + } + } + // If the Entity survives, or it is a Player wearing an Amulet of Life Saving, destroy the boulder + if ( stats->HP > 0 || bHasLifeSaving == true ) { // spawn several rock items int i = 8 + rand() % 4; From f9f190ddc17a9c306dde8b69ce2347f53366f9c1 Mon Sep 17 00:00:00 2001 From: Lutz Date: Mon, 21 Aug 2017 13:01:32 -0500 Subject: [PATCH 2/4] - Removed the TODO for 'does not protect against boulders' --- src/entity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/entity.cpp b/src/entity.cpp index 9294d86b8..20599d72e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -2473,7 +2473,7 @@ void Entity::handleEffects(Stat* myStats) } } // life saving - if ( myStats->amulet->type == AMULET_LIFESAVING ) //TODO: Doesn't save against boulder traps. + if ( myStats->amulet->type == AMULET_LIFESAVING ) { if ( myStats->HP <= 0 ) { From 2b9edd982508c225d842dbff6bbd18e647e8700e Mon Sep 17 00:00:00 2001 From: Lutz Date: Mon, 21 Aug 2017 13:18:54 -0500 Subject: [PATCH 3/4] - Removed second instance of processing Life Saving effect --- src/actboulder.cpp | 72 +--------------------------------------------- 1 file changed, 1 insertion(+), 71 deletions(-) diff --git a/src/actboulder.cpp b/src/actboulder.cpp index 72c588cb2..a04c12fc6 100644 --- a/src/actboulder.cpp +++ b/src/actboulder.cpp @@ -85,77 +85,7 @@ int boulderCheckAgainstEntity(Entity* my, Entity* entity) steamAchievementClient(entity->skill[2], "BARONY_ACH_THROW_ME_THE_WHIP"); if ( stats->amulet->type == AMULET_LIFESAVING ) { - // The Player had an Amulet of Life Saving! Revive them, if it isn't cursed - Sint32 player = -1; - for ( Sint32 iPlayer = 0; iPlayer < numplayers; ++iPlayer ) - { - if ( entity == players[iPlayer]->entity ) - { - player = iPlayer; //Set the player. - } - } - - if ( stats->amulet->beatitude >= 0 ) - { - messagePlayer(player, language[654]); // "You are brought back to life." - messagePlayer(player, language[655]); // "However, your amulet crumbles to dust." - steamAchievementClient(player, "BARONY_ACH_BORN_AGAIN"); - stats->HUNGER = 800; - - if ( stats->MAXHP < 10 ) - { - stats->MAXHP = 10; - if ( player > 0 && multiplayer == SERVER ) - { - strcpy((char*)net_packet->data, "ATTR"); - net_packet->data[4] = clientnum; - net_packet->data[5] = (Sint8)stats->STR; - net_packet->data[6] = (Sint8)stats->DEX; - net_packet->data[7] = (Sint8)stats->CON; - net_packet->data[8] = (Sint8)stats->INT; - net_packet->data[9] = (Sint8)stats->PER; - net_packet->data[10] = (Sint8)stats->CHR; - net_packet->data[11] = (Sint8)stats->EXP; - net_packet->data[12] = (Sint8)stats->LVL; - SDLNet_Write16((Sint16)stats->HP, &net_packet->data[13]); - SDLNet_Write16((Sint16)stats->MAXHP, &net_packet->data[15]); - SDLNet_Write16((Sint16)stats->MP, &net_packet->data[17]); - SDLNet_Write16((Sint16)stats->MAXMP, &net_packet->data[19]); - net_packet->address.host = net_clients[player - 1].host; - net_packet->address.port = net_clients[player - 1].port; - net_packet->len = 21; - sendPacketSafe(net_sock, -1, net_packet, player - 1); - } - } - - entity->setHP(std::max(stats->MAXHP, 10)); - for ( int iEffect = 0; iEffect < NUMEFFECTS; iEffect++ ) - { - stats->EFFECTS[iEffect] = false; - stats->EFFECTS_TIMERS[iEffect] = 0; - } - entity->flags[BURNING] = false; - serverUpdateEntityFlag(entity, BURNING); - serverUpdateEffects(player); - } - else - { - messagePlayer(player, language[656]); // "Whoops, sorry. Guess it was a dud." - messagePlayer(player, language[657]); // "See you in the next life." - } - stats->amulet->status = BROKEN; - playSoundEntity(entity, 76, 64); - if ( player > 0 && multiplayer == SERVER ) - { - strcpy((char*)net_packet->data, "ARMR"); - net_packet->data[4] = 7; - net_packet->data[5] = stats->amulet->status; - net_packet->address.host = net_clients[player - 1].host; - net_packet->address.port = net_clients[player - 1].port; - net_packet->len = 6; - sendPacketSafe(net_sock, -1, net_packet, player - 1); - } - stats->amulet = nullptr; + bool bHasLifeSaving = true; } } } From 03f4aa1be6248451b27287b341043b5ee9dd4e98 Mon Sep 17 00:00:00 2001 From: Lutz Date: Mon, 21 Aug 2017 13:40:33 -0500 Subject: [PATCH 4/4] * Rearranged code to prevent boulder from striking Entity from beyond the grave --- src/actboulder.cpp | 163 +++++++++++++++++++++++---------------------- 1 file changed, 84 insertions(+), 79 deletions(-) diff --git a/src/actboulder.cpp b/src/actboulder.cpp index a04c12fc6..e1537c66a 100644 --- a/src/actboulder.cpp +++ b/src/actboulder.cpp @@ -49,38 +49,36 @@ int boulderCheckAgainstEntity(Entity* my, Entity* entity) if ( entityInsideEntity( my, entity ) ) { Stat* stats = entity->getStats(); - if ( stats ) - { - if ( entity->behavior == &actPlayer ) - { - Uint32 color = SDL_MapRGB(mainsurface->format, 255, 0, 0); - messagePlayerColor(entity->skill[2], color, language[455]); - if ( entity->skill[2] == clientnum ) - { - camera_shakex += .1; - camera_shakey += 10; - } - else - { - strcpy((char*)net_packet->data, "SHAK"); - net_packet->data[4] = 10; // turns into .1 - net_packet->data[5] = 10; - net_packet->address.host = net_clients[entity->skill[2] - 1].host; - net_packet->address.port = net_clients[entity->skill[2] - 1].port; - net_packet->len = 6; - sendPacketSafe(net_sock, -1, net_packet, entity->skill[2] - 1); - } - } - playSoundEntity(my, 181, 128); - playSoundEntity(entity, 28, 64); - spawnGib(entity); - entity->modHP(-80); - entity->setObituary(language[1505]); + if ( stats ) + { + if ( entity->behavior == &actPlayer ) + { + Uint32 color = SDL_MapRGB(mainsurface->format, 255, 0, 0); + messagePlayerColor(entity->skill[2], color, language[455]); + if ( entity->skill[2] == clientnum ) + { + camera_shakex += .1; + camera_shakey += 10; + } + else + { + strcpy((char*)net_packet->data, "SHAK"); + net_packet->data[4] = 10; // turns into .1 + net_packet->data[5] = 10; + net_packet->address.host = net_clients[entity->skill[2] - 1].host; + net_packet->address.port = net_clients[entity->skill[2] - 1].port; + net_packet->len = 6; + sendPacketSafe(net_sock, -1, net_packet, entity->skill[2] - 1); + } + } + playSoundEntity(my, 181, 128); + playSoundEntity(entity, 28, 64); + spawnGib(entity); bool bHasLifeSaving = false; if ( entity->behavior == &actPlayer ) { - if ( stats->HP <= 0 ) + if ( (stats->HP - 80) <= 0 ) { steamAchievementClient(entity->skill[2], "BARONY_ACH_THROW_ME_THE_WHIP"); if ( stats->amulet->type == AMULET_LIFESAVING ) @@ -90,62 +88,69 @@ int boulderCheckAgainstEntity(Entity* my, Entity* entity) } } // If the Entity survives, or it is a Player wearing an Amulet of Life Saving, destroy the boulder - if ( stats->HP > 0 || bHasLifeSaving == true ) - { - // spawn several rock items - int i = 8 + rand() % 4; + if ( stats->HP > 0 || bHasLifeSaving == true ) + { + // spawn several rock items + int i = 8 + rand() % 4; - int c; - for ( c = 0; c < i; c++ ) - { - Entity* entity = newEntity(-1, 1, map.entities); - entity->flags[INVISIBLE] = true; - entity->flags[UPDATENEEDED] = true; - entity->x = my->x - 4 + rand() % 8; - entity->y = my->y - 4 + rand() % 8; - entity->z = -6 + rand() % 12; - entity->sizex = 4; - entity->sizey = 4; - entity->yaw = rand() % 360 * PI / 180; - entity->vel_x = (rand() % 20 - 10) / 10.0; - entity->vel_y = (rand() % 20 - 10) / 10.0; - entity->vel_z = -.25 - (rand() % 5) / 10.0; - entity->flags[PASSABLE] = true; - entity->behavior = &actItem; - entity->flags[USERFLAG1] = true; // no collision: helps performance - entity->skill[10] = GEM_ROCK; // type - entity->skill[11] = WORN; // status - entity->skill[12] = 0; // beatitude - entity->skill[13] = 1; // count - entity->skill[14] = 0; // appearance - entity->skill[15] = false; // identified - } + int c; + for ( c = 0; c < i; c++ ) + { + Entity* entity = newEntity(-1, 1, map.entities); + entity->flags[INVISIBLE] = true; + entity->flags[UPDATENEEDED] = true; + entity->x = my->x - 4 + rand() % 8; + entity->y = my->y - 4 + rand() % 8; + entity->z = -6 + rand() % 12; + entity->sizex = 4; + entity->sizey = 4; + entity->yaw = rand() % 360 * PI / 180; + entity->vel_x = (rand() % 20 - 10) / 10.0; + entity->vel_y = (rand() % 20 - 10) / 10.0; + entity->vel_z = -.25 - (rand() % 5) / 10.0; + entity->flags[PASSABLE] = true; + entity->behavior = &actItem; + entity->flags[USERFLAG1] = true; // no collision: helps performance + entity->skill[10] = GEM_ROCK; // type + entity->skill[11] = WORN; // status + entity->skill[12] = 0; // beatitude + entity->skill[13] = 1; // count + entity->skill[14] = 0; // appearance + entity->skill[15] = false; // identified + } - double ox = my->x; - double oy = my->y; + double ox = my->x; + double oy = my->y; - // destroy the boulder - playSoundEntity(my, 67, 128); - list_RemoveNode(my->mynode); + // destroy the boulder + playSoundEntity(my, 67, 128); + list_RemoveNode(my->mynode); - // on sokoban, destroying boulders spawns scorpions - if ( !strcmp(map.name, "Sokoban") ) - { - Entity* monster = summonMonster(SCORPION, ox, oy); - if ( monster ) - { - int c; - for ( c = 0; c < MAXPLAYERS; c++ ) - { - Uint32 color = SDL_MapRGB(mainsurface->format, 255, 128, 0); - messagePlayerColor(c, color, language[406]); - } - } - } + // on sokoban, destroying boulders spawns scorpions + if ( !strcmp(map.name, "Sokoban") ) + { + Entity* monster = summonMonster(SCORPION, ox, oy); + if ( monster ) + { + int c; + for ( c = 0; c < MAXPLAYERS; c++ ) + { + Uint32 color = SDL_MapRGB(mainsurface->format, 255, 128, 0); + messagePlayerColor(c, color, language[406]); // "You have angered the gods of Sokoban!" + } + } + } - return 1; - } - } + // Damage the Entity after destroying the boulder to prevent being hit twice + entity->modHP(-80); + entity->setObituary(language[1505]); // "fails to dodge the incoming boulder." + + return 1; + } + // Damage the Entity after checking if the boulder would be destroyed + entity->modHP(-80); + entity->setObituary(language[1505]); // "fails to dodge the incoming boulder." + } } } else if ( entity->behavior == &actGate || entity->behavior == &actBoulder || entity->behavior == &actChest || entity->behavior == &actHeadstone || entity->behavior == &actFountain || entity->behavior == &actSink )