Counter - Strike Raid Attack V1

Một bản mod của nhóm SKIN COUNTER - STRIKE

CS - AVA ( Alliance of Valiant Arms )

Bản Mod được phát triển bởi AVG4 theo hướng AVA

CSFIRED

CSFIRED một thể loại game bắn súng offline được mod theo hướng CrossFire (Đột kích) với hình ảnh sắc nét, âm thanh sống động tạo cho người chơi cảm giác như mình đang sống trong thế giới ảo

Counter Strike he Magic Athletics CD 1.0.0.2

Game do Trung Quốc làm. Dựa trên nền tảng Compete King.

Counter Strike CE

Game do Trung Quốc làm. Đang rất hot trên Group SKIN COUNTER - STRIKE

Counter-Strike NTN 2014

Counter-Strike NTN là một bản mod của Counter-Strike 1.6 huyền thoại, được mod lại với mục đích cải thiện chất lượng đồ họa và âm thanh cũng như hệ thống vũ khí Counter-Strike 1.6 với đặc điểm nổi bật.

Showing posts with label AMX. Show all posts
Showing posts with label AMX. Show all posts

Thursday, June 26, 2014

Thay Đổi Model Vũ Khí (Extended)


Note if this example is in your plugin: If its 80%> of your whole script, I suggest you dont post it as a plugin.

This is a small example on changing weapon models for Counter-Strike. With this example you can change all 3 types of the model: view, player, and world. I have written one with Engine and Fakemeta for people who are not familiar with Fakemeta yet, and one only on fakemeta for L33T coders.

I hope this helps, so people dont need to keep posting about this ;).

Engine and Fakemeta


Code:
#include <amxmodx> 
#include <engine> 
#include <fakemeta> 

new VIEW_MODEL[]        = "models/v_<model name>.mdl" 
new PLAYER_MODEL[]        = "models/p_<model name>.mdl" 
new WORLD_MODEL[]    = "models/w_<model name>.mdl"

new OLDWORLD_MODEL[]    = "models/w_<model name>.mdl" // the world model you want replaced

new PLUGIN_NAME[]    = "Custom Weapon Model" 
new PLUGIN_AUTHOR[]         = "Cheap_Suit" 
new PLUGIN_VERSION[]        = "1.0" 

public plugin_init() 
{
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)     
    register_event("CurWeapon", "Event_CurWeapon", "be","1=1")
    register_forward(FM_SetModel, "fw_SetModel")
} 

public plugin_precache() 
{    
    precache_model(VIEW_MODEL)     
    precache_model(PLAYER_MODEL) 
    precache_model(WORLD_MODEL)
} 

public Event_CurWeapon(id) 
{     
    // might not work for other mods
    new weaponID = read_data(2) 
        
    // eg, if weapon is not ak then continue
    if(weaponID != CSW_AK47)
        return PLUGIN_CONTINUE
    
    // this set's the view model (what you see when holding the gun)
    entity_set_string(id, EV_SZ_viewmodel, VIEW_MODEL)  
    
    // this set's the player model (what you see when people holding the gun)
    entity_set_string(id, EV_SZ_weaponmodel, PLAYER_MODEL)         
    
    return PLUGIN_CONTINUE 
}

public fw_SetModel(entity, model[])
{
    // check if its a valid entity or else we'll get errors
    if(!is_valid_ent(entity)) 
        return FMRES_IGNORED

    // checks if it's the model we want to change
    if(!equali(model, OLDWORLD_MODEL)) 
        return FMRES_IGNORED

    new className[33]
    entity_get_string(entity, EV_SZ_classname, className, 32)

    //            dropped weapons                      map weapons                       c4 + grenades
    if(equal(className, "weaponbox") || equal(className, "armoury_entity") || equal(className, "grenade"))
    {
        // set's the world model (what you see on the ground)
        entity_set_model(entity, WORLD_MODEL)
        return FMRES_SUPERCEDE
    }
    return FMRES_IGNORED
}
Only Fakemeta

Code:
public Event_CurWeapon(id) 
{     
    // might not work for other mods
    new weaponID = read_data(2) 
        
    // eg, if weapon is not ak then continue
    if(weaponID != CSW_AK47)
        return PLUGIN_CONTINUE
    
    // this set's the view model (what you see when holding the gun)
    set_pev(id, pev_viewmodel, engfunc(EngFunc_AllocString, VIEW_MODEL))
    
    // this set's the player model (what you see when people holding the gun)
    set_pev(id, pev_weaponmodel, engfunc(EngFunc_AllocString, PLAYER_MODEL))
    
    return PLUGIN_CONTINUE 
}

