原文地址 https://www.iddevnet.com/doom3/script.php
需要先翻牆以後人機驗證,才能訪問原英文網站,我強烈建議讀者訪問該英文網站。
譯文如下
doom3腳本部分,
腳本與Doom 3 c++的編程大致相同,您可以無需購買Visual C ++即可。該語言與C ++類似,但可以說更容易學習和使用。
Doom 3中有三個主要組件由腳本控制:
我按照難度順序列出了他們。地圖腳本很容易編寫和理解,武器腳本相當簡單,AI腳本相當複雜。
審查系統是圍繞對象和事件的思想。
對象被引用$ name,其中“name”是DOOMEdit中對象的名稱。
事件看起來像C ++成員函數調用,你可以真正想到這樣的方式。要將'hide'事件發送到speaker_280,你會寫$ speaker_280.hide();
被稱爲“sys”的特殊對象是所有系統調用(如打印)隱藏的地方。所有事件(包括系統調用)都可以在“doom_events.script”中找到
地圖腳本
地圖腳本允許級別設計者創建比以前可能的舊的目標/觸發器系統更高級的欺騙(儘管目標/觸發器系統沒有消失,它們並行工作)。當地圖啓動時,將調用worldspawn“call”鍵中指定的功能。該功能可以執行額外的設置,生成線程等。最好的解釋方法就是以示例的方式打開map_marscity2.script。
在火星城2腳本中首先要注意的是命名空間map_marscity2。DoomScript中的命名空間與C ++中的命名空間相同,它們提供了一種方便的方式來分離另外可能具有相同名稱的函數和變量。由於我們在map_marscity2命名空間中包含了所有的功能,所以我們不用擔心使用與我們其中一個函數名稱相同的函數的另一個地圖。
marscity2.map中的“call”鍵設置爲map_marscity2 :: main,它定義在map_marscity2.script的底部。雙冒號與C ++中的工作方式相同,並指定函數所在的命名空間。在此示例中,所有主要功能都是從video_request_speaker函數(上面定義)創建一個線程。
如果您不太確定C ++中的線程是什麼,不用擔心,因爲DoomScript中的線程略有不同。它們是微型線程而不是操作系統線程,但這並不重要。通常當您調用函數時,您的代碼將停止,直到該函數完成,但是當您創建一個線程來調用該函數時,代碼將繼續進行。
在marscity2示例中,我們必須創建一個線程,因爲“video_request_speaker”函數很長一段時間循環(更具體地說,只要“request_speaker”設置爲1)它就循環。該功能播放“請求的視頻鏈接”聲音,等待一秒鐘,然後再次執行。
當你走到終端,你打了一個觸發器,“call”設置爲map_marscity2 :: connect_sarge_speaker。
如果我們檢查該函數,我們看到第一件事情是將“request_speaker”設置爲0,這導致“video_request_speaker”線程中的“while”循環退出。然後,它告訴“speaker_280”(這是“請求的視頻鏈接”)來停止播放聲音,觸發“sarge_monitor”實體(這會導致屏幕上彈出一個信息)和“speaker_281”(“connection established”) 。它等待四分之一秒鐘,觸發“speaker_282”(sarges speech),並再次觸發監視器(這導致Sarge在屏幕上彈出)。最後,觸發“relay_111”等待32秒,然後觸發一堆垃圾,如“提供安全許可”和“停止說話”。
最後一部分也可以在腳本中等待32秒,然後通過腳本觸發一切,但這個特定的級別的設計師決定只是觸發繼電器,並讓它做所有的工作。使用中繼而不是腳本來實現的主要優點是更容易看到和編輯在輻射。
武器腳本
武器腳本可以做地圖腳本可以做的一切,他們只是沒有這麼多的對象來撫摸。
關於武器腳本最令人困惑的事情可能是它是一個類型爲idWeapon的對象。這意味着您不必在發送事件時指定對象名稱,因爲它將事件發送到自身。經驗豐富的C ++程序員將把它視爲隱藏的這個指針。
通常你會說$ something.hide(); 但是當函數在一個對象中被定義時,你可以只說一下hide(); 它會自動知道對象是什麼。在武器腳本的情況下,對象是武器本身。當您看到AI腳本(對象將是怪物)時,您將再次看到它。
我們來分析一下這個weapon_pistol.script。在#define部分之後,我們轉發聲明了weapon_pistol對象,並說它將繼承自weapon_base。繼承使我們能夠在武器庫中放置一些常用功能,並將其提供給所有武器。我們指定什麼變量和功能將在我們的武器。在對象定義之後,我們發現我們說的所有函數的聲明。
當一個武器被選中(用脈衝命令或者拾取它)時,在武器對象上調用init函數。通常這將從武器entityDef讀取一些默認值,並將武器狀態設置爲“提升”。
武器狀態功能是驅動武器代碼的關鍵。此功能控制從武器對象中的成員函數定義的各種武器狀態的轉換。第一個參數是要切換到的狀態的名稱(應該是一個函數名),第二個參數是在狀態更改期間混合動畫的幀數。
一個狀態變化的一個很好的例子是在weapon_pistol :: Reload中。該函數啓動重新加載動畫並等待它完成。然後它將一些子彈添加到剪輯並轉換到空閒狀態。animDone函數將共享計數作爲第二個參數。在這種情況下,混合計數是4,所以當動畫中只剩下4幀時,它將返回true。我們將相同的值傳遞給weaponState功能,所以它知道在當前動畫中還有4幀可以播放。武器狀態功能存儲這些信息,所以當空閒動畫開始播放時,前4個幀與前一個動畫的最後4個幀(重新加載)混合。
這種動畫混合可以在完全不同的動畫之間進行平滑的轉換,而不會發生真正的醜陋動作。
getOwner | 返回持有該武器的玩家實體 |
接下來的武器 | 循環到玩家庫存中的下一個武器 |
武器狀態[狀態],[混合] | (如上所述) |
useAmmo [amount] | 從剪輯中減去彈藥 |
addToClip [amount] | 將彈藥添加到剪輯 |
ammoInClip | 返回剪輯中有多少彈藥 |
ammoAvailable | 返回剩下多少張照片 |
totalAmmoCount | 返回剩下多少彈藥 |
clipSize | 返回剪輯的大小 |
weaponOutOfAmmo | 告訴遊戲代碼,武器是彈藥 |
weaponReady | 告訴遊戲代碼,武器準備開火了 |
weaponReloading | 告訴玩具正在重新加載的遊戲代碼 |
weaponHolstered | 告訴遊戲代碼,武器被降低 |
weaponRising | 告訴遊戲代碼,武器正在上升 |
weaponLowering | 告訴遊戲代碼,武器正在降低 |
手電筒[啓用] | 啓用或禁用常規槍口閃光燈 |
launchProjectiles [numProjectiles], [spread],[fuseOffset], [launchPower],[dmgPower] |
在武器entityDef中發射由“def_projectile”定義的射彈。它還從剪輯中減去適量的彈藥,設置槍口閃光和煙霧,在AI附近發出警報,踢視圖,並重置着色器第4和第5(多樣性和時間偏移)。
numProjectiles指定啓動了多少個彈丸。 |
createProjectile | 創建並返回由“def_projectile”定義的新的彈丸實體。除了返回它,它實際上並不對彈道做任何事情。幾乎每次都可能要使用launchProjectiles。這個功能目前只被手榴彈用來附加聲音。 |
ejectBrass | 隨機拋出由“def_ejectBrass”鍵定義的武器entityDef中的一些碎片實體。 |
亂鬥 | 檢查“melee_distance”範圍內的實體,並執行由“def_melee”定義的任何內容。這包括推動,竊取和破壞另一個實體(以及執行聲音)。如果有人被擊中,則返回true。 |
getWorldModel |
返回實際的動畫武器模型的實體。 目前僅被chaingun用於旋轉桶的模型。 |
allowDrop [allow] |
傳遞真實,以防止玩家掉落武器。 目前僅在BFG過度充電時使用。 |
isInvisible | 返回true,如果播放器有不可見性加電 |
自動重載 | 如果播放器設置了“ui_autoReload”,則返回true。 |
netReload | 此功能將導致服務器向客戶端發送重新加載事件。重新加載事件信號WEAPON_NETRELOAD,武器腳本捕獲在客戶端重新加載。這是需要的,所以你可以看到其他客戶端重新加載他們的武器。在更改爲“重新加載”武器狀態之前,應該始終調用它。 |
netEndReload |
類似於netReload,但當武器完成重新加載時調用。 目前只用於霰彈槍(因爲可以中止重新加載)。 |
AI腳本
AI本比地圖或武器腳本複雜幾個數量級。我真的不會嘗試觸摸他們,除非你知道C ++真的很好。
伯尼可能有最簡單的ai腳本(他只是走向你試圖嘲笑你),但即使這比大多數武器腳本更復雜。
稍後我會提供更多的文件。
findEnemy [useFOV] | 返回演員可以看到的第一個活的敵人。如果useFOV是true,那麼它只返回actors中的敵人。如果演員在玩家PVS之外,則返回null。 |
findEnemyAI [useFOV] | 返回演員可以看到的最近的敵人(而不是第一個敵人,可能不是最接近的)。否則行爲像findEnemy。 |
findEnemyInCombatNodes | 返回此演員所針對的戰鬥節點可見的第一個活的敵人。 |
nearestReachableEnemyOfEntity [entity] | 返回最接近指定實體的生物敵人。哨兵使用這個來攻擊靠近玩家的演員。 |
hearSound [ignore_team] | 如果在演員區域中創建了警報聲,則此功能將返回聲音。否則返回null。 ignore_team將使其跳過團隊成員發出的聲音。 |
setEnemy [entity] | 如果這個演員到實體設置敵人。 |
clearEnemy | 設置這個演員沒有敵人。 |
muzzleFlash [聯名] | 觸發聯合命名的槍口閃光jointname |
createMissile [jointname] | 創建一個綁定到聯合名爲jointname的聯合名稱的actor(由actor entityDef中的“def_projectile”指定),然後返回彈丸。 |
attackMissile [聯名] | 從聯合命名的聯合名稱向敵人發射彈藥。返回彈丸實體。 |
fireMissileAtTarget [jointname], [targetname] |
在指定的目標實體上發射彈體。否則的行爲就像attackMissile。 |
launchmissile [origin],[angles] | 從指定的起點和角度發射射彈。返回彈藥。 |
attackMelee [meleeDef] | 使用指定的近戰damageDef執行近戰攻擊(有關示例定義,請參閱actor_zombie_commando.def中的melee_commandoTentacle)。如果它打了東西,返回true。 |
directDamage [target],[damageDef] | 使用damageDef指定的damageDef對目標實體造成直接損害。 |
radiusDamageFromJoint [jointname], [damageDef] |
使用指定的damageDef執行半徑損傷。半徑的中心附在由聯名指定的關節上。 |
attackBegin [damageDef] | 開始攻擊,如果演員在攻擊過程中觸動任何事情,他將使用指定的damageDef對對象造成直接傷害。 |
attackEnd | 結束攻擊 |
meleeAttackToJoint [jointname], [damageDef] |
使用指定的damageDef對眼睛位置和指定關節之間的任何實體進行直接傷害。突擊隊使用這種方法來破壞觸手術的任何東西。 |
randomPath | 隨機返回此actor定位的路徑實體之一。 |
canBecomeSolid | 如果沒有與此演員碰撞幾何相交,則返回true。 |
becomeSolid | 使演員穩固。啓用和鏈接演員剪輯模型,並允許演員受到傷害(假設“noDamage”未設置)。 |
becomeRagdoll | 把演員變成一個布娃娃。用於使Ed(科學家與燈)'最終'死亡。 |
stopRagdoll | 禁用抹布並將控制權返回給動畫師。用於由Archvile復活的怪物。 |
setHealth [健康] | 設置演員的健康狀況。用於復原的東西,也是MC地下科學家變成殭屍的科學家。 |
getHealth | 返回演員的健康狀況。 |
allowDamage | 使演員受到傷害。 |
ignoreDamage | 使演員不會受到傷害。 |
getCurrentYaw | 返回演員的當前偏航角(朝向,朝向)。 |
轉到[角] | 設置演員的理想偏航(實際上不設置偏航,演員將轉過幾幀)。 |
turnToPos [position] | 爲演員設定理想的偏航,使他面對指定的位置。 |
turnToEntity [實體] | 爲演員設置理想的偏航,因此他面向指定的實體。 |
moveStatus |
返回actor的當前移動狀態,它是以下之一: MOVE_STATUS_DONE,MOVE_STATUS_MOVING,MOVE_STATUS_WAITING,MOVE_STATUS_DEST_NOT_FOUND,MOVE_STATUS_DEST_UNREACHABLE,MOVE_STATUS_BLOCKED_BY_WALL,MOVE_STATUS_BLOCKED_BY_OBJECT,MOVE_STATUS_BLOCKED_BY_ENJY,MOVE_STATUS_BLOCKED_BY_MENSTER |
stopMove | 將移動狀態設置爲MOVE_STATUS_DONE。 |
moveToCover | 告訴演員試圖移動到敵人看不到的地方。 |
moveToEnemy | 告訴演員試圖向敵人或最後一個已知的敵方陣地移動。 |
moveToEnemyHeight | 移動到與敵人相同的身高(用於監護人)。 |
moveOutOfRange [entity],[range] | 告訴演員離開指定實體至少範圍單位。 |
moveToAttackPosition [entity], [animation] |
告訴演員移動到可以使用指定動畫攻擊實體的某個位置。由於他必須進入他的“攻擊姿勢”,才能開始射擊,才能使用。 |
漫步 | 告訴演員隨便隨地漫遊,沒有任何特定的方向。 |
moveToEntity [實體] | 告訴演員儘可能靠近實體(8個單位內)。 |
moveToPosition [pos] | 告訴演員儘可能靠近指定的位置(8個單位內)。 |
slideTo [pos],[time] | 隨着時間的推移,將演員滑動到該位置。用於確保演員在觸發某事之前處於確切的位置。 時間通常很小(0.25),但不一定是。 |
facingIdeal | 如果演員面對他的理想偏航角(由turnTo或類似功能設置),則返回true。 |
faceEnemy | 告訴演員不斷轉向最後知道的敵人陣地。 |
faceEntity [entity] | 告訴演員不斷轉向指定的實體。 |
getCombatNode | 返回比當前演員位置更靠近敵人的戰鬥節點。 |
enemyInCombatCone [combatCone], [useCurrentEnemyPosition] |
如果敵人在指定的戰鬥錐體中,則返回true。如果useCurrentPosition爲真,那麼它將使用實際的敵人位置,否則將使用最後一個已知位置。 |
waitMove | 直到當前的動作完成後才返回。Doom 3中沒有使用。 |
getJumpVelocity [pos],[speed],[maxHeight] | 返回將導致演員降落在該位置的速度向量。如果不可能跳轉,則返回零向量。jumpHeight是允許跳轉的最大高度。 |
entityInAttackCone [entity] | 如果實體是我們的攻擊錐體,則返回true。 |
canSee [實體] | 如果實體在我們的視野而不是牆後面,則返回true。 |
setTalkTarget [entity] | 將通話目標設置爲指定的實體,並將AI_TALK設置爲true(如果實體爲空,則將AI_TALK設置爲false)。 |
getTalkTarget | 返回當前的通話目標。 |
setTalkState [state] |
通話狀態是: TALK_NEVER,TALK_DEAD,TALK_OK,TALK_BUSY |
enemyRange | 返回到敵人的距離。 |
enemyRange2D | 返回2d中與敵人的距離(忽略Z)。 |
getEnemy | 返回當前的敵方實體。 |
getEnemyPos | 返回當前敵人的最後一個已知位置。 |
getEnemyEyePos | 返回當前敵人眼中最後一個已知的位置。 |
預測EnemyPos [時間] | 從現在起返回當前敵方時間秒的預測位置。 |
canHitEnemy | 如果演員和他的敵人(或者演員和敵方隊伍中的其他人)之間沒有任何東西,則返回true。 |
canHitEnemyFromAnim [動畫] | 如果使用指定的動畫發射的彈丸將擊中敵人,則返回true。 |
canHitEnemyFromJoint [聯名] | 如果從指定的關節發射的彈丸將擊中敵人,則返回true。 |
enemyPositionValid | 如果演員知道敵人不在最後一個已知位置的事實,則返回false。 |
chargeAttack [damageDef] | 調用attackBegin(damageDef)然後直接向敵方位置移動。 |
testChargeAttack | 如果演員直奔,則返回擊中敵人所需的時間。如果有問題,返回0。 |
testMoveToPosition [position] | 如果演員和職位之間沒有任何內容,則返回true。 |
testAnimMoveTowardEnemy [動畫] | 如果演員可以在運行指定的動畫而沒有任何妨礙的情況下擊中敵人,則返回true。 |
testAnimMove [動畫] | 如果演員可以執行動畫而沒有阻礙某些動作,則返回true。 |
testMeleeAttack | 如果近戰攻擊將擊中敵人,則返回true。 |
testAnimAttack [動畫] | 如果執行指定的動畫將觸發播放器,則返回true。 |
shrivel [時間] | 修改shaderparm 8從1.0到0.5以上的時間(多個幀之後將返回)。Doom 3中沒有使用。 |
燒傷 | 導致演員焚燒和。開。 |
clearBurn | 重置演員刻錄時間(所以演員不再被燒)。 |
預燃 | 關閉陰影。 |
setSmokeVisibility [smokeSystem],[state] | 打開或關閉指定的煙霧粒子系統(通過將狀態設置爲true或false)。 |
numSmokeEmitters | 返回演員煙霧排放者的數量。 |
waitAction [action] | 直到指定的操作完成後才返回。在這種情況下,動作通常是一個動畫名稱。 |
別想了 | 導致線程結束,演員休眠。 |
getTurnDelta | 返回當前偏航和理想偏航之間的角度(以度爲單位)。 |
getMoveType |
獲取當前的移動類型。移動類型是以下之一: MOVETYPE_DEAD,MOVETYPE_ANIM,MOVETYPE_SLIDE,MOVETYPE_FLY,MOVETYPE_STATIC |
setMoveType | 設置當前的移動類型。 |
saveMove | 將當前移動保存到內部變量。 |
restoreMove | 恢復以前保存的動作。 |
allowMovement [flag] | 傳遞真正讓演員走動。 |
enableClip | 啓用演員碰撞幾何。 |
disableClip” | 禁用演員碰撞幾何。 |
enableGravity” | 使演員遵守物理學規律。 |
disableGravity” | 讓演員像重力一樣漂浮在一起不存在。 |
enableAFPush” | 將“af_push_moveables”設置爲true。 |
disableAFPush” | 將“af_push_moveables”設置爲false。 |
setFlySpeed [speed] | 設置“fly_speed”。 |
setFlyOffset [offset] | 設置“fly_offset”。 |
clearFlyOffset | 將“fly_offset”重新設置爲產生agrs的任何內容。 |
getClosestHiddenTarget [type] | 返回玩家無法看到的最接近的指定類型的實體。用於找到玩家無法看到的失去的戰鬥節點。 |
getRandomTarget [type] | 隨機返回指定類型的目標。 |
travelDistanceToPoint [pos] | 返回到指定位置的實際行駛距離(SLOW)。 |
travelDistanceToEntity [entity] | 返回到指定實體的實際行駛距離(SLOW)。 |
travelDistanceBetweenPoints [pointa],[pointb] | 返回從點a到點b(SLOW)的實際行駛距離。 |
travelDistanceBetweenEntities [ent1],[ent2] | 返回從實體1到實體2的實際行駛距離(SLOW)。 |
lookAt [實體],[持續時間] | 瞄準一個演員的頭和眼睛在一個實體一段時間。 |
lookAtEnemy [持續時間] | 瞄準一個演員的頭和眼睛在他的敵人一段時間。 |
setBoneMod [flag] | 啓用或禁用頭腦。 |
殺 | 殺死演員 |
wakeOnFlashlight [flag] | 傳遞真實,當手電筒照亮時,演員激活。 |
locateEnemy | 更新最後知道的敵方位置。 |
kickObstacles [實體],[force] | 對演員前面的對象施加一些踢力,將重點放在實體上(可以爲null)。 |
getObstacle | 返回阻止演員運動的實體(可能被踢的候選人)。 |
pushPointIntoAAS [pos] | 試圖將職位推向有效的AAS區域。返回新位置。 |
getTurnRate | 返回“turn_rate” |
setTurnRate [rate] | 設置“turn_rate” |
animTurn [maxAngle] | 啓用或禁用動畫控制車削。通過動畫轉換的最大度數,或0禁用。 |
allowHiddenMovement [flag] | 即使演員被隱藏也可以通過真實的運行物理學。 |
findActorsInBounds [mins],[maxs] | 返回指定範圍內的actor。 |
canReachPosition [pos] | 如果actor可以移動到指定的位置,則返回true。 |
canReachEntity [entity] | 如果actor可以移動到指定的實體,則返回true。 |
canReachEnemy | 如果演員有可能移動到他的敵人,則返回true。 |
getReachableEntityPosition [entity] | 如果可能,返回AAS中的實體的位置,否則返回該位置。 |