Raised This Month: $12 Target: $400
 3% 

Module: Orpheu (v2.6.3)


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
joaquimandrade
Veteran Member
Join Date: Dec 2008
Location: Portugal
Old 01-22-2010 , 15:13   Module: Orpheu (v2.6.3)
Reply With Quote #1

This module aims to give more power to the amxmodx coder by giving facilities to use functions that are not possible to use without it (what includes functions from other metamod plugins). For windows and linux. From the version 2.1 uploaded 29/01/2010 it also supports memory direct access / patch.

The concept is the following:
The module handles the conversion between types in C++ and pawn and makes you able to use a function if you can provide it a way to have it's address in memory and tell him the types of data that are involved with it. It includes a generic way of working with C++ structs.

For example: let's say you want to use this function:
Code:
void PM_Move( struct playermove_s *ppmove, qboolean server)
It doesn't return a value, and it receives an argument of type "playermove_s *" and another one of type "qboolean".

As long as the types it needs are implemented in the module, you can use it. If one isn't implemented you can try to use it directly and still do operations with the function, particularly hooking it, since when you hook a function you don't necessarily care about all the arguments.

The missing thing then is a way of finding it in memory so that the module know where it is. There ways of doing that are:

  • By knowing its name. In libraries compiled in linux, by default, the functions' symbolic names are attached to them making it easier to find them. Unfortunately the same doesn't happen when libraries are compiled for windows, making it useless for windows unless you have the source for the library and compile it yourself so that it attaches the symbolic names for the functions. I opted to do that for monstermod and i'm shipping a compiled library for windows and for linux that makes it easy and uniform to use it.
  • By providing a set of bytes in memory unique to that function. This is a technique called "signature scanning". The technique is talked about the first time in these forums here and its expanded on here and here. This technique basically allows you to refer to any function in memory as long as you can find it. To understand it you have to read more about the subject in the links refered above.
  • By providing their address upon having it in a plugin. If you can find the address of a function programatically you can use it. The module uses this to provide access to core functions of the engine. Those functions are provided by amxmodx without the module but by hooking them with this module you can intercept them being called in more situations (like when they are called by other metamod plugins)
Added in 2.1
  • By providing its offset in the library. This is for fast testing and shouldn't be relied upon since it can easily break if it faces an update of the library.
  • By providing its index in the virtual function table of the class. This let's you use many functions by providing only an index. It was copied from hamsandwich to work in the orpheu style. It brings the possibility of hooking virtual function of entities and objects like CGameRules. What it brings new is that it isnt limited to an hardcoded set of functions and let you use functions mod dependent that couldn't be hooked before.


To make the module aware of a function you have to create a file formatted with the notation JSON and put it in the folder "configs/orpheu/functions". The files format is like the following:

