diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/map/clif.cpp | 6 | ||||
-rw-r--r-- | src/map/map.cpp | 17 | ||||
-rw-r--r-- | src/map/map.hpp | 3 | ||||
-rw-r--r-- | src/map/npc.cpp | 3 | ||||
-rw-r--r-- | src/map/pc.cpp | 20 | ||||
-rw-r--r-- | src/map/script-fun.cpp | 35 | ||||
-rw-r--r-- | src/map/storage.cpp | 3 | ||||
-rw-r--r-- | src/mmo/clif.t.hpp | 2 | ||||
-rw-r--r-- | src/shared/lib.cpp | 28 |
9 files changed, 100 insertions, 17 deletions
diff --git a/src/map/clif.cpp b/src/map/clif.cpp index a5bb2ba..6381c09 100644 --- a/src/map/clif.cpp +++ b/src/map/clif.cpp @@ -4620,7 +4620,8 @@ RecvResult clif_parse_DropItem(Session *s, dumb_ptr<map_session_data> sd) OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[fixed.ioff2.unshift()]) { - if (bool(sdidn->mode & ItemMode::NO_DROP)) + GmLevel gmlvl = pc_isGM(sd); + if (bool(sdidn->mode & ItemMode::NO_DROP) && gmlvl.get_all_bits() < 60) { clif_displaymessage(sd->sess, "This item can't be dropped."_s); return rv; @@ -4909,7 +4910,8 @@ RecvResult clif_parse_TradeAddItem(Session *s, dumb_ptr<map_session_data> sd) if (fixed.zeny_or_ioff2.ok()) OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[fixed.zeny_or_ioff2.unshift()]) { - if (bool(sdidn->mode & ItemMode::NO_TRADE)) + GmLevel gmlvl = pc_isGM(sd); + if (bool(sdidn->mode & ItemMode::NO_TRADE) && gmlvl.get_all_bits() < 60) { clif_displaymessage(sd->sess, "This item can't be traded."_s); return rv; diff --git a/src/map/map.cpp b/src/map/map.cpp index ff69a56..f8e8bea 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -1241,6 +1241,20 @@ int map_setipport(MapName name, IP4Address ip, int port) } /*========================================== + * creates a hash of a map name + *------------------------------------------ + */ +int map_create_hash(XString str) { + const int k = 67; + const int m = 3067; + int hash = 0; + for (int i = 0; i < str.size(); i++) { + hash += (str[i] * (int)pow(k, i)) % m; + } + return hash; +} + +/*========================================== * マップ1枚読み込み *------------------------------------------ */ @@ -1265,6 +1279,9 @@ bool map_readmap(map_local *m, size_t num, MapName fn) m->npc_num = 0; m->users = 0; + + m->hash = map_create_hash(fn); + really_memzero_this(&m->flag); if (battle_config.pk_mode) m->flag.set(MapFlag::PVP, 1); diff --git a/src/map/map.hpp b/src/map/map.hpp index 56d07a5..8bb5aa7 100644 --- a/src/map/map.hpp +++ b/src/map/map.hpp @@ -184,7 +184,7 @@ struct map_session_data : block_list, SessionData None, None, None, None, None, None, None, None, None, None, }}; // explicit is better than implicit earray<IOff0, EQUIP, EQUIP::COUNT> equip_index_maybe; - int weight, max_weight; + int weight, max_weight, max_weight_override; MapName mapname_; Session *sess; // use this, you idiots! short to_x, to_y; @@ -531,6 +531,7 @@ struct map_local : map_abstract Point save; Point resave; int mask; + int hash; Array<dumb_ptr<npc_data>, MAX_NPC_PER_MAP> npc; }; diff --git a/src/map/npc.cpp b/src/map/npc.cpp index a6d3dda..0a7bfc2 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -1006,7 +1006,8 @@ int npc_selllist(dumb_ptr<map_session_data> sd, OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[item_list[i].ioff2.unshift()]) { - if (bool(sdidn->mode & ItemMode::NO_SELL_TO_NPC)) + GmLevel gmlvl = pc_isGM(sd); + if (bool(sdidn->mode & ItemMode::NO_SELL_TO_NPC) && gmlvl.get_all_bits() < 60) { //clif_displaymessage(sd->sess, "This item can't be sold to an NPC."_s); // M+ already outputs "Unable to sell unsellable item." on return value 3. diff --git a/src/map/pc.cpp b/src/map/pc.cpp index b6bce38..d28dda4 100644 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -870,6 +870,7 @@ int pc_authok(AccountId id, int login_id2, ClientVersion client_version, sd->quick_regeneration_hp.amount = 0; sd->quick_regeneration_sp.amount = 0; sd->heal_xp = 0; + sd->max_weight_override = 0; sd->canact_tick = tick; sd->canmove_tick = tick; sd->attackabletime = tick; @@ -1483,6 +1484,9 @@ int pc_calcstatus(dumb_ptr<map_session_data> sd, int first) sd->hit += skill_power(sd, SkillID::AC_OWL) / 10; // 20 for 200 } + if (sd->max_weight_override) + sd->max_weight = sd->max_weight_override; + sd->max_weight += 1000; bl = sd->status.base_level; @@ -1894,6 +1898,14 @@ int pc_bonus(dumb_ptr<map_session_data> sd, SP type, int val) if (!sd->state.lr_flag_is_arrow_2) sd->base_weapon_delay_adjust += interval_t(val); break; + case SP::MAXWEIGHT: + if (!sd->state.lr_flag_is_arrow_2) + sd->max_weight = val; + break; + case SP::MAXWEIGHT_ADD: + if (!sd->state.lr_flag_is_arrow_2) + sd->max_weight += val; + break; default: if (battle_config.error_log) PRINTF("pc_bonus: unknown type %d %d !\n"_fmt, @@ -3721,6 +3733,9 @@ int pc_readparam(dumb_ptr<block_list> bl, SP type) case SP::MAXWEIGHT: val = sd ? sd->max_weight : 0; break; + case SP::MAXWEIGHT_OVERRIDE: + val = sd ? sd->max_weight_override : 0; + break; case SP::BASEEXP: val = sd ? sd->status.base_exp : 0; break; @@ -4048,6 +4063,11 @@ int pc_setparam(dumb_ptr<block_list> bl, SP type, int val) sd->max_weight = val; clif_updatestatus(sd, type); break; + case SP::MAXWEIGHT_OVERRIDE: + nullpo_retz(sd); + sd->max_weight_override = val; + pc_calcstatus(sd, (int)CalcStatusKind::NORMAL_RECALC); + break; case SP::HP: nullpo_retz(sd); // TODO: mob mutation diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index 1efa006..74a70b3 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -5524,6 +5524,39 @@ void builtin_getmapmaxy(ScriptState *st) } /*========================================== + * Get the hash of a map + *------------------------------------------ + */ +static +void builtin_getmaphash(ScriptState *st) +{ + MapName mapname = stringish<MapName>(ZString(conv_str(st, &AARG(0)))); + P<map_local> m = TRY_UNWRAP(map_mapname2mapid(mapname), return); + push_int<ScriptDataInt>(st->stack, m->hash); +} + +/*========================================== + * Get the map name from a hash + *------------------------------------------ + */ +static +void builtin_getmapnamefromhash(ScriptState *st) +{ + int hash = conv_num(st, &AARG(0)); + MapName mapname; + for (auto& mit : maps_db) + { + map_local *ml = static_cast<map_local *>(mit.second.get()); + if (ml->hash == hash) + { + mapname = ml->name_; + break; + } + } + push_str<ScriptDataStr>(st->stack, mapname); +} + +/*========================================== * Get the NPC's info *------------------------------------------ */ @@ -5787,6 +5820,8 @@ BuiltinFunction builtin_functions[] = BUILTIN(getmap, "?"_s, 's'), BUILTIN(getmapmaxx, "M"_s, 'i'), BUILTIN(getmapmaxy, "M"_s, 'i'), + BUILTIN(getmaphash, "M"_s, 'i'), + BUILTIN(getmapnamefromhash, "i"_s, 's'), BUILTIN(mapexit, ""_s, '\0'), BUILTIN(freeloop, "i"_s, '\0'), BUILTIN(if_then_else, "iii"_s, 'v'), diff --git a/src/map/storage.cpp b/src/map/storage.cpp index cab3f0f..dc1fe62 100644 --- a/src/map/storage.cpp +++ b/src/map/storage.cpp @@ -188,7 +188,8 @@ int storage_storageadd(dumb_ptr<map_session_data> sd, IOff0 index, int amount) OMATCH_BEGIN_SOME (sdidn, sd->inventory_data[index]) { - if (bool(sdidn->mode & ItemMode::NO_STORAGE)) + GmLevel gmlvl = pc_isGM(sd); + if (bool(sdidn->mode & ItemMode::NO_STORAGE) && gmlvl.get_all_bits() < 60) { clif_displaymessage(sd->sess, "This item can't be stored."_s); return 0; diff --git a/src/mmo/clif.t.hpp b/src/mmo/clif.t.hpp index f8350a7..c1f7ed3 100644 --- a/src/mmo/clif.t.hpp +++ b/src/mmo/clif.t.hpp @@ -265,6 +265,8 @@ enum class SP : uint16_t WEIGHT = 24, // sent to client MAXWEIGHT = 25, + MAXWEIGHT_ADD = 26, + MAXWEIGHT_OVERRIDE = 27, // sent to client USTR = 32, diff --git a/src/shared/lib.cpp b/src/shared/lib.cpp index d7d1a4e..c0a4371 100644 --- a/src/shared/lib.cpp +++ b/src/shared/lib.cpp @@ -35,35 +35,35 @@ namespace tmwa { static - void try_read(const io::DirFd& dirfd, ZString filename) + void try_read(const io::DirFd& dirfd, LString dir_path, ZString filename) { io::ReadFile rf(dirfd, filename); if (!rf.is_open()) { - FPRINTF(stderr, "Could not open %s\n"_fmt, filename); + FPRINTF(stderr, "Could not open %s/%s\n"_fmt, dir_path, filename); abort(); } AString line; if (!rf.getline(line)) { - FPRINTF(stderr, "Could not read from %s\n"_fmt, filename); + FPRINTF(stderr, "Could not read from %s/%s\n"_fmt, dir_path, filename); abort(); } } static - void try_write(const io::DirFd& dirfd, ZString filename) + void try_write(const io::DirFd& dirfd, LString dir_path, ZString filename) { io::WriteFile wf(dirfd, filename); if (!wf.is_open()) { - FPRINTF(stderr, "Could not open %s\n"_fmt, filename); + FPRINTF(stderr, "Could not open %s/%s\n"_fmt, dir_path, filename); abort(); } wf.put_line("Hello, World!"_s); if (!wf.close()) { - FPRINTF(stderr, "Could not write to %s\n"_fmt, filename); + FPRINTF(stderr, "Could not write to %s/%s\n"_fmt, dir_path, filename); abort(); } } @@ -77,13 +77,17 @@ namespace tmwa io::DirFd root(portable_root); - io::DirFd etc(root, PACKAGESYSCONFDIR.xslice_t(portable)); - io::DirFd var(root, PACKAGELOCALSTATEDIR.xslice_t(portable)); - io::DirFd share(root, PACKAGEDATADIR.xslice_t(portable)); + LString etc_path = PACKAGESYSCONFDIR.xslice_t(portable); + LString var_path = PACKAGELOCALSTATEDIR.xslice_t(portable); + LString share_path = PACKAGEDATADIR.xslice_t(portable); - try_read(etc, "shared.conf"_s); - try_read(share, "shared.data"_s); - try_write(var, "shared.test"_s); + io::DirFd etc(root, etc_path); + io::DirFd var(root, var_path); + io::DirFd share(root, share_path); + + try_read(etc, etc_path, "shared.conf"_s); + try_read(share, share_path, "shared.data"_s); + try_write(var, var_path, "shared.test"_s); // io::FD::open(); } |