public fw_SetModel(entity, model[])
{
    // check if its a valid entity or else we get errors
    if(!pev_valid(entity)) 
        return FMRES_IGNORED

    // checks if its the model we want to change
    if(!equali(model, OLDWORLD_MODEL)) 
        return FMRES_IGNORED

    new className[33]
    pev(entity, pev_classname, className, 32)
    
    //            dropped weapons                    map weapons                       c4 + grenades
    if(equal(className, "weaponbox") || equal(className, "armoury_entity") || equal(className, "grenade"))
    {
        engfunc(EngFunc_SetModel, entity, WORLD_MODEL)
        return FMRES_SUPERCEDE
    }
    return FMRES_IGNORED
}
Note: Using viewmodel2 and weaponmodel2.
For Fakemeta you don't need to allocate the string when using viewmodel2 or weaponmodel2.
Amended above example:

Code:
    // this set's the view model (what you see when holding the gun)
    set_pev(id, pev_viewmodel2, VIEW_MODEL)

    // this set's the player model (what you see when people holding the gun)
    set_pev(id, pev_weaponmodel2, PLAYER_MODEL)

Weapon ID reference

Code:
#define CSW_P228        1
#define CSW_SCOUT        3
#define CSW_HEGRENADE        4
#define CSW_XM1014        5
#define CSW_C4            6
#define CSW_MAC10        7
#define CSW_AUG            8
#define CSW_SMOKEGRENADE    9
#define CSW_ELITE        10
#define CSW_FIVESEVEN        11
#define CSW_UMP45        12
#define CSW_SG550        13
#define CSW_GALI        14
#define CSW_GALIL        14
#define CSW_FAMAS        15
#define CSW_USP            16
#define CSW_GLOCK18        17
#define CSW_AWP            18
#define CSW_MP5NAVY        19
#define CSW_M249        20
#define CSW_M3            21
#define CSW_M4A1        22
#define CSW_TMP            23
#define CSW_G3SG1        24
#define CSW_FLASHBANG        25
#define CSW_DEAGLE        26
#define CSW_SG552        27
#define CSW_AK47        28
#define CSW_KNIFE        29
#define CSW_P90            30

Example of changing the skin of the knife


Code:
#include <amxmodx> 
#include <engine> 
#include <fakemeta> 

new VIEW_MODEL[]    = "models/v_newKnife.mdl" 
new PLAYER_MODEL[]    = "models/p_newKnife.mdl" 
new WORLD_MODEL[]    = "models/w_knife.mdl"

new OLDWORLD_MODEL[]    = "models/w_knife.mdl"

new PLUGIN_NAME[]        = "Custom Knife Model" 
new PLUGIN_AUTHOR[]    = "Cheap_Suit" 
new PLUGIN_VERSION[]     = "1.0" 

public plugin_init() 
{
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR)     
    register_event("CurWeapon", "Event_CurWeapon", "be","1=1")
    register_forward(FM_SetModel, "fw_SetModel")
} 

public plugin_precache() 
{    
    precache_model(VIEW_MODEL)     
    precache_model(PLAYER_MODEL) 
    precache_model(WORLD_MODEL)
} 

public Event_CurWeapon(id) 
{     
    new weaponID = read_data(2) 

    if(weaponID != CSW_KNIFE)
        return PLUGIN_CONTINUE

    set_pev(id, pev_viewmodel2, VIEW_MODEL)
    set_pev(id, pev_weaponmodel2, PLAYER_MODEL)
    
    return PLUGIN_CONTINUE 
}

public fw_SetModel(entity, model[])
{
    if(!is_valid_ent(entity)) 
        return FMRES_IGNORED

    if(!equali(model, OLDWORLD_MODEL)) 
        return FMRES_IGNORED

    new className[33]
    entity_get_string(entity, EV_SZ_classname, className, 32)
    
    if(equal(className, "weaponbox") || equal(className, "armoury_entity") || equal(className, "grenade"))
    {
        engfunc(EngFunc_SetModel, entity, WORLD_MODEL)
        return FMRES_SUPERCEDE
    }
    return FMRES_IGNORED
}

Một Vài Thông Tin Về pev_body


pev_bodylà một giá trị mà nói với các trò chơi mà submodel cần được nhìn thấy được.

Điều này có thể vô cùng mạnh mẽ với các model player, ngoại trừ không ai dường như đã sử dụng tính năng này để tiềm năng của nó được nêu ra. Như của bây giờ và như xa như tôi biết, CS chỉ sử dụng này để hiển thị bom trên người chơi.

Những gì có thể được thực hiện với giá trị này?Ví dụ, bạn có thể đặt tất cả các model và mũ trên máy chủ của bạn thành một model duy nhất. Điều này có rất nhiều ưu hơn khuyết điểm (bên dưới).

Làm thế nào để bạn thay đổi kết hợp?
Hãy nói rằng bạn có hai nhóm submodel như tôi - model và hats.

ĐÂY KHÔNG PHẢI LÀ CÁCH NÓ HOẠT ĐỘNG.
Model1 - ID: 0
Model2 - ID: 1
Model3 - ID: 2
Hat1 - ID: 3
Hat2 - ID: 4
Hat3 - ID: 5

ĐÂY LÀ CÁCH NÓ HOẠT ĐỘNG
Model1 - ID: 0
Model2 - ID: 1
Model3 - ID: 2
Hat1 - ID: 0
Hat2 - ID: 1
Hat3 - ID: 2