For the function:
PHP Code:
CMBaseMonsterspawn_monster(int monster_typeVectororiginfloat angleint respawn_index
File would be:
Code:
{
    "name" : "spawn_monster",
    "library" : "monstermod",
    "info" : "Spawns a monstermod monster in the world",
    "arguments" :
    [
        {
            "type" : "int",
            "info" : "The type of the monster"
        },
        {
            "type" : "Vector &",
            "info" : "The position where the monster will be placed at"
        },
        {
            "type" : "float",
            "info" : "Angle of the monster"
        },
        {
            "type" : "int",
            "info" : "Respawn index. Related to the order of a monster respawning if failed to spawn at the first try"
        }
    ],
    "return" :
    {
        "type" : "CMBaseMonster *",
        "info" : "The monster created"
    },
    "identifiers":
    [
        {
            "os" : "windows",
            "value" : "?spawn_monster@@YAPAVCMBaseMonster@@HAAVVector@@MH@Z"
        },
        {
            "os" : "linux",
            "value" : "_Z13spawn_monsteriR6Vectorfi"
        }
    ]
}
  • "Info" fields are optional.
  • The field "name" must match the filename.
  • The library name is "mod" for mods like cstrike, and "engine" for the engine dll. For metamod libraries you need to create a file like those you can find at "configs\orpheu\libraries" that contain a pair libraryname/libraryCvar, so the module recognize the module by a cvar of theirs.
  • The identifiers are an array of groups "os"/"value" to identify the function. In the case that the library is "mod" you need also to provide an extra field called "mod". It should look like:
    Code:
    "mod" : "cstrike"
    . The purpose of this field is documentation but it is mandatory.

In this case the method used to refer to the function address is by giving it's name. In the case of a signature, the field value would be an array of bytes or "*" or "?" like

Code:
"value"  : [0x1,"*","?"]
"*" is meant to be used when you don't care about the value of that byte.

For example:

"value" : [0x1,"*"]

matches

[0x1,0x0] , [0x1,0x1] , ... [0x1,0xFF]

"?" is meant to be used when you don't care about the value of the byte and it can even not exist like:

"value" : [0x1,"?"]

matches the same as above plus [0x1]

JSON is an object notation widely used and to make sure your file is correctly formatted you can use a validator.
For this project I slightly modified a library to parse JSON to read bytes. That means that when you want to validate a file, do not include a signature.

A special case of functions are those that belong to a class like:

PHP Code:
void CMController :: HandleAnimEventMonsterEvent_t *pEvent 
In this case you need to create a folder named "CMController" and create a file name "HandleAnimEvent" inside it. This is mandatory and has the purpose of a better organization. You will also have to provide in the file a field named "class". The file would look as:
Code:
{
    "name" : "HandleAnimEvent",
    "class" : "CMController",
    "library" : "monstermod",
    "arguments" :
    [
        {
            "type" : "MonsterEvent_t *"
        }
    ],
    "identifiers":
    [
        {
            "os" : "windows",
            "value" : "?HandleAnimEvent@CMController@@UAEXPAUMonsterEvent_t@@@Z"
        },
        {
            "os" : "linux",
            "value" : "_ZN12CMController15HandleAnimEventEP14MonsterEvent_t"
        }
    ]
}
The other method of using a function deals with having its address programatically. Take a look at http://metamod.org/sdk/dox/eiface_8h-source.html - line 100.

You can find there the representation af a struct called "enginefuncs_s". That struct contains addresses of engine functions. The module provides a stock to use them.

Let's say you want to hook the function contained in the struct at
PHP Code:
void (*pfnServerPrint)( const char *szMsg ); 
You would create a file like
Code:
{
    "name" : "ServerPrint",
    "library" : "engine",
    "arguments" :
    [
        {
            "type" : "char *"
        }
    ]
}
No need for identifiers since the address will be find at run time, programatically. In a plugin you would have:
PHP Code:
new OrpheuFunction:ServerPrint OrpheuGetEngineFunction("pfnServerPrint","ServerPrint"
And could then call it or hook it. By hooking that function you can intercept console messages like those that occur when you issued the server command "metamod".

This is a special (hardcode) case of the method of using a function when you have its address in a plugin. The other special case is OrpheuGetDLLFunction to retrieve functions from the struct DLL_FUNCTIONS

http://metamod.org/sdk/dox/eiface_8h-source.html - line 384.

For generic cases you would use the native:

PHP Code:
native OrpheuFunction:OrpheuCreateFunction(address,libFunctionName[],classname[]=""
The module let's you handle structs in a generic way. Let's say we want to hook the function PM_Move that can be found in the struct DLL_FUNCTIONS.

Its file:
Code:
{
    "name" : "PM_Move",
    "library" : "mod",
    "arguments" :
    [
        {
            "type" : "playermove_s *"
        },
        {
            "type" : "qboolean"
        }
    ]
}
Hooking it:
PHP Code:
public plugin_init()
{
    new 
OrpheuFunction:PM_Move OrpheuGetDLLFunction("pfnPM_Move","PM_Move")
    
OrpheuRegisterHook(PM_Move,"OnPM_Move")
}

public 
OnPM_Move(ppmove,server)
{
    

The first argument of the function is a struct. You can see it here http://metamod.org/sdk/dox/pm__defs_8h-source.html - line 92

Dealing with the struct data:

PHP Code:
public OnPM_Move(ppmove,server)
{
    new 
id OrpheuGetParamStructMember(1,"player_index") + 1
    
new Float:friction OrpheuGetParamStructMember(1,"friction")
    
    new 
sztexturename[20]
    
OrpheuGetParamStructMember(1,"sztexturename",sztexturename,charsmax(sztexturename))
    
    
server_print("ID %d friction %f texturename %s",id,friction,sztexturename)

More information on dealing with structs in the includes.

The same struct contains addresses for other functions. Here is an example of how to hook one of them:
Code:
{
    "name" : "PM_PlaySound",
    "library" : "engine",
    "arguments" :
    [
        {
            "type" : "int"
        },
        {
            "type" : "char *"
        },
        {
            "type" : "float"
        },
        {
            "type" : "float"
        },
        {
            "type" : "int"
        },
        {
            "type" : "int"
        }
    ]
}
PHP Code:
new OrpheuHook:PM_PlaySoundHook

public plugin_init()
{
    new 
OrpheuFunction:PM_Move OrpheuGetDLLFunction("pfnPM_Move","PM_Move")
    
OrpheuRegisterHook(PM_Move,"OnPM_Move")
    
OrpheuRegisterHook(PM_Move,"OnPM_MovePost",OrpheuHookPost)
}

public 
OnPM_Move(ppmove,server)
{
    
// Retrieves the address of the function to hook
    
new PM_PlaySoundAddress OrpheuGetParamStructMember(1,"PM_PlaySound")
    
    
// Creates the function in the module 
    
new OrpheuFunction:PM_PlaySound OrpheuCreateFunction(PM_PlaySoundAddress,"PM_PlaySound")
    
    
// Hooks it
    
PM_PlaySoundHook OrpheuRegisterHook(PM_PlaySound,"OnPM_PlaySoundHook")
}

public 
OnPM_PlaySoundHook(channel,sample[],Float:volume,Float:attenuation,fFlags,pitch)
{
    
server_print("Sample %s",sample)
}

public 
OnPM_MovePost(ppmove,server)
{
    
OrpheuUnregisterHook(PM_PlaySoundHook)

More info on the includes.

List of supported data types:

Code:
    "bool"
    "byte"
    "long"
    "CBaseEntity *"
    "char *"
    "edict_s *"
    "float"
    "Vector *"
    "CMBaseMonster *"
    "char"
    "short"
    "entvars_s *"
Structures:
Code:
    "movevars_s *"
    "usercmd_s *"
    "MonsterEvent_t *"
    "DLL_FUNCTIONS *"
    "playermove_s *"
    "enginefuncs_t *"
    "TraceResult *"
    "physent_s *"
    "pmplane_s *"
    "pmtrace_s *"
    "weapon_data_s *"
    "AmmoInfo *"
    "ItemInfo *"
    "Task_t *"
    "Schedule_t *"
I will provide more pratical examples later.

If the module doesn't run in your linux server, you must have libstdc++ installed.

Edit for Orpheu 2.1 - updated 29/01/2010

In the version 2.1 support for virtual functions (based on hamsandwich) and for memory retrieval / patching (based on mem hack) was added.

Virtual functions:

Virtual functions are functions that represent a concept shared among different classes (like Spawn) and implemented differently accordingly.
The way they are implemented by compiler permits to located them in memory by providing a simple numeric offset because references to them are kept in a table that each object of a class carries with it.

This is the table for the mod Counter Strike retrieved from it's linux binary of the class CHalfLifeMultiplay that extends CGameRules:

(Each line contains a symbolic name that represents a function)

PHP Code:
01 Think__18CHalfLifeMultiplay
02 
IsAllowedToSpawn__18CHalfLifeMultiplayP11CBaseEntity 
03 
FAllowFlashlight__18CHalfLifeMultiplay
04 
FShouldSwitchWeapon__18CHalfLifeMultiplayP11CBasePlayerP15CBasePlayerItem
05 
GetNextBestWeapon__18CHalfLifeMultiplayP11CBasePlayerP15CBasePlayerItem
06 
IsMultiplayer__18CHalfLifeMultiplay
07 
IsDeathmatch__18CHalfLifeMultiplay
08 
IsTeamplay__10CGameRules
09 
IsCoOp__18CHalfLifeMultiplay
10 
GetGameDescription__10CGameRules
11 
ClientConnected__18CHalfLifeMultiplayP7edict_sPCcT2Pc
12 
InitHUD__18CHalfLifeMultiplayP11CBasePlayer
13 
ClientDisconnected__18CHalfLifeMultiplayP7edict_s
14 
UpdateGameMode__18CHalfLifeMultiplayP11CBasePlayer
15 
FlPlayerFallDamage__18CHalfLifeMultiplayP11CBasePlayer
16 
FPlayerCanTakeDamage__18CHalfLifeMultiplayP11CBasePlayerP11CBaseEntity
17 
ShouldAutoAim__10CGameRulesP11CBasePlayerP7edict_s
18 
PlayerSpawn__18CHalfLifeMultiplayP11CBasePlayer
19 
PlayerThink__18CHalfLifeMultiplayP11CBasePlayer
20 
FPlayerCanRespawn__18CHalfLifeMultiplayP11CBasePlayer
21 
FlPlayerSpawnTime__18CHalfLifeMultiplayP11CBasePlayer
22 
GetPlayerSpawnSpot__18CHalfLifeMultiplayP11CBasePlayer
23 
AllowAutoTargetCrosshair__18CHalfLifeMultiplay
24 
ClientCommand_DeadOrAlive__18CHalfLifeMultiplayP11CBasePlayerPCc
25 
ClientCommand__18CHalfLifeMultiplayP11CBasePlayerPCc
26 
ClientUserInfoChanged__18CHalfLifeMultiplayP11CBasePlayerPc
27 
IPointsForKill__18CHalfLifeMultiplayP11CBasePlayerT1
28 
PlayerKilled__18CHalfLifeMultiplayP11CBasePlayerP9entvars_sT2
29 
DeathNotice__18CHalfLifeMultiplayP11CBasePlayerP9entvars_sT2
30 
CanHavePlayerItem__18CHalfLifeMultiplayP11CBasePlayerP15CBasePlayerItem
31 
PlayerGotWeapon__18CHalfLifeMultiplayP11CBasePlayerP15CBasePlayerItem
32 
WeaponShouldRespawn__18CHalfLifeMultiplayP15CBasePlayerItem
33 
FlWeaponRespawnTime__18CHalfLifeMultiplayP15CBasePlayerItem
34 
FlWeaponTryRespawn__18CHalfLifeMultiplayP15CBasePlayerItem
35 
VecWeaponRespawnSpot__18CHalfLifeMultiplayP15CBasePlayerItem
36 
CanHaveItem__18CHalfLifeMultiplayP11CBasePlayerP5CItem
37 
PlayerGotItem__18CHalfLifeMultiplayP11CBasePlayerP5CItem
38 
ItemShouldRespawn__18CHalfLifeMultiplayP5CItem
39 
FlItemRespawnTime__18CHalfLifeMultiplayP5CItem
40 
VecItemRespawnSpot__18CHalfLifeMultiplayP5CItem
41 
CanHaveAmmo__10CGameRulesP11CBasePlayerPCci
42 
PlayerGotAmmo__18CHalfLifeMultiplayP11CBasePlayerPci
43 
AmmoShouldRespawn__18CHalfLifeMultiplayP15CBasePlayerAmmo
44 
FlAmmoRespawnTime__18CHalfLifeMultiplayP15CBasePlayerAmmo
45 
VecAmmoRespawnSpot__18CHalfLifeMultiplayP15CBasePlayerAmmo
46 
FlHealthChargerRechargeTime__18CHalfLifeMultiplay
47 
FlHEVChargerRechargeTime__18CHalfLifeMultiplay
48 
DeadPlayerWeapons__18CHalfLifeMultiplayP11CBasePlayer
49 
DeadPlayerAmmo__18CHalfLifeMultiplayP11CBasePlayer
50 
GetTeamID__18CHalfLifeMultiplayP11CBaseEntity
51 
PlayerRelationship__18CHalfLifeMultiplayP11CBasePlayerP11CBaseEntity
52 
GetTeamIndex__10CGameRulesPCc
53 
GetIndexedTeamName__10CGameRulesi
54 
IsValidTeam__10CGameRulesPCc
55 
ChangePlayerTeam__10CGameRulesP11CBasePlayerPCcii
56 
SetDefaultPlayerTeam__10CGameRulesP11CBasePlayer
57 
PlayTextureSounds__18CHalfLifeMultiplay
58 
FAllowMonsters__18CHalfLifeMultiplay
59 
EndMultiplayerGame__18CHalfLifeMultiplay
60 
IsFreezePeriod__10CGameRules
61 
ServerDeactivate__18CHalfLifeMultiplay
62 
CheckMapConditions__18CHalfLifeMultiplay
63 
CleanUpMap__18CHalfLifeMultiplay
64 
RestartRound__18CHalfLifeMultiplay
65 
CheckWinConditions__18CHalfLifeMultiplay
66 
RemoveGuns__18CHalfLifeMultiplay
67 
GiveC4__18CHalfLifeMultiplay
68 
ChangeLevel__18CHalfLifeMultiplay
69 
GoToIntermission__18CHalfLifeMultiplay 
To use one of them you need to create a file that should look like:

Code:
{
    "name" : "GetNextBestWeapon",
    "class" : "CGameRules",
    "library" : "mod",
    "arguments" : 
    [
        {
            "type" : "CBasePlayer *"
        },
        {
            "type" : "CBasePlayerItem *"
        }
    ],
    "return" :
    {
        "type" : "bool"
    },
    "indexes" : 
    [
        {
            "os" : "windows",
            "mod" : "cstrike",
            "value" : 5
        },
        {
            "os" : "linux",
            "mod" : "cstrike",
            "value" : 6
        }
    ]
}
(In linux the virtual table includes an extra function at the beginning so the offsets should be +1 for it)

That function description should be placed at the folder "virtualFunctions" in a folder named "CGameRules" and in a file named "GetNextBestWeapon".

So that you can use those functions in a plugin some natives are provided like:

PHP Code:
OrpheuGetFunctionFromClass(entityClassName[],libFunctionName[],libClassName[])
OrpheuGetFunctionFromEntity(id,libFunctionName[],libClassName[])
OrpheuGetFunctionFromObject(object,libFunctionName[],libClassName[])
OrpheuGetFunctionFromMonster(id,libFunctionName[],libClassName[]) 
The first two work like the natives from hamsandwich:
  • The first retrieves a function based on an entity class
  • The second retrieves a function based on an entity
To use the functions from CHalfLifeMultiplay described above, we need OrpheuGetFunctionFromObject. This native retrieves a function based on an object of the class you want so we need an extra step to have the object.

For this particular case this is one way of doing it:
PHP Code:
{
    
"name" "InstallGameRules",
    
"library" "mod",
    
"return" 
    {
        
"type" "CHalfLifeMultiplay *"
    
},
    
"identifiers":
    [
        {
            
"os" "windows",
            
"mod" "cstrike",
            
"value" : [0x68,0x8c,0xea,"*",0xa,0xff,0x15,0xdc,0x23,"*",0xa,0x83,0xc4,0x4,0xff,0x15,0xe0,0x23,"*",0xa,0xa1,0xb8,0x25]
        },
        {
            
"os" "linux",
            
"mod" "cstrike",
            
"value" "InstallGameRules__Fv"
        
}
    ]

PHP Code:
public plugin_precache()
{    
    new 
OrpheuFunction:InstallGameRules OrpheuGetFunction("InstallGameRules")
    
OrpheuRegisterHook(InstallGameRules,"OnInstallGameRules",OrpheuHookPost)
}

public 
OnInstallGameRules()
{
    new 
obj OrpheuGetReturn()    
    new 
OrpheuFunction:GetNextBestWeapon OrpheuGetFunctionFromObject(obj,"GetNextBestWeapon","CGameRules")
    
OrpheuRegisterHook(GetNextBestWeapon,"OnGetNextBestWeapon")
}

public 
OnGetNextBestWeapon(obj,id,weaponID)
{
    
//    



Memory handling

The module has now support for retrieving or setting values directly in any portion of the memory where a library lies in. Examples of what can be done are: changing weapons cost, strings replacement that you can use for example to change text that appears in the console.

It can be done by using offsets to refer to where the memory you want to mess with is located or with signatures. As for the functions you need to create a file. This file can contain one or several descriptions of how/where is the memory you want to address.

Example for changing the awp cost:

PHP Code:
[
    {
        
"name" "awpCost",
        
"library" "mod",
        
"type" "long",
        
"memoryType" "data",
        
"identifiers" 
        [
            {
                
"os" "windows",
                
"mod" "cstrike",
                
"value" : [0x8E,0x12,0x00,0x00,0x7D,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x1E,0x00,0x00,0x00,0x07]
            }
        ]
    }



PHP Code:
OrpheuMemorySet("awpCost",1,1000
This is just an example and for windows and cstrike but the module can be used for both windows and linux and for any mod.

More information in the includes.

As note: if you want to replace strings that are directly placed in memory (most are) you should use the type "string" instead of "char *".


Credits


Arkshine, jim_yang, xpaw, speed, the links of "signature scanning" provided above, hamsandwich

http://jsoncpp.sourceforge.net/
http://www.boost.org/
http://forums.alliedmods.net/showpos...47&postcount=2


Original version by Joaquimandrade (v2.3a): https://github.com/Arkshine/Orpheu/tree/master/legacy
  • orpheu-source-2.3a.zip : project source code.
  • orpheu-files-2.3a.zip : binaries and configuration file.

Latest version by Arkshine (v2.6.3): https://github.com/Arkshine/Orpheu/releases
  • orpheu-files-2.6.x.zip : binaries and configuration file. Required if using HLDS version after february update.

Installation
  • Just unzip the content of orpheu-files-xx.zip in your /amxmodx directory. That's all.

Last edited by Arkshine; 12-31-2014 at 12:08. Reason: Updated to 2.6.3
joaquimandrade is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 01-22-2010 , 15:13   Re: Module: Orpheu2
Reply With Quote #2

Here some dumps of functions names and symbolic names (used for the signature) from Counter-Strike and MonsterMod.

Note: About Counter-Strike (windows), you will see that there are less many functions. The windows binary provides only some functions even if the functions list is the same than the linux one. To use the others functions you would need to search the signature into the memory. See the Joaquim's explanations in his post.
Attached Files
File Type: zip Dump Functions.zip (239.4 KB, 15424 views)
__________________

Last edited by Arkshine; 01-22-2010 at 15:32.
Arkshine is offline
Old 01-22-2010, 15:13
joaquimandrade
This message has been deleted by joaquimandrade.
xPaw
Retired AMX Mod X Moderator
Join Date: Jul 2008
Old 01-22-2010 , 15:17   Re: Module: Orpheu2
Reply With Quote #3

Its damn good, good job
__________________
xPaw is offline
Exolent[jNr]
Veteran Member
Join Date: Feb 2007
Location: Tennessee
Old 01-22-2010 , 15:22   Re: Module: Orpheu2
Reply With Quote #4

Great job
__________________
No private work or selling mods.
Quote:
Originally Posted by xPaw View Post
I love you exolent!
Exolent[jNr] is offline
Emp`
AMX Mod X Plugin Approver
Join Date: Aug 2005
Location: Decapod 10
Old 01-22-2010 , 15:38   Re: Module: Orpheu2
Reply With Quote #5

Very nice.
Emp` is offline
Send a message via AIM to Emp` Send a message via MSN to Emp` Send a message via Yahoo to Emp` Send a message via Skype™ to Emp`
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 01-22-2010 , 15:47   Re: Module: Orpheu2
Reply With Quote #6

This file includes a specially compiled MonsterMod for windows and linux and it's recommend to use if you want to use orpheu with MonsterMod.
Here a basic example of spawning a CMController, making it always being powering up, and having smoke.
Just to show us another example.

Use the command "spawnController" in game.

PHP Code:
#include <amxmodx>
#include <engine>
#include <fakemeta>
#include <xs>
#include <orpheu>

enum _:Monster
{
    
Grunt,
    
Apache,
    
Barney,
    
BigMomma,
    
Bullsquid,
    
Controller,
    
HAssassin,
    
HeadCrab,
    
HGrunt,
    
Houndeye,
    
ISlave,
    
Scientist,
    
SqueakGrenade,
    
Zombie
};

new 
OrpheuFunction:spawn_monster;
new 
OrpheuFunction:Smoke3_C;

public 
plugin_precache()
{
    new 
OrpheuFunction:HandleAnimEvent OrpheuGetFunction"HandleAnimEvent""CMController" );
    
OrpheuRegisterHookHandleAnimEvent"OnHandleAnimEvent" );
        
    
spawn_monster OrpheuGetFunction"spawn_monster" );
    
Smoke3_C OrpheuGetFunction"Smoke3_C""CGrenade" );
    
    
register_clcmd"spawnController""spawnController" );
}

public 
plugin_init ()
{
    
register_plugin"Orpheu Example""1.0.0""Orpheu" );
}

public 
OnHandleAnimEvent ( const player, const event )
{
    
server_print"Controller %d - Anim Event %d"playerOrpheuGetParamStructMember2"event" ) );
    
    
OrpheuSetParamStructMember2"event");
    
    new 
Float:origin];
    
pevplayerpev_originorigin );
    
    new 
