脚本部分者也
 
脚本部分
这个机器人,ai脚本的处理等等
武器的脚本
机器人的有限状态机的脚本的编译了者也
train火车的脚本了者也
 
 
 
脚本编译分为开始,结束,编译过程中
 
 
脚本部分也属于这个预处理阶段的部分者也   
 
 
 
使用脚本来生成机器人的名字,对应的模型文件,武器的效果威力  等等者也
 
突然想到了机器人要加载这个机器人对应的脚本者也,模型,等等,
 
对于机器人的状态的判断乃是在脚本里面写的者也
 
 
 
bot的这个加载武器的权重者也
 
对于这个bot存在这个move ai移动的ai处理者也
 
 
对于武器脚本的处理者也!
 
还有对于其他部分的处理者也
对于脚本加载,还有对于这个脚本的稳定性
调试,错误出在了哪一行程序了者也
对于武器,要加载武器的脚本文件了者也
 
这个有这个武器的名字,毁坏 类型等等者也
 
 
对于脚本绑定到了物体的名字的赋予
 
从脚本中得到了数据值,等等要实现这些
 
武器的ai脚本的处理者也
 
 
 
对于这个bot的状态等等,例如对于广播给其他的组员来进行这个广播了者也
 
对于这个bot的识别敌人者也,寻路在这个aas文件中的处理者也
 
对于这个aas中对于这个entity的处理者也
 
这个entity的更新处理者也,
 
 
 
 
对于game文件中的这个area竞技场文件这个来进行这个map的名字还有这个bot的数量,名字者也
 
对于从脚本中得到了这个变量的值,字符串的值,还有得到了这个字符的值者也
 
 
aas文件中对于这个加载脚本,运行脚本者也
 
 
 
 
脚本的处理
 
FindImmediate
 
ev_entity :
 
idCompiler::LookupDef
 
 
 
tries to find an existing immediate with the same value
 
//    尝试  查找  具有   相同  值  的  现有  立即数
 
 
 
 
id这个居然使用多线程来进行脚本的处理了者也,
 
绑定了这个线程的处理了者也,
 
最后终止 线程了
 
 
调试这个线程的处理了者也
 
 
 
class idScriptObject;
 
class idEventDef;
 
class idVarDef;
 
class idTypeDef;
 
 
 
 
class idEntity;
 
class idThread;
 
 
 
 
 
class idSaveGame;
 
class idRestoreGame;
 
 
weapon的ai脚本
 
,我们从中加载这个的,
 
武器的名字者也
 
武器的毁损 半径多大,武器的这个伤害类型的处理等等
 
 
这样子的话,各种武器的威力 值,
 
还有各种“毁损”类型的处理  等等,比如  弧形威力效果  ,圆形“毁损效果”  等等的处理
 
 
 
item标志
 
iteminfo                       "item_health"
{
 
name                             "25 Health"
 
 
model                            "models/powerups/health/medium_cross.md3"
 
 
modelindex                   MODELINDEX_HEALTH
 
type                               ITEM_HEALTH
 
 
index                               INVENTORY_HEALTH
 
respawntime                       30
 
 
mins                             {-15,-15,-15}
 
maxs                             {15,15,15}
 
 
} //end iteminfo
 
 
对于这个aas脚本
和这个bot的脚本的处理者也
还有这个bot的脚本的处理者
 
 
bot的脚本摘录
 