Cho chỉ có hai nhóm, bạn muốn sử dụng để có được số lượng pev_body bạn cần:

Code:
pev_body = hat_id * amount_of_models + model_id

Vì vậy, hãy nói rằng bạn muốn cung cấp cho người chơi Model 2 với Hat 3.
pev_body = 2 * 3 + 1 = 7

Tôi đã không cố gắng làm việc với các nhóm hơn nữa, tôi sẽ báo cáo lại một lần tôi làm.


Những gì có thể được thực hiện với điều này?


Bạn có thể ví dụ như làm một plugin cho tùy biến nhân vật đầy đủ. Tạo ra một mô hình với các bộ phận cơ thể như khuôn mặt, mái tóc, kích thước ngực, vv và cho phép người chơi lựa chọn những gì phù hợp với mình.

Ưu điểm:

- Tất cả các model là trong một tập tin lớn hơn, mang đến cho một "cảm giác" tốt hơn khi tải
- Một cách tuyệt vời để giảm số lượng các tập tin trên máy chủ của bạn precached
- Kích thước tập tin nhỏ hơn rất nhiều so với tất cả các mô hình từng người một với nhau, bởi vì các bản sao (thông tin mô hình, hình động vv) được loại bỏ
- Đối với mũ và như vậy, bạn không cần một plugin của bên thứ 3 để xử lý nó (tạo ra một thực thể mới, đặt nó là nguồn gốc, vv)
- Model + mũ vẫn là một thực thể duy nhất
- Rất nhiều khả năng mới

Nhược Điểm:

- Thêm model hơn sẽ đòi hỏi một tải mới của tập tin hoàn chỉnh
- Không quá dễ dàng để làm việc với
- Trình biên dịch là một khốn
- Các mô hình cuối cùng yêu cầu tất cả các mô hình Counter-Strike đã tồn tại, nếu bạn muốn làm cho nón có sẵn cho các mô hình tiêu chuẩn như là tốt
- Người chơi sẽ không thể nhìn thấy mô hình tùy chỉnh của họ

Vấn đề hiện tại:

- Trình biên dịch vẫn bị treo vì một lý do, sản xuất một mô hình chưa hoàn thành (chia kết cấu)
- Cần phải tìm ra cách để thêm các mô hình chia thành các phần như một submodel. Hiện nay, nó cho biết thêm từng phần như một submodel (xem ví dụ mô hình: nhóm modely ', mô hình con 5 và 6
- Cần phải làm cho các quả bom có thể nhìn thấy, tôi sẽ thêm nó vào một nhóm hoàn toàn mới và xem những gì nó như thế nào.
- Edit: biên dịch rơi khi kích thước tập tin là trên 4 MB. Cố gắng tìm một khoảng cách này (model chia tách)
Nếu bạn biết làm thế nào để giải quyết bất kỳ vấn đề trên, vui lòng cho tôi biết.


Sử dụng plugin này nhỏ với mô hình bao gồm để xem tính năng này là những gì có khả năng

Code:
#include < amxmodx > #include < fakemeta > #include < cstrike >     new const cstModel[ ] = "models/player/testmdl/testmdl.mdl" new const cstModelT[ ] = "models/player/testmdl/testmdlt.mdl" new const cstMdlName[ ] = "testmdl" public plugin_precache( ) {     precache_model( cstModel )     precache_model( cstModelT ) } public plugin_init( ) {     register_clcmd( "pev_body", "_body" )     register_clcmd( "changemdl", "_changemdl" ) } public _body( id ) {     new szArgs[ 4 ]     read_args( szArgs, charsmax( szArgs ) )         remove_quotes( szArgs )     trim( szArgs )         new iPev = str_to_num( szArgs )         set_pev( id, pev_body, iPev )         client_print( id, print_console, "Changing your pev_body value to %d", iPev )         return PLUGIN_HANDLED } public _changemdl( id ) {     cs_set_user_model( id, cstMdlName )     client_print( id, print_console, "Your model was changed to %s. You can now change your pev_body value using console command 'pev_body'.", cstMdlName ) }

Bảng giá trị:

Code:
MODEL NAME   HAT   PEV_BODY

T Model 1   Indian Hat  0
T Model 2   Indian Hat  1 
CT Model 1   Indian Hat  2
Hitman    Indian Hat  3
Banana (eyes)   Indian Hat  4
Banana (rest)   Indian Hat  5
CT Model 2   Indian Hat  6
Assassin   Indian Hat  7

T Model 1   Afro   8
T Model 2   Afro   9 
CT Model 1   Afro   10
Hitman    Afro   11
Banana (eyes)   Afro   12
Banana (rest)   Afro   13
CT Model 2   Afro   14
Assassin   Afro   15

T Model 1   Minecraft  16
T Model 2   Minecraft  17 
CT Model 1   Minecraft  18
Hitman    Minecraft  19
Banana (eyes)   Minecraft  20
Banana (rest)   Minecraft  21
CT Model 2   Minecraft  22
Assassin   Minecraft  23

T Model 1   Fly   24
T Model 2   Fly   25 
CT Model 1   Fly   26
Hitman    Fly   27
Banana (eyes)   Fly   28
Banana (rest)   Fly   29
CT Model 2   Fly   30
Assassin   Fly   31

T Model 1   Wings (broken)  32
T Model 2   Wings (broken)  33 
CT Model 1   Wings (broken)  34
Hitman    Wings (broken)  35
Banana (eyes)   Wings (broken)  36
Banana (rest)   Wings (broken)  37
CT Model 2   Wings (broken)  38
Assassin   Wings (broken)  39
Bạn có thể xem submodels trong HLMV trong "bộ phận cơ thể" tab.

UPDATE

Thanks for reading.

HUGE UPDATE

Được rồi, đây là nhận được thậm chí tốt hơn so với tôi nghĩ rằng nó sẽ.

Ảnh động
Mỗi mô hình có khoảng 120 trình tự. Có gì buồn cười về việc này là một mô hình trung bình có kích cỡ 2.3MB - 2

megabytesđó là những hình ảnh động. Có nghĩa là nếu bạn đang đi để kết hợp 5 mô hình kích thước 2.3MB mỗi, kích thước cuối cùng của bạn sẽ được 2MB cho các hình ảnh động + 5 * 300kB = 3.5MB tổng số.

Bomb and defusal kit
Tôi đã thực hiện những mô hình mới trong của tôi. Chức năng để có được ID pev_body như sau:

Code:
stock get_bodyid( iModelId, iHatId, bool: bBomb, bool: bDefusalKit ) {     new iPevBody = iHatId * g_TotalModels + iModelId         if( bBomb )         iPevBody += ( g_TotalModels * g_TotalHats )             if( bDefusalKit )         iPevBody += ( g_TotalModels * g_TotalHats * 2 )         return iPevBody }
Tôi không chắc chắn về điều này - đã không kiểm tra được chưa.

New model
Các mô hình mới là trong file đính kèm. Có 17 model và 39 mũ - tổng kích thước: 11.15MB. Tôi đã gỡ bỏ các hình ảnh động lá chắn, vì họ vô ích cho tôi. Hai mô hình là bản sao (xấu của tôi), vì tôi quên để đổi tên các kết cấu trong số này, vì vậy họ chỉ thay thế các kết cấu khác.

Limits

Các giới hạn cho các mô hình kết hợp là:
- Tối đa 16MB kích cỡ
- Tên Texture đôi khi cần phải được thay đổi hoặc họ sẽ bị ghi đè bởi các mô hình khác
- Tối đa 40 phụ model cho mỗi nhóm (39 mũ, bởi vì là người đầu tiên có sản phẩm nào)

Lưu ý các HatID đầu tiên không còn 0 (ID 0 là "không có gì", chúng tôi đang thiết HatID 0 cho những người không có bất kỳ mũ)

Monday, June 9, 2014

How to detect if player is visible. - Làm Thế Nào Để Phát Hiện Nếu Người Chơi Có Thể Nhìn Thấy


Trước Khi Đọc.
Hướng dẫn này được thực hiện đặc biệt dành cho scripters mà biết làm thế nào để làm việc với vectơ. 
Tôi sẽ cố gắng giải thích các mã càng nhiều càng tốt để mà ngay cả người dùng biết một chút ít về họ sẽ có thể hiểu! 
Này "làm thế nào để" đã được thực hiện đặc biệt cho những người muốn thực hiện điều này trong các plugin của họ. 
Lưu ý: Đây là một phương pháp rất hiệu quả, vấn đề duy nhất là có những tình huống hiếm hoi khi bạn không nhìn thấy một cầu thủ. Nhưng điều đó sẽ không là một vấn đề. 
Lưu ý: Hướng dẫn này áp dụng đối với CS nhưng có thể được thực hiện trong mods khác! Tất cả những gì bạn cần làm là chỉ cần thay đổi các hằng số để phù hợp của bạn!

Mã và mô tả:

Trước hết chúng ta cần một số hằng số:

  • Đầu tiên chúng ta cần định nghĩa một số hằng số đó sẽ có ích!
Các hằng số được sử dụng như là hằng số nhân. Chúng tôi sử dụng chúng để tạo ra một số mảng sẽ được sử dụng khi tính toán Nếu người chơi có thể nhìn thấy!
Đây là những cái mà cần phải được sửa đổi nếu bạn không hài lòng bởi kết quả mà bạn đang nhận được!
PHP Code:
#define GENERAL_X_Y_SORROUNDING             18.5         // 16.0
#define CONSTANT_Z_CROUCH_UP                 31.25         // 32.0
#define CONSTANT_Z_CROUCH_DOWN                 17.5         // 16.0
#define CONSTANT_Z_STANDUP_UP                 34.0         // 36.0
#define CONSTANT_Z_STANDUP_DOWN             35.25         // 36.0

#define GENERAL_X_Y_SORROUNDING_HALF        9.25         // 8.0
#define GENERAL_X_Y_SORROUNDING_HALF2        12.0         // 8.0
#define CONSTANT_Z_CROUCH_UP_HALF             15.5         // 16.0
#define CONSTANT_Z_CROUCH_DOWN_HALF            8.75         // 8.0
#define CONSTANT_Z_STANDUP_UP_HALF            17.0         // 18.0
#define CONSTANT_Z_STANDUP_DOWN_HALF        17.5         // 18.0

#define ANGLE_COS_HEIGHT_CHECK                0.7071        // cos(45  degrees)  
  • Bây giờ chúng ta cần một số mảng cung cấp các plugin thứ tự của các tính toán.
PHP Code:
// Cái này dùng để xác định weapon head point 
new const Float:weapon_edge_point[CSW_P90+1] =
{
    
0.00, 35.5, 0.00, 42.0, 0.00, 35.5, 0.00, 37.0, 37.0, 0.00, 35.5, 35.5, 32.0, 41.0, 32.0, 36.0, 41.0, 35.5, 41.0, 32.0, 37.0, 35.5, 42.0, 41.0, 44.0, 0.00, 35.5, 37.0, 32.0, 0.00, 32.0 }// Điều này được sử dụng như một mảng nhân bên

new const Float:vec_multi_lateral[] =
{
    
GENERAL_X_Y_SORROUNDING,
    -
GENERAL_X_Y_SORROUNDING,
    
GENERAL_X_Y_SORROUNDING_HALF2,
    -
GENERAL_X_Y_SORROUNDING_HALF }// This is used as height multiplicator if the user crouches! 

new const Float:vec_add_height_crouch[] =
{
    
CONSTANT_Z_CROUCH_UP,
    -
CONSTANT_Z_CROUCH_DOWN,
    
CONSTANT_Z_CROUCH_UP_HALF,
    -
CONSTANT_Z_CROUCH_DOWN_HALF }// This is used as height multiplicator if the user stands up! 

new const Float:vec_add_height_standup[] =
{
    
CONSTANT_Z_STANDUP_UP,
    -
CONSTANT_Z_STANDUP_DOWN,
    
CONSTANT_Z_STANDUP_UP_HALF,
    -
CONSTANT_Z_STANDUP_DOWN_HALF }  
Secondly we need some variables:
  • Một dấu vết xử lý để lưu các kết quả phần (đối với khả năng hiển thị điểm)
Điều này là cần thiết bởi vì chúng tôi không muốn các plugin để can thiệp với các plugin khác kết quả và ngược lại!
PHP Code:
new thldpublic plugin_init()
{
    
// We create it in plugin_init
    
thdl = create_tr2()
}

public 
plugin_end()
{
    
// We free it on plugin end
    
free_tr2(thdl)
}  
  • Chúng tôi cũng cần một danh sách mà chúng ta có thể lưu các loại thực thể nếu các thực thể của chúng tôi là trong suốt hay không!
Phần này được thực hiện bằng cách sử dụng trong trường hợp này bitsums, cho thêm thông tin về họ đọc này! read this!
Điều này là cần thiết khi kiểm tra plugin của chúng tôi cho khả năng hiển thị người chơi offen!

PHP Code:
// These bitsums allow 2048 entities storage. I think that it is enough :P. 
new bs_array_transp[64]                
// BitSum, This is equal to 64*32 bools (good for quick search) 
new bs_array_solid[64]                 
// BitSum, This is equal to 64*32 bools (good for quick search)  
Để xử lý những bitsums dễ dàng Tôi đã thực hiện một số hàm vĩ mô sẽ làm cho mã dễ đọc!
PHP Code:
#define add_transparent_ent(%1)         bs_array_transp[((%1 - 1) / 32)] |= (1<<((%1 - 1) % 32))
#define del_transparent_ent(%1)         bs_array_transp[((%1 - 1) / 32)] &= ~(1<<((%1 - 1) % 32))
#define  is_transparent_ent(%1)        (bs_array_transp[((%1 - 1) / 32)] & (1<<((%1 - 1) % 32)))
#define add_solid_ent(%1)               bs_array_solid[((%1 - 1) / 32)] |= (1<<((%1 - 1) % 32))
#define del_solid_ent(%1)               bs_array_solid[((%1 - 1) / 32)] &= ~(1<<((%1 - 1) % 32))
#define  is_solid_ent(%1)              (bs_array_solid[((%1 - 1) / 32)] & (1<<((%1 - 1) % 32)))  
Thứ ba, chúng ta cần một số hàm hữu ích, sẽ được sử dụng trong các thử nghiệm của chúng tôi:
  • Các chức năng theo dõi
PHP Code:
// This function checks if a point is visible from start to point! It will ignore glass and players! Also it will ignore the ignore_ent! bool:is_point_visible(const Float:start[3], const Float:point[3], ignore_ent)
{
    
engfunc(EngFunc_TraceLine, start, point, IGNORE_GLASS | IGNORE_MONSTERS, ignore_ent, thdl)

    static 
Float:fraction
    get_tr2
(thdl, TR_flFraction, fraction)
   
    
// We will return the fraction
    // If 1.0 that means that we didn't hit anything
    
return (fraction == 1.0)
}
// This function is the same as above but will also check if the entity that we hited can be seen through bool:is_point_visible_texture(const Float:start[3], const Float:point[3], ignore_ent)
{
    
engfunc(EngFunc_TraceLine, start, point, IGNORE_GLASS | IGNORE_MONSTERS, ignore_ent, thdl)
   
    
// We save also the entity
    
static ent
    ent 
= get_tr2(thdl, TR_pHit)

    static 
Float:fraction
    get_tr2
(thdl, TR_flFraction, fraction)
   
    
// If we hit something start the checks
    
if (fraction != 1.0 && ent > 0)
    {
        
// That means that we didn't know what we hited
        
if (!is_transparent_ent(ent) && !is_solid_ent(ent))
        {
            static 
texture_name[2]
            static 
Float:vec[3]
            
// These calculations are made for security measures
            // TraceTexture function will crash the server if used on short distances
            
xs_vec_sub(point, start, vec)
            
xs_vec_mul_scalar(vec, (5000.0 / xs_vec_len(vec)), vec)
            
xs_vec_add(start, vec, vec)
           
            
engfunc(EngFunc_TraceTexture, ent, start, vec, texture_name, charsmax(texture_name))
           
            
// If texture_name begins with { that means that we have a trasnaparent texture,
            // if yes we will retrace and add that entity to our list as a transparent!
            // If not then we add id as solid so it will not be needed to do the checks again!
            
if (equal(texture_name, "{"))
            {
                
add_transparent_ent(ent)
                
ignore_ent = ent
                engfunc
(EngFunc_TraceLine, start, point, IGNORE_GLASS | IGNORE_MONSTERS, ignore_ent, thdl)
                
get_tr2(thdl, TR_flFraction, fraction)
                return (
fraction == 1.0)
            }
            else
            {
                
add_solid_ent(ent)
                return (
fraction == 1.0)
            }
        }
        
// This means that the entity is registered as solid or transparent so on with the checks
        
else
        {
            if (
is_solid_ent(ent))
            {
                return (
fraction == 1.0)
            }
            else
            {
                
ignore_ent = ent
                engfunc
(EngFunc_TraceLine, start, point, IGNORE_GLASS | IGNORE_MONSTERS, ignore_ent, thdl)
                
get_tr2(thdl, TR_flFraction, fraction)
                return (
fraction == 1.0)
            }
        }
    }
   
    return (
fraction == 1.0)
}  
  • Vector functions [taken from xs.inc]
PHP Code:
// This will add two vectors stock xs_vec_add(const Float:in1[], const Float:in2[], Float:out[])
{
    
out[0] = in1[0] + in2[0];
    
out[1] = in1[1] + in2[1];
    
out[2] = in1[2] + in2[2];
}
// This will substract two vectors stock xs_vec_sub(const Float:in1[], const Float:in2[], Float:out[])
{
    
out[0] = in1[0] - in2[0];
    
out[1] = in1[1] - in2[1];
    
out[2] = in1[2] - in2[2];
}
// This will multiply a vector with a scalar stock xs_vec_mul_scalar(const Float:vec[], Float:scalar, Float:out[])
{
    
out[0] = vec[0] * scalar;
    
out[1] = vec[1] * scalar;
    
out[2] = vec[2] * scalar;
}
// This will return the vector length stock Float:xs_vec_len(const Float:vec[3])
{
    return 
floatsqroot(vec[0]*vec[0] + vec[1]*vec[1] + vec[2]*vec[2]);
}
// This will make a scalar multiplication between two vectors stock Float:xs_vec_dot(const Float:vec[], const Float:vec2[])
{
    return (
vec[0]*vec2[0] + vec[1]*vec2[1] + vec[2]*vec2[2])
}
// This will check whether two vectors are equal bool:xs_vec_equal(const Float:vec1[], const Float:vec2[])
{
    return (
vec1[0] == vec2[0]) && (vec1[1] == vec2[1]) && (vec1[2] == vec2[2]);
}  
Fourthly we need to add some entities that we already know that can be seen through this can be done using this:
PHP Code:
public plugin_precache()
{
    
register_forward(FM_Spawn, "fw_spawn", 1)
}

public 
fw_spawn(ent)
{
    if (!
pev_valid(ent))
        return 
FMRES_IGNORED
   
    
static rendermode, Float:renderamt
   
    rendermode 
= pev(ent, pev_rendermode)
    
pev(ent, pev_renderamt, renderamt)
   
    
// If transparent then add it to the list!
    
if (((rendermode == kRenderTransColor || rendermode == kRenderGlow || rendermode == kRenderTransTexture) && renderamt < 255.0) || (rendermode == kRenderTransAdd))
    {
        
add_transparent_ent(ent)
        return 
FMRES_IGNORED
    
}
   
    return 
FMRES_IGNORED }  
Now having all the constants, variables and functions we can get on creating the stock that will show us whether a player is visible:
PHP Code:
stock is_player_visible(visor, target)
{
    
// Declarations, bla bla
    
static Float:origin[3], Float:start[3], Float:end[3], Float:addict[3], Float:plane_vec[3], Float:normal[3], ignore_ent
   
    
// The ignore entity is our visor at first (if needed we will change it!
    // This will be used in the point tests!
    
ignore_ent = visor
   
    
// First of all we check if the player is behind the visor or not
    // We get the visor origin
    
pev(visor, pev_origin, origin)
   
    
// We get the view angles of the visor
    
pev(visor, pev_v_angle, normal)
    
// We turn the angle vector into a direction vector
    
angle_vector(normal, ANGLEVECTOR_FORWARD, normal)
   
    
// We get the targets origin, this will be used to deremine if it the player is behind us
    
pev(target, pev_origin, end)
    
// We substract the two vectors to obtain a directional vector!
    
xs_vec_sub(end, origin, plane_vec)
    
// We normalize the vector so that we will be able to obtain the real angle between the vectors
    
xs_vec_mul_scalar(plane_vec,  (1.0/xs_vec_len(plane_vec)), plane_vec)
   
    
// When we multiply two vectors that are normalized (their length is 1)
    // We will obtain the cosinus of the angle between them, if this is negative then that means that the player is behind, so we return false!
    
if (xs_vec_dot(plane_vec, normal) < 0)
    {
        return 
false
    
}
   
    
// We get the view offsets and we add them to the origin to obtain the eye origin
    
pev(visor, pev_view_ofs, start)
    
xs_vec_add(start, origin, start)
   
    
// Origin becomes end
    
origin = end
   
    
// Until now we have 2 important vectors
    // start - that is the eye origin of the visor
    // origin - that is the target origin (usefull later)
   
    // This is used only once to update the ignore_ent
    // If point is visible then guess what, returning true!
    
if (is_point_visible_texture(start, origin, ignore_ent))
        return 
true
   
    
// This will get the view offsets of the target, we will add them to obtain the eye origin
    
pev(target, pev_view_ofs, end)
    
xs_vec_add(end, origin, end)
   
    
// If eye origin is visible return true!
    
if (is_point_visible(start, end, ignore_ent))
        return 
true
   
    
// Check weapon point, first we need to check if it is no equal to 0
    
if (weapon_edge_point[get_user_weapon(target)] != 0.00)
    {
        
// We get the view angles and turn them in directional vectors
        
pev(target, pev_v_angle, addict)
        
angle_vector(addict, ANGLEVECTOR_FORWARD, addict)
        
// We multiply it to obtain the weapon headpoint
        
xs_vec_mul_scalar(addict, weapon_edge_point[get_user_weapon(target)], addict)
        
// We add it to the end origin to obtain the weapon headpoint
        
xs_vec_add(end, addict, end)
       
        
// If weapon head is visible true!
        
if (is_point_visible(start, end, ignore_ent))
            return 
true
    
}
   
    
// We subtract them to obtain o directional vector that will be used in plane calculations!
    
xs_vec_sub(start, origin, normal)
   
    
// We have now an extra important vector
    // normal - a directional vector between the start vector and the target origin
   
    // This is the moment when we move on to plane checks
    // These functions will create a plane that will rotate based on player position
    // The checks will be done on points that will exist on this plane!
   
    // First of all we normalize the normal vector
    // This will be important when we have height problems.
    
xs_vec_mul_scalar(normal, 1.0/(xs_vec_len(normal)), normal)
    
// We turn the vector into an angle vector
    
vector_to_angle(normal, plane_vec)
    
// This will create a vector that will be orthogonal/perpendicular with the normal vector!
    // This must be done to easily create the plane!
    
angle_vector(plane_vec, ANGLEVECTOR_RIGHT, plane_vec)
   
    
// This will check if we are almost at the same level with the target
    
if (floatabs(normal[2]) <= ANGLE_COS_HEIGHT_CHECK)
    {
        
// We check whether the target crouches
        // This is important to determine what multiplicator vector to use!
        // This will create the plane
        
if (pev(target, pev_flags) & FL_DUCKING)
        {
            for (new 
i=0;i<4;i++)
            {
                if (
i<2)
                {
                    for (new 
j=0;j<2;j++)
                    {
                        
// We multiply the directional vector and add it to the origin after that we check if it is visible
                        // The same happens in the other places so this one will be the only one that will be commented!
                        
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                        
addict[2] = vec_add_height_crouch[j]
                        
xs_vec_add(origin, addict, end)
                       
                        if (
is_point_visible(start, end, ignore_ent))
                            return 
true
                    
}
                }
                else
                {
                    for (new 
j=2;j<4;j++)
                    {
                        
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                        
addict[2] = vec_add_height_crouch[j]
                        
xs_vec_add(origin, addict, end)
                       
                        if (
is_point_visible(start, end, ignore_ent))
                            return 
true
                    
}
                }
            }
        }
        else
        {
            for (new 
i=0;i<4;i++)
            {
                if (
i<2)
                {
                    for (new 
j=0;j<2;j++)
                    {
                        
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                        
addict[2] = vec_add_height_standup[j]
                        
xs_vec_add(origin, addict, end)
                       
                        if (
is_point_visible(start, end, ignore_ent))
                            return 
true
                    
}
                }
                else
                {
                    for (new 
j=2;j<4;j++)
                    {
                        
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                        
addict[2] = vec_add_height_standup[j]
                        
xs_vec_add(origin, addict, end)
                       
                        if (
is_point_visible(start, end, ignore_ent))
                            return 
true
                    
}
                }
            }
        }
    }
    else
    {
        
// This is the same as the one above
        // The only difference is that it also uses normal vector to move the points in front and in behind!
        // Here is checked if you are above the player
        
if (normal[2] > 0.0)
        {
            
normal[2] = 0.0
            xs_vec_mul_scalar
(normal, 1/(xs_vec_len(normal)), normal)
       
            if (
pev(target, pev_flags) & FL_DUCKING)
            {
                for (new 
i=0;i<4;i++)
                {
                    if (
i<2)
                    {
                        for (new 
j=0;j<2;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_crouch[j]
                            
xs_vec_add(origin, addict, end)
                            
xs_vec_mul_scalar(normal, (j == 0) ? (-GENERAL_X_Y_SORROUNDING) : (GENERAL_X_Y_SORROUNDING), addict)
                            
xs_vec_add(end, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                    else
                    {
                        for (new 
j=2;j<4;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_crouch[j]
                            
xs_vec_add(origin, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                }
            }
            else
            {
                for (new 
i=0;i<4;i++)
                {
                    if (
i<2)
                    {
                        for (new 
j=0;j<2;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_standup[j]
                            
xs_vec_add(origin, addict, end)
                            
xs_vec_mul_scalar(normal, (j == 0) ? (-GENERAL_X_Y_SORROUNDING) : (GENERAL_X_Y_SORROUNDING), addict)
                            
xs_vec_add(end, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                    else
                    {
                        for (new 
j=2;j<4;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_standup[j]
                            
xs_vec_add(origin, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                }
            }
        }
        else
        {
            
normal[2] = 0.0
            xs_vec_mul_scalar
(normal, 1/(xs_vec_len(normal)), normal)
           
            if (
pev(target, pev_flags) & FL_DUCKING)
            {
                for (new 
i=0;i<4;i++)
                {
                    if (
i<2)
                    {
                        for (new 
j=0;j<2;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_crouch[j]
                            
xs_vec_add(origin, addict, end)
                            
xs_vec_mul_scalar(normal, (j == 0) ? GENERAL_X_Y_SORROUNDING : (-GENERAL_X_Y_SORROUNDING), addict)
                            
xs_vec_add(end, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                    else
                    {
                        for (new 
j=2;j<4;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_crouch[j]
                            
xs_vec_add(origin, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                }
            }
            else
            {
                for (new 
i=0;i<4;i++)
                {
                    if (
i<2)
                    {
                        for (new 
j=0;j<2;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_standup[j]
                            
xs_vec_add(origin, addict, end)
                            
xs_vec_mul_scalar(normal, (j == 0) ? GENERAL_X_Y_SORROUNDING : (-GENERAL_X_Y_SORROUNDING), addict)
                            
xs_vec_add(end, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                    else
                    {
                        for (new 
j=2;j<4;j++)
                        {
                            
xs_vec_mul_scalar(plane_vec, vec_multi_lateral[i], addict)
                            
addict[2] = vec_add_height_standup[j]
                            
xs_vec_add(origin, addict, end)
                           
                            if (
is_point_visible(start, end, ignore_ent))
                                return 
true
                        
}
                    }
                }
            }
        }
    }
   
    
// None visible?
    
return false }  
How to see the points that are tested?
Well you just need to do add this to the code in the plugin.

PHP Code:
stock spr_bombpublic plugin_precache()
{
    
spr_bomb = precache_model("sprites/ledglow.spr")
}
stock bomb_led(const Float:point[3])
{
    
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
    
write_byte(TE_GLOWSPRITE)
    
engfunc(EngFunc_WriteCoord, point[0])
    
engfunc(EngFunc_WriteCoord, point[1])
    
engfunc(EngFunc_WriteCoord, point[2])
    
write_short(spr_bomb)
    
write_byte(1)
    
write_byte(3)
    
write_byte(255)
    
message_end()
}  
And change the functions "is_point_visible" and "is_point_visible_texture" into this:
PHP Code:
bool:is_point_visible(const Float:start[3], const Float:point[3], ignore_ent)
{
    
bomb_led(point)
    return 
false }bool:is_point_visible_texture(const Float:start[3], const Float:point[3], ignore_ent)
{
    
bomb_led(point)
    return 
false