grenade create_entity"grenade" );
    
entity_set_origingrenadeorigin );
    
    
OrpheuCallSuperSmoke3_Cgrenade );
}

public 
spawnController( const player )
{
    new 
Float:origin[3];
    
GetAimOriginDistanceplayerorigin200.0 );
    
    
OrpheuCallspawn_monsterControllerorigin0.0);  
}

GetAimOriginDistanceindexFloat:origin[3], Float:dist 
{
    new 
Float:start];
    new 
Float:view_ofs];
    
    
pevindexpev_originstart );
    
pevindexpev_view_ofsview_ofs );
    
xs_vec_addstartview_ofsstart );

    new 
Float:dest];
    
pev(indexpev_v_angledest );
    
    
engfuncEngFunc_MakeVectorsdest );
    
global_getglb_v_forwarddest );
    
    
xs_vec_mul_scalardestdistdest );
    
xs_vec_addstartdestdest );

    
engfuncEngFunc_TraceLinestartdest0index);
    
get_tr20TR_vecEndPosorigin );

Attached Files
File Type: zip monstermod_files.zip (403.6 KB, 5165 views)
__________________

Last edited by Arkshine; 01-22-2010 at 15:55.
Arkshine is offline
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 01-22-2010 , 15:55   Re: Module: Orpheu2
Reply With Quote #7