skill 1
{
CHARACTERISTIC_NAME "Xaero"
 
CHARACTERISTIC_GENDER "male"
 
CHARACTERISTIC_ATTACK_SKILL 0.45
 
CHARACTERISTIC_WEAPONWEIGHTS "bots/xaero_w.c"
 
 
 
CHARACTERISTIC_AIM_SKILL                   0.45
 
CHARACTERISTIC_AIM_ACCURACY         0.75
 
CHARACTERISTIC_VIEW_FACTOR                0.95
 
CHARACTERISTIC_VIEW_MAXCHANGE        360
 
CHARACTERISTIC_REACTIONTIME                 0.5
 
 
 
 
 
CHARACTERISTIC_CHAT_FILE "bots/xaero_t.c"
 
CHARACTERISTIC_CHAT_NAME "xaero"
 
CHARACTERISTIC_CHAT_CPM 400
 
CHARACTERISTIC_CHAT_INSULT 0.4
 
CHARACTERISTIC_CHAT_MISC                          0.5
 
CHARACTERISTIC_CHAT_STARTENDLEVEL      0.5
 
CHARACTERISTIC_CHAT_ENTEREXITGAME       0.5
 
CHARACTERISTIC_CHAT_KILL 0.5
 
CHARACTERISTIC_CHAT_DEATH                      0.5
 
CHARACTERISTIC_CHAT_ENEMYSUICIDE        0.5
 
 
 
 
CHARACTERISTIC_CHAT_HITTALKING            0.15
 
CHARACTERISTIC_CHAT_HITNODEATH     0.5
 
CHARACTERISTIC_CHAT_HITNOKILL          0.5
 
CHARACTERI
 
STIC_CHAT_RANDOM                    0.5
 
CHARACTERISTIC_CHAT_REPLY          0.25
 
 
 
 
 
 
CHARACTERISTIC_CROUCHER                      0.05
 
CHARACTERISTIC_JUMPER                             0.95
 
CHARACTERISTIC_WEAPONJUMPING           0.05
 
CHARACTERISTIC_GRAPPLE_USER                 0.05
 
 
 
 
 
CHARACTERISTIC_ITEMWEIGHTS    "bots/xaero_i.c"
 
CHARACTERISTIC_AGGRESSION                 0.75
 
CHARACTERISTIC_SELFPRESERVATION         0.95
 
CHARACTERISTIC_VENGEFULNESS 0.95
CHARACTERISTIC_CAMPER 0.25
 
 
CHARACTERISTIC_EASY_FRAGGER 0.05
CHARACTERISTIC_ALERTNESS 0.95
 
CHARACTERISTIC_AIM_ACCURACY_MACHINEGUN 0.5
CHARACTERISTIC_AIM_ACCURACY_SHOTGUN 0.5
CHARACTERISTIC_AIM_ACCURACY_ROCKETLAUNCHER 0.5
CHARACTERISTIC_AIM_ACCURACY_GRENADELAUNCHER 0.5
CHARACTERISTIC_AIM_ACCURACY_LIGHTNING 0.5
CHARACTERISTIC_AIM_ACCURACY_PLASMAGUN 0.5
CHARACTERISTIC_AIM_ACCURACY_RAILGUN 0.7
CHARACTERISTIC_AIM_ACCURACY_BFG10K 0.5
CHARACTERISTIC_AIM_SKILL_ROCKETLAUNCHER 0.5
CHARACTERISTIC_AIM_SKILL_GRENADELAUNCHER 0.5
CHARACTERISTIC_AIM_SKILL_PLASMAGUN 0.5
CHARACTERISTIC_AIM_SKILL_BFG10K 0.5
 
CHARACTERISTIC_FIRETHROTTLE 0.4
}
 
2
机器人的脚本
机器人的动画部分的定义
sex m
 
// first frame, num frames, looping frames, frames per second
 
//    第一帧,帧数,循环帧数,每秒帧数
 
0 30 0 20 // BOTH_DEATH1
29 1 0 20 // BOTH_DEAD1
30 30 0 20 // BOTH_DEATH2
59 1 0 20 // BOTH_DEAD2
60 30 0 20 // BOTH_DEATH3
89 1 0 20 // BOTH_DEAD3
 
90 40 0 20 // TORSO_GESTURE
 
 
 
130 6 0 15 // TORSO_ATTACK (MUST NOT CHANGE -- hand animation is synced to this)
136 6 0 15 // TORSO_ATTACK2 (MUST NOT CHANGE -- hand animation is synced to this)
 
(不得更改--手动画   与此   同步)
 
 
142 5 0 20 // TORSO_DROP (MUST NOT CHANGE -- hand animation is synced to this)
147 4 0 20 // TORSO_RAISE (MUST NOT CHANGE -- hand animation is synced to this)
 
151 1 0 15 // TORSO_STAND
152 1 0 15 // TORSO_STAND2
 
153 8 8 20 // LEGS_WALKCR
161 12 12 20 // LEGS_WALK
173 8 8 18 // LEGS_RUN
181 10 10 20 // LEGS_BACK
191 10 10 15 // LEGS_SWIM
 
201 7 0 15 // LEGS_JUMP
208 2 0 15 // LEGS_LAND
 
210 8 0 15 // LEGS_JUMPB
218 1 0 15 // LEGS_LANDB
 
219 10 10 15 // LEGS_IDLE
229 10 10 15 // LEGS_IDLECR
 
239 7 7 15 // LEGS_TURN
 
 
 
脚本的编译
加载这些bot脚本,来绑定到了bot身上了者也
 
