Page 1 of 1
[d&d 3.5][wip]
Posted: Fri Jun 21, 2013 7:10 am
by arawra
Coming back from the dead, its D&D CSS! Inspired by Jeff's old mod, this is rewritten in python for the CS:GO game. The wiki I am maintaining can be found here: http://dnd-css-mod.wikidot.com/
Note: this is a WORK IN PROGRESS
http://github.com/xxauroraxx/dndcsgo
In DnD CSS Mod players choose a combination of a Race and a Class. New players start as the default Race "Human" and the default Class "Fighter."
A Race is a species, like Human or Orc. A Class is a profession, such as Wizard or Fighter. You may be any combination of Race and any Class.
Killing enemies, rescuing hostages, planting the bomb, and defusing the bomb results in the player obtaining experience for their current Class.
Players start out as Level 1 for every class (Fighter, Cleric, Wizard, Rogue, and Paladin). To Level Up a Class the player must earn enough experience to meet or exceed the total required and then obtain a kill. To view how much experience is needed type !menu and select 6 for your personal stats.
It takes 1000 experience to go from Level 1 to Level 2, 2000 to go from Level 2 to Level 3, and so on.
Certain classes can only use certain weapons. For instance, a Wizard can not use an AK or AWP. The class with the least restrictions on it is the Fighter, and Wizard is the most. This is not yet implemented but is planned.UPDATE 1-17-2015:
Added API for status effects
Methodology for weapon restrictions
Race information to player_spawn event
Stealth API
CHANGES NOT TESTEDCreated github for further changes:
http://github.com/xxauroraxx/dndcsgoUPDATE 1-1-2015:
Most menus are implemented
Pruning implemented for database
Playerinfo and stats menu added
Timer working
TODO:
Test regen
Stun and freeze
Weapon restriction/removal/give
Bonus damage
Stealth
UPDATE (unknown date):
Due to the wonderful help of the guys here, I have:
The ability to switch Classes, Races, Level-Adjustment Races, and Prestiges working (may be buggy)
XP is able to be obtained
Database functionality implemented (no pruning yet)
Posted: Mon Sep 02, 2013 6:16 am
by arawra
I have a working database to save player information, as well as a procedure (somewhat tested) for changing class and race.
!class Fighter
!race Troll
This is the current method for changing class and race until popups are introduced. I have a method for accounting for LA races, but not prestige classes yet.
Until SourcePython has a working method for delaying commands, Rogues can not restealth after "x" seconds and there will be no cooldowns, etc. There will also be no stealth at all until that functionality is added. There are also no menus until popups are added.
Posted: Mon Sep 02, 2013 1:06 pm
by satoon101
We have had delays built in for quite some time:
- Directly from the C++ side:
- From the Python side API:
You can also use threading, but that can get tricky. We have not added any threading delays to the Python API, yet, but we do intend to do so at some point.
You can also use the following command to delay using the server console:
Code: Select all
sp delay <seconds> <command> [arguments]
http://www.sourcepython.com/showwiki.php?title=Wiki:The+sp+command#delaySatoon
Posted: Mon Sep 02, 2013 2:15 pm
by satoon101
Also, you can use the messages package's ShowMenu to create menus, for now. And then, once we have added a proper "menu" package, switch all the popups over to using it instead.
Satoon
Posted: Mon Sep 02, 2013 7:38 pm
by arawra
Thanks for all the awesome info, Satoon. Glad we have someone in the community like you ;D Now if we only had the ability to pre-hook events so I could mess with damage before player_hurt ...
Posted: Tue Sep 03, 2013 1:11 am
by satoon101
You actually can do that already!! Though, the current implementation is going to be changed slightly here very soon, so I would not advise using it quite yet.
Satoon
Posted: Tue Sep 03, 2013 7:31 am
by arawra
Ok, one last question. Is there an equivalent for est_getviewplayer ?
Posted: Tue Sep 03, 2013 8:10 am
by Ayuto
At the moment it requires the memory_c module. Then you can use UTIL_TraceLine for doing that.
Posted: Thu Sep 05, 2013 8:51 am
by arawra
I was looking through the methods in memory_c, and I am clueless on how to use them with UTIL_TraceLine. Could you give me an example?
Posted: Thu Sep 05, 2013 11:08 pm
by Omega_K2
Find offset or signature, then call it by using that and give the appropinate parameters (I bet you can also fetch it from sourcemod gamedata files so you don't have to do the work

)
UTIL_TraceLine( const Vector& vecAbsStart, const Vector& vecAbsEnd, unsigned int mask, const IHandleEntity *ignore, int collisionGroup, trace_t *ptr ).
https://developer.valvesoftware.com/wiki/UTIL_TraceLine
Posted: Fri Sep 06, 2013 5:18 am
by arawra
So I tried making something that would work for this, but I was unable to get it to load because I couldn't get the Vector class from vecmath in EventScripts 2 to load, and was unable to debug this. The class will be omitted for size restrictions. Not sure if it would work anyway, but could you at least give some indication of where to proceed?
Code: Select all
'''
# 16.05.13
# UTIL_TraceLine(Vector const&, Vector const&, unsigned int, IHandleEntity const*, int, CGameTrace *)
[UTIL_TraceLine]
shortname = TraceLine
sig = 53 8B DC 83 EC 08 83 E4 F0 83 C4 04 55 8B 6B 04 89 6C 24 04 8B EC 83 EC 6C 56
symbol = _Z14UTIL_TraceLineRK6VectorS1_jPK13IHandleEntityiP10CGameTrace
param = ppipip)v
convention = cdecl
'''
import memory_c
from commands.client import ClientCommand
from players.entity import PlayerEntity
from players.helpers import edict_from_userid
from players.helpers import index_from_userid
from players.helpers import userid_from_playerinfo
engine = memory_c.find_binary('bin/engine')
TraceLineRef = engine.find_symbol('_Z14UTIL_TraceLineRK6VectorS1_jPK13IHandleEntityiP10CGameTrace')
@ClientCommand('someCall')
def someFunc(player, ccommand):
userid = userid_from_playerinfo(player)
index = index_from_userid(userid)
edict = edict_from_userid(userid)
x,y,z = PlayerEntity(index).location
viewOffset = [edict.get_prop('m_vecViewOffset[' + str(x) + ']'), y]
myEyeAngle0 = edict.get_prop('m_angEyeAngles[0]')
myEyeAngle1 = edict.get_prop('m_angEyeAngles[1]')
myX = math.cos(math.radians(myEyeAngle1))
myY = math.sin(math.radians(myEyeAngle1))
myZ = -1 * math.sin(math.radians(myEyeAngle0))
pStart = createVector(*viewOffset)
pEnd = createVector(*list(Vector(startvec) + Vector(myX, myY, myZ) * 16384))
ptr = memory_c.alloc(84)
myTrace = Vector(TraceLineRef(pStart, pEnd, 0xFFFFFFFF, userid, 0, ptr))
return myTrace
def createVector(x, y, z):
obj = spe.makeObject('Vector', spe.alloc(SIZE_VECTOR))
obj.x = x
obj.y = y
obj.z = z
return obj.base
# Taken from vecmatch, EventScripts 2
class Vector(object):
Posted: Sat Sep 07, 2013 11:49 am
by Ayuto
There are more errors. However..
Syntax: Select all
# =============================================================================
# >> IMPORTS
# =============================================================================
# Python
import math
import os
# Source.Python
import players
import entities
import core
import memory_c
from memory_c import Convention
from events import Event
from vecmath_c import CVector
# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
MAX_COORD_RANGE = 16384
server = memory_c.find_binary(core.GAME_NAME + '/bin/server')
if os.name == 'nt':
identifier = b'\x53\x8B\xDC\x83\xEC\x08\x83\xE4\xF0\x83\xC4\x04\x55\x8B\x6B\x04\x89\x6C\x24\x04\x8B\xEC\x83\xEC\x6C\x56'
else:
identifier = '_Z14UTIL_TraceLineRK6VectorS1_jPK13IHandleEntityiP10CGameTrace'
UTIL_TraceLine = server[identifier].make_function(Convention.CDECL, 'ppIpip)v')
# =============================================================================
# >> GAME EVENTS
# =============================================================================
@Event
def player_say(ev):
userid = ev.get_int('userid')
edict = players.helpers.edict_from_userid(userid)
index = get_viewed_entity(edict)
print(entities.helpers.edict_from_index(index).get_class_name())
def get_view_coords(edict, mask=0xFFFFFFFF, collision_group=0):
'''
Returns the edict's view coordinates as a tuple.
'''
# Create the start and end vectors
startvec = get_eye_location(edict)
endvec = startvec + get_eye_angle(edict) * MAX_COORD_RANGE
# "Convert" them to pointers
startvec_ptr = create_vector(*startvec)
endvec_ptr = create_vector(*endvec)
# Allocate space for the CGameTrace pointer
ptr = memory_c.CPointer()
ptr.alloc(84)
# Call UTIL_TraceLine
UTIL_TraceLine(startvec_ptr, endvec_ptr, mask,
entities.helpers.pointer_from_edict(edict), collision_group, ptr)
# Get the end vector of the ray
result = (ptr.get_float(12), ptr.get_float(16), ptr.get_float(20))
# Deallocate the pointers to avoid memory leaks
startvec_ptr.dealloc()
endvec_ptr.dealloc()
ptr.dealloc()
return result
def get_viewed_entity(edict, mask=0xFFFFFFFF, collision_group=0):
'''
Returns the index of the entity which is the edict looking at.
'''
# Create the start and end vectors
startvec = get_eye_location(edict)
endvec = startvec + get_eye_angle(edict) * MAX_COORD_RANGE
# "Convert" them to pointers
startvec_ptr = create_vector(*startvec)
endvec_ptr = create_vector(*endvec)
# Allocate space for the CGameTrace pointer
ptr = memory_c.CPointer()
ptr.alloc(84)
# Call UTIL_TraceLine
UTIL_TraceLine(startvec_ptr, endvec_ptr, mask,
entities.helpers.pointer_from_edict(edict), collision_group, ptr)
# Get the entity that was hit
result = ptr.get_ptr(76).addr
# Deallocate the pointers to avoid memory leaks
startvec_ptr.dealloc()
endvec_ptr.dealloc()
ptr.dealloc()
# Return either None or the entity's index
return entities.helpers.index_from_pointer(result) if result else None
# =============================================================================
# >> HELPER FUNCTIONS
# =============================================================================
def create_vector(x, y, z):
ptr = memory_c.CPointer()
ptr.alloc(12)
ptr.set_float(x)
ptr.set_float(y, 4)
ptr.set_float(z, 8)
return ptr
def get_eye_location(edict):
info = players.helpers.playerinfo_from_edict(edict)
return CVector(*tuple(edict.get_prop('m_vecViewOffset[%s]'% x).get_float() + y for x, y in enumerate(info.get_abs_origin())))
def get_eye_angle(edict):
myEyeAngle0 = edict.get_prop('m_angEyeAngles[0]').get_float()
myEyeAngle1 = edict.get_prop('m_angEyeAngles[1]').get_float()
myX = math.cos(math.radians(myEyeAngle1))
myY = math.sin(math.radians(myEyeAngle1))
myZ = -1 * math.sin(math.radians(myEyeAngle0))
return CVector(myX, myY, myZ)
Posted: Sun Sep 08, 2013 1:10 am
by satoon101
Just as a heads up, but the DynCall and DynDetours stuff is going to be changed very soon. While that script might work now, it will be broken once the proper changes are made.
Satoon
Posted: Sat Apr 19, 2014 7:17 pm
by arawra
UPDATE: Due to the wonderful help of the guys here, I have:
The ability to switch Classes, Races, Level-Adjustment Races, and Prestiges working (may be buggy)
XP is able to be obtained
Database functionality implemented (no pruning yet)