Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 14 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,16 @@
# TF2: Sandbox, the gamemode that releashes player's creative head.
# Team Fortress 2 Sandbox
[![Build status](https://ci.appveyor.com/api/projects/status/9a3so69rx377o652?svg=true)](https://ci.appveyor.com/project/LeadKiller/tf2sb/build/artifacts)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
### Information
In Team Fortress 2 Sandbox, players can release their creativity and build things they love. You can roleplay, build bases, make a machinima, start a resturant, build a town, take over a planet in space. The only limit is your imagination!

This is a fork mod of the original BuildMod for HL2DM (https://sourceforge.net/projects/smbuildmod)
### Sandbox Features
- Spawnmenu - The spawnmenu allows you to spawn props. It features categories such as Construction, Comic, Items, Weapons, and HL2.
- Move/Rotate/Scale Props - Use +copy, +move, or even sm_skin to customize your props.
- Physics Gun - The Garry's Mod classic returns here, with a easy way of moving around props, you'll never have issues.
- Tool Gun - Explode everything, customize a prop, or disallow collisions on a prop.
- Noclip - Fly through walls to get where you need to.
- Player Menu - Add conditions or pose yourself.

TF2: Sandbox is a open-source gamemode for Team Fortress 2 that introduces PhysGun, ability to build.

In this game, players can releash their creative head and build things they love, you can roleplay, can build, can do many things like building a parkour, building a house, a restaurant and many more.

General Sandbox Features:
- Spawn Props - Spawn any props in order to build something.
- Physics Gun - This gun lets you to pick up any props, just like in Garry's Mod.
- Tool Gun - Allow you to customize the prop.
- Noclip - Let you to fly around the map (!fly)
- Addcond - Gives you things in addcond, like full crits.
- Set Health (not done yet)
- Set Speed (not done yet)
- Set Model (not done yet)
- Set Pitch (not done yet)

To Do:
- Assign a WeaponID to the Physics Gun.
- Tool Gun
- MSTR Sandbox Messages

Main server:
http://steamcommunity.com/groups/TF2Sandbox

Pull requests are welcome!
### Social Media
You can find links to our Discord, TF2 Server, and Steam Group [here](https://sandbox.moddage.site/).
Binary file removed plugins/TF2Sandbox-AIO.smx
Binary file not shown.
Binary file removed plugins/TF2Sandbox-Core.smx
Binary file not shown.
Binary file removed plugins/disabled/old, do not use/BuildMod.smx
Binary file not shown.
Binary file not shown.
Binary file removed plugins/disabled/old, do not use/BuildMod_Copy.smx
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed plugins/disabled/old, do not use/BuildMod_Grab.smx
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
128 changes: 89 additions & 39 deletions scripting/TF2Sandbox-AIO.sp
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,35 @@
#include <tf2items>
#include <stocklib>
#include <matrixmath>
#include <updater>

//#pragma newdecls required

#define MDL_TOOLGUN "models/weapons/v_crossbow.mdl"
#define SND_TOOLGUN_SHOOT "weapons/357/357_fire2.wav"
#define SND_TOOLGUN_SHOOT2 "weapons/357/357_fire3.wav"
#define MDL_TOOLGUN "models/weapons/v_357.mdl"
#define SND_TOOLGUN_SHOOT "weapons/airboat/airboat_gun_lastshot1.wav"
#define SND_TOOLGUN_SHOOT2 "weapons/airboat/airboat_gun_lastshot2.wav"
#define SND_TOOLGUN_SELECT "buttons/button15.wav"

#define UPDATE_URL "https://sandbox.moddage.site/plugin/updater.txt"

// Toolgun
#define EF_BONEMERGE (1 << 0)
#define EF_BONEMERGE_FASTCULL (1 << 7)

new Handle:g_hSdkEquipWearable;
new g_CollisionOffset;

new int:g_hWearableOwner[2049];
new int:g_iTiedEntity[2049];
new g_hWearableOwner[2049];
new g_iTiedEntity[2049];
new bool:g_bIsToolgun[2049];
new String:g_sCurrentColor[MAXPLAYERS + 1][32];
new RenderFx:g_fxEffectTool[MAXPLAYERS + 1];
new int:g_iCurrentColor[MAXPLAYERS + 1][3];
new g_iCurrentColor[MAXPLAYERS + 1][3];
new LastUsed[MAXPLAYERS + 1];

new int:g_iTool[MAXPLAYERS + 1];
new int:g_iColorTool[MAXPLAYERS + 1];
new int:g_iEffectTool[MAXPLAYERS + 1];
new g_iTool[MAXPLAYERS + 1];
new g_iColorTool[MAXPLAYERS + 1];
new g_iEffectTool[MAXPLAYERS + 1];
new bool:g_bPlayerPressedReload[MAXPLAYERS + 1];
new bool:g_bAttackWasMouse2[MAXPLAYERS + 1];
new bool:g_bAttackWasMouse3[MAXPLAYERS + 1];
Expand Down Expand Up @@ -99,7 +102,7 @@ new Float:g_fDelRangePoint3[MAXPLAYERS][3];
new String:g_szDelRangeStatus[MAXPLAYERS][8];
new bool:g_szDelRangeCancel[MAXPLAYERS] = { false, ... };

new int:g_RememberGodmode[MAXPLAYERS];
new g_RememberGodmode[MAXPLAYERS];

new ColorBlue[4] = {
50,
Expand Down Expand Up @@ -292,10 +295,10 @@ new g_iPhys;

public Plugin:myinfo = {
name = "TF2 Sandbox All In One Module",
author = "Danct12, DaRkWoRlD, FlaminSarge, javalia, greenteaf0718, hjkwe654",
author = "LeadKiller, Danct12, DaRkWoRlD, FlaminSarge, javalia, greenteaf0718, hjkwe654",
description = "Everything in one module, isn't that cool?",
version = BUILDMOD_VER,
url = "http://dtf2server.ddns.net"
url = "https://sandbox.moddage.site/"
};

public OnPluginStart() {
Expand Down Expand Up @@ -805,6 +808,19 @@ public OnPluginStart() {
RegAdminCmd("sm_tf2sb", Command_TF2SBCred, 0);
RegAdminCmd("hidehudtf2sb", Command_TF2SBHideHud, 0);

// updater
if (LibraryExists("updater"))
{
Updater_AddPlugin(UPDATE_URL);
}
}

public OnLibraryAdded(const String:name[])
{
if (StrEqual(name, "updater"))
{
Updater_AddPlugin(UPDATE_URL);
}
}

public Action:Command_TF2SBCred(client, args)
Expand Down Expand Up @@ -937,7 +953,7 @@ public OnClientDisconnect(Client) {
}

public OnClientConnected(Client) {
g_RememberGodmode[Client] = 1.0;
g_RememberGodmode[Client] = 1;
}

public Action:Timer_Disconnect(Handle:Timer, Handle:hPack) {
Expand Down Expand Up @@ -2285,13 +2301,13 @@ public Action:Command_ChangeGodMode(Client, Args) {
if (GetEntProp(Client, Prop_Data, "m_takedamage") == 0)
{
Build_PrintToChat(Client, "God Mode OFF");
g_RememberGodmode[Client] = 0.0;
g_RememberGodmode[Client] = 0;
SetEntProp(Client, Prop_Data, "m_takedamage", 2, 1);
}
else
{
Build_PrintToChat(Client, "God Mode ON");
g_RememberGodmode[Client] = 1.0;
g_RememberGodmode[Client] = 1;
SetEntProp(Client, Prop_Data, "m_takedamage", 0, 1);
}

Expand Down Expand Up @@ -2496,7 +2512,10 @@ public EntityInfo(Client, iTarget) {
}

new String:szModel[128], String:szOwner[32], String:szPropString[256];
new String:szGetThoseString = GetEntPropString(iTarget, Prop_Data, "m_iName", szPropString, sizeof(szPropString));

new String:szGetThoseString[512];
GetEntPropString(iTarget, Prop_Data, "m_iName", szPropString, sizeof(szPropString));

new iOwner = Build_ReturnEntityOwner(iTarget);
GetEntPropString(iTarget, Prop_Data, "m_ModelName", szModel, sizeof(szModel));
if (iOwner != -1)
Expand Down Expand Up @@ -3484,7 +3503,7 @@ public CondMenu(Handle:menu, MenuAction:action, param1, param2)
if (StrEqual(item, "fly"))
{
if (!Build_AllowToUse(param1) || Build_IsBlacklisted(param1) || !Build_IsClientValid(param1, param1, true) || !Build_AllowFly(param1))
return Plugin_Handled;
return 0;

if (GetEntityMoveType(param1) != MOVETYPE_FLY)
{
Expand Down Expand Up @@ -3974,7 +3993,7 @@ public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:ang
switch (g_iTool[client])
{
case 1:ShowHudText(client, -1, "TOOL:\nREMOVER\n\n\n\n[PRIMARY] Remove\n[SECONDARY] Remove\n[RELOAD] Switch Tools");
case 2:ShowHudText(client, -1, "TOOL:\nEXPLODE TARGET\n\n\n\n[PRIMARY] BOOM!\n[RELOAD] Switch Tools");
case 2:ShowHudText(client, -1, "TOOL:\nALLAHU AKBAR!!\n\n\n\n[PRIMARY] BOOM!\n[RELOAD] Switch Tools");
case 3:ShowHudText(client, -1, "TOOL:\nRESIZE TOOL\n\n\n\n[PRIMARY] Larger\n[SECONDARY] Smaller\n[RELOAD] Switch Tools");
case 4:ShowHudText(client, -1, "TOOL:\nNO COLLIDE\n\n\n\n[PRIMARY] No Collide\n[SECONDARY] Collide\n[RELOAD] Switch Tools");
case 5:ShowHudText(client, -1, "TOOL:\nDUPLICATOR\n\n\n\n[PRIMARY] Paste\n[SECONDARY] Copy\n[RELOAD] Switch Tools");
Expand Down Expand Up @@ -4237,7 +4256,7 @@ grab(client) {

targetentity = GetClientAimEntity3(client, distancetoentity, resultpos);

if (targetentity != -1) {
if (targetentity != -1 && !IsValidClient(targetentity)) {

new PropTypeCheck:entityType = entityTypeCheck(targetentity);

Expand Down Expand Up @@ -4545,13 +4564,13 @@ hold(client) {
physgunaimfinal[1] = fOrigin[1] - aimorigin[1];
physgunaimfinal[2] = fOrigin[2] - aimorigin[2];

if (grabentitytype[client] == PROP_PHYSBOX || grabentitytype[client] == PROP_RAGDOLL) {
if (grabentitytype[client] == PROP_PHYSBOX || grabentitytype[client] == PROP_RAGDOLL || grabentitytype[client] == PROP_PLAYER) {

SetEntPropEnt(grabbedentref[client], Prop_Data, "m_hPhysicsAttacker", client);
SetEntPropFloat(grabbedentref[client], Prop_Data, "m_flLastPhysicsInfluenceTime", GetGameTime());

}
if (grabentitytype[client] == PROP_RIGID || grabentitytype[client] == PROP_PLAYER) {
if (grabentitytype[client] == PROP_RIGID) {

decl Float:eyeposfornow[3];
GetClientEyePosition(client, eyeposfornow);
Expand All @@ -4574,11 +4593,11 @@ PropTypeCheck:entityTypeCheck(entity) {
new String:classname[64];
GetEdictClassname(entity, classname, 64);

if (StrContains(classname, "prop_dynamic", false) != -1 || StrContains(classname, "prop_physics", false) != -1 || StrContains(classname, "tf_dropped_weapon", false) != -1 || StrContains(classname, "prop_door_", false) != -1 || StrContains(classname, "tf_ammo_pack", false) != -1 || StrContains(classname, "prop_physics_multiplayer", false) != -1) {
if (StrContains(classname, "prop_dynamic", false) != -1 || StrContains(classname, "tf_dropped_weapon", false) != -1 || StrContains(classname, "prop_door_", false) != -1 || StrContains(classname, "tf_ammo_pack", false) != -1 || StrContains(classname, "prop_physics_multiplayer", false) != -1) {

return PROP_RIGID;
}
else if (StrContains(classname, "func_physbox", false) != -1) {
else if (StrContains(classname, "func_physbox", false) != -1 || StrContains(classname, "prop_physics", false) != -1) {

return PROP_PHYSBOX;

Expand Down Expand Up @@ -4669,7 +4688,7 @@ bool:clientcangrab(client) {


}

return false;
}

bool:clientisgrabbingvalidobject(client) {
Expand Down Expand Up @@ -4761,7 +4780,7 @@ public Action:ClientRemoveAll(client, args)
return Plugin_Handled;
}

decl String:arg[65], String:cmd[192];
decl String:arg[65], cmd[192];
GetCmdArg(1, arg, sizeof(arg));

decl String:target_name[MAX_TARGET_LENGTH];
Expand Down Expand Up @@ -4937,8 +4956,6 @@ stock GiveToolgun(client)
TF2Items_SetLevel(hWeapon, 100);
TF2Items_SetQuality(hWeapon, 5);

TF2Items_SetAttribute(hWeapon, 0, 305, 1.0); //Fire tracer rounds
TF2Items_SetAttribute(hWeapon, 1, 731, 1.0); //Allow inspect
TF2Items_SetAttribute(hWeapon, 2, 106, 0.0); //Accuracy bonus
TF2Items_SetAttribute(hWeapon, 3, 1, 0.0); //Damage Penalty
TF2Items_SetNumAttributes(hWeapon, 4);
Expand Down Expand Up @@ -4973,7 +4990,7 @@ stock GiveToolgun(client)

SetEntProp(weapon, Prop_Send, "m_iWorldModelIndex", PrecacheModel(MDL_TOOLGUN));
SetEntProp(weapon, Prop_Send, "m_nModelIndexOverrides", PrecacheModel(MDL_TOOLGUN), _, 0);
SetEntProp(weapon, Prop_Send, "m_nSequence", 3);
SetEntProp(weapon, Prop_Send, "m_nSequence", 2);

SetEntityRenderMode(weapon, RENDER_NONE);
SetEntityRenderColor(weapon, 0, 0, 0, 0);
Expand All @@ -4990,9 +5007,10 @@ public Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &boo
{
if (IsValidEntity(weapon) && g_bIsToolgun[weapon])
{
new Float:flStartPos[3], flEyeAng[3], flHitPos[3];
new Float:flStartPos[3], Float:flEyeAng[3], Float:flHitPos[3], Float:fOrigin[3];
GetClientEyePosition(client, flStartPos);
GetClientEyeAngles(client, flEyeAng);
GetClientAbsOrigin(client, fOrigin);

new Handle:hTrace = TR_TraceRayFilterEx(flStartPos, flEyeAng, MASK_SHOT, RayType_Infinite, TraceRayDontHitEntity, client);
TR_GetEndPosition(flHitPos, hTrace);
Expand Down Expand Up @@ -5032,12 +5050,23 @@ public Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &boo
}
case 2:
{
if (iHitEntity > 0)
if (Build_IsAdmin(client))
{
if (iHitEntity <= MaxClients && IsClientInGame(iHitEntity) && IsPlayerAlive(iHitEntity))
FakeClientCommandEx(iHitEntity, "explode");
else
AcceptEntityInput(iHitEntity, "explode");
new explosion = CreateEntityByName("env_explosion");
DispatchKeyValue(explosion, "magnitude", "10000");
DispatchKeyValue(explosion, "radius_override", "256");
DispatchKeyValue(explosion, "rendermode", "5");
DispatchKeyValue(explosion, "spawnflags", "0");
TeleportEntity(explosion, flHitPos, NULL_VECTOR, NULL_VECTOR);
DispatchSpawn(explosion);
ActivateEntity(explosion);
AcceptEntityInput(explosion, "Explode");

AcceptEntityInput(explosion, "Kill");
}
else
{
PrintCenterText(client, "This tool now is only for admin due to abusive reasons.");
}
}
case 3:
Expand Down Expand Up @@ -5258,7 +5287,7 @@ public Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &boo
{
g_sCurrentColor[client] = "Blue";
g_iCurrentColor[client][0] = 0;
g_iCurrentColor[client][1] = 0.0;
g_iCurrentColor[client][1] = 0;
g_iCurrentColor[client][2] = 255;
}
case 6:
Expand Down Expand Up @@ -5404,15 +5433,28 @@ public Action:TF2_CalcIsAttackCritical(client, weapon, String:weaponname[], &boo

new random = GetRandomInt(0, 1);
if (random == 1) {
EmitSoundToAll(SND_TOOLGUN_SHOOT2, weapon, SNDCHAN_WEAPON, SNDLEVEL_RAIDSIREN);
EmitSoundToClient(client, SND_TOOLGUN_SHOOT2);
EmitAmbientSound(SND_TOOLGUN_SHOOT2, flHitPos, iHitEntity, SNDLEVEL_NORMAL, SND_NOFLAGS, 1.0, 100);
EmitAmbientSound(SND_TOOLGUN_SHOOT2, fOrigin, client, SNDLEVEL_NORMAL, SND_NOFLAGS, 1.0, 100);
/*EmitSoundToAll(SND_TOOLGUN_SHOOT2, weapon, SNDCHAN_WEAPON, SNDLEVEL_RAIDSIREN);
EmitSoundToClient(client, SND_TOOLGUN_SHOOT2);*/
} else {
EmitSoundToAll(SND_TOOLGUN_SHOOT, weapon, SNDCHAN_WEAPON, SNDLEVEL_RAIDSIREN);
EmitSoundToClient(client, SND_TOOLGUN_SHOOT);
/*EmitSoundToAll(SND_TOOLGUN_SHOOT, weapon, SNDCHAN_WEAPON, SNDLEVEL_RAIDSIREN);
EmitSoundToClient(client, SND_TOOLGUN_SHOOT);*/

EmitAmbientSound(SND_TOOLGUN_SHOOT, flHitPos, iHitEntity, SNDLEVEL_NORMAL, SND_NOFLAGS, 1.0, 100);
EmitAmbientSound(SND_TOOLGUN_SHOOT, fOrigin, client, SNDLEVEL_NORMAL, SND_NOFLAGS, 1.0, 100);
}

TE_SetupBeamRingPoint(flHitPos, 10.0, 150.0, g_Beam, g_Halo, 0, 10, 0.6, 3.0, 0.5, ColorWhite, 20, 0);
TE_SendToAll();
TE_SetupBeamPoints(flHitPos, fOrigin, g_PBeam, g_Halo, 0, 66, 1.0, 3.0, 3.0, 0, 0.0, ColorBlue, 20);
TE_SendToAll();



SetEntProp(weapon, Prop_Send, "m_iClip1", -1);
}
return Plugin_Continue;
}

public bool:TraceRayDontHitEntity(entity, mask, any:data)
Expand Down Expand Up @@ -5529,4 +5571,12 @@ public Action:Command_TF2SBHideHud(client, args)
Client_SetDrawViewModel(client, true);
}
return Plugin_Handled;
}

stock bool:IsValidClient(client)
{
if (client <= 0)return false;
if (client > MaxClients)return false;
if (!IsClientConnected(client))return false;
return IsClientInGame(client);
}
Loading