对于脚本的处理者也,将这些脚本增加到了这个堆栈上了者也
 
 
AddScriptToStack( const char *filename )
LoadScriptFile
void ParseFromMemory (char *buffer, int size)
 
 
分析这个脚本的缓存的处理者也
 
 
GetToken (qboolean crossline)
{
对于脚本,quake3居然能够找到了这个错误在哪一行那一列的处理了者也
 
id的这个编译器居然还使用了这个多线程来进行这个的处理了者也
编译脚本
 
当前文件的数目,这个不是编译一个文件的者也
 
编译出了错误的话,那么输出了这个错误信息了者也
 
输出了这个警告了者也
doom3这部分居然使用的虚函数的调用了者也
VirtualFunctionConstant
 
Creates a def for an index into a virtual function table
 
//  ..为虚函数表  中的   索引    创建    定义
 
 
 
 
尺寸,跳转尺寸了者也
 
寻找图像的函数了者也
 
 
 
compiles the 0 terminated text, adding definitions to the program structure
 
// ..编译0  终止的   文本,并向   程序  结构   添加    定义
 
 
一以下乃是在doom3代码中的东西,quake3的脚本着太乱了,
只好看doom3的处理部分
 
 
脚本居然关联了这么多的这个类型,还有这个事件的处理了者也
类型的定义了者也,还有对于entity的处理了者也
对于gamesave的处理了者也
对于变量的处理了择业
脚本对象的处理了者也
还有对于这个事件定义的处理了等等
 
 
脚本的内存的处理,把脚本中的数据给于了各个部分了者也,例如武器脚本的变量给了这个武器的,
bot脚本的内容,供给了一个bot处理了
 
加载武器,玩家,怪物们等等的有限状态机脚本了者也
 
train,守卫者,最后的boss1脚本
 
脚本文件的一个例子了者也
 
float dmsp_skill = 0;
 
float dmsp_nextComboTime = -1;
 
float dmsp_combo = 1;
 
float dmsp_score = 0;
 
 
// Create a target_null for every deathmatch spawnpoint, because func_spawners reject 
// anything that isn't a target_null for some strange reason
 
 
// 为   每个 DeathMatch SpawnPoint    创建一个target_null,
 
//   因为   func_spawners拒绝。
 
//由于某些奇怪的原因,任何不是target_null的内容
 
 
float dmsp_createSpawns()
{
 
 
float i, j = 0;
 
entity spawny, newNull;
 
 
string namey;
 
 
for (i = 1; i < 64; i++)
 {
 
       namey = ("info_player_deathmatch_" + i);
 
 
       spawny = sys.getEntity(namey);
 
 
if (spawny)
{
 
      namey = "dudeSpawnPoint_" + j;
 
 
      sys.setSpawnArg( "name", namey );
 
 
       sys.setSpawnArg( "origin", spawny.getWorldOrigin() );
 
       newNull = sys.spawn( "target_null" );
 
j++;
 
}
}
return j;
 
}
 
 
// Set spawnargs of the func_spawner to target all of the new spawn nulls
 
//  将  func_spawner  的   spawnargs    设置为  以所有   新生成的   null  为  目标
 
 
 
void dmsp_setSpawns( float j )
{
float i;
 
entity spawny;
 
string namey;
 
 
 
for (i = 0; i <= j; i++)
{
 
namey = ("dudeSpawnPoint_" + i);
 
spawny = sys.getEntity(namey);
 
if (spawny)
{
             sys.setSpawnArg("target_" + i, namey );
}
 
}
}
 
// score!
// take the given score and display it with the ordinarily dev-only function sys.drawText
//  and float/shrink it per frame for extra arcade cach?
 
//   得分!
 
//获取  给定的   得分,
 
//并使用  通常   仅用于开发的函数sys.drawText  显示它。
 
//并  每帧  浮动/收缩它,以获得  额外的 街机缓存?
 
 
void dmsp_scorePip (   string text, vector origin, float pipTime )
{
 
 
float frameTime = sys.getFrameTime(  );
 
float startTime =    sys.getTime(   );
 
 
float i, d, score;
 
vector org = origin, color;
 
string comboType;
 
 
 
if (startTime <= dmsp_nextComboTime) dmsp_combo = dmsp_combo + 1;
 
        else dmsp_combo    = 1;
 
 
 
 
dmsp_nextComboTime = startTime + 2 * pipTime;
 
 
// window until combo cutoff
 
//   窗口   直到   组合框   关闭
 
 
 
score = sys.strToFloat( text ) * dmsp_combo;
 
 
 
pipTime = pipTime + ( 0.25 * pipTime * ( dmsp_combo - 1 ) );
 
 
 
 
for ( i = startTime; i < (startTime + pipTime); i = i + frameTime )
{
 
      d = (i - startTime) / pipTime;
 
 
// pick a lerping color & extra floaty text print based on combo level
// this feels kind of unwieldy but without arrays or case switches it's the best we can do
 
 
//  根据    组合级别   选择Lerping颜色  和   额外的 浮动  文本  打印。
 
//    这感觉有点  笨拙,但没有    数组或大小写   切换,这是我们能做的最好的。
 
 
 
 
if (dmsp_combo == 1)
         color_x = 1 - d; // red
}
 
  else if (dmsp_combo == 2)
 
   color_x = 1 - d; 
 
 
   color_y = 0.5 * ( 1 - d ); // orange
 
   comboType = "Combo!";
 
 
}
 
 
else if (dmsp_combo == 3)
 
color_x = 1 - d; 
 
color_y = 1 - d; // yellow
 
comboType = "Double Combo!";
 
}
 
