Changeset 77:6d865a4a045a

Show
Ignore:
Timestamp:
11/22/07 12:01:03 (3 years ago)
Author:
mdoison
Branch:
madcat
convert_revision:
svn:7c786126-522e-0410-a822-d6d8feae56ca/branches/madcat@99
Message:

add mauradeur.patch (tjw 1.2)

  • improve mauradeur capacities
  • rewrite zap attack
  • FIXME: Why zap effect never called ???
Location:
src/game
Files:
6 modified

Legend:

Unmodified
Added
Removed
  • src/game/bg_public.h

    r73 r77  
    580580  EV_DCC_ATTACK,      //TA: dcc under attack 
    581581 
    582   EV_RPTUSE_SOUND     //TA: trigger a sound 
     582  EV_RPTUSE_SOUND,     //TA: trigger a sound 
     583  EV_LEV2_ZAP 
    583584} entity_event_t; 
    584585 
     
    12691270  ET_MODELDOOR, 
    12701271  ET_LIGHTFLARE, 
    1271   ET_LEV2_ZAP_CHAIN, 
     1272  ET_LEV2_ZAP_CHAIN, // TODO: REMOVE ME !!! 
    12721273 
    12731274  ET_EVENTS       // any of the EV_* events can be added freestanding 
  • src/game/g_active.c

    r76 r77  
    13381338} 
    13391339 
     1340static void G_CheckZap( gentity_t *ent ) 
     1341{ 
     1342  int i; 
     1343 
     1344  if( !ent->zapping ) 
     1345  { 
     1346    // clear out established targets 
     1347    for( i = 0; i < LEVEL2_AREAZAP_MAX_TARGETS; i++ ) 
     1348    { 
     1349      ent->zapTargets[ i ] = -1; 
     1350    } 
     1351    ent->zapDmg = 0.0f; 
     1352  } 
     1353  ent->wasZapping = ent->zapping; 
     1354  ent->zapping = qfalse; 
     1355 
     1356  if( ent->client->ps.weapon == WP_ALEVEL2_UPG && 
     1357    ( ent->client->pers.cmd.buttons & BUTTON_ATTACK2 ) ) 
     1358  { 
     1359    ent->zapping = qtrue; 
     1360  } 
     1361   
     1362  if( ent->wasZapping && !ent->zapping ) 
     1363    ent->client->ps.weaponTime = LEVEL2_AREAZAP_REPEAT; 
     1364} 
     1365 
    13401366/* 
    13411367============== 
     
    16911717  // touch other objects 
    16921718  ClientImpacts( ent, &pm ); 
    1693    
     1719 
     1720  G_CheckZap( ent ); 
     1721  
    16941722  // execute client events 
    16951723  ClientEvents( ent, oldEventSequence ); 
     
    19762004  G_SetClientSound( ent ); 
    19772005 
     2006  G_UpdateZaps( ent ); 
     2007 
    19782008  // set the latest infor 
    19792009  if( g_smoothClients.integer ) 
  • src/game/g_local.h

    r68 r77  
    241241 
    242242  int               lastDamageTime; 
     243 
     244  qboolean          zapping;                        // adv maurader is zapping 
     245  qboolean          wasZapping;                     // adv maurader was zapping 
     246  int               zapTargets[ LEVEL2_AREAZAP_MAX_TARGETS ]; 
     247  float             zapDmg;                         // keep track of damage 
    243248}; 
    244249 
     
    911916qboolean  CheckPounceAttack( gentity_t *ent ); 
    912917void      ChargeAttack( gentity_t *ent, gentity_t *victim ); 
    913 void      G_UpdateZaps( int msec ); 
     918void      G_UpdateZaps( gentity_t *ent ); 
    914919 
    915920 
  • src/game/g_main.c

    r72 r77  
    24682468  G_SpawnClients( PTE_HUMANS ); 
    24692469  G_CalculateAvgPlayers( ); 
    2470   G_UpdateZaps( msec ); 
    24712470 
    24722471  // see if it is time to end the level 
  • src/game/g_weapon.c

    r75 r77  
    10181018*/ 
    10191019 
    1020 #define MAX_ZAPS  64 
    1021  
    1022 static zap_t  zaps[ MAX_CLIENTS ]; 
    1023  
    1024 /* 
    1025 =============== 
    1026 G_FindNewZapTarget 
    1027 =============== 
    1028 */ 
    1029 static gentity_t *G_FindNewZapTarget( gentity_t *ent ) 
     1020static vec3_t sortReference; 
     1021 
     1022static int QDECL G_SortDistance( const void *a, const void *b ) 
     1023{ 
     1024  gentity_t    *aent, *bent; 
     1025  float        adist, bdist; 
     1026  aent = &g_entities[ *(int *)a ]; 
     1027  bent = &g_entities[ *(int *)b ]; 
     1028  adist = Distance( sortReference, aent->s.origin ); 
     1029  bdist = Distance( sortReference, bent->s.origin ); 
     1030  if( adist > bdist ) 
     1031    return -1; 
     1032  else if( adist < bdist ) 
     1033    return 1; 
     1034  else 
     1035    return 0; 
     1036} 
     1037 
     1038/* 
     1039=============== 
     1040G_UpdateZaps 
     1041=============== 
     1042*/ 
     1043void G_UpdateZaps( gentity_t *ent ) 
    10301044{ 
    10311045  int       entityList[ MAX_GENTITIES ]; 
    1032   vec3_t    range = { LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_RANGE }; 
     1046  int       hitList[ MAX_GENTITIES ]; 
     1047  vec3_t    range = { LEVEL2_AREAZAP_CUTOFF, 
     1048                      LEVEL2_AREAZAP_CUTOFF, 
     1049                      LEVEL2_AREAZAP_CUTOFF }; 
    10331050  vec3_t    mins, maxs; 
    1034   int       i, j, k, num; 
     1051  int       i, j; 
     1052  int       hit = 0; 
     1053  int       num; 
    10351054  gentity_t *enemy; 
     1055  gentity_t *effect; 
    10361056  trace_t   tr; 
     1057  qboolean  alreadyTargeted = qfalse; 
     1058  int       damage; 
     1059 
     1060  if( !ent->zapping || ent->health <= 0 ) 
     1061    return; 
    10371062 
    10381063  VectorScale( range, 1.0f / M_ROOT3, range ); 
     
    10461071    enemy = &g_entities[ entityList[ i ] ]; 
    10471072 
    1048     if( ( ( enemy->client && enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || 
     1073    if( ( ( enemy->client && 
     1074            enemy->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || 
    10491075        ( enemy->s.eType == ET_BUILDABLE && 
    1050           BG_FindTeamForBuildable( enemy->s.modelindex ) == BIT_HUMANS ) ) && enemy->health > 0 ) 
     1076            BG_FindTeamForBuildable( enemy->s.modelindex ) == BIT_HUMANS ) ) && 
     1077        enemy->health > 0 ) 
    10511078    { 
    1052       qboolean foundOldTarget = qfalse; 
    1053  
    1054       trap_Trace( &tr, muzzle, NULL, NULL, enemy->s.origin, ent->s.number, MASK_SHOT ); 
    1055  
    1056       //can't see target from here 
    1057       if( tr.entityNum == ENTITYNUM_WORLD ) 
    1058         continue; 
    1059  
    1060       for( j = 0; j < MAX_ZAPS; j++ ) 
     1079      alreadyTargeted = qfalse; 
     1080      for( j = 0; j < LEVEL2_AREAZAP_MAX_TARGETS; j++ ) 
    10611081      { 
    1062         zap_t *zap = &zaps[ j ]; 
    1063  
    1064         for( k = 0; k < zap->numTargets; k++ ) 
     1082        if( ent->zapTargets[ j ] == entityList[ i ] ) 
    10651083        { 
    1066           if( zap->targets[ k ] == enemy ) 
    1067           { 
    1068             foundOldTarget = qtrue; 
    1069             break; 
    1070           } 
    1071         } 
    1072  
    1073         if( foundOldTarget ) 
     1084          alreadyTargeted = qtrue; 
    10741085          break; 
    1075       } 
    1076  
    1077       // enemy is already targetted 
    1078       if( foundOldTarget ) 
    1079         continue; 
    1080  
    1081       return enemy; 
    1082     } 
    1083   } 
    1084  
    1085   return NULL; 
    1086 } 
    1087  
    1088 /* 
    1089 =============== 
    1090 G_UpdateZapEffect 
    1091 =============== 
    1092 */ 
    1093 static void G_UpdateZapEffect( zap_t *zap ) 
    1094 { 
    1095   int       j; 
    1096   gentity_t *effect = zap->effectChannel; 
    1097  
    1098   effect->s.eType = ET_LEV2_ZAP_CHAIN; 
    1099   effect->classname = "lev2zapchain"; 
    1100   G_SetOrigin( effect, zap->creator->s.origin ); 
    1101   effect->s.powerups = zap->creator->s.number; 
    1102  
    1103   effect->s.time = effect->s.time2 = effect->s.constantLight = -1; 
    1104  
    1105   for( j = 0; j < zap->numTargets; j++ ) 
    1106   { 
    1107     int number = zap->targets[ j ]->s.number; 
    1108  
    1109     switch( j ) 
    1110     { 
    1111       case 0: effect->s.time = number;          break; 
    1112       case 1: effect->s.time2 = number;         break; 
    1113       case 2: effect->s.constantLight = number; break; 
    1114       default:                                  break; 
    1115     } 
    1116   } 
    1117  
    1118   trap_LinkEntity( effect ); 
    1119 } 
    1120  
    1121 /* 
    1122 =============== 
    1123 G_CreateNewZap 
    1124 =============== 
    1125 */ 
    1126 static void G_CreateNewZap( gentity_t *creator, gentity_t *target ) 
    1127 { 
    1128   int       i, j; 
    1129   zap_t     *zap; 
    1130  
    1131   for( i = 0; i < MAX_ZAPS; i++ ) 
    1132   { 
    1133     zap = &zaps[ i ]; 
    1134  
    1135     if( !zap->used ) 
    1136     { 
    1137       zap->used = qtrue; 
    1138  
    1139       zap->timeToLive = LEVEL2_AREAZAP_TIME; 
    1140       zap->damageUsed = 0; 
    1141  
    1142       zap->creator = creator; 
    1143  
    1144       zap->targets[ 0 ] = target; 
    1145       zap->numTargets = 1; 
    1146  
    1147       for( j = 1; j < MAX_ZAP_TARGETS && zap->targets[ j - 1 ]; j++ ) 
    1148       { 
    1149         zap->targets[ j ] = G_FindNewZapTarget( zap->targets[ j - 1 ] ); 
    1150  
    1151         if( zap->targets[ j ] ) 
    1152           zap->numTargets++; 
    1153       } 
    1154  
    1155       zap->effectChannel = G_Spawn( ); 
    1156       G_UpdateZapEffect( zap ); 
    1157  
    1158       return; 
    1159     } 
    1160   } 
    1161 } 
    1162  
    1163  
    1164 /* 
    1165 =============== 
    1166 G_UpdateZaps 
    1167 =============== 
    1168 */ 
    1169 void G_UpdateZaps( int msec ) 
    1170 { 
    1171   int   i, j; 
    1172   zap_t *zap; 
    1173   int   damage; 
    1174  
    1175   for( i = 0; i < MAX_ZAPS; i++ ) 
    1176   { 
    1177     zap = &zaps[ i ]; 
    1178  
    1179     if( zap->used ) 
    1180     { 
    1181       //check each target is valid 
    1182       for( j = 0; j < zap->numTargets; j++ ) 
    1183       { 
    1184         gentity_t *source; 
    1185         gentity_t *target = zap->targets[ j ]; 
    1186  
    1187         if( j == 0 ) 
    1188           source = zap->creator; 
    1189         else 
    1190           source = zap->targets[ j - 1 ]; 
    1191  
    1192         if( target->health <= 0 || !target->inuse || //early out 
    1193             Distance( source->s.origin, target->s.origin ) > LEVEL2_AREAZAP_RANGE ) 
    1194         { 
    1195           target = zap->targets[ j ] = G_FindNewZapTarget( source ); 
    1196  
    1197           //couldn't find a target, so forget about the rest of the chain 
    1198           if( !target ) 
    1199             zap->numTargets = j; 
    12001086        } 
    12011087      } 
    12021088 
    1203       if( zap->numTargets ) 
     1089      if( !alreadyTargeted && 
     1090          Distance( ent->s.origin, enemy->s.origin ) > LEVEL2_AREAZAP_RANGE ) 
    12041091      { 
    1205         for( j = 0; j < zap->numTargets; j++ ) 
    1206         { 
    1207           gentity_t *source; 
    1208           gentity_t *target = zap->targets[ j ]; 
    1209           float     r = 1.0f / zap->numTargets; 
    1210           float     damageFraction = 2 * r - 2 * j * r * r - r * r; 
    1211           vec3_t    forward; 
    1212  
    1213           if( j == 0 ) 
    1214             source = zap->creator; 
    1215           else 
    1216             source = zap->targets[ j - 1 ]; 
    1217  
    1218           damage = ceil( ( (float)msec / LEVEL2_AREAZAP_TIME ) * 
    1219               LEVEL2_AREAZAP_DMG * damageFraction ); 
    1220  
    1221           // don't let a high msec value inflate the total damage 
    1222           if( damage + zap->damageUsed > LEVEL2_AREAZAP_DMG ) 
    1223             damage = LEVEL2_AREAZAP_DMG - zap->damageUsed; 
    1224  
    1225           VectorSubtract( target->s.origin, source->s.origin, forward ); 
    1226           VectorNormalize( forward ); 
    1227  
    1228           //do the damage 
    1229           if( damage ) 
    1230           { 
    1231             G_Damage( target, source, zap->creator, forward, target->s.origin, 
    1232                     damage, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); 
    1233             zap->damageUsed += damage; 
    1234           } 
    1235         } 
     1092        continue; 
    12361093      } 
    1237  
    1238       G_UpdateZapEffect( zap ); 
    1239  
    1240       zap->timeToLive -= msec; 
    1241  
    1242       if( zap->timeToLive <= 0 || zap->numTargets == 0 || zap->creator->health <= 0 ) 
    1243       { 
    1244         zap->used = qfalse; 
    1245         G_FreeEntity( zap->effectChannel ); 
    1246       } 
     1094      trap_Trace( &tr, ent->s.origin, NULL, NULL, enemy->s.origin, 
     1095        ent-g_entities, MASK_SHOT ); 
     1096      if( tr.entityNum == enemy-g_entities ) 
     1097        hitList[ hit++ ] = tr.entityNum; 
    12471098    } 
    12481099  } 
    1249 } 
    1250  
    1251 /* 
    1252 =============== 
    1253 areaZapFire 
    1254 =============== 
    1255 */ 
    1256 void areaZapFire( gentity_t *ent ) 
    1257 { 
    1258   trace_t   tr; 
    1259   vec3_t    end; 
    1260   gentity_t *traceEnt; 
    1261   vec3_t    mins, maxs; 
    1262  
    1263   VectorSet( mins, -LEVEL2_AREAZAP_WIDTH, -LEVEL2_AREAZAP_WIDTH, -LEVEL2_AREAZAP_WIDTH ); 
    1264   VectorSet( maxs, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH ); 
    1265  
    1266   // set aiming directions 
    1267   AngleVectors( ent->client->ps.viewangles, forward, right, up ); 
    1268  
    1269   CalcMuzzlePoint( ent, forward, right, up, muzzle ); 
    1270  
    1271   VectorMA( muzzle, LEVEL2_AREAZAP_RANGE, forward, end ); 
    1272  
    1273   G_UnlaggedOn( muzzle, LEVEL2_AREAZAP_RANGE ); 
    1274   trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT ); 
    1275   G_UnlaggedOff( ); 
    1276  
    1277   if( tr.surfaceFlags & SURF_NOIMPACT ) 
    1278     return; 
    1279  
    1280   traceEnt = &g_entities[ tr.entityNum ]; 
    1281  
    1282   if( ( ( traceEnt->client && traceEnt->client->ps.stats[ STAT_PTEAM ] == PTE_HUMANS ) || 
    1283       ( traceEnt->s.eType == ET_BUILDABLE && 
    1284         BG_FindTeamForBuildable( traceEnt->s.modelindex ) == BIT_HUMANS ) ) && traceEnt->health > 0 ) 
    1285   { 
    1286     G_CreateNewZap( ent, traceEnt ); 
    1287   } 
    1288 } 
    1289  
     1100 
     1101  for( i = 0; i < LEVEL2_AREAZAP_MAX_TARGETS; i++ ) 
     1102    ent->zapTargets[ i ] = -1; 
     1103 
     1104  if( !hit ) 
     1105    return; 
     1106 
     1107  ent->zapDmg += ( (float)( level.time - level.previousTime ) / 1000.0f ) 
     1108                     * LEVEL2_AREAZAP_DMG; 
     1109  damage = (int)ent->zapDmg; 
     1110  // wait until we've accumulated enough damage for bsuit to take at 
     1111  // least 1 HP  
     1112  if( damage < 5 ) 
     1113    damage = 0; 
     1114  else 
     1115    ent->zapDmg -= (int)damage; 
     1116 
     1117  VectorCopy( ent->s.origin, sortReference ); 
     1118  qsort( hitList, hit, sizeof( int ), G_SortDistance ); 
     1119 
     1120  // FIXME: event should be EV_LEV2_ZAP, but unknow by standard client 
     1121  // temporary give old zap effect (is it valid ?) 
     1122  effect = G_TempEntity( ent->s.origin, ET_LEV2_ZAP_CHAIN ); 
     1123 
     1124  effect->s.powerups = ent-g_entities; 
     1125  effect->s.time = effect->s.time2 = effect->s.constantLight = -1; 
     1126  for( i = 0; i < hit; i++ ) 
     1127  { 
     1128    if( i >= LEVEL2_AREAZAP_MAX_TARGETS ) 
     1129      break; 
     1130 
     1131    ent->zapTargets[ i ] = hitList[ i ]; 
     1132 
     1133    enemy = &g_entities[ hitList[ i ] ]; 
     1134 
     1135    if( damage > 0 )     
     1136    { 
     1137      G_Damage( enemy, ent, ent, NULL, enemy->s.origin, 
     1138        damage, DAMAGE_NO_KNOCKBACK | DAMAGE_NO_LOCDAMAGE, MOD_LEVEL2_ZAP ); 
     1139    } 
     1140    switch( i ) 
     1141    { 
     1142      case 0: effect->s.time = hitList[ i ];          break; 
     1143      case 1: effect->s.time2 = hitList[ i ];         break; 
     1144      case 2: effect->s.constantLight = hitList[ i ]; break; 
     1145      default:                                        break; 
     1146    } 
     1147  } 
     1148} 
    12901149 
    12911150/* 
     
    15061365      poisonCloud( ent ); 
    15071366      break; 
    1508     case WP_ALEVEL2_UPG: 
    1509       areaZapFire( ent ); 
    1510       break; 
    15111367 
    15121368    case WP_LUCIFER_CANNON: 
  • src/game/tremulous.h

    r76 r77  
    7575#define LEVEL2_CLAW_DMG             ADM(40) 
    7676#define LEVEL2_CLAW_RANGE           96.0f 
    77 #define LEVEL2_CLAW_WIDTH           12.0f 
     77#define LEVEL2_CLAW_WIDTH           16.0f 
    7878#define LEVEL2_CLAW_REPEAT          500 
    7979#define LEVEL2_CLAW_K_SCALE         1.0f 
    8080#define LEVEL2_CLAW_U_REPEAT        400 
    8181#define LEVEL2_CLAW_U_K_SCALE       1.0f 
    82 #define LEVEL2_AREAZAP_DMG          ADM(80) 
    83 #define LEVEL2_AREAZAP_RANGE        200.0f 
    84 #define LEVEL2_AREAZAP_WIDTH        15.0f 
    85 #define LEVEL2_AREAZAP_REPEAT       1500 
    86 #define LEVEL2_AREAZAP_TIME         1000 
     82#define LEVEL2_AREAZAP_DMG          ADM(33) 
     83#define LEVEL2_AREAZAP_RANGE        90.0f 
     84#define LEVEL2_AREAZAP_CUTOFF       350.0f 
     85#define LEVEL2_AREAZAP_REPEAT       500 
    8786#define LEVEL2_AREAZAP_MAX_TARGETS  3 
    8887#define LEVEL2_WALLJUMP_MAXSPEED    1000.0f