Page 1 of 1

[d&d 3.5][wip]

Posted: Fri Jun 21, 2013 7:10 am
by arawra
Image

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 TESTED
Created github for further changes: http://github.com/xxauroraxx/dndcsgo

UPDATE 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:
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#delay

Satoon

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)