else if (dmsp_combo == 4)
 
              color_y = 1 - d; // green
 
 
               comboType = "Triple Combo!";
 
}
 
else if (dmsp_combo == 5)
      color_y = 1 - d; 
 
      color_z = 1 - d; // cyan
 
      comboType = "Super Combo!";
 
}
 
 
 
else if (dmsp_combo == 6)
          color_y = 0.5 * ( 1 - d ); 
 
           color_z = 1 - d; // light blue
 
            comboType = "Mega Combo!";
}
 
 
else if (dmsp_combo == 7)
              color_z = 1 - d; // deep blue
 
             comboType = "Ultra Combo!";
}
 
else if (dmsp_combo >= 8)
 
 
 
         color_x = color_y = color_z = 1 - d; // white
 
 
          comboType = "Holy Shit!";
 
}
 
 
 
org_z = origin_z + d * 96;
 
 
sys.drawText( score, org, 0.5 * (1 - d), color, 1, 0 );
 
 
 
if (dmsp_combo > 1)
{
       org_z = origin_z + d * 96 + 12;
 
        sys.drawText( comboType, org, 0.25 * ( 1 - d ), color, 1, 0 );
 
}
 
 
sys.waitFrame(  );
 
}
 
 
 
 
dmsp_score = dmsp_score + score;
 
// The only way to show the player his score is to update it in the
 
//向玩家显示其分数的唯一方法是在
 
 
 
sys.println( dmsp_score );
 
 
// console since there's no way to display it on the player hud
 
//    控制台,因为   无法在   播放器HUD上  显示   它
 
 
 
 
}
 
 
 
 
 
// Sprinkle goodies around a given point
 
 
 
//在    给定点        周围         撒上   供给 
 
void dmsp_throwLoots ( vector org,
 
                                          string lootClass,
 
                                         float cnt,
 
                                         float nodoubles
                                        )
{
float i;
 
entity loots;
 
vector toss;
 
 
float dist = 128;            // radius distance to spawn goodies
 
//          生成     好东西的      半径距离
 
 
 
 
float doubChance = 1 - ( 0.1 * dmsp_skill );
 
 
 
// more double drops on harder skill to keep the player stocked
 
//   在更难的技能上   有更多的    双倍掉落,以保持   玩家的 储备。
 
 
if ( sys.random(1) > doubChance && nodoubles == 0 )
{
 
      cnt = cnt * 2;       //   twice the goodies
 
       //   两倍的   供给品
 
         dist = 192;
 
}
 
 
 
 
for( i = 0; i < cnt; i++ )
{
toss_x = dist - sys.random(2 * dist);
toss_y = dist - sys.random(2 * dist);
toss_z = dist;
sys.setSpawnArg( "origin", org );
sys.setSpawnArg( "nodrop", 1 );
loots = sys.spawn( lootClass );
sys.waitFrame(); // wait until entity exists to set toss velocity
loots.setLinearVelocity( toss );
}
}
 
