// vim: set ts=4 sw=4 tw=99 noet: // // AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO"). // Copyright (C) The AMX Mod X Development Team. // // This software is licensed under the GNU General Public License, version 3 or higher. // Additional exceptions apply. For full license details, see LICENSE.txt or visit: // https://alliedmods.net/amxmodx-license // // Natural Selection Module // #include "amxxmodule.h" #include "ns.h" #include "utilfunctions.h" #include "NEW_Util.h" int IsValidBuilding[AVH_USER3_MAX + 1] = { 0, // AVH_USER3_NONE = 0, 0, // AVH_USER3_MARINE_PLAYER, 0, // AVH_USER3_COMMANDER_PLAYER, 0, // AVH_USER3_ALIEN_PLAYER1, 0, // AVH_USER3_ALIEN_PLAYER2, 0, // AVH_USER3_ALIEN_PLAYER3, 0, // AVH_USER3_ALIEN_PLAYER4, 0, // AVH_USER3_ALIEN_PLAYER5, 0, // AVH_USER3_ALIEN_EMBRYO, 0, // AVH_USER3_SPAWN_TEAMONE, 0, // AVH_USER3_SPAWN_TEAMTWO, 0, // AVH_USER3_PARTICLE_ON, // only valid for AvHParticleEntity: entindex as int in fuser1, template index stored in fuser2 0, // AVH_USER3_PARTICLE_OFF, // only valid for AvHParticleEntity: particle system handle in fuser1 0, // AVH_USER3_WELD, // float progress (0 - 100) stored in fuser1 0, // AVH_USER3_ALPHA, // fuser1 indicates how much alpha this entity toggles to in commander mode, fuser2 for players 0, // AVH_USER3_MARINEITEM, // Something a friendly marine can pick up 0, // AVH_USER3_WAYPOINT, 2, // AVH_USER3_HIVE, 0, // AVH_USER3_NOBUILD, 0, // AVH_USER3_USEABLE, 0, // AVH_USER3_AUDIO_ON, 0, // AVH_USER3_AUDIO_OFF, 0, // AVH_USER3_FUNC_RESOURCE, 1, // AVH_USER3_COMMANDER_STATION, 1, // AVH_USER3_TURRET_FACTORY, 1, // AVH_USER3_ARMORY, 1, // AVH_USER3_ADVANCED_ARMORY, 1, // AVH_USER3_ARMSLAB, 1, // AVH_USER3_PROTOTYPE_LAB, 1, // AVH_USER3_OBSERVATORY, 0, // AVH_USER3_CHEMLAB, 0, // AVH_USER3_MEDLAB, 0, // AVH_USER3_NUKEPLANT, 1, // AVH_USER3_TURRET, 1, // AVH_USER3_SIEGETURRET, 1, // AVH_USER3_RESTOWER, 0, // AVH_USER3_PLACEHOLDER, 1, // AVH_USER3_INFANTRYPORTAL, 0, // AVH_USER3_NUKE, 0, // AVH_USER3_BREAKABLE, 0, // AVH_USER3_UMBRA, 1, // AVH_USER3_PHASEGATE, 2, // AVH_USER3_DEFENSE_CHAMBER, 2, // AVH_USER3_MOVEMENT_CHAMBER, 2, // AVH_USER3_OFFENSE_CHAMBER, 2, // AVH_USER3_SENSORY_CHAMBER, 2, // AVH_USER3_ALIENRESTOWER, 0, // AVH_USER3_HEAVY, 0, // AVH_USER3_JETPACK, 1, // AVH_USER3_ADVANCED_TURRET_FACTORY, 0, // AVH_USER3_SPAWN_READYROOM, 0, // AVH_USER3_CLIENT_COMMAND, 0, // AVH_USER3_FUNC_ILLUSIONARY, 0, // AVH_USER3_MENU_BUILD, 0, // AVH_USER3_MENU_BUILD_ADVANCED, 0, // AVH_USER3_MENU_ASSIST, 0, // AVH_USER3_MENU_EQUIP, 0, // AVH_USER3_MINE, 0 // AVH_USER3_MAX }; // ns_build_structure(idStructure); static cell AMX_NATIVE_CALL ns_build_structure(AMX *amx, cell *params) { // Trick NS into thinking that this structure is being spawned from the map // set the "startbuilt" setting to 1, then remove it. // "startbuilt" is set as "spawnflag" "1" in the ns.fgd CreateNonPlayerEdict(amx,params[1]); if (Entity->free) { return 0; }; if (Entity->v.iuser3 <= AVH_USER3_NONE || Entity->v.iuser3 >= AVH_USER3_MAX) { return 0; } int StructureType=IsValidBuilding[Entity->v.iuser3]; if (StructureType==0) { return 0; } if (Entity->v.iuser3==AVH_USER3_HIVE) { return 0; } // Already set? if (Entity->v.spawnflags & 1) { MDLL_Spawn(Entity); goto undo_ghost; } Entity->v.spawnflags |= 1; MDLL_Spawn(Entity); Entity->v.spawnflags &= ~1; undo_ghost: if (StructureType==1) // marine, remove "ghost" appearance { if (get_private(Entity,MAKE_OFFSET(GHOST_STRUCTURE))!=0) { set_private(Entity,MAKE_OFFSET(GHOST_STRUCTURE),0); Entity->v.rendermode=kRenderNormal; Entity->v.renderamt=100.0; } } return 1; }; #define MASK_ELECTRICITY 8192 static cell AMX_NATIVE_CALL ns_get_build(AMX *amx, cell *params) { int iLength; char *buildtype = MF_GetAmxString(amx,params[1],0,&iLength); int iBuiltOnly = params[2]; int iNumber = params[3]; edict_t* pBuild = NULL; int iCount=0; while ((pBuild = UTIL_FindEntityByString(pBuild,"classname",buildtype)) != NULL) { if (iBuiltOnly > 0) { if (FStrEq("team_advarmory",buildtype) || FStrEq("team_advturretfactory",buildtype)) { iCount++; } else { if (pBuild->v.fuser1 >= 1000 || pBuild->v.iuser4 & MASK_ELECTRICITY) { iCount++; } } } else { iCount++; } if (iNumber > 0 && iCount == iNumber) return ENTINDEX_NEW(pBuild); } return iCount++; } static cell AMX_NATIVE_CALL ns_set_hive_trait(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } set_private(Entity,MAKE_OFFSET(HIVE_TRAIT),static_cast(params[2])); return 1; } static cell AMX_NATIVE_CALL ns_get_hive_trait(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return get_private(Entity,MAKE_OFFSET(HIVE_TRAIT)); } static cell AMX_NATIVE_CALL ns_get_struct_owner(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return get_private(Entity,MAKE_OFFSET(STRUCTOWNER)); } // ns_set_struct_owner(idStructure,idPlayer) - -1 means no owner static cell AMX_NATIVE_CALL ns_set_struct_owner(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (params[2] > gpGlobals->maxClients || params[2] < -1) { return 0; } if (Entity->pvPrivateData == NULL) { return 0; } set_private(Entity,MAKE_OFFSET(STRUCTOWNER),params[2]); return 1; } // Float:ns_get_obs_energy(id); static cell AMX_NATIVE_CALL ns_get_obs_energy(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return amx_ftoc2(get_private(Entity,MAKE_OFFSET(OBS_ENERGY))); }; // Float:ns_set_obs_energy(id,Float:energy); static cell AMX_NATIVE_CALL ns_set_obs_energy(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } set_private_f(Entity,MAKE_OFFSET(OBS_ENERGY),amx_ctof2(params[2])); return 1; }; // Float:ns_add_obs_energy(id,Float:energy); static cell AMX_NATIVE_CALL ns_add_obs_energy(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(OBS_ENERGY),amx_ctof2(params[2]),0.0,100.0)); }; // Float:ns_get_weld_time(idWeldable); static cell AMX_NATIVE_CALL ns_get_weld_time(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return amx_ftoc2(get_private_f(Entity,MAKE_OFFSET(WELD_TIME))); }; // ns_set_weld_time(idWeldable,Float:value); static cell AMX_NATIVE_CALL ns_set_weld_time(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } set_private_f(Entity,MAKE_OFFSET(WELD_TIME),amx_ctof2(params[2])); return 1; }; // Float:ns_add_weld_time(idWeldable,Float:value); static cell AMX_NATIVE_CALL ns_add_weld_time(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(WELD_TIME),amx_ctof2(params[2]),0.0)); }; // Float:ns_get_weld_done(idWeldable); static cell AMX_NATIVE_CALL ns_get_weld_done(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return amx_ftoc2(get_private_f(Entity,MAKE_OFFSET(WELD_DONE))); }; // ns_set_weld_done(idWeldable,Float:value); static cell AMX_NATIVE_CALL ns_set_weld_done(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } set_private_f(Entity,MAKE_OFFSET(WELD_DONE),amx_ctof2(params[2])); return 1; }; // Float:ns_add_weld_done(idWeldable,Float:value); static cell AMX_NATIVE_CALL ns_add_weld_done(AMX *amx, cell *params) { CreateNonPlayerEdict(amx,params[1]); if (Entity->pvPrivateData == NULL) { return 0; } return amx_ftoc2(inc_private_f(Entity,MAKE_OFFSET(WELD_DONE),amx_ctof2(params[2]),0.0)); }; AMX_NATIVE_INFO structure_natives[] = { { "ns_build_structure", ns_build_structure }, { "ns_get_build", ns_get_build }, { "ns_get_hive_trait", ns_get_hive_trait }, { "ns_set_hive_trait", ns_set_hive_trait }, { "ns_get_struct_owner", ns_get_struct_owner }, { "ns_set_struct_owner", ns_set_struct_owner }, { "ns_get_obs_energy", ns_get_obs_energy }, { "ns_set_obs_energy", ns_set_obs_energy }, { "ns_add_obs_energy", ns_add_obs_energy }, { "ns_get_weld_time", ns_get_weld_time }, { "ns_set_weld_time", ns_set_weld_time }, { "ns_add_weld_time", ns_add_weld_time }, { "ns_get_weld_done", ns_get_weld_done }, { "ns_set_weld_done", ns_set_weld_done }, { "ns_add_weld_done", ns_add_weld_done }, /* prototypes for natives i have planned */ //{ "ns_get_phase_target", ns_get_phase_target }, //{ "ns_set_phase_target", ns_set_phase_target }, //{ "ns_set_phase_nextuse", ns_set_phase_nextuse }, //{ "ns_get_phase_nextuse", ns_get_phase_nextuse }, //{ "ns_add_phase_nextuse", ns_add_phase_nextuse }, { NULL, NULL } }; void AddNatives_Structure() { MF_AddNatives(structure_natives); }