summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/map/clif.cpp6
-rw-r--r--src/map/map.cpp17
-rw-r--r--src/map/map.hpp3
-rw-r--r--src/map/npc.cpp3
-rw-r--r--src/map/pc.cpp20
-rw-r--r--src/map/script-fun.cpp35
-rw-r--r--src/map/storage.cpp3
-rw-r--r--src/mmo/clif.t.hpp2
-rw-r--r--src/shared/lib.cpp28
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();
}