// Drop one of the single player weapon mods
void dmsp_throwMod( vector org )
{
string mod;
entity loots;
vector toss;
toss_x = 128 - sys.random(256);
toss_y = 128 - sys.random(256);
toss_z = 128;
 
float val = sys.random(10);
if (val > 9) mod = "weaponmod_shotgun_ammo";
else if (val > 8) mod = "weaponmod_machinegun_ammo";
else if (val > 7) mod = "weaponmod_hyperblaster_bounce1";
else if (val > 6) mod = "weaponmod_hyperblaster_bounce2";
else if (val > 5) mod = "weaponmod_nailgun_seek";
else if (val > 4) mod = "weaponmod_nailgun_power";
else if (val > 3) mod = "weaponmod_railgun_penetrate";
else if (val > 2) mod = "weaponmod_rocketlauncher_seek";
else if (val > 1) mod = "weaponmod_rocketlauncher_burst";
else mod = "weaponmod_lightninggun_chain";
 
sys.setSpawnArg( "model", "models/pick_ups/mp_pickups/moderator.lwo" ); // give it a better/more noticeable model
sys.setSpawnArg( "origin", org );
loots = sys.spawn( mod );
sys.waitFrame(); // wait until entity exists to set toss velocity
loots.setLinearVelocity( toss );
}
 
// check the killed monster's spawnclass and decide on a drop and score
void dmsp_killMonster( entity victim )
{
string vicType = victim.getKey( "classname" ); // what kind of monster is it?
vector vicOrg, vicSize, vicDrop, vicPip;
 
float score = (dmsp_skill + 1) * 25 * dmsp_combo; // score on general = 4x score on easy
vicOrg = victim.getWorldOrigin(); // where was it killed?
vicSize = victim.getSize(); // how big was it?  for deciding how high to toss items and print score
vicDrop = vicOrg;
vicDrop_z = vicDrop_z + vicSize_z * 0.5; // drop items waist high
vicPip = vicOrg;
vicPip_z = vicPip_z + vicSize_z * 0.75; // print score pip about head high
 
float val = sys.random(1);
if ( vicType == "monster_strogg_marine" ) {
if ( val > 0.7 ) dmsp_throwLoots( vicDrop, "ammo_hyperblaster_mp", 1, 0 );
else if ( val > 0.5 ) dmsp_throwLoots( vicDrop, "item_health_shard_mp", 1, 0);
else if ( val > 0.3 ) dmsp_throwLoots( vicDrop, "item_armor_shard", 1, 0);
 
thread dmsp_scorePip( score, vicPip, 1 );
 
} else if ( vicType == "monster_strogg_marine_sgun" ) {
if ( val > 0.7 ) dmsp_throwLoots( vicDrop, "ammo_shotgun_mp", 1, 0 );
else if ( val > 0.5 ) dmsp_throwLoots( vicDrop, "item_health_shard_mp", 1, 0);
else if ( val > 0.3 ) dmsp_throwLoots( vicDrop, "item_armor_shard", 1, 0);
thread dmsp_scorePip( score, vicPip, 1 );
 
} else if ( vicType == "monster_strogg_marine_mgun" )  {
if ( val > 0.7 ) dmsp_throwLoots( vicDrop, "ammo_machinegun_mp", 1, 0 );
else if ( val > 0.5 ) dmsp_throwLoots( vicDrop, "item_health_shard_mp", 1, 0 );
else if ( val > 0.3 ) dmsp_throwLoots( vicDrop, "item_armor_shard", 1, 0 );
thread dmsp_scorePip( score, vicPip, 1 );
 
} else if ( vicType == "monster_sentry" ) {
if ( val > 0.66 ) dmsp_throwLoots( vicDrop, "item_armor_shard", 4, 0 );
else if ( val > 0.33 ) dmsp_throwMod( vicDrop ); // 1/3 chance of dropping a sexy weaponmod
else dmsp_throwLoots( vicDrop, "item_health_shard_mp", 4, 0 );
 
score = score * 2;
thread dmsp_scorePip( score, vicPip, 1.25 );
 
} else if ( vicType == "monster_grunt" ) {
if ( val > 0.5 ) dmsp_throwLoots( vicDrop, "item_health_small_mp", 1, 0 );
 
score = score * 3;
thread dmsp_scorePip( score, vicPip, 1 );
 
} else if ( vicType == "monster_berserker" ) {
if ( val > 0.5 ) dmsp_throwLoots( vicDrop, "item_health_small_mp", 1, 0 );
else if ( val > 0.2 ) dmsp_throwLoots( vicDrop, "ammo_lightninggun_mp", 1, 0 );
 
score = score * 3;
thread dmsp_scorePip( score, vicPip, 1 );
 
} else if ( vicType == "monster_gunner" ) {
if ( val > 0.6 ) dmsp_throwLoots( vicDrop, "ammo_nailgun_mp", 1, 0 );
else if ( val > 0.2 ) dmsp_throwLoots( vicDrop, "ammo_grenadelauncher_mp", 1, 0 );
else dmsp_throwLoots( vicDrop, "item_health_small_mp", 1, 0 );
 
score = score * 3;
thread dmsp_scorePip( score, vicPip, 1 );
} else if ( vicType == "monster_iron_maiden" ) {
if ( val > 0.6 ) dmsp_throwLoots( vicDrop, "ammo_rocketlauncher_mp", 1, 0 );
else if ( val > 0.3 ) dmsp_throwLoots( vicDrop, "ammo_hyperblaster_mp", 1, 0 );
else dmsp_throwLoots( vicDrop, "item_health_small_mp", 1, 0 );
 
score = score * 5;
thread dmsp_scorePip( score, vicPip, 1.25 );
} else if ( vicType == "monster_gladiator" ) {
if ( val > 0.6 ) dmsp_throwLoots( vicDrop, "ammo_railgun_mp", 1, 0 );
else if ( val > 0.3 ) dmsp_throwLoots( vicDrop, "item_health_small_mp", 1, 0 );
else if ( val > 0.2 ) dmsp_throwLoots( vicDrop, "item_health_large_mp", 1, 0 );
 
score = score * 6;
thread dmsp_scorePip( score, vicPip, 1.25 );
} else if ( vicType == "monster_lt_tank" ) {
if ( val > 0.5 ) dmsp_throwLoots( vicDrop, "ammo_rocketlauncher_mp", 2, 0 );
else if ( val > 0.2 ) dmsp_throwLoots( vicDrop, "item_armor_large_mp", 1, 1 );
else dmsp_throwLoots( vicDrop, "item_health_mega", 1, 1 );
 
score = score * 10;
thread dmsp_scorePip( score, vicPip, 1.5 );
}
}
 
