From 4049a0c3be7ea5a5240d0a5b59fdea218b7ff3d0 Mon Sep 17 00:00:00 2001 From: Steve Dudenhoeffer Date: Sat, 26 Apr 2008 21:40:56 +0000 Subject: [PATCH] Initial addition of ns_remove_upgrade (amb1635): oh god I hope this will suffice --- dlls/ns/natives/player_memory.cpp | 96 ++++++++++++++++++++++++++++++- dlls/ns/ns_const.h | 7 +++ plugins/include/ns.inc | 17 ++++++ 3 files changed, 118 insertions(+), 2 deletions(-) diff --git a/dlls/ns/natives/player_memory.cpp b/dlls/ns/natives/player_memory.cpp index dfd456dd..66fe5c2f 100644 --- a/dlls/ns/natives/player_memory.cpp +++ b/dlls/ns/natives/player_memory.cpp @@ -318,7 +318,99 @@ static cell AMX_NATIVE_CALL ns_get_hive_ability(AMX *amx, cell *params) return (params[2] > 0) ? (result >= params[2] - 1) : result; } +static cell AMX_NATIVE_CALL ns_remove_upgrade(AMX *amx, cell *params) +{ + CreatePlayerPointer(amx, params[1]); + if (!GameMan.IsCombat()) + { + return 0; + } + + if (!player->IsConnected() || !player->HasPrivateData()) + { + return 0; + } + + // Upgrades are stored in a std::vector in the player's private data + // The integer value represents the impulse for the offset + // std::vector's memory layout is: + // void *start + // void *lastobject + // void *lastreserved + struct upgradevector + { + int *start; + int *end; + int *allocated; + + inline int size() { return static_cast((reinterpret_cast(end) - reinterpret_cast(start)) / sizeof(int)); } + inline int at(int which) { return start[which]; } + inline void set(int which, int val) { start[which] = val; } + inline bool remove(int val) + { + + for (int i = 0; i < this->size(); i++) + { + if (this->at(i) == val) + { + + int last = this->size() - 1; + while (i < last) + { + this->set(i, this->at(i + 1)); + + i++; + } + + this->end--; + + return true; + } + } + + return false; + } + inline void print() + { + printf("size: %d values: ", this->size()); + for (int i = 0; i < this->size(); i++) + { + if (i != 0) + printf(", "); + + printf("%d", this->at(i)); + } + printf("\n"); + } + }; + + + upgradevector *bought = reinterpret_cast(reinterpret_cast(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(UPGRADES_BOUGHT)); + upgradevector *active = reinterpret_cast(reinterpret_cast(player->GetEdict()->pvPrivateData) + MAKE_OFFSET(UPGRADES_ACTIVE)); + + + //bought->print(); + //active->print(); + + bool bfound = bought->remove(params[2]); + bool afound = active->remove(params[2]); + + if (bfound) + { + if (afound) + { + return 2; + } + return 1; + } + if (afound) + { + // shouldn't happen, but just incase + return 3; + } + return 0; +} AMX_NATIVE_INFO player_memory_natives[] = { @@ -343,9 +435,9 @@ AMX_NATIVE_INFO player_memory_natives[] = { { "ns_set_deaths", ns_set_deaths }, { "ns_add_deaths", ns_add_deaths }, - { "ns_get_hive_ability", ns_get_hive_ability}, - + { "ns_get_hive_ability", ns_get_hive_ability }, + { "ns_remove_upgrade", ns_remove_upgrade }, { NULL, NULL } }; diff --git a/dlls/ns/ns_const.h b/dlls/ns/ns_const.h index 90337c94..3de02c1d 100755 --- a/dlls/ns/ns_const.h +++ b/dlls/ns/ns_const.h @@ -137,6 +137,13 @@ #define OFFSET_LIN_GAMEPLAY_TEAMB 0x68 +#define OFFSET_WIN_UPGRADES_BOUGHT 0x1980 +#define OFFSET_LIN_UPGRADES_BOUGHT 0x1994 + +#define OFFSET_WIN_UPGRADES_ACTIVE 0x198C +#define OFFSET_LIN_UPGRADES_ACTIVE 0x19A0 + + // TODO: Symbols / signatures instead // Not actually offsets, but easier to use MAKE_OFFSET stuff for this :o // First functions listed in the disassembler diff --git a/plugins/include/ns.inc b/plugins/include/ns.inc index 6bbff8f0..fbcfa025 100755 --- a/plugins/include/ns.inc +++ b/plugins/include/ns.inc @@ -663,6 +663,23 @@ native Float:ns_add_weld_done(idWeldable,Float:value); native Float:ns_get_obs_energy(idObs); native ns_set_obs_energy(idObs,Float:value); native Float:ns_add_obs_energy(idObs,Float:value); + +/** + * Removes an upgrade from the player's bought and active upgrade lists. + * This will not refund the points spent on the upgrade, nor will it + * immediately strip the upgrade if the player is alive. Rather, it will + * make it so the player no longer receives the upgrade on spawn. + * + * @note This only works in combat. + * @params idPlayer The player index to change upgrades for. + * @params ugprade The impulse number for the upgrade to strip. + * @return 2 for upgrade removed from player's bought and active list. + * 1 for upgrade removed from player's bought list only. + * 3 for upgrade removed from player's active list only (shouldn't happen, just incase.) + * 0 for the player didn't have the upgrade in either list. + */ +native ns_remove_upgrade(idPlayer, upgrade); + /** * Particle system natives * -