Follow up to 2fc7472
Fixed an issue with random calculation on abra in some cases. Moved some commonly used functions into util and yaml database for global usage. Thanks to @Daegaladh and @aleos89
This commit is contained in:
@@ -249,6 +249,10 @@ bool YamlDatabase::asUInt16Rate( const YAML::Node& node, const std::string& name
|
||||
if( out > maximum ){
|
||||
this->invalidWarning( node[name], "Node \"%s\" with value %" PRIu16 " exceeds maximum of %" PRIu16 ".\n", name.c_str(), out, maximum );
|
||||
|
||||
return false;
|
||||
}else if( out == 0 ){
|
||||
this->invalidWarning( node[name], "Node \"%s\" needs to be at least 1.\n", name.c_str() );
|
||||
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
@@ -263,6 +267,10 @@ bool YamlDatabase::asUInt32Rate( const YAML::Node& node, const std::string& name
|
||||
if( out > maximum ){
|
||||
this->invalidWarning( node[name], "Node \"%s\" with value %" PRIu32 " exceeds maximum of %" PRIu32 ".\n", name.c_str(), out, maximum );
|
||||
|
||||
return false;
|
||||
}else if( out == 0 ){
|
||||
this->invalidWarning( node[name], "Node \"%s\" needs to be at least 1.\n", name.c_str() );
|
||||
|
||||
return false;
|
||||
}else{
|
||||
return true;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "cbasetypes.hpp"
|
||||
#include "core.hpp"
|
||||
#include "utilities.hpp"
|
||||
|
||||
class YamlDatabase{
|
||||
// Internal stuff
|
||||
@@ -84,6 +85,10 @@ public:
|
||||
this->data.clear();
|
||||
}
|
||||
|
||||
bool empty(){
|
||||
return this->data.empty();
|
||||
}
|
||||
|
||||
bool exists( keytype key ){
|
||||
return this->find( key ) != nullptr;
|
||||
}
|
||||
@@ -113,6 +118,14 @@ public:
|
||||
size_t size(){
|
||||
return this->data.size();
|
||||
}
|
||||
|
||||
std::shared_ptr<datatype> random(){
|
||||
if( this->empty() ){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return rathena::util::umap_random( this->data );
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* DATABASE_HPP */
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "cbasetypes.hpp"
|
||||
#include "random.hpp"
|
||||
|
||||
// Class used to perform time measurement
|
||||
class cScopeTimer {
|
||||
@@ -120,6 +121,19 @@ namespace rathena {
|
||||
else
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a random value from the given map
|
||||
* @param map: Unordered Map to search through
|
||||
* @return A random value by reference
|
||||
*/
|
||||
template <typename K, typename V> V& umap_random( std::unordered_map<K, V>& map ){
|
||||
auto it = map.begin();
|
||||
|
||||
std::advance( it, rnd_value( 0, map.size() - 1 ) );
|
||||
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6410,20 +6410,23 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
break;
|
||||
|
||||
case SA_ABRACADABRA:
|
||||
if (abra_db.size() == 0) {
|
||||
if (abra_db.empty()) {
|
||||
clif_skill_nodamage (src, bl, skill_id, skill_lv, 1);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
int abra_skill_id = 0, abra_skill_lv, checked = 0, checked_max = abra_db.size() * 3;
|
||||
auto abra_spell = abra_db.begin();
|
||||
|
||||
do {
|
||||
std::advance(abra_spell, rnd() % abra_db.size());
|
||||
auto abra_spell = abra_db.random();
|
||||
|
||||
abra_skill_id = abra_spell->second->skill_id;
|
||||
abra_skill_id = abra_spell->skill_id;
|
||||
abra_skill_lv = min(skill_lv, skill_get_max(abra_skill_id));
|
||||
} while (checked++ < checked_max && rnd() % 10000 >= abra_spell->second->per[max(skill_lv - 1, 0)]);
|
||||
|
||||
if( rnd() % 10000 < abra_spell->per[max(skill_lv - 1, 0)] ){
|
||||
break;
|
||||
}
|
||||
} while (checked++ < checked_max);
|
||||
|
||||
if (!skill_get_index(abra_skill_id))
|
||||
break;
|
||||
@@ -21629,11 +21632,6 @@ uint64 AbraDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
if (!this->asUInt16Rate(probNode, "Probability", probability))
|
||||
return 0;
|
||||
|
||||
if (!probability) {
|
||||
this->invalidWarning(probNode["Probability"], "Probability has to be within the range of 1~10000, skipping.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
abra->per.fill(probability);
|
||||
} else {
|
||||
abra->per.fill(0);
|
||||
@@ -21652,11 +21650,6 @@ uint64 AbraDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
if (!this->asUInt16Rate(it, "Probability", probability))
|
||||
continue;
|
||||
|
||||
if (!probability) {
|
||||
this->invalidWarning(it["Probability"], "Probability has to be within the range of 1~10000, skipping.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
abra->per[skill_lv - 1] = probability;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user