// play effects on spawn so guys don't just blink into view
// this doesn't work on every monster, because guys like monster_sentry don't have chest bones
// but setting this up special for each skeleton isn't worth the cruft
void dmsp_whoosh( entity me )
{
me.playEffect( "fx_burn_particles_chest", "chest", 0 );
me.playEffect( "fx_burn_particles_chest", "head", 0 );
me.playEffect( "fx_burn_particles_chest", "origin", 0 );
}
 
// Create the func_spawner that drives the whole thing
// All arguments must be set on the spawner when it spawns, hence spawnArgs rather than setKeys
void dmsp_createSpawner()
{
float j = dmsp_createSpawns(); // make nulls for spawn points
 
// high odds for puny dudes, so list them several times
sys.setSpawnArg("def_spawn", "monster_strogg_marine");
sys.setSpawnArg("def_spawn_1", "monster_strogg_marine");
sys.setSpawnArg("def_spawn_2", "monster_strogg_marine");
sys.setSpawnArg("def_spawn_3", "monster_strogg_marine");
sys.setSpawnArg("def_spawn_4", "monster_strogg_marine_sgun");
sys.setSpawnArg("def_spawn_5", "monster_strogg_marine_sgun");
sys.setSpawnArg("def_spawn_6", "monster_strogg_marine_sgun");
sys.setSpawnArg("def_spawn_7", "monster_strogg_marine_sgun");
sys.setSpawnArg("def_spawn_8", "monster_strogg_marine_mgun");
sys.setSpawnArg("def_spawn_9", "monster_strogg_marine_mgun");
sys.setSpawnArg("def_spawn_10", "monster_strogg_marine_mgun");
sys.setSpawnArg("def_spawn_11", "monster_strogg_marine_mgun");
 
// medium odds for medium guys
sys.setSpawnArg("def_spawn_12", "monster_gunner");
sys.setSpawnArg("def_spawn_13", "monster_gunner");
sys.setSpawnArg("def_spawn_14", "monster_grunt");
sys.setSpawnArg("def_spawn_15", "monster_grunt");
sys.setSpawnArg("def_spawn_16", "monster_sentry");
sys.setSpawnArg("def_spawn_17", "monster_sentry");
sys.setSpawnArg("def_spawn_18", "monster_berserker");
sys.setSpawnArg("def_spawn_19", "monster_berserker");
 
// low odds for tough SOBs
 
sys.setSpawnArg("def_spawn_20", "monster_iron_maiden");
 
sys.setSpawnArg("def_spawn_21", "monster_gladiator");
 
sys.setSpawnArg("def_spawn_22", "monster_lt_tank");
sys.waitFrame();
 
 
 
sys.setSpawnArg("max_active", j); // assume # of spawns in map is a good monster limit
 
 
sys.setSpawnArg("delay", ( 5 - dmsp_skill ) ); // shorter delay on harder skill
 
 
sys.setSpawnArg("auto_target", "1");
 
sys.setSpawnArg("face_enemy", "1");
 
sys.setSpawnArg("skipVisible", "0");
sys.setSpawnArg("remove", "0"); // don't disappear from the entity list if I break this
// spawn_* keys are set on the spawned monster:
sys.setSpawnArg("spawn_neverdormant", "1");
sys.setSpawnArg("spawn_script_death", "dmsp_killMonster"); // for spawning loots
sys.setSpawnArg("spawn_script_init", "dmsp_whoosh"); // for spawning zoots
sys.waitFrame();
dmsp_setSpawns( j ); // set previously created nulls as possible targets
entity dudeSpawner = sys.spawn( "func_spawner" );
sys.trigger(dudeSpawner);
}
 
void main()
{
dmsp_skill = sys.strToFloat( sys.getcvar("g_skill") );
 
// Spawn all possible monsters and items in main to force them to cache when the map loads
// then remove them out of the way
entity tempy, tempy2, tempy3; // three at a time so it doesn't take 30 game frames
tempy = sys.spawn( "monster_strogg_marine" );
tempy2 = sys.spawn( "monster_strogg_marine_sgun" );
tempy3 = sys.spawn( "monster_strogg_marine_mgun" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "monster_gunner" );
tempy2 = sys.spawn( "monster_grunt" );
tempy3 = sys.spawn( "monster_iron_maiden" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "monster_berserker" );
tempy2 = sys.spawn( "monster_sentry" );
tempy3 = sys.spawn( "monster_gladiator" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "monster_lt_tank" );
tempy2 = sys.spawn( "item_health_small_mp" );
tempy3 = sys.spawn( "item_health_large_mp" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "ammo_machinegun_mp" );
tempy2 = sys.spawn( "ammo_shotgun_mp" );
tempy3 = sys.spawn( "ammp_hyperblaster_mp" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "ammo_nailgun_mp" );
tempy2 = sys.spawn( "ammo_railgun_mp" );
tempy3 = sys.spawn( "ammo_lightninggun_mp" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "ammo_grenadelauncher_mp" );
tempy2 = sys.spawn( "ammo_rocketlauncher_mp" );
tempy3 = sys.spawn( "ammo_machinegun_mp" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "item_health_mega" );
tempy2 = sys.spawn( "item_armor_large_mp" );
tempy3 = sys.spawn( "item_armor_shard_mp" );
sys.waitFrame();
tempy.remove(); tempy2.remove(); tempy3.remove();
 
tempy = sys.spawn( "item_health_shard_mp" );
sys.waitFrame();
tempy.remove();
sys.wait(2);
sys.println("Three ... ");
sys.wait(1);
sys.println("Two ... ");
sys.wait(1);
sys.println("One ... ");
sys.wait(1);
dmsp_createSpawner();
sys.println("The invasion has begun!");
}
 
如果你新建了一个新的地图的话,或者怪物
If you create a new map, weapon, or monster you're probably going to want to add a new script file to go along with it. However, if you just drop the .script file in the scripts directory you will notice that it doesn't get recognized automatically.

The scripts directory does not just get scanned and loaded automatically. The only file it loads up is doom_main.script, that file then includes all the other script files. If you want to add your own script, you need to be sure to #include it in doom_main.script! 

 

为什么我不能够加载武器?

 

One of the first things that any mod maker wants to do is add a new weapon. Luckily, Doom 3 makes this much easier than it has been in the past. In fact, for most weapon types, you won't even need to open up the code -- it can all be done through scripts. For our new weapon let's make a fireball, that way we can reuse the current models and sounds.

The first thing you'll want to do is open player.def. If you remember on Monday we found out that weapon 13 isn't quite as usable is it looks, so move weapon_pda to slot 13, and set "def_weapon12" to "weapon_fireball". "weapon12_cycle" should be 1, and all the else should be 0. Next, scroll down to the "weapon" key and add "weapon_fireball" to the list after "weapon_pda", this will make us start with fireballs (since there aren't any fireball pickups on any maps, we have to do it this way or cheat by typing "give weapon_fireball").

Next we begin the process of duplicating the hand grenade:

  • Create a new file named weapon_fireball.def
  • Start off by copying the weapon_handgrenade entityDef and name it weapon_fireball
  • Change the following keys from "grenade" to "fireball"
    • model_view
    • model_world
    • def_dropItem
    • inv_weapon
    • weapon_scriptobject
    • def_projectile
    We'll leave ammoType as grenades for now
  • Copy over moveable_item_grenades and rename it to moveable_item_fireballs, making sure to change "inherit" in the process.
  • Copy over worldmodel_grenade and rename it to worldmodel_fireball.
  • Copy over viewmodel_grenade and rename it to viewmodel_fireball.
  • Copy over projectile_impfireball (from monster_demon_imp.def) and rename it to projectile_fireball.
  • Copy over damage_impfireball and damage_impfireball_splash (also from monster_demon_imp.def) and rename them so they are not imp fire balls. Change the references in projectile_fireball to point to the new name. Change the damage for both to 100.
  • Make a copy of weapon_handgrenade.script and rename it to weapon_fireball.script. Open weapon_fireball.script and use find/replace for handgrenade to fireball.
  • Be sure to add #include "script/weapon_fireball.script" to doom_main.script

At this point if you run your mod, you should be able to cycle to something that looks like a hand grenade, but shoots fireballs.

The biggest problem with it now is it takes grenade ammo, and as we all know fireballs don't take any ammo at all (they are summoned from hell). We must rectify this situation. Open player.def and set "weapon12_allowempty" to 1. Inside the weapon_fireball, remove "inv_ammo_grenades", set the "ammoType" to "", and set "ammoRequired" to 0. You should now be able to fire as many fire balls as you want.

Now the problem is it still looks like a grenade when you are holding it. If I were an artist, I would create a new model that looked less like a grenade and more like hands waving around, but since I'm a programmer I'm just going to put a random lava texture on it. Create a new file in the 'skins' folder called 'skins_fireball.skin' and inside it, put:

skin skins/models/weapons/fireball {
    models/weapons/grenades/grenades3 textures/hell/lavascroll_ns
    models/weapons/grenades/grenades3fx textures/hell/lavascroll_ns
}

skin skins/models/weapons/fireball_invis {
    models/weapons/grenades/grenades3 textures/hell/lavascroll_ns
    models/weapons/grenades/grenades3fx textures/hell/lavascroll_ns
        models/characters/player/arm2 models/characters/player/arm2_invis
}

skin skins/models/weapons/nofireball {
        models/weapons/grenades/grenades3 textures/common/nodraw
        models/weapons/grenades/grenades3fx textures/common/nodraw
}

skin skins/models/weapons/nofireball_invis {
        models/weapons/grenades/grenades3 textures/common/nodraw
        models/weapons/grenades/grenades3fx textures/common/nodraw
        models/characters/player/arm2 models/characters/player/arm2_invis
}

Then in weapon_fireball, change the skin_nade, skin_nade_invis, skin_nonade, and skin_nonade_invis keys to point to the new skins we just made.

Once we do this, the fireball actually looks pretty good as long as we throw it overhanded, but quick tosses look kind of funny. This is an easy fix, just open weapon_fireball.script and change FIREBALL_QUICKTHROWTIME from .2 to 0.

There you go, your own weapon in the game. You can actually place these in radiant now, but if you want to do that then I would recommend not making them have infinite ammo (how to add ammo may be covered later, but it's not any more difficult than adding a weapon). The hardest part of adding a new weapon is getting it modeled and animated correctly. I would strongly recommend prototyping all weapons using existing art.

If you are having problems, you can download my version and compare it against your own version. 

在多人部分能够使用的这个鞋脚本了者也

If you are not planning on using any of the id maps in your mod, then you should really remove them from doom_main in order to speed up compile time and cut down on memory usage. If you are making a multiplayer only mod, you can further cut it down by removing the monster scripts. Here is a base doom_main that could be used for a multiplayer only mod:

// base defines and util functions 
#include "script/doom_defs.script" 
#include "script/doom_events.script" 
#include "script/doom_util.script" 
#include "script/weapon_base.script" 
#include "script/ai_base.script" 
 
// weapons 
#include "script/weapon_fists.script" 
#include "script/weapon_pistol.script" 
#include "script/weapon_shotgun.script" 
#include "script/weapon_machinegun.script" 
#include "script/weapon_chaingun.script" 
#include "script/weapon_handgrenade.script" 
#include "script/weapon_plasmagun.script" 
#include "script/weapon_rocketlauncher.script" 
#include "script/weapon_bfg.script" 
#include "script/weapon_soulcube.script" 
#include "script/weapon_chainsaw.script" 
#include "script/weapon_flashlight.script" 
#include "script/weapon_pda.script" 
 
#include "script/ai_player.script"  

If you are making a total conversion, you can further slim it down by removing the weapon scripts. 

 

 

 

 

 

 

 

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