Please donate.
__________________
Arkshine is offline
joropito
AlliedModders Donor
Join Date: Mar 2009
Location: pfnAddToFullPack
Old 01-22-2010 , 15:56   Re: Module: Orpheu2
Reply With Quote #8

I wonder if it's possible now to access global variables.

Is it?
__________________

Divide et vinces
approved plugins | steam account

I don't accept PM for support. Just ask on forums.
If you're looking for private work, PM me.
joropito is offline
Send a message via MSN to joropito
joaquimandrade
Veteran Member
Join Date: Dec 2008
Location: Portugal
Old 01-22-2010 , 15:57   Re: Module: Orpheu2
Reply With Quote #9

Quote:
Originally Posted by joropito View Post
I wonder if it's possible now to access global variables.

Is it?
The module deals with functions. If you find a function that receives that variable you can use it.
joaquimandrade is offline
joropito
AlliedModders Donor
Join Date: Mar 2009
Location: pfnAddToFullPack
Old 01-22-2010 , 16:02   Re: Module: Orpheu2
Reply With Quote #10

Quote:
Originally Posted by joaquimandrade View Post
The module deals with functions. If you find a function that receives that variable you can use it.
I read again this answer from you and now I understand it.

Cool module
__________________

Divide et vinces
approved plugins | steam account

I don't accept PM for support. Just ask on forums.
If you're looking for private work, PM me.
joropito is offline
Send a message via MSN to joropito
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 08:53.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode