Results 1 to 3 of 3

Thread: Rebuilding the CoD4MoD

  1. #1
    Assadministrator IzNoGoD's Avatar
    Join Date
    Aug 2012
    Posts
    1,718
    Thanks
    17
    Thanked 1,068 Times in 674 Posts

    Rebuilding the CoD4MoD

    Hey all

    Currently Im rebuilding the CoD4MoD.
    Will probably continue until bored.

    Rebuilding it with a modular function system.

    Code:

    Code:
    init()
    {
    	level.functions = [];
    	level.functions["onconnect"] = [];
    	level.functions["onspawn_once"] = [];
    	level.functions["onspawn_continuous"] = [];
    	level.functions["onplayerdamage"] = [];
    	level.functions["onplayerkilled"] = [];
    
    	add_functions();
    
    	thread waitforplayerconnect();
    }
    
    add_functions()
    {
    	maps\mp\izno\_assists::init();
    }
    
    waitforplayerconnect()
    {
    	while(true)
    	{
    		level waittill("connecting",player);
    		player.izno = [];
    		for(i = 0; i < level.functions["onconnect"].size; i++)
    		{
    			player [[level.functions["onconnect"][i]]]();
    		}
    		player thread waitforspawn();
    	}
    }
    
    waitforspawn()
    {
    	self endon("disconnect");
    	while(true)
    	{
    		self waittill("spawned_player");
    		for(i = 0; i < level.functions["onspawned_once"].size; i++)
    		{
    			self [[level.functions["onspawned_once"][i]]]();
    		}
    		self thread while_alive();
    	}
    }
    
    while_alive()
    {
    	while(isdefined(self) && isdefined(self.sessionstate) && self.sessionstate == "playing")
    	{
    		for(i = 0; i < level.functions["onspawned_continuous"].size; i++)
    		{
    			self [[level.functions["onspawned_continuous"][i]]]();
    		}
    		wait 0.05;
    	}
    }
    
    Callback_PlayerDamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
    {
    	for(i = 0; i < level.functions["onplayerdamage"].size; i++)
    	{
    		self [[level.functions["onplayerdamage"][i]]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
    	}
    	self [[level.Callback_PlayerDamage]](eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset);
    }
    
    Callback_PlayerKilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
    {
    	for(i = 0; i < level.functions["onplayerkilled"].size; i++)
    	{
    		self [[level.functions["onplayerkilled"][i]]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
    	}
    	self [[level.Callback_PlayerKilled]](eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration);
    }
    And
    Code:
    #include maps\mp\_util;
    
    //assists: store in player's array
    //go over 64 items in said array, as players might disconnect during the assist-array building
    //if not found, find nearest open spot in said array
    //array is self.izno["assists"][].
    //store damage done by said player in self.izno["assists_damage"][]
    //init both arrays on playerconnect, reset on full health and on playerspawn().
    
    
    init()
    {
    	Settings();
    	level.functions["onconnect"][level.functions["onconnect_once"].size] = ::onconnect_once;
    	level.functions["onspawn_once"][level.functions["onspawn_once"].size] = ::onspawn_once;
    	level.functions["onspawn_continuous"][level.functions["onspawn_continuous"].size] = ::onspawn_continuous;
    	level.functions["onplayerdamage"][level.functions["onplayerdamage"].size] = ::onplayerdamage;
    	level.functions["onplayerkilled"][level.functions["onplayerkilled"].size] = ::onplayerkilled;
    }
    
    Settings()
    {
    	level.scorebonus = [];
    	level.scorebonus["assist"] = 2;
    	level.scorebonus["kill"] = 10;
    
    	level.moneybonus = [];'
    	level.moneybonus["assist"] = 2;
    	level.moneybonus["kill"] = 2;
    
    	level.xpbonus = [];
    	level.xpbonus["assist"] = 2;
    	level.xpbonus["kill"] = 10;
    
    	level.moneybonus = [];
    	level.moneybonus["assist"] = 2;
    	level.moneybonus["kill"] = 10;
    }
    
    onconnect_once()
    {
    	self.izno["assists"] = [];
    	self.izno["assists_damage"] = [];
    }
    
    onspawn_once()
    {
    	self.izno["assists"] = [];
    }
    
    onspawn_continuous()
    {
    	if(self.health >= self.maxhealth)
    	{
    		self.izno["assists"] = []; //no need to reset self.izno["assists_damage"] as it is fixed in the callback_playerdamage anyway.
    	}
    }
    
    onplayerdamage(eInflictor, eAttacker, iDamage, iDFlags, sMeansOfDeath, sWeapon, vPoint, vDir, sHitLoc, timeOffset)
    {
    	if(isdefined(eAttacker) && isplayer(eAttacker))
    	{
    		save_here = -1;
    		for(i = 0; i < 64; i++)
    		{
    			if(!isdefined(self.izno["assists"][i]) && save_here == -1)
    			{
    				save_here = i;
    				self.izno["assists_damage"][i] = 0;
    			}
    			else if(self.izno["assists"][i] == eAttacker)
    			{
    				save_here = i;
    				break;
    			}
    		}
    		if(save_here != -1)
    		{
    			self.izno["assists_damage"][save_here] += iDamage;
    			self.izno["asists"][save_here] = eAttacker;
    		}
    	}
    }
    
    onplayerkilled(eInflictor, eAttacker, iDamage, sMeansOfDeath, sWeapon, vDir, sHitLoc, timeOffset, deathAnimDuration)
    {
    	for(i = 0; i < 64; i++)
    	{
    		if(isdefined(self.izno["assists"][i]) && (!isdefined(eAttacker) || !isplayer(eAttacker) || eAttacker != self.izno["assists"][i]))
    		{
    			self.izno["assists"][i].score += level.scorebonus["assist"];
    			self.izno["assists"][i] AddStat("money", level.moneybonus["assist"]);
    			self.izno["assists"][i] AddStat("xp", level.xpbonus["assist"]);
    			//self.izno["assists"][i] updatedamagefeedback(); //not the right name i guess
    		}
    	}
    	if(isdefined(eAttacker) && isplayer(eAttacker) && self != eAttacker)
    	{
    		eAttacker.score += level.scorebonus["kill"] - 1; //-1 for the normal Callback_PlayerKilled already adds one
    		//does NOT handle teamkills well. Disable friendlyfire as it is annoying anyway.
    		eAttacker AddStat("money", level.moneybonus["kill"]);
    		eAttacker AddStat("xp", level.xpbonus["kill");
    	}
    }
    So, what do you all think?
    Will this be useful to you in a future project too, or couldnt you care less?

  2. The Following User Says Thank You to IzNoGoD For This Useful Post:

    kung foo man (2nd November 2012)

  3. #2
    Assadministrator kung foo man's Avatar
    Join Date
    Jun 2012
    Location
    trailerpark
    Posts
    2,011
    Thanks
    2,102
    Thanked 1,084 Times in 753 Posts
    Usefull for not adding all the same logic over and over again

    On the other side, i like to write this kind of things directly in the maps/mp/gametypes/$gametype.gsc, for the case of manipulating the flow of some hooked function:

    Code:
        if (sMeansOfDeath == "MOD_FALLING")
            return;
    So in the end, i would end up with different ways of manipulating the same function, which could become confusing.

    But for functions shared between mods, its fast and easy to integrate them
    timescale 0.01

  4. #3
    Brigadier General
    Join Date
    Oct 2012
    Posts
    994
    Thanks
    20
    Thanked 588 Times in 388 Posts
    It's right and proper to try to eliminate as many script variables (wait, waittill, endon, etc) as possible. The stock game files have far too many of them as it is.This looks like a good way to manage multiple game events. It uses callbacks, which eliminates the need for script variables. So, it gets my thumbs up!
    Last edited by Tally; 2nd November 2012 at 16:27.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •