Advertisement
Guest User

AutoPickupGold

a guest
Jul 2nd, 2018
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.97 KB | None | 0 0
  1. void NPC::Killed(Character *from, int amount, int spell_id)
  2. {
  3.     double droprate = this->map->world->config["DropRate"];
  4.     double exprate = this->map->world->config["ExpRate"];
  5.     int sharemode = this->map->world->config["ShareMode"];
  6.     int partysharemode = this->map->world->config["PartyShareMode"];
  7.     int dropratemode = this->map->world->config["DropRateMode"];
  8.     std::set<Party *> parties;
  9.  
  10.     int most_damage_counter = 0;
  11.     Character *most_damage = nullptr;
  12.     NPC_Drop *drop = nullptr;
  13.  
  14.     this->alive = false;
  15.  
  16.     this->dead_since = int(Timer::GetTime());
  17.  
  18.     if (dropratemode == 1)
  19.     {
  20.         std::vector<NPC_Drop *> drops;
  21.  
  22.         UTIL_FOREACH_CREF(this->Data().drops, checkdrop)
  23.         {
  24.             if (util::rand(0.0, 100.0) <= checkdrop->chance * droprate)
  25.             {
  26.                 drops.push_back(checkdrop.get());
  27.             }
  28.         }
  29.  
  30.         if (drops.size() > 0)
  31.         {
  32.             drop = drops[util::rand(0, drops.size()-1)];
  33.         }
  34.     }
  35.     else if (dropratemode == 2)
  36.     {
  37.         UTIL_FOREACH_CREF(this->Data().drops, checkdrop)
  38.         {
  39.             if (util::rand(0.0, 100.0) <= checkdrop->chance * droprate)
  40.             {
  41.                 drop = checkdrop.get();
  42.                 break;
  43.             }
  44.         }
  45.     }
  46.     else if (dropratemode == 3)
  47.     {
  48.         double roll = util::rand(0.0, this->Data().drops_chance_total);
  49.  
  50.         UTIL_FOREACH_CREF(this->Data().drops, checkdrop)
  51.         {
  52.             if (roll >= checkdrop->chance_offset && roll < checkdrop->chance_offset+checkdrop->chance)
  53.             {
  54.                 drop = checkdrop.get();
  55.                 break;
  56.             }
  57.         }
  58.     }
  59.  
  60.     if (sharemode == 1)
  61.     {
  62.         UTIL_FOREACH_CREF(this->damagelist, opponent)
  63.         {
  64.             if (opponent->damage > most_damage_counter)
  65.             {
  66.                 most_damage_counter = opponent->damage;
  67.                 most_damage = opponent->attacker;
  68.             }
  69.         }
  70.     }
  71.  
  72.     int dropuid = 0;
  73.     int dropid = 0;
  74.     int dropamount = 0;
  75.     Character* drop_winner = from;
  76.  
  77.     if (drop)
  78.     {
  79.         dropuid = this->map->GenerateItemID();
  80.         dropid = drop->id;
  81.         dropamount = util::rand(drop->min, drop->max);
  82.  
  83.         // Selects a random number between 0 and maxhp, and decides the winner based on that
  84.         switch (sharemode)
  85.         {
  86.             case 0:
  87.                 drop_winner = from;
  88.                 break;
  89.  
  90.             case 1:
  91.                 drop_winner = most_damage;
  92.                 break;
  93.  
  94.             case 2:
  95.             {
  96.                 int rewarded_hp = util::rand(0, this->totaldamage - 1);
  97.                 int count_hp = 0;
  98.                 UTIL_FOREACH_CREF(this->damagelist, opponent)
  99.                 {
  100.                     if (opponent->attacker->InRange(this))
  101.                     {
  102.                         if (rewarded_hp >= count_hp && rewarded_hp < opponent->damage)
  103.                         {
  104.                             drop_winner = opponent->attacker;
  105.                             break;
  106.                         }
  107.  
  108.                         count_hp += opponent->damage;
  109.                     }
  110.                 }
  111.             }
  112.             break;
  113.  
  114.             case 3:
  115.             {
  116.                 int rand = util::rand(0, this->damagelist.size() - 1);
  117.                 int i = 0;
  118.                 UTIL_FOREACH_CREF(this->damagelist, opponent)
  119.                 {
  120.                     if (opponent->attacker->InRange(this))
  121.                     {
  122.                         if (rand == i++)
  123.                         {
  124.                             drop_winner = opponent->attacker;
  125.                             break;
  126.                         }
  127.                     }
  128.                 }
  129.             }
  130.             break;
  131.         }
  132.  
  133.         int accessory = drop_winner->paperdoll[Character::Accessory];
  134.         int auto_gold_accessory = this->map->world->accesory_config["GoldPickupId"];
  135.  
  136.         bool do_auto_gold = (accessory > 0
  137.                           && accessory == auto_gold_accessory);
  138.  
  139.         if (do_auto_gold && drop->id == 1)
  140.         {
  141.             if (drop_winner->AddItem(dropid, dropamount))
  142.             {
  143.                 PacketBuilder reply(PACKET_ITEM, PACKET_GET);
  144.                 reply.AddShort(0);
  145.                 reply.AddShort(dropid);
  146.                 reply.AddThree(dropamount);
  147.                 reply.AddChar(from->weight);
  148.                 reply.AddChar(from->maxweight);
  149.                 drop_winner->Send(reply);
  150.             }
  151.  
  152.             dropuid = 0;
  153.             dropid = 0;
  154.             dropamount = 0;
  155.         }
  156.         else
  157.         {
  158.             std::shared_ptr<Map_Item> newitem(std::make_shared<Map_Item>(dropuid, dropid, dropamount, this->x, this->y, drop_winner->PlayerID(), Timer::GetTime() + static_cast<int>(this->map->world->config["ProtectNPCDrop"])));
  159.             this->map->items.push_back(newitem);
  160.         }
  161.     }
  162.  
  163.     UTIL_FOREACH(this->map->characters, character)
  164.     {
  165.         std::list<std::unique_ptr<NPC_Opponent>>::iterator findopp = this->damagelist.begin();
  166.         for (; findopp != this->damagelist.end() && (*findopp)->attacker != character; ++findopp); // no loop body
  167.  
  168.         if (findopp != this->damagelist.end() || character->InRange(this))
  169.         {
  170.             bool level_up = false;
  171.  
  172.             PacketBuilder builder(spell_id == -1 ? PACKET_NPC : PACKET_CAST, PACKET_SPEC, 26);
  173.  
  174.             if (this->ENF().exp != 0)
  175.             {
  176.                 if (findopp != this->damagelist.end())
  177.                 {
  178.                     int reward;
  179.                     switch (sharemode)
  180.                     {
  181.                         case 0:
  182.                             if (character == from)
  183.                             {
  184.                                 reward = int(std::ceil(double(this->ENF().exp) * exprate));
  185.  
  186.                                 if (reward > 0)
  187.                                 {
  188.                                     if (partysharemode)
  189.                                     {
  190.                                         if (character->party)
  191.                                         {
  192.                                             character->party->ShareEXP(reward, partysharemode, this->map);
  193.                                         }
  194.                                         else
  195.                                         {
  196.                                             character->exp += reward;
  197.                                         }
  198.                                     }
  199.                                     else
  200.                                     {
  201.                                         character->exp += reward;
  202.                                     }
  203.                                 }
  204.                             }
  205.                             break;
  206.  
  207.                         case 1:
  208.                             if (character == most_damage)
  209.                             {
  210.                                 reward = int(std::ceil(double(this->ENF().exp) * exprate));
  211.  
  212.                                 if (reward > 0)
  213.                                 {
  214.                                     if (partysharemode)
  215.                                     {
  216.                                         if (character->party)
  217.                                         {
  218.                                             character->party->ShareEXP(reward, partysharemode, this->map);
  219.                                         }
  220.                                         else
  221.                                         {
  222.                                             character->exp += reward;
  223.                                         }
  224.                                     }
  225.                                     else
  226.                                     {
  227.                                         character->exp += reward;
  228.                                     }
  229.                                 }
  230.                             }
  231.                             break;
  232.  
  233.                         case 2:
  234.                             reward = int(std::ceil(double(this->ENF().exp) * exprate * (double((*findopp)->damage) / double(this->totaldamage))));
  235.  
  236.                             if (reward > 0)
  237.                             {
  238.                                 if (partysharemode)
  239.                                 {
  240.                                     if (character->party)
  241.                                     {
  242.                                         character->party->temp_expsum += reward;
  243.                                         parties.insert(character->party);
  244.                                     }
  245.                                     else
  246.                                     {
  247.                                         character->exp += reward;
  248.                                     }
  249.                                 }
  250.                                 else
  251.                                 {
  252.                                     character->exp += reward;
  253.                                 }
  254.                             }
  255.                             break;
  256.  
  257.                         case 3:
  258.                             reward = int(std::ceil(double(this->ENF().exp) * exprate * (double(this->damagelist.size()) / 1.0)));
  259.  
  260.                             if (reward > 0)
  261.                             {
  262.                                 if (partysharemode)
  263.                                 {
  264.                                     if (character->party)
  265.                                     {
  266.                                         character->party->temp_expsum += reward;
  267.                                     }
  268.                                     else
  269.                                     {
  270.                                         character->exp += reward;
  271.                                     }
  272.                                 }
  273.                                 else
  274.                                 {
  275.                                     character->exp += reward;
  276.                                 }
  277.                             }
  278.                             break;
  279.                     }
  280.  
  281.                     character->exp = std::min(character->exp, static_cast<int>(this->map->world->config["MaxExp"]));
  282.  
  283.                     while (character->level < static_cast<int>(this->map->world->config["MaxLevel"]) && character->exp >= this->map->world->exp_table[character->level+1])
  284.                     {
  285.                         level_up = true;
  286.                         ++character->level;
  287.                         character->statpoints += static_cast<int>(this->map->world->config["StatPerLevel"]);
  288.                         character->skillpoints += static_cast<int>(this->map->world->config["SkillPerLevel"]);
  289.                         character->CalculateStats();
  290.                     }
  291.  
  292.                     if (level_up)
  293.                     {
  294.                         builder.SetID(spell_id == -1 ? PACKET_NPC : PACKET_CAST, PACKET_ACCEPT);
  295.                         builder.ReserveMore(33);
  296.                     }
  297.                 }
  298.             }
  299.  
  300.             if (spell_id != -1)
  301.                 builder.AddShort(spell_id);
  302.  
  303.             builder.AddShort(drop_winner->PlayerID());
  304.             builder.AddChar(drop_winner->direction);
  305.             builder.AddShort(this->index);
  306.             builder.AddShort(dropuid);
  307.             builder.AddShort(dropid);
  308.             builder.AddChar(this->x);
  309.             builder.AddChar(this->y);
  310.             builder.AddInt(dropamount);
  311.             builder.AddThree(amount);
  312.  
  313.             if (spell_id != -1)
  314.                 builder.AddShort(from->tp);
  315.  
  316.             if ((sharemode == 0 && character == from) || (sharemode != 0 && findopp != this->damagelist.end()))
  317.             {
  318.                 builder.AddInt(character->exp);
  319.             }
  320.  
  321.             if (level_up)
  322.             {
  323.                 builder.AddChar(character->level);
  324.                 builder.AddShort(character->statpoints);
  325.                 builder.AddShort(character->skillpoints);
  326.                 builder.AddShort(character->maxhp);
  327.                 builder.AddShort(character->maxtp);
  328.                 builder.AddShort(character->maxsp);
  329.             }
  330.  
  331.             character->Send(builder);
  332.         }
  333.     }
  334.  
  335.     UTIL_FOREACH(parties, party)
  336.     {
  337.         party->ShareEXP(party->temp_expsum, partysharemode, this->map);
  338.         party->temp_expsum = 0;
  339.     }
  340.  
  341.     UTIL_FOREACH_CREF(this->damagelist, opponent)
  342.     {
  343.         opponent->attacker->unregister_npc.erase(
  344.             std::remove(UTIL_RANGE(opponent->attacker->unregister_npc), this),
  345.             opponent->attacker->unregister_npc.end()
  346.         );
  347.     }
  348.  
  349.     this->damagelist.clear();
  350.     this->totaldamage = 0;
  351.  
  352.     short childid = -1;
  353.  
  354.     if (this->ENF().boss)
  355.     {
  356.         std::vector<NPC*> child_npcs;
  357.  
  358.         UTIL_FOREACH(this->map->npcs, npc)
  359.         {
  360.             if (npc->ENF().child && !npc->ENF().boss && npc->alive)
  361.             {
  362.                 child_npcs.push_back(npc);
  363.             }
  364.         }
  365.  
  366.         UTIL_FOREACH(child_npcs, npc)
  367.         {
  368.             if (!npc->temporary && (childid == -1 || childid == npc->id))
  369.             {
  370.                 npc->Die(false);
  371.                 childid = npc->id;
  372.             }
  373.             else
  374.             {
  375.                 npc->Die(true);
  376.             }
  377.         }
  378.     }
  379.  
  380.     if (childid != -1)
  381.     {
  382.         PacketBuilder builder(PACKET_NPC, PACKET_JUNK, 2);
  383.         builder.AddShort(childid);
  384.  
  385.         UTIL_FOREACH(this->map->characters, character)
  386.         {
  387.             character->Send(builder);
  388.         }
  389.     }
  390.  
  391.     if (this->temporary)
  392.     {
  393.         this->map->npcs.erase(
  394.             std::remove(this->map->npcs.begin(), this->map->npcs.end(), this),
  395.             this->map->npcs.end()
  396.         );
  397.     }
  398.  
  399.     UTIL_FOREACH(from->quests, q)
  400.     {
  401.         if (!q.second || q.second->GetQuest()->Disabled())
  402.             continue;
  403.  
  404.         q.second->KilledNPC(this->ENF().id);
  405.     }
  406.  
  407.     if (this->temporary)
  408.     {
  409.         delete this;
  410.         return;
  411.     }
  412. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement